学习 backward

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的Function3.  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)

本文链接:https://my.lmcjl.com/post/11363.html

展开阅读全文

4 评论

留下您的评论.