本篇文章观点仅限于目前的理解,后续若有新的理解,还会继续更新。
1. YOLOv2改进点总结
使用论文中的一张图来总结YOLOv2所做的一些改进: 这里解释以下几点:
-
convolutional: 通过对YOLOv1的分析可以知道,YOLOv1最后一层是全连接层,全连接层经过reshape操作得到了我们所需要的
7*7*30
的结构,而在YOLOv2中,作者使用1*1
的卷积替换掉了全连接层,这样可以直接得到所需的结构; -
anchor boxes: anchor boxes一栏的√并没有延续到最后,因为作者在直接使用anchor box方法时发现了它的两个问题,进而使用dimension priors和location prediction两个方法分别解决了这两个问题,进而用它们替换掉了原有的anchor box方法,也相当于对anchor box方法的一个升级;
-
passthrough: 这里对应于文中所述的Fine-Grained Features(细粒度特征)。在YOLOv1中,对图像的下采样倍数为64倍,最终在
7*7
的特征图上进行预测,而在YOLOv2中,输入图像416*416
,下采样32倍,使得网络最终可以在13*13
的特征图上进行预测,但作者考虑到这样的下采样倍数,对小物体的检测还是过大,所以作者借鉴ResNet的思想,在网络上加了一个passthrough通道,将浅层的26*26*512
的特征经过隔行隔列采样的方法,得到一个13*13*2048
的特征图,这个特征图再与网络输出的13*13
的特征图沿通道方向连接,网络最后一层则在这个大的特征图上使用1*1
的卷积核进行卷积,得到最终所需的输出shape; -
multi-scale: 作者在论文中的Convolution With Anchor Boxes一节,提到了为了使用于检测的特征图边长为奇数,所以需要输入图像为
416*416
,这样最终输出的特征图为13*13
,而在Multi-Scale Training一节,作者又提到了在不同尺度图像下的训练。不同尺度图像下的训练必然会导致最终特征图大小的变化,所以可以不必在意作者上面提到的13*13
的特征图。事实上,作者在程序中的做法为:在训练前期,每隔一定数量的eopch,随机选择一个尺度进行训练,而在训练的最后阶段,则是按照最大尺度训练,测试阶段也是按照最大尺度进行检测; -
最终的feature map: 和YOLOv1相比,YOLOv2用于预测的feature map有所变化,变化点就在于,每个box有属于自己的类别预测,也即,对两个box,YOLOv1的feature map格式为
[x1,y1,w1,h1,conf1,x2,y2,w2,h2,conf2,class]
,而YOLOv2的feature map格式则为[[x1,y1,w1,h1,conf1,class1],[x2,y2,w2,h2,conf2,class2]]
,同一个格点对应的不同的box分别独立地进行预测,不再相互关联,且每一个格点所预测的box个数即为anchor box的个数。
2. 如何理解YOLOv2中的Dimension Clusters?
YOLOv2借鉴了Faster R-CNN中的anchor box的思想,预先给出一些已知大小的anchor box(先验框),网络的输出则相当于对这些框进行一定程度的平移和缩放,但YOLOv2对anchor box的方法做了一些改进,一个是Dimension Clusters,另一个是Direct location prediction。 Dimension Clusters的作用就是找到一组合适的anchor box的尺寸,这些anchor box的尺寸能够大致概括truth box中的几类尺寸。
论文中使用了K-means方法对truth box的长和宽进行聚类,需要注意,这些聚类是位置无关的,只对box的长和宽进行聚类,每个聚类中心是由一组(h, w)组成的一个anchor box。在使用K-means方法时,作者使用的度量两个box距离的准则为d(box, centroid) = 1-IOU(box, centroid)
,也就是说,将两个box中心重合,然后计算其IOU,IOU越大的,其距离越小。
如下图所示,下方左图显示了不同聚类中心所对应的平均IOU,也即在这些聚类中心(anchor box)下,truth box与这些anchor box的平均IOU,如当k=5时,在VOC 2007上的Avg IOU达到了约0.7,这说明这些anchor box的大小已经足够接近truth box大小。
3. 如何理解YOLOv2中的Direct location prediction?
Direct location predition是YOLOv2中对anchor box方法的第二个改进,Faster R-CNN中预测的是bounding box的位置相对anchor box的偏移,作者这里没有去预测偏移,所以自称为Direct location predition,但实际上并非是直接预测bounding box的位置坐标,而是进行了一个公式的转换。
下面的叙述要考虑一个问题:标注的box参数是相对于原图的,而yolo网络输入时会对原图进行reshape,因此一个好的方法就是先将box参数相对原图做归一化,在运算时全部使用归一化参数,通过yolo层计算出的归一化的box坐标结果再乘以原图尺寸即可得到box在原图中的实际坐标。 由于anchor是按照yolo网络输入尺寸的基础上求得到,因此anchor要相对该尺寸做归一化。
如下图所示,t_x, t_y, t_w, t_h, t_o
是网络对每个bounding box的预测输出,其中$t_o$是对confidence的预测。(c_x, c_y)
是当前bounding box所在的格点位置,为一对整数坐标。经过一个Sigmoid函数的转换,(σ(t_x), σ(t_y))
相当于就是YOLOv1中所预测的相对某个格点的偏移,从前一篇关于yolov1的blog中可以知道,(σ(t_x), σ(t_y)) + (c_x, c_y)
得到的(b_x, b_y)
就相当于:
b_x = x*s
b_y = y*s
其中(x, y)
是truth box相对原始图像的归一化参数,s是yolo层的shape(正方形,长宽相等),若要通过(b_x, b_y)
得到在原图中的坐标,需要除以s再乘以原图的shape即可,但要注意,此时得到的坐标是box的左上角坐标。
(p_w, p_h)
是某一个anchor box相对yolo网络输入图片尺度的归一化尺寸,经过公式转换,得到的(b_w, b_h)
就是当前bounding box相对原图的归一化尺寸,再乘以原图尺寸即可得到bounding box的实际尺寸。
这种方法比直接预测坐标偏移的好处是,(t_x, t_y)
经过一个logistic(或者说:Sigmoid)函数的转换,使得其范围被限制在[0, 1]
,这样可以保证它不会跑到图像以外的区域。
所以为什么不对(t_w, t_h)
也使用这种变化?
4. YOLOv2中如何计算Loss Function?
这里总结一下YOLOv2中计算loss的逻辑,假设最后的feature map大小为13*13
,有5个anchor box,物体类别为20类,则feature map的shape为13*13*(5*(5+20))
。
在计算loss时,总体分为两步:
- 找到没有物体的box,仅计算其confidence loss;
- 找到有物体的box,计算其各种loss;
对第一步:作者先将feature map的预测参数通过anchor box参数转换为bounding box相对原图的比例,然后对每一个预测的box(共有13*13*5
个),与所有的truth box计算iou,找到该bounding box与truth box的最大IOU,若该最大IOU小于某阈值,则判断该box不包含物体,仅计算confidence loss;
对第二步:对当前图片的每一个truth box(在程序中,作者限定每张图片最多30个truth box),与每个anchor box计算iou,找到与当前truth box的iou最大的anchor box(也即大小最接近)。此时,通过truth box位置映射,可找到该truth box所属的格点位置,通过该anchor box的索引可找到该truth box应该属于该格点的第几个预测bounding box,然后使用truth box与该bounding box计算各种loss即可。
// 新的理解
对第一步:对一个feature map中预测的所有box与每一个truth box计算IoU,找到每一个预测的box与所有truth box中最大的IoU,若最大的IoU仍小于某个阈值,则认为该预测的box不包含物体,仅计算其confidence loss;
对第二步:对当前图片的每一个truth box,与每一个anchor box计算IoU(YOLOv3共9个anchor box),找到与之IoU最大的anchor box,然后判断该anchor box是否属于当前yolo层,如果不属于,则直接忽略,如果属于,则可以通过truth box的映射得到它在当前feature map上的格点位置`(c_x, c_y)`,通过与之最大IoU的anchor box可以知道具体是当前格点预测的三个box中的哪一个来负责该truth的预测,比如可能是图1.2中的第二个anchor位置处的box,然后将truth box的参数与该位置处预测的参数计算loss。
5. YOLOv3有何改进?
YOLOv3相对于YOLOv2的改进,主要体现在其网络结构上。
在darknet53网络的设计上,作者借鉴了ResNet的残差连接的方式,同时使用步长为2的卷积代替max pooling进行下采样。在总计53层的卷积上,作者一共进行了5次下采样,在后面为了使深层特征和浅层特征进行组合,又对深层特征分别进行了2次上采样(YOLOv2中是对浅层特征进行’下采样’),整体结构很精妙。
在预测上,YOLOv3在下采样倍数分别为8/16/32
这三个尺度上进行预测,每个尺度使用三个不同大小的anchor box,记由浅到深的三个预测层分别为y1, y2, y3
,则y1
对应了32倍下采样,使用较大的anchor box,负责预测大物体,y3
则经历了两次上采样,对应着8倍的下采样,使用较小的anchor box,负责预测小物体。
YOLOv3的其他方面在YOLOv2中都有体现,不再赘述。
6. 源码
附上自己注释的一份darknet源码链接,注释主要集中在三个不同版本的yolo层,其中的pdf文件简单说明了代码的框架。 darknet源码注释