Gated Self-Matching Networks for Reading Comprehension and Question Answering [Wang+, ACL'17]
https://www.aclweb.org/anthology/P/P17/P17-1018.pdf
概要
SQuAD QAでSOTAを出しましたという論文。会場で発表を聞いていたけどネットワークが複雑で一回だと良く分からなかった。 改めてもう一度読んでも良く分からなかった。一応読んだのでメモ。
SQuADは文書と複数の質問が与えられ,回答となるそれぞれのスパンを文書から見つけるタスク(のデータセット)。train, devデータのみ配布されて、 testデータについては事前に配られず、公式サイト からテストを受けて結果だけを受け取る形式を取るそうな(どうやってるんだろう?) 公式サイトのトップにランキング形式で結果が乗るのがゲームっぽくて人気が出てるのも頷ける。
このタスクを解く際に元文書からどうやってスパンを取っているのかが分からなかった(SQuAD系列をちゃんと読んだことが無かった)ため試しに読んでみた。
モデル
モデルは上図。既存研究の積み重ねをフルに使っており,見ての通りとても複雑。図の下から順に,
(1. Question and Passage GRU Layer) Bi-RNNで質問文・元文書をwordとcharacter両方使ってエンコードしてベクトル列
,
を獲得
(2. Question and Passage Matching Layer)
(質問文をエンコードしたベクトル列全体) をattention-poolingして
を獲得し,文書側のt番目のベクトル
とconcatしてRNNに入力。それを文書の単語数と同じ回数だけ繰り返すことで
を獲得。
は文書のt番目の単語が質問文のどの単語とマッチしているかの情報を持ったベクトル。
獲得の際のattentionには
,
が使われる。(対象となる単語と前のマッチ結果を参考にしている)
この際に,RNNの更新時 ではなく下式で表される
を使うというのが提案手法その1。
意図としては文書中のある単語と質問文とのマッチ結果のうち、重要じゃないマッチについてはgateで弱めて入力している感じだろうか。
(3. Passage Self-Matching Layer) 提案手法その2。 2. で得たマッチングのベクトルに対してもう一度attention-poolingしてBi-RNNに入力。やっている操作は 2. と同じで、アテンション先・アテンション元のベクトルが変わっているだけ。 正直この操作はよく意図が分からなかった。説明では2. でマッチ結果をgateすることによって重要な部分の情報しか残らなくなってしまうから,文書全体の文脈をもう一度獲得するためにself-matchingするんだ・・・と述べていたが、この操作で本当にそれをしたことになるのか?(そもそもattention-poolingする対象が2.のマッチング結果のベクトルなのだから、その時点で文書の細かい情報なんて無くなってしまっているんじゃないのか?)
(4. Output Layer) 回答スパンの初めと終わりを推定するレイヤ。気になっていた部分だが、 Pointer Networks [Vinyal+, NIPS'15] (attentionする時に隠れ層のweighted averageをとるのではなく推定した重みのargmaxを取るだけ。どこに強い重みがあるかのインデックスだけを得る) を使うのがトレンドらしい。 その際に使うのが3.でself-matchingを行って獲得したベクトル。
実験結果
既存研究との比較とablation testの結果が上図。ablation testの結果を見るに提案手法(gating, self-matching)はそれなりの効果がありそう。 ただぶっちゃけこれNNにありがちな手当たり次第あちこち繋げてモデルの複雑度を上げたことで良くなっただけなんじゃないの感がある(失礼)
感想
精度競争が激しいタスクにはありがちだけどいまいち研究の大目標が掴めない感じの論文だった。モデルとかなんでこんなことになってしまったんだ・・・
また、重要なマッチングもそうじゃないマッチングも平等に残るのが嫌でゲート構造を導入したとのことだが、それは結局attentionの際に重みの総和を1にしていることに起因するわけで、Dynamic Entity Representation with Max-pooling Improves Machine Reading[Kobayashi+, NAACL'16]のbyway attention(attentionの際に"どれにもアテンションしない"に相当するベクトルを1つ用意する)とかを使えばいいんじゃないか、とも思った。 特に2つのテキストの単語に対応関係のあることが概ね保証されている翻訳と違って、QAなどのタスクではそもそもattentionする必要のない単語がしょっちゅう出てくるんだから。