双阶段与单阶段目标检测的区别:

双阶段(two-stage):第一级网络用于候选区域的提取;第二级网络对提取的候选区域进行分类和精确坐标回归,如RCNN系列。
单阶段(one-stage):摒弃了候选区域提取这一步骤,只用一级网络就完成了分类和回归两个任务,列如YOLO和SSD等。

YOLOv1

YOLOv1(CVPR2015)
You Only Look Once:Unified,Real-Time Object Detection
思路是:直接输出中心在grid内目标的所有信息,包括置信度、边框回归、分类类别

目标检测之-YOLO家族那些事 - 图1

参考:
https://gitthhub.github.io/2019/03/17/yolov1/
https://zhuanlan.zhihu.com/p/70387154

网络结构

目标检测之-YOLO家族那些事 - 图2

YOLOv1 的基本网络结构如上图所示,共有24层卷积层和2层全连接层,图片下方参数中的s-2指的是步长为2,这里要注意以下三点:

  • 在ImageNet中预训练网络时,使用的输入是224*224,用于检测任务时,输入大小改为448*448,这是通过调整第一个卷积层的步长来实现的;预训练时,网络结构使用前 20 个卷积层加上平均池化和全连接层进行训练。
  • 网络的设计借鉴了 GoogLeNet,使用了很多1*1的卷积层来进行特征降维;
  • 最后一个卷积层的输出为(7, 7, 1024),经过flatten后紧跟两个全连接层,形成一个线性回归,最后一个全连接层又被reshape成(7, 7, 30),形成对2个box坐标及20个物体类别的预测 (PASCAL VOC) (源码中实际上是预测了3个box->7*7*35)。
  • 最后一层采用线性激活函数,其他层采用 leaky rectified linear activation,并且在第一个 fc 后添加 dropout 层,丢弃率 0.5,防止过拟合。

网络的输出特征解码图:

目标检测之-YOLO家族那些事 - 图3

如上图所示,这就是最后一层全连接经过reshape之后的(7, 7, 30)的张量,这张图需要结合论文中所述的Grid Cell来理解。 我们知道,YOLO网络输入的是448*448正方形图片,最终输出的是一个7*7的特征图,下采样倍数为64倍,在输出的7*7的特征图上,每个格点对应原图中一个64*64的区域,也就是论文中所述的Grid Cell。 在上面的图片中,7*7特征图中的每一个格点都是一个1*30的向量,格点对应原图中的一个64*64的Grid Cell,格点中的参数就是对以该Grid Cell中心的物体类别和bounding box的预测,因此很容易理解,对一张图片,每个格点预测一个物体类别和两个bounding box,预测阶段选择置信度高的 bounding box,这里要注意,每个格点的两个bounding box预测的是同一类物体,要是分别负责预测不同物体,则最后一层的shape应该为7*7*(2*(5+20))=7*7*50 (YOLOv2)。

训练时如何根据 grouth truth 打标签

训练过程中,grouth truth 顺序 confidence,x,y,w,h,c1,c2,...,c20
gt预测类别标注:
预测边框在论文中被称为 predictor,yolov1 中每个 grid 中包含 2 个 predictor ,中心在 grid 的 gt 中与 任意 predictor 的 IOU 最大的 gt 类别作为标注类别。

It also only pe- nalizes bounding box coordinate error if that predictor is “responsible” for the ground truth box (i.e. has the highest IOU of any predictor in that grid cell).

其中 confidence 计算方法如下:
目标检测之-YOLO家族那些事 - 图4*IOU%7Btruth%7D%5E%7Bpred%7D%0A#card=math&code=C%20%3D%20Pr%28obj%29%2AIOU%7Btruth%7D%5E%7Bpred%7D%0A)

目标检测之-YOLO家族那些事 - 图5 是预测框和真实标注框的交并比。目标检测之-YOLO家族那些事 - 图6#card=math&code=Pr%28obj%29) 是表示一个 grid 有物体(判断物体标准是物体中心在 grid内)的概率,再有物体时候值为 1,没有物体的时候值为 0。

grouth truth 坐标回归目标编码方式如下所示:
之所以处理除以分母是为了进行尺度上的缩放,对小物体检测有一定的适应性。
目标检测之-YOLO家族那些事 - 图7#card=math&code=%28x%2Cy%29) 是目标中心坐标,在 grid 中的相对位置,值域为 目标检测之-YOLO家族那些事 - 图8
目标检测之-YOLO家族那些事 - 图9#card=math&code=%28w%2Ch%29)是目标检测框的长宽和图像长宽的比,值域为 目标检测之-YOLO家族那些事 - 图10

