Python 叠加卷积网络与递归层

Python 叠加卷积网络与递归层,python,keras,lstm,recurrent-neural-network,Python,Keras,Lstm,Recurrent Neural Network,我正在研究一种视频序列分类器。它应该在输入和输出一个标签(0或1)上获取多个视频帧。因此,这是一个多对一网络 我已经有了一个单帧分类器。此分类器使用Conv2D进行若干卷积,然后应用globalaveragepoolg2d。这将产生长度为64的1D向量。然后,原始每帧分类器有一个带有softmax激活的层 现在我想扩展这个分类器来处理序列。理想情况下,序列应该具有不同的长度,但现在我将长度固定为4 为了扩展我的分类器,我将用一个带有1个单元的LSTM层替换densed。所以,我的目标是让LSTM

我正在研究一种视频序列分类器。它应该在输入和输出一个标签(0或1)上获取多个视频帧。因此,这是一个多对一网络

我已经有了一个单帧分类器。此分类器使用
Conv2D
进行若干卷积,然后应用
globalaveragepoolg2d
。这将产生长度为64的1D向量。然后,原始每帧分类器有一个带有softmax激活的

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

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

示意图上,我现在拥有:

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)
])
结果是异常
索引器:列表索引超出范围

同样的例外

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

我做错了什么?

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

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