web-dev-qa-db-ja.com

ミニバッチトレーニングとオンラインテスト用のKerasを使用したLSTM

時系列予測をストリーミングするために、KerasにLSTMを実装したいと思います。つまり、オンラインで実行し、一度に1つのデータポイントを取得します。 これはここでよく説明されています しかし、当然のことながら、オンラインLSTMのトレーニング時間は非常に遅くなる可能性があります。ミニバッチでネットワークをトレーニングし、オンラインでテスト(実行予測)したいと思います。 Kerasでこれを行うための最良の方法は何ですか?

たとえば、ミニバッチは、連続するタイムステップで発生する1000個のデータ値([33, 34, 42, 33, 32, 33, 36, ... 24, 23])のシーケンスである可能性があります。ネットワークをトレーニングするために、形状(900, 100, 1)の配列Xを指定しました。ここで、長さ100の900のシーケンスと、形状(900, 1)の配列yがあります。例えば。、

X[0] = [[33], [34], [42], [33], ...]]
X[1] = [[34], [42], [33], [32], ...]]
...
X[999] = [..., [24]]

y[999] = [23]

したがって、各シーケンスX[i]には、時系列の次の値、つまり予測したい値を表す対応するy[i]があります。

テストでは、次のデータ値1000〜1999を予測します。これを行うには、1000〜1999の各ステップの形状(1, 100, 1)の配列をフィードし、モデルが次のステップで値を予測しようとします。

これは私の問題に対して推奨されるアプローチとセットアップですか?ステートフルネスを有効にすることは、純粋にオンラインでの実装に進む方法かもしれませんが、Kerasでは、トレーニングとテストで一貫したbatch_input_shapeが必要です。これは、ミニバッチでトレーニングしてからオンラインでテストするという私の意図では機能しません。または私がこれを行うことができる方法はありますか?

更新:@nemo推奨としてネットワークを実装しようとしています

ブログ投稿のサンプルネットワークで独自のデータセットを実行しました "LSTMリカレントニューラルネットワークを使用した時系列予測Python with Keras" 、次に予測の実装を試みましたステートフルネットワークとしてのフェーズ。

モデルの構築とトレーニングはどちらも同じです。

# Create and fit the LSTM network
numberOfEpochs = 10
look_back = 30
model = Sequential()
model.add(LSTM(4, input_dim=1, input_length=look_back))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, nb_Epoch=numberOfEpochs, batch_size=1, verbose=2)
# trainX.shape = (6883, 30, 1)
# trainY.shape = (6883,)
# testX.shape = (3375, 30, 1)
# testY.shape = (3375,)

バッチ予測は次の方法で行われます。

trainPredict = model.predict(trainX, batch_size=batch_size)
testPredict = model.predict(testX, batch_size=batch_size)

ステートフル予測フェーズを試すために、以前と同じモデルのセットアップとトレーニングを実行しましたが、次のようにしました。

w = model.get_weights()
batch_size = 1
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
trainPredictions, testPredictions = [], []
for trainSample in trainX:
    trainPredictions.append(model.predict(trainSample.reshape((1,look_back,1)), batch_size=batch_size))
trainPredict = numpy.concatenate(trainPredictions).ravel()
for testSample in testX:
    testPredictions.append(model.predict(testSample.reshape((1,look_back,1)), batch_size=batch_size))
testPredict = numpy.concatenate(testPredictions).ravel()

結果を調べるために、以下のプロットは、実際の(正規化された)データを青で、トレーニングセットの予測を緑で、テストセットの予測を赤で示しています。

Results for batch prediction

Results from stateful prediction

最初の図はバッチ予測の使用によるもので、2番目の図はステートフルによるものです。私が間違ってやっているアイデアはありますか?

14
BoltzmannBrain

私があなたを正しく理解しているなら、あなたはあなたが訓練の後にステートフルネスを可能にすることができるかどうか尋ねています。はい、これは可能であるはずです。例えば:

net = Dense(1)(SimpleRNN(stateful=False)(input))
model = Model(input=input, output=net)

model.fit(...)

w = model.get_weights()
net = Dense(1)(SimpleRNN(stateful=True)(input))
model = Model(input=input, output=net)
model.set_weights(w)

その後、ステートフルな方法で予測できます。

10
nemo