闲话少说,进入正题。YOLO是一种One-stage的物体检测网络1。one-stage即直接生成物体的类别概率和位置坐标值,经过单次检测就可以直接得到结果;相对应的是two-stage甚至multi-stage,multi-stage已经淘汰,所以不提,two-stage则是将检测问题划分为两个阶段,先产生候选区域(region proposals)然后对候选区域分类(一般还需要对位置精修),Faster R-CNN之类的就属于这一类2。v1带有全连接网络,但是v2和v3都舍弃掉了全连接网络,改成了纯CNN的结构,主要目的是减少参数和加快网络的分类速度。

YOLO的速度很快,下图是YOLO V3和其他网络的检测速度对比图1

可以看到YOLO网络具有很强的实时性(虽然是在性能很强的GPU上跑的)。

大致了解下背景之后我们直接看网络。

V1

网络结构

直接放论文中的图:

注意上图中提到pretrain步骤中使用的图片分辨率为$224 \times 224$,而在detection步骤中图片分辨率用的却是$448 \times 448$,这点在后面的版本会被统一成$448 \times 448$

或者可以表示成这张图:

可以看到,前20层是GoogleNet inception V1网络(有改动),这部分用于特征提取,以提高模型泛化能力。pretrain步骤中就是用了这部分网络来做分类任务,然后再用在Object Detection任务上。

除了最后一层用的是线性激活函数,其他层用的是leaky rectified线性激活函数。

目标检测过程

  1. 将原始图片变形成$448 \times 448$大小
  2. 将图片划分成$S \times S$个网格(这里$S$为7),每个网格预测$B$个bounding box的置信度和位置(中心坐标和box的宽高)(这里$B$为2)
  3. 每个网格预测$C$个类别对应的概率$\mathrm{Pr}$

结合上面的图,最后网络生成$7 \times 7 \times 30$的输出,每个网格30维的输出,总共$7 \times 7$个网格。每个网格预测2个bounding box的坐标$(x, y, w, h)$和box内是否包含物品的confidence,以及物品属于20类别中每一类的概率(训练数据为VOC,一个20分类数据集),所以每个网格输出$(4 \times 2 + 2 + 20) = 30$的向量。

上图中图片就被划分为$7 \times 7$的网格,每个grid(红色框选部分)对应两个不同的bounding box(黄色框)每个box由$(x, y, w, h)$确定位置和大小(x和y表示位置,w和h表示宽高)。这些预测值会在训练过程中与数据集中标注的ground truth$(Gx, Gy, Gw, Gh)$进行对比和训练,可以计算出初始bounding box平移和伸缩得到最终位置的模型。

置信度公式

$$\mathrm{confidence} = \mathrm{Pr}(\mathrm{Object}) \times \mathrm{IOU}^{\mathrm{truth}}_{\mathrm{pred}}$$

$\mathrm{Pr}(\mathrm{Object})$表示有无人工标记的物品落入网格内,如果有则为1,没则为0。$\mathrm{IOU}^{\mathrm{truth}}_{\mathrm{pred}}$代表bounding box和真实标记的box之间的重合度,值越大box越接近ground truth。

注意每个网格之需要预测20个类别中的每个类别的概率,而不是bounding box来预测,即分类是在网格基础上作出的,所以只需要20,而不是40个(即不是每个bounding box各预测20个)。$\mathrm{confidence}$只用来表示bounding box中是否有物品,不需要预测类别。

IOU解析看这里

NMS

NMS用于从多个bounding box中筛选出最合适的几个,简单地说就是先过滤掉score低于阈值的box,并去除掉重叠度比较高的box,具体可以看这里

预测类别

每个网格会预测$C$个(这里是20个)条件类别概率$\mathrm{Pr}(\mathrm{Class}_i|\mathrm{Object})$,前提是网格只包含一个物品,这个概率就是该物品对应某个类别的概率。

在测试阶段就会将每个网格的conditional class probability与每个bounding box的confidence score想成,就可以得到每个bounding box的class-specific confidence scores:

$$\mathrm{Pr}(\mathrm{Class}i|\mathrm{Object}) \times \mathrm{Pr}(\mathrm{Object}) \times \mathrm{IOU}^{\mathrm{truth}}{\mathrm{pred}} = \mathrm{Pr}(\mathrm{Class}i) \times \mathrm{IOU}^{\mathrm{truth}}{\mathrm{pred}}$$