yolov1_position2.png

具体例子:
左上角的 grid 的 ground truth 是:0,?,?,?,?,?,...,?
中间的 grid 的 ground truth 是(假设该目标属于第一个类别):iou,0.48,0.28,0.5,0.32,1,0,...,0

预测阶段

计算 class-specific confidence score
公式如下,该结果不仅仅包含了类别的准确率,也包含了该预测边框置信度,输入结果更加可信。

目标检测之-YOLO家族那些事 - 图12%20%20%5Coperatorname%7BPr%7D(%5Ctext%20%7B%20Object%20%7D)%20%20%5Ctext%20%7B%20IOU%20%7D%7B%5Ctext%20%7Bpred%20%7D%7D%5E%7B%5Ctext%20%7Btruth%20%7D%7D%3D%5Coperatorname%7BPr%7D%5Cleft(%5Ctext%20%7B%20Class%20%7D%7Bi%7D%5Cright)%20*%20%5Ctext%20%7B%20IOU%20%7D%7B%5Ctext%20%7Bpred%20%7D%7D%5E%7B%5Ctext%20%7Btruth%20%7D%7D%0A#card=math&code=%5Coperatorname%7BPr%7D%5Cleft%28%5Ctext%20%7B%20Class%20%7D%7Bi%7D%20%5Cmid%20%5Ctext%20%7B%20Object%20%7D%5Cright%29%20%2A%20%5Coperatorname%7BPr%7D%28%5Ctext%20%7B%20Object%20%7D%29%20%2A%20%5Ctext%20%7B%20IOU%20%7D%7B%5Ctext%20%7Bpred%20%7D%7D%5E%7B%5Ctext%20%7Btruth%20%7D%7D%3D%5Coperatorname%7BPr%7D%5Cleft%28%5Ctext%20%7B%20Class%20%7D%7Bi%7D%5Cright%29%20%2A%20%5Ctext%20%7B%20IOU%20%7D_%7B%5Ctext%20%7Bpred%20%7D%7D%5E%7B%5Ctext%20%7Btruth%20%7D%7D%0A)
一种三项后面两项是 预测出来的 confidence,前一项是预测出来的类别概率。

使用 NMS 进行过滤多余的框
得到每个box的class-specific confidence score以后,设置阈值,滤掉得分低的 boxes,对保留的 boxes 进行NMS处理,就得到最终的检测结果。

损失函数

