当前位置: 首页 > ai >正文

深度学习(鱼书)day07--误差反向传播(前四节)

深度学习(鱼书)day07–误差反向传播(前四节)

数值微分虽然简单,也容易实现,但缺点是计算上比较费时间。本章学习一个能够高效计算权重参数的梯度的方法——误差反向传播法

在这里插入图片描述

一、计算图

计算图将计算过程用图形表示出来。这里说的图形是数据结构图,通过多个节点和边表示(连接节点的直线称为“边”)。

  1. 用计算图求解

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

    可以将“2”和“1.1”分别作为变量“苹果的个数”和“消费税”标在○外面。

在这里插入图片描述

问题2:太郎在超市买了2个苹果、3个橘子。其中,苹果每个100日元,橘子每个150日元。消费税是10%,请计算支付金额。
在这里插入图片描述

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

1.构建计算图。

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

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

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

    比如,在超市买了2个苹果和其他很多东西。

在这里插入图片描述

这里的重点是,各个节点处的计算都是局部计算。这意味着,例如苹果和其他很多东西的求和运算(4000 + 200 4200)并不关心4000这个数字是如何计算而来的,只要把两个数字相加就可以了。换言之, 各个节点处只需进行与自己有关的计算(在这个例子中是对输入的两个数字进行加法运算),不用考虑全局。

  1. 为何用计算图解题

    使用计算图最大的原因是,可以通过反向传播高效计算导数

    假设我们想知道苹果价格的上涨会在多大程度上影响最终的支付金额,即求“支付金额关于苹果的价格的导数”。设苹果的价格为x,支付金额为L,则相当于求在这里插入图片描述
    这个导数的值表示当苹果的价格稍微上涨时,支付金额会增加多少。

在这里插入图片描述

反向传播从右向左传递导数的值(1 1.1 2.2)。“支付金额关于苹果的价格的导数”的值是2.2,如果苹果的价格上涨1日元,最终的支付金额会增加2.2日元(严格地讲,如果苹果的价格增加某个微小值,则最终的支付金额将增加那个微小值的2.2倍)。

二、链式法则

传递这个局部导数的原理,是基于 链式法则(chain rule) 的。

  1. 计算图的反向传播

    假设存在y = f(x)的计算,这个计算的反向传播如图所示。反向传播的计算顺序是,将信号E乘以节点的局部导数在这里插入图片描述
    ,然后将结果传递给下一个节点。

在这里插入图片描述

  1. 什么是链式法则

    我们需要先从复合函数说起。复合函数是由多个函数构成的函数。比如,z = (x + y) 2 是由式(5.1)所示的两个式子构成的。
    z=t2t=x+y z=t^2\\ t=x+y z=t2t=x+y
    如果某个函数由复合函数表示,则该复合函数的导数可以用构成复合函数的各个函数的导数的乘积表示。
    在这里插入图片描述

  2. 链式法则和计算图

    如果用“**2”节点表示平方运算的话,则计算图如图所示。

在这里插入图片描述

三、反向传播

  1. 加法节点的反向传播
    在这里插入图片描述

    本例中把从上游传过来的导数的值设为在这里插入图片描述
    。这是因为,如图所示,我们假定了一个最终输出值为L的大型计算图。

在这里插入图片描述

在这里插入图片描述

  1. 乘法节点的反向传播

    我们考虑z = xy

在这里插入图片描述

乘法的反向传播会将上游的值乘以正向传播时的输入信号的“翻转值”后传递给下游

在这里插入图片描述

实现乘法节点的反向传播时,要保存正向传播的输入信号

  1. 苹果的例子

    这里要解的问题是苹果的价格、苹果的个数、消费税这3个变量各自如何影响最终支付的金额。这个问题相当于求“支付金额关于苹果的价格的导数”“支付金额关于苹果的个数的导数”“支付金额关于消费税的导数”。用计算图的反向传播来解的话,求解过程如图所示。

    在这里插入图片描述

    练习:求解“购买苹果和橘子”的反向传播。

在这里插入图片描述

四、简单层的实现

