勉強会の題材、詳解ディープラーニング

の6章を軽く見る。 5章で意味が分からない説明が多くて、理解しようとして無駄に消耗したので、コードや式から自分で考えるくらいの気持ちで、説明自体は軽く見ていく。

6.1 Bidirectional RNN

さっそく肝となる6.2式が分からない。

なんかパラメータの上の矢印以外全く同じになってしまっているが。 普通に考えてt+1期を食わせるんじゃないか?しかもhidden unitは未来から戻った時の現時点のコンテキストだからhの上にも矢印が要るんじゃないか?

つまりこうじゃない?

6.1ってこの式以外はだいたい前と一緒、って程度の内容なので、ここが間違ってると台無しな感じなんだが…

どうせならトレーニングの所をもうちょっと詳しく説明したらいいのにね。 各 \(y(t)\)を予測する時にforwardとバックワードがどのデータを見ているか、というのは説明しても良いと思うのだが。

6.2 Encoder-Decoder

p265のコードを見ているが、encoderのweightがこれでどうして学習出来るのだろうか?

でも、考えてみると、こういう物かもしれない。

普通encoderは自身を予測出来るように学習すると思うが、この問題の場合、ある数字の次に何が来るかってほとんど独立なので学習しようが無いよな。

一方で答えが合うように学習するだけでも、最終的にはencoderのweightsは合うはずだ。 そんな遠い関係で学習出来るのかな?と不安にもなるが、たかだか9文字とかその程度の長さなので、この位なら頑張れるか。
答えだけから学習する事で内部での大小関係とかを学ぶのだろうから、ちょっと人工知能っぽくて面白いな。

6.3 Attention

attentionは以前元論文を読んだ事があって、そんな難しくはなかった記憶がある。

で、つらつら読んでいくと、6.11から6.16の議論が早すぎるので、ちょっとゆっくり考える必要がありそう。

対応関係を表すアルファを学習して、それに応じてencoder の隠れ層の出力を持ってくるという事だろう。 ただこれだと、Tが決まってる必要はあるよな。 普通ここはウィンドウサイズ的な物になるのか。対応関係が学習出来る程度に普通の長さの所は学習出来るが、頭とケツとか離れた奴はうまく学習出来無さそうだけど、バイディレクショナルならだいたいは平気か。

ふむ、ゆっくり読めばどうという事は無かった。

LSTMにおけるAttentionが分からない

6.3.2の所で、6.22式のようにするとattentionが組み込める、と言っているが、よく分からない。 今回はdecoder側が出ていないので6.3.1とは大分違う話をしているように見えるが…

これは文献5を見ないと分からないなぁ。 文献5はこれか。

https://arxiv.org/abs/1601.06733

文献5、LSTM Network論文を眺める

という事で元論文を3章だけ読む。 普通のLSTMは

という条件付き独立が成り立っているが、これはtokenの一つ上の構造を直接学習しづらい、という欠点がある。

そこで、これまでのhidden stateの列(hidden tapeと呼んでる)と、memory stateの列(memory tapeと呼んでる)の2つを重み付け和をとって、次の期のhとc とする、という方式を提案していて、これをLSTM Network、略してLSTMNと呼んでいる。

以下は本の方と同じような式となる。

なるほど、だいたい分かったので本に戻ろう。

6.4 Memory Networks

これも説明がさっぱり分からないので元論文をあたる。ちゃんと元論文への参照が載ってるのはこの本の評価出来る所だな。

参考文献として6と7が示されているがどっち読むかなぁ。 名前がMemory networksとそのものずばりの6の方を読むか。

https://arxiv.org/abs/1410.3916

軽く読んでみた。これだけだとRNNを一般化してrecurrent以外も含めただけに見える。

とりあえず問題意識を理解する為に本に戻ろう。

さて、いつものようにtf.nn.embedding_lookupに解説が無いな。 なんかこう、肝心な所には解説をつけない、という方針で一貫していて、かえって清々しい。

これはword2vecなんかで昔触った事が有る気がする。 確か、

みたいに、各行が各単語のembeddingに対応するような行列と、単語を表すidのリストを引数にとって、このid番目の行を引いた結果を返す、みたいな感じだった気がする。

たとえば単語の並びが0, 1, 0, 2だった時には、

という感じで、行をlookupして返すだけ、という物だ。

以上を踏まえて、p287と文献6の論文を見比べて見よう。

まず、mとcはストーリーのembedだな。 何故か2つある。

で、uは質問のembedだ。

文献6では、変換としてI, G, O, Rの4つを定義していた。 Gがメモリをアップデートして、Oは入力のembedとメモリを元に出力featureを出して、Rは出力featureから答えを出す。

OとRが分かれているのは、感覚的にはOというfeatureスペースの何かと、そこから実際の答えへの変換は分けておく方が良い、ってことだと思う。 なら意味的にはo自身が答えと思って間違い無かろう。(追記: だが本の方はoとuを合わせてからWを掛けているのでoの位置づけは文献6とは違いそう)

