pytorch篇--梯度及求导

本文详细介绍了PyTorch中Variable、requires_grad、no_grad、detach等关键函数的使用,探讨了它们在训练和推测阶段的作用,以及如何正确设置以优化内存使用和加速计算。
部署运行你感兴趣的模型镜像

目录
1.pytorch相关函数: Variable、requires_grad、volatile、no_grad、detach()
2. 什么时候使用
3. 参考资料

正文

推测阶段(inteference)指预测阶段,并不反向求导,只有前向计算,求导及梯度更新只出现在训练阶段。
可以参考pytorch官网:
自动求导机制:https://www.pytorchtutorial.com/docs/notes/autograd/
torch.autograd:https://www.pytorchtutorial.com/docs/package_references/torch-autograd/
推荐直接看官网更清楚。

1. 相关函数

a. Variable

pytorch中常使用variable将tensor转化为可梯度更新的形式,即封装了tensor,并整合了反向传播的相关实现。

Varibale包含三个属性:
data:存储了Tensor,是本体的数据
grad:保存了data的梯度,本事是个Variable而非Tensor,与data形状一致
grad_fn:指向Function对象,用于反向传播的梯度计算之用

可以使用.backward()进行反向传播

import torch
from torch.autograd import Variable
# #Varibale 默认时不要求梯度的,如果要求梯度,需要说明
x = Variable(torch.one(2,2), requires_grad = True)
print(x)#其实查询的是x.data,是个tensor
y = x.sum()
 
y
"""
  Variable containing:
   4
  [torch.FloatTensor of size 1]
"""
 
 
#可以查看目标函数的.grad_fn方法,它用来求梯度
y.grad_fn
"""
    <SumBackward0 at 0x18bcbfcdd30>
"""
 
y.backward()  # 反向传播
x.grad  # Variable的梯度保存在Variable.grad中,为dy/dx
"""
  Variable containing:
   1  1
   1  1
  [torch.FloatTensor of size 2x2]
"""
 
 
#grad属性保存在Variable中,新的梯度下来会进行累加,可以看到再次求导后结果变成了2,
y.backward()
x.grad  # 可以看到变量梯度是累加的
"""
    Variable containing:
     2  2
     2  2
    [torch.FloatTensor of size 2x2]
"""
 
#所以要归零
x.grad.data.zero_()  # 归零梯度,注意,在torch中所有的inplace操作都是要带下划线的,虽然就没有.data.zero()方法
 
"""
 0  0
 0  0
[torch.FloatTensor of size 2x2]
"""
 
 
#对比Variable和Tensor的接口,相差无两
x = Variable(torch.ones(4, 5))
 
y = torch.cos(x)                         # 传入Variable
x_tensor_cos = torch.cos(x.data)  # 传入Tensor
 
print(y)
print(x_tensor_cos)
 
"""
Variable containing:
 0.5403  0.5403  0.5403  0.5403  0.5403
 0.5403  0.5403  0.5403  0.5403  0.5403
 0.5403  0.5403  0.5403  0.5403  0.5403
 0.5403  0.5403  0.5403  0.5403  0.5403
[torch.FloatTensor of size 4x5]
 
 
 0.5403  0.5403  0.5403  0.5403  0.5403
 0.5403  0.5403  0.5403  0.5403  0.5403
 0.5403  0.5403  0.5403  0.5403  0.5403
 0.5403  0.5403  0.5403  0.5403  0.5403
[torch.FloatTensor of size 4x5]
"""

具体可参考链接https://www.cnblogs.com/hellcat/p/8439055.html

在python之前的版本中,variable可以封装tensor,计算反向传播梯度时需要将tensor封装在variable中。但是在pytorch 0.4版本之后,将variable和tensor合并,也就是说不需要将tensor封装在variable中就可以计算梯度。tensor具有variable的性质。

