iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >PyTorch怎么如何自动计算梯度
  • 382
分享到

PyTorch怎么如何自动计算梯度

2023-06-15 04:06:37 382人浏览 独家记忆
摘要

小编给大家分享一下PyTorch怎么如何自动计算梯度,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在PyTorch中,torch.Tensor类是存储和变换数据的

小编给大家分享一下PyTorch怎么如何自动计算梯度,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

在PyTorch中,torch.Tensor类是存储和变换数据的重要工具,相比于Numpy,Tensor提供GPU计算和自动求梯度等更多功能,在深度学习中,我们经常需要对函数求梯度(gradient)。

PyTorch提供的autograd包能够根据输入和前向传播过程自动构建计算图,并执行反向传播。

本篇将介绍和总结如何使用autograd包来进行自动求梯度的有关操作。

1. 概念

Tensor是这个pytorch的自动求导部分的核心类,如果将其属性.requires_grad=True,它将开始追踪(track) 在该tensor上的所有操作,从而实现利用链式法则进行的梯度传播。完成计算后,可以调用.backward()来完成所有梯度计算。此Tensor的梯度将累积到.grad属性中。

如果不想要被继续对tensor进行追踪,可以调用.detach()将其从追踪记录中分离出来,接下来的梯度就传不过去了。此外,还可以用with torch.no_grad()将不想被追踪的操作代码块包裹起来,这种方法在评估模型的时候很常用,因为此时并不需要继续对梯度进行计算。

Function是另外一个很重要的类。Tensor和Function互相结合就可以构建一个记录有整个计算过程的有向无环图(DAG)。每个Tensor都有一个.grad_fn属性,该属性即创建该Tensor的Function, 就是说该Tensor是不是通过某些运算得到的,若是,则grad_fn返回一个与这些运算相关的对象,否则是None。

2. 具体实现

2.1. 创建可自动求导的tensor

首先我们创建一个tensor,同时设置requires_grad=True:

x = torch.ones(2, 2, requires_grad=True)print(x)print(x.grad_fn)'''

输出:

tensor([[1., 1.],

[1., 1.]], requires_grad=True)

None

'''

像x这种直接创建的tensor 称为叶子节点,叶子节点对应的grad_fn是None。如果进行一次运算操作:

y = x + 1print(y)print(y.grad_fn)'''tensor([[2., 2.],        [2., 2.]], grad_fn=<AddBackward>)<AddBackward object at 0x1100477b8>'''

而y是通过一个加法操作创建的,所以它有一个为操作的grad_fn。

尝试进行更复杂的操作:

z = y ** 2out = z.mean()print(z, out)'''tensor([[4., 4.],        [4., 4.]], grad_fn=<PowBackward0>) tensor(4., grad_fn=<MeanBackward0>)'''

上面的out是一个标量4,通常对于标量直接使用out.backward()进行求导,不需要指定求导变量,后面进行详细说明。

也可以通过.requires_grad_()改变requires_grad属性:

a = torch.randn(3, 2) # 缺失情况下默认 requires_grad = Falsea = (a ** 2)print(a.requires_grad) # Falsea.requires_grad_(True) #使用in-place操作,改变属性print(a.requires_grad) # Trueb = (a * a).sum()print(b.grad_fn)'''FalseTrue<SumBackward0 object at 0x7fd8c16edd30>'''

2.2. 梯度计算

torch.autograd实现梯度求导的链式法则,用来计算一些雅克比矩阵的乘积,即函数的一阶导数的乘积。

注意:grad在反向传播过程中是累加的(accumulated),每一次运行反向传播,梯度都会累加之前的梯度,所以一般在反向传播之前需把梯度清零x.grad.data.zero_()。

x = torch.ones(2, 2, requires_grad=True)y = x + 1z = y ** 2out = z.mean()print(z, out)out.backward()print(x.grad)# 注意grad是累加的out2 = x.sum()out2.backward()print(out2)print(x.grad)out3 = x.sum()x.grad.data.zero_()out3.backward()print(out3)print(x.grad)'''tensor([[4., 4.],        [4., 4.]], grad_fn=<PowBackward0>) tensor(4., grad_fn=<MeanBackward0>)tensor([[1., 1.],        [1., 1.]])tensor(4., grad_fn=<SumBackward0>)tensor([[2., 2.],        [2., 2.]])tensor(4., grad_fn=<SumBackward0>)tensor([[1., 1.],        [1., 1.]])'''

