Press "Enter" to skip to content

YOLO v3介绍使用TensorFlow 2进行目标检测

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

当我开始学习YOLOv3时,我注意到理解概念和实现都很有挑战性。尽管有大量关于它的博客文章和GitHub存储库,但大多数都是在复杂的架构中呈现的。

 

我不打算一步一步地从理论上介绍Yolo是如何工作的。我将尝试更详细地介绍过去教程中的所有部分以及上次遗漏的部分。如果您感兴趣,请查看我以前的教程,在那里我试图解释完整的理论。但是,我在TensorFlow 1.15中实现了它。但是越来越多的人写信告诉我关于错误的事情,因为他们在TF2.0或更高版本中尝试了我的代码,所以我决定是时候将YOLOv3实现编写到TensorFlow2中了。

 

在本系列教程中,我将为您提供如何在本地甚至在Google Colab(收到很多请求)上为您的自定义数据集训练Yolo模型的解决方案。基于这一经验,我将在本教程中尝试编写代码,使其对于许多刚刚开始学习对象检测的初学者来说更加简单和可重用。在不使事情过于复杂的情况下,只需使用本教程,您就可以在TensorFlow2中实现Yolov3。

 

必备条件

熟悉Python3;
了解目标检测和卷积神经网络(CNN);
基本TensorFlow用法。

YOLO算法简介

 

2015年,Redmon J等人。提出了YOLO网络,其特点是将候选盒生成和分类回归一步到位。提出的体系结构加快了目标检测的速度,帧率高达45fps!在预测时,将特征图划分为7×7个单元,并对每个单元进行预测,大大降低了计算复杂度。

 

时隔一年,Redmon J再次向YOLOv2求婚。与上一代相比,VOC2007测试集上的MAP从67.4%增加到78.6%。然而,由于细胞只负责预测面对重叠目标的单个对象,识别效果不够好。

 

最终在2018年4月,笔者发布了第三版YOLOv3,在COCO数据集上的MAP-50从YOLOv2的44.0%提升到了57.9%。与RetinaNet的61.1%MAP相比,RetinaNet默认的输入大小为500×500。在这种情况下,检测速度约为98ms/帧,而当输入大小为416×416时,YOLOv3的检测速度为29ms/帧。

上图足以证明,YOLOv3在保证速度的前提下,实现了非常高的准确率。

 

YOLO v3构想

 

作者将YOLO算法中的目标检测问题作为一个回归问题来处理,并将图像划分为S×S网格。如果目标的中心落入网格中,网格负责检测目标。

每个网格将输出边界框、置信度和类别概率图。其中包括:

边界框包含四个值:x,y,w,h,(x,y)表示框的中心。(w,h)定义箱子的宽度和高度;
置信度表示该预测框中包含对象的概率,即预测框与实际框之间的IOU值;
类概率表示对象的类概率,YOLOv3使用两类方法。

YOLO v3架构

 

对于那些没有太多Yolo v3或其他对象检测经验的人,我建议您阅读我以前的教程,了解算法是如何工作的。

 

顾名思义,YOLO(你只需看一次)将单一的前向传递神经网络应用于整个图像,并预测边界框及其类别概率。这种技术使得YOLO相当快,而不会损失很多精度。

 

如原文所述,YOLOv3有53个卷积层,称为“暗网-53”,如下图所示。图形主要由卷积结构和剩余结构组成。应注意,最后三层Avgpool、Connected和SoftMax层用于对Imagenet数据集进行分类训练。使用Darknet-53图层从图片中提取特征时,不使用这三个图层。 original paper

以代码实现的DarkNet-53:

 

暗网-53的威力有多大?看下图,笔者对比得出结论,Darknet-53在精度上堪比最先进的分类器,而且浮点运算更少,计算速度最快。与ResNet-101相比,Darknet-53网络的速度是前者的1.5倍;ReseNet-152虽然与其性能相近,但耗时超过两倍。

 

此外,Darknet-53还可以实现每秒最高的测量浮点运算,这意味着网络结构可以更好地利用GPU,从而使其更高效、更快。

但是从上面的Darknet-53架构图来看,很难理解或想象Yolo v3是如何工作的,所以下面是Yolo v3架构的另一个图:

从上面的架构图可以看到,YOLO使用32、16和8的步长进行了3种不同尺度的检测,以适应不同的对象大小,也就是说,如果我们输入大小为416×416的图像,YOLOv3将按照13×13、26×26和52×52的比例进行检测。

 

YOLOv3将输入图像下采样为13×13,并预测第一个比例的第82层。第一个检测标度产生大小为13x13x255的3-D张量。

 

之后,YOLOv3从层79获取特征地图,并应用一个卷积层,然后将其上采样2倍,使其大小为26×26。然后,将该上采样的特征图与来自层61的特征图连接。级联的特征映射经受更多的卷积层,直到在层94执行第二检测尺度。第二个预测标度产生大小为26x26x255的三维张量。

 

再次执行相同的设计以预测第三级。来自层91的特征地图被添加到一个卷积层,然后与来自层36的特征地图级联。最后的预测层在层106处完成,产生大小为52x52x255的3-D张量。总而言之,Yolo预测了三种不同的尺度检测,因此如果我们输入大小为416×416的图像,它会产生三种不同的输出形状张量,分别是13x13x255、26x26x255和52x52x255。

 

但是,尽管如此,看到Darknet-53和Yolo v3的结构,我们仍然不能完全理解所有的层。这就是为什幺我对YOLOv3网络的整体架构有了更多的了解。下图显示大小为416×416的输入画面在进入Darknet-53网络后得到三个分支。这些分支经历一系列卷积、上采样、合并和其他操作。最终得到三张不同大小的特征地图,形状分别为[13,13,255],[26,26,255]和[52,52,255]:

在代码中实现:

 

剩余模

 

残差模块最显着的特点是使用了捷径机制(有点类似于电路中的短路机制)来缓解神经网络中由于增加深度而导致的梯度消失问题,从而使神经网络更容易优化。它使用身份映射在输入和输出之间建立直接关联通道,使网络能够集中学习输入和输出之间的残差。

Python代码中的实现:

 

提取特征

 

要详细了解YOLO的预测过程,首先需要了解特征映射和嵌入。

 

要素地图

 

当我们谈到CNN网络时,我们总是听到单词功能图。它也称为特征映射。简单地说,就是将输入图像与卷积核进行卷积,得到图像特征。

 

一般来说,当CNN网络自下而上提取图像特征时,特征映射的数量(实际上就是卷积核的数量)会增加,而空间信息会减少。它的特征也会越来越抽象。以着名的VGG16网络为例,其功能图变化如下:

特征地图在空间上越来越小,但在通道大小上却越来越深。这是VGG16的功能。

 

特征向量

 

说到特征地图,我们在人脸识别领域经常能听到提及。早在2006年,深度学习的鼻祖欣顿就在《科学》上发表了一篇论文。一般说来,它实际上是由最后一个完全连通的图层提取成特征向量的特征地图。首次使用自编码网络从Mnist手写数字中提取特征向量(2D或3D向量)。值得一提的是,这篇论文还开启了深度学习的崛起之路:

当CNN网络从自下而上的图像中提取特征时,得到的特征图通常在空间大小上变得越来越小,在通道大小上变得越来越深:

这与ROI(感兴趣区域)到特征地图的映射有关。该信息是映射到CNN网络上的ROI区域中的图像信息的特征表示。上图:将原始图像中的一个ROI映射到CNN网络空间后,特征地图上的空间大小会变小,甚至是一个点,但这个点的频道信息会很有活力。由于图像像素在空间上紧密相连,这导致该区域存在显着的冗余。因此,我们经常通过空间降维和通道增维来消除这种冗余,并试图在最小的维度中获取其最本质的特征:

例如,原始图像左上角的红色ROI被CNN映射,在特征地图空间上只获得一个点,但这个点有85个通道。因此,ROI的维度从原来的[32,32,3]变为现在的85维。

 

这是CNN网络对ROI进行特征提取后得到的85维特征向量。该特征向量的前四个维度表示候选盒信息,中间维度表示判断对象有无的概率,接下来的80个维度表示80个类别的分类概率信息。

 

YOLO v3检测

 

多尺度检测

 

YOLO对输入图像执行粗略、中等和精细网格化,以分别预测大、中和小对象。如果输入图片大小为416×416,则粗、中和细网格大小分别为13×13、26×26和52×52。这样,它的长度和宽度将分别缩放32倍、16倍和8倍:

边界框的尺寸

 

YOLOv3网络的三个分支的输出将被发送到解码功能,对特征地图的信道信息进行解码。通过对输出应用对数空间变换,然后与锚点相乘来预测边界框的尺寸:在下图中:黑色虚线框表示先验框(锚点),蓝色框表示预测框。

B分别表示预测帧的长度和宽度,P表示先验帧的长度和宽度。
T表示对象中心相对于栅格左上角的偏移,C表示栅格左上角的坐标。

Python代码中的实现:

 

网管处理

 

顾名思义,非最大抑制会抑制不是最大的元素。NMS会移除重叠率较高、得分较低的边界框。网管的算法简单明了,迭代过程如下:

过程一:判断包围盒个数是否大于0,如果不大于0,则结束迭代;
过程2:按照得分顺序选择得分最高的边界框A并将其移除;
步骤3:计算该包围盒A和所有剩余包围盒的借条,删除IOU值高于阈值的包围盒,重复上述步骤;

Python代码中的实现:

 

最后,所有的包围盒A都是我们想要的。举个简单的例子:如果五个包围框和分数是:A:0.8,B:0.05,C:0.9,D:0.5,E:0.6,设定的分数阈值是0.3,计算步骤如下:

第一步:包围盒个数为5,满足迭代条件;
第二步:选择分数最高的包围盒A,按照分数顺序排序;
步骤3:计算包围盒A和其他四个包围盒的借条。假设得到的借条数值为:B:0.2,C:0.7,D:0.01,E:0.08,并去掉包围盒C;
第四步:现在只剩下边界框B、D、E,满足迭代条件;
步骤5:按照得分顺序选择得分最高的边框D并将其移除;
步骤7:现在只剩下边界框B,满足迭代条件;
步骤8:根据得分顺序选择得分最高的边界框B并将其移除;
步骤9:此时边界框个数为零,迭代结束。

最后,我们得到了包围盒A、B和D,但是包围盒B的分数非常低,这表明该包围盒没有对象,所以应该将其丢弃。在YOLO算法中,NMS处理有两种情况:一种是所有预测帧都与NMS一起处理,另一种是针对每一类预测帧单独进行NMS处理。在后一种情况下,会出现预测框既属于类别A又属于类别B的现象,这更适合于小单元中同时存在多个对象的情况。

 

因此,到目前为止,我们已经介绍了简单使用YOLOv3所需的所有理论。现在我们可以尝试实现一个简单的检测示例。在下一教程中,我将介绍自定义对象检测器培训所需的其他函数。

 

实施

 

因此,这只是第一个教程;为了不使它太复杂,我将进行简单的YOLOv3对象检测。要使其与TensorFlow 2一起工作,我们需要执行以下步骤:

在TensorFlow和KERAS中构建和编译Yolov3模型;
将权重从原始的暗网权值转移到构建的模型中;
使用图像和视频检测测试对象。

我不会在这个文本教程中显示完整的代码。如果您有兴趣尝试,可以在GitHub上下载。 GitHub

 

首先,你需要拿到我的项目:

 

Git克隆https://github.com/pythonlessons/TensorFlow-2.x-YOLOv3.git https://github.com/pythonlessons/TensorFlow-2.x-YOLOv3.git

 

接下来,您可能需要安装所需的python包:

 

PIP安装-r./requirements.txt

 

现在,从项目文件夹下载Training yolov3.weight:

 

WGET-P型号_数据https://pjreddie.com/media/files/yolov3.weights https://pjreddie.com/media/files/yolov3.weights

 

现在,您可以使用以下脚本测试Yolo v3检测:

 

Python检测_demo.py

 

如果所有操作都正确,您应该会看到下图:

现在,您可以通过打开并编辑Detection_demo.py脚本来播放和测试您的图像。

 

结论:

 

本教程到此为止;在下一部分中,我将介绍更多与自定义Yolov3培训相关的理论,当然,我们还将培训我们的第一个自定义对象检测器。到时见!

 

最初发表于https://pylessons.com/YOLOv3-TF2-introduction https://pylessons.com/YOLOv3-TF2-introduction

 

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注