【问题标题】:Connecting CNN to RNN将 CNN 连接到 RNN
【发布时间】:2020-07-16 12:58:11
【问题描述】:

我想训练一个神经网络来对简单的视频进行分类。我的方法是使用输出连接到 RNN (LSTM) 的 CNN。我在尝试将两者连接在一起时遇到了一些问题。

X_train.shape
(2400, 256, 256, 3)

Y_train.shape
(2400, 6)

这是我定义的网络

model = Sequential()
model.add(Conv2D(32 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu' , input_shape = (256,256,3)))
model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))

model.add(Conv2D(64 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu'))
model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))

model.add(Conv2D(128 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu'))
model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))

model.add(Conv2D(256 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu'))
model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))

model.add(Flatten())

model.add(layers.LSTM(64, return_sequences=True, input_shape=(1,256)))

model.add(layers.LSTM(32, return_sequences=True))

model.add(layers.LSTM(32))

model.add(layers.Dense(6, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

我收到以下错误

ValueError: Input 0 of layer lstm_7 is incompatible with the layer: expected ndim=3, found ndim=2. Full shape received: [None, 65536]

我感觉这与 RNN 的输入形状有关。目的是让 CNN 获取帧的特征,然后 RNN 获取帧之间的高级差异。用两个完全不同的网络来做这件事会更好吗?如果是这样,我该如何实现?还有一种方法可以用批量数据训练这两个网络,因为它非常大。

【问题讨论】:

    标签: python tensorflow keras deep-learning neural-network


    【解决方案1】:

    问题在于传递给 LSTM 的数据,它可以在您的网络内部解决。它需要 3D,而使用 Flatten 您正在破坏它。您可以采用两种可能性:1)重塑(batch_size, H, W*channel); 2)(batch_size, W, H*channel)。通过这种方式,您可以在 LSTM 中使用 3D 数据。下面是一个例子

    model = Sequential()
    model.add(Conv2D(32 , (3,3) , strides = 1 , padding = 'same' , 
                     activation = 'relu' , input_shape = (256,256,3)))
    model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))
    
    model.add(Conv2D(64 , (3,3) , strides = 1 , padding = 'same' , 
                     activation = 'relu'))
    model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))
    
    model.add(Conv2D(128 , (3,3) , strides = 1 , padding = 'same' , 
                     activation = 'relu'))
    model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))
    
    model.add(Conv2D(256 , (3,3) , strides = 1 , padding = 'same' , 
                     activation = 'relu'))
    model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same'))
    
    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.add(Lambda(ReshapeLayer))
    model.add(LSTM(64, return_sequences=True))
    model.add(LSTM(32, return_sequences=True))
    model.add(LSTM(32))
    
    model.add(Dense(6, activation='softmax'))
    
    model.compile(loss='categorical_crossentropy', optimizer='adam', 
                  metrics=['accuracy'])
    model.summary()
    

    【讨论】:

      【解决方案2】:

      你说的很对。在 tensorflow 中,LSTM 需要一个形状为 (batch_size, time_steps, embedding_size) 的输入,有关更多详细信息,请参阅 example。在您的情况下,请尝试使用 model.add(Reshape((16, 16*256))) 而不是 model.add(Flatten())。不是最漂亮的解决方案,但它可以让您进行测试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-28
        • 2017-08-29
        • 2019-02-01
        • 1970-01-01
        • 2020-09-30
        • 2020-06-07
        相关资源
        最近更新 更多