Tensor的自动求导对于标量比如上面的out.backward()十分方便,但是当反向传播的对象不是标量时,需要在y.backward()种加入一个与out同形的Tensor,不允许张量对张量求导,只允许标量对张量求导,求导结果是和自变量同形的张量。

这是为了避免向量(甚至更高维张量)对张量求导,而转换成标量对张量求导。

x = torch.tensor([1.0, 2.0, 3.0, 4.0], requires_grad=True)y = 2 * xz = y.view(2, 2)print(z)'''tensor([[2., 4.],        [6., 8.]], grad_fn=<ViewBackward>)'''

显然上面的tensor z不是一个标量,所以在调用 z.backward()时需要传入一个和z同形的权重向量进行加权求和得到一个标量。

c = torch.tensor([[1.0, 0.1], [0.01, 0.001]], dtype=torch.float)z.backward(c)print(x.grad)'''tensor([[2., 4.],        [6., 8.]], grad_fn=<ViewBackward>)tensor([2.0000, 0.2000, 0.0200, 0.0020])'''

2.3 停止梯度追踪

我们可以使用detach()或者torch.no_grad()语句停止梯度追踪:

x = torch.tensor(1.0, requires_grad=True)y1 = x ** 2 with torch.no_grad():    y2 = x ** 3y3 = y1 + y2print(x.requires_grad)print(y1, y1.requires_grad) # Trueprint(y2, y2.requires_grad) # Falseprint(y3, y3.requires_grad) # True'''Truetensor(1., grad_fn=<PowBackward0>) Truetensor(1.) Falsetensor(2., grad_fn=<ThAddBackward>) True'''

我们尝试计算梯度:

y3.backward()print(x.grad)# y2.backward() #这句会报错,因为此时 y2.requires_grad=False,,无法调用反向传播'''tensor(2.)'''

这里结果为2,是因为我们没有获得y2的梯度,仅仅是对y1做了一次反向传播,作为最后的梯度输出。

2.4. 修改tensor的值

如果我们想要修改tensor的数值,但是不希望保存在autograd的记录中,require s_grad = False, 即不影响到正在进行的反向传播,那么可以用tensor.data进行操作。但是这种操作需要注意可能会产生一些问题,比如标量为0

x = torch.ones(1,requires_grad=True)print(x.data) # 仍然是一个tensorprint(x.data.requires_grad) # 但是已经是独立于计算图之外y = 2 * xx.data *= 100 # 只改变了值,不会记录在计算图,所以不会影响梯度传播y.backward()print(x) # 更改data的值也会影响tensor的值print(x.grad)

pytorch0.4以后保留了.data() 但是官方文档建议使用.detach(),因为使用x.detach时,任何in-place变化都会使backward报错,因此.detach()是从梯度计算中排除子图的更安全方法。

如下面的例子:

torch.tensor([1,2,3.], requires_grad = True)out = a.sigmoid()c = out.detach()c.zero_()  # in-place为0 ,tensor([ 0.,  0.,  0.])print(out) # modified by c.zero_() !! tensor([ 0.,  0.,  0.])out.sum().backward()  # Requires the original value of out, but that was overwritten by c.zero_()'''RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation'''a = torch.tensor([1,2,3.], requires_grad = True)out = a.sigmoid()c = out.datac.zero_() # tensor([ 0.,  0.,  0.])print(out)  # out  was modified by c.zero_() tensor([ 0.,  0.,  0.])out.sum().backward()a.grad  # 这么做不会报错,但是a已经被改变,最后计算的梯度实际是错误的'''tensor([ 0.,  0.,  0.])'''

补充:pytorch如何计算导数_Pytorch 自动求梯度(autograd)

深度学习其实就是一个最优化问题,找到最小的loss值,因为自变量过多,想要找到最小值非常困难。所以就出现了很多最优化方法,梯度下降就是一个非常典型的例子。本文针对python的pytorch库中的自动求梯度进行了详细的解释

Tensor

pytorch里面的tensor可以用来存储向量或者标量。

torch.tensor(1) # 标量torch.tensor([1]) # 1*1 的向量

tensor还可以指定数据类型,以及数据存储的位置(可以存在显存里,硬件加速)