目标检测之-YOLO家族那些事 - 图13%5E%7B2%7D%2B%5Cleft(y%7Bi%7D-%5Chat%7By%7D%7Bi%7D%5Cright)%5E%7B2%7D%5Cright%5D%20%5C%5C%0A%5Cquad%2B%5Clambda%7B%5Ctext%20%7Bcoord%20%7D%7D%20%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Ctext%20%7Bobj%20%7D%7D%5Cleft%5B%5Cleft(%5Csqrt%7Bw%7Bi%7D%7D-%5Csqrt%7B%5Chat%7Bw%7D%7Bi%7D%7D%5Cright)%5E%7B2%7D%2B%5Cleft(%5Csqrt%7Bh%7Bi%7D%7D-%5Csqrt%7B%5Chat%7Bh%7D%7Bi%7D%7D%5Cright)%5E%7B2%7D%5Cright%5D%20%5C%5C%0A%5Cquad%2B%20%5Clambda%7B%5Ctext%7Bnoobj%7D%7D%20%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Ctext%20%7Bnoobj%20%7D%7D%5Cleft(C%7Bi%7D-%5Chat%7BC%7D%7Bi%7D%5Cright)%5E%7B2%7D%20%5C%5C%0A%5Cquad%2B%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Ctext%20%7Bobj%20%7D%7D%5Cleft(C%7Bi%7D-%5Chat%7BC%7D%7Bi%7D%5Cright)%5E%7B2%7D%20%5C%5C%0A%5Cqquad%2B%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Cmathbb%7B1%7D%7Bi%7D%5E%7B%5Ctext%20%7Bobj%20%7D%7D%20%5Csum%7Bc%20%5Cin%20%5Ctext%20%7B%20classes%20%7D%7D%5Cleft(p%7Bi%7D(c)-%5Chat%7Bp%7D%7Bi%7D(c)%5Cright)%5E%7B2%7D%0A%5Cend%7Barray%7D%0A#card=math&code=%5Cbegin%7Barray%7D%7Bl%7D%0A%5Clambda%7B%5Ctext%20%7Bcoord%20%7D%7D%20%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Cmathrm%7Bobj%7D%7D%5Cleft%5B%5Cleft%28x%7Bi%7D-%5Chat%7Bx%7D%7Bi%7D%5Cright%29%5E%7B2%7D%2B%5Cleft%28y%7Bi%7D-%5Chat%7By%7D%7Bi%7D%5Cright%29%5E%7B2%7D%5Cright%5D%20%5C%5C%0A%5Cquad%2B%5Clambda%7B%5Ctext%20%7Bcoord%20%7D%7D%20%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Ctext%20%7Bobj%20%7D%7D%5Cleft%5B%5Cleft%28%5Csqrt%7Bw%7Bi%7D%7D-%5Csqrt%7B%5Chat%7Bw%7D%7Bi%7D%7D%5Cright%29%5E%7B2%7D%2B%5Cleft%28%5Csqrt%7Bh%7Bi%7D%7D-%5Csqrt%7B%5Chat%7Bh%7D%7Bi%7D%7D%5Cright%29%5E%7B2%7D%5Cright%5D%20%5C%5C%0A%5Cquad%2B%20%5Clambda%7B%5Ctext%7Bnoobj%7D%7D%20%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Ctext%20%7Bnoobj%20%7D%7D%5Cleft%28C%7Bi%7D-%5Chat%7BC%7D%7Bi%7D%5Cright%29%5E%7B2%7D%20%5C%5C%0A%5Cquad%2B%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Csum%7Bj%3D0%7D%5E%7BB%7D%20%5Cmathbb%7B1%7D%7Bi%20j%7D%5E%7B%5Ctext%20%7Bobj%20%7D%7D%5Cleft%28C%7Bi%7D-%5Chat%7BC%7D%7Bi%7D%5Cright%29%5E%7B2%7D%20%5C%5C%0A%5Cqquad%2B%5Csum%7Bi%3D0%7D%5E%7BS%5E%7B2%7D%7D%20%5Cmathbb%7B1%7D%7Bi%7D%5E%7B%5Ctext%20%7Bobj%20%7D%7D%20%5Csum%7Bc%20%5Cin%20%5Ctext%20%7B%20classes%20%7D%7D%5Cleft%28p%7Bi%7D%28c%29-%5Chat%7Bp%7D%7Bi%7D%28c%29%5Cright%29%5E%7B2%7D%0A%5Cend%7Barray%7D%0A)

所有的损失都是使用平方和误差公式,暂时先不看公式中的 目标检测之-YOLO家族那些事 - 图14目标检测之-YOLO家族那些事 - 图15,输出的预测数值以及所造成的损失有:

  1. 预测框的中心点 目标检测之-YOLO家族那些事 - 图16#card=math&code=%28x%2Cy%29) 。造成的损失是图五中的第一行。其中 目标检测之-YOLO家族那些事 - 图17 为控制函数,在标签中包含物体的那些格点处,该值为 1;若格点不含有物体,该值为 0。也就是只对那些有真实物体所属的格点进行损失计算,若该格点不包含物体,那么预测数值不对损失函数造成影响。目标检测之-YOLO家族那些事 - 图18#card=math&code=%28x%2Cy%29)数值与标签用简单的平方和误差。
  2. 预测框的宽高目标检测之-YOLO家族那些事 - 图19#card=math&code=%28w%2Ch%29)。造成的损失是图五的第二行。目标检测之-YOLO家族那些事 - 图20 的含义一样,也是使得只有真实物体所属的格点才会造成损失。这里对 在 目标检测之-YOLO家族那些事 - 图21#card=math&code=%28w%2Ch%29) 损失函数中的处理分别取了根号,原因在于,如果不取根号,损失函数往往更倾向于调整尺寸比较大的预测框。取根号是为了尽可能的消除大尺寸框与小尺寸框之间的差异。(主要是为了放大小物体的误差,根号函数相比线性函数,会缩小较大的数值,变相的放大小物体的误差)
  3. 第三行与第四行,都是预测框的置信度 目标检测之-YOLO家族那些事 - 图22。当该格点不含有物体时,该置信度的标签为 0;若含有物体时,该置信度的标签为预测框与真实物体框的 IOU 数值。
  4. 第五行为物体类别概率目标检测之-YOLO家族那些事 - 图23,对应的类别位置,该标签数值为 1,其余位置为 0,与分类网络相同。

