yolov3实验总结

yolov3可去darknet官网下载,github上有caffe、keras、pytorch等版本。

基本思想

首先通过特征提取网络对输入的图像提取特征,得到一定大小的feature map 比如 13X13,然后将输入的图像分为13X13个grid cell,然后如果groundtruth中的某个物体的中心坐标落到那个grid cell中就由该grid cell预测该物体,每个grid cell 都会预测固定数量的bounding box (v1 :2个,V2 :5个 ,V3 : 3个)这几个bounding box的初始size是不一样的),那么这几个bounding box中最终是由哪一个来预测该object?答案是:这几个bounding box中只有和ground truth的IOU最大的bounding box才是用来预测该物体。

Darknet-53特征提取网络

不同于Darknet-19,YOLO v3中使用了一个53层的卷积网络,这个网络由残差单元叠加而成。根据作者的实验,在分类准确度上跟效率的平衡上,这个模型比ResNet-101、ResNet-152和Darknet-19表现得更好。模型作为图像分类器进行预训练,之后再针对检测任务进行调整,Redmond发现在分类预训练结束时使用更高分辨率的图像能够提升检测表现。将分类网络调整为检测网络只需移除网络的最后几层,然后添加一个带有B个过滤器的卷积层,以得到N*N*B的边界框预测。一方面基本采用全卷积(YOLO v2中采用pooling层做feature map的sample,这里都换成卷积层来做了),另一方面引入了residual结构(YOLO v2中还是类似VGG那样直筒型的网络结构,层数太多训起来会有梯度问题,所以Darknet-19也就19层,因此得益于ResNet的residual结构,训深层网络难度大大减小,因此这里可以将网络做到53层,精度提升比较明显)。

边界框预测

YOLO v3使用逻辑回归预测每个边界框的分数。 如果先验边界框与真实框的重叠度比之前的任何其他边界框都要好,则该值应该为1。 如果先验边界框不是最好的,但确实与真实对象的重叠超过某个阈值(这里是0.5),那么就忽略这次预测。YOLO v3只为每个真实对象分配一个边界框,如果先验边界框与真实对象不吻合,则不会产生坐标或类别预测损失,只会产生物体预测损失。
YOLO 模型的第一个迭代版本是直接预测描述一个边界框的所有 4 个值。每个边界框的 x 和 y 坐标都是相对每个网格单元的左上角定义的,并且根据单元尺寸进行了归一化,以便这些坐标值的范围在 0 到 1 之间。我们定义框宽度和高度的方式让我们的模型预测的是平方根宽度和高度;通过平方根值的形式定义框的宽度和高度,大数值之间的差会没有小数值之间的差那样显著(看看 的图就能确定这一点)。Redmond 选择这个形式是因为「小偏差在大框中的重要性比在小框中小」,因此,当我们计算我们的损失函数时,我们希望将重点放在更准确地得到小框上面。边界框的宽度和高度根据图像的宽和高进行归一化,因此取值也在 0 到 1 之间。训练过程中使用 L2 损失。
这种形式后来进行了修改,引入了边界框先验(bounding box prior)的概念。我们不再期望模型为每张新图像直接生成唯一的边界框描述量,而是定义一个边界框集合,其中的边界框有不同的宽高比,这些宽高比嵌入了某些关于我们预计会检测到的目标的形状的先验信息。Redmond 提供了一种用于发现最佳宽高比的方法,即在你的训练数据集中的所有边界框上执行 k-均值聚类(使用一个自定义的距离度量)。
在下图中,你可以看到针对中心黄色的网格单元的一个包含 5 个边界框先验(也被称为锚框(anchor boxes))的集合。通过这种形式,B 个边界框中的每个都能明确地专门检测特定尺寸和宽高比的目标。
这里写图片描述
注:尽管图中没有给出,但我们的预测网格中的每个单元都有这些锚框。
我们不再直接预测边界框的尺寸,而是重新形式化了我们的任务,从而只需简单预测与我们的边界框先验尺寸的偏移量,这样我们就可以优化我们的预测边界框尺寸了。这种处理方式能让这一预测任务更容易学习。由于与原来的预测平方根宽度和高度相似的原因,我们将定义我们的任务来预测与我们的边界框先验的对数偏移量。

目标度(以及将被标注的目标分配给一个边界框)

