1、计算图:将计算过程用数据结构图表示,通过多个节点和边表示,节点用O表示,O中是计算内容,将计算的中间结果写在箭头上方,表示各个节点的计算结果从左向右传递。用计算图解题的流程即:①构建计算图;②在计算图上从左向右进行计算(正向传播,从计算图出发点到结束点的传播,反向传播正好相反)。

2、计算图的优点
①计算图可以集中精力于局部计算,从而简化问题,无论全局计算多么复杂,各个步骤所要做的就是对象节点的局部计算,通过传递它的计算结果,可以获得全局的复杂计算结果。
②可以通过反向传播高效计算导数,反向传播使用与正方向相反的箭头(粗线表示),传递“局部导数”,将导数值写在箭头下方,并且计算途中求得的导数结果可以被共享,从而可以高效地计算多个导数。

3、链式法则:如果某个函数由复合函数表示,则该复合函数的导数可以用构成复合函数的导数的乘积表示,这是关于复合函数的导数的性质。以复合函数z = (x+y)^2为例,由式子z = t^2,t = x+y构成。

反向传播的顺序是,先将节点的输入信号乘以节点的局部导数(偏导数),然后再传递给下一个节点,这个过程也基于链式法则。


4、反向传播的结构

  • 加法节点的反向传播——以z=x+y为对象观察反向传播,将上游传来的导数乘以1传向下游,因为加法节点的反向传播只乘以1,所以输入值原封不动流向下一个节点。

  • 乘法节点的反向传播——y以z=xy为对象观察反向传播,乘法的反向传播会将上游的值乘以正向传播时输入信号的翻转值(一种翻转关系),然后传递给下游,这个过程要保存正向传播的输入信号。

5、乘法层的实现:层的实现中有两个共通的方法(接口)forward()和backward(),分别对应正向传播和反向传播,*_ init _()*中初始化实例变量x和y,用于保存正向传播时的输入值,forward()接收x和y两个参数,将它们相乘后输出,backward()将从上游传来的导数乘以正向传播的翻转值,然后传给下游。

class MulLayer:     #乘法层def __init__(self):self.x = Noneself.y = Nonedef forward(self,x,y):self.x = xself.y = yout = x * yreturn outdef backward(self,dout):dx = dout * self.ydy = dout * self.xreturn dx,dy

6、加法层的实现:不需要特意进行初始化,_ init _()中什么也不运行,加法层的forward()接收x和y两个参数,将它们相加后输出,backward()将上游传来的导数原封不动传给下游。

class AddLayer:     #加法层def __init__(self):passdef forward(self,x,y):out = x + yreturn outdef backward(self,dout):dx = dout * 1dy = dout * 1return dx,dy

7、ReLU层的实现:激活函数ReLU由下式表示,并可求出y关于x的导数,如果正向传播时所输入的x>0,则反向传播会将上游的值原封不动传给下游;如果正向传播时输入的x≤0,则反向传播中传递给下游的信号将停在此处。

class Relu:def __init__(self):self.mask = Nonedef forward(self,x):self.mask = (x <= 0)    #标记下标out = x.copy()out[self.mask] = 0return outdef backward(self,dout):dout[self.mask] = 0dx = doutreturn dx

其中,实例变量mask是由True/False构成的Numpy数组,将输入元素中≤0的值的索引保存为True,反向传播中会使用正向传播时保存的mask,将从上游传来的dout的mask中元素为True的地方设为0。

8、Sigmoid层的实现:除了“x”和“+”节点,还有新节点“exp”和“/”节点,①“/”节点表示y=1/x,导数可以解析性地表示为-1/(x^2)=-(y**2),反向传播时会将上游值乘以该值后再传给下游;②“+”节点将上游值原封不动传给下游;③“exp”节点表示y=exp(x),导数仍是自身;④“x”节点将正向传播值翻转后做乘法运算,即-1。通过对节点进行集约化,可以无须在意Sigmoid层中琐碎的细节,只需要注意它的输入和输出。


class Sigmoid:def __init__(self):self.out = Nonedef forward(self,x):out = 1 / (1 + np.exp(-x))self.out = outreturn outdef backward(self,dout):dx = dout * (1.0 - self.out) * self.outreturn dx

9、Affine层的实现:神经网络的正向传播中进行的矩阵乘积运算在几何学领域被称为“仿射变换”,仿射变换的处理过程即Affine层的实现过程。比如正向传播为了计算加权信号总和,使用了矩阵的乘积运算,Y = np.dot(X,W) + B,在反向传播时以矩阵为对象,按矩阵各个元素进行计算,步骤和以标量为对象的计算图相同。

