数值错误:输入0与层lstm_1不兼容:期望的 ndim=3,实际得到的 ndim=2 [Keras]

3

我使用以下代码出现了错误:ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=2,这与LSTM层的预期维度为3而实际数据维度为2有关。

def make_model():
  model = Sequential()      

  model.add(Conv2D(20,(5,5), input_shape = (24,48,30), activation = "relu", strides = 1, padding = "valid"))
  model.add(MaxPooling2D(pool_size=(2,2)))        
  model.add(Conv2D(50, (5,5), use_bias = 50))    
  model.add(MaxPooling2D(pool_size=(2,2)))    
  model.add(Flatten())
  model.add(Dense(20, activation = "relu"))
  model.add(LSTM(50, activation="relu", return_sequences=True))

  return model

我的输入是30个大小为24 * 48的矩阵。


尝试使用 input_shape=(24, 48) - George
不行,那个不起作用。出现错误 ValueError: 输入 0 与层 conv2d_1 不兼容:期望 ndim=4,但发现 ndim=3 - yamini goel
乔治是正确的,你不应该在模型中指定数据的数量。如果问题仍然存在,请参考:https://machinelearningmastery.com/reshape-input-data-long-short-term-memory-networks-keras/。 - Mete Han Kahraman
请检查您在model.fit()调用中提供的x_train和x_validation,它们的大小应为(30,24,48),而不是(24,48,30)。input_shape = (24,48,30) 应该改为 input_shape = (24,48)。 - Mete Han Kahraman
@yaminigoel:X_train的形状是什么? - George
@George,我对机器学习这个领域非常陌生,这是我的第一个模型,所以请原谅我提出的愚蠢问题和回答。我有点困惑于X_train的形状。我的问题是我有很多用户,每个用户都有30个形状为(24,48)的矩阵。现在,对于一个用户,我想从模型中得到一个答案。因此,理想情况下,X_train的形状应该是(24,48),但是对于这30个矩阵,我只需要一个输出。我认为我要么改变X_train的形状,要么修改模型。 - yamini goel
1个回答

6
问题在于最后一个 Dense 层(在 lstm 层之前)的输出形状是 (?, 20),而 lstm 层需要 3D 张量,而非 2D。因此,在输入到 lstm 层之前需要扩展维度。
您可以使用 tf.expand_dims 扩展维度(假设您使用 tensorflow 作为后端)。tf expand
input_layer = Input((30,24,48))

model = Conv2D(20,(5,5), input_shape = (30,24,48), activation = "relu", strides = 1, padding = "valid")(input_layer)
model = MaxPooling2D(pool_size=(2,2))(model)        
model = Conv2D(50, (5,5), use_bias = 50)(model)    
model = MaxPooling2D(pool_size=(2,2))(model)  
model = Flatten()(model)
model = Dense(20, activation = "relu")(model)
model = tf.expand_dims(model, axis=-1)
model = LSTM(50, activation="relu", return_sequences=True)(model)

我没有使用顺序模式,而是使用 函数式 API,因为它更加灵活。

如果想要使用顺序模型:

    model = Sequential()      

    model.add(Conv2D(20,(5,5), input_shape = (30, 24, 48), activation = "relu", strides = 1, padding = "valid"))
    model.add(MaxPooling2D(pool_size=(2,2)))        
    model.add(Conv2D(50, (5,5), use_bias = 50))    
    model.add(MaxPooling2D(pool_size=(2,2)))    
    model.add(Flatten())
    model.add(Dense(20, activation = "relu"))
    model.add(Lambda(lambda x: tf.expand_dims(model.output, axis=-1)))
    model.add(LSTM(50, activation="relu", return_sequences=True))

Lambda 内部,您必须使用 expand_dims


如果我使用函数式API,它可以正常工作,但在Sequential模式下,它会给我以下错误TypeError: Failed to convert object of type <class 'keras.engine.sequential.Sequential'> to Tensor. Contents: <keras.engine.sequential.Sequential object at 0x7f44e3530668>. Consider casting elements to a supported type.,因为model = tf.expand_dims(model, axis=-1)。我需要使用Sequential模式,你能帮我解决吗? - yamini goel
嗨@George!你的回答解决了我的问题。我在某个层面上有点困惑,我相信你可以回答我。我有“n”个大小相等的向量,如何将它们组合起来以馈送到RNN中。我的意思是向量是2d的,我有n个这样的2d向量,我需要将它们发送到一个RNN中,你能告诉我如何实现吗?另外,我不希望将它们连接起来,我需要将“n”个特定大小的向量输入到RNN层中。 - yamini goel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接