作为能否autograd的标签,requires_grad现在是Tensor的属性,所以,只要当一个操作的任何输入Tensor具有requires_grad = True的属性,autograd就可以自动追踪历史和反向传播了。
具体可参考链接:https://zhuanlan.zhihu.com/p/93502821

a. requires_grad

Variable变量的requires_grad的属性默认为False,若一个节点requires_grad被设置为True,那么所有依赖它的节点的requires_grad都为True。

x=Variable(torch.ones(1))
w=Variable(torch.ones(1),requires_grad=True)
y=x*w
x.requires_grad,w.requires_grad,y.requires_grad
Out[23]: (False, True, True)
b. volatile && no_grad()

在pytorch 0.4版本及之后已被移除,换成no_grad()。使用volatile时会收到warning。
volatile=True是Variable的另一个重要的标识,它能够将所有依赖它的节点全部设为volatile=True,其优先级比requires_grad=True高。因而volatile=True的节点不会求导,即使requires_grad=True,也不会进行反向传播,对于不需要反向传播的情景(inference,测试推断),该参数可以实现一定速度的提升,并节省一半的显存,因为其不需要保存梯度。

>>> x = torch.tensor([1], requires_grad=True)
>>> with torch.no_grad():
...   y = x * 2
>>> y.requires_grad
False
>>> @torch.no_grad()
... def doubler(x):
...     return x * 2
>>> z = doubler(x)
>>> z.requires_grad
False
c. no_grad()和requires_grad区别

当一个节点设为no_grad()时,其依赖的所有节点均为no_grad()。而对requires_grad, 所有节点为false时,输出才为false。

d. detach()

返回一个新的Variable,从当前图中分离下来的。
即使之后重新将它的requires_grad置为true,它也不会具有梯度grad

这样我们就会继续使用这个新的Variable进行计算,后面当我们进行反向传播时,到该调用detach()的Variable就会停止,不能再继续向前进行传播

2. 什么时候使用

测试时推荐使用no_grad()。当你确定你甚至不会调用.backward()时。它比任何其他自动求导的设置更有效——它将使用绝对最小的内存来评估模型。volatile(no_grad())也决定了require_grad is False。

#可以写在很多地方,比如testloader之前
with torch.no_grad():
	for img,target in testloader:

Variable: 当读取数据时,img和target都要转为variable形式,这样计算loss的时候都为variable形式,可以计算loss的反向传播

requires_grad=Fasle时不需要更新梯度, 适用于冻结某些层的梯度;

detach()可以用于减少显存计算。

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

PyTorch是一个开源的机器学习框架,它提供了一个灵活且高效的工具集,可用于构建各种类型的深度学习模型。PyTorch 使用动态计算图的方式来定义和计算网络模型,这使得模型的构建更加灵活,并提供了更好的调试和可视化功能。PyTorch具有丰富的库和接口,可以方便地进行数据加载、模型定义、训练和推断。 PyTorch-Memlab是一个用于分析PyTorch模型内存占用的工具。深度学习模型通常需要大量的内存来存储网络结构、参数和计算中间结果。PyTorch-Memlab通过记录和分析模型的内存使用情况,帮助用户优化模型的内存消耗,提高模型的运行效率。它可以用于查看各个模块和操作的内存使用情况,帮助用户识别内存泄露和优化模型的内存占用。 使用PyTorch,我们可以使用简单而直观的方式来构建深度学习模型,它提供了丰富的API和函数,用于定义和训练模型、优化模型参数、评估模型性能等。PyTorch还支持自动求导,使得梯度计算更加简单和高效。它还提供了用于并行化和分布式训练的工具,使得处理大规模数据和模型变得更加方便和高效。 PyTorch-Memlab可以帮助我们深入了解模型的内存占用情况,它可以告诉我们哪些模块或操作占用了大量的内存,帮助我们找到内存消耗较大的瓶颈和优化空间。通过使用PyTorch-Memlab,我们可以减少模型的内存占用,并提高模型的性能和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值