自动微分
正如我们在 :numref:sec_calculus
中所说的那样,求导是几乎所有深度学习优化算法的关键步骤。
虽然求导的计算很简单,只需要一些基本的微积分。
但对于复杂的模型,手工进行更新是一件很痛苦的事情(而且经常容易出错)。
深度学习框架通过自动计算导数,即自动微分(automatic differentiation)来加快求导。
实际中,根据我们设计的模型,系统会构建一个计算图(computational graph),
来跟踪计算是哪些数据通过哪些操作组合起来产生输出。
自动微分使系统能够随后反向传播梯度。
这里,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数。
一个简单的例子
(假设我们想对函数 y = 2 x ⊤ x y=2\mathbf{x}^{\top}\mathbf{x} y=2x⊤x (标量) 关于列向量 x \mathbf{x} x求导)。
首先,我们创建变量x
并为其分配一个初始值。
import torch
x = torch.arange(4.0)
x
tensor([0., 1., 2., 3.])
[在我们计算 y y y关于 x \mathbf{x} x的梯度之前,我们需要一个地方来存储梯度。]
重要的是,我们不会在每次对一个参数求导时都分配新的内存。
因为我们经常会成千上万次地更新相同的参数,每次都分配新的内存可能很快就会将内存耗尽。
注意,一个标量函数关于向量 x \mathbf{x} x的梯度是向量,并且与 x \mathbf{x} x具有相同的形状。
# 需要梯度 = 存储梯度
x.requires_grad_(True) # 等价于 `x = torch.arange(4.0, requires_grad=True)`
x.grad # 默认值是None
print(x.grad)
None
(现在让我们计算