在该模型的第一个版本中,「目标度(objectness)」分数 pobj 的训练目标是近似求取被预测框和基本真值标签之间的交并比(IoU)。当我们在训练过程中计算损失时,我们会将目标与有最高 IoU 分数的边界框预测(在同一个网格单元上)进行匹配。对于未匹配的框,我们会包含进我们的损失函数的唯一描述量是 pobj。
YOLOv2 加入了边界框先验之后,我们只需简单地将被标注出的目标分配给与该被标注目标有最高 IoU 分数的锚框(在同一个网格单元上)即可。
在第三个版本中,Redmond 重新定义了「目标度」目标分数 pobj,每个给定目标有最高 IoU 分数的边界框取值 1,其它所有框都为 0。但是,在计算损失时,我们将不会包含有较高 IoU 分数(超过某个阈值),但不是最高分数的边界框。简单来说,只是因为一个优良预测不是最佳预测就惩罚它是不合理的。

类别预测

为了实现多标签分类,模型不再使用softmax函数作为最终的分类器(softmax 不一定能得到优良表现。这个选择取决于你的数据集以及你的标签是否重叠),而是使用 logistic loss,由于每个点所对应的 bounding box 少并且差异大,每个 bounding 与 ground truth 的 matching 策略变成了 1 对 1。原来分类网络中的softmax层都是假设一张图像或一个object只属于一个类别,但是在一些复杂场景下,一个object可能属于多个类,比如你的类别中有woman和person这两个类,那么如果一张图像中有一个woman,那么你检测的结果中类别标签就要同时有woman和person两个类,这就是多标签分类,需要用逻辑回归层来对每个类别做二分类。逻辑回归层主要用到sigmoid函数,该函数可以将输入约束在0到1的范围内,因此当一张图像经过特征提取后的某一类输出经过sigmoid函数约束后如果大于0.5,就表示属于该类,当预测的目标类别很复杂的时候,采用 logistic regression 进行分类是更有效的,比如在 Open Images Dataset 数据集进行分类。

多尺度预测

不同于之前的YOLO,YOLO v3从三种不同尺度的特征图谱上进行预测任务。在Darknet-53得到的特征图的基础上,经过7个卷积得到第一个特征图谱,在这个特征图谱上做第一次预测。然后从后向前获得倒数第3个卷积层的输出,进行一次卷积一次x2上采样,将上采样特征与第43个卷积特征连接,经过7个卷积得到第二个特征图谱,在这个特征图谱上做第二次预测。然后从后向前获得倒数第3个卷积层的输出,进行一次卷积一次x2上采样,将上采样特征与第26个卷积特征连接,经过7个卷积得到第三个特征图谱,在这个特征图谱上做第三次预测。每个预测任务得到的特征大小都为N ×N ×[3∗(4+1+80)] ,N为格子大小,3为每个格子得到的边界框数量, 4是边界框坐标数量,1是目标预测值,80是类别数量该网络在第一个检测层之前对输入图像执行下采样,检测层使用步幅为 32 的层的特征图执行检测。随后在执行因子为 2 的上采样后,并与前一个层的特征图(特征图大小相同)拼接。另一个检测在步幅为 16 的层中执行。重复同样的上采样步骤,最后一个检测在步幅为 8 的层中执行。在每个尺度上,每个单元使用3个锚点预测3个边界框,锚点的总数为9(不同尺度的锚点不同)。对于大小为 416 x 416 的图像,YOLO 预测 ((52 x 52) + (26 x 26) + 13 x 13)) x 3 = 10647 个边界框。但是,我们的示例中只有一个对象——一只狗。那么我们怎么才能将检测次数从 10647 减少到 1 呢?

目标置信度阈值:首先,我们根据它们的 objectness 分数过滤边界框。通常,分数低于阈值的边界框会被忽略。我们的预测张量包含有关 B x 10647 边界框的信息。对于有低于一个阈值的 objectness 分数的每个边界框,我们将其每个属性的值(表示该边界框的一整行)都设为零。

非极大值抑制:非极大值抑制(NMS)可解决对同一个图像的多次检测的问题。从高层面看,这个技术会检查高度重叠的边界框并抑制(即丢弃)除最高置信度预测外的所有预测。我们会为每一类都单独执行非极大抑制。同样,这里的目标是移除冗余的预测,所以如果有两个重叠度很高的边界框分别描述的是不同类别的目标(比如一个框描述人,一个框描述车),那么我们就不必担心。但是,如果两个重叠度很高的边界框都在描述人,那么很有可能这两个预测描述的是同一个人。