class-specific confidence scores包含两个信息:预测该bounding box中物体类别的probability信息(物体类别分类)和bounding box定位坐标的准确度(主要是IOU计算,物体定位)。

损失函数

先看下SSE:

图源见水印

YOLO的损失函数就是在SSE基础上构建的:

对应到输出中:

看上图(此图来自目标检测中One-stage的检测算法)主要有三个部分:位置、confidence、分类。三个部分都用了均方差算法。YOLO中位置误差权重为5,类别误差权重为1,不包含物体的box的置信度误差权重为0.5(因为我们不怎么关心这些box,而这类box数量很多),包含物品的权重为1。此外,为了让损失函数能够反映大box的误差对检测的影响应小于小box的误差对检测的影响,作者在YOLO中将box的大小w、h求平方根,这样,在一个像素大小为100100的物体和像素大小为2020的物体都预测大了10个像素时,后者对损失函数的影响更大。

总结

优点:

  1. 检测速度快
  2. 能很好地避免背景错误,因为在训练和测试时网络都可以看到一整张图片,可以很好地利用上下文信息,不容易将背景当成要预测的物品
  3. 可以学到物品的泛化特征,从而迁移到其他领域

缺点:

  1. 精度相对于其他目标检测算法较低
  2. 容易产生物品的定位错误
  3. 对小物品检测效果不好,尤其是密集的小物品,因为一个栅格只能预测2个物品

核心:
1. Grid Cell的设计,舍弃用selective search获取Proposal Region的设计
2. 将目标检测转化成了回归问题(大大提升速度)

V2

从这一版开始YOLO就没有全连接层了,开始变成了真正的FCN(纯卷积神经网络)3。引入anchor,同时使用了k-means方法来对anchor数量进行选择;作者还引入了世界树(WordTree)结构,并提出了一种层次性联合训练的方法,同时用COCO和ImageNet训练集来对模型进行训练。所有的改进可以用下图来表示:

Batch Normalization

YOLO V2给每个卷积层后添加了batch normalization,改善了收敛速度并减少了对其它正则方法的依赖,提高了mAP 2个百分点(mean Average Precision,平均精度均值)。关于batch normalization的详细解析看这里

使用高分辨率图像微调特征提取器

YOLO V1的特征提取器在$224 \times 224$的分辨率上进行训练,正式训练时才将图片分辨率提升到$448 \times 448$,这样需要模型去适应新的分辨率。因此YOLO V2改成了先将特征提取器在$224 \times 224$分辨率上训练,然后再在$448 \times 448$分辨率上进行训练并fine tune(训练10个epoch),使网络适应$448 \times 448$分辨率,最后才让整体网络在$448 \times 448$的检测样本上进行训练。这个操作提升了mAP 4个百分点。

先验框

第二版中借鉴了Faster R-CNN中的anchor(先验框)思想。为了加入anchor boxes来预测候选框,作者移除了全连接层还去掉了池化层,以此保证网络卷积层输出具有更高的分辨率。然后将网络的输入分辨率调整到$416 \times 416$(图片分辨率),这样在经过多次卷积后就可以得到$13 \times 13$的feature map(之前调整分辨率就是为了让这里的feature map的长宽都是奇数,这样就可以产生一个中心框center cell)。feature map中每个grid对应9个anchor boxes(先验框),最终得到$13 \times 13 \times 9 = 1521$个anchor boxes,比1版多很多。这些不同大小、宽高比的“框”,用来覆盖图像中物品的多种尺度,最后目标检测将会依据这些先验框作为候选区来检测目标和微调边框位置/大小。这种设定让YOLO第二版的recall提高到了88%,但是导致了mAP有0.2%的下降。这里的9个先验框是手工设置的。

YOLO V2还对先验框进行了改良。改良后的先验框的尺度是通过k-means聚类来选定的,具体做法是先对训练集中标注的边框进行k-means聚类分析,然后寻找尽可能匹配样本的边框尺寸。YOLO V2使用的k-means聚类算法的距离度量是:$d(\mathrm{box}, \mathrm{centroid}) = 1 – \mathrm{IOU}(\mathrm{box}, \mathrm{centroid})$,$\mathrm{centroid}$被选作中心的边框,$\mathrm{box}$是其他边框,$d$是用于计算“距离”的函数。这里我们更加关心的是边框的IOU,而不是两个边框之间的欧式距离,所以公式中用的是$\mathrm{IOU}$。

图源见水印

