第5章——深度学习入门(鱼书)

 第5章 误差反向传播法

上一章中,我们介绍了神经网络的学习,并通过数值微分计算了神经网络的权重参数的梯度(严格来说,是损失函数关于权重参数的梯度)。数值微分虽然简单,也容易实现,但缺点是计算上比较费时间。本章我们将学习一个能够高效计算权重参数的梯度的方法——误差反向传播法。

要正确理解误差反向传播法,我个人认为有两种方法:一种是基于数学式;另一种是基于计算图(computational graph)。前者是比较常见的方法,机器学习相关的图书中多数都是以数学式为中心展开论述的。因为这种方法严密且简洁,所以确实非常合理,但如果一上来就围绕数学式进行探讨,会忽略一些根本的东西,止步于式子的罗列。因此,本章希望大家通过计算图,直观地理解误差反向传播法。然后,再结合实际的代码加深理解,相信大家一定会有种“原来如此!”的感觉。

5.1 计算图

计算图将计算过程用图形表示出来。这里说的图形是数据结构图,通过多个节点和边表示(连接节点的直线称为“边”)。为了让大家熟悉计算图,本节先用计算图解一些简单的问题。从这些简单的问题开始,逐步深入,最终抵达误差反向传播法。

5.1.1 用计算图求解

现在,我们尝试用计算图解简单的问题。下面我们要看的几个问题都是用心算就能解开的简单问题,这里的目的只是通过它们让大家熟悉计算图。掌握了计算图的使用方法之后,在后面即将看到的复杂计算中它将发挥巨大威力,所以本节请一定学会计算图的使用方法。

问题1:太郎在超市买了2个100日元一个的苹果,消费税是10%,请计算支付金额。 

计算图通过节点和箭头表示计算过程。节点用○表示,○中是计算的内容。将计算的中间结果写在箭头的上方,表示各个节点的计算结果从左向右传递。用计算图解问题1,求解过程如图5-1所示。

如图5-1所示,开始时,苹果的100日元流到“× 2”节点,变成200日元,然后被传递给下一个节点。接着,这个200日元流向“× 1.1”节点,变成220日元。因此,从这个计算图的结果可知,答案为220日元。

虽然图5-1中把“× 2”“× 1.1”等作为一个运算整体用○括起来了,不过只用○表示乘法运算“×”也是可行的。此时,如图5-2所示,可以将“2”和“1.1”分别作为变量“苹果的个数”和“消费税”标在○外面。

问题2:太郎在超市买了2个苹果、3个橘子。其中,苹果每个100日元,橘子每个150日元。消费税是10%,请计算支付金额。同问题1,我们用计算图来解问题2,求解过程如图5-3所示。

这个问题中新增了加法节点“+”,用来合计苹果和橘子的金额。构建了计算图后,从左向右进行计算。就像电路中的电流流动一样,计算结果从左向右传递。到达最右边的计算结果后,计算过程就结束了。从图5-3中可知,问题2的答案为715日元。

综上,用计算图解题的情况下,需要按如下流程进行。

1.构建计算图。

2.在计算图上,从左向右进行计算。 

这里的第2歩“从左向右进行计算”是一种正方向上的传播,简称为正向传播(forward propagation)。正向传播是从计算图出发点到结束点的传播。既然有正向传播这个名称,当然也可以考虑反向(从图上看的话,就是从右向左)的传播。实际上,这种传播称为反向传播(backward propagation)。反向传播将在接下来的导数计算中发挥重要作用。

5.1.2 局部计算

计算图的特征是可以通过传递“局部计算”获得最终结果。“局部”这个词的意思是“与自己相关的某个小范围”。局部计算是指,无论全局发生了什么,都能只根据与自己相关的信息输出接下来的结果。

我们用一个具体的例子来说明局部计算。比如,在超市买了2个苹果和其他很多东西。此时,可以画出如图5-4所示的计算图。

如图5-4所示,假设(经过复杂的计算)购买的其他很多东西总共花费4000日元。这里的重点是,各个节点处的计算都是局部计算。这意味着,例如苹果和其他很多东西的求和运算(4000 + 200 → 4200)并不关心4000这个数字是如何计算而来的,只要把两个数字相加就可以了。换言之,各个节点处只需进行与自己有关的计算(在这个例子中是对输入的两个数字进行加法运算),不用考虑全局。

综上,计算图可以集中精力于局部计算。无论全局的计算有多么复杂,各个步骤所要做的就是对象节点的局部计算。虽然局部计算非常简单,但是通过传递它的计算结果,可以获得全局的复杂计算的结果。

