YOLO系列正传(三)神经网络的反向传播(back propagation)与公式推导

系列文章

YOLO系列基础

YOLO系列基础合集——小白也看得懂的论文精解-CSDN博客

YOLO系列正传

YOLO系列正传(一)类别损失与MSE损失函数、交叉熵损失函数-CSDN博客

YOLO系列正传(二)YOLOv3论文精解(上)——从FPN到darknet-53-CSDN博客

YOLO系列正传(三)神经网络的反向传播(back propagation)与公式推导-CSDN博客

YOLO系列正传(四)YOLOv3论文精解(下)——损失函数推导与其他优化项-CSDN博客


目录

系列文章

YOLO系列基础

YOLO系列正传

背景

从普通神经网络的基础结构开始讲起

反向传播的高层级理解

损失函数计算

第一层反向传播公式推导:w1

1. 偏导数求解

2. w1参数更新

第二层反向传播公式推导:w3

1. 偏导函数求解

2. w3参数更新

MSE&sigmoid神经网络w参数更新公式普世规律推演

交叉熵&sigmoid反向推导公式

损失函数计算

第一层反向传播公式推导:w1 

1. 偏导数求解

2. w1参数更新

 第二层反向传播公式推导:w3

1. 偏导数求解

2. w3参数更新

交叉熵&sigmoid神经网络w参数更新公式普世规律推演


 

背景

        随着YOLOv11版本的发布,YOLO算法在视觉检测领域独领风骚,本系列旨在从小白出发,给大家讲解清楚视觉检测算法的前世今生,并讲清楚YOLOv11版本算法的所有模块功能!

        在YOLO系列基础中,我们对所有的基础知识进行了讲解和说明。

        在私信反馈中,发现有些读者针对反向传播的原理不甚了解,所以我们今天我们针对神经网络的正向与反向传播的原理进行详解。求赞!!

从普通神经网络的基础结构开始讲起

 以下是神经网络的经典结构,包括一个输入层,两个隐藏层和一个输出层。

其中

f(x)=WX+b=\sum_{i=1}^{n}w_ix_i+b,n为该神经元左侧进入线的数量

\sigma(x)=\frac{1}{1+e^{f(x)}} 

反向传播的高层级理解

老规矩我们从反向传播的高层级理解开始说起。

所谓反向传播,其最终目的是将Loss的数值不断降低。

也就是说,假设我们的损失函数要是一个凸函数,有且只有一个局部最小值。那么很简单,我们只需要对此函数求导并使得导函数为零我们就能解出最小的loss所需要的参数w和b。

注意:我们更新的参数是f(x)中的w和b!

令人兴奋的事情是我们损失函数刚好是一个凸函数,如下: 

所以我们直接计算损失函数对各个w的偏导然后等于0,再然后求解最佳w不就结束了吗? 

这样的办法有一个专业名词叫做:解析解,也就是通过数学公式直接解出参数。这对于一些小型单层网络往往是可行的,但是无法适用于大型网络。

这是因为我们在求解某一层的w的解析解的时候,我们有一个前提,那就是前一层的输入不变。这就直接导致了在多层神经网络的场景下根本无法直接使用解析解的方式求解参数值。

但是这个思想我们可以借鉴,那就是loss下降的方向一定是偏导数下降的方向。我们只需要逐步慢慢靠近偏导数指向的方向,我们就能将模型慢慢拟合到我们期望的方向!

也就是说,针对每一个w_i,更新公式如下:

w_{new}=w-\eta \frac{\partial Loss}{\partial w} 

其中

\eta为步长,也叫学习率

损失函数计算

最简单的神经网络使用最简单的损失函数计算公式:MSE均方差

由于我们的y只有两个,所以loss计算公式如下:

Loss=\frac{1}{2}\sum_{i=1}^2(y_i-\hat{y_i})^2

第一层反向传播公式推导:w1

首先,我们反向传播公式如下:

w_{new1}=w_{1}-\eta \frac{\partial Loss}{\partial w_1}

1. 偏导数求解

\frac{\partial Loss}{\partial w_1} =\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial w_1}

各个部分分解如下:

\frac{\partial Loss}{\partial y_1}=\frac{\frac{1}{2}\sum_{i=1}^2(y_i-\hat{y_i})^2}{y_1}=y_1

\frac{\partial y_1}{\partial f(x)}=\frac{\partial \frac{1}{1+e^{-f(x)}}}{\partial f(x)}=\frac{e^{f(x)}}{(1+e^{-f(x)})^2}= \frac{1}{1+e^{-f(x)}}(1- \frac{1}{1+e^{-f(x)}})=y_1(1-y_1)

\frac{\partial f(x)}{\partial w_1}=\frac{\partial \sum_{i=1}^{n}w_ix_i+b}{\partial w_1}=out_{N1}

注:y1=σ(f(x))

其中out_{N1}为上图中N1神经元的输出,也是式子中xi的一员。

综上

\frac{\partial Loss}{\partial w_1} =\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial w_1}=y_1^2(1-y_1)out_{N1}

