PyTorch学习之 自动微分

PyTorch学习之 自动微分


autograd包

autograd 包是 PyTorch 中所有神经网络的核心。该 autograd 软件包为 Tensors 上的所有操作提供自动微分。它是一个由运行定义的框架,这意味着以代码运行方式定义你的后向传播,并且每次迭代都可以不同。

Tensor的属性设置

属性 说明
.requires_grad = True 开始跟踪针对 tensor 的所有操作
.backward() 自动计算所有梯度
.grad 张量的梯度将累积到其中
.deatch() 停止tensor历史记录的追踪
with.torch.no_grad() 停止跟踪历史记录和使用内存。在评估模型时,这是特别有用,因为模型在训练阶段具有 requires_grad = True 的可训练参数有利于调参,但在评估阶段我们不需要梯度。

Function 类

Function类对于autograd非常重要,Tensor与Function构成一个非循环图,它保存整个完整的计算过程的历史信息。.grad_fn属性保存着创建了张量的Function的引用。如果想计算导数,可以调用Tensor.backward()。
需要注意的是, 当tensor的是标量时, 不需要指定任何参数backward,但若有更多元素,则需要指定一个gradient参数来指定张量的形状。

代码

# -*- coding: UTF-8 -*-
"""
Modify: 2019-12-12
"""
import torch
#创建一个张量,设置requires_grad=True来跟踪与它相关的计算
x = torch.ones(2, 2, requires_grad=True)
print(x)
#输出
# tensor([[1., 1.],
#         [1., 1.]], requires_grad=True)

#针对张量做一个操作
y = x + 2
print(y)
#输出
# tensor([[3., 3.],
#         [3., 3.]], grad_fn=<AddBackward0>)

#y作为操作的结果被创建,所以它有grad_fn
print(y.grad_fn)
#输出
#<AddBackward0 object at 0x0000023783F70588>

# 针对y做更多的操作
z = y * y *3
out = z.mean()
print(z)
print(out)
#输出
# tensor([[27., 27.],
#         [27., 27.]], grad_fn=<MulBackward0>)
# tensor(27., grad_fn=<MeanBackward0>)

#.requires_grad(...)会改变张量的requires_grad标记
# 如果没有提供相应的参数,输入的标记默认为False
a = torch.randn(2, 2)
a = (a * 3) / (a - 1)
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)
#输出
# False
# True
# <SumBackward0 object at 0x00000261ADB56208>


# 梯度
#因为输出包含了一个标量,out.backward()等同于out.backward(torch.tensor(1.))
out.backward()
#打印梯度 d(out)/dx
print(x.grad)
#输出
# tensor([[4.5000, 4.5000],
#         [4.5000, 4.5000]])
# 下面来看一个雅可比向量积的例子
x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:    # y.data.norm(input, p=2) 求y的范数
   y = y * 2
print(y)
#输出
#tensor([ -745.7645, -1334.8055,   385.1612], grad_fn=<MulBackward0>)

#现在在这种情况下,y 不再是一个标量。torch.autograd 不能够直接计算整个雅可比,
#但是如果我们只想要雅可比向量积,只需要简单的传递向量给 backward 作为参数。
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
#输出
#tensor([4.0960e+02, 4.0960e+03, 4.0960e-01])

#可以通过将代码包裹在with torch.no_grad(),
#来停止对从跟踪历史中的.requires=True的张量自动求导
print(x.requires_grad)
print((x ** 2).requires_grad)
with torch.no_grad():
    print((x ** 2).requires_grad)
#输出
# True
# True
# False
发布了38 篇原创文章 · 获赞 29 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/ruotianxia/article/details/103517824