yolov3里有很多细节需要注意,下面就把那里面的一些细节总结一下。
1. YOLOv3的先验边框
先验边框,也可以叫建议框,锚框(anchorbox),是对coco数据集的真实框KMEANS聚类获得,对目标物体的真实框具有代表性。在yolov3中,3个不同深度的网络输出52*52,26*26,13*13
这三种不同尺寸的特征图,一共9个建议框,将这9个建议框分为3组,每组建议框和每种特征图一一对应。这里借鉴了SSD网络的思想:不同深度网络检测不同大小的物体。52*52
的特征图大,感受野小,因此对小物体更敏感。13*13
特征图小,感受野大,因此对大物体更敏感。
"anchor box是对coco数据集聚类获得"
ANCHORS_GROUP_KMEANS = {
52: [[10, 13], [16, 30], [33, 23]],
26: [[30, 61], [62, 45], [59, 119]],
13: [[116, 90], [156, 198], [373, 326]]}
2. 网络的输出
YOLOv3会为每个边界框预测4个值:tx、ty、tw和th,目标中心的所在网格与图像左上角的偏移是(cx, cy),它对应的建议框的宽和高为pw、ph。那么预测值将会由以下式子给出:
以原图大小为416*416
的网络为例,若特征图大小为13*13
,则将原图划分为13*13
个正方形网格,每个网格边长为32。每个网格与特征图上的点一一对应,因此,可以通过特征图上点的索引得到每个网格在原图上的位置,特征图索引*32
就是cx和cy。
σ
(
t
x
)
\sigma(t_{x})
σ(tx)就是中心点相对网格左上角的偏移率,其中
t
x
t_{x}
tx是网络的输出,经过sigmoid压缩到(0-1)之间。
b
x
=
σ
(
t
x
)
∗
32
+
c
x
∗
32
b_{x} = \sigma (t_{x})*32 + c_{x}*32
bx=σ(tx)∗32+cx∗32,32为对应的每个网格的像素,如果特征图为26*26
,则每个网格边长16像素,如果特征图为52*52
,每个网格边长8像素。训练时可采用损失MSELoss(),而非BCEWithLogits(),即直接输出,不用sigmoid激活,这样效果更佳。
b
w
b_{w}
bw是目标框的宽,
p
w
p_{w}
pw是建议框的宽,
e
t
w
e^{t_{w}}
etw 就是目标框的宽相对于建议框宽的偏移率,而网络输出的
t
w
t_{w}
tw实际上是偏移率的对数。因此,在做标签的时候,就需要求出真实框相对于建议框的偏移率并取对数,以对数值作为标签。
3. YOLOv3中计算iou的方式
计算iou有很多种方式,比如小框比大框,交集比小框,交集比并集等。
在做标签时,采用小框比大框的方式。这是因为目标框和建议框同中心点,因此采用小框比大框比较合适。
在侦测时,采用交集比最小框的方式,这是因为侦测时各个预测框比较容易出现大框套小框的情况,因此采用交集比并集。
4.分类方法
采用多标签分类方法,而不是多分类,因此,不再使用softmax,而使用sigmoid+二分类交叉熵,pytorch中用BCEWithLogits()函数。
每个框都会使用多标签分类来预测边框中可能包含的类。我们不再使用softmax,因为我们发现它无助于提升模型的性能,取而代之的是单独的逻辑分类器。在训练过程中,我们用二元交叉熵损失来评价类别预测。
当我们把YOLOv3用在更复杂的数据集时,比如Open Images数据集[7],上述操作就会有很大的帮助。Open Images中包含了大量重叠的标签(如女性和人),如果使用softmax,它会强加一个假设,即每个框只有一个类别,然而事实常常不是如此。相比之下,多标签分类方法能更好地拟合这些数据。
5.网络结构
YOLOv3中变动最大的就是网络模型(darknet53)
网络结构
附上链接:
论文地址:YOLOv3: An Incremental Improvement
翻译:YOLOv3论文全文完整理解翻译