比赛已经结束,很荣幸能和队友一起拿到这个冠军,非常感谢队友的付出,写个总结,算是对这几个月付出的一个交代。
队名:学学没完
队伍成绩:
初赛榜 0.85245 排名第一 (a榜第二,b榜重回第一)
决赛榜 0.9307 排名第二 (第一老哥很猛,搞得我们很慌,硬是肝了一晚上才拉近了和他们的差距)
受益于官方对大家前三个月工作的肯定,初赛的权重是复赛的两倍,因此最后加权总榜第一。
初赛赛题是对一组唇语图片序列进行中文单词的预测,给定的数据集是封闭集(类别数量是一定的,测试集中的类别均在训练集中出现过),如下图所示:
拿到数据,我们先简单的对数据进行了分析:
数据分析让我们对数据有了一个整体的把握。除此以外,我们还观察了一些样本数据,发现了他们采集的样本中,包含说话的有用信息图片大都集中在前半序列中,而最后几张往往都是闭嘴状态,没有提供任何有用的信息。
因此我们手动标注了七八百张图片图片送进了CornerNet_Lite网络中去训练一个检测嘴唇的网络。
Why CornerNet_Lite?
其实其他的也可以,如Yolov3,毕竟任务简单,但是这篇论文号称吊打Yolov3,且我前一段时间也跑过这个网络,所以就拿来用了,下图即为文章中的性能对比图,由于没有速度的要求,我们最终采用的是Cornernet-Saccade版本。
切割效果基本完美,我们切割原则是:1.保证嘴巴在图片正中央;2、保持一组图片切割大小一样,且嘴唇不能占满全图。
在切割的时候我们也发现一些图片没有检测到嘴唇,结果发现样本序列中夹杂了一些噪声数据,我们将这些进行了去除,大致如下图所示:
我们当时的切割程序写了一些BUG,导致没有贯彻思想,最终直接测试的结果并没有不切割的好。当时也没发现这个问题,所以初赛并没有用到切割图片,但是我也对标注的图片中嘴唇边界离图片边界的信息进行了统计,最后大致对图片做了一个统一的切割或者说限制区域的操作。
通过对数据的分析,且考虑到任务是多分类问题,无需考虑词与词之间的关系,所以我们将这个问题简单的看作动作视频多分类的问题,因此我们尝试了多种类别的 SOTA 模型。
1)基于3D 卷积模型
3D 卷积模型是我们首先想到和尝试的,3D 模型的代表之一是《ECO: Efficient convolutional Network For online video understanding》,这篇文章是去年 ECCV 的文章,模型结构如下:
这个模型的效果也不错,我们队伍前期霸榜就是依靠这个模型,ECO-lite 最高 0.74 多,ECO-Full 最高 0.76 多,之后我们又尝试了其他一些模型,如今年的CVPR 何凯明实验室的文章《SlowFast Networks for Video Recognition》,但是该网络需要高低帧率间配合才能有更好的效果,而我们这个数据毕竟不是视频,帧数实在有限,最终跑出来效果不尽如人意,但如果有高帧率的视频,我想应该会有不错的效果。
篇外探讨:
关于《SlowFast Networks for Video Recognition》这篇文章中提出的一个观点我觉的值得我们去思考,大致意思:
我们对于一张图片,我们可以简单的将其分为两个维度来看待,I(x,y) 。似乎很合理,x与 y方向的重要性似乎是相等的。然而对于一个视频,引入了时间维度t ,I(x,y,t) 。但这个t与 x,y可以同等看待吗,显然不是的啊,现实这个世界中,大多数的物体都是静止的。而我们传统的卷积如 3D卷积却是同等对待的,按照作者的理解,这是不合理的。既然不合理,就需要将时间t与空间(x,y)单独的处理。
值得一提的是,今年这个领域几篇顶会如SlowFast、STM、TSM都是基于2D卷积模型来做的,只是提取时序的结构不一样,且达到了超越3D卷积的效果,所以是否可以推想:对于时序特征的提取,最好还是不要将时序信息与图片的长宽维度等同看待,而是加以区别来提取,设计更好的时序提取结构来获得一个更好的效果才是上上策呢?
2)基于2D 卷积模型
2D 卷积模型由于其轻量的结构和多元的 backbone 选择,使得其在云端计算和边缘部署上相对 3D 卷积模型具有巨大的优势,但 2D 卷积模型因为时序上的关系很难利用好,各种加如 lstm 等结构的网络还是被 3D 卷积实力碾压,通常情况下如果只考虑精度则不考虑 2D 卷积模型 。 但是如果一个模型只使用 2D 卷积,且在分类精度上仍然能达到 SOTA,那么其带来的实用价值是巨大的,是碾压一切 3D 模型的存在。
而今年 ICCV 上的这篇文章《TSM: Temporal Shift Module for Efficient Video Understanding》提出的 Temporal Shift Module 这个模块很好的利用了帧间的时序关系,实现了 3D 卷积的性能且保持了 2D 卷积的相对较小的计算量。并且截至它的发行日,它在注重动作的数据集 Something-Something 排行榜上排名第一,这也更加符合我们的需求。
我们最终采用的模型也正是2D卷积网络+TSM模块的结构,期间我们也尝试了加Non_Local,但是效果并没有提升,反而是模型变得沉重,推断变慢。
TSM原理:
TSM在时间维度上移动了部分通道,从而促进相邻帧在信息之间的交流。而这一操作插入到2D卷积中又基本算是实现了在零计算量的情况下对时间轴的信息建模。
如上图所示TSM模块通过沿时间维度移动特征图来执行有效的时间建模,图a是原始的tensor,图b是离线模式所适用的双向TSM将过去和未来的帧和当前帧混合,而图c是在线模式,实时识别,由于不能获取到未来的帧信息,所以仅用过去的帧和当前的帧混合在一起。我们最终采用的是图b的方式。
可以看到,仅仅是对部分通道进行了移位,几乎没有额外的其他操作(也意味着没有额外的计算消耗,且没有多余的参数)。
更多关于TSM的内容,有兴趣的可以去看一下原论文,我也写了一篇大致翻译的博客,不想看英文原文的可以简单看一下这个。
视频分类网络通常输入的数据并不是整个视频,而是从视频中截取的一些帧图像,按照其时序关系送入模型。而截取的原则一般是按照一定的帧率均匀采样,亦或者先均匀将视频分成几个片段,然后从每个片段中随机选一帧图像,以此来增强模型的泛化能力,同时减小计算量。
而我们的唇语数据集是已经截取好的图片,数量从2张(0或1张视为噪声数据去除)到24张不等,模型输入的图片数量是一定的,所以模型输入采用多少帧和缺少的帧图像如何填充都是一个问题。
本着不丢失信息和尽可能小的模型输入原则,我们选择了24帧作为模型的统一输入。至于模型的插帧,内容上我们是复制前一帧的图像来填充,而插帧方法上我们采用了尽可能在前几张图像多插帧的原则,这样就等效为放慢了前几张图像带来的信息,这样做的原因是通过观察数据,我们发现最后几张图像采集者往往是闭嘴状态并不提供任何信息,所以预测时的插帧公式如下:
copy_times代表所有图片至少复制的次数,frame_num代表模型输入的帧数,这里我们设定的是24帧,len(images)代表的是样本中原始图片的数量,moreone_num代表的是需要多复制一遍的图片数量。预测时,我们直接将前moreone_num张图片多复制一次,以达到24帧的输入。
而对于训练过程,我们考虑到采集者说话可能在每个字上的时间并不相同,为了提高模型的鲁棒性,我们并没有采用固定位置多复制一次的方法,而是随机选择一个起始点进行多复制一次操作。
除此之外,我们还加入了随机丢帧的处理,具体做法是对样本图像数量大于一定值(如12)的样本进行随机丢帧,当然帧数小于2且不能为连续帧。另外还加入了图片随机移动,让一组嘴巴并不在一个位置,来增强模型的泛化能力。
对于数据增广,我们还采用了一些常规的增广方式:随机加入高斯噪声,随机对图像做双边滤波,随机调图像的明暗度、对比度、饱和度、色度,随机对图像加入小旋转(5°以内),随机对图像做上下左右小平移,随机水平反转操作。这些数据增广操作都是在不损失模型的关键信息的原则上,去告诉模型它应该关注的信息是什么,以此来增强模型的泛化能力。
决赛由于数据由中文单词变成了数字组合,且数据量极少,所以我们也尝试过将1000类问题转化为10类去做,由于策略不佳最终的准确率却只有八十多,所以还是用的初赛方案,将其视作1000类分类问题,也取得了不错的效果。
题外话:
比赛的时候我们对预测出来的答案就做了分析,发现1,4,7包含这些数字的样本相对于其他就很少,我们猜测可能官方为了让准确率变得更好看,所以刻意将难分的数据去掉了一些。事后我们问了出题的小哥,事实确实如此。
记得当时决赛那天第一支上传成绩的队伍,直接八十多,而我们线下验证集才六十多,心态都炸了,还以为成都旅游来了。结果最后发现是测试集变简单了。
很开心也很荣幸能够获得这次比赛的冠军,但是说起来也有些惭愧,只是跨领域的做了一下做了一些尝试,没有理论性的创新,可能我们是属于运气比较好的那一支队伍吧,答辩中看到其他队伍的一些工作也很棒,非常希望其他队伍的大佬能开源方便我们学习一波。最后感谢一下主办方和协办单位的工作人员,他们非常辛苦,同时也感谢我的两个队友,没有他们也没有这个冠军奖杯。欢迎交流!
代码开源链接:代码示例