YOLO配置文件理解

http://www.infocool.net/kb/WWW/201703/317548.html


 
 
  1. [ net]
  2. batch= 64 每batch个样本更新一次参数。
  3. subdivisions= 8 如果内存不够大,将batch分割为subdivisions个子batch,每个子batch的大小为batch/subdivisions。
  4. 在darknet代码中,会将batch/subdivisions命名为batch。
  5. height= 416 input图像的高
  6. width= 416 Input图像的宽
  7. channels= 3 Input图像的通道数
  8. momentum= 0.9 动量
  9. decay= 0.0005 权重衰减正则项,防止过拟合
  10. angle= 0 通过旋转角度来生成更多训练样本
  11. saturation = 1.5 通过调整饱和度来生成更多训练样本
  12. exposure = 1.5 通过调整曝光量来生成更多训练样本
  13. hue= .1 通过调整色调来生成更多训练样本
  14. learning_rate= 0.0001 初始学习率
  15. max_batches = 45000 训练达到max_batches后停止学习
  16. policy=steps 调整学习率的policy,有如下policy:CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM
  17. steps= 100, 25000, 35000 根据batch_num调整学习率
  18. scales= 10, .1, .1 学习率变化的比例,累计相乘
  19. [ convolutional]
  20. batch_normalize= 1 是否做BN
  21. filters= 32 输出多少个特征图
  22. size= 3 卷积核的尺寸
  23. stride= 1 做卷积运算的步长
  24. pad= 1 如果pad为 0,padding由 padding参数指定。如果pad为 1,padding大小为size/ 2
  25. activation=leaky 激活函数:
  26. logistic,loggy,relu,elu,relie,plse,hardtan,lhtan,linear,ramp,leaky,tanh,stair
  27. [ maxpool]
  28. size= 2 池化层尺寸
  29. stride= 2 池化步进
  30. [ convolutional]
  31. batch_normalize= 1
  32. filters= 64
  33. size= 3
  34. stride= 1
  35. pad= 1
  36. activation=leaky
  37. [ maxpool]
  38. size= 2
  39. stride= 2
  40. ......
  41. ......
  42. #######
  43. [ convolutional]
  44. batch_normalize= 1
  45. size= 3
  46. stride= 1
  47. pad= 1
  48. filters= 1024
  49. activation=leaky
  50. [ convolutional]
  51. batch_normalize= 1
  52. size= 3
  53. stride= 1
  54. pad= 1
  55. filters= 1024
  56. activation=leaky
  57. [ route] the route layer is to bring finer grained features in from earlier in the network
  58. layers= -9
  59. [ reorg] the reorg layer is to make these features match the feature map size at the later layer.
  60. The end feature map is 13x13, the feature map from earlier is 26x26x512.
  61. The reorg layer maps the 26x26x512 feature map onto a 13x13x2048 feature map
  62. so that it can be concatenated with the feature maps at 13x13 resolution.
  63. stride= 2
  64. [ route]
  65. layers= -1, -3
  66. [ convolutional]
  67. batch_normalize= 1
  68. size= 3
  69. stride= 1
  70. pad= 1
  71. filters= 1024
  72. activation=leaky
  73. [ convolutional]
  74. size= 1
  75. stride= 1
  76. pad= 1
  77. filters= 125 region前最后一个卷积层的filters数是特定的,计算公式为filter=num*(classes+ 5)
  78. 5的意义是 5个坐标,论文中的tx,ty,tw,th,to
  79. activation=linear
  80. [ region]
  81. anchors = 1.08, 1.19, 3.42, 4.41, 6.63, 11.38, 9.42, 5.11, 16.62, 10.52 预选框,可以手工挑选,
  82. 也可以通过k means 从训练样本中学出
  83. bias_match= 1
  84. classes= 20 网络需要识别的物体种类数
  85. coords= 4 每个box的 4个坐标tx,ty,tw,th
  86. num= 5 每个grid cell预测几个box
  87. softmax= 1 使用softmax做激活函数
  88. jitter= .2 通过抖动增加噪声来抑制过拟合
  89. rescore= 1 暂理解为一个开关,非 0时通过重打分来调整l.delta(预测值与真实值的差)
  90. object_scale= 5 暂理解为计算损失时预测框中有物体时的权重
  91. noobject_scale= 1 暂理解为计算损失时预测框中无物体时的权重
  92. class_scale= 1 暂理解为计算类别损失时的权重
  93. coord_scale= 1 暂理解为计算损失时坐标偏差的权重
  94. absolute= 1
  95. thresh = .6
  96. random= 0 是否随机确定最后一个预测框

darknet对应代码

找到cfg文件解析的代码,选择detector demo 作为入口