批版本的Affine层:输入X的形状由(1,2)变为(N,2),在正向传播时,偏置会被加到X▪W的各个数据上,比如N=2时偏置会被分别加到这两个数据计算结果上;反向传播时,各个数据的反向传播值需要汇总为偏置元素,使用np.sum()函数(axis=0指定0维)指定对应轴方向上的元素进行求和。

class Affine:def __init__(self,W,b):self.W = Wself.b = bself.x = Noneself.dW = Noneself.db = Nonedef forward(self,x):self.x = xout = np.dot(x,self.W) + self.breturn outdef backward(self,dout):dx = np.dot(dout,self.W.T)self.dW = np.dot(self.x.T,dout)self.db = np.sum(dout,axis=0)return dx

10、Softmax-with-Loss层:Softmax会将输入值正规化之后再输出(将输出值的和调整为1),考虑到也包含作为损失函数的交叉熵误差(cross entropy error),所以称为Softmax-with-Loss层。

上述计算图可以进行简化,softmax函数记为Softmax层,交叉熵误差记为Cross Entropy Error层,假设要进行3类分类,从前面层接收3个输入,Softmax层将这3个输入(a1,a2,a3)正规化,输出(y1,y2,y3),Cross Entropy Error层接收(y1,y2,y3)和监督标签(t1,t2,t3),从这些数据中输出损失L。反向传播时Softmax层得到的(y1-t1,y2-t2,y3-t3)是该层输出和监督标签的差分,神经网络的反向传播会把这个差分表示的误差传递给前面的层,这是神经网络学习的重要性质,因为神经网络的学习目的就是通过调整权重参数,使神经网络的输出接近监督标签(y与t)。

class SoftmaxWithLoss:def __init__(self):self.loss = Noneself.y = Noneself.t = Nonedef forward(self,x,t):self.t = tself.y = softmax(x)self.loss = cross_entropy_error(self.y,self.t)return self.lossdef backward(self,dout = 1):batch_size = self.t.shape[0]dx = (self.y - self.t) / batch_size#传递给前面层的是单个数据的误差return dx

11、误差反向传播法的实现
①前提:神经网络中有合适的权重和偏置,调整权重和偏置以便拟合训练的过程称为学习;
②mini-batch:从训练数据中随机选择一部分数据;
③计算梯度:计算损失函数关于各个权重参数的梯度;
④更新参数:将权重参数沿着梯度方向进行微小更新;
⑤重复上述步骤。
误差反向传播法主要在③中得以运用,和需要花费较多时间的数值微分不同,误差反向传播法可以快速高效地计算梯度,通过使用层,获得识别结果的处理(predict())和计算梯度的处理(gradient())只需要通过层之间的传递就能实现。在确认误差反向传播法的实现是否正确时需要使用数值微分,将两者的结果进行比较的操作称为梯度确认

class TwoLayerNet:def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):#初始化权重self.params = {}self.params['W1'] = weight_init_std * np.random.randn(input_size,hidden_size)self.params['b1'] = np.zeros(hidden_size)self.params['W2'] = weight_init_std * np.random.randn(hidden_size,output_size)self.params['b2'] = np.zeros(output_size)#生成层self.layers = OrderedDict()self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])self.layers['Relu1'] = Relu()self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])self.lastLayer = SoftmaxWithLoss()def predict(self,x):for layer in self.layers.values():x = layer.forward(x)return xdef loss(self,x,t):y = self.predict(x)return self.lastLayer.forward(y,t)def accuracy(self,x,t):y = self.predict(x)y = np.argmax(y,axis=1)if t.ndim != 1:t = np.argmax(t,axis=1)accuracy = np.sum(y==t) / float(x.shape[0])return accuracydef numerical_gradient(self,x,t):loss_W = lambda W: self.loss(x,t)grads = {}grads['W1'] = numerical_gradient(loss_W, self.params['W1'])grads['b1'] = numerical_gradient(loss_W, self.params['b1'])grads['W2'] = numerical_gradient(loss_W, self.params['W2'])grads['b2'] = numerical_gradient(loss_W, self.params['b2'])return gradsdef gradient(self,x,t):#forwardself.loss(x,t)#backwarddout = 1dout = self.lastLayer.backward(dout)layers = list(self.layers.values())layers.reverse()for layer in layers:dout = layer.backward(dout)#设定grads = {}grads['W1'] = self.layers['Affine1'].dWgrads['b1'] = self.layers['Affine1'].dbgrads['W2'] = self.layers['Affine2'].dWgrads['b2'] = self.layers['Affine2'].dbreturn grads

将神经网络的层保存为OrderDict有序字典,自身可以记住向字典里添加元素的顺序,正向传播只需按照添加元素的顺序调用各层的forward()方法,反向传播则按照相反的顺序调用各层。

