论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!

YOLOV2全面解读+YOLOV3全面解读!
  • yolov1可以参考: YOLOV1最全面解读!

文章目录

  • 【YOLOV2全面解读】
    • 一、Better
        • 1.1、Batch Normalization
        • 1.2、High Resolution Classifier
        • 1.3、Convolutional With Anchor Boxes
        • 1.4、Dimension Clusters
        • 1.5、Direct Location prediction
        • 1.6、Fine-Grained Features
        • 1.7、Multi-Scale Training
    • 二、Faster
        • 2.1、Darknet-19
        • 2.2、Training for Classification
        • 2.3、Training for Detection
    • 三、Stronger
  • 【YOLOV3全面解读】
    • 一、YOLOV3
        • 1.1、YOLOV3网络结构
        • 1.2、backbone
        • 1.3、Output
        • 1.4、some tricks
        • 1.5、loss function
    • 参考作者

主要包括三个部分:Better,Faster,Stronger,其中前面两部分基本上讲的是YOLOV2,最后一部分讲的是YOLO9000。

【YOLOV2全面解读】

一、Better

本篇论文是YOLO作者为了改进原有的YOLO算法所写的。
YOLO有两个缺点:

  • 1、定位不准确
  • 2、基于region proposal的方法相比召回率(预测样本中实际正样本数 / 预测的样本数)较低

因此YOLOv2主要是要在这两方面做提升。另外YOLOv2并不是通过加深或加宽网络达到效果提升,反而是简化了网络。

下面就是使用的一些手段。

1.1、Batch Normalization

BN(Batch Normalization:批次归一化)层简单讲就是对网络的每一层的输入都做了归一化,这样网络就不需要每层都去学数据的分布,收敛会快点。作者在YOLOv2中为每个卷积层都添加了BN层,由于BN可以规范模型,所以加入BN后就把dropout去掉了,实验证明添加了BN层可以提高2%的mAP。

  • 就是把每层输出input——>归一化到均值为0,方差为1正态分布。

1.2、High Resolution Classifier

现在基本跑个分类或目标检测模型都不会从随机初始化所有参数开始,所以一般都是用预训练(详细介绍参考:yolov1可以参考: 预训练(pre-training/trained)与微调!
)的网络来fine-tuning自己的网络,而且预训练的网络基本上都是在ImageNet数据集上跑的,一方面数据量大,另一方面训练时间久,而且也比较容易得到。

  • YOLOV1在预训练的时候用的是224×224的输入,一般预训练的分类模型都是在ImageNet数据集上进行的,然后在检测的时候采用448×448的输入。这会导致从分类模型切换到检测模型的时候,模型还要适应图像分辨率的改变
  • YOLOV2中将预训练分成两步: 首先用224×224的输入从头开始训练网络,大概160个epoch,然后再将输入调整到448×448,再训练10个epoch。注意这两步都是在ImageNet数据集上操作最后再在检测的数据集上fine tuning,也就是检测的时候用448×448的图像作为输入就可以顺利过渡了。

1.3、Convolutional With Anchor Boxes

  • YOLOV1是利用全连接层直接预测bounding box的坐标。
  • YOLOV2借鉴了Faster R-CNN的思想,引入anchor

YOLOV2做了以下改变:

  • 删掉全连接层和最后一个pooling层,使得最后的卷积层可以有更高分辨率的特征;
  • 缩减网络,用416×416大小的输入代替原来448×448。这样做是希望希望得到的特征图都有奇数大小的宽和高,奇数大小的宽和高会使得每个特征图在划分cell的时候就只有一个中心cell。因为大的目标一般会占据图像的中心,所以希望用一个中心cell去预测,而不是4个中心cell。网络最终将416×416的输入下采样32倍变为13×13大小的feature map输出,查看.cfg文件可以看到有8个pooling层。
  • YOLOV1中将输入图像分成7×7的网格,每个网格预测2个bounding box,一共只有772=98个box
  • YOLOV2中引入anchor boxes,输出feature map大小为13×13,每个cell有5个anchor box预测得到5个bounding box,一共有13×13×5=845个box。增加box数量是为了提高目标的定位准确率。

