suzuzusu日記

(´・ω・`)

KerasのstatefulなLSTMのtrain出力を記録する

忘備録として書く.

FAQ - Keras Documentation からstatefulなRNN系だと学習や予測時に状態を更新してしまうので,単純に同じデータを入力して出力を得ることはできない.

そこでメトリック経由で出力を得る.

# 教師データ
def true(y_true, y_pred):
    return y_true[0]

# 出力データ
def pred(y_true, y_pred):
    return y_pred[0]

上記のようにカスタムメトリックから無理矢理出力を得る.あとはmetricsとして追加すればいい.

model.compile(loss='mean_squared_error', optimizer='rmsprop', metrics=[true, pred])

以下,正弦波の予測のExample

import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, LSTM

def true(y_true, y_pred):
    return y_true[0]

def pred(y_true, y_pred):
    return y_pred[0]

T = 30
f = 1/T
N = 10000
hidden_unit = 30

model = Sequential()
model.add(LSTM(hidden_unit, stateful=True, batch_input_shape=(1, 1, 1), return_sequences=True))
model.add(LSTM(hidden_unit, stateful=True, return_sequences=True))
model.add(LSTM(hidden_unit, stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='rmsprop', metrics=[true, pred])

# logger
true_log = np.zeros(N)
pred_log = np.zeros(N)

# train
for i in range(N):
    x = np.sin(2*np.pi*i*f)
    t = np.sin(2*np.pi*(i+1)*f)
    history = model.train_on_batch(np.array(x).reshape(1, 1, 1), np.array(t).reshape(1,1))
    true = history[1]
    pred = history[2]
    true_log[i] = true
    pred_log[i] = pred

# plot
plt.plot(true_log[N-3*T:], label='true')
plt.plot(pred_log[N-3*T:], label='prediction')
plt.legend()
plt.show()

f:id:suzuzusu:20180317071711p:plain

すごい無理矢理感があるので,誰かもっと良い方法を知っていたら教えてほしい.