写点什么

全网呕血整理:关于 YOLO v3 原理分析

发布于: 2021 年 01 月 18 日

摘要:YOLO 系列的目标检测算法可以说是目标检测史上的宏篇巨作,接下来我们来详细介绍一下 YOLO v3 算法内容。

算法基本思想


首先通过特征提取网络对输入特征提取特征,得到特定大小的特征图输出。输入图像分成 13×13 的 grid cell,接着如果真实框中某个 object 的中心坐标落在某个 grid cell 中,那么就由该 grid cell 来预测该 object。每个 object 有固定数量的 bounding box,YOLO v3 中有三个 bounding box,使用逻辑回归确定用来预测的回归框。


网络结构



上图 DBL 是 Yolo v3 的基本组件。Darknet 的卷积层后接 BatchNormalization(BN)和 LeakyReLU。除最后一层卷积层外,在 yolo v3 中 BN 和 LeakyReLU 已经是卷积层不可分离的部分了,共同构成了最小组件。


主干网络中使用了 5 个 resn 结构。n 代表数字,有 res1,res2, … ,res8 等等,表示这个 res_block 里含有 n 个 res_unit,这是 Yolo v3 的大组件。从 Yolo v3 开始借鉴了 ResNet 的残差结构,使用这种结构可以让网络结构更深。对于 res_block 的解释,可以在上图网络结果的右下角直观看到,其基本组件也是 DBL。


在预测支路上有张量拼接(concat)操作。其实现方法是将 darknet 中间层和中间层后某一层的上采样进行拼接。值得注意的是,张量拼接和 Res_unit 结构的 add 的操作是不一样的,张量拼接会扩充张量的维度,而 add 只是直接相加不会导致张量维度的改变。


Yolo_body 一共有 252 层。23 个 Res_unit 对应 23 个 add 层。BN 层和 LeakyReLU 层数量都是 72 层,在网络结构中的表现为:每一层 BN 后面都会接一层 LeakyReLU。上采样和张量拼接操作各 2 个,5 个零填充对应 5 个 res_block。卷积层一共有 75 层,其中有 72 层后面都会接 BatchNormalization 和 LeakyReLU 构成的 DBL。三个不同尺度的输出对应三个卷积层,最后的卷积层的卷积核个数是 255,针对 COCO 数据集的 80 类:3×(80+4+1)=255,3 表示一个 grid cell 包含 3 个 bounding box,4 表示框的 4 个坐标信息,1 表示置信度。


下图为具体网络结果图。



输入映射到输出



不考虑神经网络结构细节的话,总的来说,对于一个输入图像,YOLO3 将其映射到 3 个尺度的输出张量,代表图像各个位置存在各种对象的概率。


我们看一下 YOLO3 共进行了多少个预测。对于一个 416416 的输入图像,在每个尺度的特征图的每个网格设置 3 个先验框,总共有 13133 + 26263 + 5252*3 = 10647 个预测。每一个预测是一个(4+1+80)=85 维向量,这个 85 维向量包含边框坐标(4 个数值),边框置信度(1 个数值),对象类别的概率(对于 COCO 数据集,有 80 种对象)。



边界框预测(Bounding Box Prediction)


Yolo v3 关于 bounding box 的初始尺寸还是采用 Yolo v2 中的 k-means 聚类的方式来做,这种先验知识对于 bounding box 的初始化帮助还是很大的,毕竟过多的 bounding box 虽然对于效果来说有保障,但是对于算法速度影响还是比较大的。


在 COCO 数据集上,9 个聚类如下表所示,注这里需要说明:特征图越大,感受野越小。对小目标越敏感,所以选用小的 anchor box。特征图越小,感受野越大。对大目标越敏感,所以选用大的 anchor box。



Yolo v3 采用直接预测相对位置的方法。预测出 b-box 中心点相对于网格单元左上角的相对坐标。直接预测出(tx,ty,tw,th,t0),然后通过以下坐标偏移公式计算得到 b-box 的位置大小和 confidence。



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。在训练这几个坐标值的时候采用了 sum of squared error loss(平方和距离误差损失),因为这种方式的误差可以很快的计算出来。


注:这里 confidence = Pr(Object)*IoU 表示框含有 object 的置信度和这个 box 预测的有多准。也就是说,如果这个框对应的是背景,那么这个值应该是 0,如果这个框对应的是前景,那么这个值应该是与对应前景 GT 的 IoU。


