デジタル・デザイン・ラボラトリーな日々

アラフィフプログラマーが数学と物理と英語を基礎からやり直す。https://qiita.com/yaju

TensorFlow 2.xによる sin波予測

はじめに

時系列データを使用した予測をやりたいと思って、良さげな教材が下記サイトになります。
qiita.com qiita.com

記事自体が、2016~2017年ということで少し古いですが、機械学習のリハビリもかねて動かしてみました。

環境

  • Google Colaboratory
  • TensorFlow 2.1.0-rc1

現時点(2019/12/30)ではGoogle Colaboratoryでは標準で「TensorFlow 2.x」になってないですが、もうすぐなると思います。
下記コードを入力することで「TensorFlow 2.x」に切り替えることができます。

%tensorflow_version 2.x
import tensorflow as tf
print(tf.__version__)

ソース

説明

4000件(50 x 80)のノイズ入りのサイン関数データを用意します。
左図は全体、右図は先頭160件(80 x 2)です。
f:id:Yaju3D:20191231204538p:plain

これを訓練データ、テストデータに分類し、100ステップ分の入力Xがあった際の出力yが101ステップ目になる様なデータセットを作ります。
この「100ステップ分の入力Xがあった際の出力yが101ステップ目になる」をしている意味がよく分からなくて悩んでいたところ、下記サイトに「普通の regression と異なるのは、履歴 sequence から next value を予測することです。」と書かれていて、なるほどと思いました。
https://tensorflow.classcat.com/2016/09/17/sine-wave-prediction-by-rnn-lstm/

つまり、1~100の履歴値の予測値は101番目の値、2~101の履歴値の予測値は102番目の値、3~102の履歴値の予測値は103番目の値というようにするわけです。

訓練データは、全体の9割 4000 \times (1 - 0.1) = 3600 件で、テストデータは残りの 400 件となります。

in_out_neurons = 1
hidden_neurons = 300

model = Sequential()  
model.add(tf.keras.layers.LSTM(hidden_neurons, batch_input_shape=(None, length_of_sequences, in_out_neurons), return_sequences=False))  
model.add(Dense(in_out_neurons))  
model.add(Activation("linear"))

ニューラルネットの構造は model にさまざまなレイヤを add() することで構築できます。
300個の LSTM 中間層に投げ、それを1個の出力層に集約し、linear 活性化関数を掛け合わせています。

model.compile(loss="mean_squared_error", optimizer="rmsprop")

modelのコンパイル時に、誤差関数(平均二乗誤差)、最適化アルゴリズム(RMSprop)を指定しています。

学習データを用いた予測は、predict() を用いて行います。

predicted = model.predict(X_test) 

dataf =  pd.DataFrame(predicted[:200])
dataf.columns = ["predict"]
dataf["input"] = y_test[:200]
dataf.plot(figsize=(15, 5))

予測値と入力値の 200 件分を同時に表示します。

最後に

ちゃんと中身を理解していかないとですね。

スポンサーリンク