1.4、Dimension Clusters

Faster R-CNN中anchor box的大小和比例是按经验设定的,然后网络会在训练过程中调整anchor box的尺寸。如果一开始就能选择到合适尺寸的anchor box,那肯定可以帮助网络更好地预测。所以作者采用k-means的方式对训练集的bounding boxes做聚类,试图找到合适的anchor box
作者发现采用标准的k-means(即用欧式距离来衡量差异),在box的尺寸比较大的时候其误差也更大,而我们希望的是误差和box的尺寸没有太大关系。所以通过IOU定义了距离函数,使得误差和box的大小无关

注意:设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,所以聚类分析师使用box与聚类中的box之间的IOU值作为距离指标。

在VOC和COCO数据集上的聚类分析结果,随着聚类中心数目的增加,平均IOU值(各个边界框与聚类中心的IOU的平均值)是增加的,但是综合考虑模型复杂度和召回率,作者最终选取5个聚类中心作为先验框。
对于两个数据集,5个先验框的width和height如下:

COCO: (0.57273, 0.677385), (1.87446, 2.06253), (3.33843, 5.47434), (7.88282, 3.52778), (9.77052, 9.16828)
VOC: (1.3221, 1.73145), (3.19275, 4.00944), (5.05587, 8.09892), (9.47112, 4.84053), (11.2364, 10.0071)

这里先验框的大小具体指什么作者在论文中并没有说明,从代码实现上看,应该是相对于13*13的特征图的大小。

论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第1张图片

实验对比:

  • 采用聚类分析得到的先验框比手动设置的先验框平均IOU值更高,因此模型更容易训练学习。
  • 仅选取5种box就能达到Faster RCNN的9种box的效果。

1.5、Direct Location prediction

这部分细节很多,作者在引入anchor box的时候遇到的第二个问题:模型不稳定,尤其是在训练刚开始的时候。作者认为这种不稳定主要来自预测box的中心坐标 ( x , y ) (x,y) (x,y)值。
在基于region proposal的目标检测算法中,是通过预测 t x t_{x} tx t y t_{y} ty 来得到 ( x , y ) (x,y) (x,y) 值,也就是预测的是offsets。
论文这里公式是错的,应该是“+”号。依据是下文中的例子,以及Faster R-CNN中的公式。

论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第2张图片
  • 这个公式是无约束的,预测的边界框很容易向任何方向偏移。
    t x = 1 t_{x}=1 tx=1时,box将向右偏移一个anchor box的宽度;
    t y = 1 t_{y}=1 ty=1时,box将向左偏移一个anchor box的宽度;
  • 因此,每个位置预测的边界框可以落在图片任何位置,这导致模型的不稳定性,在训练时需要很长时间来预测出正确的offsets。
  • YOLOv2中没有采用这种预测方式,而是沿用了YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值。网络在最后一个卷积层输出 13×13的feature map,有13×13个cell,每个cell有5个anchor box来预测5个bounding box,每个bounding box预测得到5个值。
    分别为: t x 、 t y 、 t w 、 t h 和 t o t_{x}、t_{y}、t_{w}、t_{h}和t_{o} txtytwthto(类似YOLOv1的confidence)为了将bounding box的中心点约束在当前cell中,使用sigmoid函数将tx、ty归一化处理,将值约束在0~1,这使得模型训练更稳定。
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第3张图片
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第4张图片

1.6、Fine-Grained Features

细粒度特征

  • 这里添加了一个直通层(passthrough layer),即就是源码中的reorg layer,将前面一层的26×26的特征图和本层13×13的特征图进行连接,与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。
    在13×13的特征图上做预测,虽然对于大目标已经足够了,但对小目标不一定足够好,这里合并前面大一点的特征图可以有效的检测小目标。
    具体操作:对于26×26×512的特征图,经passthrough层处理之后就变成了13×13×2048的新特征图(特征图大小变为1/4,而通道数变为以前的4倍),然后与后面的13×13×1024特征图连接在一起形成13×13×3072的特征图,最后在该特征图上卷积做预测。