torch.tensor([1,2], dtype=torch.float64)

梯度

数学里,梯度的定义如下:

PyTorch怎么如何自动计算梯度

可以看出,自变量相对于因变量的每一个偏导乘以相应的单位向量,最后相加,即为最后的梯度向量。

在pytorch里面,我们无法直接定义函数,也无法直接求得梯度向量的表达式。更多的时候,我们其实只是求得了函数的在某一个点处相对于自变量的偏导。

我们先假设一个一元函数:y = x^2 + 3x +1,在pytorch里面,我们假设x = 2, 那么

>>> x = torch.tensor(2, dtype=torch.float64, requires_grad=True)>>> y = x * x + 3 * x + 1>>> y.backward()>>> x.gradtensor(7., dtype=torch.float64)

可以看出,最后y相对于x的导数在x=2的地方为7。在数学里进行验证,那么就是

y' = 2*x + 3, 当x=2时,y' = 2 * 2 + 3 = 7, 完全符合torch自动求得的梯度值。

接下来计算二元函数时的情况:

>>> x1 = torch.tensor(1.0)>>> x2 = torch.tensor(2.0, requires_grad=True)>>> y = 3*x1*x1 + 9 * x2>>> y.backward()tensor(6.)>>> x2.gradtensor(9.)

可以看出,我们可以求得y相对于x2的偏导数。

以上讨论的都是标量的情况,接下来讨论自变量为向量的情况。

mat1 = torch.tensor([[1,2,3]], dtype=torch.float64, requires_grad=True)>>> mat2tensor([[1.],        [2.],        [3.]], dtype=torch.float64, requires_grad=True)

mat1是一个1x3的矩阵,mat2是一个3x1的矩阵,他们俩的叉乘为一个1x1的矩阵。在pytorch里面,可以直接对其进行backward,从而求得相对于mat1或者是mat2的梯度值。

>>> y = torch.mm(mat1, mat2)>>> y.backward()>>> mat1.gradtensor([[1., 2., 3.]], dtype=torch.float64)>>> mat2.gradtensor([[1.],        [2.],        [3.]], dtype=torch.float64)

其实可以把mat1中的每一个元素当成一个自变量,那么相对于mat1的梯度向量,就是分别对3个x进行求偏导。

相当于是y = mat1[0] * mat2[0] + mat1[1] * mat2[1] + mat1[2] * mat2[2]

然后分别求y对于mat1,mat2每个元素的偏导。

另外,如果我们最后输出的是一个N x M 的一个向量,我们要计算这个向量相对于自变量向量的偏导,那么我们就需要在backward函数的参数里传入参数。

PyTorch怎么如何自动计算梯度

如上图所述,其实pytorch的autograd核心就是计算一个 vector-jacobian 乘积, jacobian就是因变量向量相对于自变量向量的偏导组成的矩阵,vector相当于是因变量向量到一个标量的函数的偏导。最后就是标量相对于一个向量的梯度向量。

pytorch的优点

1.PyTorch是相当简洁且高效快速的框架;2.设计追求最少的封装;3.设计符合人类思维,它让用户尽可能地专注于实现自己的想法;4.与Google的Tensorflow类似,FaiR的支持足以确保PyTorch获得持续的开发更新;5.PyTorch作者亲自维护的论坛 供用户交流和求教问题6.入门简单

以上是“PyTorch怎么如何自动计算梯度”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: PyTorch怎么如何自动计算梯度

