LSTMで三角関数を組み合わせた周期関数を予測してみる

簡単な周期関数をLSTMネットワークに学習させ、予測させてみる。

環境
  • python:3.6.0 (Anaconda 4.3.1)
  • keras:2.0.1
  • tensorflow: 1.0.1

予測させる周期関数

今回予測させる周期的な関数は、 周期の異なるsinとcosの和で作る。 (下図上段のオレンジと黄の曲線)

この周期関数 {y} は以下の式で表される。 {} $$ y = \sin(\frac{\pi x}{20}) + \cos(\frac{\pi 3 x}{20}) $$ (下図中段の赤い曲線)

f:id:yusuke_ujitoko:20170411205932p:plain

なお、そのまま学習させるとあまりにも簡単なので、
ノイズを混ぜた曲線を学習させることにした。
(上図下段の青い曲線)

データ作成
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程度で収束している。

f:id:yusuke_ujitoko:20170411214721p:plain

予測した曲線の変化

5 epochのときの予測曲線

f:id:yusuke_ujitoko:20170411214432p:plain

10 epochのときの予測曲線

f:id:yusuke_ujitoko:20170411214454p:plain

20 epochのときの予測曲線

f:id:yusuke_ujitoko:20170411214548p:plain

40 epochのときの予測曲線

f:id:yusuke_ujitoko:20170411214613p:plain

60 epochのときの予測曲線

f:id:yusuke_ujitoko:20170411214649p:plain

LSTMで周期関数の予測ができた。 次はもう少し複雑な系列データを予測してみたい。