darknet 源码学习

darknet

box.c

  • x=x+1,x+=1,x++的区别

  • (a>b)?y:n 如果A大于B,那么选择Y的结果,如果A小于B,那么选择N的结果。

  • 计算两个矩形框相交部分矩形的某一边的边长(视调用情况,可能是相交部分矩形的高,也可能是宽)。
    x1  第一个矩形框的x坐标(或者y坐标,视调用情况,如果计算的是相交部分矩形的宽,则输入的是x坐标)
    w1  第一个矩形框的宽(而如果要计算相交部分矩形的高,则为y坐标,下面凡是说x坐标的,都可能为y坐标,当然,对应宽变为高)
    x2  第二个矩形框的x坐标
    w2  第二个矩形框的宽
      首先计算两个框左边的x坐标,比较大小,取其大者,记为left;而后计算两个框右边的x坐标,取其小者,记为right,right-left即得相交部分矩形的宽。两个矩形框相交部分矩形的宽或者高。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    float overlap(float x1, float w1, float x2, float w2)
    {
    float l1 = x1 - w1/2;
    float l2 = x2 - w2/2;
    float left = l1 > l2 ? l1 : l2;
    float r1 = x1 + w1/2;
    float r2 = x2 + w2/2;
    float right = r1 < r2 ? r1 : r2;
    return right - left;
    }

  • 计算IoU值,是目标检测精确度的一个评判指标,全称是intersection over union,翻译成中文就是交比并值,字面上的意思很直接,就是两个矩形相交部分的面积比两个矩形求并之后的总面积,用来做检测评判指标时,含义为模型检测到的矩形框与GroundTruth标记的矩形框之间的交比并值(即可反映检测到的矩形框与GroundTruth之间的重叠度),当两个矩形框完全重叠时,值为1;完全不相交时,值为0。

    1
    2
    3
    4
    5
    6
    7
    8
    float box_intersection(box a, box b)
    {
    float w = overlap(a.x, a.w, b.x, b.w);
    float h = overlap(a.y, a.h, b.y, b.h);
    if(w < 0 || h < 0) return 0;
    float area = w*h;
    return area;
    }

  • pow(float x, float y)函数:计算x的y次幂

 

blas.c

  • 方差的无偏估计 (样本方差) \(\frac{1}{n-1} \sum_{i=1}^{n}\left(X_{i}-\bar{X}\right)^{2}\),你会发现样本均值这一项都包含在内。考虑到方差是衡量数据偏差程度的统计量,计算一下样本均值作为中间步骤的中间量,也不失其合理性。于是,为计算样本方差,样本里原有的 n个自由度,有一个自由度被分配给计算样本均值,剩下自由度即为n-1 。
  • axpy是线性代数中一种基本操作,完成y= alpha*x + y操作,其中x,y为矢量,alpha为实数系数
  • 计算预测数组与真实标签数组中每对元素的l2范数值,或者说是计算squared error,注意此函数,并没有求和,没有将所有误差加起来,而是对网络输出的每个元素计算误差的平方值。
    n  输出元素个数,也即pred中的元素个数,也是truth中的元素个数; pred   网络最终的输出值,或者说网络的预测值,其中输出元素个数为n(也即最后一层网络神经元个数为n)
    truth   真实标签值,其中元素个数为n(也即最后一层网络神经元个数为n) delta   相当于本函数的输出,为网络的敏感度图(一般为cost_layer.c的敏感度图)
    error   相当于本函数的输出,包含每个输出元素的squared error
1
2
3
4
5
6
7
8
9
void l2_cpu(int n, float *pred, float *truth, float *delta, float *error)
{
int i;
for(i = 0; i < n; ++i){
float diff = truth[i] - pred[i];
error[i] = diff * diff;
delta[i] = diff;
}
}
  • softmax
    input   一组输入图片数据(含义见下面softmax_cpu()注释,下同)
    n   一组输入数据中含有的元素个数n=l.inputs/l.groups
    temp   温度参数,关于softmax的温度参数,softmax with temperature
    stride   跨度
    output   这一组输入图片数据对应的输出(也即l.output中与这一组输入对应的某一部分)
      本函数实现的就是标准的softmax函数处理,唯一有点变化的就是在做指数运算之前,将每个输入元素减去了该组输入元素中的最大值,以增加数值稳定性,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    void softmax(float *input, int n, float temp, int stride, float *output)
    {
    int i;
    float sum = 0;
    // 赋初始最大值为float中的最小值-FLT_MAX(定义在float.h中)
    float largest = -FLT_MAX;
    // 寻找输入中的最大值,至于为什么要找出最大值,是为了数值计算上的稳定,详细请戳:http://freemind.pluskid.org/machine-learning/softmax-vs-softmax-loss-numerical-stability/
    // 这篇博客写的不错,博客在接近尾声的时候,提到了为什么要减去输入中的最大值。
    for(i = 0; i < n; ++i){
    if(input[i*stride] > largest) largest = input[i*stride];
    }
    for(i = 0; i < n; ++i){
    // 在进行指数运算之间,如上面博客所说,首先减去最大值(当然温度参数也要除)
    float e = exp(input[i*stride]/temp - largest/temp);
    sum += e; // 求和
    output[i*stride] = e; // 并将每一个输入的结果保存在相应的输出中
    }
    // 最后一步:归一化转换为概率(就是softmax函数的原型~),最后的输出结果保存在output中
    for(i = 0; i < n; ++i){
    output[i*stride] /= sum;
    }
    }

  • 赋值运算符

  • softmax

 

 

参考