此时再来看 目标检测之-YOLO家族那些事 - 图24目标检测之-YOLO家族那些事 - 图25,YOLO 面临的物体检测问题,是一个典型的类别数目不均衡的问题。其中49个格点,含有物体的格点往往只有3、4个,其余全是不含有物体的格点。此时如果不采取点措施,那么物体检测的 mAP 不会太高,因为模型更倾向于不含有物体的格点。 目标检测之-YOLO家族那些事 - 图26目标检测之-YOLO家族那些事 - 图27 的作用,就是让含有物体的格点,在损失函数中的权重更大,让模型更加“重视”含有物体的格点所造成的损失。在论文中,目标检测之-YOLO家族那些事 - 图28目标检测之-YOLO家族那些事 - 图29 的取值分别为 5 与 0.5。

目标检测之-YOLO家族那些事 - 图30

缺点

  • 图像下采样 64 倍,容易漏检小物体;
  • 每张图像仅预测出 98 个 bounding box,且每个格点的 bounding box 负责预测的是同一个物体,若一幅图中有多个物体都落入同一个格点,则只能预测其中的一个,使得算法召回率不高;

YOLOv2

YOLOv2 (CVPR2017)
YOLO9000: Better, Faster, Stronger

效果

YOLOv2 使用 coco 数据集训练后,可以识别 80 个类别;
YOLO9000 可以使用 coco 数据集合 ImageNet 数据集联合训练,可以识别 9000多个类别;

结构

backbone 采用的 Darknet-19

目标检测之-YOLO家族那些事 - 图31

改进

YOLOv2 是在 YOLOv1 基础上的改进,具体的改进如下:

  • batch norm

YOLO 每个卷积层中加入 BN 后,mAP 提示了 2%,并且去除了 Dropout。

  • high resolution classifier

高分辨率预训练
对于 YOLOv1 ,网络的 backbone 部分会在 ImageNet 数据集上进行预训练,训练时网络的输入图像的分辨率为 224*224
在 YOLOv2 中,将网络的 backone 部分在 ImageNet 数据集上以 分辨率 448*448 的图片预训练 10 个 epoch,再使用数据集(例如 coco)进行微调。
使得 mAP 提高了大约 4%

  • 去掉了全连接层

V2 中 移除了 v1 的最后两个全连接层,全连接层计算量大耗时久。移除全连接层的另外一个优点是,能够进行多尺度训练。

  • 引入了 anchor box

v2 中的 anchor box 不是人为设计的,是将训练集中的矩形框全部拿出来,用k-means聚类得到的先验宽和高;
K-means 聚类的具体步骤如下:

  1. 提取所有训练数据的 bounding boxes 的宽高数据,将坐标转化为宽高的大小,计算方法:长 = 右下角横坐标 - 左上角横坐标、宽 = 右下角纵坐标 - 左上角纵坐标。
  2. 初始化 k 个anchor box,在所有的 bounding boxes 中随机的选取 k 个值作为 k 个 anchor boxes 的初始值。
  3. 计算每个 bounding box 和 每个 anchor box 的 iou 值:

目标检测之-YOLO家族那些事 - 图32%20%3D%201%20-%20IOU(%5Ctext%7Bbox%7D%2C%5Ctext%7Bcentroid%7D)%0A#card=math&code=d%28%5Ctext%7Bbox%7D%2C%5Ctext%7Bcentroid%7D%20%29%20%3D%201%20-%20IOU%28%5Ctext%7Bbox%7D%2C%5Ctext%7Bcentroid%7D%29%0A)

  1. 分类:比较每个 bounding box 对于每个 anchor box 的误差大小 目标检测之-YOLO家族那些事 - 图33%2Cd(i%2C2)%2C…%2Cd(i%2Ck)%20%5C%7D#card=math&code=%5C%7B%20d%28i%2C1%29%2Cd%28i%2C2%29%2C…%2Cd%28i%2Ck%29%20%5C%7D) 选取误差最小的那个 anchor box,将这个 bounding box 分类给它,对于每个 bounding box 都做这个操作,最后记录下来每个 anchor box 有哪些 bounding box 属于它。
  2. Anchor box 更新:对于每个 anchor box 中的那些 bounding box ,再求这些 bounding box 宽高中值的大小。
  3. 重复 3 到 5 步,直到第 5 步中发现对于全部的 bounding box 其所属的 anchor box 类与之前所属的 anchor box 类完全一样。(指bounding box 的分类已经不再更新)
  • 绝对位置预测

