使用 Keras 进行视频预测(时间序列)
Posted
技术标签:
【中文标题】使用 Keras 进行视频预测(时间序列)【英文标题】:Using Keras for video prediction (time series) 【发布时间】:2017-07-26 19:06:32 【问题描述】:我想在给定N
前一帧的情况下预测(灰度)视频的下一帧 - 在 Keras 中使用 CNN 或 RNN。大多数关于时间序列预测和 Keras 的教程和其他信息在他们的网络中使用一维输入,但我的是 3D (N frames x rows x cols)
我目前真的不确定解决这个问题的好方法是什么。我的想法包括:
使用一个或多个 LSTM 层。这里的问题是我不确定它们是否适合将一系列图像而不是一系列标量作为输入。内存消耗不会爆炸吗?如果可以使用它们:如何在 Keras 中将它们用于更高维度?
在输入(先前视频帧的堆栈)上使用 3D 卷积。这引发了其他问题:当我不进行分类而是进行预测时,为什么这会有所帮助?如何堆叠层,使网络的输入具有维度(N x cols x rows)
,输出具有维度(1 x cols x rows)
?
我对 CNN/RNN 和 Keras 还很陌生,如果能提供任何正确方向的提示,我将不胜感激。
【问题讨论】:
【参考方案1】:所以基本上每种方法都有其优点和缺点。让我们仔细检查您提供的方法,然后再找出最佳方法:
LSTM
:它们最大的优势之一是能够学习数据中的长期依赖模式。它们的设计是为了能够分析长序列,例如语音或文字。由于数字参数可能非常高,这也可能导致问题。其他典型的循环网络架构,如GRU
可能会克服这个问题。主要缺点是,在他们的标准(顺序实现)中,将其拟合到视频数据上是不可行的,原因与密集层对图像数据不利的原因相同 - 时间和空间不变性的负载必须通过完全完全的拓扑来学习不适合以有效的方式捕捉它们。将视频向右移动一个像素可能会完全改变网络的输出。
值得一提的另一件事是,训练LSTM
被认为类似于在两个竞争过程之间找到平衡 - 为 dense-like 输出计算找到好的权重并找到一个好的处理序列中的内存动态。找到这种平衡可能会持续很长时间,但一旦找到 - 它通常会非常稳定并产生非常好的结果。
Conv3D
:它们最大的优势之一可能是在图像案例中以与Conv2D
相同的方式捕捉空间和时间不变性的能力。这使得维度灾难的危害性大大降低。另一方面 - 与Conv1D
相同,较长的序列可能不会产生好的结果 - 同样 - 缺乏任何记忆可能会使学习长序列变得更加困难。
当然可以使用不同的方法,例如:
TimeDistributed + Conv2D
:使用TimeDistributed
包装器 - 可以使用一些预训练的卷积网络,例如Inception
逐帧,然后依次分析特征图。这种方法的一个真正巨大的优势是迁移学习的可能性。作为一个缺点 - 人们可能会将其视为Conv2.5D
- 它缺乏对您的数据的时间分析。
ConvLSTM
:最新版本的Keras
(2017 年 3 月 6 日)尚不支持此架构,但正如大家所见,here 应该会在未来提供。这是LSTM
和Conv2D
的混合体,相信比堆叠Conv2D
和LSTM
更好。
当然这些不是解决这个问题的唯一方法,我会再提一个可能有用的方法:
-
堆叠:可以轻松堆叠上层方法以构建其最终解决方案。例如。可以构建一个网络,在开始时使用
TimeDistributed(ResNet)
转换视频,然后通过多个积极的空间池化将输出馈送到Conv3D
,最后由GRU/LSTM
层进行转换。
PS:
还有一点值得一提的是视频数据的形状实际上是4D
和(frames, width, height, channels
)。
PS2:
如果您的数据实际上是3D
和(frames, width, hieght)
,您实际上可以使用经典的Conv2D
(通过将channels
更改为frames
)来分析这些数据(这实际上可能在计算上更有效)。在迁移学习的情况下,您应该添加额外的维度,因为大多数CNN
模型都是使用形状为(width, height, 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)
【讨论】:
非常有用的信息,尤其是 TimeDistributed 层。我的视频数据的形状是 3D,因为只有一个通道,我应该重塑它吗?另外,您能否为 5. 方法提供一些(伪)代码来说明如何连接层?尺寸仍然让我感到困惑。非常感谢! 我还有一些其他问题。伪代码引用 nb_of_classes 但我不需要分类,而是下一个时间步的帧。没有更简单的解决方案吗?我还不需要迁移学习,只需要一个简单的网络,获取 N 个前帧并预测下一个帧。 明天我会回答吗?好吗? 我可以让 ConvLSTM2D 模型工作,但 InceptionV3 到 TimeDistributed 失败:ValueError: The shape of the input to "Flatten" is not fully defined (got (None, x, y, z)). Make sure you pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.
【参考方案2】:
经过大量研究,我终于偶然发现了Keras Example 用于ConvLSTM2D
层(Marcin Możejko 已经提到过),这正是我所需要的。
在当前版本的Keras(v1.2.2)中,已经包含了这一层,可以使用
from keras.layers.convolutional_recurrent import ConvLSTM2D
要使用该层,视频数据必须按以下格式进行:
[nb_samples, nb_frames, width, height, channels] # if using dim_ordering = 'tf'
[nb_samples, nb_frames, channels, width, height] # if using dim_ordering = 'th'
【讨论】:
渠道的价值应该是什么,是什么意思? 通道数表示 RGB 或灰度,即分别为 3 或 1 个通道。以上是关于使用 Keras 进行视频预测(时间序列)的主要内容,如果未能解决你的问题,请参考以下文章
使用 Keras LSTM 进行多步提前时间序列预测的多个输出