比如,组装汽车是一个复杂的工作,通常需要进行“流水线”作业。 每个工人(机器)所承担的都是被简化了的工作,这个工作的成果会传递给下一个工人,直至汽车组装完成。计算图将复杂的计算分割成简单的局部计算,和流水线作业一样,将局部计算的结果传递给下一个节点。在将复杂的计算分解成简单的计算这一点上与汽车的组装有相似之处。

5.1.3 为何用计算图解题

前面我们用计算图解答了两个问题,那么计算图到底有什么优点呢?一个优点就在于前面所说的局部计算。无论全局是多么复杂的计算,都可以通过局部计算使各个节点致力于简单的计算,从而简化问题。另一个优点是,利用计算图可以将中间的计算结果全部保存起来(比如,计算进行到2个苹果时的金额是200日元、加上消费税之前的金额650日元等)。但是只有这些理由可能还无法令人信服。实际上,使用计算图最大的原因是,可以通过反向传播高效计算导数。

在介绍计算图的反向传播时,我们再来思考一下问题1。问题1中,我们计算了购买2个苹果时加上消费税最终需要支付的金额。这里,假设我们想知道苹果价格的上涨会在多大程度上影响最终的支付金额,即求“支付金额关于苹果的价格的导数”。设苹果的价格为x,支付金额为L,则相当于求\frac{\partial L}{\partial x}

。这个导数的值表示当苹果的价格稍微上涨时,支付金额会增加多少。

如前所述,“支付金额关于苹果的价格的导数”的值可以通过计算图的反向传播求出来。先来看一下结果,如图5-5所示,可以通过计算图的反向传播求导数(关于如何进行反向传播,接下来马上会介绍)。

如图5-5所示,反向传播使用与正方向相反的箭头(粗线)表示。反向传播传递“局部导数”,将导数的值写在箭头的下方。在这个例子中,反向传播从右向左传递导数的值(1 → 1.1 → 2.2)。从这个结果中可知,“支付金额 关于苹果的价格的导数”的值是2.2。这意味着,如果苹果的价格上涨1日元,最终的支付金额会增加2.2日元(严格地讲,如果苹果的价格增加某个微小值,则最终的支付金额将增加那个微小值的2.2倍)。

这里只求了关于苹果的价格的导数,不过“支付金额关于消费税的导数”“支付金额关于苹果的个数的导数”等也都可以用同样的方式算出来。并且,计算中途求得的导数的结果(中间传递的导数)可以被共享,从而可以高效地计算多个导数。综上,计算图的优点是,可以通过正向传播和反向传播高效地计算各个变量的导数值。

5.2 链式法则

前面介绍的计算图的正向传播将计算结果正向(从左到右)传递,其计算过程是我们日常接触的计算过程,所以感觉上可能比较自然。而反向传播将局部导数向正方向的反方向(从右到左)传递,一开始可能会让人感到困惑。传递这个局部导数的原理,是基于链式法则(chain rule)的。本节将介绍链式法则,并阐明它是如何对应计算图上的反向传播的。

5.2.1 计算图的反向传播

话不多说,让我们先来看一个使用计算图的反向传播的例子。假设存在y = f(x)的计算,这个计算的反向传播如图5-6所示。

5.2.2 什么是链式法则

介绍链式法则时,我们需要先从复合函数说起。复合函数是由多个函数构成的函数。比如,z = (x + y)2 是由式(5.1)所示的两个式子构成的。

如果某个函数由复合函数表示,则该复合函数的导数可以用构成复合函数的各个函数的导数的乘积表示。

5.3 反向传播

5.3.1 加法节点的反向传播

5.3.2 乘法节点的反向传播

5.4 简单层的实现

5.5 激活函数层的实现

5.5.1 ReLU层
在神经网络的层的实现中,一般假定 forward()和 backward() 的参数是 NumPy 数组。
ReLU层的作用就像电路中的开关一样 。正向传播时,有电流通过的话,就将开关设为 ON;没有电流通过的话,就将开关设为 OFF。反向传播时,开关为ON的话,电流会直接通过;开关为OFF的话,则不会有电流通过。
5.5.2 Sigmoid层

5.6 Affine/Softmax层的实现

5.6.1 Affine层

5.6.2 批版本的Affine层

5.6.3 Softmax-with-Loss 层

