PyTorch学习教程(二)-------Autograd:自动微分

%matplotlib inline

Autograd:自动微分

autograd package是PyTorch神经网络的核心。我们先简单看一下,然后开始训练第一个神经网络。

autograd package为张量的所有operations(操作或运算)提供了自动微分。它是一个define-by-run框架,意思是说你的反向传播(backpropagation)是由 如何运行代码 定义的,并且每一个迭代可以是不同的。

用例子和一些简单的术语来看下:

Tensor(张量)

torch.Tensor是包的核心类。如果你设置它的**.requires_grad属性 为 True,它的所有操作都会被跟踪记录。完成计算后可以调用.backward()**方法,并自动计算所有的梯度。这个张量的梯度将会被累积到.grad属性。

你可以调用**.detach()**方法来阻止张量对所有操作的跟踪记录。

阻止跟踪历史的另一种方法是你在代码块外包裹语句 with torch.no_grad(): ,这种方法在模型中训练参数设置了requires_grad=True时依然有效。

实现自动微分的另一个重要的类是Function.(这里function可理解为一个运算。比如加法运算)

Tensor 和 Function相互关联建立了一个非循环图,它记录了完整的计算历史。每一个张量有一个.grad_fn属性,这个属性与创建张量(除了用户自己创建的张量,它们的**.grad_fn**是None)的Function关联。

如果你想要计算导数,你可以调用张量的**.backward()**方法。如果张量是一个标量(例如,它只有一个元素),你不需要指定backward()的参数,然而,如果张量有多个元素,你需要指定一个匹配张量大小的gradient参数。

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 0x00000298859D6278>

对y进行运算:

z = y * y * 3
out = z.mean()

print(z, out)
tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward1>)

.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 0x00000298859C8E80>

梯度

有了自动微分,现在我们可以反向传播了。

因为out只是一个简单的标量,out.backward()等价于out.backward(torch.tensor(1))

out.backward()

打印出导数 d(out)/dx

print(x.grad)
tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

用下图来解释下为什么对out进行反向传播,x的梯度是4.5的矩阵吧:

x = torch.randn(3, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)
tensor([-1016.0380,  -869.8464,   611.4693], grad_fn=<MulBackward0>)

你可以用自动微分做更多有趣的事。之前都是对标量进行backward(),不需要参数。下面看下是向量或矩阵时,gradient参数的值对梯度的影响:

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)

print(x.grad)
tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])

如果你不想要跟踪历史并自动微分的时候,你可以在代码块外面包一层:with torch.no_grad():

print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
	print((x ** 2).requires_grad)
True
True
False

原文网页:https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html

全部评论

相关推荐

10-25 00:32
香梨想要offer:感觉考研以后好好学 后面能乱杀,目前这简历有点难
点赞 评论 收藏
分享
10-24 11:10
山西大学 Java
若梦难了:哥们,面试挂是很正常的。我大中厂终面挂,加起来快10次了,继续努力吧。
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务