神经网络中BP(back propagation)到底在干些什么

前言

想要理解神经网络的工作原理,反向传播(BP)是必须搞懂的东西。BP其实并不难理解,说白了就是用链式法则(chain rule)算算算。本文试图以某个神经网络为例,尽可能直观,详细,明了地说明反向传播的整个过程。

正向传播

在反向传播之前,必然是要有正向传播的。正向传播时的所有参数都是预先随机取的,没人能说这样的参数好不好,得要试过才知道,试过之后,根据得到的结果与目标值的差距,再通过反向传播取修正各个参数。下图就是一个神经网络,我们以整个为例子来说明整个过程

图1:神经网络图

我懒,此图取自参考文献[1],图中的各个符号说明如下(顺序从下往上):
xix_ixi:输入样本中的第iii个特征的值
vihv_{ih}vihxix_ixi与隐层第hhh个神经元连接的权重
αh\alpha_hαh:第h个隐层神经元的输入,αh=∑i=1dvihxi\alpha_h=\sum_{i=1}^d v_{ih}x_iαh=i=1dvihxi
bhb_hbh:第h个隐层神经元的输出,某个神经元的输入和输出有关系f(αh)=bhf(\alpha_h)=b_hf(αh)=bh,其中f(x)f(x)f(x)为激活函数,比如Sigmoid函数f(x)=11+e−xf(x)=\dfrac{1}{1+e^{-x}}f(x)=1+ex1
whjw_hjwhj:隐层第hhh个神经元和输出层第jjj个神经元连接的权重
βj\beta_jβj:输出层第jjj个神经元的输入,βj=∑h=1qwhjbh\beta_j=\sum_{h=1}^q w_{hj}b_hβj=h=1qwhjbh
yjy_jyj:第jjj个输出层神经元的输出,f(βj)=yjf(\beta_j)=y_jf(βj)=yjf(x)f(x)f(x)为激活函数
为了方便书写,我们假设截距项bias已经在参数wwwvvv之中了,也就是说在输入数据的时候,我们增添了一个x0=1x_0=1x0=1,由于我懒,图中没有画出来,但心里要清楚这一点。
相信看了图之后,神经网络的正向传播就相当简单明了了,不过,这里我还是啰嗦一句,举个例子,比如输出yjy_jyj的计算方法为

yj=f(βj)=f(∑h=1qwhjbh)=f(∑h=1qwhjf(αh))=f(∑h=1qwhjf(∑i=1dvihxi))y_j=f(\beta_j)=f(\sum_{h=1}^q w_{hj}b_h)=f(\sum_{h=1}^q w_{hj}f(\alpha_h))=f(\sum_{h=1}^q w_{hj}f(\sum_{i=1}^d v_{ih}x_i))yj=f(βj)=f(h=1qwhjbh)=f(h=1qwhjf(αh))=f(h=1qwhjf(i=1dvihxi))

反向传播

好了,通过正向传播,我们就已经得到了lllyyy的值了,将它们与目标值ttt,也就是我们期望它们成为的值作比较,并放入损失函数中,记作LLL
损失LLL可以自行选择,比如常见的均方误差L=12∑j=1l(yj−tj)2L=\dfrac{1}{2}\sum_{j=1}^l (y_j - t_j)^2L=21j=1l(yjtj)2
利用这个误差,我们将进行反向传播,以此来更新参数wwwvvv。更新时,我们采用的是梯度下降法,也就是