神经网络之误差反向传播法相关推荐

  1. 【深度学习的数学】2×3×1层带sigmoid激活函数的神经网络感知机对三角形平面的分类训练预测(绘制出模型结果三维图展示效果)(梯度下降法+最小二乘法+激活函数sigmoid+误差反向传播法)

    文章目录 训练数据 数据示意 训练数据生成及绘制三维图像代码 训练数据三维图像 搭建神经网络结构 网络结构 利用梯度下降法和误差反向传播法计算损失函数损失值 代码 [灾难降临]代码出现严重问题,已将其 ...

  2. 误差反向传播法(二)【神经网络以层的方式实现】

    我们来看激活函数层的实现,对于激活函数,大家初学神经网络的时候就经常听到,准确来说是在接触感知机的时候熟悉的,它是进入神经网络大门的钥匙,是现代神经网络快速发展的源头. ReLU层(Rectified ...

  3. 深度学习入门-误差反向传播法(人工神经网络实现mnist数据集识别)

    文章目录 误差反向传播法 5.1 链式法则与计算图 5.2 计算图代码实践 5.3激活函数层的实现 5.4 简单矩阵求导 5.5 Affine 层的实现 5.6 softmax-with-loss层计 ...

  4. 一文弄懂神经网络中的反向传播法——BackPropagation

    https://www.cnblogs.com/charlotte77/p/5629865.html 最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是 ...

  5. 一文弄懂神经网络中的反向传播法

    最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进 ...

  6. 一文弄懂神经网络中的反向传播法——BackPropagation【转】

    本文转载自:https://www.cnblogs.com/charlotte77/p/5629865.html 一文弄懂神经网络中的反向传播法--BackPropagation 最近在看深度学习的东 ...

  7. [转] 一文弄懂神经网络中的反向传播法——BackPropagation

    在看CNN和RNN的相关算法TF实现,总感觉有些细枝末节理解不到位,浮在表面.那么就一点点扣细节吧. 这个作者讲方向传播也是没谁了,666- 原文地址:https://www.cnblogs.com/ ...

  8. 深度学习入门|第5章 误差反向传播法(二)

    误差反向传播法 前言 此为本人学习<深度学习入门>的学习笔记 四.简单层的实现 本节将用 Python 实现前面的购买苹果的例子.这里,我们把要实现的计算图的乘法节点称为"乘法层 ...

  9. BP反向传播一文弄懂神经网络中的反向传播法

    最近在看深度学习的东西,一开始看的吴恩达的UFLDL教程,有中文版就直接看了,后来发现有些地方总是不是很明确,又去看英文版,然后又找了些资料看,才发现,中文版的译者在翻译的时候会对省略的公式推导过程进 ...

最新文章

  1. Django CMS教程一:安装
  2. Oozie 出现 ClassNotFoundException 解决方法
  3. 19.12 添加自定义监控项目 19.13/19.14 配置邮件告警 19.15 测试告警 19.16 不发邮件的问题处理...
  4. 当 高并发系统下 Redis 发生高延迟时,其内部到底发生了什么
  5. 027——VUE中事件修饰符:stop prevent self capture
  6. as3.0横向渐变发光字
  7. QT应用编程: 编写HC05串口蓝牙调试助手(Android系统APP)
  8. 红旗Linux中文教程
  9. 电脑上怎么批量压缩图片?如何快速批量压缩图片?
  10. Java并发教程(Oracle官方资料) 分享
  11. 遥感影像地图分类识别的研究与实现
  12. 在浏览器中打开“只能用微信内置浏览器”打开的页面
  13. 【C++】C++基础语法
  14. Vue项目中750设计稿px自动转化成rem方法(小白一个,记录自己遇到的小白问题,大家勿怪)
  15. 什么办法能让鹅长头包 鹅什么药头上头瘤长得快
  16. ALGO-986 藏匿的刺客 C++
  17. HTTPS访问Git远程仓库,上报SSL证书错误解决方法
  18. python 正则表达式生成器_正则表达式生成器
  19. centos安装mysql_centos如何安装mysql
  20. c++英雄联盟_C联盟

热门文章

  1. 【python设计模式】6、装饰器模式
  2. cmd导入导出mysql中的数据库为sql文件
  3. 解决windows服务器装虚拟机windows系统无网络连接网络
  4. linu安装python走到300就不动了_linux centos 安装python3.7报错会在load avg: 0.63 [307/416] test_socket卡住 解决办法...
  5. 电信校园招聘计算机真题,2019中国电信校园招聘试题(一)
  6. C++在线编辑器:cpp.sh
  7. 使用汉明距离、LAB色彩空间相似性来衡量图片相似性
  8. Javascript 设计模式之代理模式【讲师辅导】-曾亮-专题视频课程
  9. 2021四川省赛A,B,D,H,K
  10. 238 除自身以外数组的乘积(前后缀分解)