论文链接:http://arxiv.org/abs/1907.09702
论文代码:
https://github.com/PaddlePaddle/…(PaddlePaddle)
https://github.com/JJBOY/…(Pytorch)
原作者知乎解析:https://zhuanlan.zhihu.com/p/75
BSN方法回顾
相比“自上而下”的方法,BSN生成的提名具有更加精确的时间边界和更加灵活的持续时间。
优点:
框架:提出了一种全新的且非常有效的时序提名生成框架,能够产生满足(1)时长灵活(2)边界准确(3)评分可靠的时序动作提名;
灵活性:BSN方法的模块非常简单且灵活,能够灵活地应用于不同的垂类场景。
但也存在一些问题:
1.BSN中提名特征构建和置信度评估过程无法并行地对Proposals处理,导致效率低下:BSN中,每个window会生成各自的动作发生概率集合,以及不同位置和持续时间的proposals。window需要依赖各自的概率构建不同的插值函数对proposals进行特征采样。
2.BSN中构造的Proposal特征过于简单,无法很好地捕捉时间上下文:BSN从TEM预测的动作发生概率中采样BSP特征,相比于直接使用原始特征,其丢失了很多信息。同时,其也缺乏相邻Proposals之间的特征交互。
3.BSN是多阶段而非统一的框架:BSN分为三个阶段,PEM的训练依赖于前面TEM和PGM模块的输出,导致整体框架的繁琐,缺乏统一性。
BMN改进:针对以上问题,BSN的原作者Tianwei Lin等人在ICCV2019上提出了边界匹配网络(Boundary-Matching Network,BMN),对BSN进行了改进。主要贡献包括下列三个方面:
1.引入了边界匹配机制来评估密集分布的提名的置信度,该机制可以很容易地嵌入到网络中。
2.提出边界匹配网络(BMN),在BMN的两个分支中同时生成时间边界概率序列和BM置信图,并将其作为一个统一的框架进行联合训练。
3.大量的实验表明,BMN可以获得比其他SOTA方法更好的提名生成性能。具有显著的效率、很强的通用性和更好的时间动作检测性能。
BMN运行逻辑:
因为BMN是一个End-to-End网络,相比于BSN的三阶段模型,其更加简洁,只包括一个训练和一个推断过程.
特征抽取
同BSN一样,BMN采用相同的双流网络来提取空间和时间特征,并将其进行拼接,输出
(
l
w
,
400
)
\left(l_{w}, 400\right)
(lw,400) 大小的特征,如下图所示。其中400表示拼接后的特征维度。而
l
w
l_w
lw表示:每个视频以相同的时间间 隔
σ
\sigma
σ 进行采样,送入双流网络,因为每个视频的帧数不同,能得到不同时间长度
l
w
=
l
v
/
σ
l_{w}=l_{v} / \sigma
lw=lv/σ 的特 征。
BMN
BMN由三个模块组成:
1.Base Module:通过两个1D卷积来增大时间感受野,并作为主干为后续的TEM和PEM模块提供共享特征。
2.Temporal Evaluation Module(TEM):利用Base Module的输出,生成每个时间位置动作开始和结束的概率。
3.Proposal Evaluation Module (PEM):利用Base Module的输出,经过BM Layer生成BM Feature Map。BM Feature Map再经过一系列卷积层处理后得到BM Confidence Map,作为Proposals的置信度分数。
Base Module
与BSN不同,为了方便后续端到端的训练,BMN先引入了一个基本模块,其为TEM和PEM模块提供共享的特征,并采用时间卷积来增大感受野。
输入: Feature Extraction中得到的大小为
(
l
w
,
400
)
\left(l_{w}, 400\right)
(lw,400) 的特征
F
w
F_{w}
Fw ,对应一个Window中的
l
w
l_{w}
lw 个 时间位置。
结构: Base Module由两个kernel_size
=
3
=3
=3 , groups
=
4
=4
=4 的
1
D
1 \mathrm{D}
1D 卷积组成,融合邻域内时间位置的信息:
### Base Module ###
# feat_dim: 400
# hidden_dim_1d: 256
# input: (B, 400, l_w)
self.x_1d_b = nn.Sequential(
nn.Conv1d(self.feat_dim, self.hidden_dim_1d, kernel_size=3, padding=1, groups=4),
nn.ReLU(inplace=True),
nn.Conv1d(self.hidden_dim_1d, self.hidden_dim_1d, kernel_size=3, padding=1, groups=4),
nn.ReLU(inplace=True)
)
### forward ###:
base_feature = self.x_1d_b(x)
输出: 经过两个1D卷积,通道数变为 256 ,时间长度维持
l
w
l_{w}
lw 。因此输出base_feature维度为
(
B
,
256
,
l
w
)
\left(B, 256, l_{w}\right)
(B,256,lw) 。这样window信息可以被表示为
ω
=
{
t
w
,
s
,
t
w
,
e
,
Ψ
w
,
F
w
}
\omega=\left\{t_{w, s}, t_{w, e}, \Psi_{w}, F_{w}\right\}
ω={tw,s,tw,e,Ψw,Fw} 。
t
w
,
s
t_{w, s}
tw,s 和
t
w
,
e
t_{w, e}
tw,e 分别 表示该window在整个视频中的开始和结束时间,
Ψ
w
\Psi_{w}
Ψw 表示该window中包含的真实动作实例标 注,而
F
w
F_{w}
Fw 即Base Module中得到的特征。
总结:通过共享主干的方法,BMN中不再需要先生成概率,再构造每个proposal的BSP特征,而 是直接从Base Module的输入构造proposal特征。这为BMN的端到端训练创造了可能。
Temporal Evaluation Module
提起TEM,BSN中也有一个同名的模块。两篇文章中TEM模块的作用和结构类似但也略有区别。从输入输出的角度来看,这里的Base Module和TEM模块合起来的作用近似于BSN中的TEM模块。而且在BSN中,TEM模块需要生成三个值,包括动作发生,开始和结束的概率。而BMN中,TEM模块只需要生成后两个值。如下图中左边的红色实线(Starting概率曲线)和蓝色虚线(Ending概率曲线)。同时,两个TEM模块都需要监督信号进行监督。但是,BSN中的TEM模块作为分阶段训练中的第一阶段,完成该模块的训练后才能进行后续步骤,而BMN为端到端的模型。
输入: Base Module作为共享主干,其输出的
(
B
,
256
,
l
w
)
\left(B, 256, l_{w}\right)
(B,256,lw) 被同时输入到两个模块,左边即为这 里的TEM模块。
结构:对于开始和结束分支,都包含一个核为 3 的1D卷积(进行时间信息融合)和一个核为1的1D 卷积(改变通道数匹配输出)。最后利用sigmoid函数生成相应范围为
[
0
,
1
]
[0,1]
[0,1] 的概率。
### Temporal Evaluation Module ###
# hidden_dim_1d: 256
# input: (B, 256, l_w)
self.x_1d_s = nn.Sequential(
nn.Conv1d(self.hidden_dim_1d, self.hidden_dim_1d, kernel_size=3, padding=1, groups=4),
nn.ReLU(inplace=True),
nn.Conv1d(self.hidden_dim_1d, 1, kernel_size=1),
nn.Sigmoid()
)
self.x_1d_e = nn.Sequential(
nn.Conv1d(self.hidden_dim_1d, self.hidden_dim_1d, kernel_size=3, padding=1, groups=4),
nn.ReLU(inplace=True),
nn.Conv1d(self.hidden_dim_1d, 1, kernel_size=1),
nn.Sigmoid()
)
### forward ###
start = self.x_1d_s(base_feature).squeeze(1)
end = self.x_1d_e(base_feature).squeeze(1)
输出: 对于每一个观测window,得到
l
w
l_{w}
lw 个时间位置的开始概率
P
S
,
w
=
{
p
t
n
s
}
n
=
1
l
w
P_{S, w}=\left\{p_{t_{n}}^{s}\right\}_{n=1}^{l_{w}}
PS,w={ptns}n=1lw 和结束概率
P
E
,
w
=
{
p
t
n
e
}
n
=
1
l
w
P_{E, w}=\left\{p_{t_{n}}^{e}\right\}_{n=1}^{l_{w}}
PE,w={ptne}n=1lw 。大小皆为
(
B
,
l
w
)
\left(B, l_{w}\right)
(B,lw) 。
标签: BMN采用与BSN相同的TEM标签生成方式,利用区域的重叠程度来对预测出的概率进行监督。具体来说,对于window内每一个真实动作实例
φ
g
=
(
t
s
,
t
e
)
\varphi_{g}=\left(t_{s}, t_{e}\right)
φg=(ts,te) ,定义其开始和结束区域分别为
r
S
=
[
t
s
−
d
g
/
10
,
t
s
+
d
g
/
10
]
,
r
E
=
[
t
e
−
d
g
/
10
,
t
e
+
d
g
/
10
]
r_{S}=\left[t_{s}-d_{g} / 10, t_{s}+d_{g} / 10\right] , r_{E}=\left[t_{e}-d_{g} / 10, t_{e}+d_{g} / 10\right]
rS=[ts−dg/10,ts+dg/10],rE=[te−dg/10,te+dg/10] 。其中
d
g
=
t
e
−
t
s
d_{g}=t_{e}-t_{s}
dg=te−ts ,表示动作实例的持续时间。对于window内每一个时间位置
t
n
t_{n}
tn ,定义属于它的局部区域为
r
t
n
=
[
t
n
−
d
f
/
2
,
t
n
+
d
f
/
2
]
r_{t_{n}}=\left[t_{n}-d_{f} / 2, t_{n}+d_{f} / 2\right]
rtn=[tn−df/2,tn+df/2] ,其中
d
f
=
t
n
−
t
n
−
1
d_{f}=t_{n}-t_{n-1}
df=tn−tn−1 ,表示两个时间位置间隔。 然后,将
r
t
n
r_{t_{n}}
rtn 与每一个实例的
r
S
r_{S}
rS 和
r
E
r_{E}
rE 分别计算重叠程度IoR。
O
\mathrm{O}
O 。R表示重叠区域与
r
t
n
r_{t_{n}}
rtn 的比 值。取其中的最大值作为
g
t
n
s
g_{t_{n}}^{s}
gtns 和
g
t
n
e
g_{t_{n}}^{e}
gtne ,得到标签集合
G
S
,
w
=
{
g
t
n
s
}
n
=
1
l
w
,
G
E
,
w
=
{
g
t
n
e
}
n
=
1
l
w
G_{S, w}=\left\{g_{t_{n}}^{s}\right\}_{n=1}^{l_{w}} , G_{E, w}=\left\{g_{t_{n}}^{e}\right\}_{n=1}^{l_{w}}
GS,w={gtns}n=1lw,GE,w={gtne}n=1lw
# temporal_scale: 100
# temporal_gap: 0.01
# boundary_ratio: 0.5
# generate R_s and R_e
gt_bbox = np.array(gt_bbox)
gt_xmins = gt_bbox[:, 0]
gt_xmaxs = gt_bbox[:, 1]
gt_lens = gt_xmaxs - gt_xmins
gt_len_small = np.maximum(self.temporal_gap, self.boundary_ratio * gt_lens)
gt_start_bboxs = np.stack((gt_xmins - gt_len_small / 2, \
gt_xmins + gt_len_small / 2), axis=1)
gt_end_bboxs = np.stack((gt_xmaxs - gt_len_small / 2, \
gt_xmaxs + gt_len_small / 2), axis=1)
# calculate the ioa for all timestamp
anchor_xmin = [self.temporal_gap * (i - 0.5) for i in range(self.temporal_scale)]
anchor_xmax = [self.temporal_gap * (i + 0.5) for i in range(self.temporal_scale)]
match_score_start = []
for jdx in range(len(anchor_xmin)):
match_score_start.append(np.max(ioa_with_anchors(anchor_xmin[jdx], anchor_xmax[jdx],
gt_start_bboxs[:, 0], gt_start_bboxs[:, 1])))
match_score_end = []
for jdx in range(len(anchor_xmin)):
match_score_end.append(np.max(ioa_with_anchors(anchor_xmin[jdx], anchor_xmax[jdx],
gt_end_bboxs[:, 0], gt_end_bboxs[:, 1])))
match_score_start = torch.Tensor(match_score_start)
match_score_end = torch.Tensor(match_score_end)
损失:为了保证得到的概率的可靠性,需要损失函数对TEM进行监督。这一步也与BSN中基本一 致。具体而言,损失函数可以分为两部分:
L
T
E
M
=
L
b
l
(
P
S
,
G
S
)
+
L
b
l
(
P
E
,
G
E
)
L_{T E M}=L_{b l}\left(P_{S}, G_{S}\right)+L_{b l}\left(P_{E}, G_{E}\right)
LTEM=Lbl(PS,GS)+Lbl(PE,GE)
L
b
l
(
P
S
,
G
S
)
L_{b l}\left(P_{S}, G_{S}\right)
Lbl(PS,GS) 对应动作开始概率预测的损失,
L
b
l
(
P
E
,
G
E
)
L_{b l}\left(P_{E}, G_{E}\right)
Lbl(PE,GE) 对应动作结束概率预测的损失。
L
b
l
L_{b l}
Lbl 的计算方法如下:
L
b
l
=
1
l
w
∑
i
=
1
l
w
(
α
+
b
i
log
(
p
i
)
+
α
−
(
1
−
b
i
)
log
(
1
−
p
i
)
)
L_{b l}=\frac{1}{l_{w}} \sum_{i=1}^{l_{w}}\left(\alpha^{+} b_{i} \log \left(p_{i}\right)+\alpha^{-}\left(1-b_{i}\right) \log \left(1-p_{i}\right)\right)
Lbl=lw1i=1∑lw(α+bilog(pi)+α−(1−bi)log(1−pi))
其中,
b
i
=
sign
(
g
i
−
θ
I
o
P
)
b_{i}=\operatorname{sign}\left(g_{i}-\theta_{I o P}\right)
bi=sign(gi−θIoP) ,其通过
g
i
g_{i}
gi 与阈值
θ
I
o
P
\theta_{I o P}
θIoP 的比较,将
[
0
,
1
]
[0,1]
[0,1] 连续分布的标签
g
i
g_{i}
gi 转 换为
{
0
,
1
}
\{0,1\}
{0,1} 的二值标签
b
i
b_{i}
bi ,阈值大小设置为
0.5
0.5
0.5 。
α
+
=
l
w
l
+
,
α
−
=
l
w
l
−
\alpha^{+}=\frac{l_{w}}{l+}, \alpha^{-}=\frac{l_{w}}{l-}
α+=l+lw,α−=l−lw 起到平衡正负样本的作 用。
l
+
l_{+}
l+和
l
−
l_{-}
l−分别代表正负样本的数目,即
b
i
b_{i}
bi 为 1 和为 0 的数目。
注意:BMN与BSN不同,是端到端的,这里只是得到了第一个loss,要联合后面PEM的loss进行联合训练。
Proposal Evaluation Module
在BSN中,我们需要经过TEM和PGM模块得到Proposals和相应的BSP特征,然后再将其送入PEM 模块,为每个Proposal生成一个置信度分数。但是,这样的做没办法端到端的训练,也无法实现 快速的推断。而PEM模块很好地解决了这两个问题。具体来看看它是怎么做到的。
PEM模块可以分为两个步骤:
1.利用Boundary-Matching Layer生成BM feature map:
M
F
∈
R
C
×
N
×
D
×
T
M_{F} \in R^{C \times N \times D \times T}
MF∈RC×N×D×T 。
2.将BM feature map经过几个卷积层,进一步得到BM confidence map:
M
C
∈
R
D
×
T
M_{C} \in R^{D \times T}
MC∈RD×T 。
BM feature map
首先介绍一下什么是BM置信度图。此处,我们将一个时序提名定义为一个开始边界和一个结束边界所构成的边界匹配对。然后我们按照时序提名开始边界的位置以及时序提名的长度将所有可能存在的时序提名结合成一个二维的边界匹配图。如下图所示,在这个图上的每一列上的时序提名具有相同的开始时间,而每一行上的时序提名具有相同的时序长度。此外,由于右下角这个三角形区域中的时序提名的结束时间超出了视频的范围,因此在训练和测试时不被纳入考虑。
输入:同TEM模块,使用Base Module的输出特征
(
B
,
256
,
l
w
)
\left(B, 256, l_{w}\right)
(B,256,lw) 作为输入。
结构: 在Boundary-Matching Layer之前,先会经过一个核为3的1D卷积:
# hidden_dim_1d: 256
# input: base_feature (B, 256, l_w)
# output: (B, 256, l_w)
self.x_1d_p = nn.Sequential(
nn.Conv1d(self.hidden_dim_1d, self.hidden_dim_1d, kernel_size=3, padding=1),
nn.ReLU(inplace=True)
### forward ###
confidence_map = self.x_1d_p(base_feature)
下面对Boundary-Matching Layer进行介绍。
为了更好地实现并行化,我们定义一个大小为
D
×
T
D \times T
D×T 的矩阵,如上图所示。其中T为时间位置的数目,即这里的
l
w
l_{w}
lw 。而
D
\mathbf{D}
D 表示预先设置好的Propsoal的最大持续时间。对于ActivityNet1.3,矩 阵大小为
100
×
100
100 \times 100
100×100 ;对于 THUMOS14,矩阵大小为
64
×
128
64 \times 128
64×128 。这样一来,矩阵中的每一个位置
(
i
,
j
)
(i, j)
(i,j) 代表了一个proposal
φ
i
,
j
\varphi_{i, j}
φi,j ,每个proposal对应的时间范围为[starting,
starting+duration],整体上涵盖了所有可能的proposal情况。如
(
48
,
42
)
(48 , 42)
(48,42) 代表了起始位置为 42,结束位置为 90 的proposal。图中的灰色区域,对应无法取到的值,该区域中的proposal的结 束位置会超过采样的时间长度
T
T
T 。
有了这样一个
D
×
T
D \times T
D×T 的矩阵,接着就需要为矩阵中的每一个位置(每一个proposal
φ
i
,
j
\varphi_{i, j}
φi,j )构造 一个大小为
C
×
N
C \times N
C×N 的特征,最终就可以得到
M
F
∈
R
C
×
N
×
D
×
T
M_{F} \in R^{C \times N \times D \times T}
MF∈RC×N×D×T 的BM特征图。下面具体来看 是如何构造特征的。
我们可以对每个proposal所处区域[starting, starting +duration]内的输入特征进行采样。其中, C等于输入的通道维度256,而
N
\mathrm{N}
N 代表在一个proposal中采样的点的个数,原文中取
N
=
32
N=32
N=32 。为 了更快地进行采样,对于每一个proposal
φ
i
,
j
\varphi_{i, j}
φi,j ,我们预先定义好一个单独的采样权重矩阵,记为
w
i
,
j
w_{i, j}
wi,j ,如上图中的sampling mask weight所示,其大小为
T
×
N
T \times N
T×N 。 使用大小为
C
×
T
C \times T
C×T (即
256
×
l
w
)
\left.256 \times l_{w}\right)
256×lw) 的输入特征
S
F
S_{F}
SF 与其进行矩阵乘法,即可以产生该proposal采样后的
C
×
N
C \times N
C×N 的 boundary-matching feature。这样一来,特征采样过程可以很简单快速地用一个矩阵乘法来实 现:
S
F
×
W
=
M
F
S_{F} \times W=M_{F}
SF×W=MF
其中,
S
F
∈
R
C
×
T
;
W
∈
R
T
×
N
×
D
×
T
S_{F} \in R^{C \times T} ; W \in R^{T \times N \times D \times T}
SF∈RC×T;W∈RT×N×D×T ,对应
D
×
T
D \times T
D×T 个proposals各自的采样权重
w
i
,
j
∈
R
T
×
N
w_{i, j} \in R^{T \times N}
wi,j∈RT×N ,当数据集的设置确定后,这个矩阵就可以确定下来; 而
M
F
∈
R
C
×
N
×
D
×
T
M_{F} \in R^{C \times N \times D \times T}
MF∈RC×N×D×T , 对应
D
×
T
D \times T
D×T 个proposals各自采样后的特征
m
i
,
j
f
∈
R
C
×
N
m_{i, j}^{f} \in R^{C \times N}
mi,jf∈RC×N 。
注意:实际使用时,对不同的window而言,所有可能的proposal的位置是固定的,所以采样 mask权重矩阵
W
W
W 对不同window是相同的,即对Batch维度是相同的。因此,实现是非常高效 的。
参考网站:
1.https://zhuanlan.zhihu.com/p/451759608
2.https://zhuanlan.zhihu.com/p/75444151
3 .https://blog.csdn.net/cxx654