前言
目标检测的模型还是很多的,要挨个挨个学还是有点吃力(精力旺盛可忽略),所以这里总结一下当前流行的目标检测的框架:darknet yolov4,mmdetection2.0,detectron2.0。至于这三个框架怎么去选择,我的答案是只有你真正懂了,上手试了这几个框架之后你才能比较它们之间的优劣。
1 Darknet YOLOv4 配置
我的环境:WIN10,CUDA10.1,cuDNN7.6.4,Anaconda,VS2019,OpenCV3.4.10,GTX1660(6G内存)
- Windows10 这几个框架全都是在windows10上配置成功的(符合大多数不懂Linux的朋友)。windows10不用我多说,windows7的小伙伴找个机会赶紧升级吧,不然接下来的很多操作你会不适应。
- CUDA10.1 各个版本的CUDA下载(没有CUDA的小伙伴你就放弃吧,真心跑不动)。
- cuDNN7.6.4 cuDNN官方下载地址(需要注册NVIDIA账号下载)。
- Python3.7 这个Anaconda已经自带。
- VS2019 进入VS官网下载社区版。
- OpenCV3.4.10 官网下载3.4.10版本
- YOLO v4 GitHub下载YOLO v4项目并解压。
- 复制OpenCV文件 将
opencv\build\x64\vc15\bin
的两个dll文件:opencv_ffmpeg340_64.dll
和opencv_world340.dll
复制到darknet\build\darknet\x64
- 配置VS2019 见下
具体如何将上述软件整合到一起的操作,详见:WIN10+YOLOv4,windows上完美执行YOLOv4目标检测
2 YOLOv4如何使用
- Yolo v4 COCO - 检测一张图片:
darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.25
- 输出被检测物体坐标:
darknet.exe detector test cfg/coco.data yolov4.cfg yolov4.weights -ext_output dog.jpg
- Yolo v4 COCO - 检测一段视频:
darknet.exe detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -ext_output test.mp4
- Yolo v4 COCO - 本地摄像头检测:
darknet.exe detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights -c 0
- Yolo v4 COCO 智能网络摄像头(海康):
darknet.exe detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights http://192.168.0.80:8080/video?dummy=param.mjpg
- Yolo v4 - 保存结果视频文件res.avi:
darknet.exe detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4 -out_filename res.avi
- Yolo v3 Tiny COCO - 视频:
darknet.exe detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights test.mp4
- JSON和MJPEG服务器,允许来自您的软件浏览器或Web浏览器
ip-address:8070
和8090
的多个连接:./darknet detector demo ./cfg/coco.data ./cfg/yolov3.cfg ./yolov3.weights test50.mp4 -json_port 8070 -mjpeg_port 8090 -ext_output
- Yolo v3 Tiny 在 GPU #1上:
darknet.exe detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights -i 1 test.mp4
- 替代方法Yolo v3 COCO-检测图片:
darknet.exe detect cfg/yolov4.cfg yolov4.weights -i 0 -thresh 0.25
- 在Amazon EC2上进行训练,以使用URL来查看mAP和丢失图表,例如:
http://ec2-35-160-228-91.us-west-2.compute.amazonaws.com:8090
在Chrome / Firefox中(Darknet应该使用OpenCV进行编译):./darknet detector train cfg/coco.data yolov4.cfg yolov4.conv.137 -dont_show -mjpeg_port 8090 -map
- 186 MB 的Yolo9000-检测图片:
darknet.exe detector test cfg/combine9k.data cfg/yolo9000.cfg yolo9000.weights
- 如果使用cpp api构建应用程序,请记住将
data / 9k.tree
和data / coco9k.map
放在应用程序的同一文件夹下。 - 要处理图像列表
data/train.txt
并将检测结果保存到result.json
文件中,请使用:darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -ext_output -dont_show -out result.json < data/train.txt
- 处理图像列表
data/train.txt
并保存检测结果以result.txt
供使用:darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -dont_show -ext_output < data/train.txt > result.txt
- Pseudo-lableing - 处理图像列表
data/new_train.txt
并将检测结果以Yolo训练格式保存为每个图像作为标签<image_name>.txt
(通过这种方式,您可以增加训练数据量)使用:darknet.exe detector test cfg/coco.data cfg/yolov4.cfg yolov4.weights -thresh 0.25 -dont_show -save_labels < data/new_train.txt
- 计算 anchors:
darknet.exe detector calc_anchors data/obj.data -num_of_clusters 9 -width 416 -height 416
- 检查 mAP@IoU=50:
darknet.exe detector map data/obj.data yolo-obj.cfg backup\yolo-obj_7000.weights
- 检查 mAP@IoU=75:
darknet.exe detector map data/obj.data yolo-obj.cfg backup\yolo-obj_7000.weights -iou_thresh 0.75
- YOLOv4-tiny调用摄像头
darknet.exe detector demo cfg/coco.data cfg/yolov4-tiny.cfg yolov4-tiny.weights -c 0
- YOLOv4-tiny调用海康摄摄像头
darknet.exe detector demo cfg/coco.data cfg/yolov4-tiny.cfg yolov4-tiny.weights rtsp://admin:forward1@192.168.7.102:554/Streaming/Channels/1
3 YOLOv4训练自己的数据集
3.1 labelme
制作数据集
这里先说明一下为什么我要选择labelme来制作数据集,鉴于目前网上大多数都是采用的labelimg来制作YOLO的数据,但是思考到一个问题:
- 如果每用一个框架或者训练一个网络就去重新制作一次数据集,这样会不会重复做一无用功?
所以我才用labelme来制作数据集,最明显的优点就是既可以目标检测又可以实力分割。
至于如何用labelme来标记数据,不会的自己百度,很简单。
3.2 labelme2voc
由于目前网络上很多都是针对VOC数据集的,所以主要是如何将labelme制作的数据转化为VOC格式的数据。(我知道daknet一定可以直接训练coco格式的数据格式,由于资料过少,就没有具体去尝试,有会的大佬还望不吝赐教)
在data目录下创建一个VOCdevkit
文件夹,格式如下:
x64
├── backup
├── cfg
├── configs
├── voc
├── data
│ ├── VOCdevkit
│ │ ├── VOC2007
│ │ │ ├── Annotations
│ │ │ ├── ImageSets
│ │ │ ├── JPEGImages
│ │ │ ├── labels
labelme制作的json文件并不能直接使用,需要转换工具转换成VOC数据集文件的格式。去GitHub下载labelme2voc.py
文件,然后修改里面的文件路径。主要修改以下两个地方:
#1.标签路径
labelme_path = "./labelme/" #原始labelme标注数据路径
saved_path = "./VOCdevkit/VOC2007/" #保存路径
(如果报错,那就把错误打印出来在百度,很快就能解决)。
完成了上面的转化就生成了标准的VOC数据格式。
3.3 voc_label
YOLO并不能直接训练VOC的数据格式,还需要转化成YOLO自己的数据格式。
数据准备完毕后,打开voc/voc_label.py
修改以下几个地方:
- 第七行:
sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
- 将第9行改为自己数据集的类别名称:
classes = ["cat","dog"]
更改完成保存。将voc_label.py
复制到data
文件夹下,运行命令python voc_label.py
在VOCdevkit/VOC2007
路径在可以看到labels文件夹,并且在data
文件夹内会有2007_test.txt
、2007_train.txt
、2007_val.txt
这三个文件。至此数据集准备完毕。
3.4 修改配置文件
- 修改
data/voc.data
classes= 1
train = data/2007_train.txt
valid = data/2007_val.txt
#difficult = data/difficult_2007_test.txt
names = data/voc.names
backup = backup/
- 2.修改
data/voc.names
将里面改成自己类别的名字。 - 修改
cfg/yolov4-custom.cfg
3.5 修改cfg/yolov4-custom.cfg
cfg/yolov4-custom.cfg
总共有6处修改:
- yolov4-cat.cfg文件第1-7行如下:
----------------------------------------------------------------
[net]
# Testing
#batch=1
#subdivisions=1
# Training
batch=64
subdivisions=16
----------------------------------------------------------------
注意:由于是进行训练,这里不需要修改。训练过程中可能出现CUDA out of memory
的提示,可将这里的subdivisions
增大,如32或64,但是数值越大耗时越长,因此需要权衡一下; yolov4-cat.cfg
文件第8-9行将608修改为416:
----------------------------------------------------------------
width=416
height=416
----------------------------------------------------------------
注意:这里也可不改,如果原始的数值608可能会导致CUDA out of memory
的提示,而且这里的数值必须是32的倍数,这里也是数值越大耗时越长;- 第20行的参数
max_batches
也要修改,原始值为500500,max_batches = classes*2000
,但是max_batches
不要低于训练的图片张数,这里只训练1类,因此max_batches = 2000
; - 第22行的参数
steps=1600,1800
,这两个数值分别为`max_batches的80%和90%; - 继续修改
yolov4-cat.cfg
文件,按Ctrl+F键,搜索“classes”,一共有3处,先定位到第一处,将classes=80
改为classes=1
,并将classes前面最近的filters修改为18,计算由来(classes+5)*3=18
; - 继续修改
yolov4-cat.cfg
文件,按照上面的步骤同样修改第二处和第三处的classes;
继续修改
进入darknet/data
文件夹下,创建名称为cat.names
的文件(参考该文件夹voc.names
文件的写法),在cat.names
文件中添加类别名称,本次实验只需添加cat即可;
进入darknet/cfg
文件夹下,创建名称为cat.data
的文件,在该文件中添加相关内容,一共5行,参考示例voc.data
文件,类别改为1;
----------------------------------------------------------------
classes= 1
train = ~/darknet/data/cat_data/train.txt
valid = ~/darknet/data/cat_data/test.txt
names = data/cat.names
backup = backup/
----------------------------------------------------------------
(1)其中第二行和第三行分别为train.txt
和test.txt
所在的路径,第5行改为前面新建的cat.names
;
(2)这里的train.txt和
test.txt`前一篇博客中第1步生成的文件;
(3)第5行backup = backup/
不能写成其它路径,否则会报错;
3.6 训练和测试
训练
打开命令行窗口进入darknet目录下,并输入以下指令:
#单GPU
C:\Darknet\darknet-master\build\darknet\x64>.\darknet.exe detector train cfg/voc.data cfg/yolov4-custom.cfg yolov4.conv.137
#多GPU
C:\Darknet\darknet-master\build\darknet\x64>.\darknet.exe detector train cfg/voc.data cfg/yolov4-custom.cfg yolov4.conv.137 -gpus 0,1,2,3
训练的过程中,生成的权重文件会存放在/darknet/backup
文件夹下,训练过程每隔一段时间会生成一个.weights文件;
训练的一些输出说明:
-
Region xx
: cfg文件中yolo-layer的索引; -
Avg IOU
:当前迭代中,预测的box与标注的box的平均交并比,越大越好,期望数值为1; -
Class
: 标注物体的分类准确率,越大越好,期望数值为1; -
obj
: 越大越好,期望数值为1; -
No obj
: 越小越好; -
.5R
: 以IOU=0.5为阈值时候的recall; recall = 检出的正样本/实际的正样本 -
0.75R
: 以IOU=0.75为阈值时候的recall; -
count
:正样本数目
测试
生成.weights文件后,便可以进行测试了(此时训练仍在继续,另外开一个终端进入darknet路径下)。也可以等待全部训练完成后再进行测试。测试指令如下:
C:\Darknet\darknet-master\build\darknet\x64>.\darknet.exe detect cfg/yolov4-custom.cfg backup/yolov4-custom_last.weights data/test2014/1.jpg
注意,Yolo v4版本添加了训练时候训练误差随着迭代次数的增加而变化的图,可以方便看误差的变化情况。