darknet.c文件 main 函数开始


 
 
  1. } else if ( 0 == strcmp(argv[ 1], "detector")){
  2. run_detector(argc, argv);

Detector.c文件 run_detector函数


 
 
  1. char *prefix = find_char_arg(argc, argv, "-prefix", 0);
  2. float thresh = find_float_arg(argc, argv, "-thresh", .24);
  3. float hier_thresh = find_float_arg(argc, argv, "-hier", .5);
  4. int cam_index = find_int_arg(argc, argv, "-c", 0);
  5. int frame_skip = find_int_arg(argc, argv, "-s", 0);
  6. if(argc < 4){
  7. fprintf( stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[ 0], argv[ 1]);
  8. return;
  9. }
  10. char *gpu_list = find_char_arg(argc, argv, "-gpus", 0);
  11. char *outfile = find_char_arg(argc, argv, "-out", 0);
  12. ......
  13. ......
  14. else if( 0== strcmp(argv[ 2], "demo")) {
  15. list *options = read_data_cfg(datacfg);
  16. int classes = option_find_int(options, "classes", 20);
  17. char *name_list = option_find_str(options, "names", "data/names.list");
  18. char **names = get_labels(name_list);
  19. demo(cfg, weights, thresh, cam_index, filename, names, classes, frame_skip, prefix, hier_thresh);
  20. }

read_data_cfg函数解析配置文件,保存到options指针。

class

int classes = option_find_int(options, "classes", 20);

 
 

classes为YOLO可识别的种类数

batch、learning_rate、momentum、decay和 subdivisions

demo.c文件demo函数

net = parse_network_cfg(cfgfile);

 
 

Parser.c文件 parse_network_cfg函数


 
 
  1. list *sections = read_cfg(filename);
  2. node *n = sections->front;
  3. if(!n) error( "Config file has no sections");
  4. network net = make_network(sections->size - 1);
  5. net.gpu_index = gpu_index;
  6. size_params params;
  7. section *s = (section *)n->val;
  8. list *options = s->options;
  9. if(!is_network(s)) error( "First section must be [net] or [network]");
  10. parse_net_options(options, &net);

parse_net_options函数


 
 
  1. net->batch = option_find_int(options, "batch", 1);
  2. net->learning_rate = option_find_float(options, "learning_rate", .001);
  3. net->momentum = option_find_float(options, "momentum", .9);
  4. net->decay = option_find_float(options, "decay", .0001);
  5. int subdivs = option_find_int(options, "subdivisions", 1);
  6. net->time_steps = option_find_int_quiet(options, "time_steps", 1);
  7. net->batch /= subdivs;
  8. net->batch *= net->time_steps;
  9. net->subdivisions = subdivs;

learning_rate为初始学习率,训练时的真正学习率和学习率的策略及初始学习率有关。

momentum为动量,在训练时加入动量可以帮助走出local minima 以及saddle point。

decay是权重衰减正则项,用来防止过拟合。

batch的值等于cfg文件中的batch/subdivisions 再乘以time_steps。
time_steps在yolo默认的cfg中是没有配置的,所以是默认值1。
因此batch可以认为就是cfg文件中的batch/subdivisions。

前面有提到batch的意义是每batch个样本更新一次参数。

而subdivisions的意义在于降低对GPU memory的要求。
darknet将batch分割为subdivisions个子batch,每个子batch的大小为batch/subdivisions,并将子batch命名为batch。

我们看下训练时和batch有关的代码

Detector.c文件的train_detector函数


 
 
  1. #ifdef GPU
  2. if(ngpus == 1){
  3. loss = train_network(net, train);
  4. } else {
  5. loss = train_networks(nets, ngpus, train, 4);
  6. }
  7. #else
  8. loss = train_network(net, train);
  9. #endif

Network.c文件的train_network函数


 
 
  1. int batch = net.batch;
  2. int n = d.X.rows / batch;
  3. float *X = calloc(batch*d.X.cols, sizeof( float));
  4. float *y = calloc(batch*d.y.cols, sizeof( float));
  5. int i;
  6. float sum = 0;
  7. for(i = 0; i < n; ++i){
  8. get_next_batch(d, batch, i*batch, X, y);
  9. float err = train_network_datum(net, X, y);
  10. sum += err;
  11. }

train_network_datum函数


 
 
  1. *net.seen += net.batch;
  2. ......
  3. ......
  4. forward_network(net, state);
  5. backward_network(net, state);
  6. float error = get_network_cost(net);
  7. if(((*net.seen)/net.batch)%net.subdivisions == 0) update_network(net);

我们看到,只有((*net.seen)/net.batch)%net.subdivisions == 0时才会更新网络参数。
*net.seen是已经训练过的子batch数,((*net.seen)/net.batch)%net.subdivisions的意义正是已经训练过了多少个真正的batch。

policy、steps和scales

Parser.c文件 parse_network_cfg函数


 
 
  1. char *policy_s = option_find_str(options, "policy", "constant");
  2. net->policy = get_policy(policy_s);
  3. net->burn_in = option_find_int_quiet(options, "burn_in", 0);
  4. if(net->policy == STEP){
  5. net->step = option_find_int(options, "step", 1);
  6. net->scale = option_find_float(options, "scale", 1);
  7. } else if (net->policy == STEPS){
  8. char *l = option_find(options, "steps");
  9. char *p = option_find(options, "scales");
  10. if(!l || !p) error( "STEPS policy must have steps and scales in cfg file");
  11. int len = strlen(l);
  12. int n = 1;
  13. int i;
  14. for(i = 0; i < len; ++i){
  15. if (l[i] == ',') ++n;
  16. }
  17. int *steps = calloc(n, sizeof( int));
  18. float *scales = calloc(n, sizeof( float));
  19. for(i = 0; i < n; ++i){
  20. int step = atoi(l);
  21. float scale = atof(p);
  22. l = strchr(l, ',')+ 1;
  23. p = strchr(p, ',')+ 1;
  24. steps[i] = step;
  25. scales[i] = scale;
  26. }
  27. net->scales = scales;
  28. net->steps = steps;
  29. net->num_steps = n;
  30. } else if (net->policy == EXP){
  31. net->gamma = option_find_float(options, "gamma", 1);
  32. } else if (net->policy == SIG){
  33. net->gamma = option_find_float(options, "gamma", 1);
  34. net->step = option_find_int(options, "step", 1);
  35. } else if (net->policy == POLY || net->policy == RANDOM){
  36. net->power = option_find_float(options, "power", 1);
  37. }

get_policy函数


 
 
  1. if ( strcmp(s, "random")== 0) return RANDOM;
  2. if ( strcmp(s, "poly")== 0) return POLY;
  3. if ( strcmp(s, "constant")== 0) return CONSTANT;
  4. if ( strcmp(s, "step")== 0) return STEP;
  5. if ( strcmp(s, "exp")== 0) return EXP;
  6. if ( strcmp(s, "sigmoid")== 0) return SIG;
  7. if ( strcmp(s, "steps")== 0) return STEPS;
  8. fprintf( stderr, "Couldn't find policy %s, going with constant\n", s);
  9. return CONSTANT;

学习率动态调整的策略有多种,YOLO默认使用的是steps。

yolo-voc.cfg文件:

steps=100,25000,35000

scales=10,.1,.1

Network.c文件get_current_rate函数


 
 
  1. int batch_num = get_current_batch(net);
  2. int i;
  3. float rate;
  4. switch (net.policy) {
  5. case CONSTANT:
  6. return net.learning_rate;
  7. case STEP:
  8. return net.learning_rate * pow(net.scale, batch_num/net.step);
  9. case STEPS:
  10. rate = net.learning_rate;
  11. for(i = 0; i < net.num_steps; ++i){
  12. if(net.steps[i] > batch_num) return rate;
  13. rate *= net.scales[i];
  14. //if(net.steps[i] > batch_num - 1 && net.scales[i] > 1) reset_momentum(net);
  15. }
  16. return rate;

get_current_batch获取的是(*net.seen)/(net.batch*net.subdivisions),即真正的batch。

steps的每个阶段是根据batch_num划分的,根据配置文件,学习率会在batch_num达到100、25000、35000时发生改变。

当前的学习率是初始学习率与当前阶段及之前所有阶段对应的scale的总乘积。

convolutional超参数加载

Parser.c文件parse_network_cfg函数


 
 
  1. LAYER_TYPE lt = string_to_layer_type( s->type);
  2. if( lt == CONVOLUTIONAL){
  3. l = parse_convolutional(options, params);

parse_convolutional函数


 
 
  1. int n = option_find_int(options, "filters", 1);
  2. int size = option_find_int(options, "size", 1);
  3. int stride = option_find_int(options, "stride", 1);
  4. int pad = option_find_int_quiet(options, "pad", 0);
  5. int padding = option_find_int_quiet(options, "padding", 0);
  6. if(pad) padding = size/ 2;
  7. char *activation_s = option_find_str(options, "activation", "logistic");
  8. ACTIVATION activation = get_activation(activation_s);
  9. int batch,h,w,c;
  10. h = params.h;
  11. w = params.w;
  12. c = params.c;
  13. batch= params.batch;
  14. if(!(h && w && c)) error( "Layer before convolutional layer must output image.");
  15. int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0);

需要注意的是如果enable了pad,cfg文件中的padding不会生效,实际的padding值为size/2。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: YOLO(You Only Look Once)是一种流行的目标检测算法,可以有效地识别图像或视频中的物体。在训练YOLO模型时,需要使用.json文件来标记训练集中的目标物体的位置和类别。 首先,我们需要为每个训练图像创建一个对应的.json文件。这个文件包含了图像中每个目标物体的位置信息和类别标签。位置信息通常以矩形框来表示,需要标注物体的左上角和右下角的坐标。类别标签通常是一个整数值,用于表示物体的类别。 在标记图像时,可以使用各种图像标注工具,例如LabelImg或VGG Image Annotator。标注完成后,保存标注信息为.json文件。该文件通常包含一个列表,每个元素表示一个目标物体,包括位置信息和类别标签。 接下来,我们需要准备一个描述数据集的.json文件,通常命名为train.json或val.json。这个文件列出了训练集或验证集中所有图像的文件名、路径和对应的.json文件。 训练YOLO模型时,通常需要将数据集分为训练集和验证集。可以使用train.json和val.json文件来指定训练和验证使用的图像。这样,模型可以在训练过程中根据验证集的性能进行调整。 最后,我们可以使用标记好的.json文件来训练YOLO模型。可以使用各种深度学习框架,如TensorFlow或PyTorch,加载.json文件中的标注信息,并将其转换为模型能够理解的格式。 总而言之,训练YOLO模型的.json文件是为图像数据集中的目标物体提供位置和类别信息的文件。通过创建正确的.json文件,可以有效地训练目标检测模型,并用于识别图像或视频中的物体。 ### 回答2: YOLO(You Only Look Once)是一种流行的目标检测算法,可以用于识别图像或视频中的物体。在训练YOLO模型时,我们需要使用JSON文件来标记图像中出现的物体及其位置。 首先,我们需要收集一组用于训练的图像,这些图像应包含我们感兴趣的目标物体。接下来,我们需要使用标注工具手动标记每个目标物体的位置。常用的标注工具有labelImg等。 在完成图像标注后,我们需要将标注结果保存为JSON格式的文件。JSON文件中的每一行表示一个图像及其对应的目标物体。每个目标物体由以下信息组成:类别(物体的类型,如人、车、狗)、边界框坐标(物体的边界框在图像中的位置)。 标注一个目标物体的JSON示例: { "image_id": "image1.jpg", "bbox": [x, y, width, height], "category_id": category } 在上述示例中,"image_id"表示图像的文件名,"bbox"表示物体的边界框坐标,"category_id"表示物体的类别。 最后,我们将所有图像的标注信息整合到一个JSON文件中,以供YOLO模型训练使用。通常,每个图像对应一个标注信息。 在训练YOLO模型时,我们使用这个JSON文件作为训练数据,将其与YOLO的训练代码结合起来。训练过程中,YOLO模型将学习从图像中提取特征和检测目标物体的能力。通过不断迭代的训练,YOLO模型将逐渐提高目标检测的准确性。 总之,训练YOLO模型的JSON文件包含图像的文件名、目标物体的边界框位置和类别信息。通过手动标注图像,我们可以生成这样的JSON文件,用于YOLO模型的训练。 ### 回答3: YOLO(You Only Look Once)是一种用于目标检测的算法,可以通过训练自定义的JSON文件来教会YOLO识别特定的目标类别。 首先,我们需要收集包含目标类别的图像数据集。数据集应该包含各种场景和角度下的目标图像,并涵盖我们想要训练的所有类别。然后,我们需要为每个目标类别创建一个标注文件。 标注文件通常以JSON(JavaScript对象表示)的格式存在,每个图像对应一个JSON文件。在JSON文件中,我们为每个目标提供了以下信息:类别名称、目标的矩形框坐标(左上角和右下角坐标)以及目标在图像中的可见性。 接下来,我们可以使用YOLO的训练工具来训练模型。在训练之前,我们需要设置训练参数,如学习率、迭代次数等。我们还需要提供一个包含目标类别名称的配置文件,该文件将与训练工具一起使用。 训练开始后,YOLO会根据提供的图像和标注文件来学习目标类别的特征。训练过程中,YOLO会不断调整模型的权重,以最大化目标检测的准确性。 完成训练后,我们可以使用YOLO的测试工具来评估模型在新图像上的性能。我们可以将测试结果保存为JSON文件,其中包含每个检测到的目标的类别、置信度以及矩形框坐标。 总之,通过训练基于JSON文件的YOLO模型,我们可以让它识别和定位我们感兴趣的目标类别。这种方法非常灵活,可以适应不同的目标类别和应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值