Yolo v3 使用逻辑回归预测每个边界框的分数。如果边界框与真实框的重叠度比之前的任何其他边界框都要好,则该值应该为 1。如果边界框不是最好的,但确实与真实对象的重叠超过某个阈值(Yolo v3 中这里设定的阈值是 0.5),那么就忽略这次预测。Yolo v3 只为每个真实对象分配一个边界框,如果边界框与真实对象不吻合,则不会产生坐标或类别预测损失,只会产生物体预测损失。


多尺度预测


在上面网络结构图中可以看出,Yolo v3 设定的是每个网格单元预测 3 个 box,所以每个 box 需要有(x, y, w, h, confidence)五个基本参数。Yolo v3 输出了 3 个不同尺度的 feature map,如上图所示的 y1, y2, y3。y1,y2 和 y3 的深度都是 255,边长的规律是 13:26:52。


每个预测任务得到的特征大小都为 N ×N ×[3∗(4+1+80)] ,N 为格子大小,3 为每个格子得到的边界框数量, 4 是边界框坐标数量,1 是目标预测值,80 是类别数量。对于 COCO 类别而言,有 80 个类别的概率,所以每个 box 应该对每个种类都输出一个概率。所以 3×(5 + 80) = 255。这个 255 就是这么来的。


Yolo v3 用上采样的方法来实现这种多尺度的 feature map。在 Darknet-53 得到的特征图的基础上,经过六个 DBL 结构和最后一层卷积层得到第一个特征图谱,在这个特征图谱上做第一次预测。Y1 支路上,从后向前的倒数第 3 个卷积层的输出,经过一个 DBL 结构和一次(2,2)上采样,将上采样特征与第 2 个 Res8 结构输出的卷积特征张量连接,经过六个 DBL 结构和最后一层卷积层得到第二个特征图谱,在这个特征图谱上做第二次预测。Y2 支路上,从后向前倒数第 3 个卷积层的输出,经过一个 DBL 结构和一次(2,2)上采样,将上采样特征与第 1 个 Res8 结构输出的卷积特征张量连接,经过六个 DBL 结构和最后一层卷积层得到第三个特征图谱,在这个特征图谱上做第三次预测


