本文是“Siam 系列网络深度解析”之三,重点对比并深入剖析SiamMask在跟踪与分割任务中,分类分支、回归分支和Mask分支的不同设计思路、网络结构与训练策略。
SiamMask以多任务学习的方式,实现了目标跟踪(Tracking)与目标分割(Segmentation)的统一框架。模型共有三条并行分支:分类分支(Classification Head)、回归分支(Regression Head)和Mask分支(Mask Head)。虽然它们都基于同一个深度相关特征图 g ∈ R C × H × W g\in\mathbb R^{C\times H\times W} g∈RC×H×W,并且都执行二分类或回归操作,但在设计目标、网络结构、输入/输出粒度、损失函数及训练方式等方面均存在本质区别。
本篇文章将从以下角度展开:
分支 | 任务目标 | 输出意义 |
---|---|---|
分类分支 | 判断某空间位置是否为目标中心 | 前景概率热力图 S ∈ [ 0 , 1 ] 1 × H × W \mathbf S\in[0,1]^{1\times H\times W} S∈[0,1]1×H×W |
回归分支 | 回归Anchor相对于真实框的偏移量 | 边界框偏移量 Δ = ( l , t , r , b ) ∈ R 4 × H × W \Delta=(l,t,r,b)\in\mathbb R^{4\times H\times W} Δ=(l,t,r,b)∈R4×H×W |
Mask分支 | 对目标区域进行像素级前景/背景分割 | 掩膜概率图 M ^ ∈ [ 0 , 1 ] 1 × H m × W m \hat M\in[0,1]^{1\times H_m\times W_m} M^∈[0,1]1×Hm×Wm |
示例代码:
self.cls_conv = nn.Conv2d(C, C, kernel_size=3, padding=1)
self.cls_score = nn.Conv2d(C, 1, kernel_size=1)
# forward:
feat = F.relu(self.cls_conv(g)) # [B,C,H,W]
score = torch.sigmoid(self.cls_score(feat)) # [B,1,H,W]
示例代码:
self.reg_conv = nn.Conv2d(C, C, kernel_size=3, padding=1)
self.reg_offset = nn.Conv2d(C, 4, kernel_size=1)
# forward:
feat = F.relu(self.reg_conv(g)) # [B,C,H,W]
offset = self.reg_offset(feat) # [B,4,H,W]
示例代码:
# RoIAlign后得到局部特征 [B,C,H,W]
x = roi_align(feature_map, boxes, output_size=(H,W))
x = F.relu(self.conv1(x))
x = F.relu(self.conv2(x))
x = F.convTranspose2d(x, ...) # 上采样
mask = torch.sigmoid(self.conv_final(x)) # [B,1,H_m,W_m]
分支 | 输入特征 | 输出形式 | 下游依赖 |
---|---|---|---|
分类分支 | 全局 DW-XCorr 特征 g g g | 热力图 S \mathbf S S | 决定回归与Mask的位置 |
回归分支 | 全局 DW-XCorr 特征 g g g | 偏移量 Δ \Delta Δ | 生成最终边界框 |
Mask分支 | RoIAlign 裁剪特征 | 掩膜 M ^ \hat M M^ | 精细分割 |
二元交叉熵:
L c l s = − ∑ i , j [ y i , j log S i , j + ( 1 − y i , j ) log ( 1 − S i , j ) ] \mathcal L_{cls} = -\sum_{i,j}\bigl[y_{i,j}\log S_{i,j} + (1-y_{i,j})\log(1 - S_{i,j})\bigr] Lcls=−i,j∑[yi,jlogSi,j+(1−yi,j)log(1−Si,j)]
Smooth L1 Loss:
L r e g = ∑ c ∈ { l , t , r , b } ∑ i , j S m o o t h L 1 ( Δ c , i , j − Δ c , i , j ∗ ) \mathcal L_{reg} = \sum_{c\in\{l,t,r,b\}} \sum_{i,j} \mathrm{SmoothL1}(\Delta_{c,i,j} - \Delta^*_{c,i,j}) Lreg=c∈{l,t,r,b}∑i,j∑SmoothL1(Δc,i,j−Δc,i,j∗)
像素级二元交叉熵:
L m a s k = − 1 H m W m ∑ u , v [ M u , v ∗ log M ^ u , v + ( 1 − M u , v ∗ ) log ( 1 − M ^ u , v ) ] \mathcal L_{mask} = -\frac{1}{H_mW_m}\sum_{u,v}\bigl[M^*_{u,v}\log\hat M_{u,v} + (1-M^*_{u,v})\log(1-\hat M_{u,v})\bigr] Lmask=−HmWm1u,v∑[Mu,v∗logM^u,v+(1−Mu,v∗)log(1−M^u,v)]
多任务加权:
L t o t a l = λ c l s L c l s + λ r e g L r e g + λ m a s k L m a s k \mathcal L_{total} = \lambda_{cls}\mathcal L_{cls} + \lambda_{reg}\mathcal L_{reg} + \lambda_{mask}\mathcal L_{mask} Ltotal=λclsLcls+λregLreg+λmaskLmask
常见设定: λ c l s = 1 , λ r e g = 1.2 , λ m a s k = 32 \lambda_{cls}=1,\lambda_{reg}=1.2,\lambda_{mask}=32 λcls=1,λreg=1.2,λmask=32。
下面对比三者输出:
+----------------------+----------------------+----------------------+
| Classification | BBox Regression | Mask |
+----------------------+----------------------+----------------------+
| 17×17 heatmap | 4×17×17 offsets | 63×63 mask |
+----------------------+----------------------+----------------------+
(此处可插入示意图:热力图、边框图、掩膜图)
三者分工明确、协同高效,共同构成了SiamMask的跟踪+分割能力。
下篇我们将撰写:
《分类分支 vs Mask分支:为什么不能一个分支包办所有任务?》
敬请期待!