1.7、Multi-Scale Training

YOLOv2中只有卷积层和池化层,因此不需要固定的输入图片的大小。为了让模型更有鲁棒性,作者引入了多尺度训练。就是在训练过程中,每迭代一定的次数,改变模型的输入图片大小

注意:这一步是在检测数据集上fine tuning时候采用的,不要跟前面在Imagenet数据集上的两步预训练分类模型混淆。

具体操作:

  • 在训练时,每 10 个batch?确定不是10个epoch?网络就会随机选择另一种 size 的输入。
  • 网络输入是416×416,经过5次max pooling之后会输出13×13的feature map,也就是下采样32倍,因此作者采用32的倍数作为输入的size,具体采用320、352、384、416、448、480、512、544、576、608共10种size。
  • 输入图片大小为320×320时,特征图大小为10×10,输入图片大小为608×608时,特征图大小为19×19。每次改变输入图片大小还需要对最后检测层进行处理,然后开始训练。
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第5张图片
  • 这种网络训练方式使得相同网络可以对不同分辨率的图像做检测。在输入 size 较大时,训练速度较慢,在输入 size 较小时,训练速度较快,而 multi-scale training 又可以提高准确率,因此算是准确率和速度都取得一个不错的平衡。

二、Faster

  • YOLOV1作者采用的训练网络是基于GooleNet,GooleNet在计算复杂度上要优于VGG16,但是在ImageNet上的top-5准确率要稍低于VGG16。
  • YOLOV2,作者采用了新的分类模型作为基础网络,那就是Darknet-19。

2.1、Darknet-19

网络包含19个卷积层和5个max pooling层,而在YOLOV1中采用的GooleNet,包含24个卷积层和2个全连接层,因此Darknet-19整体上卷积卷积操作比YOLOV1中用的GoogleNet要少,这是计算量减少的关键。最后用average pooling层代替全连接层进行预测。

论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第6张图片

2.2、Training for Classification

这部分前面有提到,就是训练处理的小trick。这里的Training for Classification都是在ImageNet上进行预训练。
YOLOV2的训练主要包括三个阶段:

  • 第一阶段: 在ImageNet分类数据集上从头开始预训练Darknet-19,训练160个epoch。输入图像的大小是224×224,初始学习率为0.1。另外在训练的时候采用了标准的数据增加方式比如随机裁剪,旋转以及色度,亮度的调整等。
  • 第二阶段: 将网络的输入调整为448×448,继续在ImageNet分类数据集上fine-tuning分类模型,训练10个epoch。参数的除了epoch和learning rate改变外,其他都没变,这里learning rate改为0.001。

2.3、Training for Detection

  • 第三阶段: 修改Darknet-19分类模型为检测模型,并在检测数据集上继续fine tuning网络。

  • 其中网络修改包括: 移除最后一个卷积层、global avgerage pooling层以及softmax层,新增了三个3×3卷积层,同时增加了一个passthrough层,最后使用 1×1卷积层输出预测结果。输出通道数计算如下。对于VOC数据,每个 c e l l cell cell预测num=5个bounding box,每个bounding box有5个坐标值和20个类别值,所以每个cell有125个filter。即: f i l t e r n u m = n u m ∗ ( c l a s s e s + 5 ) = 5 ∗ ( 20 + 5 ) = 125 filter_{num} = num * (classes + 5) = 5 * (20 + 5) = 125 filternum=num(classes+5)=5(20+5)=125

  • 注意:

  1. 这里 f i l t e r n u m filter_{num} filternum 的计算和YOLOV1不同,在YOLOv1中: f i l t e r n u m = c l a s s e s + n u m ∗ ( c o o r d s + c o n f i d e n c e ) = 20 + 2 ∗ ( 4 + 1 ) = 30 filter_{num} = classes + num * (coords + confidence) = 20 + 2 * (4 + 1) = 30 filternum=classes+num(coords+confidence)=20+2(4+1)=30在YOLOV1中,类别概率是由cell来预测的,一个cell对应的两个box的类别概率是一样的,但是在YOLOV2中,类别概率是属于box的,每个box对应一个类别概率,而不是由cell决定,因此这边每个box对应25个预测值(5个坐标加20个类别值)。
  2. YOLOV2和YOLOV3的计算方式是一致的。 YOLOv2训练的三个阶段如下图所示:
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第7张图片
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第8张图片