我们用Python实现前面的购买苹果的例子。这里,把要实现的计算图的乘法节点称为 “乘法层”(MulLayer),加法节点称为 “加法层”(AddLayer)

  • 乘法层的实现

    层的实现中有两个共通的方法(接口)forward()和backward()。forward()对应正向传播,backward()对应反向传播。

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

    forward()接收x和y两个参数,将它们相乘后输出。backward()将从上游传来的导数(dout)乘以正向传播的翻转值,然后传给下游。

在这里插入图片描述

     from layerNaive import *mul_apple_layer = MulLayer()mul_tax_layer = MulLayer()apple = 100apple_num = 2tax = 1.1# forwardapple_price = mul_apple_layer.forward(apple, apple_num)price = mul_tax_layer.forward(apple_price, tax)# backwarddprice = 1dapple_price, dtax = mul_tax_layer.backward(dprice)dapple, dapple_num = mul_apple_layer.backward(dapple_price)print("price:", int(price))print("dApple:", dapple)print("dApple_num:", int(dapple_num))print("dTax:", dtax)

在这里插入图片描述

  • 加法层的实现

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

    我们使用加法层和乘法层,实现图所示的购买2个苹果和3个橘子的例子。
    在这里插入图片描述

from layerNaive import *
apple = 100
apple_num = 2
orange = 150
orange_num = 3
tax = 1.1# layer
mul_apple_layer = MulLayer()
mul_orange_layer = MulLayer()
mul_tax_layer = MulLayer()
add_apple_orange_layer = AddLayer()
# forward
apple_price = mul_apple_layer.forward(apple, apple_num)
orange_price = mul_orange_layer.forward(orange, orange_num)
all_price = add_apple_orange_layer.forward(apple_price, orange_price)
price = mul_tax_layer.forward(all_price, tax)# backward
dprice = 1
dall_price, dtax = mul_tax_layer.backward(dprice)
dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price)
dorange, dorange_num = mul_orange_layer.backward(dorange_price)
dapple, dapple_num = mul_apple_layer.backward(dapple_price)print("price:", int(price))
print("dApple:", dapple)
print("dApple_num:", int(dapple_num))
print("dOrange:", dorange)
print("dOrange_num:", int(dorange_num))
print("dTax:", dtax)

在这里插入图片描述

http://www.xdnf.cn/news/16676.html

相关文章:

  • 基于PyTorch利用CNN实现MNIST的手写数字识别
  • 抽象工厂模式
  • 视觉图像处理中级篇 [2]—— 外观检查 / 伤痕模式的原理与优化设置方法
  • 中宇联:以“智云融合+AI”赋能全栈云MSP服务,深化阿里云生态合作
  • 【大模型理论篇】混合思考之自适应思维链
  • Kubernetes架构概览
  • MySQL转PostgreSQL迁移实战:从语法错误到完美兼容
  • spring cloud ——gateway网关
  • 嵌入式系统常用架构
  • 【02】大恒相机SDK C#开发 —— 初始化相机,采集第一帧图像
  • 如何使用一台电脑adb调试多个Android设备
  • vue+elementUI上传图片至七牛云组件封装及循环使用
  • 【机器学习】KNN算法与模型评估调优
  • 蓝牙 BR/EDR 与 BLE PHY
  • 告别物业思维:科技正重构产业园区的价值坐标系
  • 微信小程序中进行参数传递的方法
  • 基于Spring Boot实现中医医学处方管理实践
  • 【数据结构】算法代码
  • 将开发的软件安装到手机:环境配置、android studio设置、命令行操作
  • Coze Studio:开源AI Agent开发工具的全方位实践指南
  • Rust视频处理开源项目精选
  • 电商数据采集 API 接口:开启数据驱动业务的新引擎
  • Android依赖注入框架Hilt入门指南
  • 深度学习:损失函数Loss Function
  • Android 基础入门学习目录(持续更新)
  • Java 大视界 -- Java 大数据在智能交通公交客流预测与线路优化中的深度实践(15 城验证,年省 2.1 亿)(373)
  • 软件项目中如何编写项目计划书?指南
  • Linux日志管理与时间同步
  • 468. 验证IP地址
  • 【JavaEE】(7) 网络原理 TCP/IP 协议