Yolo和SSD的主要思路是均匀地在图片的不同位置进行密集抽样,抽样时可以采用不同尺度和长宽比,然后利用CNN提取特征后直接进行分类与回归,整个过程只需要一步,所以其优势是速度快,但是均匀的密集采样的一个重要缺点是训练比较困难,这主要是因为正样本与负样本(背景)极其不均衡,导致模型准确度稍低。YOLO 和 SSD 的一大主要区别是 SSD 不会试图为 pobj 预测一个值。YOLO 模型是在存在一个目标时预测目标的概率,然后再预测每个类别的概率,而 SSD 模型则试图直接预测一个类别存在于一个给定目标框中的概率。

batch: 每一次迭代送到网络的图片数量,也叫批数量。增大这个可以让网络在较少的迭代次数内完成一个epoch。在固定最大迭代次数的前提下,增加batch会延长训练时间,但会更好的寻找到梯度下降的方向。如果你显存够大,可以适当增大这个值来提高内存利用率。这个值是需要大家不断尝试选取的,过小的话会让训练不够收敛,过大会陷入局部最优。
subdivision:这个参数很有意思的,它会让你的每一个batch不是一下子都丢到网络里。而是分成subdivision对应数字的份数,一份一份的跑完后,在一起打包算作完成一次iteration。这样会降低对显存的占用情况。如果设置这个参数为1的话就是一次性把所有batch的图片都丢到网络里,如果为2的话就是一次丢一半。
angle:图片旋转角度,这个用来增强训练效果的。从本质上来说,就是通过旋转图片来变相的增加训练样本集。
saturation,exposure,hue:饱和度,曝光度,色调,这些都是为了增强训练效果用的。
learning_rate:学习率,训练发散的话可以降低学习率。学习遇到瓶颈,loss不变的话也减低学习率。
max_batches: 最大迭代次数。
policy:学习策略,一般都是step这种步进式。
step,scales:这两个是组合一起的,举个例子:learn_rate: 0.001, step:100,25000,35000 scales: 10, .1, .1 这组数据的意思就是在0-100次iteration期间learning rate为原始0.001,在100-25000次iteration期间learning rate为原始的10倍0.01,在25000-35000次iteration期间learning rate为当前值的0.1倍,就是0.001, 在35000到最大iteration期间使用learning rate为当前值的0.1倍,就是0.0001。随着iteration增加,降低学习率可以是模型更有效的学习,也就是更好的降低train loss。
最后一层卷积层中filters数值是 5×(类别数 + 5)。具体原因就不多说了,知道就好哈。
region里需要把classes改成你的类别数。
最后一行的random,是一个开关。如果设置为1的话,就是在训练的时候每一batch图片会随便改成320-640(32整倍数)大小的图片。目的和上面的色度,曝光度等一样。如果设置为0的话,所有图片就只修改成默认的大小 416*416。

训练log中各参数的意义

Region Avg IOU:平均的IOU,代表预测的bounding box和ground truth的交集与并集之比,期望该值趋近于1。

Class:是标注物体的概率,期望该值趋近于1.

Obj:期望该值趋近于1.

No Obj:期望该值越来越小但不为零.

Avg Recall:期望该值趋近1

avg:平均损失,期望该值趋近于0

rate:当前学习率

:如果是学习如何训练,建议不要用VOC或者COCO,这两个数据集复杂,类别较多,复现作者的效果需要一定的功力,迭代差不多5w次,就可以看到初步的效果。所以,不如挑个简单数据集的或者手动标注个几百张就可以进行训练学习。

未来发展

mAP 会继续提高。随着模型训练越来越高效,神经网络层级的不断加深,信息抽象能力的不断提高,以及一些小的修修补补,未来的目标检测应用mAP会不断提升。
实时检测会成为标配。目前所谓的“实时”,工业界是不认可的。为什么呢,因为学术圈的人,验证模型都是建立在 TitanX 或者 Tesla 这类强大的独立显卡上,而实际的潜在应用场景中,例如无人机/扫地/服务机器人/视频监控等,是不会配备这些“重型装备”的。所以,在嵌入式设备中,如 FPGA,轻量级 CPU 上,能达到的实时,才是货真价实的。
模型小型化成为重要分支。类似于 tiny YOLO 的模型分支会受到更多关注。模型的小型化是应用到嵌入式设备的重要前提。而物联网机器人无人机等领域还是以嵌入式设备为主的。模型剪枝/二值化/权值共享等手段会更广泛的使用。
垂直领域特定目标检测对于不同场景不同需求可设计特定模型推广应用。

猜你喜欢

转载自blog.csdn.net/qq_20657717/article/details/81669006