学习 backward

本文详细解析了PyTorch中反向传播的关键函数`backward()`,包括`grad_tensors`、`retain_graph`和`create_graph`参数的作用。通过实例展示了如何处理标量和张量的梯度计算,以及如何利用`backward()`进行多步梯度计算。此外,还解释了计算图的概念和自动求导原理。
摘要由CSDN通过智能技术生成
import torch
#=======================backward:深度学习中最为重要的反向传播计算==================
'''
backward(tensors,grad_tensors=None,retain_graph=None,create_graph=False,grad_varibles=None):
          有三个比较重要的参数grad_tensors,retain_graph,create_graph
          
          关于retain_graph,create_graph:
          pytoch构建的计算图是动态图,为了节约内存,所以每次一轮迭代完也即是进行了一次backward函数计算之
          后计算图就被在内存释放,因此如果你需要多次backward只需要在第一次反向传播时候添加一个
          retain_graph=True标识,让计算图不被立即释放。实际上文档中retain_graph和create_graph
          两个参数作用相同,因为前者是保持计算图不释放,而后者是创建计算图,因此如果我们不想要计算图释放掉,
          将任意一个参数设置为True都行。
'''
#===============================关于grad_tensors参数=================================
'''
          
1.  创建一个张量x,并设置其 requires_grad参数为True,程序将会追踪所有对于该张量的操作,
    当完成计算后通过调用 .backward(),自动计算所有的梯度,这个张量的所有梯度将会自动积累到 .grad 属性。
    
2.  创建一个关于x的函数z,由于x的requires_grad参数为True,所以y对应的用于求导的参数grad_fn为<...Backward0>.
    -----原因:
    自动梯度的计算中有一个Function类,Tensor和Function互相连接生成非循环图,存储完整计算历史,每个张量都有一个
    .grad_fn属性,这个属性引用了一个创建了Tensor的Function

3.  z.backward()时,如果y是标量(scalar),则不需要为backward()传入任何参数; 如果y是张量(tensor),
    需要传入一个与y同形的Tensor(张量)
    ------原因是:
    如果是标量对向量求导(scalar对tensor求导),那么就可以保证计算图的根节点只有一个,此时不用引入grad_tensors
    参数,直接调用backward函数即可。
    如果是(向量)矩阵对(向量)矩阵求导(tensor对tensor求导),实际上是先求出Jacobian(雅克比)矩阵中每一个元素
    的梯度值(每一个元素的梯度值的求解过程对应上面的计算图的求解方法),然后将这个Jacobian矩阵与grad_tensors
    参数对应的矩阵进行对应的点乘,得到最终的结果。
    
'''
#=====Z是标量===
x=torch.tensor([1.0,2.0],dtype=torch.float32,requires_grad=True)
y=(x+2).pow(2)
print(y)
z=torch.mean(y)
print(z)
z.backward()
print(x.grad)
#======y是Tensor张量,直接像标量一样会报错====
# x=torch.tensor([1.0,2.0],requires_grad=True)
# y=(x+2).pow(2)
# print(y)
# z = 4*y
# z.backward()
# print(x.grad)

#====z是Tensor张量的正确做法===========
x=torch.tensor([1.0,2.0,3.0],requires_grad=True)
y=(x+2).pow(2)
z=4*y
z.backward(torch.tensor([1,1,1]))#其实添加的这个tensor是待求得x的梯度的系数;即grad_tensors参数对应的矩阵
print(x.grad)
#==========例子============
x=torch.tensor([[1,2,3,]],dtype=torch.float32,requires_grad=True)
Jacobian=torch.zeros(3,3)
y=torch.zeros(1,3)
y[0,0] = x[0,0]**2 + 2*x[0,1]
y[0,1] = x[0,1]**2 + 4*x[0,0]
y[0,2] = x[0,2]**2 + 2*x[0,0] +x[0,1]
#====每次求导前需要清0,不然会在前面求导结果上迭代
y.backward(torch.tensor([[1,0,0]]),retain_graph=True)
print(x.grad)
y.backward(torch.tensor([[0,1,0]]),retain_graph=True)
print(x.grad)
y.backward(torch.tensor([[0,0,1]]),retain_graph=True)
print(x.grad)
y.backward(torch.tensor([[1,1,1]]),retain_graph=True)
print(x.grad)

参考链接:(88条消息) pytorch中backward()函数详解_Camlin_Z的博客-CSDN博客_backward()

                 Pytorch中的backward函数 - 知乎 (zhihu.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值