使用Keras进行视频预测(时间序列)
Using Keras for video prediction (time series)
我想预测给定 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)
?
我是 CNNs/RNNs 和 Keras 的新手,非常感谢任何关于正确方向的提示。
所以基本上每种方法都有其优点和缺点。让我们仔细检查您提供的方法和其他方法以找到最佳方法:
LSTM
:它们最大的优势之一是能够学习数据中的长期依赖模式。它们的设计是为了能够分析长序列,例如语音或文本。这也可能会导致问题,因为数字参数可能非常高。其他典型的循环网络架构,如 GRU
可能会克服这个问题。主要缺点是,在他们的标准(顺序实现)中,由于密集层对图像数据不利的相同原因,将其安装在视频数据上是不可行的——时间和空间不变性的负载必须通过完全是不适合以有效的方式捕捉它们。将视频向右移动一个像素可能会完全改变网络的输出。
另一件值得一提的事情是,训练 LSTM
被认为类似于在两个竞争过程之间找到平衡 - 为 dense-like[=82= 找到合适的权重] 输出计算并在处理序列中找到良好的内部内存动态。找到这种平衡可能会持续很长时间,但一旦找到 - 它通常会非常稳定并产生非常好的结果。
Conv3D
:在它们最大的优势中,人们可能很容易发现能够以与图像案例中的 Conv2D
相同的方式捕捉空间和时间不变性。这使得维数诅咒的危害小得多。另一方面 - 与 Conv1D
相同的方式可能不会用更长的序列产生好的结果 - 同样地 - 缺乏任何记忆可能会使学习长序列更加困难。
当然可以使用不同的方法,例如:
TimeDistributed + Conv2D
:使用 TimeDistributed
包装器 - 可以使用一些预训练的卷积网络,例如Inception
framewise 然后按顺序分析特征图。这种方法的一个真正巨大的优势是迁移学习的可能性。作为一个缺点 - 人们可能会将其视为 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)
经过大量研究,我终于偶然发现了 ConvLSTM2D
层的 Keras Example(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'
我想预测给定 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)
?
我是 CNNs/RNNs 和 Keras 的新手,非常感谢任何关于正确方向的提示。
所以基本上每种方法都有其优点和缺点。让我们仔细检查您提供的方法和其他方法以找到最佳方法:
LSTM
:它们最大的优势之一是能够学习数据中的长期依赖模式。它们的设计是为了能够分析长序列,例如语音或文本。这也可能会导致问题,因为数字参数可能非常高。其他典型的循环网络架构,如GRU
可能会克服这个问题。主要缺点是,在他们的标准(顺序实现)中,由于密集层对图像数据不利的相同原因,将其安装在视频数据上是不可行的——时间和空间不变性的负载必须通过完全是不适合以有效的方式捕捉它们。将视频向右移动一个像素可能会完全改变网络的输出。另一件值得一提的事情是,训练
LSTM
被认为类似于在两个竞争过程之间找到平衡 - 为 dense-like[=82= 找到合适的权重] 输出计算并在处理序列中找到良好的内部内存动态。找到这种平衡可能会持续很长时间,但一旦找到 - 它通常会非常稳定并产生非常好的结果。Conv3D
:在它们最大的优势中,人们可能很容易发现能够以与图像案例中的Conv2D
相同的方式捕捉空间和时间不变性。这使得维数诅咒的危害小得多。另一方面 - 与Conv1D
相同的方式可能不会用更长的序列产生好的结果 - 同样地 - 缺乏任何记忆可能会使学习长序列更加困难。
当然可以使用不同的方法,例如:
TimeDistributed + Conv2D
:使用TimeDistributed
包装器 - 可以使用一些预训练的卷积网络,例如Inception
framewise 然后按顺序分析特征图。这种方法的一个真正巨大的优势是迁移学习的可能性。作为一个缺点 - 人们可能会将其视为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)
经过大量研究,我终于偶然发现了 ConvLSTM2D
层的 Keras Example(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'