有很多方法都声称可以提升检测的精度,因此需要一个实用的测试来评估组合这些方法并且从理论上分析可行性的方案。有些方法只能用于特定的问题和小数据集,但还有一些方法如批归一化和残差连接等,对于大多数模型和数据集都是适用的。YOLO v4提供了一个很好的基准.
如果想要训练yolov2-voc.cfg
, yolov2-tiny-voc.cfg
, yolo-voc.cfg
, yolo-voc.2.0.cfg类似更早的版本,请点击这个链接
训练Yolo v4 (and v3):
0. 训练cfg/yolov4-custom.cfg
需要下载预训练模型yolov4.conv.137
1. 拷贝yolov4-custom.cfg 并命名为yolo-obj.cfg,修改batch_size大小,如果你的GPU显存较小报内存不足的错误,可以尝试调大subdivisions的值
batch=64
subdivisions=16
max_batches设成要训练的类别数*2000,但是不能少于要训练的图片数和6000
学习率下降的步长设为max_batches的80%和90%, 总数是6000的话要设置成 steps=4800, 5400
网络输入设为width=416 height=416,或者其他可以被32整除的数
在yolo层中把类别数classes=80改成要训练的数目
- https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L610
- https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L696
- https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L783
把yolo前面的convolutional层中 滤波器数量
filters=255改成 filters=(classes + 5)x3,只改yolo前面最后那个卷积层即可
- https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L603
- https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L689
- https://github.com/AlexeyAB/darknet/blob/0039fd26786ab5f71d5af725fc18b3f521e7acfd/cfg/yolov3.cfg#L776
因此,如果只训练1类的话改成18,训练2类要改成21. 其实就是3N+15,N是类别数。
2.data目录下新建一个obj.names,里面写上要训练类别的名称,每行一个类别
3.在data下新建一个obj.data
classes= 1
train = data/train.txt
valid = data/test.txt
names = data/obj.names
backup = backup/
4.收集图片并放置到适当位置
5.标注上面收集的图片,标注文件格式为
<object-class> <x_center> <y_center> <width> <height>
即类别 中心点坐标 宽度和高度
6.创建要训练文件的列表
7.下载预训练模型
- for
yolov4.cfg
,yolov4-custom.cfg
(162 MB): yolov4.conv.137 (Google drive mirror yolov4.conv.137 ) - for
csresnext50-panet-spp.cfg
(133 MB): csresnext50-panet-spp.conv.112 - for
yolov3.cfg, yolov3-spp.cfg
(154 MB): darknet53.conv.74 - for
yolov3-tiny-prn.cfg , yolov3-tin
y.cfg
(6 MB): yolov3-tiny.conv.11 - for
enet-coco.cfg (EfficientNetB0-Yolov3)
(14 MB): enetb0-coco.conv.132
8.使用如下命令开始训练
./darknet detector train data/obj.data yolo-obj.cfg yolov4.conv.137
每100个迭代会保存yolo-obj_last.weights,每1000个迭代会保存yolo-obj_xxxx.weights,如果你的机器上没有窗口环境,可以使用
-dont_show来关掉Loss窗口的显示
如果想看mAP,在命令后加上-map,结合上面那条,经常使用的是 -dont_show -mjpeg_port 8090 -map
然后打开http://ip-address:8090
在浏览器中就可以看到Loss的下降过程了。
9.训练完成后会生成yolo-obj_final.weights
注意:如果在avg上看到nan说明训练有问题,但是如果是其他部分的话,问题不大,接着训就成
注意:如果你改变了网络的宽度和高度的话,一定得是32的倍数
注意:训练完成后使用类似darknet detector test data/obj.data yolo-obj.cfg yolo-obj_8000.weights来进行检测
注意:如果遇到Out of memory之类的错误,在.cfg文件中提高它的值subdivisions=16
, 32 or 64,这个参数的含义是把一个batch分成多个批。
如何训练tiny-yolo
和上面的步骤一样,但是有一下几点不同:
- 预训练权重改成https://pjreddie.com/media/files/yolov3-tiny.weights
- Get pre-trained weights
yolov3-tiny.conv.15
using command:darknet.exe partial cfg/yolov3-tiny.cfg yolov3-tiny.weights yolov3-tiny.conv.15 15
- Make your custom model
yolov3-tiny-obj.cfg
based oncfg/yolov3-tiny_obj.cfg
instead ofyolov3.cfg
- Start training:
darknet.exe detector train data/obj.data yolov3-tiny-obj.cfg yolov3-tiny.conv.15
什么时候停止训练:
通常来说2000*类别数个迭代就够了,但是不能少于图片总数也不能少于6000.更精确的停止训练可以参考下面的手册:
1.在训练过程中,你会看到不同的错误指示,你应该在
0.XXXXXXX avg不再下降时停止训练
Region Avg IOU: 0.798363, Class: 0.893232, Obj: 0.700808, No Obj: 0.004567, Avg Recall: 1.000000, count: 8 Region Avg IOU: 0.800677, Class: 0.892181, Obj: 0.701590, No Obj: 0.004574, Avg Recall: 1.000000, count: 8
9002: 0.211667, 0.60730 avg, 0.001000 rate, 3.868000 seconds, 576128 images Loaded: 0.000000 seconds
- 9002表示迭代的次数
- 0.60730 avg:平均损失,越低越好
如果在多个迭代后0.xxxxxx avg 仍然不再下降你应该停止训练,最终的loss会在0.5(小的模型、简单的数据)到3(大模型和复杂的数据)之间
2.一旦停止训练,你应该选择最近的权重.weights,并且从中选择最好的那个
例如你在9000次时停止训练,最好的结果可能在7000,8000,9000上得到,因为可能会有过拟合。
你可以使用-map来得到这些权重在测试集上的mAP值。
mAP时VOC数据集上默认的精度指标,和COCO数据集上 AP50 的含义是一样的。PR在VOC和COCO上可能稍有不同,但是交并比这个指标是一样的。
怎样提高检测的精度
在训练前:
- 在.cfg文件中把random置1,它会提高不同分辨率的精度
- 在.cfg文件中提高网络的分辨率,
height=608
,width=608,或者其他32的倍数
检查下你要检测的物体都有标注-不要漏标数据集中的目标,毕竟训练中最多的问题就是标注的问题
Loss很高并且map很低,训练是否有误?在训练的命令后加上
-show_imgs检查下标注的目标- 对于每个你要检测的目标,至少有一个相似的物体:形状、边、相对大小、旋转的角度、倾斜和光照。没类目标至少有2000张图片,并且训练2000*类别数个迭代。
- 训练集上还应包含你不希望见检测到的物体-也就是那些不包含任何目标的背景,他们的标注设为空。
- 标注目标最好的方式:只标注目标的可见部分,或者重叠且可见的部分,或者比整个目标略小,你希望它们怎样被检测到就怎样去标
- 如果一张训练图中有很多的目标,把max=200设大。
- 为了加速训练,把cfg文件中layer-136 的stopbackward=1
- 为了使检测的结果更精确,你可以在每个[yolo]层中添加3个参数,ignore_thresh = .9 iou_normalizer=0.5 iou_loss=giou,它会提升[email protected],但是会降低[email protected].
- 除非你是神经网络方面的专家,重新计算网络的锚框坐标,不然的话使用默认的就成