2014年之前,如果你想让计算机看懂一段视频里的人在做什么,最靠谱的办法不是深度学习。
这句话现在听起来有点奇怪。毕竟深度学习在图像识别领域已经杠杠的了,2012年AlexNet横扫ImageNet比赛,把错误率从26%砍到15%,整个学术圈都被震了一下。但这股风潮吹到视频领域,却撞了墙。
当时视频动作识别领域最强的方法,叫做**密集轨迹**
(资料图片)
> 密集轨迹(Dense Trajectories):一种手工设计的特征提取方法,通过跟踪视频里密集分布的点随时间的运动轨迹,再手工计算这些轨迹周围的图像特征,来判断视频里发生了什么动作。
在标准测试集UCF-101上,密集轨迹能做到88%左右的准确率,而当时能找到的深度学习方案,普遍卡在65%到70%之间,差了将近20个百分点。
20个百分点是什么概念?意味着每5个动作里,深度学习就要比手工方法多认错1个。这在学术圈是很难看的差距,尤其是深度学习在图像上已经证明了自己。大家开始怀疑,视频这个领域是不是有什么深度学习学不来的东西。
牛津大学的Karen Simonyan和Andrew Zisserman盯上了这个问题。他们俩当时同在VGG实验室,几个月后就发表了后来大名鼎鼎的VGGNet。也就是说,他们一边在死磕如何把卷积网络做得更深更强,一边在琢磨视频这个更难的战场怎么打。这两件事不是巧合,是同一批人在同一时间段,从两个角度攻打深度学习的边界。
问题出在哪:视频比图片多了一个维度
要理解他们的解法,得先搞清楚视频到底比图片难在哪。
一张图片,卷积网络要学的是空间信息:这里有个轮子的形状,那里有个人脸的轮廓,靠这些空间模式拼出"这是一辆车"或者"这是一个人"的判断。
视频不一样。视频除了空间信息,还有时间信息,也就是画面是怎么随时间变化的。同样一张"人抬起腿"的静止画面,你根本判断不出这个人是在踢球、在跨栏、还是刚从椅子上站起来。要分辨这些动作,你必须看到腿是往哪个方向移动、移动得多快。
早期把卷积网络搬到视频上的做法,通常是把视频的多帧图像堆叠起来,直接扔给一个3D卷积网络,让网络自己去学习时间和空间的规律。听起来挺合理,但效果不好。原因很简单:从原始像素堆叠里,直接学出"运动"这个概念,对网络来说太难了。像素的变化里混杂了太多噪声,光照变化、摄像机抖动、背景杂物移动,网络很难从这堆信息里提炼出真正有用的运动模式。
这就好比让一个从没学过物理的人,直接看着一堆散乱的连续照片,去推算出物体的速度和加速度。理论上信息都在那儿,但如果没人告诉他"你可以先算算两张照片之间每个点挪动了多远",他很可能永远也理不出头绪来。密集轨迹这类手工方法的优势就在这里,它们不需要网络自己去发现运动的存在,而是直接把运动信息用光流的形式喂给了后续的处理流程。
核心思路:把运动直接喂给网络,而不是让网络自己去发现运动
Simonyan和Zisserman的解法说出来其实很朴素:既然网络自己学运动这么费劲,那就不要让它自己学,直接把运动信息算好了喂给它。
具体怎么做?他们设计了两条独立的卷积网络通路,一条叫**空间流**
> 空间流(Spatial Stream):一个专门处理单帧静止图像的卷积网络分支,输入是视频里的某一帧RGB图片,负责识别画面里的物体、场景、人物外观等静态信息。
另一条叫**时间流**
> 时间流(Temporal Stream):一个专门处理运动信息的卷积网络分支,输入不是原始图像,而是预先计算好的光流场,负责捕捉画面里物体的运动方向和速度。
这里最关键的一步,是时间流的输入不是视频帧本身,而是**光流**
> 光流(Optical Flow):描述视频里每个像素点从一帧到下一帧移动方向和速度的向量场,可以理解成给画面里每一个点都画一个箭头,指出它接下来往哪儿动、动了多远。
光流是提前用传统算法计算好的,不是靠网络自己学出来的。这一步相当于把"运动"这个抽象概念,提前翻译成了一种网络更容易理解的具体数据格式,即一堆方向箭头。
这个设计思路可以类比成教小孩看地图。如果你直接把一张没有任何标注的卫星航拍图丢给一个从没接触过地图的孩子,让他自己去分辨哪里是马路哪里是河流,他大概率会一头雾水,因为原始图像里信息太杂,分辨率也不匀。但如果你先帮他把马路用红线标出来,河流用蓝线标出来,他立刻就能看懂地图在说什么。光流做的就是这件"预先标注"的工作,它把最重要的运动信息提前提炼出来,用清晰的箭头形式呈现给网络,而不是让网络从原始像素的混沌里自己去摸索。
如果不这么做会怎样?论文里做了对比实验,答案很直接。单独只用空间流,也就是只看静止画面判断动作,在UCF-101上的准确率是72.6%。这个数字和当时那些直接堆叠视频帧硬训3D网络的方法差不多,说明只看静态外观确实学不出运动的门道。而把空间流和时间流结合起来,准确率跳到了88.0%,直接追平甚至反超了密集轨迹这个手工方法的战绩。
单看这15个百分点的跃升,就知道运动信息在动作识别里有多重要,而光流这种显式提供运动信息的方式,比让网络自己瞎猜要有效得多。
双流网络具体长什么样
整个架构后来被称为**双流卷积网络**
> 双流卷积网络(Two-Stream Convolutional Networks):由空间流和时间流两个独立的卷积网络分支组成的架构,两条通路各自处理不同类型的输入,最后把两边的预测结果融合起来,给出最终的动作分类判断。
两条通路的网络结构基本是照搬当时图像分类领域效果最好的架构,跟AlexNet那套卷积加池化再加全连接层的路子差不多。区别只在于输入不同:空间流吃的是单张RGB图,通道数是3;时间流吃的是光流场,通常会把连续多帧的光流叠在一起作为输入,比如把10帧光流的水平和垂直分量堆成20个通道,一次性喂给网络。
两条流各自独立训练,各自输出一个动作类别的概率分布,最后用简单的加权平均或者再训练一个小分类器,把两边的结果融合成最终答案。
这里有个细节值得说一说。研究者在做时间流训练的时候发现一个问题:标注好的视频动作数据集,数据量不算大,直接拿光流去训练一个较深的卷积网络,很容易过拟合。他们采用了一个叫**多任务学习**
> 多任务学习(Multi-task Learning):让同一个网络同时在多个相关任务上训练,共享底层特征,以此利用不同数据集的信息,缓解单一数据集数据量不足的问题。
的技巧,把两个不同的动作识别数据集合并起来一起训练时间流网络,共享大部分网络参数,只在最后分类层区分是哪个数据集的任务。这个做法有效缓解了数据不足带来的过拟合问题。
这就好比一个厨师同时给两家口味相近的餐厅打工,虽然两家餐厅的菜单不完全一样,但基础的刀工、火候这些底层功夫是通用的。厨师在两边轮流练习,反而比只在一家餐厅练习练得更扎实,因为练习的样本总量变多了。如果没有这个多任务的技巧,单靠一个数据集的量去喂饱一个较深的网络,大概率会出现网络记住了训练集里的特定画面,却学不到真正泛化的运动规律。
光流该怎么表示才好用
时间流具体输入什么形式的光流,论文里也做了细致的探索。他们对比了好几种方案。
一种是直接用光流场的原始形式,每个像素点给出水平和垂直两个方向的位移量。另一种是把光流做归一化处理,还有一种尝试是用轨迹堆叠的方式,把光流沿着物体的运动轨迹进行采样,而不是简单地在固定网格位置采样。
实验发现,用简单的密集光流叠加多帧的方案,效果已经相当不错,比更复杂的轨迹对齐方案省事,效果也没差太多。这也说明了一个道理,有时候简单粗暴的方案不一定比精巧设计的方案差,尤其是在深度网络本身已经具备一定学习能力的情况下。
论文里还观察了一个有意思的现象。他们把光流场的方向做了正反两种处理,也就是把每个箭头都反过来看看会怎样,发现这样做能进一步提升一点效果,因为这相当于变相扩充了训练数据,让网络看到了同一个动作正着来和倒着来的两种版本,加强了网络对运动方向本身的敏感度而不是死记硬背某个具体方向。
结果和意义:这是深度学习第一次在视频动作识别上赢过手工特征
把所有实验数据放在一起看,双流网络在UCF-101数据集上做到了88.0%的准确率,在另一个常用的HMDB-51数据集上做到了59.4%。这两个数字,双双超过或者追平了当时最强的密集轨迹方法。
| 方法 | UCF-101准确率 | HMDB-51准确率 |
| 密集轨迹(手工特征) | 88.0% | 57.2% |
| 仅空间流 | 72.6% | 40.5% |
| 仅时间流 | 81.2% | 47.1% |
| **双流网络融合** | **88.0%** | **59.4%** |
这张表格里最能说明问题的是时间流单独跑出来的81.2%,已经明显超过空间流的72.6%,证明了运动信息确实是识别动作的关键线索,比单纯的外观信息更管用。而两者融合之后,在HMDB-51上比手工特征还高出了2.2个百分点。
这是深度学习在视频动作识别这个具体任务上,第一次真正打赢手工特征。这句话放在2014年的语境里,分量不亚于两年前AlexNet在图像识别上的横空出世。区别是,视频领域这场胜利没有那么干净利落,深度学习没有靠一个端到端的网络暴力取胜,而是靠"承认自己在时间维度上学不好,干脆借用传统算法算好的光流"这种务实的妥协,才勉强追平战绩。这种带着妥协色彩的胜利,反而更值得琢磨,它说明了一个道理:深度学习不是万能钥匙,有时候和传统方法结合,效果比硬碰硬要好。
后续的故事:双流网络开启了一整条研究路线
双流网络这个思路一开炮,后面几年整个视频理解领域基本是沿着这条路往前走。
2015年,Feichtenhofer等人发表了改进双流网络融合方式的工作,探索了在网络的不同层级把空间流和时间流的特征提前融合,而不是等到最后才融合两边的预测结果,这个改动进一步提升了准确率,证明了两条流之间的信息如果能更早地互相交流,效果会更好。
2016年,Wang等人提出了**时间分段网络**
> 时间分段网络(Temporal Segment Networks,TSN):把一段视频切成若干个时间片段,从每个片段里各抽取一帧和一段光流,分别跑双流网络,再把所有片段的结果汇总,用来解决长视频里动作发生在哪个时间段不确定的问题。
这个方法把双流网络的处理范围从几帧扩展到了整段视频,进一步把UCF-101的准确率推到了94%以上。
再往后,Carreira和Zisserman(同一个Zisserman)在2017年发表了**I3D网络**
> I3D(Inflated 3D ConvNets):把双流网络里的2D卷积核直接膨胀成3D卷积核,让空间流和时间流都能同时处理时间和空间维度,并且借助大规模视频数据集Kinetics进行预训练。
I3D把双流网络的思想和3D卷积结合起来,加上大规模数据集的加持,把这条技术路线的准确率又往上推了一大截,成为后续很长一段时间里视频理解领域的标准基线模型。
从密集轨迹到双流网络,再到时间分段网络、I3D,这条脉络清晰地展示了一个领域是怎么一步步从手工特征过渡到深度学习,又是怎么在深度学习内部不断迭代改进的。双流网络在这条脉络里的位置,是那个关键的分水岭:它证明了深度学习完全可以打赢视频理解这场仗,只是需要找到合适的输入表示方式。
写在后面
读这篇论文最触动我的一点,是研究者没有执着于"端到端"这个当时深度学习圈子里近乎信仰的原则。他们直接承认,网络自己从像素里学运动学不好,干脆借用传统算法算好的光流塞进去。这种务实的妥协,在追求纯粹端到端学习的年代里,其实需要一点勇气去承认。
还有一个细节值得琢磨。反转光流方向能提升效果这件事,说明网络学到的很可能不是某个具体方向的运动模式,而是运动这件事本身的结构。这让我想到人类学外语语法的过程,死记硬背例句效果差,理解规律之后随便换个例子都能套用。网络在这里似乎也在往"理解规律"的方向靠,而不是单纯记住训练集里出现过的画面。
双流网络没有解决的问题是,长时间跨度的动作依赖关系,一个持续几十秒的复杂动作,光靠几帧光流很难捕捉全貌。这也是后来时间分段网络要解决的事。如果一个动作发生在十分钟的视频里,网络要怎么知道该往哪个时间点看?这个问题现在有了更好的答案,但2014年的双流网络还没来得及触碰它。
Q&A
Q1:双流卷积网络是什么?
A:双流卷积网络是Simonyan和Zisserman在2014年提出的视频动作识别模型,由空间流和时间流两个独立的卷积网络分支组成,空间流处理单帧图像捕捉外观信息,时间流处理光流场捕捉运动信息,两者结果融合后进行动作分类。
Q2:双流网络为什么要用光流而不是直接用视频帧训练?
A:因为直接让网络从原始像素堆叠里学习运动模式效果不好,网络很难从噪声中提炼出真正的运动规律。光流提前用传统算法算好了每个像素的运动方向和速度,相当于把运动信息预先翻译成网络容易理解的格式,实验证明这样做能把准确率从72.6%提升到88%。
Q3:双流网络后来被哪些方法超越了?
A:2015年Feichtenhofer等人改进了融合方式,2016年Wang等人提出时间分段网络把准确率推到94%以上,2017年Carreira和Zisserman提出I3D网络,结合3D卷积和大规模数据集预训练,成为后续视频理解领域的标准基线模型。