BP算法是一种最有效的多层神经网络学习方法,其主要特点是信号前向传递,而误差后向传播,通过不断调节网络权重值,使得网络的最终输出与期望输出尽可能接近,以达到训练的目的。

一、多层神经网络结构及其描述

下图为一典型的多层神经网络。

通常一个多层神经网络由L层神经元组成,其中:第1层称为输入层,最后一层(第L层)被称为输出层,其它各层均被称为隐含层(第2层~第L-1层)。

令输入向量为:

\[ \vec x = [x_1 \quad x_2 \quad \ldots \quad x_i \quad \ldots \quad x_m], i=1,2,\ldots, m \]

输出向量为:

\[ \vec y = [y_1 \quad y_2 \quad \ldots \quad y_k \quad \ldots \quad y_n], k = 1,2, \ldots,n \]

l隐含层各神经元的输出为:

\[ h^{(l)}= [h_1^{(l)} \quad h_2^{(l)} \quad \ldots \quad h_j^{(l)} \quad \ldots \quad h_{s_l}^{(l)}],j=1,2,\ldots,s_l \]

其中,$s_l$为第l层神经元的个数。

设$W_{ij}^{(l)}$为从l-1层第j个神经元与l层第i个神经元之间的连接权重;$b_i^{(l)}$为第l层第i个神经元的偏置,那么:

\[ h_i^{(l)} = f(net_i^{(l)})\]

\[ net_i^{(l)} = \sum_{j=1}^{s_{l-1}} W_{ij}^{(l)} h_j^{(l-1)} + b_i^{(l)}\]

其中,$net_i^{(l)}$为l层第i个神经元的输入,$f(\cdot)$为神经元的激活函数。通常在多层神经网络中采用非线性激活函数,而不是用线性激活函数,因为采用基于线性激活函数的多层神经网络本质上还是多个线性函数的叠加,其结果仍然为一个线性函数。

二、激活函数

BP神经网络通常使用下面两种非线性激活函数:

\[ f(x) = \frac 1 {1 + e^{-x}}\]

\[ f(x) = \frac {1 - e^{-x}} {1 + e^{-x}}\]

第一种称为sigmod函数或者logistics函数,第二种为双曲正切函数。

