须知: 对于占比较小的目标检测效果不好,虽然每个格子可以预测多个bounding box,但是最终只选择IOU(预测的矩形框和真实目标的交集与并集之比)最高的bounding box作为物体检测输出,即每个格子最多只预测出一个物体。当一个格子中包含多个物体时,如鸟群等,却只能检测出其中一个。另外,YOLO对车牌识别的效果一般。
如果不使用相关功能,不必修改路径。
GPU=1 #如果使用GPU设置为1,CPU设置为0 CUDNN=0 #如果使用CUDNN设置为1,否则为0 OPENCV=0 #如果调用摄像头,还需要设置OPENCV为1,否则为0 OPENMP=0 #如果使用OPENMP设置为1,否则为0 DEBUG=0 #如果使用DEBUG设置为1,否则为0 CC=gcc NVCC=nvcc #修改为自己的路径 AR=ar ARFLAGS=rcs OPTS=-Ofast LDFLAGS= -lm -pthread COMMON= -Iinclude/ -Isrc/ CFLAGS=-Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC ... ifeq ($(GPU), 1) COMMON+= -DGPU -I/usr/local/cuda/include/ #修改为自己的路径 CFLAGS+= -DGPU LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand #修改为自己的路径 endif 1234567891011121314151617181920保存后退出,在当前路径make一下。
首先创建一个目录来存储所有数据,如VOCdevkit/来包含VOC训练数据的子目录。创建子目录各文件夹结构如下所示: —VOCdevkit ——VOC2019 ———Annotations ———ImageSets ————Main ———JPEGImages
图片及标注可以从网上找,也可自己爬取后使用labelImg标注。 图片放入JPEGImages文件夹中。 对应图片标注生成的XML文件放入Annotations文件夹中。
labelImg下载方式:使用git命令
git clone https://github.com/tzutalin/labelImg 1安装:
$ sudo apt-get install pyqt4-dev-tools # 安装PyQt4 $ sudo pip install lxml # 安装lxml,如果报错,可以试试下面语句 $ sudo apt-get install python-lxml 123在labelImg目录下执行:
python labelImg.py 1快捷键: Ctrl + u 加载目录中的所有图像,鼠标点击Open dir同功能 Ctrl + r 更改默认注释目标目录(xml文件保存的地址) Ctrl + s 保存 Ctrl + d 复制当前标签和矩形框 space 将当前图像标记为已验证 w 创建一个矩形框 d 下一张图片 a 上一张图片 del 删除选定的矩形框 Ctrl++ 放大 Ctrl-- 缩小
Main中包含train.txt和val.txt
使用如下代码可生成对应的两个txt文件(代码位置与主目录同级)
import os from os import listdir, getcwd from os.path import join if __name__ == '__main__': source_folder='/home/lixiaoyu/darknet/scripts/VOCdevkit/VOC2019/JPEGImages/' dest='/home/lixiaoyu/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/train.txt' dest2='/home/lixiaoyu/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/val.txt' file_list=os.listdir(source_folder) train_file=open(dest,'a') val_file=open(dest2,'a') for file_obj in file_list: file_path=os.path.join(source_folder,file_obj) file_name,file_extend=os.path.splitext(file_obj) file_num=int(file_name) if(file_num<80000): train_file.write(file_name+'\n') else : val_file.write(file_name+'\n') train_file.close() val_file.close() 123456789101112131415161718192021222324在VOCdevkit同级目录下载voc_label.py文件
wget https://pjreddie.com/media/files/voc_label.py 1修改文件中sets和classes,如:
sets=[('2019', 'train'), ('2019', 'val')] classes = ["1",“2”,“3”] 123运行它
python voc_label.py 1几分钟后,此脚本将生成所有必需的文件。如2019_train.txt和2019_val.txt文件,还会在VOCdevkit/VOC2019/labels/中生成大量标签文件。 类似于:
0 0.449074074074 0.679861111111 0.685185185185 0.456944444444 1即:
<object-class> <x> <y> <width> <height> 11.现在转到Darknet目录。我们必须更改cfg/voc.data配置文件以指向您的数据:
classes= 3 train = /home/lixiaoyu/darknet/scripts/2019_train.txt valid = /home/lixiaoyu/darknet/scripts/2019_val.txt names = /home/lixiaoyu/darknet/data/voc.names backup = backup(忘说了...backup文件夹要自己创建在Darknet目录下) 123452.更改data/voc.names(数据集的标签名)如本例:
1 2 3 1233.修改cfg/yolov3-voc.cfg
[net] #Testing #batch=1 #subdivisions=1 #Training batch=64 #批次,显存不够可减小,但会出现Nan问题(解决办法:增大batch。。。) subdivisions=16 #训练迭代包含16组,每组4张图片 width=416 height=416 channels=3 momentum=0.9 #滑动平均模型,在训练的过程中不断地对参数求滑动平均,这样能够更有效地保持稳定性,使其对当前参数更新不敏感 decay=0.0005 #权重衰减,防止过拟合 angle=0 saturation = 1.5 exposure = 1.5 hue=.1 learning_rate=0.001 #学习率 学习率决定了参数移动到最优值的速度快慢 burn_in=1000 max_batches = 50200 policy=steps steps=40000,45000 scales=.1,.1 ...... [convolutional] size=1 stride=1 pad=1 filters=24 #3*(类别+5) activation=linear [yolo] mask = 6,7,8 anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 classes=3 #类别 num=9 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=1 #如果显存很小,将random设置为0,关闭多尺度训练 ...... [convolutional] size=1 stride=1 pad=1 filters=24 #这儿 activation=linear [yolo] mask = 3,4,5 anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 classes=3 #还有这儿 num=9 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=0 ...... [convolutional] size=1 stride=1 pad=1 filters=24 #。。。 activation=linear [yolo] mask = 0,1,2 anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 classes=3 #。。。 num=9 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=0 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677普通训练:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 1若想使用多个GPU训练
./darknet detector train cfg/coco.data cfg/yolov3.cfg darknet53.conv.74 -gpus 0,1,2,3 1如终止训练,权重会保存在backup文件夹下。如果要从检查点停止并重新启动训练
./darknet detector train cfg/coco.data cfg/yolov3.cfg backup/yolov3.backup -gpus 0,1,2,3 1如图所示:
Region 82 Avg IOU: 0.874546, Class: 0.983519, Obj: 0.984566, No Obj: 0.008776, .5R: 1.000000, .75R: 0.750000, count: 4 Region 94 Avg IOU: 0.686372, Class: 0.878314, Obj: 0.475262, No Obj: 0.000712, .5R: 1.000000, .75R: 0.200000, count: 5 Region 106 Avg IOU: 0.893751, Class: 0.762553, Obj: 0.388385, No Obj: 0.000089, .5R: 1.000000, .75R: 1.000000, count: 1 123三个尺度上预测不同大小的框,82卷积层为最大预测尺度,使用较大的mask,可以预测出较小的物体,94卷积层 为中间预测尺度,使用中等的mask, 106卷积层为最小预测尺度,使用较小的mask,可以预测出较大的物体。
下面以其中一个为例:
Region 82 Avg IOU: 0.874546, Class: 0.983519, Obj: 0.984566, No Obj: 0.008776, .5R: 1.000000, .75R: 0.750000, count: 4 1详解: Region Avg IOU: 表示在当前subdivision内的图片的平均IOU,代表预测的矩形框和真实目标的交集与并集之比。 Class: 标注物体分类的正确率,期望该值趋近于1。 Obj: 越接近1越好。 No Obj: 期望该值越来越小,但不为零。 count: count后的值是所有的当前subdivision图片中包含正样本的图片的数量。
每过一个批次会返回一个输出:
1: 806.396851, 806.396851 avg, 0.000000 rate, 1.457291 seconds, 64 images 11: 指示当前训练的迭代次数 806.396851:是总体的Loss(损失) 806.396851 avg:是平均Loss,这个数值应该越低越好,一般到0.几的时候就可直接退出训练。 0.000000 rate:代表当前的学习率,是在.cfg文件中定义的。 1.843955 seconds:表示当前批次训练花费的总时间。 64 images:这一行最后的这个数值是1*64的大小,表示到目前为止,参与训练的图片的总量。