目标检测中边框回归的坐标参数化说明
1. 原始公式
目标检测中边框回归的坐标参数化如下(公式源自Faster R-CNN论文):
t
x
=
(
x
−
x
a
)
/
w
a
,
t
y
=
(
y
−
y
a
)
/
h
a
t
w
=
log
(
w
/
w
a
)
,
t
h
=
log
(
h
/
h
a
)
t
x
∗
=
(
x
∗
−
x
a
)
/
w
a
,
t
y
∗
=
(
y
∗
−
y
a
)
/
h
a
t
w
∗
=
log
(
w
∗
/
w
a
)
,
t
h
∗
=
log
(
h
∗
/
h
a
)
t_{x} = (x - x_{a}) / w_{a}, \quad t_{y} = (y - y_{a}) / h_{a} \\ t_{w} = \log(w / w_{a}), \quad t_{h} = \log(h / h_{a}) \\ t^{*}_{x} = (x^{*} - x_{a}) / w_{a}, \quad t^{*}_{y} = (y^{*} - y_{a}) / h_{a} \\ t^{*}_{w} = \log(w^{*} / w_{a}), \quad t^{*}_{h} = \log(h^{*} / h_{a})
tx=(x−xa)/wa,ty=(y−ya)/hatw=log(w/wa),th=log(h/ha)tx∗=(x∗−xa)/wa,ty∗=(y∗−ya)/hatw∗=log(w∗/wa),th∗=log(h∗/ha)
上述公式可看成是从一个锚框anchor到邻近的真值框ground-truth box的边框回归任务。
1.1 参数说明
- x a / y a / w a / h a x_{a}/y_{a}/w_{a}/h_{a} xa/ya/wa/ha 为锚框(Anchor Bounding Boxes)的像素坐标;
- x ∗ / y ∗ / w ∗ / h ∗ x^{*}/y^{*}/w^{*}/h^{*} x∗/y∗/w∗/h∗ 为真值框(Ground-Truth Bounding Boxes)的像素坐标;
- x / y / w / h x/y/w/h x/y/w/h 为预测框(Predicted/Detected Bounding Boxes)的像素坐标;
- t x / t y / t w / t h t_{x}/t_{y}/t_{w}/t_{h} tx/ty/tw/th 为检测器Head的regression分支输出的预测结果,即预测的真实物体(预测框)相对于锚框的偏移量(Deltas);
- t x ∗ / t y ∗ / t w ∗ / t h ∗ t^{*}_{x}/t^{*}_{y}/t^{*}_{w}/t^{*}_{h} tx∗/ty∗/tw∗/th∗ 为边框偏移量的目标值,或叫边框偏移量真值(target_deltas),即真实物体(真值框)实际相对于锚框的准确偏移量。
1.2 分析
一般看到的编码(Encode)和解码(Decode)操作大概如下:
-
编码(Encode):根据真值框的参数化坐标 x ∗ / y ∗ / w ∗ / h ∗ x^{*}/y^{*}/w^{*}/h^{*} x∗/y∗/w∗/h∗跟锚框参数化坐标 x a / y a / w a / h a x_{a}/y_{a}/w_{a}/h_{a} xa/ya/wa/ha可以计算得到边框的偏移量真值 t x ∗ / t y ∗ / t w ∗ / t h ∗ t^{*}_{x}/t^{*}_{y}/t^{*}_{w}/t^{*}_{h} tx∗/ty∗/tw∗/th∗,可与网络预测的边框偏移量 t x / t y / t w / t h t_{x}/t_{y}/t_{w}/t_{h} tx/ty/tw/th一起用于计算回归损失。
-
解码(Decode):根据预测边框偏移量 t x / t y / t w / t h t_{x}/t_{y}/t_{w}/t_{h} tx/ty/tw/th跟锚框参数化坐标 x a / y a / w a / h a x_{a}/y_{a}/w_{a}/h_{a} xa/ya/wa/ha可以计算得到预测框的实际坐标值 x / y / w / h x/y/w/h x/y/w/h。
-
一般边框的数据格式是 ( x t o p − l e f t , y t o p − l e f t , x b o t t o m − r i g h t , y b o t t o m r i g h t ) (x_{top-left}, y_{top-left}, x_{bottom-right}, y_{bottom_right}) (xtop−left,ytop−left,xbottom−right,ybottomright),而不是 ( x c e n t e r , y c e n t e r , w i d t h , h e i g h t ) (x_{center}, y_{center}, width, height) (xcenter,ycenter,width,height)
-
偏移量的计算中,位置量的偏移(如 t x t_{x} tx和 t y t_{y} ty)进行了归一化处理(除了锚框的宽和高),而宽高的偏移(如t_{w}和t_{h})则进行了对数处理,这些处理可进一步限制偏移量的范围,偏于预测以及网络收敛
2. 相关公式演变与说明
(更新于2020.7.27)
在SSD的边框回归公式中,有个额外的参数 ‘variance’ (下面用
σ
\sigma
σ表示),其公式大概如下:
t
x
∗
σ
x
y
=
(
x
−
x
a
)
/
w
a
,
t
y
∗
σ
x
y
=
(
y
−
y
a
)
/
h
a
t
w
∗
σ
w
h
=
log
(
w
/
w
a
)
,
t
h
∗
σ
w
h
=
log
(
h
/
h
a
)
t
x
∗
=
(
x
∗
−
x
a
)
/
(
w
a
∗
σ
x
y
)
,
t
y
∗
=
(
y
∗
−
y
a
)
/
(
h
a
∗
σ
x
y
)
t
w
∗
=
log
(
w
∗
/
w
a
)
/
σ
w
h
,
t
h
∗
=
log
(
h
∗
/
h
a
)
/
σ
w
h
t_{x} * \sigma_{xy} = (x - x_{a}) / w_{a}, \quad t_{y} * \sigma_{xy} = (y - y_{a}) / h_{a} \\ t_{w} * \sigma_{wh} = \log(w / w_{a}), \quad t_{h} * \sigma_{wh} = \log(h / h_{a}) \\ t^{*}_{x} = (x^{*} - x_{a}) / (w_{a} * \sigma_{xy}), \quad t^{*}_{y} = (y^{*} - y_{a}) / (h_{a} * \sigma_{xy}) \\ t^{*}_{w} = \log(w^{*} / w_{a}) / \sigma_{wh}, \quad t^{*}_{h} = \log(h^{*} / h_{a})/ \sigma_{wh}
tx∗σxy=(x−xa)/wa,ty∗σxy=(y−ya)/hatw∗σwh=log(w/wa),th∗σwh=log(h/ha)tx∗=(x∗−xa)/(wa∗σxy),ty∗=(y∗−ya)/(ha∗σxy)tw∗=log(w∗/wa)/σwh,th∗=log(h∗/ha)/σwh
其中
σ
x
y
\sigma_{xy}
σxy一般是0.1,
σ
w
h
\sigma_{wh}
σwh一般是0.2。对此原作者在Github上的解释翻译过来就是:添加这个variance这个参数的主要目的是为了放大梯度(应该是要放大损失,加速收敛),也可认为是边框坐标周围的方差为0.1的高斯分布。
(更新于2020.7.29)
YOLO v2的作者Joseph Redmon指出使用Faster R-CNN中标准的边框回归方法会遭遇一个问题——模型在训练时会不稳定,特别是在早期迭代中,而大部分的不稳定都来源于预测边框的中心点 ( x , y ) (x, y) (x,y)。
从原公式(此文最上面的公式)推导出的中心点位置计算公式如下:
x
=
t
x
∗
w
a
+
x
a
y
=
t
y
∗
h
a
+
y
a
x = t_{x} * w_{a} + x_{a} \\ y = t_{y} * h_{a} + y_{a} \\
x=tx∗wa+xay=ty∗ha+ya
Redmon认为这样的公式没有限制预测的边框偏移量,导致边框的中心点可能预测在图像的任何一点上,而忽略了是哪个点预测的边框。例如,当 t x = ± 1 t_{x} = \pm 1 tx=±1时,预测的边框将偏离锚框一个宽度那么多。网络的随机初始化会让模型花很长一段时间去稳定地预测合理的偏移量。
因此,Redmon提出了新的回归公式,不再预测相对于边框中心点的偏移量,而是像YOLO v1那也预测相对于边框中心点对应的网格单元的偏移量:
b x = σ ( t x ) + c x b y = σ ( t y ) + c y b w = p w e t w b h = p h e t h P r ( o b j e c t ) ∗ I O U ( b , o b j e c t ) = σ ( t o ) b_{x} = \sigma (t_{x}) + c_{x} \\ b_{y} = \sigma (t_{y}) + c_{y} \\ b_{w} = p_{w} e^{t_{w}} \\ b_{h} = p_{h} e^{t_{h}} \\ Pr(object) * IOU(b, object) = \sigma(t_{o}) bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=phethPr(object)∗IOU(b,object)=σ(to)
其中预测框的宽高 ( b w , b h ) (b_{w}, b_{h}) (bw,bh)仍是通过预测相对于锚框的宽高 ( p w , p h ) (p_{w}, p_{h}) (pw,ph)的偏移量 ( t w , t h ) (t_{w}, t_{h}) (tw,th)得到,在Faster R-CNN中对于中心点位置 ( x , y ) (x, y) (x,y)的预测是根据相对于锚框中心点位置 ( x a , y a ) (x_{a}, y_{a}) (xa,ya)的偏移量计算得来的,而上面的公式对于中心点位置 ( b x , b y ) (b_{x}, b_{y}) (bx,by)的预测是根据相对于锚框中心点所在网格单元(grid cell)的左上角坐标 ( c x , c y ) (c_{x}, c_{y}) (cx,cy)的偏移量 ( t x , t y ) (t_{x}, t_{y}) (tx,ty)计算得来的,通过Sigmoid函数 σ ( x ) = 1 / ( 1 + exp ( − x ) ) \sigma(x) = 1 / (1 + \exp(-x)) σ(x)=1/(1+exp(−x))可以将偏移量 ( t x , t y ) (t_{x}, t_{y}) (tx,ty)限制在(0, 1)之间,也就是说预测框的中心点肯定还会落在锚框的中心点所在网格单元中,这样就限制了预测的范围,将有利于模型的收敛。 上面公式中的最后一行是对边框置信度 t o t_{o} to的预测。(下图为YOLO v2论文中对上述公式的可视化解释。)
Redmon提出的这种预测边框中心点的方式加上通过聚类算法设计的锚框尺寸,相比于Faster R-CNN的标准边框回归,可以给YOLO带来(在PASCAL VOC数据集上)大概5%的精度以及7%的召回率的提升。
(更新于2020.8.15)
YOLO上面的回归公式会存在一个问题:由于sigmoid函数 σ ( ⋅ ) \sigma(\cdot) σ(⋅)的值域是 ( 0 , 1 ) (0, 1) (0,1),那么最终网络预测的边框的中心点将只会在网格单元内部,而不能落在网格单元边界上。即若网格单元的左上角坐标为 ( C x , C y ) (C_x, C_y) (Cx,Cy),那么预测框的中心点的横坐标只能取值为 ( C x , C x + 1 ) (C_x, C_x + 1) (Cx,Cx+1),相应的纵坐标只能取值为 ( C y , C y + 1 ) (C_y, C_y + 1) (Cy,Cy+1)。
YOLO v4作者AB大神称这个问题为grid sensitivity,而AB大神为了解决/消除(eliminate)这个问题,提出一个简单的解决办法:给sigmoid的输出值乘上一个大小超过1.0的因子(如1.1),这样预测框的中心点就可以取值在网格单元边界上了。
(更新与2020.8.19)
YOLO v4中通过给sigmoid输出值乘上一个大于1的因子,从而消除了grid sensitivity的问题,但其他公式仍然没有改变,这也就意味着YOLO v4可能会遭受与YOLO v2v3一样的问题,即原公式中的致命问题:宽度Width与高度Height的取值是无界的 (如 w ∼ exp ( t w ) w \sim \exp(t_{w}) w∼exp(tw)),这就可能导致消失的梯度(runaway gradients)、不稳定(instabilities)、NaN值损失(NaN losses)等,最终导致训练失败。
因此在YOLO v5(此部分编辑时v5尚未完成,此版本仍未得到普遍认可)中,v5的作者对公式进行了修改:对网络预测的所有偏移量都作sigmoid映射,同时确保中心点保持不变。具体公式如下方第一张图片中所示,此公式可以将预测框的宽和高限制为anchor的宽和高的0~4倍之间,同时锚框(anchor)与目标框(target)的匹配也被更新为基于宽-高倍数,其中使用了一个上界阈值为0.4的超参数。此外此公式的中心点计算不会遭受grid sensitivity的问题,因中心点坐标(以横坐标为例)的取值范围为 ( C x − 0.5 , C x + 1.5 ) (C_{x} - 0.5, C_{x} + 1.5) (Cx−0.5,Cx+1.5)。
第二张图片为宽高公式的输入输出映射图,2与1.6为2sigma的幂,用于控制宽高的取值范围,幂为2时取值范围是(0, 4),幂为1.6时取值范围为(0, 3),幂为1时则为(0, 2)。
3. 参考文献
- 《深度学习之PyTorch物体检测实战》- 董洪义
- Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
- The meanings of parameter “variance” in PriorBox layer
- YOLO9000: Better, Faster, Stronger
- YOLOv4: Optimal Speed and Accuracy of Object Detection
- Want to figure out critical algorithm of Detect layer #471