2. w1参数更新

w_{new1}=w_{1}-\eta \frac{\partial Loss}{\partial w_1}=w_1-\eta \cdot y_1^2(1-y_1)out_{N1}

第二层反向传播公式推导:w3

我知道大伙懒得往上翻,我再次粘贴图片如下:

        可以看到w3出来的线可以影响N1、N4和N5。故我们分两条线进行求解,但是主公式还是不变的如下:

w_{new3}=w_3-\eta \frac{\partial Loss}{\partial w_3}

1. 偏导函数求解

由于w3一共有两条线,所以我们偏导函数也有两项,如下:

偏导函数如下:

\frac{\partial Loss}{\partial w_3}=\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}+\frac{\partial Loss}{\partial y_2}\frac{\partial y_2}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}

左侧偏导计算如下:

\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}=y_1^2(1-y_1)w_1out_{N1}(1-out_{N1})x1

右侧偏导计算如下

\frac{\partial Loss}{\partial y_2}\frac{\partial y_2}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}=y_2^2(1-y_2)w_2out_{N1}(1-out_{N1})x1

好复杂!!但是安心,我们马上化简一下!

 不知大家还记不记得Loss对w1的偏导函数,如下:

\frac{\partial Loss}{\partial w_1} =\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial w_1}=y_1^2(1-y_1)out_{N1}

我们将其记为:\Delta _1

同理我们可以得到Loss对w2的偏导函数,如下:

\frac{\partial Loss}{\partial w_2} =\frac{\partial Loss}{\partial y_2}\frac{\partial y_2}{\partial f(x)}\frac{\partial f(x)}{\partial w_2}=y_2^2(1-y_2)out_{N1}

同理我们记为:\Delta _2

那么左侧偏导我们可以简化为如下公式:

\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}=\Delta_1w_1(1-out_{N1})x1

同理,右侧简化如下:

\frac{\partial Loss}{\partial y_2}\frac{\partial y_2}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}=\Delta_2w_2(1-out_{N1})x1

综上,我们可得最终的偏导函数如下:

\frac{\partial Loss}{\partial w_3}=(\Delta_1w_1+\Delta_2w_2)(1-out_{N1})x1

2. w3参数更新

w_{new3}=w_{3}-\eta \frac{\partial Loss}{\partial w_3}=w_3-\eta \cdot (\Delta_1w_1+\Delta_2w_2)(1-out_{N1})x1

MSE&sigmoid神经网络w参数更新公式普世规律推演

很简单如下所示:

w_{new}=w_{}-\eta \frac{\partial Loss}{\partial w}=w-\eta \cdot (\sum_i\Delta_iw_i)(1-y)x

其中:

  • \eta:学习率
  • \Delta _i:待更新w的后续一层神经元计算的偏导数
  • w _i:待更新w的后续一层神经元的参数
  • y:本神经元的输出
  • x:本神经元的输入

注:以上推导为博主自己推导所得,若有错漏请指出!

其实各位看官可以自己也推导一边,会更有感悟,随便也帮忙纠错下是否正确~

交叉熵&sigmoid反向推导公式

有关YOLOv3损失函数的内容可以先看下以下博文:

YOLO系列正传(一)类别损失与MSE损失函数、交叉熵损失函数_yolov1 分类损失-CSDN博客

损失函数计算

我们可得YOLOv3类别损失函数如下:

Loss_{YOLOv3Cross Entropy} = \\ -\sum_{i = 0}^{S^2}\sum_{j = 0}^{B}\mathbb{I}_{ij}^{obj}\sum_{c \in classes} (p_{ij}(c)log(\hat{p_{ij}(c)}) + (1-p_{ij}(c))log(1-\hat{p_{ij}(c)}) ) 

其中,最主要的就是二叉熵损失函数。我们从此入手进行推导!首先我们列出公式如下:

\sum_{i} (\hat{y_i}log(y_i) + (1-\hat{y_i})log(1-y_i) )

其中yi为预测值,\hat{y_i}为真值。

 以上为交叉熵损失函数的表达式。

还是针对一样的图片,我们假设YOLOv3的网络结构如上所示!

注意,YOLOv3在训练时候的输出层采用一个conv2d卷积直接输出,没有经过激活函数激活(YOLOv3训练的激活函数在计算损失函数的时候采用sigmoid函数激活)。本文我们从激活函数全部都是sigmoid函数出发进行推导!

第一层反向传播公式推导:w1 

首先,我们反向传播公式如下:

w_{new1}=w_{1}-\eta \frac{\partial Loss}{\partial w_1}

1. 偏导数求解

\frac{\partial Loss}{\partial w_1} =\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial w_1}

各个部分分解如下:

\frac{\partial Loss}{\partial y_1}=\hat{y_1}\frac{1}{y_1}-(1-\hat{y_1})\frac{1}{1-y_1}

