跟着沐神学深度学习DAY2

07 自动求导【动手学深度学习v2】

P1 自动求导

(1)向量链式法则

  注意标量对向量求导、向量对向量求导(前一个向量大小为m,后一个向量大小为n,则结果矩阵为m*n大小)

(2)计算图的定义 

  1. 将代码分解成操作子
  2. 将计算表示成一个无环图

(3)自动求导的两种模式 

  依照链式法则,有两种方向:从前往后计算,从后往前计算。分别称作正向累积和反向累积(反向 传递)。主要是因为求导过程中存在多个中间变量。

(4)反向传递

  自动求导中的反向传递(Backpropagation),简称BP。是深度学习中一个关键的优化算法,其主要目的是通过链式法则计算神经网络各层参数的梯度,并用于更新这些参数以优化模型性能。

  计算反向时,要利用到正向中的结果,所以计算正向时要将结果保存下来。

  而且看反向这个树,下一层的结点的求导必须要依赖上一层的求导结果,例如对a求导时,要知道z对b求导的结果。  

   

P2 求导实现

(1)首先需要一个地方存储梯度,下面代码中的grad就是存储的位置。

x.requires_grad(True)  #等价于‘x=torch.arange(4.0,requires_grad=True)’
x.grad #默认值时None

 (2)计算y

y = 2 * torch.dot(x, x)
y

 (3)y.backward()就是利用反向传递求梯度,x.grad打印出y关于x每一个分量的梯度。

y.backward()
x.grad

 注意:求下一个函数导数时,注意x.grad.zero_()清理存储的梯度信息。

(4)一般不用向量对向量求导(结果为矩阵),利用sum()函数将y求和得到一个标量,然后再对x向量求导。这里,我们的目的不是计算微分矩阵,而是单独计算批量中每个样本的偏导数之和。

# 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
# 本例只想求偏导数的和,所以传递一个1的梯度是合适的
x.grad.zero_()
y = x * x
# 等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad

结果: 

tensor([0., 2., 4., 6.])

ps:帮助理解y的求和:y.sum()=x(0,0)^2+x(0,1)^2+...

将某些计算移动到记录的计算图之外

  u是记录了y的常数,此时它不是关于x的变量,用法为u=y.detach()。通俗点说就是用了detach()也就是说y=x*x不再是对x的函数,理解成y=t*t就行。

书中的话:有时,我们希望将某些计算移动到记录的计算图之外。 例如,假设y是作为x的函数计算的,而z则是作为yx的函数计算的。 想象一下,我们想计算z关于x的梯度,但由于某种原因,希望将y视为一个常数, 并且只考虑到xy被计算后发挥的作用。

这里可以分离y来返回一个新变量u,该变量与y具有相同的值, 但丢弃计算图中如何计算y的任何信息。 换句话说,梯度不会向后流经ux。 因此,下面的反向传播函数计算z=u*x关于x的偏导数,同时将u作为常数处理, 而不是z=x*x*x关于x的偏导数。

x.grad.zero_()
y = x * x
u = y.detach()
z = u * x

z.sum().backward()
x.grad == u

 (6) 即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度。 pytorch隐式构造,每次都会保存计算图。

08 线性回归 + 基础优化算法【动手学深度学习v2】

09 Softmax 回归 + 损失函数 + 图片分类数据集【动手学深度学习v2】

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值