在Keras 和 Tensorflow 框架下五种视频分类的实施方法

来源:互联网 发布:windows loader 和kms 编辑:程序博客网 时间:2024/06/05 10:08

本文是翻译一篇大神的文章,点击查看原文,可能需要VPN才能查看。

  目前视频分类是机器学习模式中独树一帜的挑战。今天我们就要来看看在Keras 和 Tensorflow 框架下的不同的视频行为识别策略,我们将会学着如何使用五深度学习的模式去学习UCF101数据组,具体代码在GitHub,有需要可以下载来看看

视频分类的方法:

  我们将会轮流讲述这五种方法来看看哪一个能够达到最好的效果,我们会检验top1和top5的准确率(top5表示前五个的概率排名,这里采用的数据组就是UCF101):
1、用Convnet逐一划分帧
2、在一个网络中用一个时间分布式的Convnet并且传递这样的特征给RNN
3、使用3D的卷积网络
4、用Convnet从每一帧中提取特征,并且传递这个特征序列给另一个RNN
5、用Convnet从每一帧中提取特征,并且传递这个特征序列给另一个MLP

约束

  每个方法都有很多不同的拓展,所以我们将会利用一些约束来帮助简化他们,也同样减小将来应用在实际系统中的计算复杂性。
1、我们将不会用光流图像,我们考虑他们减弱了模型的复杂性、训练时间和超参数的整体负荷力度
2、每个视频将会被下采样到40帧,所以在41到500帧的视频都会通过基本的快进被减少到40帧之内
3、我们不会采用个多预处理的方式,视频分类通常的预处理步骤是减少中间值,但是我们将会保持它从头到尾的原始性
4、在新的 AWS p2.xlarge的实例中,每个模式必须要适用于12GiB的运存空间的GPU
  利用这些约束,我们不会达到最好的94%的准确率,但是我们可以知道我们是否找对了方向

数据准备:

  我们首先需要做的就是获取一个我们能够训练的数据集。我们需要完成下面的步骤:
1、区分文件为训练集还是测试集的文件
2、提取每个视频中的每一帧的JPEG图片
3、利用CSV方式(观察全部的训练过程的方式)通过视频类型、训练集或测试集状态、帧数去概括这些视频。
  需要注意的一点是,训练集中有很多的视频是很相似的。也就是说多个视频可能出现相同的人在相同的角度上有相同的动作。所以我们需要注意不要因为效果很好而停止探索,这有可能是训练集和测试集有相同的视频导致的。
  我们就用UCF提供的三种训练和测试集推荐分类,为了节省时间,我们仅仅使用第一个分类来进行我们的实验。

关于下列图表的注释:

  每个图表包括三个系列:
1、只用CNN,top1的准确率用红线表示(通常作为基准线)。
2、绿色为top5的绝对准确率
3、蓝色为top1的绝对准确率

方法零:随机猜测或者总是选择最普遍的

  这不是一个真正的方法,但是如果我们的模型不能找到比随机的或者最常用的方法更好的结果,我们就走错了方向。
  试着进行随机分来,准确率只有0.9%。得出这个结果是因为有101个分类···再加上数学的计算
  如果总是选择最普遍的类似于“网球摆动”(一个实验),它的准确率是1.32%。同样是因为网球摆动的成功例子是我们数据集的1.32%。这至少证明我们找对了方向,并且能够找到一些结果,接下来一起建立一些模型吧。

方法一:用CNN逐一给帧进行分类

  首要的方法,我们将忽略视频的时间特征,然后试着观察每一次帧的内容来分类。使用CNN,AKA ConvNet。更具体的说,我们将会采用Inception-V3,pre-trained on ImageNet这篇文章的内容
  我们将会使用迁移学习来重载训练我们的数据。这有两个步骤:
  首先,我们调整最密集的那一层训练10次(每次训练10240个图像),在进入深层之前调整最顶层让其尽可能保持以前的学习状态。奇怪的是,在这些层上训练时我们没有看到任何可观的准确率。但是没事,inception blocks是很难的部分,能做好这个就基本成功了。
  第二,我们重新学习最上面的两层的inception blocks,训练70次,我们可以看出来,结果达到了65%的准确率。
这里写图片描述

线top1绿top5

  值得注意的是我们逐一地观察每个独立的帧图像,并且仅仅基于一帧的内容给整个视频进行分类。我们没有观察所有的帧并且做任何的平均值或者最大值分类。
  让我们从测试集中随机检测几个样本图片,看看我们是怎么做的:
我们并没有看到
预测:跳高:0.37,体操:0.14,罚点球:0.09  实际上:玩儿双节棍   结果:失败
这里写图片描述
预测:墙壁俯卧撑:0.67,拳击吊带:0.09,杂耍球:0.08  实际上:墙壁俯卧撑   结果:第一个成功
这里写图片描述
预测:击鼓:1   实际上:墙壁俯卧撑   结果:第一个成功
这里写图片描述
预测:倒立行走:0.32,双节棍:0.16,跳绳:0.11  实际上:跳绳   结果:前五个中有成功

最后我们得出测试准确率:~65% top 1, ~90% top 5

