代码链接:https://github.com/ultralytics/yolov3
文章链接https://blog.csdn.net/sinat_27634939/article/details/89884011
注意几点
1.训练语句有问题。python train.py --data-cfg data/rbc.data --cfg cfg/yolov3-tiny.cfg --epochs 10 这个语句肯定是错的了
应该是: 传入参数。
python train.py --data data/rbc.data --cfg cfg/yolov3-tiny.cfg --epochs 10
2.yolov3-tiny.cfg这个文件如果直接复制会出两个错误。错误就不贴了,
a.修改方法就是空行去掉空格例如第17行 第24行存在空格,在解析cfg文件的时候会报错。
b. filters=18#3*(class + 4 + 1) 这句改成
#3*(classes + 4 + 1)
filters=18 记得 这个东西有两个位置要改,因为tiny版本是在第1层和第二层分别输出的
3.测试语句也存在问题。和训练语句一样 改一下就好 书写错误。
总结一下:
a.上面代码适用1类的目标检测,如果多类记得把train.py中的这句话改下
parser.add_argument('--single-cls', action='store_false', help='train as single-class dataset')
代码中默认是store_true。
2.cfg这里面要主要写对了,要不会一直报错的。tiny版本需要改两处 因为输出2层,每层的classes和filters写对filters的计算公式是 3 * (1 + 4 + classes)
3.理解那个文件生成的labels的意义,分别代表 :(类别 x中心 y中心 框高 框宽),知道了这几点,可以不用他的脚本,自己写写生成labels文件的代码就好。
4.关于clsloss的计算不知道需不需要改这行代码在train.py里hyp['cls'] *= nc / 80 # update coco-tuned hyp['cls'] to current dataset 。后面那个80应该对应的80类吧
5.一直以为是调用的adam方法做的优化,打印下发现用的是SGD。 用SGD迭代了100多次收敛慢的要死,换adam方法试试。学习率初始用的是0.01不是cfg中的0.001.关于迭代次数以及收敛速度后续再加
6.有个非常重要的地方要注意,这个版本的程序不是将图像强制成416*416的。我用yolov3做实验出现这么个情况,tiny版本是一样的。
img shape finale = torch.Size([1, 3, 320, 512])
pred = torch.Size([1, 10080, 9])
上面这个是中间打印结果。输入图像被放缩成了320*512.那么按照一yolov3的网络结构,这个图像分块最高层是10*16(32倍放缩)。次高层是20*32,第三个输出层是 40* 64 ,每个层预测3个框。那么结果就是10*16* 3 + 20 * 32 * 3 + 40 * 64 * 3 = 10080.与模型预测结果的维度对应上了。那训练的时候肯定也是按这个大小来做的了
下面链上yolo学习比较重要的链接
介绍yolov3和yolov3-tiny结构的。豁然开朗
https://zhuanlan.zhihu.com/p/93809416
介绍yolov1 yolov2 yolov3 原理的 里面有对应地址 防走失 不迷路
https://www.jianshu.com/p/cad68ca85e27
介绍代码中读取数据细节的
https://blog.csdn.net/h__ang/article/details/100577041
介绍loss函数的 loss结果不对了可以来这里翻翻
https://www.cnblogs.com/pprp/p/12590801.html
下面记录下我的工作流程吧:
1.生成train.txt与对应的img图库,每张图已经标记好,对应图生成labels文件。文件内容如上所述,我练手的找了四类来检测。
2.在train.tx里截出几个放在test.txt与val.txt里。
3.将图片放入images里,将标签文件放入labels里面。
4.因为多分类,修改一下代码中的上面提到的那句代码
5.修改cfg文件 我用的tiny版本 将calsses设置为2 filters设置为4就好。
6.修改.name文件等 依照上面博客链接就好。
7.训练:python train.py --data data/rbc.data --cfg cfg/yolov3-tiny.cfg --epochs 20 来20轮就行 主要看看效果
8.测试 不贴了 一会贴个结果图看看
cfg参数说明
[net]
# Testing #推理时才用的到Testing
# batch=1
# subdivisions=1
# Training #训练时使用以下参数
batch=64 #每次载入的批次大小,这里是每次载入64张图片
subdivisions=16 #这里将batch张图片分为16次送入,为了避免显存不够导致溢出
width=608 #训练时的图片宽度
height=608 #训练时的图片高度
#这里注意:训练集中的图片可以是各种尺度的,darknet框架下的训练会自动将图片resize成此大小
#也可以提前自己resize再作为训练集,这样训练速度会快一些
channels=3 #三通道的图像
momentum=0.9 #动量,影响梯度下降的速度
decay=0.0005 #权重衰减比,该值越大,模型抑制过拟合的能力越强,但过大会导致模型无法收敛
angle=15 #样本增强项-角度,会随机将样本在-15度到15度之间旋转来增多样本
saturation = 1.5 #样本增强项-饱和度,目的同样是增多样本
exposure = 1.5 #样本增强项-曝光度,目的同上
hue=.1 #样本增强项-色调,目的同上
learning_rate=0.001 #初始学习率
burn_in=1000 #训练次数少于burn_in次时,学习率不变,多于burn_in次时采用policy的学习率更新策略
max_batches = 500200 #最大训练的batch数,超过该数就停止训练
policy=steps #使用policy的训练策略,训练策略有:CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM这几种
steps=300000,450000 #训练次数达到300000次时,学习率衰减第一个scale倍(10倍),450000次时同样衰减10倍
scales=.1,.1 #与steps配合
[convolutional]
batch_normalize=1 #是否使用bn层,1代表是
filters=32 #该卷积层滤波器的个数
size=3 #滤波器大小,这里是3x3
stride=1 #滑动步长
pad=1 #是否需要padding补0
activation=leaky #激活函数,leaky_Relu
# Downsample 下采样过程,这里代表下一层卷积层运算过后,特征图的x,y维度会变为原来的stride倍
[convolutional]
batch_normalize=1
filters=64
size=3
stride=2 #滑动步长为2,这里实现了下采样
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=32
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=64
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
# Downsample
[convolutional]
batch_normalize=1
filters=128
size=3
stride=2
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=64
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=128
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
# Downsample
[convolutional]
batch_normalize=1
filters=256
size=3
stride=2
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
# Downsample
[convolutional]
batch_normalize=1
filters=512
size=3
stride=2
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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
[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
[shortcut]
from=-3
activation=linear
# Downsample
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=2
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
filters=1024
size=3
stride=1
pad=1
activation=leaky
[shortcut]
from=-3
activation=linear
###################### 从这里开始,三个yolo层共用的网络结构到此结束
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky
[convolutional]
batch_normalize=1
filters=512
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=1024
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=255
activation=linear
[yolo]
mask = 6,7,8 #表示该层yolo层选用那几个Anchor
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
#整个yolov3网络使用了9个Ancnor尺寸,都在这里,通过mask来选择该层yolo层选用哪几个anchor。
#anchor是利用k-means算法基于训练集而得到的目标统计尺寸。本层选用了最大的三个anchor,很显然,本层的目的是着眼于检测大目标。
classes=80 #训练集的类别数
num=9 #anchor数目
jitter=.3 #利用数据抖动来产生更多的数据,这里的抖动概率是0.3
ignore_thresh = .7
#当预测框与真实框(ground truth)的IOU超过该值时,不参与loss计算,否则参与计算
truth_thresh = 1
random=1#如果为1,每次迭代图片大小随机从320到608,步长为32,如果为0,每次训练大小与输入大小一致。也就是多尺度训练。
[route]
layers = -4
#用于特征融合,这里表示从上一层开始数的倒数第4层作为本层。
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[upsample]
stride=2 #上采样过程,特征图的x,y维度变为上一层的2倍
[route]
layers = -1, 61
#特征融合,倒数第1层(上一层开始算)与第61层融合,也就是滤波器直接叠加。
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky
[convolutional]
batch_normalize=1
filters=256
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=512
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=255
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=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
[route]
layers = -4
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[upsample]
stride=2
[route]
layers = -1, 36
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=256
activation=leaky
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=256
activation=leaky
[convolutional]
batch_normalize=1
filters=128
size=1
stride=1
pad=1
activation=leaky
[convolutional]
batch_normalize=1
size=3
stride=1
pad=1
filters=256
activation=leaky
[convolutional]
size=1
stride=1
pad=1
filters=255
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=80
num=9
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=1
关于学习率,这个里面可能更清楚些吧 代码中没用cfg中的学习率用的是train.py中的超参数列表
https://blog.csdn.net/songwsx/article/details/102656935
注:https://uzshare.com/view/828033 yolov4 他来了他来了