深度学习中的一阶段目标检测

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

 博主简介

博主是一名大二学生主攻人工智能研究。感谢让我们在CSDN相遇博主致力于在这里分享关于人工智能c++Python爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主博主会继续更新的如果有错误之处大家可以指正。

专栏简介   本专栏主要研究计算机视觉涉及算法案例实践网络模型等知识。包括一些常用的数据处理算法也会介绍很多的Python第三方库。如果需要点击这里订阅专栏   。

给大家分享一个我很喜欢的一句话“每天多努力一点不为别的只为日后能够多一些选择选择舒心的日子选择自己喜欢的人”


目录

前言

YOLO网络

YOLO起源

YOLO原理

YOLOv2网络

 YOLOv3网络

SSD网络

1.1 模型

1.2 训练


前言

我们前面说的两阶段目标检测本质上就是训练俩个网络分别对两个问题进行求解这两个网络有什么区别喃在网络结构上没有本质的区别在特征输入上也没有任何的区别唯一的区别就是网络的目标不同或者说是使用的损失函数不同所以我们完全可以将两个网络合并将输出向量也拼接在一起并且使用不同的损失函数对不同部分的输出进行拟合。

一阶段目标检测主要的网络有YOLO网络和SSD网络。下面我们就进入这两个网络的学习。

YOLO网络

作为目标检测最优秀的网络结构YOLO。全名叫you look only once意思是你只需看一次就能完成整个目标检测。

YOLO起源

YOLO的发展其实是一个毫无波澜的发展在两阶段目标检测发展的时候YOLO开始悄悄的发展可以说在YOLO真正公布的前一天都没人注意到这个然而YOLO网路一经问世就异军突起当然和他一起出世的还有SSD网络但是把他们的准确率还是有很大的有待提升。之后经过一段时间YOLOv2诞生增加了输出类别成就了YOLO9000此时YOLO网络已经稳居第一不过一段时间后YOLOv3也被推出可以说是横扫武林。

YOLO原理

对于目标识别问题我们最后进行分类的时候就是根据最后一层的概率值用作分类。于是在YOLO网络的最后一层我们在预测类别的基础上加入预测位置的部分。

为了预测位置我们输出五个值xywhp这五个值分别对应候选框的左下角坐标或者候选框的中心、候选框的宽度和高度以及候选框中存在物体的置信概率。置信概率的计算是如果候选框中存在物体则置信概率为候选框与真实物体框的交并比IOU否则为0.

我们开始的时候把图片分成SxS格默认为7每个格子用来预测中心点落在其中哪一个物体上。当然分成SxS也是由于网络的最后一层特征层的大小为SxS也就是说最后一层特征层的每个像素对应一个候选框。当然这个分成SxS个格子只是抽象的说法实际测试的时候并不会真正的划分就像磁感线一样只是为了方便我们的学习和计算。

一般来说一个格子会输出置信概率最大的B个候选框B默认值为2测试时我们会选取概率最大的那个作为预测结果。也就是说我们总共可预测的候选框为SxSxB98.当然每个格子还需要C个物体类别预测C默认值为20这C个类别预测其实是条件概率P某一类物体|存在物体这是由于前面我们已经预测了物体的置信概率P存在物体所以两者相乘就得到P某一类物体于是每个方格输出Bx5+C维度的数据也就是说我们最后一共输出维度为SxSxBx5+C的张量进行回归预测。

在YOLO中分类损失采取类别概率的平方损失在YOLO计算中只计算有物体的候选框的分类损失而忽略背景框所以分类损失为

\sum\sum(p(c)-p(c))^{2}

对于边框预测中的x和y我们可以利用欧几里得距离来计算位置损失但是对于w和h就不行因为w和h的绝对值很小他们的欧几里得距离误差就会很大。所以这里定义一个位置损失式

\sum \sum (x-\hat{x})^{2}+(y-\hat{y})^{2}+(\sqrt{w}-\hat{\sqrt{w}})^{2}+(\sqrt{h}-\hat{\sqrt{h}})^{2}

最后就是置信概率p的损失函数我们还是用拼房损失函数不过不含物体的框怎么处理喃我们可以给他一个很小的权重这样就可以解决正负样本不均衡的问题。下面给出置信概率的损失函数

\sum \sum (c-\hat{c})^{2}+\lambda \sum \sum (c-\hat{c})^{2}

第一个是有物体的候选框第二个是无物体的候选框。

上面这个图就是YOLO网络损失函数的设计图。

对于网络预测层与原图的映射关系我们可以有以下几个步骤

1.首先需要对图片层经过卷积层和最大池化层的组合层最后变成7x7x1024的张量最后再进过两个全连接层变成我们前面讲过的7x7x30的张量再有它进行损失函数的计算即可。只有最后一层采用线性激活函数其他层都采用Leaky ReLU激活函数。

2.由于数据集样本较少YOLO先使用ImageNet数据集对前20层卷积网络进行预训练然后使用完整的网络在PASCAL VOC数据集上进行物体分类和候选框位置的训练和预测。训练中采用dropout和数据增强来防止过拟合。

最后我们来分析一下YOLO的优缺点

1.预测速度快超过了一般的网络预测速度。

2.对边框的预测精度不高总体的预测精度低于Fast R-CNN、类网络。 

YOLOv2网络

YOLOv2的全名是YOLO9000Better、Faster、Stronger。我们来讲解一下YOLOv2网络的改变1.首先就是将YOLO网络层中的Dropout层转换为BN层Batch Normalization也叫做批归一化层。这是一个非常好的正则化方法。

2.其次就是增加图像的分辨率YOLOv2增加了在ImageNet数据集上使用448x448原来为224x224来训练分类过程使用高频率的分类器模型就更加准确。

 3.为了改变YOLO中的候选框个数太少的问题YOLOv2使用了Faster R-CNN网络的先验框策略并且把最后一层全连接层去除改为卷积层。召回率也会得到很大的提升。

4.YOLOv2还改进了先验框的选取方式它使用了K-means方法对锚框做了聚类分析。

 5.最后YOLOv2约束了测边框的位置YOLOv2调整了预测公式将预测边框的中心约束在特定的网格内。

 除了上面说的这些YOLOv2还提出了一中passthrough层来获取特征图可以说YOLOv2已经是非常优秀的网络结构采用了很多优秀的方式除了我上面列举的这些还有其他很多的优点。

就像我上面说的除了上面列举的这些YOLOv2网络还做出了很多的优化比如损失函数优化结构i优化等例如我下面给出YOLOv2的损失函数的优化

经过了这些的优化YOLOv2网络的效率得到了很大的提升我们可以看一下他们的效果对比

可以说YOLOv2已经是非常的完美了但是YOLO网络的作者又推出了YOLOv3网络这也就奠定了YOLO网络不败的地步下面我们来看看YOLOv2的网络结构代码

#YOLOv2代码实现
def darknet(images, n_last_channels=425):
    net = conv2d(images, 32, 3, 1, name="conv1")
    net = maxpool(net, name="pool1")
    net = conv2d(net, 64, 3, 1, name="conv2")
    net = maxpool(net, name="pool2")
    net = conv2d(net, 128, 3, 1, name="conv3_1")
    net = conv2d(net, 64, 1, name="conv3_2")
    net = conv2d(net, 128, 3, 1, name="conv3_3")
    net = maxpool(net, name="pool3")
    net = conv2d(net, 256, 3, 1, name="conv4_1")
    net = conv2d(net, 128, 1, name="conv4_2")
    net = conv2d(net, 256, 3, 1, name="conv4_3")
    net = maxpool(net, name="pool4")
    net = conv2d(net, 512, 3, 1, name="conv5_1")
    net = conv2d(net, 256, 1, name="conv5_2")
    net = conv2d(net, 512, 3, 1, name="conv5_3")
    net = conv2d(net, 256, 1, name="conv5_4")
    net = conv2d(net, 512, 3, 1, name="conv5_5")
    shortcut = net
    net = maxpool(net, name="pool5")
    net = conv2d(net, 1024, 3, 1, name="conv6_1")
    net = conv2d(net, 512, 1, name="conv6_2")
    net = conv2d(net, 1024, 3, 1, name="conv6_3")
    net = conv2d(net, 512, 1, name="conv6_4")
    net = conv2d(net, 1024, 3, 1, name="conv6_5")
    # ---------
    net = conv2d(net, 1024, 3, 1, name="conv7_1")
    net = conv2d(net, 1024, 3, 1, name="conv7_2")
    # shortcut
    shortcut = conv2d(shortcut, 64, 1, name="conv_shortcut")
    shortcut = reorg(shortcut, 2)
    net = tf.concat([shortcut, net], axis=-1)
    net = conv2d(net, 1024, 3, 1, name="conv8")
    # detection layer
    net = conv2d(net, n_last_channels, 1, batch_normalize=0,
                 activation=None, use_bias=True, name="conv_dec")
    return net
def decode(detection_feat, feat_sizes=(13, 13), num_classes=80,
           anchors=None):
    H, W = feat_sizes
    num_anchors = len(anchors)
    detetion_results = tf.reshape(detection_feat, [-1, H * W, num_anchors,num_classes + 5])
    bbox_xy = tf.nn.sigmoid(detetion_results[:, :, :, 0:2])
    bbox_wh = tf.exp(detetion_results[:, :, :, 2:4])
    obj_probs = tf.nn.sigmoid(detetion_results[:, :, :, 4])
    class_probs = tf.nn.softmax(detetion_results[:, :, :, 5:])
    anchors = tf.constant(anchors, dtype=tf.float32)
    height_ind = tf.range(H, dtype=tf.float32)
    width_ind = tf.range(W, dtype=tf.float32)
    x_offset, y_offset = tf.meshgrid(height_ind, width_ind)
    x_offset = tf.reshape(x_offset, [1, -1, 1])
    y_offset = tf.reshape(y_offset, [1, -1, 1])
    # decode
    bbox_x = (bbox_xy[:, :, :, 0] + x_offset) / W
    bbox_y = (bbox_xy[:, :, :, 1] + y_offset) / H
    bbox_w = bbox_wh[:, :, :, 0] * anchors[:, 0] / W * 0.5
    bbox_h = bbox_wh[:, :, :, 1] * anchors[:, 1] / H * 0.5
    bboxes = tf.stack([bbox_x - bbox_w, bbox_y - bbox_h,
                       bbox_x + bbox_w, bbox_y + bbox_h], axis=3)
    return bboxes, obj_probs, class_probs

 YOLOv3网络

前面说到YOLOv2已经是非常完美的网络模型所以YOLOv3对于YOLOv2的改变并没有太多只是对4个方面进行了改变。

1.使用多级预测以前的YOLO只是用最后一张特征图作为预测结果在YOLOv3中使用最后三张特征图13x1326x2652x52用较大的特征图预测小物体因为较大的特征图划分的更加细致较小的特征图预测大物体从而提高准确率。

2.将物体分类的损失改为逻辑回归损失也就是说对每一个类别做预测而不是以往的只输出概率最大的类别采用复合标签更加的准确。

3.加深网络结构从YOLOv2的darknet-19变成了YOLOv3的darkent-53其实就是提高了算力。

4.YOLOv3使用K-means方法将锚点框聚成9类得到9类锚点框大小为10x13,16x30,33x23,30x61,62x45,59x119,116x90,156x198和373x326.

SSD网络

SSD检测网络全名为Single Shot MultiBox Detector。总的来说和YOLO相比SSD相比较差但是比一般的网络模型强了太多唯一的缺点就是速度慢但是模型非常的完美。下面我们来介绍一下SSD网络

1.1 模型

SSD方法基于前馈卷积网络生成固定大小的边界框集和这些框中存在物体类别的置信度接着使用非最大化抑制产生最终的检测结果。位于网络前面的一些层是基于做高质量图像分类的标准架构截取该框架分类层之前的层我们将其称为基础网络。然后我们向网络添加辅助结构来利用下边的主要特征来生成感知器

多尺度特征图检测我们将卷积特征层添加到截断了的基础网络的尾端。这些层的尺寸逐渐减小并且允许多尺度的预测。用于检测的卷积模型对于每个特征层是不同的而Overfeat [4]和YOLO[5]是在单个尺度特征图上操作的。

用于检测的卷积预测器每个添加的特征层或者基础网络的特征层使用一系列卷积滤波器filter可以产生一系列固定的预测。这些在图2中SSD网络架构已指出。对于p通道大小为m*n的特征层对于一个可能的检测它的预测参数的基本元素是一个3*3*p的核这个核产生决定每个类别的置信度或生成相对于默认框坐标的偏移量。在m*n的特征图的每个位置均应用这个卷积核各自产生一个输出值。边界框偏移输出值与默认框相关而默认框位置又是与每个特征图的位置相关参见YOLO [5]的架构它在这个步骤使用全连接层而不是卷积滤波器

默认框与宽高比我们为网络顶部的多个特征图的每个特征单元都关联固定的一组默认框。默认框以卷积形式作用于特征图使得每个框相对于其对应的单元格的位置是固定的。我们为每个特征图单元预测相对于该单元格的默认框的偏移量以及为每个类别预测反映框中该物体类别存在的置信度得分。具体来说对于一个给定的位置的k个框中的每个框我们都计算c个类的分数和相对于原始默认框的4个偏移值。这样致使总共有c+4k个滤波器作用于特征图中的每个位置若特征图的大小为m*n则会产生c+4*k*m*n个输出。有关默认框的说明请参考图1。我们的默认框类似于Faster R-CNN [2]中使用的锚检查框anchor boxes但不同的是我们将其应用于几个不同分辨率的特征图。在多个特征图上使用不同形状的默认框致使有效地离散可能的输出框的形状的空间。

1.2 训练

训练SSD和训练使用区域候选框region proposal的典型分类器的主要不同点在于真实标签需要被分配到固定的一组检测器输出中的某个特定的输出。YOLO [5]的训练阶段Faster R-CNN [2]和MultiBox [7]的region proposal阶段也需要类似这样的操作。一旦把真实标签分配好损失函数和反向传播就能端对端地应用。训练还包括选择一系列的默认框和用于检测的特征图尺度以及难分样本挖掘hard negative mining和数据增强策略

匹配策略在训练时我们需要确定哪些默认框和哪个真实标签框关联然后据此进行训练。对于每个真实标签框我们选择一些位置、长宽比和吃尺寸大小都不同的默认框。开始时我们把每个真实标签框与默认框中与之具有最佳的雅可比重叠值best jaccard overlap 跟MultiBox [7]的方法一样的框匹配。与MultiBox不同的是我们之后又将默认框与所有的真实标签框 ground truth box 配对只要两者之间的雅可比重叠值jaccard overlap 大于某个阈值本文的阈值为 0.5。 这样做简化了学习问题它使得网络能够为多个重叠的默认框预测高的置信度而不是要求它只选择具有最大重叠值的那个框。

训练目标SSD训练的目标函数从MultiBox[7,8]中导出但它进一步扩展到处理多个物体类别。

成为一个指示第i个默认框与类别p的第j个真实标签框的匹配指示器。根据上述的匹配策略我们可以得到

整体的目标损失函数是一个位置损失与置信度损失的加权和

其中N是匹配的默认框的数目如果N=0我们把loss设为0位置损失是smooth l1 loss这是一个介于预测框与真实框之间的参数类似于faster r-cnn我们将对默认框的中心与框的长宽进行回归。

置信度损失是softmax 多类别分类损失函数

选择默认框的比例和宽高比为了处理多个尺寸的物体有些算法[49]提议处理具有不同尺寸的多张图片然后把结果综合起来。但是用一个网络的不同层的特征图也可以得到类似的效果同时让所有不同尺寸的物体间能共享参数。之前的工作[10,11]已经表明使用较低层的特征图可以提高语义分割的质量因为较低层能捕获到输入目标的更精细的细节。类似地[12]指出增加特征图的全局上下文池化有助于平滑分割结果。受这些方法启发我们既用低层也用高层的特征图进行检测预测。图1展现了框架中使用的两个特征图8×8和4×4实例。在实践中我们可以使用更多计算开销小的特征图。

通常网络中不同层次的特征图具有不同大小的感受野[13]。幸运的是对于SSD框架默认框不需要与每层的实际感受野对应。我们可以设计默认框的平铺tiling使得特定的特征图学习响应特定的物体尺度。假设我们要使用m个特征图做预测。每个特征图的默认框的尺寸可用下式计算

其中Smin是0.2Smax是0.9意味着最底层是0.2最高层是0.9期间所有的层按规律递增我们为默认的bbox应用了不同的长宽比标记为

{1230.50.3333}我们可以计算每个默认的bbox的长度与宽度

对于长宽比为1的我们也加了一个默认的bbox尺度为

特征图的每个位置有6个默认的box我们设置每个bbox的中心为

其中|Fk|是第k个特征图的尺寸在实际中为了适应特定的数据集大家也可以设置不同尺寸与长宽比的默认框如何最优的设计这些也是一个开放的问题。

通过组合多个特征图在所有位置的不同尺寸和长宽比的所有默认框的预测我们得到涵盖各种输入物体尺寸和形状的多样性的预测集。例如图 1中的狗被匹配到4×4特征图中的某个默认框但没有匹配到8×8特征图中的任何默认框。这是因为那些框具有不同的尺度但都与狗的框不匹配因此在训练期间这些框被认为是负的。

难分样本挖掘 在匹配步骤后大多数默认框都是负的特别是当可能的默认框数量很大时。这导致了正负训练样本的严重不平衡。我们没有使用所有的负样本而是先把负样本根据置信度损失进行从大到小排序然后为每个默认框只选择分值最高的那些样本这样做的目的是使得正负样本的比例不超过1:3. 我们发现这样还可以使得优化更快训练更平稳

数据增强为了使模型对不同大小、形状的输入目标更具鲁棒性对每个图像通过随机采取以下策略之一进行采样

  1. 使用整张原始输入图像
  2. 采样一个片段使得与目标物体的最小的雅可比重叠为0.1,0.3,0.5,0.7,0.9之一。
  3. 随机采样一个部分

每个采样部分的大小为原图的[0.1,1]长宽比在1/2和2之间。如果真实标签框的中心位于采样部分内则保留重叠部分。在上述采样步骤之后将每个采样片大小调整为固定大小并以0.5的概率进行水平翻转还有对图片做一些跟[14]所描述的光度扭曲的操作。

 

对于SSD网络他的闪耀点远远不及YOLO网络但是他的闪光点依旧是存在的他的模型是非常完美的只是在运行速度上较慢相比较于YOLO网络SSD可以说是生不逢时它本身是非常完美的但是却和YOLO网络同时期。所以这里只是简单的介绍了一下。本节的只是就到此结束了至于网络的搭建后面的神经网络专栏会介绍的。拜拜了您嘞

点赞加关注不迷路

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6