参考:
https://arxiv.org/pdf/1804.02767.pdf
https://blog.csdn.net/weixin_43334693/article/details/129143961
网上有很多关于yolo的文章,有些东西没讲清楚,基于自己对论文的理解,也做一个按照自己的想法做的理解。
1. 预测框的改进
1.1 Anchor的引入
Anchor(锚框)的概念最早是在Faster R-CNN中被提出的。引入的目的是更好的预测边界框,也被叫做先验框。为什么叫先验框,我们知道yolov1里面根本没有这个概念,v1里面是直接预测两个边界框,根本没有先验框这个概念。引入先验框一个目的是让模型更容易预测边界框,也就是说提前告诉你一个框,然后去修正这个框,比你直接漫无目的预测就变得容易多了。
Anchor怎么设定?先验框的大小该多大,有几个?这些似乎成为了理解的关键。作者用k-means算法选出来9个了,按照大中小尺度分成了三组:
大: (116 × 90), (156 × 198), (373 × 326)
中: (30 × 61), (62 × 45), (59 × 119)
小:(10 × 13), (16 × 30), (33 × 23)
为何分成三组,因为最后作者预测三个尺度矩阵,我们往下接着看。
1.2 预测矩阵
网上很多这样的图,随便找了个。
我们刚才说了作者预测了三个尺度的矩阵,这三个矩阵分别是如下:
13
∗
13
∗
(
3
∗
(
4
+
1
+
80
)
13*13*(3*(4 + 1 + 80)
13∗13∗(3∗(4+1+80) 对应大: (116 × 90), (156 × 198), (373 × 326)
26
∗
26
∗
(
3
∗
(
4
+
1
+
80
)
26*26*(3*(4 + 1 + 80)
26∗26∗(3∗(4+1+80) 对应中: (30 × 61), (62 × 45), (59 × 119)
52
∗
52
∗
(
3
∗
(
4
+
1
+
80
)
52*52*(3*(4 + 1 + 80)
52∗52∗(3∗(4+1+80) 对应小:(10 × 13), (16 × 30), (33 × 23)
3就是我们对应的三个anchor,4是确定边界框的四个值,1就是置信度,80是类别
这样的话,我们可以通过优化anchor的w和h就能得到更加准确的预测框,不会再像v1那样漫无目的预测w和h了,那置信度呢?聪明的你是否已经猜到,直接拿anchor去和真实框做IOU不就得了,事实也如此,而v1是拿预测的框和真实框做IOU。需要注意的是,设置anchor的目的是来更好的预测w和h,不是中心点坐标的。因为不必要,而且anchor的设置本身也没中心点,更难以确定anchor的中心点,一会看预测的值就明白了。
1.3 预测框调整
上图是论文中的图,加了两个圈为了好描述一点
我们来看这个预测框到底有何神奇之处。首先:
- 网格是对图片划为一个个grid cell;
- 虚线框就是其中一个Anchor,宽为Pw,高为Ph;
- 蓝色框为真实框,蓝点为真实框中心,bw和bh为真实框的宽和高,也同时意味着中间这个grid cell是用来预测的;
- cx,cy就是当前用来预测的grid cell 的左上角(红色的圈)距离图片右上角(粉色的圈)
- tx,ty,tw,th是预测值,bx,by,bw,bh为预测边界框对应的中心和宽高,它于预测的边界框的值关系为:
b x = σ ( t x ) + c x b y = σ ( t y ) + c y b w = p w e t w b h = p w e t h b_x = \sigma{(t_x)} + c_x \\ b_y = \sigma{(t_y)} + c_y \\ b_w =p_we^{t_w}\\ b_h =p_we^{t_h}\\ bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pweth
2.网络结构的改进
2.1 FPN
Feature Pyramid Networks,特征金字塔
我们看一下中间那个粉色框就是FPN,我们知道CNN的低层特征富含细节信息但语义信息较弱,而高层特征则相反,拥有丰富的语义信息但空间分辨率较低。通俗一点是,比如一整图,经过一次卷积和经过100次卷积,那个更像一张图的结构,肯定是经过1次卷积的,100次卷积的都已经面部全非了,所以低层特征富含细节信息,那么反过来从感受野的角度考虑,经过100次卷积的每一个值是融合了很多,甚至圈图像素的值计算而来的,因此高层拥有丰富的语义信息,而细节信息少也就是空间分辨低,因为它一个值融合了那么多像素值哪还有什么分辨率。自己揣摩一下。
而FPN的做法,
第一个直接出来的是
13
∗
13
∗
255
13*13*255
13∗13∗255直接是高层信息,那么它自然而然适合预测大目标;
第二个是高层的通过上采样到中层(意思包好了高层信息)在和中层contact,即包含了中层的信息又有高层的信息,但是中层是直接过来的,高层是上采样过来的,自然适合预测中目标;
第三个是中层的通过上采样到高层(意思包含了中层和高层)在和低层contact,即包含了低层和中层和高层的信息,但是低层是直接过来的,中高层是上采样过来的,自然适合预测小目标。
2.2 骨干网络(Backbone Network)
骨干网络用的是Darknet53,也就是多个残差结构,毕竟残差终究是好,其他就是加了一些BN
3 损失函数
经过上面的分析,其实损失函数已经出来了,注意这里我们不按照什么官方代码里面的来写,我们就按照论文里面来写,也不去说什么BCE损失来代替MSE损失,完全没有必要,完全用yolov1的损失即可。
需要注意的是,
- 预测x,y,w,h为1.3中的计算结果;
- C和P的计算可以用交叉熵;
- C的预测有变化,该anchor为预测框时,和v1不一样,这里是所有的anchor和GT求IOU最大那个是正样本,C的标签为1,该anchor不为预测框,也就是IOU不是最大,但是超过设定的IOU,则不计算任何损失,低于设定的IOU才计算损失,其归类到noobj中。也就是说C的noobj计算不在是判断这个anchor是否为预测框(是否最大IOU),而是通过判断IOU是否超过设定的值。
其实只需要理解C的计算即可,其他不是很重要,因为我们的目标是更高的yolo版本,低版本主要理解思路即可,理解方法,为高版本打下基础。
重新解释一下正负样本:
正样本:所有的anchor,不是GT中心落在那个grid cell 的anchor,而是所有的,
(
13
∗
13
+
26
∗
26
+
52
∗
52
)
∗
3
(13*13 + 26*26+52*52)*3
(13∗13+26∗26+52∗52)∗3个与GT求IOU,最大那个是正样本,正样本只有一个;
负样本:IOU小于某个设定阈值,比如0.2,则为负样本;
忽略样本:其他是忽略样本。
可以看到正负样本严重失衡。
后面版本改进了这一做法。