web-dev-qa-db-ja.com

Keras LSTM RNN input_shapeエラーが発生するのはなぜですか?

次のコードからinput_shapeエラーが発生し続けます。

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM

def _load_data(data):
    """
    data should be pd.DataFrame()
    """
    n_prev = 10
    docX, docY = [], []
    for i in range(len(data)-n_prev):
        docX.append(data.iloc[i:i+n_prev].as_matrix())
        docY.append(data.iloc[i+n_prev].as_matrix())
    if not docX:
        pass
    else:
        alsX = np.array(docX)
        alsY = np.array(docY)
        return alsX, alsY

X, y = _load_data(dframe)
poi = int(len(X) * .8)
X_train = X[:poi]
X_test = X[poi:]
y_train = y[:poi]
y_test = y[poi:]

input_dim = 3

上記のすべてがスムーズに実行されます。これはそれがうまくいかないところです。

in_out_neurons = 2
hidden_neurons = 300
model = Sequential()
#model.add(Masking(mask_value=0, input_shape=(input_dim,)))
model.add(LSTM(in_out_neurons, hidden_neurons, return_sequences=False, input_shape=(len(full_data),)))
model.add(Dense(hidden_neurons, in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, nb_Epoch=10, validation_split=0.05)

このエラーを返します。

Exception: Invalid input shape - Layer expects input ndim=3, was provided with input shape (None, 10320)

ウェブサイト をチェックすると、タプルを指定するように指示されています「(たとえば、100次元入力の場合は(100、)」)。

そうは言っても、私のデータセットは長さ10320の1つの列で構成されています。つまり、input_shapeとして(10320,)を入力する必要があると思いますが、とにかくエラーが発生します。誰かが解決策を持っていますか?

13
Ravaal

私の理解では、入力と出力の両方が1次元ベクトルです。秘訣は、Kerasの要件に従ってそれらを再形成することです。

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
import numpy as np

X= np.random.Rand(1000)
y = 2*X

poi = int(len(X) * .8)
X_train = X[:poi]
y_train = y[:poi]

X_test = X[poi:]
y_test = y[poi:]

# you have to change your input shape (nb_samples, timesteps, input_dim)
X_train = X_train.reshape(len(X_train), 1, 1)
# and also the output shape (note that the output *shape* is 2 dimensional)
y_train = y_train.reshape(len(y_train), 1)


#in_out_neurons = 2 
in_out_neurons = 1

hidden_neurons = 300
model = Sequential()
#model.add(Masking(mask_value=0, input_shape=(input_dim,)))
model.add(LSTM(hidden_neurons, return_sequences=False, batch_input_shape=X_train.shape))
# only specify the output dimension
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, nb_Epoch=10, validation_split=0.05)

# calculate test set MSE
preds = model.predict(X_test).reshape(len(y_test))
MSE = np.mean((preds-y_test)**2)

重要なポイントは次のとおりです。

  • 最初のレイヤーを追加するときは、隠れノードの数と入力形状を指定する必要があります。後続のレイヤーは、前のレイヤーの隠れノードから推測できるため、入力シェイプを必要としません。
  • 同様に、出力レイヤーについては、のみ出力ノードの数を指定します

お役に立てれば。

4
Radix

いくつかの詳細情報:可変長のシーケンスでRNN(LSTMなど)を使用する場合は、データの形式を考慮する必要があります。

シーケンスをグループ化してfitメソッドに渡すと、kerasはサンプルの行列を作成しようとします。つまり、すべての入力シーケンスは同じサイズである必要があります。そうしないと、正しい次元の行列が得られません。

いくつかの可能な解決策があります:

  1. サンプルを1つずつ使用してネットワークをトレーニングします(たとえば、fit_generatorを使用)
  2. 同じサイズになるようにすべてのシーケンスをパディングします
  3. シーケンスをサイズでグループ化し(最終的にはパディング)、ネットワークをグループでトレーニングします(ここでもジェネレータベースのフィットを使用)

3番目のソリューションは、可変サイズの最も一般的な戦略に対応します。また、シーケンスをパディングする場合(2番目または3番目のソリューション)、入力としてマスキングレイヤーを追加することをお勧めします。

よくわからない場合は、データの形状を印刷してみてください(numpy配列のshape属性を使用)。

あなたは見る必要があるかもしれません: https://keras.io/preprocessing/sequence/ (pad_sequences)と https://keras.io/layers/core/#masking ==

2
Marwan Burelle

以下は、Keras 2.0.、変更された基数のコードを使用した作業バージョンです。

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
import numpy as np

X= np.random.Rand(1000)
y = 2 * X

poi = int(len(X) * .8)
X_train = X[:poi]
y_train = y[:poi]

X_test = X[poi:]
y_test = y[poi:]

# you have to change your input shape (nb_samples, timesteps, input_dim)
X_train = X_train.reshape(len(X_train), 1, 1)
# and also the output shape (note that the output *shape* is 2 dimensional)
y_train = y_train.reshape(len(y_train), 1)

# Change test data's dimension also.
X_test = X_test.reshape(len(X_test),1,1)
y_test = y_test.reshape(len(y_test),1)


#in_out_neurons = 2
in_out_neurons = 1

hidden_neurons = 300
model = Sequential()
# model.add(Masking(mask_value=0, input_shape=(input_dim,)))
# Remove batch_input_shape and add input_shape = (1,1) - Imp change for Keras 2.0.0
model.add(LSTM(hidden_neurons, return_sequences=False, input_shape=(X_train.shape[1],X_train.shape[2])))
# only specify the output dimension
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.summary()
model.fit(X_train, y_train, epochs=10, validation_split=0.05)

# calculate test set MSE
preds = model.predict(X_test).reshape(len(y_test))
print(preds)
MSE = np.mean((preds-y_test)**2)
print('MSE ', MSE)
2
Shakti

入力形状を指定せずにLSTMレイヤーを使用してみてください。 Kerasにあなたのために仕事をさせてください。同様の問題が発生したため、マスキングについてもコメントしたと思います。私は前にそれに直面しました、そしてそれはinput_shape =(time_steps、input_dim)であることがわかりました。これは、Kerasの新しい自動形状推論が原因だと思います。

0
mxy