簡単な周期関数をLSTMネットワークに学習させ、予測させてみる。
環境
- python:3.6.0 (Anaconda 4.3.1)
- keras:2.0.1
- tensorflow: 1.0.1
予測させる周期関数
今回予測させる周期的な関数は、 周期の異なるsinとcosの和で作る。 (下図上段のオレンジと黄の曲線)
この周期関数 は以下の式で表される。 $$ y = \sin(\frac{\pi x}{20}) + \cos(\frac{\pi 3 x}{20}) $$ (下図中段の赤い曲線)
なお、そのまま学習させるとあまりにも簡単なので、
ノイズを混ぜた曲線を学習させることにした。
(上図下段の青い曲線)
データ作成
from random import random import numpy as np x = np.arange(0, 2000) data = np.sin(np.pi*x/20) + np.cos(np.pi*x*3/20) # 予測させたい周期関数 data_noised = [d * (0.75+0.5*random()) for d in data] # ノイズを混ぜる
モデル
- 入力層
- 過去100の時刻のデータ(ベクトル)を入れる。
- 中間層は一層のみ(30ユニット)。
- 非常に単純な構造。
- 出力層
- スカラ値
イメージとしては、過去の時刻から現在までの全てのデータを入力したら、 現在の1つ先のデータが出力される感じ。
from keras.models import Sequential from keras.layers.core import Dense, Activation from keras.layers.recurrent import LSTM in_out_neurons = 1 hidden_neurons = 30 model = Sequential() model.add(LSTM(hidden_neurons, return_sequences=False, input_shape=(None, in_out_neurons))) model.add(Dense(in_out_neurons, input_dim=hidden_neurons)) model.add(Activation("linear")) model.compile(loss="mean_squared_error", optimizer="rmsprop")
________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm_18 (LSTM) (None, 30) 3840 _________________________________________________________________ dense_18 (Dense) (None, 1) 31 _________________________________________________________________ activation_18 (Activation) (None, 1) 0 ================================================================= Total params: 3,871.0 Trainable params: 3,871.0 Non-trainable params: 0.0 _____________________________
学習
誤差の変化
60epoch程度で収束している。
予測した曲線の変化
5 epochのときの予測曲線
10 epochのときの予測曲線
20 epochのときの予測曲線
40 epochのときの予測曲線
60 epochのときの予測曲線
LSTMで周期関数の予測ができた。 次はもう少し複雑な系列データを予測してみたい。