YOLO v2 损失函数源码分析

损失函数的定义是在region_layer.c文件中,关于region层使用的参数在cfg文件的最后一个section中定义。

  1. 首先来看一看region_layer 都定义了那些属性值:

layer make_region_layer(int batch, int w, int h, int n, int classes, int coords)
{
    layer l = {0};
    l.type = REGION;

    l.n = n; // anchors 的个数, 文章中选择为5
    l.batch = batch; // batchsize
    l.h = h;
    l.w = w;
    l.c = n*(classes + coords + 1); // 输出的通道数 
    l.out_w = l.w;
    l.out_h = l.h;
    l.out_c = l.c;
    l.classes = classes; // 检测的类别数
    l.coords = coords; 
    l.cost = calloc(1, sizeof(float));
    l.biases = calloc(n*2, sizeof(float));  // anchors的存储位置,一个anchor对应两个值
    l.bias_updates = calloc(n*2, sizeof(float));
    l.outputs = h*w*n*(classes + coords + 1); //输出tensor的存储空间大小 13*13*5*(20+4+1)
    l.inputs = l.outputs;
    l.truths = 30*(l.coords + 1); // ***********注1************
    l.delta = calloc(batch*l.outputs, sizeof(float)); // 批量梯度
    l.output = calloc(batch*l.outputs, sizeof(float));// 批量输出tensor的存储空间
    int i;
    for(i = 0; i < n*2; ++i){
        l.biases[i] = .5;//anchors的默认值设为0.5
    }

    l.forward = forward_region_layer; // 前向计算函数
    l.backward = backward_region_layer;//反向计算函数,这里delta在前向计算函数中获得了,所以该函数为空
#ifdef GPU
    l.forward_gpu = forward_region_layer_gpu;
    l.backward_gpu = backward_region_layer_gpu;
    l.output_gpu = cuda_make_array(l.output, batch*l.outputs);
    l.delta_gpu = cuda_make_array(l.delta, batch*l.outputs);
#endif
    fprintf(stderr, "detection\n");
    srand(0);
    return l;
}
 1 layer parse_region(list *options, size_params params)
 2 {
 3     int coords = option_find_int(options, "coords", 4);
 4     int classes = option_find_int(options, "classes", 20);
 5     int num = option_find_int(options, "num", 1);// 每一个cell对应的anchors个数, 文中num=5
 6 
 7     layer l = make_region_layer(params.batch, params.w, params.h, num, classes, coords);
 8     assert(l.outputs == params.inputs);
 9 
10     l.log = option_find_int_quiet(options, "log", 0); // 是否计算log,这个标志定义了,却未使用
11     l.sqrt = option_find_int_quiet(options, "sqrt", 0); // 输出预测值的w,h是否开方
12 
13     l.softmax = option_find_int(options, "softmax", 0); // 采用softmax分类
14     l.background = option_find_int_quiet(options, "background", 0);
15     l.max_boxes = option_find_int_quiet(options, "max",30); //******** 注2 **************
16     // 图片中最多真实boxes的个数,这个应该和make_region_layer中的30有关
17     l.jitter = option_find_float(options, "jitter", .2);//抖动,cfg中设置为.3
18     l.rescore = option_find_int_quiet(options, "rescore",0); //******** 注3 **************
19 
20     l.thresh = option_find_float(options, "thresh", .5); // .6 大于该值的时候认为包含目标
21     l.classfix = option_find_int_quiet(options, "classfix", 0);
22     l.absolute = option_find_int_quiet(options, "absolute", 0); // 1
23     l.random = option_find_int_quiet(options, "random", 0); // 1
24 
25     l.coord_scale = option_find_float(options, "coord_scale", 1); // 坐标损失的权重,1
26     l.object_scale = option_find_float(options,