为啥我会收到 Keras LSTM RNN input_shape 错误?

Posted

技术标签:

【中文标题】为啥我会收到 Keras LSTM RNN input_shape 错误?【英文标题】:Why do I get a Keras LSTM RNN input_shape error?为什么我会收到 Keras LSTM RNN input_shape 错误? 【发布时间】:2016-07-04 07:33:54 【问题描述】:

我不断收到以下代码中的 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)

当我检查 the website 时,它说要指定一个元组“(例如 (100,) 用于 100 维输入)。”

话虽如此,我的数据集由长度为 10320 的一列组成。我认为这意味着我应该将 (10320,) 作为 input_shape 放入,但我还是得到了错误。有人有解决办法吗?

【问题讨论】:

这个运气好吗? 不,伙计。这是一场悲剧。因为这个,我不得不去咨询。我坏了。 发现这个 - 似乎你必须手动执行 epochs(代码的最后一点):github.com/fchollet/keras/blob/master/examples/stateful_lstm.py 如果它有效,那就是黄金。我会尽快测试的 【参考方案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)

以下是重点:

添加第一层时,需要指定隐藏节点的数量和输入形状。后续层不需要输入形状,因为它们可以从前一层的隐藏节点推断出来 同样,对于您的输出层,您只需指定输出节点的数量

希望这会有所帮助。

【讨论】:

【参考方案2】:

更多信息:当使用具有可变长度序列的 RNN(如 LSTM)时,您必须采用数据格式。

当您对序列进行分组以将其传递给 fit 方法时,keras 将尝试构建样本矩阵,这意味着所有输入序列必须具有相同的大小,否则您将没有正确的矩阵维度。

有几种可能的解决方案:

    使用样本一个一个地训练您的网络(例如使用 fit_generator) 填充所有序列,使它们具有相同的大小 按大小对序列进行分组(最终填充它们)并按组训练您的网络(再次使用基于生成器的拟合)

第三种解决方案对应于最常见的可变大小策略。如果您填充序列(第二种或第三种解决方案),您可能需要添加一个遮罩层作为输入。

如果不确定,请尝试打印数据的形状(使用 numpy 数组的 shape 属性。)

您可能需要查看:https://keras.io/preprocessing/sequence/ (pad_sequences) 和 https://keras.io/layers/core/#masking

【讨论】:

【参考方案3】:

以下是Keras 2.0.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)

【讨论】:

【参考方案4】:

尝试在不指定输入形状的情况下使用 LSTM 层。让 Keras 为您完成工作。我认为您也评论了掩蔽,因为您遇到了类似的问题。我之前遇到过它,结果是 input_shape = (time_steps, input_dim)。我认为这是由于 Keras 中新的自动形状推断而发生的。

【讨论】:

以上是关于为啥我会收到 Keras LSTM RNN input_shape 错误?的主要内容,如果未能解决你的问题,请参考以下文章

使用Keras与LSTM和RNN进行斗争

Keras之RNN和LSTM

Keras 如何处理单元格和隐藏状态(RNN、LSTM)的初始值以进行推理?

keras---cnn---rnn---lstm

将 gridsearchCV 与 Keras RNN-LSTM 一起使用时出现尺寸错误

Tensorflow RNN LSTM 输出解释