TensorFlow : Tutorials : Sequences : リカレント・ニューラルネットワーク (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
更新日時 : 07/16 (v1.9), 05/22/2018 (v1.8) ; 10/10/2016, 09/04/2016
作成日時 : 02/19/2016
* TensorFlow 1.9 でドキュメント構成が変わりましたので調整しました。
* 本ページは、TensorFlow 本家サイトの Tutorials – Sequences – Recurrent Neural Networks を翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
リカレント・ニューラルネットワーク と特に LSTM へのイントロダクションのためには この優れた記事 を見てください。
言語モデリング
このチュートリアルでは言語モデリングの挑戦的なタスクでリカレント・ニューラルネットワークをどのように訓練するかを示します。問題のゴールは文に確率を割り当てる確率モデルを最適化することです。以前の単語の履歴を与えられたテキストで次の単語を予測することで達成します。この目的のために Penn Tree Bank (PTB) を使用します。これは訓練するに小さくて比較的速く、これらのモデルのクオリティを測定するためのポピュラーなベンチマークです。
言語モデリングは、音声認識、機械翻訳あるいは画像キャプションのような多くの興味深い問題へのキーです。これらもまた、楽しみです – こちら をご覧ください。
このチュートリアルのために、Zaremba et al., 2014 (pdf) からの結果を再現します。これは PTB データセット上で非常に良い結果を達成しています。
(訳注 : )
Recurrent Neural Network Regularization
W. Zaremba, I. Sutskever, O. Vinyals
(Submitted on 8 Sep 2014 (v1), last revised 19 Feb 2015 (this version, v5))Abstract – LSTM ユニットを持つ RNN のための単純な正則化技術を提案します。Dropout – ニューラルネットワークを正則化するためのもっとも成功的な技術 – は RNN と LSTM では上手く動作しません。このペーパーでは、どのように dropout を LSTM に正しく適用するかを示し、様々なタスクで overfitting を実質的に減じることを示します。これらのタスクは言語モデル、音声認識、画像キャプション生成、そして機械翻訳を含みます。
チュートリアル・ファイル
このチュートリアルは TensorFlow models レポジトリ の models/tutorials/rnn/ptb からの次のファイルを参照します :
ファイル | 目的 |
ptb_word_lm.py | PTB データセット上で言語モデルを訓練するコード。 |
reader.py | データセットを読むコード。 |
データをダウンロードして準備する
このチュートリアルに必要なデータは Tomas Mikolov の web ページからの PTB データセット の data/ ディレクトリにあります。
データセットは既に前処理されて、文の最後のマーカーと珍しい単語のための特殊なシンボル (\<unk>) を含む、全体で 10000 の異なる単語を含みます。reader.py では、ニューラルネットワークがデータを処理することを簡単にするために、各単語を一意の整数識別子に変換します。
モデル
LSTM
モデルのコアは LSTM セルから構成されてこれは一度に 1 つの単語を処理してセンテンスの次の単語のための起こりうる値の確率を計算します。ネットワークのメモリ状態はゼロのベクトルで初期化されて各単語を読んだ後に更新されます。計算上の理由で、データをサイズ batch_size のミニバッチで処理します。このサンプルでは、current_batch_of_words は単語の “sentence” に対応していないことに注意することは重要です。バッチの総ての単語は time t に対応すべきです。TensorFlow は各バッチの勾配を貴方のために自動的に総計します。
例えば :
t=0 t=1 t=2 t=3 t=4 [The, brown, fox, is, quick] [The, red, fox, jumped, high] words_in_dataset[0] = [The, The] words_in_dataset[1] = [brown, red] words_in_dataset[2] = [fox, fox] words_in_dataset[3] = [is, jumped] words_in_dataset[4] = [quick, high] batch_size = 2, time_steps = 5
基本的な擬似コードは次のようなものです :
words_in_dataset = tf.placeholder(tf.float32, [time_steps, batch_size, num_features]) lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size) # Initial state of the LSTM memory. hidden_state = tf.zeros([batch_size, lstm.state_size]) current_state = tf.zeros([batch_size, lstm.state_size]) state = hidden_state, current_state probabilities = [] loss = 0.0 for current_batch_of_words in words_in_dataset: # The value of state is updated after processing each batch of words. output, state = lstm(current_batch_of_words, state) # The LSTM output can be used to make next word predictions logits = tf.matmul(output, softmax_w) + softmax_b probabilities.append(tf.nn.softmax(logits)) loss += loss_function(probabilities, target_words)
Truncated バックプロパゲーション
設計上、リカレント・ニューラルネットワーク (RNN) の出力は任意に離れた入力に依拠します。不幸なことに、これは backpropagation 計算を困難にします。学習プロセスを扱いやすくするために、ネットワークの “unrolled (展開された)” バージョンを作成することは一般的な方法で、これは LSTM 入力と出力の固定数 (num_steps) を含みます。それからモデルは RNN の有限の近似上で訓練されます。これは一度に長さ num_steps の入力を供給してそのような各入力ブロックの後で backward パスを遂行することにより実装可能です。
truncated backpropagation を遂行するグラフを作成するためのコードの単純化されたブロックがここにあります :
# Placeholder for the inputs in a given iteration. words = tf.placeholder(tf.int32, [batch_size, num_steps]) lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size) # Initial state of the LSTM memory. initial_state = state = tf.zeros([batch_size, lstm.state_size]) for i in range(num_steps): # The value of state is updated after processing each batch of words. output, state = lstm(words[:, i], state) # The rest of the code. # ... final_state = state
そしてこれがデータセット全体に渡る iteration をどのように実装するかです :
# A numpy array holding the state of LSTM after each batch of words. numpy_state = initial_state.eval() total_loss = 0.0 for current_batch_of_words in words_in_dataset: numpy_state, current_loss = session.run([final_state, loss], # Initialize the LSTM state from the previous iteration. feed_dict={initial_state: numpy_state, words: current_batch_of_words}) total_loss += current_loss
入力
単語 ID は LSTM に供給される前に密な表現(単語のベクタ表現チュートリアル 参照)に埋め込まれます。これはモデルに、特定の単語についての知識を効率的に表現することを可能にします。書くのもまた簡単です:
# embedding_matrix is a tensor of shape [vocabulary_size, embedding size] word_embeddings = tf.nn.embedding_lookup(embedding_matrix, word_ids)
埋め込み行列はランダムに初期化されてモデルはデータを単に見ることにより単語の意味を識別するために学習します。
損失関数
私達はターゲット単語の負の対数確率の平均を最小化することを望みます :
\[ \text{loss} = -\frac{1}{N}\sum_{i=1}^{N} \ln p_{\text{target}_i} \]
実装はそれほど難しいということはありませんが、関数 sequence_loss_by_example
は既に利用可能ですので、ここでは単に使用できます。
ペーパーで報告されている典型的な尺度は平均単語毎 (per-word) perplexity (単に perplexity とも)で、これは以下に等しいです
\[e^{-\frac{1}{N}\sum_{i=1}^{N} \ln p_{\text{target}_i}} = e^{\text{loss}} \]
そして私たちは訓練プロセスを通じてこの値をモニタします。
複数 LSTM をスタックする(積み重ねる)
モデルにより表現力を与えるために、データを処理するために LSTM の複数層を追加できます。第 1 層の出力は第 2 層の入力、等々になります。
私たちは MultiRNNCell と呼ばれるクラスを持ち、これは実装をシームレスにします :
def lstm_cell(): return tf.contrib.rnn.BasicLSTMCell(lstm_size) stacked_lstm = tf.contrib.rnn.MultiRNNCell( [lstm_cell() for _ in range(number_of_layers)]) initial_state = state = stacked_lstm.zero_state(batch_size, tf.float32) for i in range(num_steps): # The value of state is updated after processing each batch of words. output, state = stacked_lstm(words[:, i], state) # The rest of the code. # ... final_state = state
コードを実行する
コードを実行する前に、このチュートリアルの冒頭で議論されたように、PTB データセットをダウンロードします。それから、PTB データセットを貴方のホームディレクトリに次のように解凍します :
tar xvfz simple-examples.tgz -C $HOME
今、GitHub から TensorFlow models レポジトリ をクローンします。次のコマンドを実行します :
cd models/tutorials/rnn/ptb python ptb_word_lm.py --data_path=$HOME/simple-examples/data/ --model=small
チュートリアル・コードには3つのサポートされたモデル構成があります : “small”, “medium” そして “large” です。それらの違いは LSTM のサイズと訓練に使われるハイパーパラメータのセットにあります。
より大きなモデルは、より良い結果を得られるでしょう。small モデルはテストセット上で 120 以下の perplexity に達することができ、large モデルは 80 以下です、訓練に数時間かかるかもしれませんが。
What Next?
モデルを良くするための私たちが言及していない幾つかのトリックあります、これは次を含みます:
- 学習率を減少するスケジュール
- LSTM 層間のドロップアウト
コードを研究してモデルを更に改善するように修正しましょう。
以上