Pytorch基础知识 2

        Autograd是PyTorch中的自动微分(automatic differentiation)引擎,用于计算梯度。它是PyTorch实现深度学习中反向传播算法的核心组件。

        PyTorch是动态图,即计算图的搭建和运算是同时的,随时可以输出结果。在pytorch的计算图里只有两种元素:数据(tensor)和 运算(operation)。

        运算包括了:加减乘除、开方、幂指对、三角函数等可求导运算。

        数据可分为:叶子节点(leaf node)和非叶子节点;叶子节点是用户创建的节点,不依赖其它节点;它们表现出来的区别在于反向传播结束之后,非叶子节点的梯度会被释放掉,只保留叶子节点的梯度,这样就节省了内存。如果想要保留非叶子节点的梯度,可以使用retain_grad()方法。参考:https://www.jb51.net/python/2925062of.htm#_lab2_0_0

        在Autograd中,torch.Tensor是核心类,它具有追踪操作历史和计算梯度的功能。通过将张量的属性.requires_grad设置为True,可以追踪对该张量的所有操作,并在需要时自动计算梯度。梯度会自动累加到.grad属性中。

  torch.requires_grad_(...) 原地改变了现有张量的requires_grad标志。如果没有指定的话,默认输入的这个标志是 False

import torch
#需要注意的是: 只有浮点数据类型的张量才能要求gradients
x = torch.tensor([1.0, 2.0, 3.0])
print(x.requires_grad)  # 输出 False

# 设置requires_grad=True
x.requires_grad_(True)

# 现在,x需要计算梯度
print(x.requires_grad)  # 输出:True

        另一个在Autograd中非常重要的类是FunctionTensorFunction相互连接形成一个无环图(acyclic graph),它编码了完整的计算历史。每个张量都有一个.grad_fn属性,它引用了创建该张量的Function(如果张量是由用户手动创建的,则此时grad_fnNone)。

import torch
x = torch.ones(3, 3, requires_grad=True)
print(x)
#tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], requires_grad=True)

y=x**3
print(y)
#tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], grad_fn=<PowBackward0>) 
#grad_fn=<PowBackward0> 是PyTorch的一种标记方式,表示这个张量是通过什么操作得到的。
#加法的反向传播函数是AddBackward,乘法的是MulBackward,指数运算的是PowBackward等.

        要阻止一个张量被跟踪历史,可以使用.detach()方法将其与计算历史分离,并阻止未来的计算记录被跟踪。为了避免跟踪历史记录和节省内存,可以使用with torch.no_grad()将代码块包装起来。这在评估模型时特别有用,因为模型的可训练参数可能具有requires_grad=True,但在评估过程中不需要计算它们的梯度。

>>> x=torch.tensor([1,2,3],dtype=torch.float,requires_grad=True)
>>> x
tensor([1., 2., 3.], requires_grad=True)
>>> y=x*2
>>> y
tensor([2., 4., 6.], grad_fn=<MulBackward0>)
>>> y_detached=y.detach()  # 使用.detach()方法将y与计算历史分离
>>> y
tensor([2., 4., 6.], grad_fn=<MulBackward0>)
>>> y_detached
tensor([2., 4., 6.])
>>> y_detached.requires_grad
False       #y_detached不再需要计算梯度
import torch
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)

# 使用with torch.no_grad()将代码块包装起来
with torch.no_grad():
    # 在这个代码块中,对x的所有操作都不会被跟踪
    y = x * 2

# y不需要计算梯度
print(y.requires_grad)  # 输出:False

       自动求导的核心是反向传播算法(Backpropagation)。反向传播算法使用链式法则计算每个可导操作的梯度,然后利用这些梯度更新参数。一旦我们创建了可导张量,PyTorch 将会自动追踪所有涉及这些张量的操作,并构建一个计算图。计算图是一个有向无环图,表示了计算过程中张量之间的依赖关系。

        使用Autograd,可以方便地进行反向传播,计算模型参数的梯度,并使用优化算法更新参数,以训练深度学习模型。计算导数可以在 Tensor 上调用 .backward()。如果 Tensor 是一个标量(即它包含一个元素的数据),则不需要为 backward() 指定任何参数,但是如果它有更多的元素,则需要指定一个gradient参数,该参数是形状匹配的张量。

>>> x = torch.tensor([2.0], requires_grad=True)
>>> y=x**2
>>> y.backward()
>>> print(x.grad)
tensor([4.])
>>> z=x**3
>>> z.backward()
>>> print(x.grad)
tensor([16.])
>>> x.grad.data.zero_()
>>> w=x**3
>>> w.backward()
>>> print(x.grad)
tensor([12.])

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

        如果需要再次反向浏览图形,或者在反向调用后需要访问已保存张量,请指定retain_graph=True。

>>> y=x**2
>>> y.backward(retain_graph=True)
>>> print(x.grad)
tensor([4.])
>>> x.grad.zero_()
tensor([0.])
>>> y.backward(retain_graph=True)
>>> print(x.grad)
tensor([4.])

        如果y不再是标量。torch.autograd 不能直接计算完整的雅可比矩阵,但是如果我们只想要雅可比向量积,只需将这个向量作为参数传给 backward:

>>> x = torch.randn(3, requires_grad=True)
>>> x
tensor([-0.5904, -1.3413,  0.9258], requires_grad=True)
>>> y=x*2
>>> y
tensor([-1.1808, -2.6825,  1.8517], grad_fn=<MulBackward0>)
>>> v=torch.tensor([1.0,1.0,1.0])
>>> y.backward(v)
>>> print(x.grad)
tensor([2., 2., 2.])

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值