さて、p287のモデルでは、ストーリーズと質問文を合わせた物が入力、という事になるだろう。 これはmとuをconcatした物になりそうだが、それに該当しそうなpはmatmulして足を潰してsoftmaxしてる。

kの足を潰す、というのは、どこの次元だろう。iはストーリーと質問文の対の数だろう。

図にするか。

jとlは分かった。残るkは各単語のembed の次元だろうな。

kの足を潰すのだから、embedの次元について和をとってるのだろう。 つまりどういう事だろう?

とりあえず一つのストーリーと質問の組について考えて、iは忘れよう。 残るはjとlとkだ。

jとlの行列を作る訳だ。 jがストーリーの先頭から何ワード目かを表し、lは質問文の先頭から何ワード目かを表している。

で、アインシュタインの縮約をする訳だから、質問と答えの各単語の全組み合わせを掛けて、それぞれの積がこの結果の行列の要素になる訳だよな。

で、単語を掛ける、というのは各単語のembedの内積か。

ふむ。

つまりconcatよりも、もっと全単語の組について見るのだから、細かい組み合わせを見る訳だな。

pの次元のjとlは、jがストーリーの単語の先頭からのインデックスを、lが答えの単語の先頭からのインデックスを表す。

oはこのpとcの和となってる。 pもcもストーリーの単語の数の方の次元は対応するので良いとして、質問のワードの方の次元に対応するのはcではどうなるのか? とlookupする行列Cの次元を見ると、question_maxlenとなってる。

あれ?次元合わない事あるじゃん。 questionはfillしてるのか?

p286を見ると0でパディングしてるっぽいね。

さて、oとは何か? pはストーリーと質問文のembedの内積だ。気分としてはそれぞれの単語がどのくらい関係してるか、を表していると思えば良かろう。

cはストーリーの単語そのまんまだよなぁ。

足した結果は関係と、ストーリーの単語の両方を勘案した何か、という事か。

ここまでを考えると、感覚的にはpは単に入力からembedをlookupしただけの物に見える。

で、oはpにcを足しただけ。cはストーリーのembedだった。 入力のembedと、入力のうちストーリーだけのembedを足す。

inferenceの結果は、気分的にはこのoと質問文をconcatしてFeed Forwardのニューラルネットに食わせているような物だろう。

さて、論文との対応を考えよう。

pは気分的には入力のメモリ、という事か? で、c がsecond supporting memoryという事になるのか。

ちょっと解せないのは、論文の方ではG でメモリから値を取り出す所では、それまでのメモリの値も引数に渡している。 これに相当する部分がよく分からない。

と言うか大分別のモデルな気がするな。

参考にしているのはどれか?と前のページを見直すと、p284にkerasのexampleへのリンクがある。

https://github.com/keras-team/keras/blob/master/examples/babi_memnn.py

コードを読むと、この本と同じモデルに見える。 このコードの上の方にはコメントで論文へのリンクがある。

2つあるが、関係ありそうなのはこっちか? End-To-End Memory Networks

これは本の方では文献8と言われている物だな。

End-To-End Memory Networks

軽く読んでいこう。 どうもこれは、一つ前に読んだ文献6の論文の発展版で、back propagationで普通にトレーニング出来る、というのがウリっぽい。

式はいかにも本と同じなので、この論文を下敷きに書いた事が分かる。

2.1のSingle Layerの式は分かりやすいが、幾つか疑問に思う事もある。まず素直に読んでいこう。

(1)式はuと\(m_i\) の内積を取って、そのsoftmaxをとってる。 uには足がついてなくて、質問文が一つのフィーチャーベクトルにまとめられているらしい。方法はこの時点では不明。

距離では無く内積なのは直感的な解釈は難しい部分もあるが、基本的には関連の強い所は大きな値となるのだろう。 つまり質問文と関連の強いストーリー内の文のメモリ位置を学習するのだろう。

(2)のOutputを見る。 \(c_i\) が各ストーリ一文一文から考えられる答え、というか、抽象的な事実的な何かなのだろうな。 で、どのストーリーの事実を重視するか、というのをpで判断するのだろう。

最後にoとuを足している。uを足す必要性が何故あるのかは自明じゃないし、何故和なのかも自明では無いが、感覚的には変換する前のqをもう一度食わせるとスコアは上がりそうな気はする。 concatの方が良い気はするが。

さて、ここまでだと質問文はシーケンスなのになんでu一つで表せるのか、とか、ストーリーも一文を一メモリで表せる理屈とか良く分からないので、実際の実験の詳細を読む。4.1か。

そこを読むと、なんとuは単語のembedの和をとってる。BoW表現だと和でも簡易的には集約出来てるとは言えそうだが、さすがにこれじゃ乱暴過ぎるだろう。

で、その後にさすがに位置の情報は必要だろうからポイントエンコーディングする方が良いぜ、とか書いてある。

ふむ、ここまで読んだ事を考えてみよう。 まず、Memory Networkの論文とはかなり揃った話となっている。向こうはより一般的な話で、こちらはその考え方にある程度沿った、具体的なネットワークの話となっている。