\frac{\partial y_1}{\partial f(x)}=\frac{\partial \frac{1}{1+e^{-f(x)}}}{\partial f(x)}=\frac{e^{f(x)}}{(1+e^{-f(x)})^2}= \frac{1}{1+e^{-f(x)}}(1- \frac{1}{1+e^{-f(x)}})=y_1(1-y_1)

\frac{\partial f(x)}{\partial w_1}=\frac{\partial \sum_{i=1}^{n}w_ix_i+b}{\partial w_1}=out_{N1}

最终我们可以得到如下公式:

\begin{array}{c} \frac{\partial Loss}{\partial w_1} = [\hat{y_1}\frac{1}{y_1}-(1-\hat{y_1})\frac{1}{1-y_1}]y_1(1-y_1)out_{N1}= [\hat{y_1}(1-y_1)-y_1(1-\hat{y_1})]out_{N1} \end{array}

2. w1参数更新

w_{new1}=w_{1}-\eta \frac{\partial Loss}{\partial w_1}=w_1-\eta \cdot [\hat{y_1}(1-y_1)-y_1(1-\hat{y_1})]out_{N1}

 第二层反向传播公式推导:w3

首先,我们反向传播公式如下:

w_{new3}=w_{3}-\eta \frac{\partial Loss}{\partial w_3}

1. 偏导数求解

偏导函数如下:

\frac{\partial Loss}{\partial w_3}=\frac{\partial Loss}{\partial y_1}\frac{\partial y_1}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}+\frac{\partial Loss}{\partial y_2}\frac{\partial y_2}{\partial f(x)}\frac{\partial f(x)}{\partial out_{N1}}\frac{\partial out_{N1}}{\partial f(x)}\frac{\partial f(x)}{\partial w_3}

左侧偏导计算如下:

left=[\hat{y_1}(1-y_1)-y_1(1-\hat{y_1})]w_1out_{N1}(1-out_{N1})x1

右侧偏导计算如下

right=[\hat{y_2}(1-y_2)-y_2(1-\hat{y_2})]w_2out_{N1}(1-out_{N1})x1

同理,我们将w1的偏导函数 [\hat{y_1}(1-y_1)-y_1(1-\hat{y_1})]out_{N1} 记为\Delta 1

将w2的偏导函数 [\hat{y_2}(1-y_2)-y_2(1-\hat{y_2})]out_{N1} 记为\Delta 2

综上,可得偏导函数如下:

w_{new3}=w_{3}-\eta \frac{\partial Loss}{\partial w_3}=(\Delta_1w_1+\Delta _2w_2)(1-out_{N1})x1

2. w3参数更新

w_{new3}=w_{3}-\eta \frac{\partial Loss}{\partial w_3}=w_3-\eta \cdot (\Delta_1w_1+\Delta_2w_2)(1-out_{N1})x1

交叉熵&sigmoid神经网络w参数更新公式普世规律推演

很简单如下所示:

w_{new}=w_{}-\eta \frac{\partial Loss}{\partial w}=w-\eta \cdot (\sum_i\Delta_iw_i)(1-y)x

其中:

  • \eta:学习率
  • \Delta _i:待更新w的后续一层神经元计算的偏导数
  • w _i:待更新w的后续一层神经元的参数
  • y:本神经元的输出
  • x:本神经元的输入

注意和之前的结论居然一模一样!

以此类推,我们就能求解后续所有参数的更新过程了!

各位读者大大,求赞求关注……为了写此篇博客,脑细胞死了很多了……

注:推导若有错漏请不吝赐教!
Linux创始人LinusTorvalds有一句名言:Talk is cheap, Show me the code.(冗谈不够,放码过来!)。 代码阅读是从入门到提高的必由之路。尤其对深度学习,许多框架隐藏了神经网络底层的实现,只能在上层调包使用,对其内部原理很难认识清晰,不利于进一步优化和创新。  YOLOv3是一种基于深度学习的端到端实时目标检测方法,以速度快见长。YOLOv3的实现Darknet是使用C语言开发的轻型开源深度学习框架,依赖少,可移植性好,可以作为很好的代码阅读案例,让我们深入探究其实现原理。  本课程将解析YOLOv3的实现原理和源码,具体内容包括: YOLO目标检测原理  神经网络及Darknet的C语言实现,尤其是反向传播的梯度求解和误差计算 代码阅读工具及方法 深度学习计算的利器:BLAS和GEMM GPU的CUDA编程方法及在Darknet的应用 YOLOv3的程序流程及各层的源码解析本课程将提供注释后的Darknet的源码程序文件。  除本课程《YOLOv3目标检测:原理源码解析》外,本人推出了有关YOLOv3目标检测的系列课程,包括:   《YOLOv3目标检测实战:训练自己的数据集》  《YOLOv3目标检测实战:交通标志识别》  《YOLOv3目标检测:原理源码解析》  《YOLOv3目标检测:网络模型改进方法》 建议先学习课程《YOLOv3目标检测实战:训练自己的数据集》或课程《YOLOv3目标检测实战:交通标志识别》,对YOLOv3的使用方法了解以后再学习本课程。
需要学习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网络模型架构图】 下图由白勇老师绘制  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千天夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值