就整个网络而言,Yolo v3 多尺度预测输出的 feature map 尺寸为 y1:(13×13),y2:(26×26),y3:(52×52)。网络接收一张(416×416)的图,经过 5 个步长为 2 的卷积来进行降采样(416 / 2ˆ5 = 13,y1 输出(13×13)。从 y1 的倒数第二层的卷积层上采样(x2,up sampling)再与最后一个 26×26 大小的特征图张量连接,y2 输出(26×26)。从 y2 的倒数第二层的卷积层上采样(x2,up sampling)再与最后一个 52×52 大小的特征图张量连接,y3 输出(52×52)感受一下 9 种先验框的尺寸,下图中蓝色框为聚类得到的先验框。黄色框式 ground truth,红框是对象中心点所在的网格。



预测框的 3 种情况


预测框一共分为三种情况:正例(positive)、负例(negative)、忽略样例(ignore)。


  • 正例:任取一个 ground truth, 与上面计算的 10647 个框全部计算 IOU, IOU 最大的预测框, 即为正例。并且一个预测框, 只能分配给一个 ground truth。 例如第一个 ground truth 已经匹配了一个正例检测框, 那么下一个 ground truth, 就在余下的 10646 个检测框中, 寻找 IOU 最大的检测框作为正例。ground truth 的先后顺序可忽略。正例产生置信度 loss、检测框 loss、类别 loss。预测框为对应的 ground truth box 标签(使用真实的 x、y、w、h 计算出); 类别标签对应类别为 1, 其余为 0; 置信度标签为 1。

  • 忽略样例:正例除外, 与任意一个 ground truth 的 IOU 大于阈值(论文中使用 5), 则为忽略样例。忽略样例不产生任何 loss。


o 为什么会有忽略样例?


由于 Yolov3 采用了多尺度检测, 那么再检测时会有重复检测现象. 比如有一个真实物体,在训练时被分配到的检测框是特征图 1 的第三个 box,IOU 达 0.98,此时恰好特征图 2 的第一个 box 与该 ground truth 的 IOU 达 0.95,也检测到了该 ground truth,如果此时给其置信度强行打 0 的标签,网络学习效果会不理想。


  • 负例:正例除外(与 ground truth 计算后 IOU 最大的检测框,但是 IOU 小于阈值,仍为正例), 与全部 ground truth 的 IOU 都小于阈值(0.5), 则为负例。负例只有置信度产生 loss, 置信度标签为 0。


如下图所示:



  • λ为权重参数, 用于控制检测框 loss, obj 与 noobj 的置信度 loss, 以及类别

  • 对于正类而言, 1ijobj 输出为 1; 对于负例而言, 1ijnoobj 输出为 1; 对于忽略样例而言, 全部为 0;

  • 类别采用交叉熵作为损失函数。


类别预测


类别预测方面 Yolo v2 网络中的 Softmax 分类器,认为一个目标只属于一个类别,通过输出 Score 大小,使得每个框分配到 Score 最大的一个类别。但在一些复杂场景下,一个目标可能属于多个类(有重叠的类别标签),因此 Yolo v3 用多个独立的 Logistic 分类器替代 Softmax 层解决多标签分类问题,且准确率不会下降。


举例说明,原来分类网络中的 softmax 层都是假设一张图像或一个 object 只属于一个类别,但是在一些复杂场景下,一个 object 可能属于多个类,比如你的类别中有 woman 和 person 这两个类,那么如果一张图像中有一个 woman,那么你检测的结果中类别标签就要同时有 woman 和 person 两个类,这就是多标签分类,需要用 Logistic 分类器来对每个类别做二分类。Logistic 分类器主要用到 sigmoid 函数,该函数可以将输入约束在 0 到 1 的范围内,因此当一张图像经过特征提取后的某一类输出经过 sigmoid 函数约束后如果大于 0.5,就表示该边界框负责的目标属于该类。


物体分数和类置信度


物体分数:表示一个边界框包含一个物体的概率,对于红色框和其周围的框几乎都为 1,但边角的框可能几乎都为 0。物体分数也通过一个 sigmoid 函数,表示概率值。


类置信度:表示检测到的物体属于一个具体类的概率值,以前的 YOLO 版本使用 softmax 将类分数转化为类概率。在 YOLOv3 中作者决定使用 sigmoid 函数取代,原因是 softmax 假设类之间都是互斥的,例如属于“Person”就不能表示属于“Woman”,然而很多情况是这个物体既是“Person”也是“Woman”。


输出处理


我们的网络生成 10647 个锚框,而图像中只有一个狗,怎么将 10647 个框减少为 1 个呢?首先,我们通过物体分数过滤一些锚框,例如低于阈值(假设 0.5)的锚框直接舍去;然后,使用 NMS(非极大值抑制)解决多个锚框检测一个物体的问题(例如红色框的 3 个锚框检测一个框或者连续的 cell 检测相同的物体,产生冗余),NMS 用于去除多个检测框。


具体使用以下步骤:抛弃分数低的框(意味着框对于检测一个类信心不大);当多个框重合度高且都检测同一个物体时只选择一个框(NMS)。



为了更方便理解,我们选用上面的汽车图像。首先,我们使用阈值进行过滤一部分锚框。模型有 19193*85 个数,每个盒子由 85 个数字描述。将(19,19,3,85)分割为下面的形状:


box_confidence:(19,19,3,1)表示 19*19 个 cell,每个 cell 的 3 个框,每个框有物体的置信度概率;


boxes:(19,19,3,4)表示每个 cell 的 3 个框,每个框的表示;


box_class_probs:(19,19,3,80)表示每个 cell 的 3 个框,每个框 80 个类检测概率。


每个锚框我们计算下面的元素级乘法并且得到锚框包含一个物体类的概率,如下图:



即使通过类分数阈值过滤一部分锚框,还剩下很多重合的框。第二个过程叫 NMS,里面有个 IoU,如下图所示。



实现非极大值抑制,关键在于:选择一个最高分数的框;计算它和其他框的重合度,去除重合度超过 IoU 阈值的框;回到步骤 1 迭代直到没有比当前所选框低的框。



Loss Function


在 Yolo v3 的论文里没有明确提出所用的损失函数,确切地说,Yolo 系列论文里面只有 Yolo v1 明确提了损失函数的公式。在 Yolo v1 中使用了一种叫 sum-square error 的损失计算方法,只是简单的差方相加。我们知道,在目标检测任务里,有几个关键信息是需要确定的:(x,y),(w,h),class,confidence 。根据关键信息的特点可以分为上述四类,损失函数应该由各自特点确定。最后加到一起就可以组成最终的 loss function 了,也就是一个 loss function 搞定端到端的训练。



yolov3 网络硬核讲解(视频)


视频地址:


https://www.bilibili.com/video/BV12y4y1v7L6?from=search&seid=442233808730191461


真实值是如何编码




预测锚框的设计



锚框与目标框做 iou





本文分享自华为云社区《YOLOV3 原理分析(全网资料整理)》,原文作者:lutianfei 。


点击关注,第一时间了解华为云新鲜技术~


发布于: 2021 年 01 月 18 日阅读数: 29
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
全网呕血整理:关于YOLO v3原理分析