
2012年,AlexNet横空出世,图片识别这件事几乎一夜之间被重新定义了。ImageNet比赛的错误率从二十多个百分点直接砍到十五个百分点左右,整个计算机视觉圈子都在议论卷积神经网络这四个字。
可两年后,当研究者们把同样的思路搬到视频上,想让神经网络认出画面里的人在跳远还是在扔铅球,却发生了一件挺尴尬的事。
深度学习输了。而且输给的不是另一个更花哨的神经网络,是一个诞生于传统计算机视觉时代的手工方法,叫密集轨迹。
> 密集轨迹(Dense Trajectories,改进版简称iDT):一种不依赖神经网络的传统视频特征提取方法,靠追踪画面里密集分布的点在多帧之间的运动路径,再手工统计这些路径周围的图像和运动信息来判断动作类别。
这不是一次小差距的失利。当时最好的纯CNN方案,也就是Karpathy等人2014年发表的大规模视频分类研究,在UCF101这个动作识别数据集上只能做到65.4%的准确率,而iDT轻松跑到了87.9%。
二十多个百分点的差距,意味着什么。
意味着每识别5个动作,深度学习就要比手工方法多认错一个还不止。这在图片识别领域几乎是不可想象的局面,毕竟AlexNet早就把手工特征打得没有还手之力了。
这篇文章要讲的,是Karen Simonyan和Andrew Zisserman在2014年发表的论文,他们提出的方法让深度学习第一次在视频动作识别上追平、甚至反超了iDT。这个方法叫双流卷积网络。
核心问题:视频比照片多了什么
一张图片和一段视频,最本质的区别是什么。
图片给你一个静止的瞬间,你能看到场景、物体、颜色、纹理。视频除了这些,还多了一条时间轴,多了运动本身。一个人举着球拍站在网球场上,从照片上你能看出他在打网球,但你看不出他是在发球还是在接球,是在扣杀还是在轻挑。这些信息藏在连续帧之间的变化里,藏在运动的方向和节奏里。
早期直接把CNN搬到视频上的做法,基本就是把图片识别的套路照搬过来,让网络吃进去几张连续帧,指望它自己从像素变化里学出运动规律。问题是,动作识别的训练数据集在当时小得可怜,UCF101总共只有一万三千多段视频,HMDB51更少,只有几千段。而ImageNet有上百万张标注图片。
数据量差了两个量级,网络自己去学"运动"这个抽象概念,学不出来,只能靠记住训练集里的场景细节混日子,换一批测试视频立刻现原形。这大概就是为什么当时纯CNN方案只能做到65.4%,比iDT差了一大截。
Simonyan和Zisserman当时都在牛津大学的视觉几何组工作。
> VGG(Visual Geometry Group):牛津大学的一个计算机视觉研究组,几个月后同一批人还发表了后来家喻户晓的VGGNet图像分类网络,这两篇论文几乎是同期的工作。
他们的思路挺直接:既然网络自己学不好运动信息,那就别指望它凭空学出来,直接把运动信息用传统方法先算好,喂给网络一个专门处理运动的分支。
拆成两条河:空间流与时间流
双流网络的核心设计,是把一个原本很难的问题拆成两个相对简单的子问题,分别用两个独立的卷积网络去解决,最后再把结果合并。
> 双流卷积网络(Two-Stream Convolutional Network):由两个独立的CNN组成的架构,一个负责处理单帧画面的外观信息,叫空间流,一个负责处理帧与帧之间的运动信息,叫时间流,最后融合两条网络的判断结果得出最终类别。
空间流吃的是单张RGB图像,学的是场景、物体、人物外观这些静态线索。这条分支本质上跟图片分类网络没什么区别,甚至可以直接借用在ImageNet上预训练好的模型权重。
时间流吃的不是原始画面,是一种叫光流的东西,专门捕捉运动方向和速度。
这个设计的必要性藏在一个具体的场景里。想象你在看一场默剧比赛的评分现场,评委分成两组。第一组评委只能看剧照,也就是单张照片,判断演员穿的衣服、站的场地、手里拿的道具。第二组评委只能看骨骼动作捕捉出来的火柴人动画,只有运动轨迹,没有任何场景信息。
如果只让第一组评委打分,让他们分清"打网球"和"打羽毛球",大概率分不清,因为球拍长得差不多,场地也接近,一个正在扣杀的网球动作和一个正在轻挑的羽毛球动作,从静态照片上看差别不大。反过来,如果只让第二组评委看火柴人动画,他们能看出运动的方向和节奏,但分不清运动员到底站在游泳池边还是网球场上,遇到"扔铅球"和"扔链球"这种运动路径相似但项目完全不同的场景,第二组评委也会犯迷糊。
真正靠谱的判断,得把两组评委的意见综合起来。
这正是双流网络实验数据告诉我们的事。如果只用空间流单独判断,在UCF101上的准确率只有72.6%,掉了整整十五个百分点。如果只用时间流,准确率能到81%左右,比空间流强不少,但还是不如两者融合的88.0%。
单独跑任何一条流都会漏掉另一半信息,这就是为什么必须两条流一起上。
光流:给每个像素画一支箭头
时间流吃的光流到底是什么东西。
> 光流(Optical Flow):描述图像中每个像素点在相邻两帧之间移动方向和距离的一种表示方法,稠密光流指的是给画面里几乎每一个像素都算出这样一个移动向量,最终形成一张记录着运动方向的"运动地图"。
具体做法是,取连续的十帧画面,两两之间算出光流场,光流场本身有水平方向和垂直方向两个分量,十帧就是二十个通道,这二十个通道堆叠在一起,作为时间流网络的输入。
为什么不直接把原始帧堆在一起扔给网络,非要先算好光流再喂进去。
光流场就像给每一帧画面上的每个像素都画一支箭头,告诉你这个点下一帧往哪个方向、挪动了多远。如果不用光流,直接把连续几帧原始图像叠在一起扔给CNN,网络看到的其实是好几张几乎一样的照片叠在一起,像素值的差异本身并不会直接告诉网络"手往左边移动了三个像素"这种运动信息,网络得自己从这些微小的像素差异里硬猜运动方向。在训练数据只有一万多段视频的情况下,这种猜测基本猜不准,网络学到的更像是噪声,而不是真正的运动规律。
先用传统算法把光流算好再喂给网络,相当于把最难的那一步提前做完,网络只需要在一张已经标好运动方向的地图上做分类,任务难度直接降了一个台阶。
论文里有一张展示时间流网络第一层卷积核的图,看上去大多是带方向性的条纹状滤波器,像是在专门检测某个特定方向的运动模式。这不是随便训练出来的巧合,这是网络自己学出来的,它发现光流场里最重要的信息恰恰就是方向,于是第一层就把自己调成了一堆方向探测器。
数据太少怎么办:让两个数据集互相帮忙
前面提到,UCF101和HMDB51这两个数据集加起来也没多少视频,单独训练一个深层网络很容易过拟合。
Simonyan和Zisserman用了一个多任务训练的办法来缓解这个问题。
> 多任务学习(Multi-task Learning):让同一个网络同时在多个相关任务上训练,共享网络的大部分参数,只在最后的输出层为每个任务单独设一套分类层,逼着网络学到对所有任务都通用的特征,而不是死记硬背某一个数据集的细节。
具体做法是,同一个时间流网络同时在UCF101和HMDB51上训练,前面的卷积层完全共享,只在最后接两个独立的softmax分类层,一个对应UCF101的101个动作类别,一个对应HMDB51的51个动作类别。
> softmax:神经网络最后一层常用的输出方式,把网络算出来的一堆数值转换成每个类别的概率,所有类别的概率加起来等于1。
这个设计对应的场景是,一个学生同时要准备两门内容相近的考试,比如中国古代史和世界古代史。如果分别报两个培训班,各自的复习资料都很单薄,复习效果有限。但如果这个学生把两门课的复习资料合并起来一起看,共用的分析方法和年代感训练本身就是通用的,只是最后答题的时候按各自科目分别填答题卡,复习效率就高多了。
双流网络里,共享的卷积层部分就是这份通用复习资料,专门学运动和外观的一般规律,最后接的两套softmax才是各自的答题卡。如果不这样共享训练,只用UCF101一个数据集单独训练时间流网络,过拟合会很严重,网络容易把训练集里的背景细节死记硬背下来,而不是真的学会识别运动模式,换一批新视频立刻掉分。
融合与最终成绩
两条流各自训练完之后,怎么把它们的判断结果合并成一个最终答案。
论文里试了两种融合方式,一种是直接把两条流最后softmax输出的概率取平均,另一种是把两条流的特征拼起来,训练一个SVM分类器做最终判断。
> SVM(支持向量机):一种经典的机器学习分类算法,通过找到一个能最大程度区分不同类别数据的分界线来做判断,在深度学习流行之前是主流的分类工具之一。
两种融合方式效果接近,最终在UCF101上把准确率做到了88.0%,第一次追平并小幅超过了iDT的87.9%。
下面这张表大致还原了几种方案在UCF101上的表现差距。
| 方法 | UCF101准确率 |
| 纯CNN(Karpathy等,2014) | 65.4% |
| iDT手工特征 | 87.9% |
| 双流网络:仅空间流 | 72.6% |
| 双流网络:仅时间流 | 81.0% |
| 双流网络:融合 | **88.0%** |
这张表格里最扎眼的对比,是纯CNN的65.4%和融合后88.0%之间足足二十多个百分点的落差。同一个基本工具,卷积神经网络,仅仅因为多了一条专门处理运动信息的分支,成绩就发生了这么大的跃升。
这是深度学习在视频动作识别上第一次真正赢过手工特征。放在2014年这个时间点上,这句话的分量不亚于AlexNet当年在图片识别上的横空出世,只不过这一次,胜利来得更艰难一些,靠的不是一个更深的网络,而是一次架构上的巧妙拆分。
后来的路,走向了哪里
双流网络提出的空间流加时间流这个基本框架,成了后面好几年视频动作识别领域的标准起点。
2016年,Feichtenhofer等人发表了一篇关于卷积双流融合的论文,他们发现原始双流网络只在最后softmax层做融合太晚了,信息交流不够,于是改成在网络中间的卷积层就让两条流互相看一眼对方的特征,融合位置提前之后,识别准确率进一步提升。
同样是2016年,Wang等人在ECCV上发表了时间片段网络。
> TSN(Temporal Segment Network,时间片段网络):一种改进的双流网络训练方式,不再只从视频里截取连续的一小段帧,而是把整段视频均匀切成几个片段,每个片段各取一小段稀疏采样,让网络能看到整段视频的长时间结构,而不只是局部的一小截。
这个改动让网络能捕捉动作在更长时间尺度上的规律,最终把UCF101上的准确率推到了94%左右,比原始双流网络又高了一大截。
2017年,Carreira和Zisserman,还是原来那位Zisserman,发表了I3D。
> I3D(Inflated 3D ConvNet):一种把原本针对图片设计的二维卷积核直接"膨胀"成三维卷积核的网络结构,让网络能直接在原始视频帧序列上学习时空特征,同时依然保留了空间流加时间流两条分支的思路,并配合当时新发布的大规模视频数据集Kinetics进行预训练。
I3D把双流的思路和三维卷积、大规模预训练结合起来,把动作识别的准确率又往上推了一截,也成了后面很长一段时间的强基线模型。
从87.9%到88.0%,再到94%,再到I3D之后更高的数字,这条准确率曲线背后,是同一个基本判断的一路延伸,空间信息和运动信息本来就是两种不同性质的东西,分开处理再融合,比硬塞给一个网络自己去猜,效果更好。
写在后面
写这篇论文的时候,一个念头一直在脑子里转,双流网络这个结构,其实和人类大脑处理视觉信息的方式有点像。神经科学里早就有一个说法,人的视觉皮层存在两条通路,一条叫腹侧通路,负责识别"这是什么",处理物体和场景的静态外观,另一条叫背侧通路,负责判断"它在哪、怎么动",处理空间位置和运动信息。这两条通路在解剖结构上是分开的,最后在更高层的脑区汇合,形成完整的知觉判断。
Simonyan和Zisserman大概没有直接照着神经科学的论文来设计双流网络,但两者殊途同归这件事本身挺让人感慨的。有时候一个领域里最优雅的工程解法,恰好和另一个完全不相关的领域里演化了几百万年得出的生物结构对上了。
论文里还有个细节值得单独说一说,多任务训练用的两个数据集,UCF101和HMDB51,动作类别其实并不完全重合,一个数据集里有"骑马",另一个可能没有,但共享的卷积层依然能从两边同时学到通用的运动特征。这说明网络真正学到的东西,是一种比"具体动作类别"更底层的运动表示能力,这种能力可以在不同任务之间自由迁移,这个发现后来在整个深度学习领域反复被验证,预训练加迁移这条路子,本质上就是从这里延伸出去的。
这篇论文没有解决的问题也很明显,光流本身是用传统算法提前计算好的,不是端到端学出来的,这多少有点别扭,相当于在一个深度学习系统里嵌入了一段手工设计的模块。后来I3D用三维卷积直接吃原始帧序列,某种程度上就是想把这最后一块手工的部分也交给网络自己学。这个方向对不对,现在的三维卷积网络和后来的视频Transformer架构给出了自己的答案,但答案本身好不好,可能还得再过几年才看得清楚。
Q&A
Q1:双流卷积网络是什么?
A:双流卷积网络是Simonyan和Zisserman在2014年提出的视频动作识别方法,用一个空间流处理单帧图像的外观信息,一个时间流处理光流表示的运动信息,最后融合两条网络的判断结果,在UCF101上首次让深度学习追平并超过了手工特征方法iDT。
Q2:双流网络为什么要单独设计一条时间流处理光流?
A:因为当时的视频数据集太小,网络很难自己从原始帧的像素变化里学出运动规律。先用传统算法把光流算好再输入网络,相当于提前把最难的运动信息提取好,让网络只需要在这个基础上做分类,大幅降低了学习难度。
Q3:双流网络后来被哪些方法改进了?
A:2016年Feichtenhofer等人提出更早的卷积层融合方式提升了效果,同年Wang等人提出时间片段网络TSN让网络能看到整段视频的长时间结构,准确率提升到94%左右,2017年Carreira和Zisserman提出I3D,把双流思路和三维卷积、大规模Kinetics数据集预训练结合起来,进一步提升了性能。







