【问题标题】:Stacking convolutional network and recurrent layer堆叠卷积网络和循环层
【发布时间】:2018-06-01 18:13:58
【问题描述】:

我正在开发视频序列的分类器。它应该在输入上接收几个视频帧并输出一个标签,0 或 1。因此,它是一个多对一的网络。

我已经有一个单帧分类器。该分类器使用Conv2D 进行多次卷积,然后应用GlobalAveragePooling2D。这会产生长度为 64 的一维向量。然后原始的每帧分类器有一个带有 softmax 激活的Dence 层。

现在我想扩展这个分类器来处理序列。理想情况下,序列应该具有不同的长度,但现在我将长度固定为 4。

为了扩展我的分类器,我将用 1 个单元的 LSTM 层替换 Dense。所以,我的目标是让 LSTM 层一个一个地获取几个长度为 64 的一维向量,并输出一个标签。

简而言之,我现在拥有的:

input(99, 99, 3) - [convolutions] - features(1, 64) - [Dense] - [softmax] - label(1, 2)

所需架构:

4x { input(99, 99, 3) - [convolutions] - features(1, 64) } - [LSTM] - label(1, 2)

我不知道如何使用 Keras。

这是我的卷积代码

from keras.layers import Conv2D, BatchNormalization, GlobalAveragePooling2D, \
LSTM, TimeDistributed

IMAGE_WIDTH=99
IMAGE_HEIGHT=99
IMAGE_CHANNELS=3

convolutional_layers = Sequential([
    Conv2D(input_shape=(IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS),
           filters=6, kernel_size=(3, 3), strides=(2, 2), activation='relu',
           name='conv1'),
    BatchNormalization(),
    Conv2D(filters=64, kernel_size=(1, 1), strides=(1, 1), activation='relu',
           name='conv5_pixel'),
    BatchNormalization(),
    GlobalAveragePooling2D(name='avg_pool6'),
])

总结如下:

In [24]: convolutional_layers.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv1 (Conv2D)               (None, 49, 49, 6)         168
_________________________________________________________________
batch_normalization_3 (Batch (None, 49, 49, 6)         24
_________________________________________________________________
conv5_pixel (Conv2D)         (None, 49, 49, 64)        448
_________________________________________________________________
batch_normalization_4 (Batch (None, 49, 49, 64)        256
_________________________________________________________________
avg_pool6 (GlobalAveragePool (None, 64)                0
=================================================================
Total params: 896
Trainable params: 756
Non-trainable params: 140

现在我想要一个循环层来处理这些 64 维向量的序列并为每个序列输出一个标签。

我在手册中读到TimeDistributed 层将其输入层应用于输入数据的每个时间片。

我继续我的代码:

FRAME_NUMBER = 4

td = TimeDistributed(convolutional_layers, input_shape=(FRAME_NUMBER, 64))
model = Sequential([
    td,
    LSTM(units=1)
])

结果是异常IndexError: list index out of range

同样的例外

td = TimeDistributed(convolutional_layers, input_shape=(None, FRAME_NUMBER, 64))

我做错了什么?

【问题讨论】:

  • 当您传递一系列图像时,您的时间分布输入形状将是shape=(FRAME_NUM, W, H, C),64 是多少?一丝错误也会有所帮助。
  • 每个传递的图像都与Conv2D + GlobalAvgPooling2D 进行卷积并变成长度为64的一维向量。我希望LSTM对这些向量进行分类,而不是输入图像。
  • 你混淆了时间分布,如果你对conv_layers进行时间分布,那么它将这些层应用于每个输入图像,输出是shape=(F_NUM, 64)不是输入。

标签: python keras lstm recurrent-neural-network


【解决方案1】:

将 cmets 扩展到答案; TimeDistributed 层将给定层应用于输入的每个时间步。因此,您的 TimeDistributed 将应用于提供输入 shape=(F_NUM, W, H, C) 的每一帧。将卷积应用于每张图像后,您会返回 (F_NUM, 64),这是每一帧的特征。

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 2012-03-06
    • 2019-09-08
    • 2020-11-22
    • 1970-01-01
    相关资源
    最近更新 更多