结合 CNN 和双向 LSTM

4 python conv-neural-network lstm keras tensorflow

我正在尝试结合 CNN 和 LSTM 进行图像分类。

我尝试了以下代码,但收到错误。我有 4 个课程需要训练和测试。

以下是代码:

from keras.models import Sequential
from keras.layers import LSTM,Conv2D,MaxPooling2D,Dense,Dropout,Input,Bidirectional,Softmax,TimeDistributed


input_shape = (200,300,3)
Model = Sequential()
Model.add(TimeDistributed(Conv2D(
            filters=16, kernel_size=(12, 16), activation='relu', input_shape=input_shape)))
Model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2),strides=2)))
Model.add(TimeDistributed(Conv2D(
            filters=24, kernel_size=(8, 12), activation='relu')))
Model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2),strides=2)))
Model.add(TimeDistributed(Conv2D(
            filters=32, kernel_size=(5, 7), activation='relu')))
Model.add(TimeDistributed(MaxPooling2D(pool_size=(2, 2),strides=2)))
Model.add(Bidirectional(LSTM((10),return_sequences=True)))
Model.add(Dense(64,activation='relu'))
Model.add(Dropout(0.5))
Model.add(Softmax(4))
Model.compile(loss='sparse_categorical_crossentropy',optimizer='adam')
Model.build(input_shape)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

“输入张量必须为 3、4 或 5 级,但为 {}。”.format(n + 2)) ValueError:输入张量必须为 3、4 或 5 级,但为 2。

Mar*_*ani 5

我在代码中发现了很多问题:

  1. 你的数据是4D的所以简单Conv2D就可以了,TimeDistributed不需要
  2. 你的输出是二维的,所以设置return_sequences=False在最后一个 LSTM 单元中
  3. 你的最后一层非常混乱:不需要在层输出和激活之间放置 dropout
  4. 你需要categorical_crossentropy而不是sparse_categorical_crossentropy因为你的目标是one-hot编码的
  5. LSTM 需要 3D 数据。所以你需要从 4D(卷积的输出)过渡到 3D。您可以采用两种可能性:1)进行重塑(batch_size,H,W *通道);2) (batch_size, W, H * 通道)。这样,您就可以在 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=(12, 16), activation='relu', input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))
model.add(Conv2D(filters=24, kernel_size=(8, 12), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))
model.add(Conv2D(filters=32, kernel_size=(5, 7), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2),strides=2))
model.add(Lambda(ReshapeLayer)) # <========== pass from 4D to 3D
model.add(Bidirectional(LSTM(10, activation='relu', return_sequences=False)))
model.add(Dense(nclasses,activation='softmax'))

model.compile(loss='categorical_crossentropy',optimizer='adam')
model.summary()
Run Code Online (Sandbox Code Playgroud)

这是正在运行的笔记本