Yolov3 training own dataset
一、搭建环境
搭建环境和验证环境,确保tensorflow,cuda,cudnn,opencv等环境配置完毕。
二、数据准备
使用YOLOv3训练自己的数据集时一共需要修改6个文件
文件名 | 文件路径 | 文件说明 |
---|---|---|
makefile | darknet | 编译成可执行程序的文件,在其中指定是否使用GPU和Cuda,是否使用摄像头,OpenCV等 |
train.txt | 自定义 | 用来保存训练图片的路径,每一行是一张图片的完整路径,找不到图片的错误一般是路径不对 |
label | 文件夹 | 整个文件夹存放所有图片的标注信息,标注信息用txt文档保存 |
.cfg文件 | darknet-master/cfg | .cfg文件指定了网络结构和其他超参数 |
.names文件 | 自定义 | 该文件指定了训练的标签,如:person,car等,一个标签占一行 |
.data文件 | 自定义 | 该文件的内容指示了上述train.txt,.name和模型的保存的位置等 |
1.修改makefile文件,makefile文件一共修改四处
1.修改开始几行的内容,0表示否,1表示是 2.修改运算架构,自己显卡支持什么架构可以自己查询,按需修改,也可以使用默认值。
ARCH= -gencode arch=compute_30,code=sm_30 \
-gencode arch=compute_35,code=sm_35 \
-gencode arch=compute_50,code=[sm_50,compute_50] \
-gencode arch=compute_52,code=[sm_52,compute_52]
-gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?
3.修改NVCC值:NVCC=nvcc, 改为你cuda路径下的nvcc,也可不改 4.修改cuda路径值:48行处
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif
此处路径为你安装cuda的路径,一般只需要把cuda换成chuda9.0或其他版本
2.生成train.txt
train.txt的生成,需要自己写脚本生成,python推荐os.listdir()遍历一个文件夹里的所有文件。
3.制作标签文件夹
总原则:每张训练图片生成一个以图片名命名的txt标签文档,假设有:1.jpg,2.jpg,3.jpg三张训练图片,那你就需要生成1.txt,2.txt,3.txt三个标签文档,同时train.txt中一定是三行内容,其中:
每一行表示该图片中一个矩形框的信息
第一列表示该矩形框中对象的类别索引号,这个类别索引号与.name文件有关,从上到下,索引号从0开始
第二列表示该矩形框的中心点的x坐标值。
第三列表示该矩形框的中心点的y坐标值。
第四列表示该矩形框的宽度值,第五列表示该矩形框的高度值
注意:第2-5列的值都是归一化后的值,x和宽度值相对与图片的宽度归一化,y值和高度值相对与图片的高度归一化。
4.修改.cfg的内容
Darknet中的.cfg文件
[net] //[xxx]开始的行表示网络的一层,其后内容为该层的参数配置,[net]为特殊的层,配置整个网络
#Testing //带#号为注释行,在解析cfg文件时会忽略该行
#batch=1
#subdivisions=1
#Training
batch=64 //这里的batch与机器学习中的batch有少许差别,仅表示网络累计多少个样本后进行一次BP
subdivisions=16 //表示将一个batch中的图片分sub次完成前向传播
//在Darknet中,batch和sub是结合使用的,例如:batch=64,subdivisions=16表示训练过程中将
一次性加载64张图片进内存,然后分16次完成前向传播,意思是每次4张,前向传播过程中累加loss求平均,
待64张图片都完成前向传播后,再一次性后传更新参数
//调参经验:sub一般设置16,不能太大或太小,且为8的倍数,没有硬性规定,batch的值可以自行根据显存的大小情况动态调整,一次性加减一个sub大小即可,
通常情况下batch越大越好,但是在test时,batch和sub都设置为1,避免发生神秘错误!
width=608 //网络输入的宽width
height=608 //网络输入的高height
channels=3 //网络输入的通道数channels
//注意:width和height一定要为32的倍数,否则不能加载网络
//提示:width也可以设置为不等于height,通常情况下width和height值越大对小目标的检测效果越好,
但受到显存但限制。
momentum=0.9 //动量 DeepLearning中最优化方法中但动量参数,这个值影响着梯度下降到最优值的速度
decay=0.0005 //权重衰减正则项,防止过拟合
angle=0 //数据增强参数,通过旋转角度来生成更多的训练样本
saturation = 1.5 //数据增强参数,通过调整图片饱和度来生成更多训练样本
exposure = 1.5 //数据增强参数,通过调整图片曝光量来生成更多训练样本
hue=.1 //数据增强参数,通过调整色调来生成更多训练样本
learning_rate=0.001 //学习率决定着权值的更新速度,设置太大会导致结果超过最优值,太小会使下降速度过慢,
如果仅靠人为干预调整参数,需要不断更改学习率。刚开始训练可以将学习率设置的高一点,
而一定轮数之后,将其减小在训练过程中,一般根据训练的轮数来动态更新学习率刚开始训练时:学习率以 0.01 ~ 0.001 为宜。
一定轮数过后:逐渐减缓。接近训练结束:学习速率的衰减应该在100倍以上。学习率的调整参考https://blog.csdn.net/qq_33485434/article/details/80452941
//学习率调整一定不要太死,实际训练过程中根据loss的变化和其他指标动态调整,手动ctrl+c结
束此次训练后,修改学习率,再加载刚才保存的模型继续训练即可完成手动调参,调整的依据是根据训练
日志来,如果loss波动太大,说明学习率过大,适当减小,变为1/5,1/10均可,如果loss几乎不变,
可能网络已经收敛或者陷入了局部极小,此时可以适当增大学习率,注意每次调整学习率后一定要训练久一点,充分观察,调参是个细活,慢慢琢磨
//说明:实际学习率与GPU的个数有关,例如你的学习率设置为0.001,如果你有4块GPU,那真实学习率为0.001/4
burn_in=1000 //在迭代次数小于burn_in时,其学习率的更新有一种方式,大于burn_in时,才采用policy的更新方式
max_batches = 500200//训练次数达到max_batches后停止学习,一次为跑完一个batch
policy=steps //学习率调整的策略:constant, steps, exp, poly, step, sig, RANDOM,constant等方式参考https://nanfei.ink/2018/01/23/YOLOv2%E8%B0%83%E5%8F%82%E6%80%BB%E7%BB%93/#more
steps=400000,450000//steps和scale是设置学习率的变化,比如迭代到400000次时,学习率衰减十倍,45000次迭代时,学习率又会在前一个学习率的基础上衰减十倍
scales=.1,.1
[convolutional] //一层卷积层的配置说明
batch_normalize=1 //是否进行BN处理,0为否,1为是
filters=32 //卷积核的个数也是输出通道数
size=3 //卷积核尺寸
stride=1 //卷积核步长
pad=1 //卷积时是否进行padding,padding的个数和卷积核尺寸有关,为size/2向下取整,如3/2=1
activation=leaky //网络层的激活函数
#downsample
[convolutional] //下采样配置说明
batch_normalize=1
filters=64
size=3
stride=2
pad=1
activation=leaky //卷积核尺寸大小为3*3时,配合padding且步长为2时,featrue map变为原来图片尺寸一半大小。
[shortcut] //shortcut层配置说明
from=-3 //与前面的多少层进行融合,-3表示前面的第三层
activation=linear //层激活函数
......
......
[convolutional] //yolo层前面一层卷积配置说明
size=1
stride=1
pad=1
filters=255 //filters=num(预测框个数)*(classes + 5),5表示4个坐标值加一个置信率,论文中的tx,ty,th,tw,c,classes为类别数,
COCO数据集个数为80,num表示YOLO中每个cell中的预测框个数,YLOLOv3中为3
//自行使用时,此处的值一定要根据自己的数据集进行修改,例如识别5个类,则:
filters=3*(5 + 5)= 30,三个filters都需要修改
activation=linear
[yolo] //YOLO层的配置说明
mask = 0,1,2 //使用anchor的索引,0, 1, 2 表示下面定义的anchors中的前三个
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80 //类别数目
num=9 //每个grid cell总共预测多少个box,和anchors的数量一至,想要使用更多anchors时需要调大num
jitter=.3 //数据增强手段,jitter为随机调整宽高比的范围
ignore_thresh = .7
truth_thresh = 1 //参与计算的IOU阈值大小,当预测的检测框与ground true的IOU大于ignore_thresh时,参与loss的计算,否则,检测框不参与损失的计算。
//理解:目的是控制参与loss计算的检测框的规模,当ignore_thresh过于大,接近于1的时候,那么参与
检测框回归loss的个数就会比较少,同时也容易造成过拟合;而如果ignore_thresh设置的过于小,
那么参与计算的会数量规模就会很大。同时也容易在进行检测框回归的时候造成欠拟合。
//参数设置:一般选取0.5-0.7之间的一个值,之前的计算基础都是小尺度(13*13)用的是0.7,(26*26)用的是0.5。
这次先将0.5更改为0.7。参考:https://www.e-learn.cn/content/qita/804953
random=1 //为1打开随机多尺度训练,为0则关闭
//提示:当打开随机多尺度训练时,前面设置的网络输入尺寸width和height其实就不起作用了,width会在320到608之间随机取值,
且width=height,没10轮随机改变一次,一般建议可以根据自己需要修改随机尺度训练的范围,这样可以增大batch。
##### 5.学习率的设定规律
在训练过程中,一般根据训练轮数设置动态变化的学习率
- 刚开始训练时:学习率以0.01~0.001为宜。
- 一定轮数之后:逐渐减缓
- 接近训练结束时:学习速率的衰减该在100倍以上
1.曲线 初始时 上扬 [红线]: Solution:初始 学习率过大 导致 振荡,应减小学习率,并 从头 开始训练 。 2.曲线 初始时 强势下降 没多久 归于水平 [紫线]: Solution:后期 学习率过大 导致 无法拟合,应减小学习率,并 重新训练 后几轮 。 3.曲线 全程缓慢 [黄线]: Solution:初始 学习率过小 导致 收敛慢,应增大学习率,并 从头 开始训练 。
6.修改.names内容
其为标签名称,每一个标签占一行,根据自己的需要进行修改:
//这是voc.names文件中的标签名称
aeroplane
bicycle
bird
boat
bottle
bus
car
cat
chair
cow
......
7.修改.data文件的内容
classes= 20
train = /home/pjreddie/data/voc/train.txt
valid = /home/pjreddie/data/voc/2007_test.txt
names = data/voc.names
backup = backup
1.Classes表示数据集的类别数目 2.train表示生成train.txt文件的文件路径,也就是图片绝对路径的存储文件 3.valid表示验证数据图片路径存储的位置 4.names表示刚刚处理过的.names文件的位置 5.backup表示训模型保存的位置,该位置一定要存在,如果不存在可以新创建