TensorFlowメモ(RNNその1)
RNN(Recurrent Neural Network)を試してみる。
以下のサイトを参考にさせていただいた。
第6回 リカレントニューラルネットワークの実装(2)|Tech Book Zone Manatee
正弦波の時系列データ5つ(tからt+4)の値をもとに、t+5の値を予測する。
インプットデータ
- 周波数0.01の純音データを200個分し、5個分を1セットとして、196セット
- トレーニング用に9割、検証用に1割を割り当てるとして、176セットが学習用、20セットが検証用
検証
- 検証用の「20」セットを使って評価
- 損失関数は学習と同じ(「最小二乗法」)
RNNの設定
- Cellは「tf.contrib.rnn.BasicRNNCell」
- 隠れ層のユニット数は「20」
- 最後の出力に対して重みとバイアスを与える
(参考)kerasで書き直したモデルをmodel.summary()で表示
学習で更新されるパラメータ数の内訳
# simple_rnn_1 Layer weight(input) : 1row * 20col = 20 weight(state) : 20row * 20col = 400 bias : 20 # dense_1 Layer weight : 20row * 1col bias : 1
認識精度は以下のとおり推移した。
('epoch:', 0, ' validation loss:', 0.36871427) ('epoch:', 1, ' validation loss:', 0.2549196) ('epoch:', 2, ' validation loss:', 0.13921228) ('epoch:', 3, ' validation loss:', 0.067716144) ('epoch:', 4, ' validation loss:', 0.05464934) ... ('epoch:', 95, ' validation loss:', 0.00034664402) ('epoch:', 96, ' validation loss:', 0.0004254885) ('epoch:', 97, ' validation loss:', 0.0003979026) ('epoch:', 98, ' validation loss:', 0.00039949064) ('epoch:', 99, ' validation loss:', 0.0003302602)
学習後、適当な入力を与えて予測させてみる。
t=30における入力と正解、予測値
# 入力 training value X[30] : [0.95105652 0.92977649 0.90482705 0.87630668 0.84432793] # 正解 training value Y[30] : 0.809016994375 # 予測 estimate value : 0.8363162
RNN Cell内部のパラメータの形状を確認してみる。
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=20) print(basic_cell.variables)
出力
[<tf.Variable 'RNN/basic_rnn_cell/kernel:0' shape=(21, 20) dtype=float32_ref>, <tf.Variable 'RNN/basic_rnn_cell/bias:0' shape=(20,) dtype=float32_ref>]
この部分に関しては以下のサイトが分かりやすい。
"inputに対する重み"と"stateに対する重み"を結合したものが"kernel"に該当する。
python - internal variables in BasicRNNCell - Stack Overflow
inputとkernelの演算を図にすると以下のとおり。
Wがinputに対する重み、Uがstateに対する重みに該当する。
inputと重みの演算結果にバイアスを加え、活性化関数(デフォルトはtanh)を通したものを次の時系列のインプットとする。
LSTMについては下記ご参照。
TensorFlowメモ(RNNその2) - ichou1のブログ