KZKY memo

自分用メモ.

TensorFlow: Sequence-to-Sequence Models

sequence 2 sequenceの学習の話.この記事を書いている時点で,TFのversionは,0.6.

データのダウンロード

cd tensorflow/models/rnn/translate
python translate.py --data_dir [your_data_directory]

で,English to Frenchのデータセットのダウンロードが始まる.20GBくらいある.

seq2seqのライブラリは,ここにある.ただし実態は,こっち

このチュートリアル自体のコードは,ここ

Sequence-to-Sequence Basics

まずは,RNN Encoder-Decoderの話から.RNN Encoder-Decoderは,Encoder (RNN)でインプットをEncodeし,fixed-length vectorにして,それをDecoder (RNN)のインプットにする.DecoderもRNNであって,そのfixed-length vectorをRNNのセルがいつも見に行く.たぶん,一番シンプルなAttentionと考えることもできると思う.しかし,fixed-length vectorしか見ないので,Input Vecotr SequenceのどこがOutput Vector Sequenceに効くのかよく分わからないので,Attentionの概念がでてくるのだと思う.EncoderとDecoderでは,パラメータをシェアしていてもいいし,一般的には,違うセル(異なるパラメータセット)を使ってもいい.

Attentionの細かい説明は,Bahdanu et al., 2014に書いてある.簡単にいうと,AttentionはRNN Encoder-Decoderにおいて,Decoderが,ステップの度に,Encoderの出力を覗き見ること.Bahdanu et al., 2014では,sequenceのannotationを覗き見ている.annotationは,forward hidden stateとbackward hidden stateを結合したものと定義している.そうすることで,word_iの周辺情報をみることができるので良いとのこと(BiRNNだと思う).


f:id:KZKY:20160216231837p:plain

言語に限らず,画像関連でも使用される.これでは,フィルターを使ってどこを見るかをシークエンシャルに決めることで,Attention.これもAttentionで,次にどこみるかを決める.

これによると,RNNの次(というか延長でもう来ている)は,Attention!

Attentionのコード自体は,これの431行目あたりに書いてあって,decoder inputの度に呼ばれて,結合されている(ここの456行目からあたり).

TensorFlow seq2seq Library

基本これ.

outputs, states = basic_rnn_seq2seq(encoder_inputs, decoder_inputs, cell)

encoder_inputs, decoder_inputs, およびrnn cellを受け取って,decoderにおけるすべての,output, stateを返す.

Decoderのインプットは,普通,教師を使うのだが,学習時でもモデルをロバストにする目的やシークエンスの生成時には,Decoderの前のアウトプットを現在のインプットに使用する.

シンボルがin/outの場合は,embeddingが用意されている.

outputs, states = embedding_rnn_seq2seq(
encoder_inputs, decoder_inputs, cell,
num_encoder_symbols, num_decoder_symbols,
output_projection=None, feed_previous=False)

言語処理のように,symbolが非常に多い場合は,Sampled Softmaxを使う.それも用意されていて,ouput_projectionに (W, b)を入れればいい.

Neural Translation Model

Sampled softmax and output projection

Sampled Softmaxの話.num_symbolが512(default value)を超えない場合は,普通のSoftmaxを使った方が良いという話.

Bucketing and padding

Sequencesはそれぞれ,長さが異なるので,理想的には,すべての長さに対応するgraphを作りたいが,それは非効率的.長さが違う場合は,paddingをしたりするが,一番長いsequenceに合わせると,短いsequenceは過度にpaddingされてしまう.なので,妥協案として,bucketing and paddingをする.

これの766行目あたりからをみるとbucket毎に,モデルを作っている様に見える.これらをこれの161行目あたりで,bucket毎(モデル毎)でlossのgradとっている.(全データが全部のバケットに入っている様に見えるのは気のせいだろうか...)

Let's Run It

取り敢えず動かしたいなら,DLが終わった後,

python translate.py \
  --data_dir [your_data_directory] --train_dir [checkpoints_directory] \
  --en_vocab_size=40000 --fr_vocab_size=40000 \

代替,batch-size 64で,340K steps くらいすると,bucket0, bucket1はperplexity的にいい感じになってきて,予測ができる.

python translate.py \
  --data_dir [your_data_directory] --train_dir [checkpoints_directory] \
  --size=256 --num_layers=2 --steps_per_checkpoint=50 \

Reading model parameters from /tmp/translate.ckpt-340000
>  Who is the president of the United States?
 Qui est le président des États-Unis ?

What Next?

上記はseq2seqだったけど,同じモデルが,seq2treeのようにparserとしても使える.Vinyals & Kaiser et al., 2015は,それ系のタスクでstate-of-the-artらしい.