外部のDDRとかを使うのかと思ってたが、embeddingの行列とか学習するためにはback propagate時に全ての要素が要るので、別段外のメモリとやりとりする、という訳では無さそう。 Memory Networkの方はそういう応用を視野に入れていたように見えるが、こちらの論文では全部tf.Variableだろう。

どちらかというとattentionの一種に見える。 hidden unitをセンテンスの数だけ作って、それをpというattentionで重みを判断する、みたいな。

感覚的にはcとqだけで学習すると、cは各センテンスの意味を、最後のWはqに応じて意味から考える所を学習してくれそうな気はする。

で、この基本的なモデルのうち、意味の所を過去の意味を思い出す、的な要素に差し替えて、それがcとpの線形和となる訳だな。

かなりシンプルでやりたい事は分かる。 ただ、これだとメモリの長さはハードコードせざるを得ないし、一つのセンテンスの長さにも弱かろう。

何がメモリなのか?

ところでこれ、どの辺がメモリなんだろうか? 元のMemoryNetworkの方ではGが前のメモリを受け取って更新するのでメモリっぽさがあったが、こっちの論文では各センテンスのBoWのembedをメモリと呼んでいる気がする。 でもそれは単に一文をfeature spaceに射影しただけだよな。

\(p_i\)は単なるsoftmaxなので、学習されるパラメータは無い。 なんかpの所(つまり式1)にWが無いのは違和感があるな。 感覚的にはそれぞれの文のfeatureと質問文のfeatureのマッピングを学習する必要がありそうだが。

ようするにこのembed用の行列がまさにそうなるように学習される対象、という事になる。

式(1)は感覚的にはqとxに、結局は何かの行列を挟んで行列積をとった物となる。 これはマッピングと言える。 このマッピングが、xの側のembed行列とqの側のembed行列に分解される、と言っているんだよな。

これってどこがattentionと違うんだろう?と3のRelated Workの所の説明を見てみると、

  1. attentionはセンテンス単位だが我らのは複数センテンスに渡る
  2. 複数ホップする

との事。

なるほど、複数センテンスにまたがるQ and Aをどう解くか?というのがモチベーションだったな。で、前のattentionそのままでは複数センテンスはうまく扱えていない。 そこで各文をBoWにして普通にattention使って解いた、というのが一番目だな。 大したこと無い話でわざわざメモリとか名前変える程の事には思えないが、複数の文を扱う為に一つの文をBoWとすれば良い、というのを実際にやってみて結果を報告するのは意味の有る事だろう。

で、二番目。複数ホップはmulti layerとして2.2に書いてあった奴だな。本では扱って無さそうだったから飛ばしたが、この辺がattentionと違うといいたいのか。

軽く読んでみた。うーむ、たしかに文献6のGと類似性はあるからMemory Networkと呼ぶべきなのだろうが、なんか単に良くあるRNNと同じような感じでつなげました、という程度で、発明らしい発明とは思えないなぁ。

BoW表現のembedとして一つのベクトルにして、attentionをつけてそれっぽいネットワークを作ってみた、以上の事は言ってない気がする。

なんでこの論文をこの本に加えたのだろう?

まぁいいや。複数の文にまたがる全体をうまい事評価する為に、各文のembedと、それの質問との対応をattentionとして学んで、その重み付け和を使う事で、複数の文にまたがるタスクに答える。

この仕組みはMemory Networkのシンプルな一インスタンスと考えられるのでその用語に合わせると、メモリ、という事になるが大した意味は無い、くらいに思っておこう。

6.4のソースを見直す

ここまでを踏まえて、本の方に戻ってみよう。 mとuとcがembeddingの和になって無くてベクトルとなっていて、その結果\(p_i\)が単純な内積によるスカラーじゃなくて、単語同士の組み合わせ通りだけある行列となっている。

論文の方では一文がBoWとして一ベクトルとなっている。それがiという足で表されている。 だから\(m_i\)も、質問文と各文の相関というか関連度のような物を表している。

一方で本の方では、センテンスの区切り、というのを意識してない(p286など参照)。 するとpは、質問文の各単語と、ストーリーの各単語の関連度となる。

これでは単語同士のマッチングになってしまって、シーケンス的な要素が扱えないのでは?という気はするが、もともとBoWの線形和とかだった事を思えばよりマシになっていると言えるか。

6章を読み終わって

さて、一応最後まで読んだが、なんかちゃんと分かった感じがしない。 それぞれのモデルを実装してみる事は出来ると思うが。

いろいろなモデルを概観する事は出来たが、結局RNNのあたりを芯から分かった感じがしないので、幾ら具体的な応用をその上に積み重ねても駄目だなぁ、という印象。

本の説明は相変わらず分かる気が全くしなかったが、6章は最初からそういう物と思って元論文とかを中心に読んだので、そこまで腹がたったりはしなかった。
むしろ、単なる補助資料くらいのつもりで居ると、無いよりは結構マシだ。
元論文への参照は割とちゃんとついていて、動くソースもある。ちょっと出来の悪いレビュー論文みたいな物と思えば、存在意義はそれなりにある気がした。

ただやっぱりもうちょっとしっかりした解説が読みたいね。