Video Understanding(视频理解,I3D,SlowFast,Non-local)

在这里插入图片描述
CV领域图像已经登天很难逐渐完善,视频也开始蓬勃发展。由于早期限制于数据集和计算设备,多是从图像的2D模型直接转换成3D版本,如SIFT 3D,3D HOG,或者Dense Trajectory这种统治了很久的模型等,等到深度学习开始步入新的周期,数据集也开始扩增出现UCF101,ActivityNet,Charades,YouTube8M,Kinetics等等,也就出现了更优秀的视频理解模型3D CNN,Two-Stream Network,C3D,TSN,I3D,Slow-Fast Networks。而时下图神经网络很火,所以也有GraphLSTM,ST-Graph等等的工作。

  • 目标:学出一个通用的视频表示以支撑下游任务。
  • 挑战:比起图像,时序特征非常重要,并不是把2D图片堆叠起来,如何更好的利用时序信息(temporal information)。
  • 下游任务:基本上图片能做的,都可以往视频上靠,比如视频推荐,视频检索,视频分割Video Segmentation,Activity Detection,Video Caption,Video Question Answering。按层次分可以有:pixel(每个像素分类类别)–region(动作发生的空间位置)–clip(动作时间段定位)–video(识别视频内容,动作分类)–language(生成视频描述)。因为视频的时序很重要,比较有特色的就是:动作和运动预测,物体移动轨迹预测,视频预测模型架构等方向。

Improved Dense Trajectory(IDT)
Action Recognition with Improved Trajectory,ICCV2013.。非神经网络模型(Pre-Deep Learning),但在视频届拥有统治级的视频理解模型。
在这里插入图片描述
DT方法通过网格划分的方式在图片的多个尺度上分别密集采样特征点,然后在多个空间尺度上采样能保证采样的特征点覆盖了所有空间位置和尺度,最后tracking特征点抽取特征。即DT的关键部分有3点:

  • Dense。通过多尺度金字塔放缩以得到更丰富的特征(一般8个尺度足够了) 。
  • Trajectory。Tracking每个尺度的密集特征点轨迹(间隔w一般为5),以理解每个部分是怎么在时序方向上进行移动的。
  • HOF,HOG和MBH。方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。 HOF(Histogramsof Oriented Optical Flow)与HOG类似,是对光流方向进行加权统计,得到光流方向信息直方图。MBH( Motion Boundary Histograms)特征是分别在图像的x和y方向光流图像上计算HOG特征。计算完后,还需要进行特征的归一化,DT算法中对HOG,HOF和MBH均使用L2范数归一化。

而iDT主要改进在于对光流图像的优化,特征正则化方式的改进以及特征编码方式的改进。详见LIN大神的源码笔记

优点:iDT算法作为深度学习之前最好的行为识别算法,有着优良的效果和很好的鲁棒性。其中有很多非常值得借鉴的思路,比如相机运动引起的背景光流的消除,比如沿着轨迹提取特征的思路。
缺点:特征维度高(特征比原始视频还要大),算起来慢,延迟十几倍倍左右,无法做到实时。

DeepVideo
深度学习的早期尝试。Large-scale Video Classification with Convolutional Neural Networks,CVPR2014。
在这里插入图片描述
大多数的场景发生在图像中部,所以可以分两条线:

  • 一条是全局的context stream,输入空间大小下采样减半的图像。
  • 另一条是fovea stream只关心中心局部的信息,输入原图中心裁剪后的图像(两条线孪生,即共享同一个网络)。
  • 然后通过Slow fusion模型,在整个网络中缓慢融合时间信息的两种方法之间的平衡混合,使得更高层在空间和时间维度上逐渐获得更多的全局信息。

Optical Flow based Approaches
DeepVideo是深度学习步入视频的初期研究,虽然用了深度学习,但其效果被IDT吊打近20个百分点,其最可能的原因是没有足够的利用时序信息,即它只是把一堆图片扔进网络,没有重点图片帧的关系。而为了关于捕捉时序关系,主流有两个主要的方法:1是Optical Flow based 2是3D-CNN based Approaches。
Two-stream Network
Two-Stream Convolutional Networks for Action Recognition in Videos,NIPS2014.
在这里插入图片描述
首先在空间部分(spatial),即单个帧图片上的外观形式,它能描绘视频的场景和目标信息。其自身静态外表是一个很有用的线索,因为一些动作很明显地与特定的目标有联系。而在时间部分(temporal),以多帧上的运动形式,表达了观察者(摄像机)和目标者的运动。但是如何更好的利用时序信息呢?光流。

  • 光流是图片前后两帧中像素的移动方向,其好处在于考虑像素的移动方向后,就不需要考虑实际图片中的clothes,color,appearance,background,只要做了动作如投球,那么对于投球动作的移动是类似的,这就天然的滤去了很多无关的信息,只聚焦在动作本身上。

