如果觉得本文对您有所帮助的话,可以给我的github点个赞呀~本人有空会更新一些视频行人再识别的相关资料,比如代码注释、论文翻译等等。
github:https://github.com/AsuradaYuci/awesome_video_person_reid
1.Revisiting Temporal Modeling for Video-based Person ReID
本文以这篇18年reid文章[论文链接]为例,介绍下视频行人再识别的时间建模的一些基本方法。
2.引言
一个典型的视频行人再识别系统由三部分组成:
- 一个图像层次的特征提取器(CNN)
- 一个时间建模方法,以获得时间序列特征
- 一个用于训练的损失函数
最近的工作,集中在时间建模部分,即如何将一系列的图像层次特征聚合成一个视频片段层次的特征。目前主要有四种时间方法,分别是时间平均池化,时间注意力池化,递归循环神经网络(RNN)和3D卷积神经网络。
3.网络整体架构
视频reid网络的基本架构如图中左半部分所示。具体的:
首先,一段长视频被裁剪成连续的不重叠的
k
k
k个视频段{
C
k
C_k
Ck},每个视频段包含T帧。
然后使用图像层次的特征提取器提取每一帧图片的特征。
接着通过时间建模方法,将图像层次的特征聚合为视频序列的特征。
图中A表示平均池化的时间建模方法;图B表示递归循环神经网络(RNN)方法;图C表示时间注意力池化建模方法。
4.时间建模方法
-
3D CNN: 直接将一个包含n帧的视频段C作为输入,输出一个特征向量 f c f_c fc
采用3D Resnet50模型,在resnet架构中采用3D卷积核(为动作分类任务设计的)。将原始的最后分类层改为行人身份输出,并采用在Kinetics数据集上的预训练权重。
模型将T个连续帧作为输入,将最后分类层的之前一层的输出,作为行人的表征。 -
2D CNN:
采用标准的Resnet50模型作为图像层次的特征提取器。输入是一系列的图片帧,经过特征提取器,输出一系列的图像层次特征{ f c t f_c^{t} fct}, t ∈ [ 1 , n ] t \in[1, n] t∈[1,n],是一个 n × D n×D n×D的矩阵,其中n是视频序列的长度,D是输出的图像层次特征向量的维度。然后通过时间建模方法,将图像层次的特征聚合成一个片段层次的特征 f c f_c fc。
a. Max/Avg pooling 时间池化
最简单粗暴的时间建模方法是,直接对图像层次的特征进行最大池化或平均池化操作,即选择图像层次特征中最大值或者平均值作为整个序列的表征。
最大池化: f c = max t ( f c t ) f_c=\max \limits_{t}(f_c^{t}) fc=tmax(fct)
平均池化: f c = 1 T ∑ t = 1 n f c t f_c=\frac{1}{T}\sum_{t=1}^{n}f_c^{t} fc=T1∑t=1nfct
存在的问题:没有充分利用所有图像层次的特征。b. Attention Temporal Pooling时间注意力池化
目的:针对平均或最大池化方法没有充分利用所有图像层次特征的问题,在图像层次特征上应用了一个注意力加权平均。一个简单的想法就是,给质量高的图片高权重,质量低的图片低权重,加权求和。当所有图片的质量一致,这种加权平均就等价于平均池化。
给定的片段C的注意力为 a c t , t ∈ [ 1 , T ) a_c^{t},t \in[1, T) act,t∈[1,T)。 f c = 1 T ∑ t = 1 n a c t f c t f_c=\frac{1}{T}\sum_{t=1}^{n}a_c^{t}f_c^{t} fc=T1t=1∑nactfct
Resnet50中最后的卷积层输出的tensor尺寸为[2048, w, h],w,h取决于输入的图片尺寸。注意力生成网络将一系列图像层次特征[T, 2048, w, h]作为输入,输出T注意力分数。
(生成时间注意力分数/权重):
1) 空间卷积 + FC:
应用一个空间卷积层(卷积核的宽度为w,高度为h,输入的通道数为2048,输出的通道数为 d t d_t dt),记为[w, h, 2048, d t d_t dt]。在上述卷积层的输出后面有一个全连接层,输入的通道数为 d t d_t dt,输出的通道数为1。最后的输出为一个标量 S c t , t ∈ [ 1 , T ] S_c^{t},t \in [1, T] Sct,t∈[1,T],是帧t对于片段C的重要性分数。
2) 空间卷积 +时间卷积:
应用一个空间卷积层(卷积核的宽度为w,高度为h,输入的通道数为2048,输出的通道数为 d t d_t dt),记为[w, h, 2048, d t d_t dt]。在上述卷积层的输出后面有一个时间卷积层,输入的通道数为 d t d_t dt,输出的通道数为1,卷积核的步长为3,记为[3, 3, d t d_t dt, 1]。最后的输出为一个标量 S c t , t ∈ [ 1 , T ] S_c^{t},t \in [1, T] Sct,t∈[1,T],是帧t对于片段C的重要性分数。
一旦获得了时间注意力分数 S c t S_c^{t} Sct,可以通过 S o f t m a x Softmax Softmax或 S i g m o i d Sigmoid Sigmoid函数计算最终的注意力分数 a c t a_c^{t} act。
Softmax函数: a c t = e S c t ∑ i = 1 T e S c i a_c^{t}=\frac{e^{S_c^{t}}}{\sum_{i=1}^{T}e^{S_c^{i}}} act=∑i=1TeScieSct
Sigmoid函数: a c t = δ ( e S c t ) ∑ i = 1 T δ ( e S c i ) a_c^{t}=\frac{\delta(e^{S_c^{t}})}{\sum_{i=1}^{T}\delta(e^{S_c^{i}})} act=∑i=1Tδ(eSci)δ(eSct)
c. RNN 递归循环神经网络
RNN具有反馈连接,允许网络随时间记住信息;在每个时间步,RNN接收新输入并基于当前输入和来自先前时间步的信息产生输出。这里考虑了两种RNN聚合序列层次特征的方法。
1)直接将最后一个时步的隐藏层状态
h
T
h^T
hT作为视频片段特征:
f
c
=
h
T
f_c=h^T
fc=hT
2)计算RNN每一时步输出的平均值,作为视频片段特征:
f
c
=
1
T
∑
t
=
1
T
o
c
t
f_c=\frac{1}{T} \sum_{t=1}^{T}o_c^{t}
fc=T1t=1∑Toct
5.损失函数
文章采用三元组损失函数和 S o f t m a x Softmax Softmax交叉熵损失函数来训练网络。对于三元组损失,随机选择P个身份,为每个身份随机采样K个视频段,每个视频段包含t帧。在一个批次中,共有P×K个视频段;三元组损失定义如下:
S o f t m a x Softmax Softmax交叉熵损失函数:鼓励网络正确地预测PK视频段的ID。
最终损失:
6.总结
视频行人再识别的难点还是在如何将一系列的图像层次特征聚合成一个视频片段层次的特征。文章中给出了一些方法,但都存在问题。
时间注意力池化虽然理论上有用,但实际上由于输入是连续视频帧,如果帧数过少(比如文中选择T=4),则这些帧差别不大,最后会退化成平均池化方法(即所有帧的权重一样)。
同样地,我们认为RNN或者LSTM可以获得一些时间信息,但从实际实验结果来看,其性能比不上平均池化方法。说明这种时间建模方法也不可靠。
3D卷积虽然较为新颖,但实验结果不好。
同时采用三元组损失时,原始的采样方法破坏了视频序列的连续性(当然可以通过修改代码的方式保持连续性,但作者给出的代码没有考虑这个)
总而言之,时间建模方法仍然值得我们去探索。
结语
本文的原始代码地址为:https://github.com/jiyanggao/Video-Person-ReID
我对原始代码进行了一些注释,地址为:https://github.com/AsuradaYuci/understand_videobased_reid
最后打个广告,我收集了近几年的一些视频reid论文以及相应的代码,放在我的github中:[链接],欢迎大家star和fork,有空会继续更新的, 谢谢啦。