本文链接: https://www.lsjlt.com/news/277655.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PyTorch 如何自动计算梯度
    在PyTorch中,torch.Tensor类是存储和变换数据的重要工具,相比于Numpy,Tensor提供GPU计算和自动求梯度等更多功能,在深度学习中,我们经常需要对函数求梯度(...
    99+
    2024-04-02
  • PyTorch怎么如何自动计算梯度
    小编给大家分享一下PyTorch怎么如何自动计算梯度,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在PyTorch中,torch.Tensor类是存储和变换数据的...
    99+
    2023-06-15
  • 怎么用pytorch中backward()方法自动求梯度
    本篇内容介绍了“怎么用pytorch中backward()方法自动求梯度”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!pytorch bac...
    99+
    2023-07-05
  • CNTK支持自动微分和梯度计算吗
    是的,CNTK支持自动微分和梯度计算。CNTK提供了内置的自动微分功能,可以轻松计算神经网络模型中的梯度,从而进行模型训练和优化。用...
    99+
    2024-04-02
  • PyTorch策略梯度算法怎么使用
    这篇文章主要介绍“PyTorch策略梯度算法怎么使用”,在日常操作中,相信很多人在PyTorch策略梯度算法怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PyTorch策略梯度算法怎么使用”的疑惑有所...
    99+
    2023-07-02
  • pytorch 禁止/允许计算局部梯度的操作
    一、禁止计算局部梯度 torch.autogard.no_grad: 禁用梯度计算的上下文管理器。 当确定不会调用Tensor.backward()计算梯度时,设置禁止计算梯度会减少...
    99+
    2024-04-02
  • Python利用AutoGrad实现自动计算函数斜率和梯度
    目录1.准备2.计算斜率3.实现一个逻辑回归模型AutoGrad 是一个老少皆宜的 Python 梯度计算模块。 对于初高中生而言,它可以用来轻易计算一条曲线在任意一个点上的斜率。 ...
    99+
    2024-04-02
  • pytorch 如何打印网络回传梯度
    需求: 打印梯度,检查网络学习情况 net = your_network().cuda() def train(): ... outputs = net(inputs) ...
    99+
    2024-04-02
  • 使用pytorch怎么计算 kl散度
    使用pytorch怎么计算 kl散度 ?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。如果现在想用Y指导X,第一个参数要传X,第二个要传Y。就是被指导的放在前面,...
    99+
    2023-06-15
  • 如何使用pytorch打印网络回传梯度
    如何使用pytorch打印网络回传梯度?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。需求:打印梯度,检查网络学习情况net = your_network()...
    99+
    2023-06-15
  • PyTorch 如何检查模型梯度是否可导
    一、PyTorch 检查模型梯度是否可导 当我们构建复杂网络模型或在模型中加入复杂操作时,可能会需要验证该模型或操作是否可导,即模型是否能够优化,在PyTorch框架下,我们可以使用...
    99+
    2024-04-02
  • Pytorch反向传播中的细节-计算梯度时的默认累加操作
    Pytorch反向传播计算梯度默认累加 今天学习pytorch实现简单的线性回归,发现了pytorch的反向传播时计算梯度采用的累加机制, 于是百度来一下,好多博客都说了累加机制,但...
    99+
    2024-04-02
  • 在 pytorch 中实现计算图和自动求导
    前言: 今天聊一聊 pytorch 的计算图和自动求导,我们先从一个简单例子来看,下面是一个简单函数建立了 yy 和 xx 之间的关系 然后...
    99+
    2024-04-02
  • PyTorch中如何应对梯度消失和爆炸问题
    梯度消失问题: 使用非饱和激活函数,如ReLU、LeakyReLU等 使用Batch Normalization来规范化网络的...
    99+
    2024-03-05
    PyTorch
  • 如何在html5中自动计算fontSize
    本篇文章为大家展示了如何在html5中自动计算fontSize,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。具体如下:var winWidth = window.inn...
    99+
    2023-06-09
  • OpenCV图像梯度算子方法怎么使用
    本篇内容介绍了“OpenCV图像梯度算子方法怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.Sobel算子Sobel算子是一种图像...
    99+
    2023-07-05
  • 怎么用pytorch 计算Parameter和FLOP
    这篇文章主要介绍“怎么用pytorch 计算Parameter和FLOP”,在日常操作中,相信很多人在怎么用pytorch 计算Parameter和FLOP问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用...
    99+
    2023-06-06
  • PyTorch动态计算图的概念是什么
    PyTorch动态计算图是指在PyTorch中,计算图是动态构建的,即在每次前向传播过程中都会重新构建计算图。这意味着用户可以在运行...
    99+
    2024-03-05
    PyTorch
  • 如何实现前端表格自动计算
    这篇文章将为大家详细讲解有关如何实现前端表格自动计算,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。序言当我的团队进行税务系统模块开发的时候,我发现他们需要花费80%的时间去解决计算问题,尤其体现在表格(G...
    99+
    2023-06-08
  • 如何利用Pytorch计算三角函数
    目录一、加载库二、sin值计算方法三、cos值计算方法四、tan值计算方法五、arcsin值计算方法六、arccos值计算方法七、arctan值计算方法一、加载库 首先加载torch...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作