【问题标题】:Passing output of a CNN to BILSTM将 CNN 的输出传递给 BILSTM
【发布时间】:2020-12-26 14:20:39
【问题描述】:

我正在做一个项目,我必须将 CNN 的输出传递给双向 LSTM。我创建了如下模型,但它抛出“不兼容”错误。请让我知道我哪里出了问题以及如何解决这个问题


    model = Sequential()
    model.add(Conv2D(filters = 16, kernel_size = 3,input_shape = (32,32,1)))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2,2),strides=1, padding='valid'))
    model.add(Activation('relu'))
    
    model.add(Conv2D(filters = 32, kernel_size=3))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Activation('relu'))
    
    model.add(Dropout(0.25))
    model.add(Conv2D(filters = 48, kernel_size=3))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Activation('relu'))
    
    model.add(Dropout(0.25))
    model.add(Conv2D(filters = 64, kernel_size=3))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    
    model.add(Dropout(0.25))
    model.add(Conv2D(filters = 80, kernel_size=3))
    model.add(BatchNormalization())
    model.add(Activation('relu'))
    
    model.add(Bidirectional(LSTM(150, return_sequences=True)))
    model.add(Dropout(0.3))
    model.add(Bidirectional(LSTM(96)))
    model.add(Dense(total_words/2, activation='relu', kernel_regularizer=regularizers.l2(0.01)))
    model.add(Dense(total_words, activation='softmax'))
    
    model.summary()

返回的错误是:


    ValueError                                Traceback (most recent call last)
    <ipython-input-24-261befed7006> in <module>()
         27 model.add(Activation('relu'))
         28 
    ---> 29 model.add(Bidirectional(LSTM(150, return_sequences=True)))
         30 model.add(Dropout(0.3))
         31 model.add(Bidirectional(LSTM(96)))
    
    5 frames
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/input_spec.py in assert_input_compatibility(input_spec, inputs, layer_name)
        178                          'expected ndim=' + str(spec.ndim) + ', found ndim=' +
        179                          str(ndim) + '. Full shape received: ' +
    --> 180                          str(x.shape.as_list()))
        181     if spec.max_ndim is not None:
        182       ndim = x.shape.ndims
    
    ValueError: Input 0 of layer bidirectional is incompatible with the layer: expected ndim=3, found ndim=4. Full shape received: [None, 1, 1, 80]

【问题讨论】:

    标签: python tensorflow keras lstm conv-neural-network


    【解决方案1】:

    问题在于传递给LSTM 的数据,它可以在您的网络内部解决。 LSTM 需要 3D 数据,而 Conv2D 产生 4D。您可以采用两种可能性:

    1)重塑(batch_size, H, W*channel);

    2)重塑(batch_size, W, H*channel)

    通过这些方式,您可以在 LSTM 中使用 3D 数据。下面是一个例子

    def ReshapeLayer(x):
        
        shape = x.shape
        
        # 1 possibility: H,W*channel
        reshape = Reshape((shape[1],shape[2]*shape[3]))(x)
        
        # 2 possibility: W,H*channel
        # transpose = Permute((2,1,3))(x)
        # reshape = Reshape((shape[1],shape[2]*shape[3]))(transpose)
        
        return reshape
    
    model = Sequential()
    model.add(Conv2D(filters = 16, kernel_size = 3, input_shape = (32,32,3)))
    model.add(Lambda(ReshapeLayer))  # <============
    model.add(LSTM(16))
    model.add(Dense(units=2, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam',)
    model.summary()
    

    【讨论】:

      【解决方案2】:

      Conv2D 具有二维输入/输出,但 LSTM 采用一维输入。这就是为什么它期望 3 个维度(Batch、Sequence、Hid)但找到 4 个维度(Batch、X、Y、Hid)。解决方案是例如在 CNN 之后和 LSTM 之前使用Flatten 层将输出投影到一维序列。

      【讨论】:

      • 感谢您对此进行调查。添加 flatten 会使输出变为 2D。所以我仍然遇到不兼容问题。错误消息 - “图层双向输入 0 与图层不兼容:预期 ndim=3,发现 ndim=2。收到完整形状:[None, 80]”。有什么想法吗?
      猜你喜欢
      • 1970-01-01
      • 2023-03-15
      • 2018-02-13
      • 2012-11-29
      • 1970-01-01
      • 2015-04-12
      • 2020-08-04
      • 1970-01-01
      相关资源
      最近更新 更多