parse_network_cfg_custom函数中,读取配置文件是先把各个section
读取出来,然后再解析。
yolov3.cfg里面只有几个不同的section,分别是[net]、[convolutional]、[shortcut]、[yolo]、[route]、[upsample],下面分别探究。
参考 YOLO配置文件理解
参数名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
Testing | - | - | |
Training | - | - | |
batch | int | 1 | 前向计算梯度和通过反向传导更新权重值的计算中一次处理的图片文件的数量。 |
subdivisions | int | 1 | 批处理被细分为许多“块”。块的图像在gpu上并行运行。在darknet代码中,会将batch/subdivisions命名为batch,这个值设置比batch小往往回出现out out memory的问题。 |
width | int | 416 | 图像的宽,32的倍数 |
height | int | 416 | 图像的高,32的倍数 |
channels | int | 3 | 按照stackflow上的说法,用下图来表述channels=4的情况:在左边,我们有一个4x4像素的单一通道,重组层将大小减小到一半,然后在不同通道中创建4个相邻像素的通道。我认为可能是表示颜色通道。 |
momentum | float | 0.9 | 见 深度学习中momentum的作用 一文的解释 |
decay | float | 0.0005 | 权重衰减正则项,防止过拟合 |
angle | int | 0 | 通过旋转角度来生成更多训练样本 |
saturation | float | 1.5 | 通过调整饱和度来生成更多训练样本 |
exposure | float | 1.5 | 通过调整曝光量来生成更多训练样本 |
hue | float | 0.1 | 通过调整色调来生成更多训练样本 |
learning_rate | float | 0.001 | 初始学习率 |
burn_in | int | 1000 | 对于第首个burn_in批的训练,缓慢地提高学习率,直到它的最终值等于learning_rate设定的值。通过对学习率的监控可以了解到对于Loss函数的收敛的贡献情况 |
max_batches | int | 1000 | 训练达到max_batches后停止学习 |
policy | string | steps | 调整学习率的策略。policy取值:CONSTANT, STEP, EXP, POLY, STEPS, SIG, RANDOM。policy=steps 表示使用下面的steps参数和scales参数来调整训练时的学习速度 |
steps | int array | 1000,2000 | 如取值是1000,2000,则表示在第1000个训练批次和2000个批次后调整learning_rate |
scales | float array | 0.1,0.1 | 在1000个训练批次后,LR = 0.1, 然后在2000个训练批次后LR *= 0.1, 也就是说再执行一次调整 |
参数:
参数名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
batch_normalize | bool | 1 | 是否非规范化这个layer,见函数denormalize_convolutional_layer |
filters | int | 255 | 输出多少个特征图。filters =(classes + 5) x 3 |
size | int | 3 | 卷积核的尺寸 |
stride | int | 1 | 卷积运算的步长 |
pad | bool | 0 | 指定padding的方式 |
padding | int | 0 | padding由 padding参数指定。如果pad为1,padding大小为size/2 |
activation | string | logistic | “logistic”、“loggy”、“relu”、“elu”、“relie”、“plse”、“hardtan”、 “lhtan”、 “linear”、ramp"、“leaky”、“tanh”、"stair"是合法的激活函数值。 |
binary | int | 0 | 暂未见使用,先不管 |
xnor | int | 0 | 暂未见使用,先不管 |
bin_output | int | 0 | 暂未见使用,先不管 |
相应代码段:
int n = option_find_int(options, "filters",1);
int size = option_find_int(options, "size",1);
int stride = option_find_int(options, "stride",1);
int pad = option_find_int_quiet(options, "pad",0);
int padding = option_find_int_quiet(options, "padding",0);
if(pad) padding = size/2;
char *activation_s = option_find_str(options, "activation", "logistic");
int batch_normalize = option_find_int_quiet(options, "batch_normalize", 0);
int binary = option_find_int_quiet(options, "binary", 0);
int xnor = option_find_int_quiet(options, "xnor", 0);
int use_bin_output = option_find_int_quiet(options, "bin_output", 0);
参数:
参数名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
shortcut | int | - | 指向其他layer的索引偏移值,yolov3里面是-3 |
activation | string | - | 激活函数类型,yolov3里面是“linear” |
相应代码段:
layer parse_shortcut(list *options, size_params params, network net)
{
char *l = option_find(options, "from");
int index = atoi(l);
if(index < 0) index = params.index + index;
int batch = params.batch;
layer from = net.layers[index];
layer s = make_shortcut_layer(batch, index, params.w, params.h, params.c, from.out_w, from.out_h, from.out_c);
char *activation_s = option_find_str(options, "activation", "linear");
ACTIVATION activation = get_activation(activation_s);
s.activation = activation;
return s;
}
参数:
参数名称 | 类型 | 默认值 | 说明 |
---|---|---|---|
classes | int | 20 | |
num | int | 1 | |
mask | int | 0 | |
max | int | 90 | |
jitter | float | 0.2 | |
focal_loss | int | 0 | |
ignore_thresh | float | 0.5 | |
truth_thresh | int | 1 | |
random | int | 0 | |
map | string | “” | |
anchors | string | “” |
相应代码段:
layer parse_yolo(list *options, size_params params)
{
int classes = option_find_int(options, "classes", 20);
int total = option_find_int(options, "num", 1);
int num = total;
char *a = option_find_str(options, "mask", 0);
int *mask = parse_yolo_mask(a, &num);
int max_boxes = option_find_int_quiet(options, "max", 90);
layer l = make_yolo_layer(params.batch, params.w, params.h, num, total, mask, classes, max_boxes);
if (l.outputs != params.inputs) {
printf("Error: l.outputs == params.inputs \n");
printf("filters= in the [convolutional]-layer doesn't correspond to classes= or mask= in [yolo]-layer \n");
exit(EXIT_FAILURE);
}
//assert(l.outputs == params.inputs);
//l.max_boxes = option_find_int_quiet(options, "max", 90);
l.jitter = option_find_float(options, "jitter", .2);
l.focal_loss = option_find_int_quiet(options, "focal_loss", 0);
l.ignore_thresh = option_find_float(options, "ignore_thresh", .5);
l.truth_thresh = option_find_float(options, "truth_thresh", 1);
l.random = option_find_int_quiet(options, "random", 0);
char *map_file = option_find_str(options, "map", 0);
if (map_file) l.map = read_map(map_file);
a = option_find_str(options, "anchors", 0);
if (a) {
int len = strlen(a);
int n = 1;
int i;
for (i = 0; i < len; ++i) {
if (a[i] == ',') ++n;
}
for (i = 0; i < n && i < total*2; ++i) {
float bias = atof(a);
l.biases[i] = bias;
a = strchr(a, ',') + 1;
}
}
return l;
}
route layer只有一个参数,layers,指定一个输入的layer。
route_layer parse_route(list *options, size_params params, network net)
{
char *l = option_find(options, "layers");
int len = strlen(l);
if(!l) error("Route Layer must specify input layers");
int n = 1;
int i;
for(i = 0; i < len; ++i){
if (l[i] == ',') ++n;
}
int *layers = calloc(n, sizeof(int));
int *sizes = calloc(n, sizeof(int));
for(i = 0; i < n; ++i){
int index = atoi(l);
l = strchr(l, ',')+1;
if(index < 0) index = params.index + index;
layers[i] = index;
sizes[i] = net.layers[index].outputs;
}
int batch = params.batch;
route_layer layer = make_route_layer(batch, n, layers, sizes);
convolutional_layer first = net.layers[layers[0]];
layer.out_w = first.out_w;
layer.out_h = first.out_h;
layer.out_c = first.out_c;
for(i = 1; i < n; ++i){
int index = layers[i];
convolutional_layer next = net.layers[index];
if(next.out_w == first.out_w && next.out_h == first.out_h){
layer.out_c += next.out_c;
}else{
layer.out_h = layer.out_w = layer.out_c = 0;
}
}
return layer;
}
顾名思义,这个layer是用来做上采样的,只有stride和scale两个参数,代码如下
layer parse_upsample(list *options, size_params params, network net)
{
int stride = option_find_int(options, "stride", 2);
layer l = make_upsample_layer(params.batch, params.w, params.h, params.c, stride);
l.scale = option_find_float_quiet(options, "scale", 1);
return l;
}