结合 CNN 和双向 LSTM

2024-03-15

我正在尝试结合 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)

我收到以下错误:

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


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

  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()

这是正在运行的笔记本 https://colab.research.google.com/drive/1emyZ228yTNs8w2LuALo3Uuw2Dfg-CV3j?usp=sharing

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结合 CNN 和双向 LSTM 的相关文章

随机推荐