四、Tensor与Autograd

1.自动求导

2.计算图

3.标量反向传播

1)定义叶子节点及算子节点

import torch

# 定义输入张量x,初始化权重参数w,偏移量b,并设置require_grad属性为True(为了自动求导)
x = torch.tensor([2])
w = torch.randn(1,requires_grad=True)
b = torch.randn(1,requires_grad=True)
# 实现向前传播
y = x.mul(w)
z = y.add(b)
# 查看x/w/b叶子节点的requite_grad属性
print("x,w,b的requite_grad属性为:{},{},{}".format(x.requires_grad,w.requires_grad,b.requires_grad))
>>>x,w,b的requite_grad属性为:FalseTrueTrue

2)查看叶子节点、非叶子节点的其他属性

#查看非叶子节点的requres grad属性,
print("y,z的requires grad属性分别为:{},{}".format(y.requires_grad,z.requires_grad))
#因与w,b有依赖关系,故y,z的requires grad属性也是: True,True
>>>y,z的requires grad属性分别为:True,True

#查看各节点是否为叶子节点
print("x,w,b,y,z的是否为叶子节点:{},{},{},{},{}".format(x.is_leaf,w.is_leaf,b.is_leaf,y.is_leaf,z.is_leaf))
>>>x,w,b,y,z的是否为叶子节点:True,True,True,False,False

# #查看叶子节点的qrad_fn属性
print("x,w, b的grad fn属性:{},{},{}".format(x.grad_fn,w.grad_fn,b.grad_fn))
#因x,w,b为用户创建的,为通过其他张量计算得到,故x,w,b的grad_fn属性: None,None,None
>>>x,w, b的grad fn属性:None,None,None

#查看非叶子节点的arad_fn属性
print("y,z的是否为叶子节点: {},{}".format(y.grad_fn,z.grad_fn))
>>>y,z的是否为叶子节点: <MulBackward0 object at 0x000001F316579128>,<AddBackward0 object at 0x000001F316579160>

3)自动求导,实现梯度方向传播,即梯度的反向传播

# 基于z张量进行梯度反向传播,执行backward之后计算图会自动清空
z.backward()
#如果需要多次使用backward,需要修改参数retain_graph为True,此时梯度是累加的
# #z.backward(retain_graph=True)

#查看叶子节点的梯度,x是叶子节点但它无须求导,故其梯度为None
print("参数w,b,x的梯度分别为:{},{},{})".format(w.grad,b.grad,x.grad))
>>>参数w,b,x的梯度分别为:tensor([2.]),tensor([1.]),None)

#非叶子节点的梯度,执行backward之后,会自动清空
print("非叶子节点y,z的梯度分别为:{},{}".format(y.grad,z.grad))
>>>非叶子节点y,z的梯度分别为:None,None

4.非标量反向传播

1)定义叶子节点及算子节点

import torch
#定义叶子节点张量x,形状为1x2
x= torch.tensor([[2,3]], dtype=torch.float, requires_grad=True)
#初始化Jacobian矩阵
J= torch.zeros(2 ,2)
#初始化目标张量,形状为1x2
y = torch.zeros(1, 2)
#定义y与x之间的映射关系:
#y1=x1**2+3*x2,y2=x2**2+2*x1
y[0,0] = x[0,0] ** 2 + 3 * x[0,1]
y[0,1] = x[0,1] ** 2 + 2 * x[0,0]

2)手工计算y对x的梯度

3)调用backward来获取y对x的梯度

y.backward(torch.Tensor([[1,1]]))
print(x.grad)
>>>tensor([[6., 9.]])
# 生成y1对x的梯度
y.backward(torch.Tensor([[1, 0]]),retain_graph=True)
J[0]=x.grad
#梯度是累加的,故需要对x的梯度清零
x.grad = torch.zeros_like(x.grad)
#生成y2对x的梯度
y.backward(torch.Tensor([[0,1]]))
J[1]=x.grad
#显示jacobian矩阵的值
print(J)

>>>tensor([[4., 3.],
        [2., 6.]])

相关推荐

【pyTorch学习笔记①】Numpy基础·上篇
【pyTorch学习笔记②】Numpy基础·下篇
【pyTorch学习笔记③】PyTorch基础·上篇
【pyTorch学习笔记④】PyTorch基础·中篇

05-01 16:31