yolo_layer.c解析

本文深入解析YOLOv3框架中的yolo_layer.c文件,重点探讨该文件如何实现损失函数,包括定位损失和类别损失。通过对l.delta数组中各损失的平方和计算,最终得到总损失并存储于l.loss中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 YOLOv3中的yolo_layer.c文件

这个文件实现了YOLOv3使用的损失函数,如果你想优化损失函数部分,绕不开它的。

损失函数包含两部分:定位损失(tx,ty,tw,th)和类别损失(c,C1,C2,C3...)。l.delta是一个一维数组指针,用来存储各种损失,计算完所有的损失后,平方和这些损失得到一个浮点数值,然后存储到l.loss中。l.loss是一个指向浮点型数值的指针。

#include "yolo_layer.h"
#include "activations.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>
//原文地址:https://blog.youkuaiyun.com/qq_33614902/article/details/85063287
layer make_yolo_layer(int batch, int w, int h, int n, int total, int *mask, int classes)
{
    int i;
    layer l = {0};
    l.type = YOLO;

    l.n = n;//每个cell提出n个boxes  
    l.total = total;//anchor的个数???(不确定诶)
    l.batch = batch;//每个batch中含有的图片数
    l.h = h;
    l.w = w;
    l.c = n*(classes + 4 + 1);//3*(80+4+1)
    l.out_w = l.w;
    l.out_h = l.h;
    l.out_c = l.c;
    l.classes = classes;//训练时的物体类别总数
    l.cost = calloc(1, sizeof(float));//指向float型的指针,大小为1,只能存储一个float类型的数值
    l.biases = calloc(total*2, sizeof(float));//保存先验框的宽度和高度,所以乘2
    if(mask) l.mask = mask;//mask和用到第几个先验框有关,取值为0-9。比如,mask_n=1,先验框的宽和高是(biases[2*mask_n],biases[2*mask_n+1])
    else{
        l.mask = calloc(n, sizeof(int));
        for(i = 0; i < n; ++i){
            l.mask[i] = i;
        }
    }
    l.bias_updates = calloc(n*2, sizeof(float));
    l.outputs = h*w*n*(classes + 4 + 1);//检测器对一张图片预测的所有参数。h*w为cell的个数,n表示每个cell对应n的pre boxes
    l.inputs = l.outputs;
    l.truths = 90*(4 + 1);//每张图片含有的GT参数的个数,90表示一张图片最多有90个GT
    l.delta = calloc(batch*l.outputs, sizeof(float));
    l.output = calloc(batch*l.outputs, sizeof(float));
    for(i = 0; i < total*2; ++i){
        l.biases[i] = .5;
    }

    l.forward = forward_yolo_layer;
    l.backward = backward_yolo_layer;
#ifdef GPU
    l.forward_gpu = forward_yolo_layer_gpu;
    l.backward_gpu = backward_yolo_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, "yolo\n");
    srand(0);

    return l;
}

void resize_yolo_layer(layer *l, int w, int h)
{
    l->w = w;
    l->h = h;

    l->outputs = h*w*l->n*(l->classes + 4 + 1);
    l->inputs = l->outputs;

    l->output = realloc(l->output, l->batch*l->outputs*sizeof(float));
    l->delta = realloc(l->delta, l->batch*l->outputs*sizeof(float));

#ifdef GPU
    cuda_free(l->delta_gpu);
    cuda_free(l->output_gpu);

    l->delta_gpu =     cuda_make_array(l->delta, l->batch*l->outputs);
    l->output_gpu =    cuda_make_array(l->output, l->batch*l->outputs);
#endif
}

// box pred = get_yolo_box(l.output, l.biases, l.mask[n], box_index, i, j, l.w, l.h, net.w, net.h, l.w*l.h);
box get_yolo_box(float *x, float *biases, int n, int index, int i, int j, int lw, int lh, int w, int h, int stride)
{
    //i,j表示cell的位置(相当于公式中的cx,cy),biases是先验框的宽和高,返回的box是比例值(都除以了w,h)。具体公式见YOLOv3中2.1部分。
    //l.output中存储的tx,ty是cell内的相对距离,大小为[0,1]
    //这里告诉我们,我们的网络不是直接预测出来的回归框,而是预测的(tx,ty,tw,th),然后再用此公式转换。
    box b
需要学习Windows系统YOLOv4的同学请前往《Windows版YOLOv4目标检测实战:原理与源码解析》,课程链接 https://edu.csdn.net/course/detail/29865【为什么要学习这门课】 Linux创始人Linus Torvalds有一句名言:Talk is cheap. Show me the code. 冗谈不够,放码过来!  代码阅读是从基础到提高的必由之路。尤其对深度学习,许多框架隐藏了神经网络底层的实现,只能在上层调包使用,对其内部原理很难认识清晰,不利于进一步优化和创新。YOLOv4是最近推出的基于深度学习的端到端实时目标检测方法。YOLOv4的实现darknet是使用C语言开发的轻型开源深度学习框架,依赖少,可移植性好,可以作为很好的代码阅读案例,让我们深入探究其实现原理。【课程内容与收获】 本课程将解析YOLOv4的实现原理和源码,具体内容包括:- YOLOv4目标检测原理- 神经网络及darknet的C语言实现,尤其是反向传播的梯度求解和误差计算- 代码阅读工具及方法- 深度学习计算的利器:BLAS和GEMM- GPU的CUDA编程方法及在darknet的应用- YOLOv4的程序流程- YOLOv4各层及关键技术的源码解析本课程将提供注释后的darknet的源码程序文件。【相关课程】 除本课程《YOLOv4目标检测:原理与源码解析》外,本人推出了有关YOLOv4目标检测的系列课程,包括:《YOLOv4目标检测实战:训练自己的数据集》《YOLOv4-tiny目标检测实战:训练自己的数据集》《YOLOv4目标检测实战:人脸口罩佩戴检测》《YOLOv4目标检测实战:中国交通标志识别》建议先学习一门YOLOv4实战课程,对YOLOv4的使用方法了解以后再学习本课程。【YOLOv4网络模型架构图】 下图由白勇老师绘制  
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值