方法二:在一个网络中,用时间分布式的CNN,传递这个特征给一个RNN

  现在,我们有一个良好的开端,我们将会转换模型,考虑把视频的时间特征考虑在内。在这个网络的第一层,我们将会采用Kera的非常好用的TimeDistributed封装,它可以允许我们分配一个CNN在时间维度上的层
  在这个模型的ConvNet 部分,我们将会用一个很小的VGG16-style网络。理想中,我们在这个部分用了一个更深的的网络,但是我们将必须要给GPU重载所有的内存,我们的选择是相当有限的。
  RNN的网络部分,我们使用三层的GRU,每层由128个节点组成,两层之前0.2的流失率。
  不像方法一我们使用预先训练好的ImageNet权重,这里我们必须在我们的数据上从头开始训练我们的模型。这将意味着我们需要大量的参数或者更大的网络来达到相同的准确率作为Inception模块的产出。然而这也意味着我们的CNN权重将会沿着RNN的每一个反向传递而更新。让我们来看看:
这里写图片描述

线绿top5线top1

  最终的测试结果: 20% top 1, 41% top 5

方法三:用3D卷积网络

  所以从头开始一起训练一个CNN和一个LSTM对我们没有多大用处。那3D卷积网络怎么样呢?
  对于视频分类来说,3D ConvNets是一个明显的选择,因为他们在三维空间(在我们的案例中第三维是时间维度)固有地运用卷积(和最大的池化)。(从技术上讲,这是4D,因为我们2D图像是代表了3D的向量,但是网络最终的结果是一样的)
  然而,他们有相同的缺点:方法二的内存!在 Learning Spatiotemporal Features with 3D Convolutional Networks中,作者设定一个叫C3D的网络对于UCF101达到52.8%的准确率。我很想试着去复制这些结果,但是因为GPU的内存限制停止了。简单的C3D都不能运行,即使是我砍掉了一层又一层。
  换计划,我设计了一个更小的模型(只有三个3D的卷积),逐渐增大节点数量,从32到64再到128。:
这里写图片描述
  在28次训练之后,我们甚至还不能达到我们设置的Inception的基准线。我把学习率从5e-5减到了1e-6,并且再多加了30次训练(没上图表),这样会变得好一点,但是仍然没有比较好的结果。
  可能从头到尾的训练这条路不好走,我们还是另辟蹊径吧。

  最终的测试结果:28% top 1, 51% top 5

方法四:用CNN提取特征传递序列给分离式的RNN

  既然Inception模块分类图像时做的很好,那我们为何不试着利用这个学习呢?在这个方法中,我们将会使用Inception模块的网络在视频中提取特征,并且传递给RNN。这需要两步骤:
  第一:我们通过Inception模块遍历视频所有的帧,然后保存最后网络中的池化层的输出。我们能够有效地去掉网络中的top分类,以便我们最后能够得到一个2048维的特征向量传递给我们的RNN。想了解更多,看之前文章 blog post on continuous video classification
  第二,我们转变那些提取的特征到序列中。如果你想起我们的约束,我们可以把每个视频转变成一个40帧的序列。所以我们把这40帧的样本拼接起来,并且保存到硬盘中,这样我们在训练不同的RNN网络模型时,每当我们读取相同的样品或者训练一个全新的网络架构,就不需要连续不断地传递我们的图像给CNN了。
  在RNN中,我们使用单独的4096宽的LSTM层,紧接一个1024密度的层并且附带一定的层间流失率。我试过,这个相当的浅层的网络胜过所有的多倍堆积的LSTMs。下面是做的结果:
这里写图片描述

方法五:从每帧图像中用CNN提取特征然后传递这些特征序列给一个MLP

  我们采用同之前一样的方法用CNN提取过程,但是我们不会把序列传递给RNN,我们将平滑序列,然后把新的输入向量(2048*40)传递给一个全连接的网络,名叫MLP(multilayer perceptron)。
我们假设MLP能够在不知道它是序列的情况下从序列的有机结合中推断出时间特征。
  在尝试了一些深的、浅的、宽的、窄的网络之后,我们发现性能最好的MLP是一个简单的两层网络,每层有512个神经元:
这里写图片描述
  另一个打败只有CNN基准的方法!但是几乎没有和RNN做的一样好的。我的直觉告诉我,在这个参数调整上可以做得更好。对于大多数的方法,我只给出了我们效果比较好的网络的结果,在MLP中,当我们尝试更深的和更宽的网络的时候我们发现,top1的准确率很不确定,但是top5的准确率都快好的爆表了。这是4层的,2048宽的MLP:
这里写图片描述
这个top5的准确率非常完美,但是并不是很符合题意。

最终结果:70% top 1, 88% top 5

最终胜出的是······

  用Inception ConvNet来提取特征,紧接一个单层的LSTM的RNN!
  总结:在UCF101中74%准确率不是最好的,目前我所能达到最好的是94%。但是,随着一个视频流(不是光流模型)预处理的减少,内存的限制和非常小的参数调整,我想我们已经列出了一些深入研究这五种分类方法的大体框架。
  我从这项研究中得出的主要结论是,卷积网络在广泛的任务中是多么强大。(这句真没看懂)……当只看单个的图像在65%的准确率是令人很吃惊的。使用这种方法为其他的模型提取图片可以得到满意的结果并且利用的内存也很少。
  第二个结论是我做了很多的工作。这使我感到很舒服,我也希望这篇文章可以给你很好的想法并且能够激励很多人去更好地探索视频分类的世界

具体代码在GitHub,有需要可以下载来看看

阅读全文
0 0
原创粉丝点击