LoginSignup
2
1

More than 5 years have passed since last update.

【LSTM】カオスなDuffing振動子をシミュレートして未来予測♬

Last updated at Posted at 2018-07-12

前回の話の当然の延長として、カオスなDuffing振動子の解をシミュレートして未来予測できるのかどうかはすごく興味がわく。
ということで、今回はそこをやってみました。

やったこと

(1)LSTMは過学習;単純な減衰振動の未来予測
(2)LSTMでシミュレート;5つのDuffing振動子の振る舞い
(3)未来予測;面倒な振る舞いを予測する

(1)LSTMは過学習;単純な減衰振動の未来予測

コードは以下に置きました。
LSTM/keras_lstm_sin.py
ここでコードの主要な部分は以下のとおり

tsteps = 1
batch_size = 25
epochs = 301
lahead = 2000

def gen_cosine_amp(amp=80, period=200, x0=0, xn=5000, step=1, k=0.0001):
    cos = np.zeros(((xn - x0) * step, 1, 1))
    for i in range(len(cos)):
        idx = x0 + i * step
        cos[i, 0, 0] = amp * (np.cos(2 * np.pi * idx / period))
        cos[i, 0, 0] = cos[i, 0, 0]* np.exp(-k * idx)
    return cos

cos = gen_cosine_amp()

expected_output = np.zeros((len(cos), 1))
output = np.zeros((len(cos), 1))
for i in range(len(cos) - lahead):
    expected_output[i, 0] = cos[i]
    expected_output1 = np.zeros((len(cos), 1))
output1 = np.zeros((len(cos), 1))
for i in range(len(cos)):
    expected_output1[i, 0] = cos[i]

model = Sequential()
model.add(LSTM(100,
               input_shape=(tsteps, 1),
               batch_size=batch_size,
               return_sequences=False,
               stateful=True,
              dropout=0.0))
model.add(Dense(1))
opt=Adam(lr=0.0001, beta_1=0.5, beta_2=0.999, epsilon=1e-08, decay=0.)
model.compile(loss='mse', optimizer=opt)   #'rmsprop')
model.summary()

そして結果は以下のとおりとなった。この図を見ると、どうも過学習になっているようだ。
pend0hidden100lahead2000.gif
そこでモデルのdropout=0.75, batch_size=50で以下の結果が得られた。最下段の規格化した形状はかなり再現できた。しかし、絶対値は全く再現せず、小さい。
pend075hidden100batch50lahead2000.gif

(2)LSTMでシミュレート;5つのDuffing振動子の振る舞い

コードは以下に置きました。
LSTM/keras_lstm_duffing.py
Duffing振動子の振る舞いはパラメータや初期値によっていろいろ変わるが、今回は参考で紹介されているパラメータの組み合わせで得られる5つの領域を調べた。
結果を見ると、dropoutの値を変化させてみたが、フィッティング精度は向上せず悪い。振動の周期やアップダウンの様子はある程度再現しているようだが、絶対値含め全体に未来予測の思惑ははずれたようだ。
Duffing0
plot_x-p_duffing.png
plot_duffing_300_lstm.png
Duffing1
plot_x-p_duffing.png
plot_duffing_300_lstm.png
Duffing2
plot_x-p_duffing.png
plot_duffing_300_lstm.png
Duffing3
plot_x-p_duffing.png
plot_duffing_300_lstm.png
Duffing4
plot_x-p_duffing.png
plot_duffing_300_lstm.png

(3)未来予測;面倒な振る舞いを予測する

とはいえ、単純な減衰振動のシミュレーションのときを考えると、dropout=0でlahead=1の場合の結果では絶対値含め予測できていた。
ということで、Duffing振動子の場合も同じようにやってみた。
Duffing0と類似の振る舞いは以下のとおり、絶対値含め再現できた。ということで、少なくとも1個先の未来は予測できたことになる。
plot_x-p_duffing.png
plot_duffing_600_lstm.png
しかし、この状態は上の5つの状態の中でも一番再現性がよかった部分なので、ある意味つまらない。そこで、上で一番壊滅的な結果であるDuffing4と類似の場合についてどこまでの未来を予測可能なのかをやってみた。
Duffing4 lahead=1 [0,200]
つまりこの領域でも1個未来は予測できた。
plot_x-p_duffing.png
Duffing4Drop0lahead1.gif
以下は100個未来予測できたことを示す。
Duffing4 lahead=100 [0,200]
Duffing4Drop0lahead100.gif
なんとなく上記の領域は安定的な振動にも見えるのでもう少し不安定そうな部分の予測をやってみた。
結果は以下の通り、最初は予測しているが、フィッティングが進むにつれて、過学習が発生して、予測精度が落ちていることが分かる。とはいえ、カオス的な振動の未来予測ができるということでとても驚いた。
Duffing4 lahead=100 t=[0,168]
Duffing4Drop0lahead100[0,168].gif
lahead=200にすると、最初は予測できているが、過学習が始まるとほんの一ピーク程度を除いて予測はほとんどできていない。
Duffing4 lahead=200 t=[0,168]
Duffing4Drop0lahead200[0,168].gif

まとめ

・カオスなDuffing振動子の未来予測ができた!
・LSTMは過学習を起こし、Dropoutすると絶対値予測が失われるようである

・Duffing振動子の領域の相図的な網羅性ができていないので、振る舞いのすべてを表現できていない(今回の領域も今一つ統一性が取れていない)
・位相空間の振る舞いは運動の指紋的なものであり、これで分類する手法を確立したい
・今回の手法は一般的なので幾つかの実際の系(株価、太陽活動、地震、天気など)に適用してみようと思う

・相図の参考
Duffing oscillator

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1