我想使用Keras中的CNN或RNN,根据前N
帧预测(灰度)视频的下一帧。大多数关于时间序列预测和Keras的教程及其他信息在其网络中使用了一维输入,但我的输入将是3D的(N帧 x 行 x 列)
。
目前我对解决这个问题的良好方法感到非常不确定。我的想法包括:
-
使用一个或多个LSTM层。这里的问题是我不确定它们是否适合接受一系列图像而不是一系列标量作为输入。内存消耗会不会激增?如果可以使用它们:我如何在Keras中使用它们来处理更高维度的数据?
-
对输入(前几帧视频的堆栈)进行3D卷积。这引发了其他问题:当我不是在进行分类而是预测时,为什么这会有所帮助?我如何堆叠层,使网络的输入维度为
(N x 列 x 行)
,输出维度为(1 x 列 x 行)
?
我对CNN/RNN和Keras还很新手,任何指引我正确的方向的建议都将不胜感激。
回答:
所以基本上每种方法都有其优点和缺点。让我们逐一分析你提供的方法,然后再探讨其他方法,以找到最佳方法:
-
LSTM
:其最大的优势之一是能够学习数据中的长期依赖模式。它们被设计用来分析长序列,如语音或文本。这也可能因为参数数量可能非常高而引起问题。其他典型的循环网络架构如GRU
可能可以克服这些问题。主要缺点是,在其标准(顺序实现)中,将其应用于视频数据是不可行的,原因与密集层不适合图像数据的原因相同——需要学习大量的时间和空间不变性,而这种拓扑结构完全不适合以有效的方式捕捉这些不变性。将视频向右移动一个像素可能会完全改变网络的输出。另一个值得一提的是,训练
LSTM
被认为类似于在两个竞争过程之间寻找平衡——为类似密集层的输出计算找到好的权重,以及在处理序列时找到好的内部记忆动态。找到这种平衡可能需要很长时间,但一旦找到,通常相当稳定,并且能产生非常好的结果。 -
Conv3D
:其最大的优势之一是能够以与图像情况下的Conv2D
相同的方式捕捉空间和时间不变性。这使得维度灾难的影响大大减小。另一方面,就像Conv1D
可能无法对较长的序列产生良好结果一样,缺乏任何记忆可能使学习长序列变得更加困难。
当然,人们可以使用不同的方法,如:
-
TimeDistributed + Conv2D
:使用TimeDistributed
包装器,人们可以逐帧使用一些预训练的卷积网络,如Inception
,然后顺序分析特征图。这种方法的一个巨大优势是可以进行迁移学习。作为缺点,人们可能会将其视为Conv2.5D
——它缺乏对数据的时间分析。 -
ConvLSTM
:这种架构在截至2017年3月6日的Keras
最新版本中尚未支持,但如这里所示,未来应该会提供。这是LSTM
和Conv2D
的混合,被认为比堆叠Conv2D
和LSTM
更好。
当然,这些并不是解决这个问题的唯一方法,我再提一种可能有用的方法:
- 堆叠:人们可以轻松地堆叠上述方法以构建最终解决方案。例如,人们可以构建一个网络,首先使用
TimeDistributed(ResNet)
转换视频,然后将输出馈送到具有多个和激进的空间池化的Conv3D
,最后由GRU/LSTM
层转换。
PS:
还值得一提的是,视频数据的实际形状是4D
,为(帧, 宽度, 高度, 通道)
。
PS2:
如果你的数据实际上是3D
的,形状为(帧, 宽度, 高度)
,你实际上可以使用经典的Conv2D
(通过将通道
更改为帧
)来分析这些数据(这实际上可能更具计算效率)。在进行迁移学习的情况下,你应该添加额外的维度,因为大多数CNN
模型是在形状为(宽度, 高度, 3)
的数据上训练的。人们可能会注意到你的数据没有3个通道。在这种情况下,通常使用的技术是将空间矩阵重复三次。
PS3:
这种2.5D
方法的一个例子是:
input = Input(shape=input_shape)base_cnn_model = InceptionV3(include_top=False, ..)temporal_analysis = TimeDistributed(base_cnn_model)(input)conv3d_analysis = Conv3D(nb_of_filters, 3, 3, 3)(temporal_analysis)conv3d_analysis = Conv3D(nb_of_filters, 3, 3, 3)(conv3d_analysis)output = Flatten()(conv3d_analysis)output = Dense(nb_of_classes, activation="softmax")(output)