简单的案例
内容概况
举一个简单的例子:来记录下张量在梯度计算中的作用
一、初始案例输出
requires_grad=False
import torch
x = torch.tensor([[1,2]],dtype=torch.float32,requires_grad=False)
y=x+2
z = y * y * 3
out = z.mean()
z, out # tensor([[27., 48.]]), tensor(37.5000)
# False False False False 说明张量x,y,z out 没有创建对应的梯度计算方式
print(x.requires_grad,y.requires_grad,z.requires_grad,out.requires_grad)
二、储备知识
requires_grad=True
1.grad_fn属性
torch 为每一个运算操作,创建一个对应运算类型的Function对象:包含两个主要方法
forward():执行张量的运算操作,并且记录初始、修改后的值(保存上下文)
backward():读取上下文,根据上下文以及运算的类型,反向传播梯度
import torch
x = torch.tensor([[1,2]],dtype=torch.float32,requires_grad=True)
y=x+2
z = y * y * 3
out = z.mean()
# AddBackward0 MulBackward0 MeanBackward0
print(y.grad_fn,z.grad_fn,out.grad_fn)
2.叶子张量与根张量
在torch环境中,记录张量运算的形式为有向无环图,参与运算的张量为图中结点,相对应被创建的Function类为指向边。例如:开头的例子可以表示为:
三.计算梯度
1、叶子张量的梯度
retain_graph=True # 保留计算图,一般图计算一次就会被释放
tensor.grad:保留计算的梯度
out.backward(gradient=torch.tensor(1),retain_graph=True)
x.grad # tensor([[ 9., 12.]])
验证结果:
2、获取内部张量的梯度
y.retain_grad() Enables .grad attribute for non-leaf Tensors.
来源于报错代码:
执行代码:
# 在获取内部结点梯度之前,先对之前的梯度进行归0
x.retain_grad()
y.retain_grad()
z.retain_grad()
x.grad=torch.zeros_like(x.grad)
out.backward(gradient=torch.tensor(1),retain_graph=True)
print(x.grad,y.grad,z.grad) # tensor([[ 9., 12.]]) tensor([[ 9., 12.]]) tensor([[0.5000, 0.5000]])
验证:
四.计算分支张量对于叶子张量的梯度
因为上面举得例子为标量对向量的计算,现在探究下,向量对向量的求导(雅可比矩阵)在pytorch中的实现
先看例子:由下图可知,我们目的在于获取雅可比矩阵的每一列,从而得到x的梯度,在torch中默认为根结点为标量,现在为向量,需要指定gradient参数 ,具体参考下面博客
链接: https://blog.csdn.net/Konge4/article/details/114955821