Direct location prediction
对于每个 bounding box 预测了 5 个值 目标检测之-YOLO家族那些事 - 图34
目标检测之-YOLO家族那些事 - 图35%2C%5Csigma(t_y))#card=math&code=%28%5Csigma%28t_x%29%2C%5Csigma%28t_y%29%29) 预测的是相对于左上角坐标 目标检测之-YOLO家族那些事 - 图36#card=math&code=%28c_x%2Cc_y%29) 的偏置坐标 offset
目标检测之-YOLO家族那些事 - 图37%2Bc_x%20%5C%5C%0Ab_y%20%3D%20%5Csigma(t_y)%2Bc_y%20%5C%5C%0Ab_w%20%3D%20p_we%5E%7Bt_w%7D%20%5C%5C%0Ab_h%20%3D%20p_he%5E%7Bt_h%7D%20%5C%5C%0APr(object)*IOU(b%2Cobject)%3D%20%5Csigma(t_o)%0A#card=math&code=b_x%20%3D%20%5Csigma%28t_x%29%2Bc_x%20%5C%5C%0Ab_y%20%3D%20%5Csigma%28t_y%29%2Bc_y%20%5C%5C%0Ab_w%20%3D%20p_we%5E%7Bt_w%7D%20%5C%5C%0Ab_h%20%3D%20p_he%5E%7Bt_h%7D%20%5C%5C%0APr%28object%29%2AIOU%28b%2Cobject%29%3D%20%5Csigma%28t_o%29%0A)
其中 目标检测之-YOLO家族那些事 - 图38 是先验框长宽,目标检测之-YOLO家族那些事 - 图39 通过 目标检测之-YOLO家族那些事 - 图40 sigmoid 函数映射为置信度。

  • 目标检测之-YOLO家族那些事 - 图41

  • Fine-Grained Features

目的:为了保留较小对象的更多的信息,参考 Densnet 理念 ,构建了 passthrough 层,将更多细节的信息传递到后面的层。
具体来说,就是在最后一个pooling之前,特征图的大小是26*26*512,将其 1 拆 4,直接传递(passthrough)到pooling后(并且又经过一组卷积)的特征图,两者叠加到一起作为输出的特征图。

目标检测之-YOLO家族那些事 - 图42

具体如何 1 拆 4 参考下图
目标检测之-YOLO家族那些事 - 图43

  • Multi-Scale Training

多尺度训练
YOLOv2 中只有卷积层和池化层,所以对于网络的输入大小,并没有限制,整个网络的降采样倍数是 32 倍,只要输入的特征图尺寸为 32 的倍数即可。
在每 10 个 epoch 后,就将图片 resize 成 目标检测之-YOLO家族那些事 - 图44 中的一种。不同的输入最后产生的格点数不同。
引入多尺度后,迫使卷积核可以实现不同比例大小尺寸的特征。当输入设置为 544*544 甚至更大时,YOLOv2的 mAP 已经超过了其他物体检测方法。

YOLO9000:Stronger

Joint classification and detection
联合训练:当输入检测数据集时,标注信息有类别、有位置,那么对整个 loss 函数计算 loss,进行反向传播;当输入图片只包含分类信息时,loss 函数只计算分类 loss ,其余部分 loss 为零。
word tree 细节待续。。

YOLOv3

YOLOv3(arXiv 2018)
YOLOv3: An Incremental Improvement
参考:https://zhuanlan.zhihu.com/p/76802514

结构

backbone:Darknet-53
借鉴了 residual net

目标检测之-YOLO家族那些事 - 图45

从 v1 到 v3 backbone 发生了哪些变化
v1 借鉴了 GoogLeNet 采用 1*1 进行降为,v2 去掉了全连接层引入全局平均池化,引入了多尺度,v3 引入了 residual 模块;并且 卷积核的大小 v2 开始卷积最大是 3*3 ,计算量小防止过拟合,网络深度也是逐步加深。
选择 Darknet-53 原因:
处理速度每秒 78 张图片,比 Darknet-19 慢不少,但比同精度的 Resnet 块很多。YOLOv3 依旧能保持高性能。速度和精度的权衡 tradeoff。

目标检测之-YOLO家族那些事 - 图46