YOLOv2的结构示意图如下:

  • 论文里没有说明先验框匹配和loss是怎么做的,所以有很多细节就需要去挖掘一下!

  • 查资料有人参考YOLO在TensorFlow上的实现darkflow(见yolov2/train.py)给出了解释(见文后的参考,写的非常好,这里为了连贯我直接贴出来):

  1. 和YOLOV1一样,对于训练图片中的ground -truth,若其中心点落在某个cell内,那么该cell内的5个先验框所对应的边界框负责预测它,具体是哪个边界框预测它,需要在训练中确定,即由那个与ground truth的IOU最大的边界框预测它,而剩余的4个边界框不与该ground truth匹配。YOLOV2同样需要假定每个cell至多含有一个grounth truth,而在实际上基本不会出现多于1个的情况。与ground truth匹配的先验框计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的边界框只计算置信度误差(此时target为0)。
  2. YOLOV2和YOLOV1的损失函数一样,也为均方差函数。但是看了YOLOV2的源码(训练样本处理与loss计算都包含在文件 region_layer.c中),发现YOLOV2的处理比原来的V1版本更加复杂。loss计算公式:
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第9张图片

对应源码,参考YOLOV2–region层源码分析

论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第10张图片
  • 1、W,H分别指的是特征图(13×13)的宽与高;

  • 2、A指的是先验框数目(这里是5);

  • 3、各个 λ λ λ 值是各个 l o s s loss loss的权重系数,参考YOLOV1的loss;

  • 4、第一项 loss 是计算background的置信度误差,但是哪些预测框来预测背景呢,需要先计算各个预测框和所有ground truth的IOU值,并且取最大值Max_IOU,如果该值小于一定的阈值(YOLOV2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差;

  • 5、第二项是计算先验框与预测宽的坐标误差,但是只在前12800个iterations间计算,我觉得这项应该是在训练前期使预测框快速学习到先验框的形状;

  • 6、第三大项计算与某个ground- truth匹配的预测框各部分loss值,包括坐标误差、置信度误差以及分类误差。

  • 先说一下匹配原则,对于某个ground-truth,首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground-truth的IOU值(YOLOV2中bias_match=1),计算IOU值时不考虑坐标,只考虑形状,所以先将先验框与ground truth的中心点都偏移到同一位置(原点),然后计算出对应的IOU值,IOU值最大的那个先验框与ground truth匹配,对应的预测框用来预测这个ground truth。

  • 在计算obj置信度时,在YOLOV1中target=1,而YOLOV2增加了一个控制参数rescore,当其为1时,target取预测框与ground truth的真实IOU值。对于那些没有与ground truth匹配的先验框(与预测框对应),除去那些Max_IOU低于阈值的,其它的就全部忽略,不计算任何误差。这点在YOLOV3论文中也有相关说明:YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了。这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框。
    尽管YOLOV2和YOLOV1计算loss处理上有不同,但都是采用均方差来计算loss。
    另外需要注意的一点是,在计算boxes的和误差时,YOLOV1中采用的是平方根以降低boxes的大小对误差的影响,而YOLOV2是直接计算,但是根据ground truth的大小对权重系数进行修正: l . c o o r d l.coord l.coord_ s c a l e ∗ ( 2 − t r u t h . w ∗ t r u t h . h ) scale * (2 - truth.w*truth.h) scale(2truth.wtruth.h),这样对于尺度较小的boxes其权重系数会更大一些,起到和YOLOv1计算平方根相似的效果。

三、Stronger

带标注的检测数据集量比较,而带标注的分类数据集量比较大,因此YOLO9000主要通过结合分类和检测数据集使得训练得到的检测模型可以检测约9000类物体。

  • 一方面要构造数据集(采用WordTree解决)。
  • 另一方面要解决模型训练问题(采用Joint classification and detection)。

【YOLOV3全面解读】

本博客主要参考大神:木盏:yolo系列之yolo v3,在这里表示感谢!

yolov3作为yolo系列目前最新的算法,对之前的算法既有保留又有改进。先分析一下yolov3上保留的东西:

  • 1.“分而治之”,从yolov1开始,yolo算法就是通过划分单元格来做检测,只是划分的数量不一样。
  • 2.采用"leaky ReLU"作为激活函数。
  • 3.端到端进行训练。一个loss function搞定训练,只需关注输入端和输出端。
  • 4.从yolov2开始,yolo就用batch normalization作为正则化、加速收敛和避免过拟合的方法,把BN层和leaky relu层接到每一层卷积层之后。
  • 5.多尺度训练。在速度和准确率之间tradeoff。想速度快点,可以牺牲准确率;想准确率高点儿,可以牺牲一点速度。

yolo每一代的提升很大一部分决定于backbone网络的提升,从yolov2的darknet-19到yolov3的darknet-53。yolov3还提供替换backbone——tiny darknet。要想性能牛叉,backbone可以用Darknet-53,要想轻量高速,可以用tiny-darknet。总之,yolo就是天生“灵活”,所以特别适合作为工程算法
当然,yolov3在之前的算法上保留的点不可能只有上述几点。由于本文章主要针对yolov3进行剖析,不便跑题,下面切入正题。

一、YOLOV3

1.1、YOLOV3网络结构

图1. yolov3结构图
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第11张图片

yolo系列里面,作者只在v1的论文里给出了结构图,而v2和v3的论文里都没有结构图,这使得读者对后两代yolo结构的理解变得比较难。but,对于yolo学习者来说,脑子里没有一个清晰的结构图,就别说自己懂yolo了。为了让yolov3结构图更好理解,我对上图做一些补充解释:

  • DBL: 如图左下角所示,也就是代码中的Darknetconv2d_BN_Leaky,是yolov3的基本组件。就是Conv+BN+Leaky relu。对于v3来说,BN和leaky relu已经是和卷积层不可分离的部分了(最后一层卷积除外),共同构成了最小组件。
  • resn:如图右下角所示,n代表数字,有res1,res2, … ,res8等等,表示这个res block里含有多少个res unit。这是yolo_v3的大组件,yolo_v3开始借鉴了ResNet的残差结构,使用这种结构可以让网络结构更深(从v2的darknet-19上升到v3的darknet-53,前者没有残差结构)。对于res_block的解释,可以在图1的右下角直观看到,其基本组件也是res unit,并且res unit的基本单元是DBL。
  • concat: 张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变

1.2、backbone

整个v3结构里面,是没有池化层和全连接层的。前向传播过程中,张量的尺寸变换是通过改变卷积核的步长来实现的,比如stride=(2, 2),这就等于将图像边长缩小了一半(即面积缩小到原来的1/4)。在yolov2中,要经历5次缩小,会将特征图缩小到原输入尺寸的 1 / 2 5 1 / 2^{5} 1/25即1/32。输入为416x416,则输出为13x13(416/32=13)。yolov3也和v2一样,backbone都会将输出特征图缩小到输入的1/32。所以,通常都要求输入图片是32的倍数。可以对比v2和v3的backbone看看:

图2 图2
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第12张图片
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第13张图片
yolov2中对于前向过程中张量尺寸变换,都是通过最大池化来进行,一共有5次。 yolov3是通过卷积核增大步长来进行,也是5次

注意: darknet-53最后面有一个全局平均池化,在yolov3里面没有这一层,所以张量维度变化只考虑前面那5次。这也是416x416输入得到(416/32=13)13x13输出的原因。从上图可以看出,darknet-19是不存在残差结构(resblock,从resnet上借鉴过来)的,和VGG是同类型的backbone(属于上一代CNN结构),而darknet-53是可以和resnet-152正面刚的backbone,看下表:

论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第14张图片

从上表也可以看出,darknet-19在速度上仍然占据很大的优势。其实在其他细节也可以看出(比如bounding box prior采用k=9),yolov3并没有那么追求速度,而是在保证实时性(fps>36)的基础上追求performance。不过前面也说了,你要想更快,还有一个tiny-darknet作为backbone可以替代darknet-53,在官方代码里用一行代码就可以实现切换backbone。搭用tiny-darknet的yolo,也就是tiny-yolo在轻量和高速两个特点上,显然是state of the art级别,tiny-darknet是和squeezeNet正面刚的网络,详情可以看下表:

论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第15张图片

所以,有了yolov3,就真的用不着yolov2了,更用不着yolov1了。这也是yolo官方网站,在v3出来以后,就没提供v1和v2代码下载链接的原因了。

1.3、Output

值得关注的是输出张量: yolo v3输出了3个不同尺度的feature map,如下图所示的y1, y2, y3。这也是v3论文中提到的为数不多的改进点:predictions across scales;这个借鉴了FPN(feature pyramid networks):采用多尺度来对不同size的目标进行检测,越精细的grid cell就可以检测出越精细的物体。

图3. yolov3输出张量
论文阅读笔记:YOLOV2全面解读+YOLOV3全面解读!_第16张图片

其中:y1,y2和y3的深度都是255,边长的规律是13:26:52;对于COCO类别而言,有80个种类,所以每个box应该对每个种类都输出一个概率。yolov3设定的是每个网格单元预测3个box,所以每个box需要有(x, y, w, h, confidence)五个基本参数,然后还要有80个类别的概率。所以3×(5+80)=255。这个255就是这么来的。(还记得yolo v1的输出张量吗? 7x7x30,只能识别20类物体,而且每个cell只能预测2个box,和v3比起来就像老人机和iphoneX一样)。

yolov3用上采样的方法来实现这种多尺度的feature map,可以结合图1和图2右边来看:图1中concat连接的两个张量是具有一样尺度的(两处拼接分别是26x26尺度拼接和52x52尺度拼接,通过(2, 2)上采样来保证concat拼接的张量尺度相同);

作者并没有像SSD那样直接采用backbone中间层的处理结果作为feature map的输出,而是和后面网络层的上采样结果进行一个拼接之后的处理结果作为feature map。为什么这么做呢?我感觉是有点玄学在里面,一方面避免和其他算法做法重合,另一方面这也许是试验之后并且结果证明更好的选择,再者有可能就是因为这么做比较节省模型size的。这点的数学原理不用去管,知道作者是这么做的就对了。

1.4、some tricks

Bounding Box Prediction
具体可以参考作者博客;对于v3而言,在prior这里的处理有明确解释:选用的b-box priors 的k=9对于tiny-yolo的话,k=6。 priors都是在数据集上聚类得来的,有确定的数值,如下:

10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326

每个anchor prior(名字叫anchor prior,但并不是用anchor机制)就是两个数字组成的,一个代表高度另一个代表宽度

v3对b-box进行预测的时候,采用了logistic regression,这一波操作sao得就像RPN中的线性回归调整b-box。v3每次对b-box进行predict时,输出和v2一样都是 ( t x , t y , t w , t h , t o ) \left(t_{x}, t_{y}, t_{w}, t_{h}, t_{o}\right) (tx,ty,tw,th,to);然后通过公式1计算出绝对的 ( x , y , w , h , c ) (x, y, w, h, c) (x,y,w,h,c)

logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。作者在论文种的描述如下:

If the bounding box prior is not the best but does overlap a ground truth object by more than 
some threshold we ignore the prediction, following[17]. We use the threshold of 0.5. Unlike [17] 
our system only assigns one  bounding box prior for each ground truth object.
# 如果模板框不是最佳的即使它超过我们设定的阈值,我们还是不会对它进行predict。

不同于faster R-CNN的是,yolov3只会对1个prior进行操作,也就是那个最佳prior。 而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。logistic回归就是用曲线对prior相对于 objectness score映射关系的线性建模。

疑问解答和说明:

了解v3输出的输出是至关重要的。
第一点,9个anchor会被三个输出张量平分的。根据大中小三种size各自取自己的anchor。

第二点,每个输出y在每个自己的网格都会输出3个预测框,这3个框是9除以3得到的,这是作者设置
的,我们可以从输出张量的维度来看,13x13x255。255是怎么来的呢,3*(5+80)。80表示80个种类,5表
示位置信息和置信度,3表示要输出3个prediction。在代码上来看,3*(5+80)中的3是直接由
num_anchors//3得到的。

第三点,作者使用了logistic回归来对每个anchor包围的内容进行了一个目标性评分(objectness score)。
根据目标性评分来选择anchor prior进行predict,而不是所有anchor prior都会有输出。

1.5、loss function

对掌握Yolo来讲,loss function不可谓不重要。在v3的论文里没有明确提所用的损失函数,确切地说,yolo系列论文里面只有yolo v1明确提了损失函数的公式。对于yolo这样一种讨喜的目标检测算法,就连损失函数都非常讨喜。在v1中使用了一种叫sum-square error的损失计算方法,就是简单的差方相加而已。我们知道,在目标检测任务里,有几个关键信息是需要确定的: ( x , y ) , ( w , h ) , c l a s s , c o n f i d e n c e (x, y),(w, h),class,confidence (x,y),(w,h),class,confidence
根据关键信息的特点可以分为上述四类,损失函数应该由各自特点确定。最后加到一起就可以组成最终的loss_function了,也就是一个loss_function搞定端到端的训练。可以从代码分析出v3的损失函数,同样也是对以上四类,不过相比于v1中简单的总方误差,还是有一些调整的:

xy_loss = object_mask * box_loss_scale * K.binary_crossentropy(raw_true_xy, raw_pred[..., 0:2],
                                                                       from_logits=True)
wh_loss = object_mask * box_loss_scale * 0.5 * K.square(raw_true_wh - raw_pred[..., 2:4])
confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \
                          (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5],
                                                                    from_logits=True) * ignore_mask
