简体   繁体   English

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

[英]Why do I get a Keras LSTM RNN input_shape error?

I keep getting an input_shape error from the following code. 我不断从以下代码中获取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

All of the above runs smoothly. 以上所有都顺利进行。 This is where it goes wrong. 这是它出错的地方。

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)

It returns this error. 它返回此错误。

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

When I check the website it says to specify a tuple "(eg (100,) for 100-dimensional inputs)." 当我检查网站时,它说要指定一个元组“(例如(100,)用于100维输入)。”

That being said, my data set consists of one column with a length of 10320. I assume that that means that I should be putting (10320,) in as the input_shape, but I get the error anyways. 话虽这么说,我的数据集由一列长度为10320组成。我认为这意味着我应该把(10320,)作为input_shape,但我仍然得到错误。 Does anyone have a solution? 有没有人有办法解决吗?

My understanding is that both your input and your output are one dimensional vectors. 我的理解是你的输入和输出都是一维向量。 The trick is to reshape them per Keras requirements: 诀窍是根据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)

Here are the key points: 以下是要点:

  • when you add your first layer, you are required to specify the number of hidden nodes, and your input shape. 添加第一个图层时,需要指定隐藏节点的数量和输入形状。 Consequent layers don't require the input shape as they can infer it from the hidden nodes of the previous layer 后续图层不需要输入形状,因为它们可以从前一层的隐藏节点推断出它
  • Similarly, for your output layer you only specify the number of output nodes 同样,对于输出层,您只需指定输出节点的数量

Hope this helps. 希望这可以帮助。

Some more information: when using RNN (like LSTM) with sequences of variable length you have to take of the format of your data. 更多信息:当使用具有可变长度序列的RNN(如LSTM)时,您必须采用数据格式。

When you group sequences in order to pass it to the fit method, keras will try to build a matrix of samples, which implies that all input sequences must have the same size, otherwise you won't have a matrix of the correct dimension. 当您对序列进行分组以将其传递给fit方法时,keras将尝试构建样本矩阵,这意味着所有输入序列必须具有相同的大小,否则您将不具有正确维度的矩阵。

There several possible solutions: 有几种可能的解决方案

  1. train your network using samples one by one (using fit_generator for example) 逐个使用样本训练您的网络(例如使用fit_generator)
  2. pad all your sequences so they have the same size 填充所有序列,使它们具有相同的大小
  3. group sequences by size (eventually padding them) and train your network group by group (again using generator based fit) 按大小对序列进行分组(最终填充它们)并按组训练您的网络组(再次使用基于生成器的拟合)

The third solution corresponds to the most common strategy with variable size. 第三种解决方案对应于可变大小的最常见策略。 And if you pad sequences (second or third solution) you may want to add a masking layer as input. 如果你填充序列(第二或第三个解决方案),你可能想要添加一个掩蔽层作为输入。

If you're not sure, try to print the shape of your data (using the shape attribute of the numpy array.) 如果您不确定,请尝试打印数据的形状(使用numpy数组的shape属性。)

You may need to look at: https://keras.io/preprocessing/sequence/ (pad_sequences) and https://keras.io/layers/core/#masking 您可能需要查看: https ://keras.io/preprocessing/sequence/(pad_sequences)和https://keras.io/layers/core/#masking

Following is the working version with Keras 2.0.0 , Modified radix's code 以下是使用Keras 2.0.0 ,Modified radix代码的工作版本

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)

Try to use the LSTM layer without specifying the input shape. 尝试使用LSTM图层而不指定输入形状。 Let Keras do the work for you. 让Keras为你工作。 I think you commented the masking as well because your getting similar issue. 我认为你也评论了掩蔽,因为你得到了类似的问题。 I faced it before and it turns out the input_shape = (time_steps, input_dim). 我之前遇到过它,结果是input_shape =(time_steps,input_dim)。 I think this happens due to the new automatic shape inference in Keras. 我认为这是因为Keras的新自动形状推断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM