论文原文:YOLOv3: An Incremental Improvement
解决方案
这一部分主要介绍了 YOLOv3 的解决方案。作者从其他研究中获取了非常多的灵感,训练了一个新的分类网络。因此原文章的这一部分主要从边界框的预测、类别预测和特征抽取等方面详细介绍整个系统。
边界框预测
YOLOv3 沿用了 YOLO9000 边界框预测的方法,使用维度聚类中心作为 anchor box 来预测边界框。YOLOv3 用 logistic 回归预测每一个边界框的对象状态。如果某一个边界框先验与真实值重叠最多,对象状态值应该为 1。如果边界框不是最好的,但重叠部分超过阈值(0.5),则忽略这个预测。与 Fast-RCNN 不同的是,YOLOv3 只给每个真实对象分配一个边界框先验。如果一个边界框没有分配到一个真实对象,它对坐标或类别预测不会带来损失,只是影响对象状态。
图 1 带有维度先验和定位预测的边界框。通过预测离聚类中心的偏移度来预测边界框的宽和高,并使用 Sigmoid 函数预测边界框相对于滤波器应用位置的中心坐标。
类别预测
每个边界框会使用多类标分类来预测其中包含物体的类别。作者没有使用 Softmax,因为其对性能提升不是必要的,因此只是使用独立的 logistic 分类。在训练过程中,使用二值交叉熵损失进行类预测。
这种方法对于更复杂的数据集,如 Open Images Dataset,是很有帮助的。这个数据集有许多重叠的标签,使用 Softmax 则会带来每个边界框只有一个类标的强加假设,但现实往往不是这样的。多类标的方法可以对数据更好的建模。
跨尺度预测
YOLOv3 在 3 个不同的尺度预测边界框。系统使用类似于特征金字塔的网络从这些尺度中提取特征。作者在基本的特征提取器后添加了几个卷积层。网络的最后一层会给出一个三维张量,其中编码了边界框、对象状态和类别预测信息。在 COCO 数据集的实验中,在每个尺度预测了 3 个边界框,分别包含 4 个边界框的偏移量,1 个对象状态值,80 个类标预测值,因此张量大小为 n×n×[3*(4+1+80)]。
特征提取
作者使用了新的网络进行特征提取,新网络是 Darknet-19 和残差网络的混合体。网络使用连续的 3×3 和 1×1 卷积层,但是加入了快捷连接。由于网络有 53 层卷积层,所以作者将新网络称作 Darknet-53。
表 1 Darknet-53 结构
新网络远比 Darknet-19 更强大,而且比 resnet-101 和 resnet-152 更有效。
表 2 主干架构的性能对比(ImageNet 数据集):准确率(top-1 误差、top-5 误差)、运算次数(/ 十亿)、每秒浮点数运算次数(/ 十亿),以及 FPS 值。
总而言之,YOLOv3 的先验检测(Prior detection)系统将分类器或定位器重新用于检测任务。他们将模型应用于图像的多个位置和尺度。评分较高的区域可以视为检测结果。
此外,YOLOv3 将一个单独的神经网络应用于整张图像,该网络将图像划分为不同的区域,然后预测每个区域的边界框和类标概率,这些边界框会通过预测的类标概率进行加权。
YOLOv3 与基于分类器的系统相比有一些优势。它在测试时会查看整个图像,所以它的预测利用了图像中的全局信息。与 R-CNN 需要对单一图像进行数千次预测不同,它通过一个单独网络评估进行预测。这令 YOLOv3 非常快,比 R-CNN 快 1000 倍,比 Fast R-CNN 快 100 倍。
YOLOv3 测试效果
YOLOv3 可以在 22ms 之内执行完一张 320 × 320 的图片,mAP 得分 28.2,和 SSD 的准确率相当,但是比它*倍。此外,它在 Titan X 上经过 51 ms 训练,mAP50 为 57.9,相比之下,RetinaNet 经过 198ms 的训练之后 mAP50 为 57.5。对比起来,两者的性能差异不大,但是 YOLOv3 比 RetinaNet 快 3.8 倍。
COCO 数据集实验
表 3 从表中可以看出,YOLOv3 表现得不错。RetinaNet 需要大约 3.8 倍的时间来处理一张图像,YOLOv3 相比 SSD 变体要好得多,并在 AP_50 指标上和当前最佳模型有得一拼。
准确率 vs 速度
图 2 以 0.5 IOU 为指标的速度与准确率关系曲线(mAP vs 推断时间)。从图中可以看出 YOLOv3 准确率高,速度也快。
如何使用 YOLOv3
用预训练模型进行检测接下来将给大家介绍如何利用 YOLO 系统使用预训练模型来检测物体。首先需要安装 Darknet,或者运行命令:
git clone https://github.com/pjreddie/darknet cd darknet make
这样一来 cfg/ 子目录中就有了 YOLO 配置文件,接下来下载预训练模型的权重信息(237 MB),或运行命令:
wget https://pjreddie.com/media/files/yolov3.weights
然后就可以运行检测器:
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
输出如下:
Darknet 会输出检测到的物体、自信度以及检测时间。我们没有用 OpenCV 编译 Darknet,所以它不能直接显示检测情况。检测情况保存在 predictions.png 中。大家可以打开这个图片来查看检测到的对象。我们在 CPU 上使用 Darknet,检测每张图片大约需要 6-12 秒,如果使用 GPU 将快得多。
我还附上了一些其他图片可以尝试,或许能给大家提供灵感,data/eagle.jpg、data/dog.jpg、data/person.jpg 或 data/horses.jpg。
detect 命令是对通用版本的简写,通用版本命令如下:
./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg
如果你只是想检测图像,并不需要了解这个,但如果你想做其他的事情,比如在网络摄像头上运行 YOLO,这个命令非常有用(稍后详细描述)。
多图像检测
在命令行不给出图像信息的话就可以连续运行多个图片。当加载完配置和权重,你将看到如下提示:
输入类似 data/horses.jpg 的图像路径来进行边框预测:
一旦完成,它将提示你输入更多路径来检测不同的图像。使用 Ctrl-C 退出程序。
改变检测阈值
默认情况下,YOLO 只显示检测到的自信度不小于 0.25 的物体。可以在 YOLO 命令中加入 -thresh来更改检测门限。例如,将门限设置为 0 可以显示所有的检测结果。./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg -thresh 0网络摄像头实时检测 要运行 demo,需要用 CUDA 和 OpenCV 来编译 Darknet。然后运行如下指令:
./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights
YOLO 将会显示当前的 FPS 和预测的分类,以及带有边框的图像。
你需要一个连接到电脑的摄像头并且 OpenCV 也可以连接到,否则就无法运行。如果有多个摄像头并想选择其中某一个,可以使用 -c(OpenCV 在默认情况下使用摄像头 0)语句。如果 OpenCV 可以读取视频,也可以在视频文件中运行:
./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <video file>
如何训练 YOLO在 VOC 数据集上训练 YOLO
训练 YOLO 需要 2007-2012 年的所有 VOC 数据,这是下载地址:https://pjreddie.com/projects/pascal-voc-dataset-mirror/,要把所有数据存储在一个路径下:
wget https://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar wget https://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar wget https://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar tar xf VOCtrainval_11-May-2012.tar tar xf VOCtrainval_06-Nov-2007.tar tar xf VOCtest_06-Nov-2007.tar
这样所有的 VOC 训练数据都在 VOCdevkit/ 子目录下。
生成标签
接下来需要生成 Darknet 使用的标签文件。每张图需要一个.txt 文件,每一行对应一个目标,格式如下:
<object-class> <x> <y> <width> <height>
x, y, width 和 height 对应图像的宽和高。需要在 Darknet scripts/ 子目录下运行 voc_label.py 来生成这些文件。
wget https://pjreddie.com/media/files/voc_label.py python voc_label.py
几分钟后,这个脚本将生成所有必需文件。大部分标签文件存放在 VOCdevkit/VOC2007/labels/ 和 VOCdevkit/VOC2012/labels/ 下,大家可以在目录下看到如下信息:
ls 2007_test.txt VOCdevkit 2007_train.txt voc_label.py 2007_val.txt VOCtest_06-Nov-2007.tar 2012_train.txt VOCtrainval_06-Nov-2007.tar 2012_val.txt VOCtrainval_11-May-2012.tar
类似 2007_train.txt 的文件列出了那一年的图像集内的图像。Darknet 需要一个包含所有你想要训练的图片的文本文件。在这个例子中,我们训练了除了 2007 测试集的所有数据。运行如下命令:
cat 2007_train.txt 2007_val.txt 2012_*.txt > train.txt
现在就有了包含 2007 和 2012 所有训练验证数据集的一个大的列表。数据准备工作到这里就结束了。
修改 Pascal 数据设置
现在进入 Darknet 目录,需要改变 cfg/voc.data 配置文件让它指向数据:
1 classes= 20 2 train = <path-to-voc>/train.txt 3 valid = <path-to-voc>2007_test.txt 4 names = data/voc.names 5 backup = backup
将替换为你存放 VOC 数据的目录。
下载预训练卷积权重
在训练中使用在 Imagenet 上预训练的卷积权重。我们这里使用 darknet53 模型的权重,可以在这里下载卷积层权重:https://pjreddie.com/darknet/imagenet/#darknet53,或者运行以下命令:
wget https://pjreddie.com/media/files/darknet53.conv.74
训练模型
执行下面的命令进行训练:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
在 COCO 数据集上训练 YOLO 与 VOC 类似,读者可以在这里查看详情:https://pjreddie.com/darknet/yolo/