class_loss = object_mask * K.binary_crossentropy(true_class_probs, raw_pred[..., 5:], from_logits=True)

xy_loss = K.sum(xy_loss) / mf
wh_loss = K.sum(wh_loss) / mf
confidence_loss = K.sum(confidence_loss) / mf
class_loss = K.sum(class_loss) / mf
loss += xy_loss + wh_loss + confidence_loss + class_loss

以上是一段keras框架描述的yolo v3 的loss_function代码。忽略恒定系数不看,可以从上述代码看出:除了w, h的损失函数依然采用总方误差之外,其他部分的损失函数用的是二值交叉熵。最后加到一起。那么这个binary_crossentropy又是个什么玩意儿呢?就是一个最简单的交叉熵而已,一般用于二分类,这里的两种二分类类别可以理解为"对和不对"这两种。关于binary_crossentropy的公式详情可参考博文【常见损失函数;误差计算之MSE,Cross Enropy】

参考作者

主要参考以下作者的博客,在这里表示真诚的感谢!

  • YOLOv2 -YOLO9000:Better,Faster,Stronger
  • YOLO v2算法详解
  • 目标检测YOLOv2原理与实现(附YOLOv3)
  • 最后提示:深入yolov3可以参考作者木盏

你可能感兴趣的:(深度学习,Deep,Learning,吴恩达ML,DL作业,论文笔记)