网络的整体结构:
yolov3.png

  1. Yolov3中,只有卷积层,通过调节卷积步长控制输出特征图的尺寸。所以对于输入图片尺寸没有特别限制。流程图中,输入图片以256*256作为样例。
  2. Yolov3借鉴了金字塔特征图思想,小尺寸特征图用于检测大尺寸物体,而大尺寸特征图检测小尺寸物体。特征图的输出维度为 目标检测之-YOLO家族那些事 - 图48%5D#card=math&code=N%20%5Ctimes%20N%20%5Ctimes%20%5B3%20%5Ctimes%20%284%2B1%2B80%29%5D), 目标检测之-YOLO家族那些事 - 图49 为输出特征图格点数,一共3个Anchor框,每个框有4维预测框数值 目标检测之-YOLO家族那些事 - 图50 ,一个置信度 目标检测之-YOLO家族那些事 - 图51 ,80维物体类别数。所以第一层特征图的输出维度为 ,所以第一个输出特征图 。8*8*255
  3. Yolov3总共输出3个特征图,第一个特征图下采样32倍,第二个特征图下采样16倍,第三个下采样8倍。输入图像经过Darknet-53(无全连接层),再经过 Yoloblock 生成的特征图被当作两用,第一用为经过3*3卷积层、1*1卷积之后生成特征图一,第二用为经过 1*1 卷积层加上采样层,与 Darnet-53 网络的中间层输出结果进行拼接,产生特征图二。同样的循环之后产生特征图三。
  4. concat操作与加和操作的区别:加和操作来源于ResNet思想,将输入的特征图,与输出特征图对应维度进行相加,即 目标检测之-YOLO家族那些事 - 图52%2Bx#card=math&code=y%3Df%28x%29%2Bx) ;而 concat 操作源于 DenseNet 网络的设计思路,将特征图按照通道维度直接进行拼接,例如8*8*16的特征图与8*8*16的特征图拼接后生成8*8*32的特征图。
  5. 上采样层(upsample):作用是将小尺寸特征图通过插值等方法,生成大尺寸图像。例如使用最近邻插值算法,将8*8的图像变换为16*16。上采样层不改变特征图的通道数。
    Yolo的整个网络,吸取了Resnet、Densenet、FPN的精髓。

    输出特征图解码

根据不同的尺寸会出处不同大小的特征图,以图中结构为例 256*256*3为例,输出的特征图为8*8*25516*16*25532*32*255。在Yolov3的设计中,每个特征图的每个格子中,都配置3个不同的先验框,所以最后三个特征图,这里暂且 reshape 为 8*8*3*8516*16*3*8532*32*3*85,这样更容易理解,在代码中也是 reshape 成这样之后更容易操作。
三张特征图就是整个Yolo输出的检测结果,检测框位置(4维)、检测置信度(1维)、类别(80维)都在其中,加起来正好是 85维。特征图最后的维度 85,代表的就是这些信息,而特征图其他维度 N*N*3N*N代表了检测框的参考位置信息,3 是 3 个不同尺度的先验框。下面详细描述怎么将检测信息解码出来:

  • 先验框

在Yolov1中,网络直接回归检测框的宽、高,这样效果有限。所以在 Yolov2 中,改为了回归基于先验框的变化值,这样网络的学习难度降低,整体精度提升不小。Yolov3 沿用了 Yolov2 中关于先验框的技巧,并且使用 k-means 对数据集中的标签框进行聚类,得到类别中心点的 9 个框,作为先验框。在 COCO 数据集中(原始图片全部resize为 416*416),九个框分别是 (10,13)(16,30)(33,23)(30,61)(62,45)(59,119)(116,90)(156,198)(373,326) ,顺序为w,h
注:先验框只与检测框的w、h有关,与x、y无关。

  • 检测框解码

有了先验框与输出特征图,就可以解码检测框 x,y,w,h。
目标检测之-YOLO家族那些事 - 图53%2Bc_x%20%5C%5C%0Ab_y%20%3D%20%5Csigma(t_y)%2Bc_y%20%5C%5C%0Ab_w%20%3D%20p_we%5E%7Bt_w%7D%20%5C%5C%0Ab_h%20%3D%20p_he%5E%7Bt_h%7D%20%5C%5C%0APr(object)*IOU(b%2Cobject)%3D%20%5Csigma(t_o)%0A#card=math&code=b_x%20%3D%20%5Csigma%28t_x%29%2Bc_x%20%5C%5C%0Ab_y%20%3D%20%5Csigma%28t_y%29%2Bc_y%20%5C%5C%0Ab_w%20%3D%20p_we%5E%7Bt_w%7D%20%5C%5C%0Ab_h%20%3D%20p_he%5E%7Bt_h%7D%20%5C%5C%0APr%28object%29%2AIOU%28b%2Cobject%29%3D%20%5Csigma%28t_o%29%0A)
对于每个 bounding box 预测了 5 个值 目标检测之-YOLO家族那些事 - 图54
目标检测之-YOLO家族那些事 - 图55%2C%5Csigma(t_y)%20)#card=math&code=%28%20%5Csigma%28t_x%29%2C%5Csigma%28t_y%29%20%29) 预测的是相对于左上角坐标 目标检测之-YOLO家族那些事 - 图56#card=math&code=%28c_x%2Cc_y%29) 的偏置坐标 offset,目标检测之-YOLO家族那些事 - 图57 是 sigmoid 激活函数;目标检测之-YOLO家族那些事 - 图58 是先验框长宽,通过上述公式,计算出实际预测框的宽高 目标检测之-YOLO家族那些事 - 图59#card=math&code=%28b_w%2Cb_h%29)。
目标检测之-YOLO家族那些事 - 图60

  • 置信度解码