可以从上图看出,聚类选出的5个框就可以达到9个手工设置的先验框达到的Avg IOU。

但是这样改进还不够,因为原本anchor box的位置的计算公式为:$x = (t_x * w_a) – x_a$和$y = (t_y * h_a) – y_a$,这两个公式得出的偏移量因为没有限制,导致预测出来的边框中心可能会跑到对应的grid之外,并且会让训练收敛变慢。因此作者改成了和YOLO V1一样的方法,直接预测中心点,并用sigmoid函数来将偏移量限制在0~1之间(针对边框的比例),计算公式变成:

$b_x, b_y, b_w, b_h$分别是anchor box的中心坐标和宽高,中心坐标的尺度是相对于网络的。这样就可以将预测出来的边框限制在grid内,使得模型更容易学习且预测更稳定。网络需要学习的是$t_x, t_y, t_w, t_h, t_o$,$c_x, c_y$是当前网格左上角到图像左上角的距离,$p_w, p_h$是先验框的宽和高。

上图最下面的公式$Pr(object) * IOU(b, object) = \sigma{(t_o)}$是预测边框的置信度,相比V1多了sigmoid函数。

添加Passthrough增强小物品检测性能

同时为了改善V1小目标检测的性能,作者添加了passthrough层,将最后一个pooling之前的$26 \times 26 \times 512$的高分辨率fature map经过1拆4之后直接连到$13 \times 13$的feature map上,即把原来的$26 \times 26 \times 512$转成$13 \tiems 13 \times 2048$并拼接起来。这样可以在feature map中保留一些细节信息,从而提升检测小目标的性能。最后使mAP提升%1。

图源见水印

此外,YOLO V2因为是FCN,所以可以输入不同分辨率的图片来训练。

训练过程

  1. 在ImageNet上预训练Darknet-19,输入是$224 \times 224$分辨率的图片,训练160个epoch
  2. 输入调整为$448 \times 448$,继续训练10个epoch
  3. 修改DarkNet-19,移除最后一个卷积层、global avg pooling和softmax,并增加3个$3 \times 3 \times 1024$卷积层,同时增加一个passthrough层,最后用$1 \times 1$输出预测结果

误差函数

$1_{MaxIOU<Thresh}$意思是预测边框中,与真实对象边框IOU最大的那个,其IOU<阈值Thresh,此系数为1,即计入误差,否则为0,不计入误差。YOLO2使用Thresh=0.6。
$1_{t<128000}$意思是前128000次迭代计入误差。注意这里是与先验框的误差,而不是与真实对象边框的误差。可能是为了在训练早期使模型更快学会先预测先验框的位置。
$1_{k}^{truth}$意思是该边框负责预测一个真实对象(边框内有对象)。
各种$\lambda$是不同类型的调节系数。

YOLO9000

这次我关注的重点不在YOLO9000,因此引用下别人的东西一笔带过。

以下内容引用自【YOLO】yolo v1到yolo v3

论文提出了一种联合训练的机制:使用识别数据集训练模型识别相关部分,使用分类数据集训练模型分类相关部分。
检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。所以在YOLO V1中,边界框的预测其实并不依赖于物体的标签,YOLO V2实现了在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。
作者选择在COCO和ImageNet数据集上进行联合训练,遇到的第一问题是两者的类别并不是完全互斥的,比如”Norfolk terrier”明显属于”dog”,所以作者提出了一种层级分类方法(Hierarchical classification),根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree,结合COCO和ImageNet建立的词树(WordTree)如下图所示:

WordTree中的根节点为”physical object”,每个节点的子节点都属于同一子类,可以对它们进行softmax处理。在给出某个类别的预测概率时,需要找到其所在的位置,遍历这个路径,然后计算路径上各个节点的概率之积。
在训练时,如果是检测样本,按照YOLOv2的loss计算误差,而对于分类样本,只计算分类误差。在预测时,YOLOv2给出的置信度就是 ,同时会给出边界框位置以及一个树状概率图。在这个概率图中找到概率最高的路径,当达到某一个阈值时停止,就用当前节点表示预测的类别。

总结

V2变成了FCN,可以适应不同的输入尺寸,可以根据需要调整检测性能和检测速度。因为提出了WordTree、使用了ImageNet和COCO数据集来联合训练,所以可以识别超过9000中物品。但是对于重叠的分类性能仍然不是很好。

V3

