Keras YOLOv3代码详解(二):目标检测原理解析

我们上周分析了darknet53的网络结构,并使用Netron工具查看,搞清楚darknet53是一个具有252层的网络,并在13x13、26x26、52x52三个尺寸上输出3张特征图(featue maps),具体内容请参考:

Keras YOLO v3代码详解(一):darknet53网络结构分析+Netron工具

 

本周,我们进一步研究YOLOv3是怎样检测图片内容的,在这篇文章和下一篇文章中,我们先不研究如何训练YOLOv3的darknet53网络,而是先看一看使用已经训练好的YOLOv3模型,相应的Python程序时如何完成图片中的目标检测的。

这篇文章的主要内容是介绍YOLOv3的目标检测原理,下一篇文章详细解读目标检测的代码部分。

这篇文章的内容主要包括6部分内容,分别是:(一)检测过程、(二)anchor box、(三)中心坐标和边框、(四)目标分数、(五)类别置信度、和(六)输出处理。

(一)检测过程

YOLOv3的图像检测过程大致如下:

(1)输入一张任意大小图片,保持长宽比不变的情况下,缩放至 w 或 h 达到416,生成416x416的新图,作为网络的输入input。即网络的输入是一张416x416、3通道的RGB图片。

(2)运行网络。YOLOv3的卷积神经网络(CNN)网络的输出把图片分成NxN个网格(YOLOv3多尺度预测,输出有3层featue maps,每层feature map有NxN个网格,分别为13x13 、26 x26 和52x52),然后每个网格负责去检测那些中心点落在该格子内的目标。下图是在一个13x13的feature map中对小狗进行识别:

Keras YOLOv3代码详解(二):目标检测原理解析_第1张图片

真值对象框中心所在的网格(标记为红色,第7行的第7个)会作为负责预测目标是否是小狗的单元格,它是真值框(标记为黄色)的中心。

每个单元格需要预测并产生3x(4+1+B)个值。如果将输入的特征图(feature map)划分为NxN网格,那么每层特征图最终预测值为 NxNx3x(4+1+B) 大小的张量。 其中,3为每层特征图anchor box数量;4为边界框中心点坐标(x , y)、宽w 和高h ;1为置信度;B:可识别目标的类别数(在YOLOv3中,COCO集为80类),即B=80。

YOLOv3输出的不同尺寸的特征图,其检测目标的不同效果如下图所示:

Keras YOLOv3代码详解(二):目标检测原理解析_第2张图片

因此,26x26和52x52尺寸的特征图可以帮助该网络学习细粒度特征,有利于检测较小的目标。

(3)通过非极大值抑制(NMS),筛选出框boxes、输出框class_boxes和置信度class_box_scores,再生成类别信息classes,生成最终的检测数据框。

(二)anchor box

直接通过卷积神经网络来预测边界框的宽度和高度看起来非常合理,但在实践中,训练会带来不稳定的梯度。

因此,YOLOv3通过聚类算法得到了3组先验框(即:预训练得到的默认边界框),目标检测器通过预测对数空间(log-space)变换来确定边界框。

有人把anchor box翻译成锚箱或锚点,不过从字面意思上都不容易理解,因此这里保留anchor box这个原始的名称。

YOLOv3 的先验框anchor box一共有3组共9个,由k-means聚类得到。在COCO数据集上,这9个先验框按不同尺寸特征图分组如下,每组3个:

13x13特征图对应:【(116*90),(156*198),(373*326)】

26x26特征图对应:【(30*61),(62*45),(59*119)】

52x52特征图对应:【(10*13),(16*30),(33*23)】

特征图越小,感受野越大,对大目标越敏感,所以选用大的anchor box;特征图越大,感受野越小,对小目标越敏感,所以选用小的anchor box。

(三)中心坐标和边框

对于每一个网格,我们检测那些中心点可能落在该格子内的目标,下面的公式描述了网络输出是如何转换,以获得边界框预测结果的(tx、ty、tw、th是YOLOv3网络输出特征图的一部分,作为预测目标位置和边框的输入):

Keras YOLOv3代码详解(二):目标检测原理解析_第3张图片

中心坐标

YOLOv3对输入的feature map的每一个网格的(tx, ty)使用 sigmoid 函数进行中心坐标预测,输出值在 0 和 1 之间,再加上网格单元的偏移来计算bx和by:

(1)网格单元的偏移是:[(0~N-1),(0~N-1)]二元组定义的目标中心所在网格的格子数,即:Cx、Cy;

(2)使用特征图尺寸(如:13x13、26x26或52x52)在水平x、垂直y两个维度对bx、by进行归一化,确定中心点的相对位置。

 

边界框

对(tw, th)执行对数空间变换,然后乘以anchor box的宽和高(pw, ph),来预测边界框的宽和高:

Keras YOLOv3代码详解(二):目标检测原理解析_第4张图片

同时,使用标准图片尺寸(416x416)在宽和高两个维度对bw、bh(因为,3组9个anchor box是基于416x416尺寸定义的)进行归一化,确定目标框的高和宽的相对位置。

上面所做的分别针对(bx、by)和(bw、bh)的归一化操作,是为了将基于特征图计算得出的目标框,方便地转化为416x416尺寸的目标框坐标,并进一步转化为输入图片上的目标框坐标,最后用于输出显示。

(四)目标分数

目标分数表示目标在边界框内的概率。红色网格和相邻网格的目标分数应该接近 1,而角落处的网格的目标分数可能接近 0。

目标分数的计算也使用sigmoid函数,因此它可以被理解为概率。

(五)类别置信度

类别置信度表示检测到的对象属于某个类别的概率(如person、car、dog、sports ball等)。在 v3 之前,YOLO 需要对类别分数执行 softmax 函数操作。

但是,YOLOv3舍弃了这种设计,作者选择使用 sigmoid 函数。因为对类别分数执行 softmax 操作的前提是类别是互斥的。简言之,如果对象属于一个类别,那么必须确保其不属于另一个类别。这在我们设置检测器的 COCO 数据集上是正确的。但是,当出现类别「女性」(Women)和「人」(Person)时,该假设不可行。这就是作者选择不使用 Softmax 激活函数的原因。

(六)输出处理

对于大小为 416x416 的图像,YOLOv3预测 一共会输出((52 x 52)+ (26 x 26) +(13 x 13)) x3 = 10647 个边界框。但是,我们的示例中只有一个对象——一只小狗。那么我们怎么才能将检测次数从10647减少到1呢?

目标置信度阈值:首先,我们根据它们的 Objectness 分数过滤边界框。通常,分数低于阈值的边界框会被忽略。

非极大值抑制:非极大值抑制(NMS)可解决对同一个图像的多次检测的问题,只保留得分最高的边界框。例如,红色网格单元的 3 个边界框可以检测一个框,或者临近网格可检测相同对象。

最后,调用画图函数绘制目标检测的结果输出。

 

下一章:

Keras YOLOv3代码详解(三):目标检测的流程图和源代码+中文注释

 

参考:

https://www.pytorchtutorial.com/yolo3-in-pytorch-1/

https://blog.csdn.net/KKKSQJ/article/details/83587138

(完)

你可能感兴趣的:(Keras YOLOv3代码详解(二):目标检测原理解析)