目标检测之-YOLO家族那些事 - 图61 由 sigmoid 函数进行解码 目标检测之-YOLO家族那些事 - 图62#card=math&code=c%3D%5Csigma%28t_o%29),解码后的数值在 目标检测之-YOLO家族那些事 - 图63#card=math&code=%280%2C1%29)

  • 类别解码

COCO 数据集有80个类别,所以类别数在85维输出中占了80维,每一维独立代表一个类别的置信度。使用 sigmoid 激活函数替代了Yolov2 中的 softmax,取消了类别之间的互斥,可以使网络更加灵活。
三个特征图一共可以解码出 目标检测之-YOLO家族那些事 - 图64 个 box 以及相应的类别、置信度。这 4032 个box,在训练和推理时,使用方法不一样:

  1. 训练时4032个box全部送入打标签函数,进行后一步的标签以及损失函数的计算。
  2. 推理时,选取一个置信度阈值,过滤掉低阈值box,再经过nms(非极大值抑制),就可以输出整个网络的预测结果了。

训练策略与损失函数

  • 训练打标签策略
  1. 预测框一共分为三种情况:正例(positive)、负例(negative)、忽略样例(ignore)。
  2. 正例:任取一个 ground truth,与 4032 个框全部计算 IOU,IOU 最大的预测框,即为正例。并且一个预测框,只能分配给一个ground truth。例如第一个 ground truth 已经匹配了一个正例检测框,那么下一个 ground truth,就在余下的 4031 个检测框中,寻找IOU最大的检测框作为正例。ground truth 的先后顺序可忽略。正例产生置信度loss、检测框loss、类别loss。预测框为对应的 ground truth box 标签(需要反向编码,使用真实的x、y、w、h计算出 目标检测之-YOLO家族那些事 - 图65 );类别标签对应类别为1,其余为0;置信度标签为1。
  3. 忽略样例:正例除外,与任意一个ground truth的IOU大于阈值(论文中使用0.5),则为忽略样例。忽略样例不产生任何loss。
  4. 负例:正例除外(与ground truth计算后IOU最大的检测框,但是IOU小于阈值,仍为正例),与全部ground truth的IOU都小于阈值(0.5),则为负例。负例只有置信度产生loss,置信度标签为0。
  • loss 函数

特征图1的Yolov3的损失函数抽象表达式如下:

目标检测之-YOLO家族那些事 - 图66%5E2%2B(ty-t’_y)%5E2%5D%5C%5C%0A%20%20%26%20%2B%5Clambda%7Bbox%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7D%5B(tw-t’_w)%5E2%2B(t_h-t’_h)%5E2%5D%5C%5C%0A%20%20%26%20-%5Clambda%7Bobj%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7Dlog(c%7Bij%7D)%5C%5C%0A%20%20%26%20-%5Clambda%7Bnoobj%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bnoobj%7D%7Bij%7Dlog(1-c%7Bij%7D)%5C%5C%0A%20%20%26%20-%5Clambda%7Bclass%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7D%5Csum%7Bc%5Cin%7Bclasses%7D%7D%5Bp’%7Bij%7D(c)log(p%7Bij%7D(c))%2B(1-p’%7Bij%7D(c)%EF%BC%89log(1-p%7Bij%7D(c))%5D%5C%5C%0A%20%20%20%26%20%0A%5Cend%7Balign*%7D%0A#card=math&code=~~~%5C%5C%0A%5Cbegin%7Balign%2A%7D%0Aloss%7BN1%7D%20%3D%20%26%20%5Clambda%7Bbox%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7D%5B%28tx-t%27_x%29%5E2%2B%28t_y-t%27_y%29%5E2%5D%5C%5C%0A%20%20%26%20%2B%5Clambda%7Bbox%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7D%5B%28tw-t%27_w%29%5E2%2B%28t_h-t%27_h%29%5E2%5D%5C%5C%0A%20%20%26%20-%5Clambda%7Bobj%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7Dlog%28c%7Bij%7D%29%5C%5C%0A%20%20%26%20-%5Clambda%7Bnoobj%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bnoobj%7D%7Bij%7Dlog%281-c%7Bij%7D%29%5C%5C%0A%20%20%26%20-%5Clambda%7Bclass%7D%5Csum%5E%7BN1%5Ctimes%7BN_1%7D%7D%7Bi%3D0%7D%5Csum%5E%7B3%7D%7Bj%3D0%7D1%5E%7Bobj%7D%7Bij%7D%5Csum%7Bc%5Cin%7Bclasses%7D%7D%5Bp%27%7Bij%7D%28c%29log%28p%7Bij%7D%28c%29%29%2B%281-p%27%7Bij%7D%28c%29%EF%BC%89log%281-p_%7Bij%7D%28c%29%29%5D%5C%5C%0A%20%20%20%26%20%0A%5Cend%7Balign%2A%7D%0A)

Yolov3 Loss为三个特征图Loss之和:
目标检测之-YOLO家族那些事 - 图67

  1. 目标检测之-YOLO家族那些事 - 图68 为权重常数,控制检测框Loss、obj置信度Loss、noobj置信度Loss之间的比例,通常负例的个数是正例的几十倍以上,可以通过权重超参控制检测效果。
  2. 目标检测之-YOLO家族那些事 - 图69 若是正例则输出1,否则为0; 目标检测之-YOLO家族那些事 - 图70若是负例则输出1,否则为0;忽略样例都输出0。
  3. x、y、w、h使用 MSE 作为损失函数,也可以使用 smooth L1 loss(出自Faster R-CNN)作为损失函数。smooth L1可以使训练更加平滑。置信度、类别标签由于是0,1二分类,所以使用交叉熵作为损失函数。
  • 训练策略解释:
  1. ground truth为什么不按照中心点分配对应的预测box?

在Yolov3的训练策略中,不再像 Yolov1 那样,每个cell负责中心落在该cell中的 ground truth。原因是 Yolov3 一共产生 3 个特征图,3个特征图上的cell,中心是有重合的。训练时,可能最契合的是特征图1的第3个box,但是推理的时候特征图2的第1个box置信度最高。所以 Yolov3 的训练,不再按照 ground truth 中心点,严格分配指定 cell,而是根据预测值寻找 IOU 最大的预测框作为正例。

  1. Yolov1 中的置信度标签,就是预测框与真实框的 IOU,Yolov3 为什么是1?

置信度意味着该预测框是或者不是一个真实物体,是一个二分类,所以标签是1、0更加合理。
两种方法进行置信标签,第一种:置信度标签取预测框与真实框的IOU;第二种:置信度标签取1。第一种的结果是,在训练时,有些预测框与真实框的IOU极限值就是0.7左右,置信度以0.7作为标签,置信度学习有一些偏差,最后学到的数值是0.5,0.6,那么假设推理时的激活阈值为0.7,这个检测框就被过滤掉了。但是IOU为0.7的预测框,其实已经是比较好的学习样例了。尤其是coco中的小像素物体,几个像素就可能很大程度影响IOU,所以第一种训练方法中,置信度的标签始终很小,无法有效学习,导致检测召回率不高。而检测框趋于收敛,IOU收敛至1,置信度就可以学习到1,这样的设想太过理想化。而使用第二种方法,召回率明显提升了很高。

  1. 为什么有忽略样例?

忽略样例是Yolov3中的点睛之笔。由于Yolov3使用了多尺度特征图,不同尺度的特征图之间会有重合检测部分。比如有一个真实物体,在训练时被分配到的检测框是特征图1的第三个box,IOU达0.98,此时恰好特征图2的第一个box与该ground truth的IOU达0.95,也检测到了该ground truth,如果此时给其置信度强行打0的标签,网络学习效果会不理想。
如果给全部的忽略样例置信度标签打0,那么最终的loss函数会变成,目标检测之-YOLO家族那些事 - 图71目标检测之-YOLO家族那些事 - 图72 置信度互相抵消。 而加入了忽略样例之后,网络才可以学习区分正负例。