这才是重点,前面只是介绍。V3没有什么创新,只是吸取了别的网络的优点(并在论文中嘲讽了RetinaNet)。

V3也是纯卷积神经网络,总共75个卷积层,其中包含了一些skip connection和上采样层,没有pooling。一层stride为2的卷积层用来对feature map进行下采样,避免对低层次feature的损失。

网络结构

首先是Darknet-53,和之前一样,用作特征提取器。这部分会在Imagenet上进行分类任务训练。

可以看到总共有53个卷积层,同时加上了一些shortcut connections

图片来自YOLOv3 深入理解

v3采用了passthrough结构来实现细粒度特征的检测。v3采用了3中不同尺度的feature map来进行目标检测,分别是$13 \times 13$、$26 \times 26$、$52 \times 52$。$13 \times 13$取自79层,这一层对应的下采样率为32(结合上图理解),这一层提取出的feature map适用于大尺度对象的采样。从79层开始进行上采样并与61层的feature map concatenate,最后得到91层较细粒度的feature map,这里对应的下采样率为16,输出的feature map为$52 \times 52$,适用于中等尺度对象的检测。最后91层上采样,并与36层feature map concatenate,这里对应下采样率为8,适合检测小尺度对象。可以结合下图进行理解。

ps:concatenate就是张量拼接,说白了就是将一个张量“接”在另一个张量后面,例如$4 \times 4 \times 512$的张量和$4 * 4 * 512$的张量拼接就变成$4 \times 4 \times 1024$的张量。

上图中红框是对象中心,黄色是要学习的ground truth,3个蓝色框是和v2类似的先验框(也是聚类得到的)。先验框大小和对应的feature map如下:

feature map $13 \times 13$ $26 \times 26$ $52 \times 52$
感受野
先验框 $116 \times 90$ $156 \times 198$ $373 \times 326$ $30 \times 61$ $62 \times 45$ $59 \times 119$ $10 \times 13$ $16 \times 30$ $33 \times 23$

可以计算出,在一张图片上,v3会作出$13 \times 13 \times 3 + 26 \times 26 \times 3 + 52 \times 52 \times 3 = 10647$个预测,比v2的845个多很多,而且是在不同分辨率上进行的,所以v3的小物品检测能力和对重叠物品的检测能力比v2强。

除了上面的改动外,v3的预测用的函数也变了,从softmax改成了logistic,这样就可以支持多标签了(不需要再像v2那样弄个WordTree)。

预测

YOLO通过一个$1 \times 1$大小的卷积核的卷积层来进行object detection,最终预测$(52 \times 52 + 26 \times 26 + 13 \times 13) \times 3 = 10647$个边界框,最终先通过目标置信度阈值来过滤掉部分边界框,然后通过NMS来处理剩下的边界框(具体解析看上方V1部分的解析),这样可以解决对同一个物品多次检测的问题。

损失函数

v3的损失函数略有改动,相比于v2的:

最后面三个平方误差在v3中被交叉熵误差取代,即现在通过逻辑回归预测v3中对象置信度和类别预测。

交叉熵:

总结

优点

  1. 性能和精确度达到平衡,适用于业界
  2. 三种scale下进行目标检测,提升了对重叠物品、小物品的检测性能
  3. 可以用在不同分辨率的图片上

缺点

  1. mAP略有下降(相比v2)

参考资料

YOLO V1

How to implement a YOLO (v3) object detector from scratch in PyTorch: Part 1这是Part 1,本文章部分内容来自这个系列,这个文章中对应的代码只复现了预测部分,没有复现训练部分
深度学习: one-stage/two-stage/multi-stage 目标检测算法大致了解下one-stage和two/multi-stage之间的关系
目标检测中One-stage的检测算法
【YOLO】yolo v1到yolo v3
非极大值抑制(Non-Maximum Suppression,NMS)
详细理解YOLO
<机器爱学习>YOLO v1深入理解
YOLO: Real-Time Object Detection(YOLO项目官网)

YOLO V2

【YOLO】yolo v1到yolo v3
<机器爱学习>YOLOv2 / YOLO9000 深入理解

YOLO V3

【YOLO】yolo v1到yolo v3
YOLOv3: An Incremental Improvement解读
YOLOv3 深入理解
从零开始PyTorch项目:YOLO v3目标检测实现(上)
yolo系列之yolo v3【深度解析】
YOLO v3解析

SRIN 目标检测

发表评论

电子邮件地址不会被公开。 必填项已用*标注