{w:=w+Δwv:=v+Δv\begin{cases}w := w + \Delta w \\ v := v + \Delta v\end{cases}{w:=w+Δwv:=v+Δv

其中,Δw=−η∂L∂w\Delta w = -\eta \dfrac{\partial L}{\partial w}Δw=ηwLΔv=−η∂L∂v\Delta v = -\eta \dfrac{\partial L}{\partial v}Δv=ηvLη\etaη为学习率。
下面要做的工作就是计算出每个参数的梯度,这也就是链式法则发挥作用的地方了。
比如,我们要计算whjw_{hj}whj。从网络结构中不难看出whjw_{hj}whj影响了βj\beta_jβj从而影响了yjy_jyj,最终影响了LLL所以我们有

Δwhj=−η∂βj∂whj∂yj∂βj∂L∂yj\Delta w_{hj}=-\eta \dfrac{\partial \beta_j}{\partial w_{hj}} \dfrac{\partial y_j}{\partial \beta_j} \dfrac{\partial L}{\partial y_j}Δwhj=ηwhjβjβjyjyjL

只要确定了损失函数LLL和激活函数f(x)f(x)f(x),上面所有的都是可以算的,而且∂βh∂whj=bh\dfrac{\partial \beta_h}{\partial w_{hj}} = b_hwhjβh=bh这点是显而易见的。并且,∂yj∂βj=∂f(βj)∂βj\dfrac{\partial y_j}{\partial \beta_j} = \dfrac{\partial f(\beta_j)}{\partial \beta_j}βjyj=βjf(βj)就是激活函数的导数。
同理,vihv_{ih}vih影响了αh\alpha_hαh,从而影响了bhb_hbh,从而影响了β1\beta_{1}β1β2\beta_{2}β2,…,βl\beta_{l}βl,从而影响了y1y_1y1y2y_2y2,…,yly_lyl,最终影响了LLL

Δvih=−η∂αh∂vih∂bh∂αh∑j=1l(∂βj∂bh∂yj∂βj∂L∂yj)\Delta v_{ih} = -\eta \dfrac{\partial \alpha_h}{\partial v_{ih}} \dfrac{\partial b_h}{\partial \alpha_h}\sum_{j=1}^l (\dfrac{\partial \beta_j}{\partial b_h} \dfrac{\partial y_j}{\partial \beta_j} \dfrac{\partial L}{\partial y_j})Δvih=ηvihαhαhbhj=1l(bhβjβjyjyjL)

其中,∂αh∂vih=xi\dfrac{\partial \alpha_h}{\partial v_{ih}}=x_ivihαh=xi∂βj∂bh=whj\dfrac{\partial \beta_j}{\partial b_h} = w_{hj}bhβj=whj∂yj∂βj=∂f(βj)∂βj\dfrac{\partial y_j}{\partial \beta_j} = \dfrac{\partial f(\beta_j)}{\partial \beta_j}βjyj=βjf(βj)∂bh∂αh=∂f(αh)∂αh\dfrac{\partial b_h}{\partial \alpha_h} = \dfrac{\partial f(\alpha_h)}{\partial \alpha_h}αhbh=αhf(αh)是激活函数的导数。
至此,我们已经可以算出Δw\Delta wΔwΔv\Delta vΔv,从而更新参数了。

关于激活函数的几点说明

从推出的公式中不难看出,随着反向传播向输出层这个方向的推进,激活函数的影响也就越来越来了。通俗一点来说,在计算Δwhj\Delta w_{hj}Δwhj,我们只乘了一个激活函数的导数,然而在计算Δvih\Delta v_{ih}Δvih时,我们乘了多个激活函数的导数。

Δwhj=−η∂βj∂whjf′(βj)∂L∂yj\Delta w_{hj}=-\eta \dfrac{\partial \beta_j}{\partial w_{hj}} f'(\beta_j) \dfrac{\partial L}{\partial y_j}Δwhj=ηwhjβjf(βj)yjL

Δvih=−η∂αh∂vihf′(αh)∑j=1l(∂βj∂bhf′(βj)∂L∂yj)\Delta v_{ih} = -\eta \dfrac{\partial \alpha_h}{\partial v_{ih}} f'(\alpha_h) \sum_{j=1}^l (\dfrac{\partial \beta_j}{\partial b_h} f'(\beta_j) \dfrac{\partial L}{\partial y_j})Δvih=ηvihαhf(αh)j=1l(bhβjf(βj)yjL)

不难推断出,如果隐层的层数更多的话,激活函数的影响还要更大。
一个比较传统的激活函数时Sigmoid函数,其图像如下所示。

图2:Sigmoid函数

不难发现,当xxx比较大的时候,或比较小的时候,f′(x)f'(x)f(x)是趋近于0的,当神经网络的层数很深的时候,这么多个接近0的数相乘就会导致传到输出层这边的时候已经没剩下多少信息了,这时梯度对模型的更新就没有什么贡献了。那么大多数神经元将会饱和,导致网络就几乎不学习。这其实也是Sigmoid函数现在在神经网络中不再受到青睐的原因之一。
另一个原因是Sigmoid 函数不是关于原点中心对称的,这会导致梯度在反向传播过程中,要么全是正数,要么全是负数。导致梯度下降权重更新时出现 Z 字型的下降。
所以,就出现了ReLU这个激活函数 f(x)=max⁡(0,x)f\left( x\right) =\max \left( 0,x\right)f(x)=max(0,x),其图像如下图所示。

图3:ReLU函数

ReLU 对于 SGD 的收敛有巨大的加速作用,而且只需要一个阈值就可以得到激活值,而不用去算一大堆复杂的(指数)运算。
不过,由于它左半边的状态,ReLU在训练时比较脆弱并且可能“死掉”。
因此,人们又研究出了Leaky ReLU,PReLU等等的激活函数。这里不展开讨论。

参考文献

[1] 周志华. 机器学习 : = Machine learning[M]. 清华大学出版社, 2016.
[2] http://cs231n.github.io/neural-networks-1/
[2] http://www.jianshu.com/p/6df4ab7c235c

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470760.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TOP 子句

TOP 子句TOP 子句用于规定要返回的记录的数目。对于拥有数千条记录的大型表来说,TOP 子句是非常有用的。注释:并非所有的数据库系统都支持 TOP 子句。SQL Server 的语法:SELECT TOP number|percent column_name(s)FROM table_nameMySQL 和 Or…

Nodejs 新特性 async await 的使用 以及使用 async await 处理异步

1. let 和 var 2. const定义常量 3. 模板字符串 4. 属性简写 5. 方法简写 6. 箭头函数 7. 回调函数 7. Promise 8. async 和 await

leetcode 高薪_LeetCode 第 125 号问题:验证回文串

本文首发于公众号「五分钟学算法」,是图解 LeetCode 系列文章之一。个人网站:https://www.cxyxiaowu.com题目来源于 LeetCode 第 125 号问题:验证回文串。这道题目是 初级程序员 在面试的时候经常遇到的一道算法题,而且面试官喜欢…

从拉格朗日乘子法到SVM

前言 本文主要是讲了如何构建SVM的模型,并利用KKT条件构造其对偶型,从而求解问题,并讲述了SVM的硬间隔,软间隔和核函数三个境界。主要参考了周志华的《机器学习》,并在其中补充了自己的想法。由于内容较多&#xff0c…

nodejs 创建一个静态资源服务器 +路由

0、补充 1、Node.js 创建的第一个应用 1、引入 http 模块 var http require("http"); 2、创建服务器 接下来我们使用 http.createServer() 方法创建服务器,并使用 listen 方法绑定 3000 端口。 函数通过 request, response 参数来接收和响应数据。 co…

python输出字体的大小_Python密码学编程:文件的加密与解密

在之前的章节中,编写的程序只能操作较少的信息,这些信息往往是以字符串的形式直接写在代码中的。但本章中的程序可以对整个文件进行加密和解密,文件的大小可以包括成千上万个字符。本章要点open()方法。读、写文件。write()、close()及read()…

个人工作总结7

时间关系,只能等到编完了程序再做工作总结了,今天是第七天: 一、昨天干了什么? 服务器配置了一大圈,尝试了N1种办法,到最后也没有成功,但好像只差一点点,打算明天上移动应用开发咨询一下老师。 …

电脑k歌软件_金麦客专业k歌app下载|金麦客专业k歌软件 手机安卓版v1.1.5.0 下载...

金麦客专业k歌app能够让用户通过手机直接连接电视,从而在安卓端实现金麦客点歌的目的,平台包含上万高清mv资源,让用户在歌唱时能够更好的代入氛围中,并且还能通过网络直接搜歌,从而在线下载播放,用户在演唱…

python的普通方法、类方法和静态方法

前言 本文主要讲述了python类中的三类常用方法,普通方法、类方法和静态方法。 普通方法会将实例传入方法当中(通常用self表示),类方法会将类传入方法当中(通常用cls表示),静态方法中传入与类无…

局部内部类和匿名内部类的对比

创建内部类的典型的方式是在一个方法体的里面创建,局部内部类不能有访问说明符,因为它不是外围类的一部分,但是它可以访问当前代码块内的常量,以及此外围类的所有成员。下面的例子对局部内部类与匿名内部类的创建进行了比较。 具体代码实现&a…

Nodejs ejs模板引擎

官方网站:https://www.npmjs.com/package/ejs 我们学的 EJS 是后台模板,可以把我们数据库和文件读取的数据显示到 Html 页面上面。它 是一个第三方模块,需要通过 npm 安装 npm install ejs –save 或者 cnpm install ejs --saveNodejs 中使用…

py2中存储的pickle和py3中pickle无法读取的兼容性问题解决方案

问题描述 在py2.7当中,用以下语句将变量存储到pickle当中 with open(../dataset/m_7800/rf_preds.pickle, wb) as f:pickle.dump(rf_preds, f) 这个时候,用py3.6中的pickle取获取存储好的变量 with open(../dataset/m_7800/rf_preds.pickle, rb) as …

linux can总线接收数据串口打包上传_关于串口,你需要知道这些!!

嵌入式设备在电路中交换信息的时候必须通过共享一个通用的协议。现在嵌入式系统中已经定义了数百种通信协议来实现数据交换,一般来说可以将其分为两类:并行或串行。并行传输数据是指同时传输多个数据位,它们通常需要数据线和时钟线配合工作&a…

div里嵌套了img底部会有白块问题和图片一像素问题解决

div里嵌套了img底部会有白块 因为img默认是按基线(baseline)对齐的。对比一下图片和右边的p, q, y等字母,你会发现这三个字母的“小尾巴”和图片下方的空白一样高。下面这张图中的黑线就是那条基线。 解决方案:一:vertical-align: bottom&…

Nodejs 中的Get、Post

Get、Post 超文本传输协议(HTTP)的设计目的是保证客户端机器与服务器之间的通信。 在客户端和服务器之间进行请求-响应时,两种最常被用到的方法是:GET 和 POST。 GET - 从指定的资源请求数据。(一般用于获取数据&#…

利用二分法解决 leetcode 378. Kth Smallest Element in a Sorted Matrix

问题简述 给定一个 nn的矩阵,矩阵中每行和每列的元素都按升序排列。给定一个 k(k∈[1,n2]), 求再整个矩阵中按从小到大排序为 k的元素。 例如:matrix = [[ 1, 5, 9],[10, 11, 13],[12, 13, 15] ], k = 8,return 13.解题思路该矩阵的行和列都是按从小…

电脑故障扫描修复软件_电脑故障分析:电脑安装软件提示没有权限的解决方法...

我们安装软件时如果没有权限就会导致安装故障,最近就有用户安装软件的时候出现了无法将数值写入键software的错误提示,请验证您对该键拥有足够的访问权限,或者与您的技术支持人员联系。那么遇到这种问题该怎么办呢?接下来就让我们…

Nodejs 路由封装 封装一个类似 express 的路由

1、模块化的方式封装 routes.js: const http require(http); const fs require(fs); const path require(path) const url require(url) const ejs require(ejs) let getFileMime function (extname) {// 把异步读取文件方法改为同步读取文件方法let data fs.readFileSy…

天翼网关 ddns设置_19,微服务网关之Zuul

这一次给大家分享微服务网关的相关知识,这个也是微服务架构中,相当重要的组件之一,来,下面听我徐徐道来1,API网关概览1.1,现有的交互模式存在什么问题?目前,是客户端会直接跟多个微服…

利用bds和dfs解决 LeetCode 107. Binary Tree Level Order Traversal II

问题简述 给定一棵二叉树,返回该二叉树自底向上遍历的结点值(即从左到右,自底向上) 比如给定一颗二叉树 [3,9,20,null,null,15,7] 3/ \9 20/ \15 7 返回的结果为 [[15,7],[9,20],[3] ] 解决方案 解法1:广度优…