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

全部评论

相关推荐

被加薪的哈里很优秀:应该继续招人,不会给你留岗位的
点赞 评论 收藏
分享
小厂面经,也是我的处女面(30min)1.自我介绍2.spring&nbsp;boot的自动装配原理(好多类和接口的单词都忘了全称是啥了,就说了记得的单词,流程应该说对了吧)3.有用过redis吗?主要是用在实现什么功能(说了技术派用redis的zset来实现排行榜)5.有了解过Redisson吗?讲一下对于分布式锁的了解以及在什么场景下应用(说了秒杀场景)6.对mysql有了解吗?包括它的索引优化和创建(把想起来的全说了)7.了解设计模式吗?比如单例模式,为什么要使用单例模式,它的优点是什么(昨天刚看的设计模式)8.工厂模式有了解吗?主要的使用场景是?(也是昨天刚看的)9.场景题:有7个服务器,需要在早上十点定时的向数据库中的用户表中的用户发短信,如果做到发送的消息不重复,且如果发送失败了需要知道是到哪个用户失败了,这样下次就直接从这个用户开始(我答了用spring&nbsp;task来实现定时,用分布式锁来保证只有一份服务器可以发送消息,用消息队列来存储消息,然后用消息确认机制来保证错误信息的记录,以及在数据库或者业务层面完成消息消费的幂等性)10.场景题:如果在系统启动的时间就将数据库的所有用户相关的信息都读到一个hashmap中(这个没啥思路,没答好)27届的投了一个星期终于有一个面试了,大部分公司都只招26的
inari233:已oc,拒了
查看9道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务