所以Two-stream方法巧妙的利用光流信息,即网络本身并没有对temporal建模,而是利用optical flow来体现时序上的关系,然后再输入到神经网络做映射,这种方法就取得了很好的效果。具体如上图,采用两个分支。

  • 一个分支输入单帧图像,用于提取图像信息,即在做图像分类。
  • 另一个分支输入连续10帧的光流(optical flow)运动场,用于提取帧之间的运动信息。
  • 两个分支网络结构相同,分别用softmax进行预测,最后用直接平均或SVM两种方式融合两分支结果。

跟随Two-stream,又出现了Deeper two-stream(变得更深,网络做的更精细),two-stream+Trajectory(结合起iDT的传统轨迹方法),two-stream+LSTM(时序用LSTM),two-stream fusion(CVPR2015)等等提升的工作。

缺点:光流需要提前算(目前有方法使用自监督AE尝试学习光流),对光流的存储和读取IO都很大,在网络中也算的慢,不是最优(算了就固定了,或许端到端更好)。

Temporal Segment Networks(TSN)
Temporal Segment Networks: Towards Good Practices for Deep Action Recognition,ECCV2016。
在这里插入图片描述
如何进一步提高two stream方法?由于光流信息只是前后帧像素的移动方向,1s往往就有30帧甚至更多,而一个动作的完成前后帧显然太少了。同时作者发现视频的连续帧之间存在冗余,因此想到用稀疏采样代替密集采样,也就是说在对视频做抽帧的时候采取较为稀疏的抽帧方式,这样可以去除一些冗余信息,同时降低了计算量。

TSN的结构由上图所示,一个输入视频被分为 K 段(segment),一个片段(snippet)从它对应的段中随机采样得到,然后对这些片段进行Temporal Segment,网络部分是由双路CNN组成的,分别是spatial stream ConvNets和temporal stream ConvNets。不同片段的类别得分采用段共识函数(The segmental consensus function,如图中的小绿条和小蓝条),也就是该snippet属于每个类的得分。

3D-CNN based Approaches
除了曲线救国用Optical Flow based体现时序信息,另一方面就是把2DCNN升级,变成3D-CNN based Approaches。首先就是C3D,Learning Spatiotemporal Feature with 3D Convolutional Networks,ICCV2015。
在这里插入图片描述
C3D,想要得到时序上的关系,那么把时序也纳入卷积,即二维卷积变三维,实现可以看作是3D版VGG,直观直白也暴力。3×3×3卷积核的均匀设置是3D ConvNets的最佳选择,模型架构如下,所有3D卷积滤波器均为3×3×3,步长为1×1×1。为了保持早期的时间信息设置pool1核大小为1×2×2、步长1×2×2,其余所有3D池化层均为2×2×2,步长为2×2×2。每个全连接层有4096个输出单元。
在这里插入图片描述
优点:相比其他类型的方法,C3D一次处理多帧,所以计算效率很高。
缺点:相比2D CNN,3D CNN的参数量很大,训练变得更困难,模型深度不能很深,需要更多的大量训练数据。

class C3D(nn.Module):
    # C3D模型的实现挺简单的。想要得到时序上的关系,那么把时序也纳入卷积,即二维卷积变三维,实现可以看作是3D版VGG
    def __init__(self):
        super(C3D, self).__init__()
        # 所有3D卷积滤波器均为3×3×3,步长为1×1×1
        self.conv1 = nn.Conv3d(3, 64, kernel_size=(3, 3, 3), padding=(1, 1, 1))
        # 为了保持早期的时间信息,pool1有些许不同
        self.pool1 = nn.MaxPool3d(kernel_size=(1, 2, 2), stride=(1, 2, 2))

        self.conv2 = nn.Conv3d(64, 128, kernel_size=(3, 3, 3), padding=(1, 1, 1))
        self.pool2 = nn.MaxPool3d(kernel_size=(2, 2, 2), stride=(2, 2, 2))

        self.conv3a = nn.Conv3d(128, 256, kernel_size=(3, 3, 3), padding=(1, 1, 1))
        self.conv3b = nn.Conv3d(256, 256, kernel_size=(3, 3, 3), padding=(1, 1, 1))
        self.pool3 = nn.MaxPool3d(kernel_size=(2, 2, 2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值