最后介绍一下输出层的 softmax 函数。前面我们提到过, softmax 函数会将输入值正规化之后再输出。比如手写数字识别时, Softmax 层的输出如图 5-28 所示。
在图 5-28 中, Softmax层将输入值正规化(将输出值的和调整为1)之后再输出 。另外,因为手写数字识别要进行 10 类分类,所以向 Softmax 层的输入也有 10 个。
神经网络中进行的处理有推理(inference)和学习两个阶段 。神经网络的推理通常不使用 Softmax层。比如,用图 5-28的网络进行推理时,会将最后一个 Affine层的输出作为识别结果。神经网络中未被正规化的输出结果(图 5-28中 Softmax层前面的 Affine层的输出)有时被称为“得分”。也就是说,当神经网络的推理只需要给出一个答案的情况下,因为此时只对得分最大值感兴趣,所以不需要 Softmax层。不过,神经网络的学习阶段则需要 Softmax层。
使用 交叉熵误差 作为 softmax函数的损失函数后,反向传播得到( y 1 t 1 , y 2 t 2 , y 3 t 3 )这样“漂亮”的结果。实际上,这样“漂亮”的结果并不是偶然的,而是为了得到这样的结果,特意设计了交叉熵误差函数。回归问题中输出层使用“恒等函数”,损失函数使用“平方和误差”,也是出于同样的理由(3.5节)。也就是说,使用“平方和误差”作为“恒等函数”的损失函数,反向传播才能得到( y 1 −t 1 , y 2 t 2 , y 3 t 3 )这样“漂亮”的结果。

5.7 误差反向传播法的实现

通过像组装乐高积木一样组装上一节中实现的层,可以构建神经网络。本节我们将通过组装已经实现的层来构建神经网络。

5.7.1 神经网络学习的全貌图

在进行具体的实现之前,我们再来确认一下神经网络学习的全貌图。神经网络学习的步骤如下所示。
前提
神经网络中有合适的权重和偏置,调整权重和偏置以便拟合训练数据的过程称为学习。神经网络的学习分为下面 4 个步骤。
步骤 1 mini-batch
从训练数据中随机选择一部分数据。
步骤 2 (计算梯度)
计算损失函数关于各个权重参数的梯度。
步骤 3 (更新参数)
将权重参数沿梯度方向进行微小的更新。
步骤 4 (重复)
重复步骤 1 、步骤 2 、步骤 3
之前介绍的误差反向传播法会在步骤 2 中出现。上一章中,我们利用数值微分求得了这个梯度。数值微分虽然实现简单,但是计算要耗费较多的时间。和需要花费较多时间的数值微分不同,误差反向传播法可以快速高效地计算梯度。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

CODE V的API 之 PSF数据的获取(3)

