这两天在使用yolov3-tiny,记录下一些训练参数和其取值的意义。
在不检测目标占比小的情况时,可以选用的yolov3-tiny模型
yolo训练时输出的各项参数(这图用的是yolov3-tiny训练,所以只有16和23这二个yolo层),对比如上16层检测大的,23检测小的。
count 是表示当前层与真实label正确配对的box数。
其中所有参数都是针对这个值的平均值,除no obj外,不过从代码上来,这个参数意义并不大,所以当前yolo层如果出现nan这个的打印,也是正常的,只是表示当前batch刚好所有图片都是大框或是小框,所以提高batch的数目可以降低nan出现的机率
。
Avg IOU 表示当前层正确配对的box的交并比的平均值
Class 表示表示当前层正确配对类别的平均机率
Obj 表示confidence = P(object)* IOU,表示预测box包含对象与IOU好坏的评分
0.5R/0.7R 表示Iou在0.5/0.7上与正确配对的box的比率
①burn_in设置
拿到yolov3-tiny.cfg文件,先把burn_in修改成1,因为没有预精确数据,最开始就以原始学习率开始训练;
②训练样本数和迭代次数
2000张样本迭代2000-5000次最佳,10000样本迭代20000次左右(主要看学习率的下降和数据复杂度)
③ batch和subdivisions两个参数
batch 批尺寸,每一次迭代送到网络的图片数量。batch * iteration得到的就是一个epoch内训练的样本数。增大这个可以让网络在较少的迭代次数内完成一个epoch。在固定最大迭代次数的前提下,增加batch会延长训练时间,但会更好的寻找到梯度下降的方向。如果你显存够大,可以适当增大这个值来提高内存利用率。这个值是需要大家不断尝试选取的,过小的话会让训练不够收敛,过大会陷入局部最优。【深度机器学习中的batch的大小对学习效果有何影响?】
subdivisions 如果内存不够大,会将batch分割为subdivisions个子batch,每个子batch大小为batch/subdivisions。子batch一份一份的跑完后,在一起打包算作完成一次iteration。这样会降低对显存的占用情况。如果设置这个参数为1的话就是一次性把所有batch的图片都丢到网络里,如果为2的话就是一次丢一半。【YOLO算法学习及训练】(包括其他参数的意义)
关于YOLO的cfg配置文件理解,这个博主说的很全了【YOLO配置文件理解】
④训练初始化超参数(这里以yolov3-tiny为例)
[net]
# Testing ### 测试模式
#batch=1
#subdivisions=1
# Training ### 训练模式,每次前向的图片数目 = batch/subdivisions
batch=64 ###这个地方改成64。 ##注意##这里 batch=64
subdivisions=2 ##注意##这里 subdivisions=2
width=720 ### 网络的输入宽、高、通道数
height=1280
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 = 10000 ### 迭代次数 ##注意## 这里训练次数一般填10000到50000次
policy=steps 调整学习率的policy,有如下policy:CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM
steps=100,25000,35000 ### 根据batch_num调整学习率
scales=10,.1,.1 ###学习率变化的比例,累计相乘
[convolutional]
batch_normalize=1 是否做BN
filters=32 输出多少个特征图
size=3 卷积核的尺寸
stride=1 做卷积运算的步长
pad=1 如果pad为0,padding由 padding参数指定。如果pad为1,padding大小为size/2
activation=leaky 激活函数:
logistic,loggy,relu,elu,relie,plse,hardtan,lhtan,linear,ramp,leaky,tanh,stair
[maxpool] ###最大池化层
size=2
stride=2
[convolutional]
batch_normalize=1
filters=32
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=2
[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky
[maxpool]
size=2
stride=1
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
###########
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=512
size=3
stride=1
pad=1
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=21 region前最后一个卷积层的filters数是特定的,计算公式为filter=
num(classes+5) 5的意义是5个坐标,论文中的tx,ty,tw,th,to
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,31 预选框,可以手工挑选,
也可以通过k means 从训练样本中学出
classes=2 类别 这里类别填你的标注类别有多少类
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1 ###如果显存很小,将random设置为0,关闭多尺度训练 random为1时会启用Multi-Scale Training,随机使用不同尺寸的图片进行训练。
[route]
layers = -4 the route layer is to bring finer grained features in from earlier in the network
layers=-9
[convolutional]
batch_normalize=1
filters=128 ###更改为filters =(classes + 5)x3
size=1
stride=1
pad=1
activation=leaky
[upsample]
stride=2
[route]
layers = -1, 8
[convolutional]
batch_normalize=1
filters=21 更改为filters =(classes + 5)x3 这里更改为(classes + 5)x3
size=3
stride=1
pad=1
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=21 更改为filters =(classes + 5)x3 ##注意## 这里更改为(classes + 5)x3
activation=linear
[yolo]
mask = 0,1,2
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=2 类别 这里类别填你的标注类别有多少类
num=6 每个grid cell预测几个box,和anchors的数量一致。当想要使用更多anchors时需要调大num,且如果调大num后训练时Obj趋近0的话可以尝试调大object_scale
jitter=.3 通过抖动增加噪声来抑制过拟合
ignore_thresh = .7 文章中的阈值1
truth_thresh = 1 文章中的阈值2
random=1 如果显存很小,将random设置为0,关闭多尺度训练
①刚开始出现**-nan**正常现象,如果全部是nan,是xml生成的txt错误或者label名字错误,查看coco.names,生成的txt确定文件都正确
① 断点重新训练
如果从某次断了重新开始训练,只需要把 darknet53.conv.74 换成你的某一次的weights即可
例如:把命令行中的参数 darknet53.conv.74 改成 yolov3-tiny_1000.weights 即可
② 修改cfg/xxx.cfg,首先修改分类数为自己的分类数,然后注意开头部分训练的batchsize和subdivisions被注释了,如果需要自己训练的话就需要去掉,测试的时候需要改回来,最后可以修改动量参数为0.99和学习率改小,这样可以避免训练过程出现大量nan的情况
③ 若出现显存不足,可修改batch的大小和取消random多尺度,默认情况下random=1,取消将random=0(需要修改几处)
【1】Yolov3代码分析与训练自己数据集
【2】YOLO v3——训练自己的VOC数据及训练技巧
【3】Darknet YOLO 训练问题集锦