content合理と非合理のあいだ人工知能・哲学・スタートアップについて綴ります。前回の記事では言語モデルを作るという目的をふまえて一般的なRNNの構造について取り扱ったが、今回はPythonで実際に言語モデルを実装し、その言語モデルに自動で文章を吐き出させるプログラムを作ってみる。一般的なNNと同様、以下のモジュール構成になる。これは実装の一例であり、入出力や関数の切り分けパターンは他にも存在する。etc.)各モジュール今回の実装では、以下のようにRNNクラスのインスタンス変数として重みや重み更新値を設定した。again”)の予測を行う関数predictは、次のように実装される。前記事の図に示したように、単語の長さに応じてレイヤーの枚数が変わっていくようなイメージだ。one-hotベクトルなので、文はマトリックスになるが、この実装では1であるインデックスだけを整数で表して文を1次元のベクトルとして表している。和(あるいは平均)で表される。今回はデータセットの評価にはmean_loss関数、つまり、データ全体でみた損失関数の単語ごとの平均を用いた。mean_loss重み更新値デルタを計算する関数acc_deltas_bpttは以下のようになる。基本的に、前回記事の更新式をそのままコードにしただけである。遡るタイムステップstepsはハイパーパラメータで、大きいほど正確だが計算量は大きくなる。sum_deltaUトレーニングの関数は直接掲載しないが、基本的にはエポックごとに繰り返し、各エポックでトレーニングセンテンスごとにacc_delta_bpttを実行する(誤差逆伝搬でデルタを計算する)。計算し終わったら重みを更新し、次のエポックに移る流れとなる。各エポックごとにだんだんと学習率を下げるのが一般的で、どれくらいのペースで下げていくかもハイパーパラメータのひとつである。エポックでの学習率として、以下を用いた。0.05)の範囲で変更し、計27通りのパラメータの組み合わせで実験を行った。Corpusを利用している。(トレーニングに時間がかかるのでトレーニングセンテンスを1000個に絞った。2000、エポック数は25である。loss)の値は以下の表のようになった。良い組み合わせだとわかった。次に、この組み合わせでフルトレーニングセット(6万件くらい)でネットワークを鍛えなおし(1エポックに30分近くかかった)、できた言語モデルを使って自動で文章を生成させてみた。以下が、文章作成関数generateのコードである。lossの小さかった例が以下である。’</s>’]・・微妙である。share”とか部分的に意味の通っている表現は見受けられるものの、全体を通しては意味不明な文章が多い。文章生成だけでいったらマルコフ連鎖モデル(品詞→品詞の遷移(transition)確率と品詞→単語のemission確率を組み合わせるモデル)なんかの方がいいかも。ひとつの原因として、ボキャブラリーサイズが2000だと、one-hotベクトルを使っているので生じたベクトルがスパースになってしまうからだと考えられる。ベクトルの一番大きな値でも0.01か0.02(つまり一番出やすい単語でも1%か2%の確率、他が0.5%くらい)というケースが多く、この分布に従ったらほとんどランダムに単語をピックアップしているようなものだ。ピックアップのアルゴリズム(例えば上位100単語だけ見て確率を正規化し直すとか)を変えるだけで性能は向上するかもしれない。ハイパーパラメータやエポック数、学習アルゴリズムが原因かもしれないので、その点はもう少し検討して見る余地はあるかも。まとめ言語モデルにおいて最も伝統的なNgramは、直前N単語前の単語まで考慮して単にコーパス内の単語のつながりをカウントしまくって単にカウントとカウントの割り算で確率を計算する、というシンプルなモデルであった。このモデルの問題点は、コーパスにある単語のつながりしかカウントでいないので、実際には出現する可能性があってもコーパスに出ていないというだけで単語の生起確率が0になってしまう、というものだった。これを解消する手法が単語カウントに他の単語カウントから得られた適当な数を足して0をなくすというSmoothingであるが、これにもいろいろな問題があった(ここでは省略!)。Ngramは汎化能力が無いという点で弱い。この点、RNNは単語をカウントしているのではなく、重みを学ぶことで単語と単語のつながり方を学習しているようなものなので、汎化能力が非常に高い。コーパスに無い初見の単語でも確率0を与えないという汎化能力を持っている。今回のようなモデルではone-hotベクトルを利用するという性質上ベクトルがスパースになるという(おなじみの)問題は避けられない。今回のRNNアーキテクチャは単語の分散表現(embedding)ベクトルでも応用可能なのか、少し考えてみる必要はあるかもしれない。RNNは何も言語のために作られたモデルではないので、シーケンシャルなデータならなんでも応用できる。各タイムステップでの画像を入力にして動画を解析したり、株価の推移やFX取引のアルゴリズムとして使ったり、いろいろなことができそう。今はフルスクラッチで書かなくても、Chainerのような便利なライブラリがあるので、実践で使うならそちらの方が便利だろう。基礎を理解するのはいつでも大切なので、原理を理解する意味でフルスクラッチしてみるのも悪く無いかもね。コメントをキャンセルメールアドレスが公開されることはありません。