Yolo系列的train阶段打标签原则都是:这几个bounding box中只有和ground truth的IOU最大的bounding box才是用来预测该object的。。
YOLO算法的基本思想是:首先通过特征提取网络对输入图像提取特征,得到一定size的feature map,比如13*13,然后将输入图像分成13*13个grid cell,接着如果ground truth中某个object的中心坐标落在哪个grid cell中,那么就由该grid cell来预测该object,因为每个grid cell都会预测固定数量的bounding box(YOLO v1中是2个,YOLO v2中是5个,YOLO v3中是3个,这几个bounding box的初始size是不一样的),那么这几个bounding box中最终是由哪一个来预测该object?答案是:这几个bounding box中只有和ground truth的IOU最大的bounding box才是用来预测该object的。可以看出预测得到的输出feature map有两个维度是提取到的特征的维度,比如13*13,还有一个维度(深度)是B*(5+C),注:YOLO v1中是(B*5+C),其中B表示每个grid cell预测的bounding box的数量,比如YOLO v1中是2个,YOLO v2中是5个,YOLO v3中是3个,C表示bounding box的类别数(没有背景类,所以对于VOC数据集是20),5表示4个坐标信息和一个置信度(objectness score)。
到目前看来取得好结果要有的策略是:设置先验框,采用全卷积做预测,采用残差网络,采用多尺度特征图做预测。
YOLOv3最大的变化包括两点:(yolov2有个毛病就是对小物体的检测不敏感,关键在于它那个cell预测时导致的毛病,而如今增加了多尺度预测之后yolov3在对小物体检测方便有了好转)
1. 特征提取网络(Darknet-53)
-
使用残差模型
YOLOv3的特征提取器是一个残差模型,因为包含53个卷积层,所以称为Darknet-53,从网络结构上看,相比Darknet-19网络使用了残差单元,所以可以构建得更深。
-
采用FPN架构
采用FPN架构(Feature Pyramid Networks for Object Detection)来实现多尺度检测。YOLOv3采用了3个尺度的特征图(当输入为416*416时)—— (13*13),(26*26),(52*52)。YOLOv3每个位置使用3个先验框,所以使用k-means得到9个先验框,并将其划分到3个尺度特征图上,尺度更大的特征图使用更小的先验框???。
YOLOv3网络结构示意图(VOC数据集),其中红色部分为各个尺度特征图的检测结果。
yolov3在三个不同的尺度预测boxes,yolov3使用的特征提取模型通过FPN(feature pyramid network)网络上进行改变,最后预测得到一个3-d tensor,包含bounding box信息,对象信息以及多少个类的预测信息。论文给出是这样子的:(N×N×[3*(4+1+80)])这里的80即是80类物体。
FPN结构如下:
yolov3使用这样的方式使得模型可以获取到更多的语义信息,模型得到了更好的表现。
yolov3依然使用k-Means聚类来得到bbox的先验,选择9个anchor以及3个尺度,然后将这9个anchor均匀的分布在这几个尺度上。
YOLO v3中每个grid cell预测3个bounding box,看起来比YOLO v2中每个grid cell预测5个bounding box要少,其实不是!因为YOLO v3采用了多个scale的特征融合,所以boundign box的数量要比之前多很多,以输入图像为416*416为例:(13*13+26*26+52*52)*3和13*13*5相比哪个更多应该很清晰了。
3. 分类(Class Prediction)
每个框预测分类,bounding box使用多标签分类(一个女人即使woman类也是person类)。论文中说没有使用softmax分类,只是使用了简单的逻辑回归进行分类,采用的二值交叉熵损失(binary cross-entropy loss)。
类别预测方面主要是将原来的单标签分类改进为多标签分类,因此网络结构上就将原来用于单标签多分类的softmax层换成用于多标签多分类的逻辑回归层。首先说明一下为什么要做这样的修改,原来分类网络中的softmax层都是假设一张图像或一个object只属于一个类别,但是在一些复杂场景下,一个object可能属于多个类,比如你的类别中有woman和person这两个类,那么如果一张图像中有一个woman,那么你检测的结果中类别标签就要同时有woman和person两个类,这就是多标签分类,需要用逻辑回归层来对每个类别做二分类。逻辑回归层主要用到sigmoid函数,该函数可以将输入约束在0到1的范围内,因此当一张图像经过特征提取后的某一类输出经过sigmoid函数约束后如果大于0.5,就表示属于该类。
4. 边界框的预测
回归目标其实和v2版本一样的。
与之前yolo版本一样,yolov3的anchor也是通过聚类的方法得到的。与v2不同的是,作者使用聚类得到9个聚类中心,然后对它们进行排序,再平均分配到三个尺度上,最后每个尺度有3个anchor。
tx、ty、tw、th就是模型的预测输出。cx和cy表示grid cell的坐标,比如某层的feature map大小是13*13,那么grid cell就有13*13个,第0行第1列的grid cell的坐标cx就是0,cy就是1。pw和ph表示预测前bounding box的size。bx、by。bw和bh就是预测得到的bounding box的中心的坐标和size。坐标的损失采用的是平方误差损失。
....
5. 损失函数
IOU大于0.5但不是最佳的(与gt的iou)不参与训练,小于0.5的作为负样本计算object损失,每个gt的最佳bbox计算坐标和类别损失。
YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了。这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框。
损失函数有5个部分:
第一项:负责预测物体的anchor的xywh损失。如果anchor负责预测物体,那么需要计算坐标的L2损失。
第二项:不负责预测物体的anchor的xywh损失。如果anchor不负责预测物体,那么需要在迭代的初期(比如iteration<12800)去计算坐标的L2损失。问题的关键是,anchor都不负责预测物体,那么它的预测目标是什么呢?答:预测目标是anchor的xywh。为什么要这么做?我的理解是,这么做可以让所有anchor的预测都接近anchor自身的xywh,这样当它有物体落入这个anchor的时候,anchor的预测不至于和目标差别太大,相应的损失也会比较小,训练起来会更加容易。
第三项:负责预测物体的anchor的confidence损失。负责预测物体的anchor需要计算confidence损失,confidence的目标就是预测的bbox和真实bbox的iou。
第四项:不负责预测物体的anchor的confidece损失。对那些不负责预测gt的anchor,需要计算每个anchor和所有gt box的IOU。如果算出来的最大IOU<0.6,相应的 ,并且confidence的label就是0。但是,如果这个值大于0.6,相应的 ,也就是说,这个时候是不算这个anchor的confidence损失的。为什么要这么做呢?我的理解是,当anchor不负责预测物体的时候,如果它预测出来的结果和真实值差别很大的话,那代表它是没有物体的,那么这个时候就希望它的预测的confidence接近0。但是如果预测的结果和真实值比较接近的话,则不计算损失。
第五项:负责预测物体的anchor的类别损失。每个类别的输出概率0-1之间,计算的是L2损失。也就是说分类问题也把它当做了回归问题。另外需要注意的是,类别预测中是不需要预测背景的,因为confidence实际上就已经代表是否存在物体,类别就没必要去预测背景。
其余部分同这里,只是阈值稍作改变:【目标检测算法】YOLOv2学习笔记
参考:
YOLO v3算法笔记(?)