本系列为darknet源码解析,本次解析src/detection_layer.h 与 src/detection_layer.c 两个。detection_layer主要完成了yolo v1最后一层7*7*30,是yolo v1这篇论文的核心部分。
detection_layer.h 的定义如下:
#ifndef DETECTION_LAYER_H
#define DETECTION_LAYER_H
#include "layer.h"
#include "network.h"
typedef layer detection_layer;
// 构造detection层
detection_layer make_detection_layer(int batch, int inputs, int n, int size, int classes, int coords, int rescore);
// detection层前向传播函数
void forward_detection_layer(const detection_layer l, network net);
// detection层反向传播函数
void backward_detection_layer(const detection_layer l, network net);
#ifdef GPU
void forward_detection_layer_gpu(const detection_layer l, network net);
void backward_detection_layer_gpu(detection_layer l, network net);
#endif
#endif
detection_layer.c 的详细分析如下:
#include "detection_layer.h"
#include "activations.h"
#include "softmax_layer.h"
#include "blas.h"
#include "box.h"
#include "cuda.h"
#include "utils.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
/**
* 构建detection层,yolov1中最后一层
* @param batch 一个batch包含图片的张数
* @param inputs detection层一张输入图片元素个数
* @param n yolov1一个grid cell预测bbox的数量 2
* @param side // grid cell的大小 7
* @param classes yolov1 预测类的个数
* @param coords 一个bbox包含的坐标数量 4
* @param rescore
* @return
*/
detection_layer make_detection_layer(int batch, int inputs, int n, int side, int classes, int coords, int rescore)
{
detection_layer l = {0};
l.type = DETECTION; // 层类别
l.n = n; // 一个grid cell预测bbox的数量,在yolov1 n = 2
l.batch = batch; // 一个batch包含图片的张数
l.inputs = inputs; // detection层一张输入图片元素个数
l.classes = classes; // yolov1 预测类别数, 在yolov1 classes=20
l.coords = coords; // [x, y, w, h] bbox包含的点个数, 在yolov1 coords=4
l.rescore = rescore; //
l.side = side; // grid cell 大小
l.w = side; // grid cell的宽度
l.h = side; // grid cell的高度
assert(side*side*((1 + l.coords)*l.n + l.classes) == inputs); // 7*7*(1 + 4) * 2 + 30 ) = 7*7*30
l.cost = calloc(1, sizeof(float)); // detection层的总损失
l.outputs = l.inputs; // detection层对应输入图片的输出元素个数,detection层不改变输入输出大小
l.truths = l.side*l.side*(1+l.coords+l.classes); // GT:7*7*(1+4+20) 只有一个bbox和置信度
l.output = calloc(batch*l.outputs, sizeof(float)); // detection层所有输出(包含整个batch的)
l.delta = calloc(batch*l.outputs, sizeof(float)); // detection层误差项(包含整个batch的)
l.forward = forward_detection_layer; // detection层前向传播
l.backward = backward_detection_layer; // detection层反向传播
#ifdef GPU
l.forward_gpu = forward_detection_layer_gpu;
l.backward_gpu = backward_detection_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 Layer\n");
srand(