pytorch—torch.autograd
autogrd:自动求导系统
示例代码如下:
torch.autograd.backward(tensors,
grad_tensors = None,
retain_graph = None,
create_graph = False
)
功能:自动求取梯度
tensors:用于求导的张量,如 loss
retain_graph : 保存计算图
create_graph : 创建导数计算图,用于高阶求导
grad_tensors:多梯度权重
1.retain_graph
import torch
torch.manual_seed(10)
flag = True
if flag:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward(retain_graph=True) #保留计算过的梯度
print(w.grad)
y.backward()
只有当第一处的backward()中retain_graph=True时,再次对y进行反向求导才不会报错
2.grad_tensors–设置多个梯度之间的权重
if flag:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x) # retain_grad()
b = torch.add(w, 1)
y0 = torch.mul(a, b) # y0 = (x+w) * (w+1)
y1 = torch.add(a, b) # y1 = (x+w) + (w+1) dy1/dw = 2
loss = torch.cat([y0, y1], dim=0) # [y0, y1] ,loss现在是维度是2的向量,不再是标量
grad_tensors = torch.tensor([1., 2.]) #设置y0和y1之间的权重
loss.backward(gradient=grad_tensors) # gradient 传入 torch.autograd.backward()中的grad_tensors
print(w.grad)
3.autograd.gard
if flag:
x = torch.tensor([3.], requires_grad=True)
y = torch.pow(x, 2) # y = x**2
#一阶导数
grad_1 = torch.autograd.grad(y, x, create_graph=True) # grad_1 = dy/dx = 2x = 2 * 3 = 6,create_graph=True:创建导数的计算图,只有创建了导数的计算图才能对导数再进行求导
print(grad_1)
#二阶导数:对梯度求导
grad_2 = torch.autograd.grad(grad_1[0], x) # grad_2 = d(dy/dx)/dx = d(2x)/dx = 2
print(grad_2)
4.tips
- 梯度不自动清零
- 依赖于叶子结点的结点, requires_grad默认为True
- 叶子结点不可执行in-place(原位运算)
代码如下(示例1):
if flag:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
for i in range(4):
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
y.backward()
print(w.grad)
w.grad.zero_()
执行结果:
#执行w.grad.zero_()语句
tensor([5.])
tensor([5.])
tensor([5.])
tensor([5.])
#不执行w.grad.zero_()语句
tensor([5.])
tensor([10.])
tensor([15.])
tensor([20.])
代码如下(示例2):
if flag:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
print(a.requires_grad, b.requires_grad, y.requires_grad)
执行结果:
True True True
代码如下(示例3):
if flag:
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)
a = torch.add(w, x)
b = torch.add(w, 1)
y = torch.mul(a, b)
w.add_(1)
执行结果:
RuntimeError: a leaf Variable that requires grad is being used in an in-place operation.