Pytorch 梯度计算

使用Pytorch计算梯度或者求导,有两种方法:

Pytorch 梯度计算_第1张图片

以均方误差为例,模型pred = w*x:

import torch
from torch.nn import functional as F

# pred = x*w
x = torch.ones(1)

# dim=1,长度为1,值初始化为2
w = torch.full([1], 2)  

# 实际输出
y = torch.ones(1)  

mse = F.mse_loss(x * w, y)
print(mse)

 输出结果:

tensor(1.)

1. 使用torch.autograd.grad() 

# MSE对参数w自动求导
# 第一个参数是损失函数,第二个参数是该损失函数要求梯度的参数列表
# 返回结果grad_val是梯度列表,列表记录了每一个Tensor的grade信息
grad_val = torch.autograd.grad(mse, [w])  

发生错误:

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

 

这个错误是因为在前面定义w时,没有设定其需要梯度信息,所以PyTorch在建图的时候就没有设置它具有梯度信息。

可以在定义完w后将其设置为需要梯度信息:

w.requires_grad_()

 也可以在建立Tensor时用参数指明它需要梯度信息:

w = torch.full([1], 2, requires_grad=True)

将得到的求导结果grad_val 输出,可以得到: 

(tensor([2.]),)

 

2. 使用loss.backward()

使用loss对象的backward()方法,让PyTorch做反向的传播,将需要grad信息的Tensor求出这个loss关于它的导数出来。

import torch
from torch.nn import functional as FF

# pred = x*w
x = torch.ones(1)

# dim=1,长度为1,值初始化为2
w = torch.full([1], 2, requires_grad=True) 

# 实际输出 
y = torch.ones(1) 
mse = FF.mse_loss(x * w, y)

# 图的反向传播, 自动求出该图上所有的需要计算梯度的参数相对于这个MSE的梯度
# 计算出的梯度不会跟第一种方法一样返回一个梯度列表(列表记录了每一个Tensor的grade信息),而是将梯度信息附加到每个Tensor的成员变量grad中
mse.backward()
print(w.grad)

输出结果:

(tensor([2.]),)

 注意,这个API会将之前的梯度信息覆盖掉,所以多次调用这个loss对象的.backward()方法时会报错,如果要再次调用以生成新的梯度信息,要给它一个参数:

mse.backward(retain_graph=True)

 

 

你可能感兴趣的:(深度学习,pytorch)