人工神经网络反向传播算法(BP算法)证明推导
为了搞明白这个没少在网上搜,但是结果不尽人意,最后找到了一篇很好很详细的证明过程,摘抄整理为 latex 如下。
(原文:https://blog.csdn.net/weixin_41718085/article/details/79381863)
更新:为了让看博客的带哥们能直观的看,我编译截图了,放在这里,latex 源码在下面




这个只是为了应付作业总结的,所以没有认真检查过,如果内容、正确性(尤其是这个)和格式上有什么问题请务必在下面评论区中指出。
\documentclass{article}
\usepackage{xeCJK}
\usepackage{amsmath}
\setCJKmainfont{Noto Serif CJK SC}
\title{人工神经网络反向传播算法\\链式法则在人工智能中的应用}
\begin{document}
\maketitle
\section{背景}
\subsection{人工神经元}
人工神经元是一个运算,它将输入分别以不同的权重组合相加并做一次偏移操作后进行某个非线性运算得到输出,以数学语言描述即是
\[
x^{(j + 1)} = \sigma(b + \sum_i W_i x_i^{(j)})
\]
其中 \(j\) 指神经元所处的层数,本例中 \(x_i^{(j)}\) 是来自第 \(j\)
层的第 \(i\) 个神经元的输入,\(W_i\)
是当前神经元所有提供输入的神经元中的第 \(i\) 个的权重,\(b\)
是偏移值,\(f\)
被称作激活函数,通常是一个非线性函数,一些经典的激活函数有 Sigmoid,
ReLU, 和反正切函数。
\subsection{人工神经网络}
人工神经网络(Artificial Neural Network,后简称
ANN)由若干层人工神经元组成,在本文所考虑的模型中,每一层神经元接受上一层神经元的输入,运算,并将结果输出至下一层。事实上,若将整个网络中每个神经元的参数记为矩阵
\(A\),则整个神经网络可以认为是一个函数 \(f(A, x)\),其中 \(x\)
是整个网络的输出。
在应用的过程中,我们常常有一组输入 \(x\) 和对应着的期望输出
\(y\)。训练神经网络的过程就是寻找合适的 \(A_0\),使得
\(f(A_0, x) = y\)。为了解决这个问题,数学上我们引入损失函数\(J(y, y^*)\)
来指示 \(f(A, x)\) 训练的程度,其中 \(y^*\)
是神经网络的输出。一个典型的损失函数是欧几里得距离的平方,即
\(J_0(y, y^*) = (y - y^*)^T (y - y^*)\)。这样一来,问题便被转化为,寻找
\(A_0\) 使得 \(J(y, f(A_0, x))\) 可以取到最小值。
由于对于给定的训练数据 \(y\) 是定值,为了直观,不妨记
\(J(y, f(A, x)) = h(A, x)\),这样一来我们需要解决的问题便是:
求参数 \(A\) 使得函数 \(h(A, x)\) 可以取到最小值。
这是我们在微积分的学习中经常解决的一类问题,只需要求出
\({\partial h(A, x)} / {\partial A}\) 并令其为 0
即可。但是事实上,对 \(h\)
求导函数几乎是不可能的,我们常用的方法是在每次迭代中,求出 \(h\)
在某个点 \(A_0\)
处的导数值,并根据这个导数值的正负和绝对值大小适当地调整 \(A\)
并进入下一轮迭代。这种方法被称作梯度下降法,他有一个显著的缺点就是他只能求得局部最小值(这是显然的),但考虑到通常神经网络的局部最小值已经足够优秀,我们便勉强可以接受这个缺点的存在。然而即便有了梯度下降法的思路,我们也需要一种可以求出导数值的算法,本文将描述的反向传播算法(Back
Propagation Algorithm,常简称 BP 算法)即是一例。
\section{推导}
\subsection{符号定义}
为了方便推导过程的说明,在这里重新进行符号定义,接下来的推导过程将不会使用背景中使用的符号体系。
符号规约:
\begin{itemize}
\item 第 \(l - 1\) 层的第 \(k\) 个神经元传播给第 \(l\) 层的第 \(j\) 个神经元的值的权重记为 \(W_{jk}^{(l)}\),每一层的所有权重记为矩阵 \(W^{(l)}\),所有的参数笼统地记作 \(W\);
\item 第 \(l\) 层的第 \(j\) 个神经元的偏移值记为 \(b_j^{(l)}\),每层的所有偏移量记为向量 \(b^{(l)}\),所有的偏移笼统地记作 \(b\);
\item 第 \(l\) 层的第 \(j\) 个神经元的输入值记为 \(z_j^{(l)}\),每层的所有输入值记为向量 \(z^{(l)}\);
\item 第 \(l\) 层的第 \(j\) 个神经元的输出值记为 \(x_j^{(l)}\),每层的所有输出值记为向量 \(x^{(l)}\);
\item 第 \(l\) 层的激活函数记为 \(\sigma_l\);(通常来讲每层神经元拥有一样的激活函数)
\item 第 \(l\) 层的神经元个数记为 \(s_l\); - 神经网络共有 \(n\) 层;
\item 损失函数记为 \(J(W, b; y, y_0)\),其中 \(y_0\) 指真值,\(y\) 指网络的输出值;(在一次迭代中,\(y\) 和 \(y_0\) 是常数,因此后面将略去这两个参数)
\item \({\partial J(W, b)}/{\partial z_j^{(l)}}\) 记为 \(\Delta_j^{(l)}\),一层的所有 \(\Delta\) 记作 \(\Delta^{(l)}\);
\item 训练集为 \(T = \{(x_0, y_0), (x_1, y_1), ..., (x_m, y_m)\}\),且 \(|T| = m\);
\item 被应用于矩阵或向量间的 \(*\) 运算指对位乘法。
\end{itemize}
根据定义,显然有:
$$
z_j^{(l+1)} = \left(\sum_{k=0}^{s_{(l-1)}} W_{jk}^{(l)} x_k^{(l - 1)}\right) + b_j^{(l)} \eqno(a)
$$
$$
x_j^{(l)} = \sigma_l(z_j^{(l)}) \eqno(b)
$$
\subsection{证明目的}
给出一种算法以计算任意神经网络的 \(\partial J / \partial W_{jk}^{(l)}\) 和 \(\partial J / \partial b_{j}^{(l)}\)。出于篇幅的关系,本文仅说明对前者的计算,略去证明过程一致的后者证明部分。
\subsection{证明过程}
由链式法则知:
$$
{\partial J(W, b) \over \partial W_{jk}^{(l)}} = {\partial J(W, b) \over \partial x_j^{(l+1)}}{\partial x_j^{(l+1)} \over \partial z_j^{(l+1)}}{\partial z_j^{(l+1)} \over \partial W_{jk}^{(l)}} \eqno(0)
$$
将偏差拆分成了三部分,接下来分别对三个部分进行求解。
\paragraph{2.3.1. 第一部分}
对于第一部分有
$$
\begin{aligned}
{\partial J(W, b) \over \partial x_j^{(l+1)}}
&= \sum_{i = 1}^{s_{l + 2}} {\partial J \over \partial z_i^{(l+2)}} {\partial z_i^{(l+2)} \over \partial x_j^{(l+1)}} \\
&\overset{(a)}= \sum_{i = 1}^{s_{l+2}} {\partial J \over \partial z_i^{(l+2)}} {\partial \over \partial x_j^{(l+1)}} \left(b_j^{(l+1)} + \sum_{k = 0}^{s_{l+1}}{W_{ji}^{(l+1)}x_i^{(l+1)}}\right) \\
&= \sum_{i = 1}^{s_{l+2}} \Delta_i^{(l+2)} W_{ji}^{(l)}
\end{aligned} \eqno(2)
$$
\paragraph{2.3.2. 第二部分}
对于第二部分有
\[
\begin{aligned}
\partial x_j^{(l+1)} \over \partial z_j^{(l+1)}
&\overset{(b)}= {\partial \over \partial z_j^{(l+1)}} \sigma_{l+1}(z_j^{(l+1)}) \\
&= \sigma_{l+1}'(z_j^{(l+1)})
\end{aligned}
\]
对于激活函数 \(\sigma_l\) 来说,假设存在函数 \(f_l\) 使得
\[
f_l(\sigma_l(x)) = \sigma_l'(x)
\]
则有
\[
\begin{aligned}
{\partial x_j^{(l+1)} \over \partial z_j^{(l+1)}} = f^{(l+1)}(x_j^{(l+1)}
\end{aligned} \tag{2}
\]
\paragraph{2.3.3. 第三部分}
\[
\begin{aligned}
{\partial z_j^{(l+1)} \over \partial W_{jk}^{(l)}}
&\overset{(a)}= {\partial \over \partial W_{jk}^{(l)}} \left( b_j^{(l)} + \sum_{k=0}^{n_{l-1}} W_{jk}^{(l)} x_k^{(l - 1)}\right) \\
&= x_j^{(l)}
\end{aligned} \tag{3}
\]
\paragraph{2.3.4. 综合}
综合 \((0)\),\((1)\),\((2)\),\((3)\) 式可得
\[
\begin{aligned}
\left(\sum_{i = 1}^{s_{l+2}} \Delta_i^{(l+2)} W_{ji}^{(l)}\right) f^{(l+1)}(x_j^{(l+1)})x_j^{(l)}
\end{aligned} \tag{4}
\]
又因为
\[
\Delta_j^{(l+1)} = \frac{\partial J(W, b)}{\partial z_j^{(l + 1)}} = {\partial J(W, b) \over \partial x_j^{(l+1)}} {\partial x_j^{(l+1)} \over \partial z_j^{(l+1)}} \overset{(1), (2)}{=} \left(\sum_{i = 1}^{s_{l+2}} \Delta_i^{l+2} W_{ji}^{(l)}\right) f^{(l+1)}(x_j^{(l+1)}) \tag{5}
\]
其中 \( 0 < j < s_{l} + 1 \),\( 0 < l < n \).
\paragraph{2.3.5. 向量形式改写}
写作向量形式有
\[
\frac{\partial J(W, b)}{\partial W^{(l)}} = \Delta^{(l+1)} \left(x^{(l)}\right)^T \tag{4*}
\]
\[
\Delta^{(l)} = \left(W^{(l)}\right)^T \Delta^{(l+1)} * f_l(x^{(l+1)}) \tag{5*}
\]
\paragraph{2.3.6. 边界条件}
上文中我们求得了两个递推公式。显然,对于 \((5^*)\) 式来说,由于
\(l = n\) 时 \(l + 1\)
越界,所以不可以应用于该情况。对于该边界情况应当额外考虑。
\[
\begin{aligned}
\Delta_j^{(n)}
&= \frac{\partial J(W, b; y, y_0)}{\partial z_j^{(n)}} \\
&\overset{y = x^{(n)}}= \frac{\partial J(W, b; x^{(n)}, y_0)}{\partial x_i^{(n)}} \frac{\partial x_i^{(n)}}{\partial z_i^{(n)}} \\
&\overset{(2)}= \frac{\partial J(W, b; x^{(n)}, y_0)}{\partial x_i^{(n)}} f^{(n)}(x_j^{(n)})
\end{aligned} \tag{6}
\]
之后的计算与损失函数的具体形式有关,无法一般地给出,但考虑到接下来的运算都是显而易见的,此处略去无伤大雅。
\section{结论}
通过一个边界条件和两个递推公式:
\[
\begin{cases}
\Delta_j^{(n)} = \frac{\partial J}{\partial x_i^{(n)}}(W, b; x^{(n)}, y_0) f^{(n)}(x_j^{(n)}) \\
\frac{\partial J}{\partial W^{(l)}}(W, b) = \Delta^{(l+1)} \left(x^{(l)}\right)^T \\
\Delta^{(l)} = \left(W^{(l)}\right)^T \Delta^{(l+1)} * f_l(x^{(l+1)})
\end{cases} \eqno(conclusion)
\]
可以完成一次传播中对神经网络的求导过程。
\end{document}
人工神经网络反向传播算法(BP算法)证明推导的更多相关文章
- BP人工神经网络-反向传播法
0 网络计算结果 B(m)=f( ∑n( W(n,m)*X(n) ) + Θ(m) ) %中间层的输出 Y(k)=f( ∑m( V(m,k)*B(m) ) + ф(k) ) %输出层的输出 1 计算误 ...
- 神经网络中误差反向传播(back propagation)算法的工作原理
注意:版权所有,转载需注明出处. 神经网络,从大学时候就知道,后面上课的时候老师也讲过,但是感觉从来没有真正掌握,总是似是而非,比较模糊,好像懂,其实并不懂. 在开始推导之前,需要先做一些准备工作,推 ...
- 神经网络反向传播算法&&卷积神经网络
听一遍课程之后,我并不太明白这个算法的奇妙之处?? 为啥? 神经网络反向传播算法 神经网络的训练依靠反向传播算法,最开始输入层输入特征向量,网络层计算获得输出,输出层发现输出和正确的类号不一样,这时就 ...
- 神经网络——反向传播BP算法公式推导
在神经网络中,当我们的网络层数越来越多时,网络的参数也越来越多,如何对网络进行训练呢?我们需要一种强大的算法,无论网络多复杂,都能够有效的进行训练.在众多的训练算法中,其中最杰出的代表就是BP算法,它 ...
- 反向传播(BP)算法
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:刘皮皮链接:https://www.zhihu.com/question/24827633/answer/29120394来源 ...
- 反向传播(BP)算法理解以及Python实现
全文参考<机器学习>-周志华中的5.3节-误差逆传播算法:整体思路一致,叙述方式有所不同: 使用如上图所示的三层网络来讲述反向传播算法: 首先需要明确一些概念, 假设数据集\(X=\{x^ ...
- 第二节,神经网络中反向传播四个基本公式证明——BackPropagation
假设一个三层的神经网络结构图如下: 对于一个单独的训练样本x其二次代价函数可以写成: C = 1/2|| y - aL||2 = 1/2∑j(yj - ajL)2 ajL=σ(zjL) zjl = ∑ ...
- BP神经网络反向传播之计算过程分解(详细版)
摘要:本文先从梯度下降法的理论推导开始,说明梯度下降法为什么能够求得函数的局部极小值.通过两个小例子,说明梯度下降法求解极限值实现过程.在通过分解BP神经网络,详细说明梯度下降法在神经网络的运算过程, ...
- 神经网络中的反向传播法--bp【转载】
from: 作者:Charlotte77 出处:http://www.cnblogs.com/charlotte77/ 一文弄懂神经网络中的反向传播法——BackPropagation 最近在看深度学 ...
随机推荐
- IDEA控制台中文乱码解决
关于IDEA中文乱码的解决方法,如下. 1.打开idea安装目录,选择 打开文件,末尾添加-Dfile.encoding=UTF-8 2.打开IntelliJ IDEA>File>Sett ...
- antd 表格隔行变色
rowClassName={(record, index) => { let className = 'light-row'; if (index % 2 === 1) className = ...
- 拷贝和遍历DOM树
一.浅拷贝: 拷贝就是复制,就相当于把一个对象中的所有内容,复制一份给另一个对象,直接复制, 或者说,就是把一个对象的地址给了另外一个对象,他们的指向相同,两个对象之间有相同的属性或者方法,都可以使用 ...
- fasttext模型 训练THUCNews
# _*_coding:utf-8 _*_ import fasttext import jieba from sklearn import metrics import random def rea ...
- ubuntu中防火墙iptables配置
特别说明:此文章完全转载于https://www.cnblogs.com/EasonJim/p/6851007.html 1.查看系统是否安装防火墙 root@localhost:/usr# whic ...
- GitLab获取人员参与项目-贡献项目列表
目录 前言 获取token 登录 获取用户参与项目 完整代码 前言 最近在做的统计报表项目包含人员代码提交量. 要获取人员代码提交量首先要知道人员参与的项目.GitLab个人页面中有Contribut ...
- 如果对方网站反爬取,封IP了怎么办?
放慢抓取熟速度,减小对目标网站造成的压力,但是这样会减少单位时间内的数据抓取量 使用代理IP(免费的可能不稳定,收费的可能不划算)
- Visual Studio2019安装步骤
学校使用的版本是2012版本,而现在讲的版本是2019版本,差别不大,个人认为2019更能胜任学习任务. 另外VS2019是完全免费的,版本越高越好了!毕竟C++都出了C++20对吧. Step 1: ...
- Maven私服使用经验总结
我是使用nexus2.11.2在centos6.5上搭建的私服,以下是总结我这几天的经验. 1.当你修改pom.xml的时候,eclipse检查的是你本地仓库里的jar包,如果有了,pom.xml文件 ...
- Java 面向对象(四)
代码块 什么是代码块 在类中或方法当中 使用 { } 括起来的一段代码,就称它是一个代码块. 在代码块当中定义的变量我们称是局部变量,在外面是没有办法使用的.这里定义的 a 就是一个局部变量. 代码块 ...