Sigmod函数的图像如下图所示,它的变化范围为(0, 1),其导数为$f^{'} = f(1-f)$。

双曲正切函数的图像如下图所示,它的变化范围为(-1, 1),其导数为$f^{'} = 1-f^2$。

三、BP算法推导过程

假定我们有m个训练样本$\{ (x(1), y(1)), (x(2), y(2)), \ldots, (x(m), y(m))\}$,其中$d(i)$为对应输入$x(i)$的期望输出。BP算法通过最优化各层神经元的输入权值以及偏置,使得神经网络的输出尽可能地接近期望输出,以达到训练(或者学习)的目的。

采用批量更新方法,对于给定的m个训练样本,定义误差函数为:

\[ E = \frac 1 m \sum_{i=1}^m E(i) \]

其中,E(i)为单个样本的训练误差:

\[ E(i) = \frac 1 2 \sum_{k=1}^n (d_k(i) - y_k(i))^2 \]

因此,

\[ E = \frac 1 {2m} \sum_{i=1}^m \sum_{k=1}^n (d_k(i) - y_k(i))^2\]

BP算法每一次迭代按照以下方式对权值以及偏置进行更新:

\[ W_{ij}^{(l)} = W_{ij}^{(l)} -\alpha \frac {\partial E} {\partial W_{ij}^{(l)}} \]

\[ b_i^{(l)} = b_i^{(l)} -\alpha \frac {\partial E} {\partial b_i^{(l)}}\]

其中,$\alpha$为学习速率,它的取值范围为(0, 1)。BP算法的关键在于如何求解$W_{ij}^{(l)}$和$b_i^{(l)}$的偏导数。

对于单个训练样本,输出层的权值偏导数计算过程:

\begin{equation*}
\begin{split}
\frac {\partial E(i)} {\partial W_{kj}^{(L)}}&=\frac {\partial} {\partial W_{kj}^{(L)}} (\frac 1 2 \sum_{k=1}^n (d_k(i)-y_k(i))^2) \\
&=\frac {\partial} {\partial W_{kj}^{(L)}} (\frac 1 2 (d_k(i)-y_k(i))^2)\\
&=-(d_k(i)-y_k(i))\frac {\partial y_k(i)} {\partial W_{kj}^{(L)}}\\
&=-(d_k(i)-y_k(i))\frac {\partial y_k(i)} {\partial net_k^{(L)}} \frac {\partial net_k^{(L)}} {\partial W_{kj}^{(L)}}\\
&=-(d_k(i)-y_k(i))f(x)^{'}|_{x=net_k^{(L)}} \frac {\partial net_k^{(L)}} {\partial W_{kj}^{(L)}}\\
&=-(d_k(i)-y_k(i))f(x)^{'}|_{x=net_k^{(L)}} h_j^{(L-1)}
\end{split}
\end{equation*}

即:

\[
\frac {\partial E(i)} {\partial W_{kj}^{(L)}} = -(d_k(i) - y_k(i))f(x)^{'}|_{x=net_k^{(L)}}h_j^{(L-1)}
\]

同理可得,

\[
\frac {\partial E(i)} {\partial b_{k}^{(L)}} = -(d_k(i) - y_k(i))f(x)^{'}|_{x=net_k^{(L)}}
\]

令:

\[
\delta_k^{(L)} = -(d_k(i) - y_k(i))f(x)^{'}|_{x=net_k^{(L)}}
\]

则:

\[
\frac {\partial E(i)} {\partial W_{kj}^{(L)}} = \delta_k^{(L)} h_j^{(L)}
\]

\[
\frac {\partial E(i)} {\partial b_{k}^{(L)}} = \delta_k^{(L)}
\]

对隐含层L-1层:

\begin{equation*}
\begin{split}
\frac {\partial E(i)} {\partial W_{ji}^{(L-1)}}&=\frac {\partial} {\partial W_{ji}^{(L-1)}} (\frac 1 2 \sum_{k=1}^n (d_k(i)-y_k(i))^2) \\
&=\frac {\partial} {\partial W_{ji}^{(L-1)}} (\frac 1 2 \sum_{k=1}^n (d_k(i)-f(\sum_{j=1}^{s_{L-1}} W_{kj}^{(L)} h_j^{(L-1)} + b_k^{(L)}))^2) \\
&=\frac {\partial} {\partial W_{ji}^{(L-1)}} (\frac 1 2 \sum_{k=1}^n (d_k(i)-f(\sum_{j=1}^{s_{L-1}} W_{kj}^{(L)} f(\sum_{i=1}^{s_{L-2}} W_{ji}^{(L-2)}h_i^{(L-2)} + b_j^{(L-1)}) + b_k^{(L)}))^2) \\
&=-\sum_{k=1}^n (d_k(i) - y_k(i)) f(x)^{'}|_{x=net_k^{(L)}} \frac {\partial net_k^{(L)}} {\partial W_{ji}^{(L-1)}}
\end{split}
\end{equation*}

因为,

\begin{equation*}
\begin{split}
net_k^{(L)} &=\sum_{j=1}^{s_{L-1}} W_{kj}^{(L)} h_j^{(L-1)} + b_k^{(L)} \\
&=\sum_{j=1}^{s_{L-1}} W_{kj}^{(L)} f(\sum_{i=1}^{s_{L-2}} W_{ji}^{(L-2)}h_i^{(L-2)} + b_j^{(L-1)}) + b_k^{(L)} \\
&=\sum_{j=1}^{s_{L-1}} W_{kj}^{(L)} f(net_j^{(L-1)})
\end{split}
\end{equation*}

所以,

\begin{equation*}
\begin{split}
\frac {\partial E(i)} {\partial W_{ji}^{(L-1)}}&= \sum_{k=1}^n (d_k(i) - y_k(i)) f(x)^{'}|_{x=net_k^{(L)}} \frac {\partial net_k^{(L)}} {\partial W_{ji}^{(L-1)}} \\
&= \sum_{k=1}^n (d_k(i) - y_k(i)) f(x)^{'}|_{x=net_k^{(L)}} \frac { \partial net_k^{(L)}} {\partial f(net_j^{(L-1)})} \frac {\partial f(net_j^{(L-1)})} {\partial net_j^{(L-1)}} \frac {\partial net_j^{(L-1)}} {\partial W_{ji}^{(L-1)}} \\
&= \sum_{k=1}^n (d_k(i) - y_k(i)) f(x)^{'}|_{x=net_k^{(L)}} W_{kj}^{(L)} f(x)^{'}|_{x = net_j^{(L-1)}} h_i^{(L-2)}
\end{split}
\end{equation*}

同理,

\[
\frac {\partial E(i)} {\partial b_j^{(L-1)}} = \sum_{k=1}^n (d_k(i) - y_k(i)) f(x)^{'}|_{x=net_k^{(L)}} W_{kj}^{(L)} f(x)^{'}|_{x = net_j^{(L-1)}}
\]

令:

\begin{equation*}
\begin{split}
\delta_j^{(L-1)} &= \sum_{k=1}^n (d_k(i) - y_k(i)) f(x)^{'}|_{x=net_k^{(L)}} W_{kj}^{(L)} f(x)^{'}|_{x = net_j^{(L-1)}} \\
&=\sum_{k=1}^n W_{kj}^{(L)} \delta_k^{(L)} f(x)^{'}|_{x = net_j^{(L-1)}}
\end{split}
\end{equation*}

\[
\frac {\partial E(i)} {\partial W_{ji}^{(L-1)}} = \delta_j^{(L-1)} h_i^{(L-2)}
\]

\[
\frac {\partial E(i)} {\partial b_j^{(L-1)}} = \delta_j^{(L-1)}
\]

  

由上可推,第l层($2 \leq l \leq L-1 $)的权值和偏置的偏导可以表示为:

\[
\frac {\partial E(i)} {\partial W_{ji}^{(l)}} = \delta_j^{(l)} h_i^{(l-1)}
\]

\[
\frac {\partial E(i)} {\partial b_j^{(l)}} = \delta_j^{(l)}
\]

其中,

\[
\delta_j^{(l)} = \sum_{k=1}^{s_{l+1}} W_{kj}^{(l+1)} \delta_k^{(l+1)} f(x)^{'}|_{x=net_{j}^{(l)}}
\]

四、BP算法过程描述

采用批量更新方法对神经网络的权值和偏置进行更新:

  1. 对所有的层$2 \leq l \leq L$,设$\Delta W^{(l)} = 0, \Delta b^{(l)} = 0 $,这里$\Delta W^{(l)} $和$\Delta b^{(l)} $分别为全零矩阵和全零向量;
  2. For i = 1:m,
    1. 使用反向传播算法,计算各层神经元权值和偏置的梯度矩阵$\nabla W^{(l)} (i)$和向量和$\nabla b^{(l)}(i) $;
    2. 计算$\Delta W^{(l)} = \nabla W^{(l)}(i) $;
    3. 计算$\Delta b^{(l)} = \nabla b^{(l)}(i)$。
  3. 更新权值和偏置:
    1. 计算$W^{(l)} = W^{(l)} + \frac 1 m \Delta W^{(l)} $;
    2. 计算$b^{(l)} = b^{(l)} + \frac 1 m \Delta b^{(l)} $。

BP神经网络推导过程详解的更多相关文章

  1. uboot主Makefile分析(t配置和编译过程详解)

    1.编译uboot前需要三次make make distcleanmake x210_sd_configmake -j4 make distclean为清楚dist文件. make x210_sd_c ...

  2. uboot配置和编译过程详解

    根据朱有鹏老师讲解整理 一.uboot主Makefile分析 1.uboot version确定(Makefile的24-29行) include/version_autogenerated.h文件是 ...

  3. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

  4. TortoiseGIT的安装过程详解

    TortoiseGIT简介 TortoiseGIT 是Git版本控制系统的一个免费开源客户端,它是git版本控制的 Windows 扩展.可以使你避免使用枯燥而且不方便的命令行.它完全嵌入 Windo ...

  5. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  6. Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)

    启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...

  7. Linux启动过程详解

    Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...

  8. ping命令执行过程详解

    [TOC] ping命令执行过程详解 机器A ping 机器B 同一网段 ping通知系统建立一个固定格式的ICMP请求数据包 ICMP协议打包这个数据包和机器B的IP地址转交给IP协议层(一组后台运 ...

  9. Cordova 打包 Android release app 过程详解

    Cordova 打包 Android release app 过程详解 时间 -- :: SegmentFault 原文 https://segmentfault.com/a/119000000517 ...

随机推荐

  1. 关于调试日志Log

    __VA_ARGS__  是一个可变参数的宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持).宏前面加上##的作用在于,当可变参数的个数为0时,这里的## ...

  2. js区分鼠标单双击 阻止事件冒泡

    function clickOrDblClick(obj) { count++; if (obj != undefined) { var rowStr = $.trim($(obj).find(&qu ...

  3. C# Winform应用程序占用内存较大解决方法整理(转)

    原文:http://www.jb51.net/article/56682.htm 背景: 微软的 .NET FRAMEWORK 现在可谓如火如荼了.但是,.NET 一直所为人诟病的就是“胃口太大”,狂 ...

  4. 修改Esxi克隆的CentOS的IP地址

    1.读取/etc/udev/rules.d/70-persistent-net.rules文件中eth1的MAC地址. 2.编辑文件 /etc/sysconfig/network-script/ifc ...

  5. oracle: job使用

    oracle的job,实际上就是数据库内置的定时任务,类似代码中的Timer功能.下面是使用过程: 这里我们模拟一个场景:定时调用存储过程P_TEST_JOB 向表TEST_JOB_LOG中插入数据 ...

  6. 扩展欧几里得算法(extgcd)

    相信大家对欧几里得算法,即辗转相除法不陌生吧. 代码如下: int gcd(int a, int b){ return !b ? gcd(b, a % b) : a; } 而扩展欧几里得算法,顾名思义 ...

  7. 本地的html怎么直接通过路径就读取本地文件。

    我要做的事情是已知一个目录的相对路径,获得这个路径下面所有的txt文件,然后读到一个JS Script里面做下一步处理. 网上的例子都是使用input的,既然我是local的html文件,也知道路径了 ...

  8. 【6年开源路】海王星给你好看!FineUI v4.0正式版暨《FineUI3to4一键升级工具》发布!

    去年10-28号,我发布了一篇文章<海王星给你好看!FineUI v4.0公测版发布暨<你找BUG我送书>活动开始>,标志着FineUI开始向4.0版本迈进.经过4个月3个公测 ...

  9. centos hadoop搭建准备

    永久修改主机名:hostnamectl set-hostname <hostname> IP地址: BOOTPROTO=static IPADDR=192.168.31.128NETMAS ...

  10. Android浮动小球与开机自启动

    看着手机上的360浮动小球,不评价其具体的功能与实用性,至少在UI设计与交互方面是个不小的创新. 如图片左上角所示,球中还会显示当前手机的运行状况,向下拉动还会有弹射来达到加速.清理等目的. 那好,先 ...