CNN在别的领域已经取得了巨大的成功,但在动作识别领域却不尽人意,作者认为该领域在当时存在两个问题:
(1)数据集太小。动作识别中除了图像信息还包含运动和视角各种信息,需要的数据量应该要超过图像分类才对。然而现实是图像分类数据集imagenet每个类别的1000个样例,而ucf101每个类别只有100个样例。
(2)当时提出的CNN架构都不能充分利用时间维度的信息。
当时最好的双流CNN,也存在(2)这个问题,作者具体说了两点:
(1)双流网络无法学习到时间特征和空间特征的像素间的关系。我的理解是空间特征可以学习到物体是什么,例如手臂、躯干、腿… 时间特征可以学习到物体在做什么运动,例如挥动、平移、旋转… 而手臂挥动和腿挥动明显是不同的动作,躯干平移和躯干旋转也是不同的动作。换言之,将空间特征和时间特征结合起来考虑,能为动作识别提供更多线索,也就有希望提升网络的表现。
(2)双流网络对时间维度的利用很有限,空间网络只用了一帧,时间网络只用了10帧。
针对这两个问题,作者对应地提出两种解决方法
(1)空间融合:在隐藏层中间对两个网络进行融合(Figure 2),并且提出了多种融合方式;
(2)时间融合:提出用Conv3D和Pool3D提取时间维度的特征,在时间维度上进行“融合”(Figure 3)。
融合层有两个输入,一个输出。 x t a ∈ R H × W × D x_t^a \in R^{H\times W\times D} xta∈RH×W×D 代表空间网络的输入, x t b ∈ R H × W × D x_t^b \in R^{H\times W\times D} xtb∈RH×W×D 代表时间网络的输入, y y y 代表融合层的输出。
融合方式 | 数学表达式 | 维度 | 增加参数 |
---|---|---|---|
Sum fusion | y s u m = x t a + x t b y^{sum} = x_t^a + x_t^b ysum=xta+xtb | y s u m ∈ R H × W × D y^{sum} \in R^{H\times W\times D} ysum∈RH×W×D | 无 |
Max fusion | y m a x = m a x ( x t a , x t b ) y^{max} = max(x_t^a, x_t^b) ymax=max(xta,xtb) | y m a x ∈ R H × W × D y^{max} \in R^{H\times W\times D} ymax∈RH×W×D | 无 |
Concat fusion | y c a t = c a t ( 3 , x t a , x t b ) y^{cat} = cat(3, x_t^a, x_t^b) ycat=cat(3,xta,xtb) | y c a t ∈ R H × W × 2 D y^{cat} \in R^{H\times W\times 2D} ycat∈RH×W×2D | 后面的全连接层 |
Conv fusion | y c o n v = y c a t ∗ f + b y^{conv} = y^{cat} * f + b yconv=ycat∗f+b | f ∈ R 1 × 1 × 2 D × D , b ∈ R D y c o n v ∈ R H × W × D f \in R^{1\times 1\times 2D \times D}, b\in R^{D}\\ y^{conv} \in R^{H\times W\times D} f∈R1×1×2D×D,b∈RDyconv∈RH×W×D | f 和 b f和b f和b |
Biliner fusion | y b i l = ∑ j = 1 H ∑ i = 1 M x i , j a ⊗ x i , j b y^{bil} = \sum_{j=1}^H\sum_{i=1}^M x_{i,j}^a \otimes x_{i,j}^b ybil=j=1∑Hi=1∑Mxi,ja⊗xi,jb | y b i l ∈ R D × D y^{bil} \in R^{D\times D} ybil∈RD×D | 用SVM替代全连接分类,反而减少了参数 |
cat用来拼接矩阵, ∗ * ∗ 代表卷积操作, ⊗ \otimes ⊗ 代表矩阵外积。
不同融合方式的效果如下表:
(1)早融合:在relu5之前融合,效果不佳
(2)早融合加多融合:效果不佳
(3)晚融合(relu5)和多融合(relu5+fc8)效果最好,但是多融合训练参数多一倍
通过将2D卷积和2D池化拓展到3D卷积和3D池化,可以提取到时间维度的特征。
在concat融合层之后添加3D Conv和3D Pooling,性能略有提升。
我按照文章和代码对架构的描述,把上面的Figure 1修改了,融合后的架构图如下所示(见Netscope示意图):
添加了一个concat融合层,一个Conv3D层。用两个Pool3D层替换了原来2D的pool5。这是本文提出的最终架构,相比原来的双流架构,增加的参数只有Conv3D中的少量参数,但通过融合的方式大大的提升了网络性能。
假设现在正在计算第i个batch的输入:
i i i 代表当前在计算第i个batch
n F r a m e s = o p t s . n F r a m e s ( i ) nFrames=opts.nFrames(i) nFrames=opts.nFrames(i) 代表第i个视频总共的帧数
n S t a c k = o p t s . i m a g e S i z e ( 3 ) = 20 nStack=opts.imageSize(3) = 20 nStack=opts.imageSize(3)=20 代表输入图像尺寸的第三维,也就是20
时间网络的输入由几个参数决定:
L = n S t a c k / 2 = 10 L=nStack/2 = 10 L=nStack/2=10
T = o p t s . n F r a m e s P e r V i d T = opts.nFramesPerVid T=opts.nFramesPerVid 代表采样点的个数
τ = o p t s . t e m p o r a l S t r i d e τ = opts.temporalStride τ=opts.temporalStride 代表采样的时间间隔
o p t s . f r a m e S a m p l e opts.frameSample opts.frameSample 代表采样方法,可以取值uniformly, temporalStride, random, temporalStrideRandom
获取时间网络的输入可以分为以下几个步骤:
frameSamples
(数组长度可能大于T)
uniformly
均匀采样temporalStride
时间定长间隔采样random
完全随机采样temporalStrideRandom
时间随机间隔采样frameSamples
的长度设置为 T T T ,如果小于T就补充一些采样点,大于T就随机取连续的T个frameSamples
维度扩充为 L × T L\times T L×T通过实验,作者得出三个结论:
(1)相比在最后的Softmax层融合,在中间的卷积层融合既能够提升性能,又不会增加太多参数(见融合方式)
(2)在最后一个卷积层融合(relu5)的性能是最好的,如果再配合最后一个全连接层融合(fc8),性能还能再提升一点(见融合位置)
(3)在融合后使用pool3d代替代替pool2d能更进一步地提高性能(见3D Conv和3D Pooling)