読者です 読者をやめる 読者になる 読者になる

chainerで自然言語処理できるかマン

chainerで自然言語処理を勉強していくブログ

example\ptbがやっていることを確認

example\ptbが何をやっているかをもう少し見ていきたいと思います。
コードを読む:example\ptbを読む - chainerで自然言語処理できるかマン

RNNLM

example\ptbでは「RNNLM with LSTM」を学習しています。
RNNLMは正式にはRecurrent Neural Network Language Modelのことで、RNNを使って言語モデルを実現しています。

言語モデルは、「文の生起確率(出現のしやすさ)」を計算するモデルのことで、P(文)の具体的な確率値を求めます。
ここで用いられているのは「文は単語列で表される」と考え、以下のように表現できると仮定しています。
P(文)=P(単語1 単語2 ...)=P(単語1) \cdot P(単語2|単語1) \cdot P(単語3|単語1 単語2) \cdot ...
整理すると、
P(文)=\Pi P(単語i|単語1 ... 単語(i-1) )
としています。

RNNLMでは、ニューラルネットワークの出力層のsoftmaxによる値を各単語の生起確率P(単語i|単語1 ... 単語(i-1) )として、利用する事でRNNを言語モデルとして使います。
さらに、RNNの中間ノードとしてLSTMを使う事で、長期間の情報の保存が可能になり、さらなる改善がされており、このサンプルでもそれが実装されています。

chainerでのLSTMの実装

使っているのはchainer.links.LSTM(in_size, out_size)で、これは、in_size個の入力をうけとり、out_size個のLSTMおよび出力を持ちます。
内部変数として、入力からLSTMへのupward接続(links.Linear、下図の赤い線)と、(一つ前の時刻の)LSTM出力から(現時刻の)LSTM入力へのlateral接続(links.Linear、下図の青い線)、LSTMの状態c、一つ前の出力hを持っています。

links.LSTM(3,2)の場合を図にしてみると、
f:id:chainer_nlp_man:20160224020536p:plain
のような感じで、図のLSTMは活性関数としてのLSTM(chainer.functions.activation.lstm)を表し、fully-connectedなので、接続はlinks.LSTM内のすべてのfunctions.activation.LSTMについて張られるようです。
図ではlateral接続が出力から時間遅れで入力に行っているように書いていますが、実装上は内部変数hを使って入力しています。

net.pyで定義されているRNNLMでは、これを2層重ねたものを使っています。
また、Zaremba et al., Recurrent Neural Network Regularization, ICLR 2015メモ - chainerで自然言語処理できるかマンのとおり、recurrentしていない部分にdropoutを入れています。recurrentしている部分にいれるとしたらlateral接続の部分にいれることになるようです。

LSTM自体のバリエーションは複数あるようですが、chainerサンプルで実装されているのはchainer.functions.activation.lstm — Chainer 1.6.1 documentationで、forget gateを持ちますが、peepholeではない版のようです。