PSF的获取 文章目录 PSF的获取前言一、主要代码总结 前言 主要利用buf语句进行传递,在worksheet中有收藏。 一、主要代码 Sub OnRunPSF() Dim session As CVCommand Set session CreateObject("CodeV.Command.102") session.SetStartingDirectory (&q…

C++分支语句

个人主页:PingdiGuo_guo 收录专栏:C干货专栏 大家新年快乐,今天,我们来了解一下分支语句。 文章目录 1.什么是分支语句 1.if语句 基本形式 用法说明 练习 2.if-else语句 基本形式 用法说明 练习 3.switch语句 基本形式…

进程间通信(4):消息队列

先进先出,保证信息的有序性。 函数:msgget(搭配ftok)、msgsnd、msgrcv、msgctl 实现流程: 1、创建消息队列IPC对象 msgget 2、通信(内置函数:msgsnd、msgrcv) 3、删除消息队列IPC对象 msgctl write.c /* * 文件名称&…

数字图像处理实验记录九(数字形态学实验)

一、基础知识 1.形态学,用于从图像中提取对表达和描绘区域形状有意义的图像分量,使后续的识别工作能够抓住目标对象最为有本质的形状特征,如边界连通区域等。 2.膨胀运算:膨胀会使目标区域范围“变大”,将于目标区域接…

第三百一十五回

文章目录 1. 概念介绍2. 基本用法3. 补充用法4. 内容总结 我们在上一章回中介绍了"再谈ListView中的分隔线",本章回中将介绍showMenu的用法.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在第一百六十三回中介绍了showMenu相关的内容…

C语言指针函数学习2

之前写过一篇指针函数的博文;复习再学习一下; 指针函数,是一个函数,它的返回值是指针类型; 之前写了一个指针函数,返回一个 int * 类型的指针;下面做一个程序,返回一个结构体指针&a…

如何给闲置电脑安装黑群晖

准备 diskgenius ,黑群晖引导文件(有些需要扩展驱动包),如果给U盘安装需要balenaEtcher或者rufus(U盘安装还需要ChipGenus),如果给硬盘安装需要有pe推荐firePE或U启通 我以U盘为例 首先去找这…

【声明】关于抄袭我博客的声明

最近发现有人在抄袭我的博客,你抄了就算了,你连原链接也不贴,直接就设置的是原创的,你脸去哪了啊? 在你评论下面说了两次还在抄,事不过三,今天早上发现你又抄了一篇。既然如此,我就…

面向智算服务,构建可观测体系最佳实践

作者:蓟北 构建面向 AI、大数据、容器的可观测体系 (一)智算服务可观测概况 对于越来越火爆的人工智能领域来说,MLOps 是解决这一领域的系统工程,它结合了所有与机器学习相关的任务和流程,从数据管理、建…

前端JavaScript篇之对执行上下文的理解

目录 对执行上下文的理解创建执行上下文 对执行上下文的理解 当我们在执行JavaScript代码时,JavaScript引擎会创建并维护一个执行上下文栈来管理执行上下文。执行上下文有三种类型:全局执行上下文、函数执行上下文和eval函数执行上下文。 在写代码的时…

代码随想录算法训练营第二十五天 |216.组合总和III,17.电话号码的字母组合(已补充)

剪枝操作讲解:(已观看) 带你学透回溯算法-组合问题的剪枝操作(对应力扣题目:77.组合)| 回溯法精讲!_哔哩哔哩_bilibili 216.组合总和III(已观看) 1、题目链接&#xf…

参观宋代建筑,感受传统魅力

为了更好地了解和传承中华文化,同时深入挖掘其在现代社会的传承与发展,2024年2月8日,曲阜师范大学计算机学院“古韵新声,格物致‘知’”社会实践队队员饶子恒深入考察中国传统建筑和文化,前往山东省菏泽市郓城县的水浒…

【Flink状态管理(二)各状态初始化入口】状态初始化流程详解与源码剖析

文章目录 1. 状态初始化总流程梳理2.创建StreamOperatorStateContext3. StateInitializationContext的接口设计。4. 状态初始化举例:UDF状态初始化 在TaskManager中启动Task线程后,会调用StreamTask.invoke()方法触发当前Task中算子的执行,在…

SolidWorks学习笔记——草图绘制的基本命令

目录 一、进入草图绘制 二、直线命令与删除命令 三、圆弧命令与矩形命令 四、槽口命令以及多边形命令 五、椭圆以及倒角命令 六。草图绘制中的剪裁命令 七、草图中的几何关系 八、草图绘制中的智能尺寸 九、从外部粘贴草图(CAD) 一、进入草图绘…

ongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成

Swagger是什么? Swagger是一个规范且完整API文档管理框架,可以用于生成、描述和调用可视化的RESTful风格的 Web 服务。Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就…

Linux系统中HTTP代理的常见问题及解决方案

亲爱的Linux用户们,是不是有时候觉得HTTP代理就像是一个魔法盒子,让你在数字世界中自由穿梭?但是,就像所有的魔法物品一样,它也会偶尔出点小状况。今天,我们就来一起探讨一下Linux系统中HTTP代理的常见问题…

MyBatis之动态代理实现增删改查以及MyBatis-config.xml中读取DB信息文件和SQL中JavaBean别名配置

MyBatis之环境搭建以及实现增删改查 前言实现步骤1. 编写MyBatis-config.xml配置文件2. 编写Mapper.xml文件(增删改查SQL文)3. 定义PeronMapper接口4. 编写测试类1. 执行步骤2. 代码实例3. 运行log 开发环境构造图总结 前言 上一篇文章,我们…

Excel——合并计算

1.表格的合并计算(单张表格/多个表格) Q:请统计两个表格中各商品的总销量和总销售额,将结果放置在下方任意位置。 A:选择一个需要将合并计算数据放置区域的空白单元格 选择【数据】——【合并计算】,【函…

【Spring】Tomcat服务器部署

📝个人主页:五敷有你 🔥系列专栏:Spring⛺️稳中求进,晒太阳 单体项目部署 本地工作 项目在本地开发完毕之后进行一些必要参数的修改。 比如: 数据库的JDBC的配置文件,还有前端页面的…

STM32学习笔记——定时器

目录 一、定时器功能概述 1、基本定时器(TIM6&TIM7) 工作原理 时序 2、通用计时器(TIM2&TIM3&TIM4&TIM5) 时钟源 外部时钟源模式1&2 外部时钟源模式2 外部时钟源模式1 定时器的主模式输出 输入捕获…