YOLOv3训练过程中重要参数的理解和输出参数的含义
最近有⼈问起在YOLOv2训练过程中输出在终端的不同的参数分别代表什么含义,如何去理解这些参数?本篇⽂章中我将尝试着去回答这个有趣的问题。
刚好现在我正在训练⼀个YOLOv2模型,拿这个真实的例⼦来讨论再合适不过了,下边是我训练中使⽤的 .cfg ⽂件(你可以在cfg⽂件夹下找到它):
以下是训练过程中终端输出的⼀个截图:
以上截图显⽰了所有训练图⽚的⼀个批次(batch),批次⼤⼩的划分根据我们在 .cfg ⽂件中设置的subdivisions参数。在我使⽤的 .cfg ⽂件中 batch = 64 ,subdivision = 8,所以在训练输出中,训练迭代包含了8组,每组⼜包含了8张图⽚,跟设定的batch和subdivision的值⼀致。
(注: 也就是说每轮迭代会从所有训练集⾥随机抽取 batch = 64 个样本参与训练,所有这些 batch 个样本⼜被均分为 subdivision = 8次送⼊⽹络参与训练,以减轻内存占⽤的压⼒)
批输出
针对上图中最后⼀⾏中的信息,我们来⼀步⼀步的分析。如下的输出是由 detector.c ⽣成的,具体代码见:
9798: 指⽰当前训练的迭代次数
海口哪里好玩0.370096: 是总体的Loss(损失)
0.451929 avg: 是平均Loss,这个数值应该越低越好,⼀般来说,⼀旦这个数值低于0.060730 avg就可以终⽌训练了。
0.001000 rate: 代表当前的学习率,是在.cfg⽂件中定义的。
3.300000 conds: 表⽰当前批次训练花费的总时间。
627072 images: 这⼀⾏最后的这个数值是9798*64的⼤⼩,表⽰到⽬前为⽌,参与训练的图⽚的总量。
分块输出
在分析分块输出之前,我们得了解⼀下IOU(Interction over Union,也被称为交并集之⽐:),这样就能理解为什么分块输出中的参数是⼀些重要且必须要输出的参数了。
可以看到,IOU(交集⽐并集)是⼀个衡量我们的模型检测特定的⽬标好坏的重要指标。100%表⽰我们拥有了⼀个完美的检测,即我们的矩形框跟⽬标完美重合。很明显,我们需要优化这个参数。
回归正题,我们来分析⼀下这些⽤来描述训练图集中的⼀个批次的训练结果的输出。那些想⾃⼰深⼊
源代码验证我所说的内容的同学注意了,这段代码: 执⾏了以下的输出:
Region Avg IOU: 0.326577: 表⽰在当前subdivision内的图⽚的平均IOU,代表预测的矩形框和真实⽬标的交集与并集之⽐,这⾥是32.66%,这个模型需要进⼀步的训练。
Class: 0.742537: 标注物体分类的正确率,期望该值趋近于1。神形兼备
Obj: 0.033966: 越接近1越好。
No Obj: 0.000793: 期望该值越来越⼩,但不为零。
Avg Recall: 0.12500: 是在recall/count中定义的,是当前模型在所有subdivision图⽚中检测出的正样本与实际的正样本的⽐值。
在本例中,只有⼋分之⼀的正样本被正确的检测到。
count: 8:count后的值是所有的当前subdivision图⽚(本例中⼀共8张)中包含正样本的图⽚的数量。在输出log中的其他⾏中,可
以看到其他subdivision也有的只含有6或7个正样本,说明在subdivision中含有不含检测对象的图⽚。
总结
在这篇短⽂⾥,我们回顾了⼀下YOLOv2在终端输出的不同的参数的含义,这些参数也在告诉我们YOLOv2的训练过程是怎样进⾏的。这个能在⼀定程度上解答⼤家关于YOLOv2的训练输出的⼤部分问题,但请记住,对YOLOv2的探索决不应该到此为⽌。
跟以往⼀样,欢迎⼤家在评论区留⾔,进⼀步讨论关于YOLOv2的相关问题,我也会不断优化改进这篇⽂章,所以,别忘了留⾔评论哦!Yolo v2 训练 NAN解决过程
问题描述
今天在⽤yolo训练⾃⼰的数据集的时候,⼀开始训练过程中的loss还很正常地在下降。结果到了⼏个个batch的地⽅突然就出现loss = nan 的情况。其实到现在⾃⼰也没有发现到底是什么导致了nan,但是参考上⾯这篇⽂章,⾄少暂时解决了这个问题。
解决过程
1)⾸先检查了代码是不是对的。⼀般出现nan,第⼀反应是:会不会哪⾥出现了分母为0,或者log的真值为负数这样的情况。然后在⾃⼰修改过的源码⾥⾯检查了⼀遍,发现并没有出现这个问题。
陈冬2)然后参考上⾯这篇⽂章,检查了⼀下我的数据集有没有问题。⾸先图⽚⾃⼰看过是没有问题的,然后拿另外⼀个模型在这个数据集上跑,也没有问题。因此排除数据集出问题的可能。
3)最后担⼼是不是梯度在某⼀个batch的时候突然爆炸了。因此修改源码detector.c,训练的时候每⼀个batch都打印⼀下当前的loss。发现出现nan之前都会有⼀个batch的loss=inf。因为yolo的loss函数的定义就是均⽅差,因此,loss就等于梯度的平⽅。所以判断应该是某⼀个batch使得梯度突然增⼤。参考caffe的⽅法。设定⼀定的阈值,使得当梯度超过这个阈值的时候,直接设置为该阈值⼤⼩。暂时解决了nan的问题
生蚝肉怎么做好吃1. 下载源码,编译。
2. 运⾏demo:
a ./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
b ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights
c ./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights my.mp4
咋看参数给的很奇怪,仔细研究,example/darknet.c 中的mian函数就了然了。
int main(int argc, char **argv)
五年级下册第一单元作文
{
if(argc < 2){
fprintf(stderr, "usage: %s <function>\n", argv[0]);
return 0;
}
尽孝不能等gpu_index = find_int_arg(argc, argv, "-i", 0);
if(find_arg(argc, argv, "-nogpu")) {
gpu_index = -1;
}
#ifndef GPU
gpu_index = -1;
#el
if(gpu_index >= 0){
cuda_t_device(gpu_index);
}
#endif
if (0 == strcmp(argv[1], "average")){
average(argc, argv);
} el if (0 == strcmp(argv[1], "yolo")){
run_yolo(argc, argv);
} el if (0 == strcmp(argv[1], "super")){
run_super(argc, argv);
} el if (0 == strcmp(argv[1], "lsd")){
run_lsd(argc, argv);
} el if (0 == strcmp(argv[1], "detector")){
run_detector(argc, argv);
} el if (0 == strcmp(argv[1], "detect")){
float thresh = find_float_arg(argc, argv, "-thresh", .5);
char *filename = (argc > 4) ? argv[4]: 0;
char *outfile = find_char_arg(argc, argv, "-out", 0);
int fullscreen = find_arg(argc, argv, "-fullscreen");
test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen);
} el if (0 == strcmp(argv[1], "cifar")){
run_cifar(argc, argv);
...
return 0;
}
给不同的参数,对应跳转到不同的函数执⾏。
3. ⽤作者训练好的通⽤⽬标模型检测效果图:
a. 略
b. 略
可以看到,在简单场景下,通⽤检测检测效果还⾏,但是复杂场景正对特定⽬标,会有⼀些问题(⽐如误检、⼩⽬标⽆法检测等)
4. 训练⾃⼰的数据集,以头肩为例,训练⾃⼰的数据集。
a. ⾸先,利⽤voc_label.py将voc格式的数据转换为训练所需要的数据格式。
b. 训练
./darknet detector train cfg/voc.data cfg/yolov3-voc.v.74
训练出现问题:
Region 82 Avg IOU: 0.259673, Class: 0.593880, Obj: 0.831784, No Obj: 0.515905, .5R: 0.000000, .75R: 0.000000, count: 1
Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.494105, .5R: -nan, .75R: -nan, count: 0
Region 106 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.412357, .5R: -nan, .75R: -nan, count: 0
马龙儿子
1: 579.859924, 579.859924 avg, 0.000000 rate, 0.039695 conds, 1 images
Loaded: 0.008419 conds
Region 82 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.515768, .5R: -nan, .75R: -nan, count: 0
Region 94 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.494756, .5R: -nan, .75R: -nan, count: 0
Region 106 Avg IOU: 0.224065, Class: 0.304794, Obj: 0.247472, No Obj: 0.415191, .5R: 0.000000, .75R: 0.000000, count: 4
2: 594.244812, 581.298401 avg, 0.000000 rate, 0.092844 conds, 2 images
Loaded: 0.000024 conds
输⼊416,anchor聚类:
(29,31),(7,9),(18,30),(44,82),(119,212),(72,110),(28,56),(47,45),(14,17)
于是anchor = 7,9, 14,17, 18,30, 29,31, 28,56, 47,45, 44,82, 72,110, 119,212
时隔很久。。⼜开始训练yolo的代码。yolov2训练成功了,可是yolov3怎么也不成功。。
[net]
# Testing
# batch=1 #注释
# subdivisions=1 #注释
# Training
batch=8
# subdivisions=16
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1
结果把#Testing 后⾯的batch以及subdivisions注释就成功了…
世事洞明皆学问没注释之前,按照batch=1在计算,注释之后,按照batch=8在计算。因为我的训练样本中有很多⼩⽬标,所以batch太⼩是有问题的。唉。。
YOLOV3 COCO数据集训练,Avg: nan
2018年05⽉01⽇ 10:49:57
阅读数:1280
YOLO V3 Region 94 Avg IOU: nan
将Bach_size 修改到128以上。
这个数据是正常的,因为在⼩bach中没有找到object.
改⼤了就可以了