torch.autograd 提供了实现任意标量值函数自动微分的类和函数。它需要对现有代码进行最少的更改 - 您只需要声明 Tensors,应使用 requires_grad=True 关键字为其计算梯度。截至目前,我们仅支持浮点张量类型(half、float、double 和 bfloat16)和复杂张量类型(cfloat、cdouble)的 autograd。
|
计算给定张量相对于图叶的梯度总和。 |
|
计算并返回输出相对于输入的梯度总和。 |
WARNING:此 API 处于测试阶段。 尽管函数签名不太可能改变,但在我们认为这个稳定之前就计划对性能进行重大改进。
本节包含基于上述基本 API 的 autograd 的更高级别的 API,并允许您计算 jacobians、hessians 等。
此 API 与用户提供的函数一起使用,这些函数仅将张量作为输入并仅返回张量。如果您的函数采用非张量或未设置 requires_grad 的张量的其他参数,您可以使用 lambda 来捕获它们。例如,对于一个接受三个输入的函数 f,一个我们想要雅可比的张量,另一个应该被视为常数的张量和一个布尔标志 f(input, constant, flag=flag) 你可以将它用作functional.jacobian(lambda x: f(x, constant, flag=flag), input)。
|
计算给定函数的雅可比的函数。 |
|
计算给定标量函数的 Hessian 的函数。 |
|
计算向量 v 与给定函数在输入给定点的雅可比矩阵之间的点积的函数。 |
|
计算给定函数在输入给定点处的雅可比矩阵与向量 v 之间的点积的函数。 |
|
计算向量 v 与给定标量函数的 Hessian 之间的点积的函数,该函数在输入给定的点处。 |
|
计算给定标量函数的 Hessian 与输入给定点处的向量 v 之间的点积的函数。 |
有关 no-grad 和推理模式之间差异的更多信息,以及可能与两者混淆的其他相关机制,请参阅本地禁用梯度计算。
|
禁用梯度计算的上下文管理器。 |
|
启用梯度计算的上下文管理器。 |
|
将梯度计算设置为开或关的上下文管理器。 |
|
启用或禁用推理模式的上下文管理器 |
当非稀疏参数在 torch.autograd.backward() 或 torch.Tensor.backward() 期间收到非稀疏梯度时,param.grad 按如下方式累积。
如果 param.grad 最初是 None:
1.如果 param 的内存是非重叠且密集的,则 .grad 将使用匹配 param 的步幅创建(从而匹配 param 的布局)。
2.否则, .grad 将使用 rowmajor-contiguous strides 创建。
如果 param 已经有一个非稀疏的 .grad 属性:
3.如果create_graph=False,则backward() 就地累积到.grad 中,从而保留其步幅。
4.如果 create_graph=True,backward() 用新的张量 .grad + new grad 替换 .grad,它尝试(但不保证)匹配预先存在的 .grad 的步幅。
建议使用默认行为(在第一个backward()之前让 .grads 为 None,以便它们的布局根据 1 或 2 创建,并根据 3 或 4 随着时间的推移保留)以获得最佳性能。 调用 model.zero_grad() 或 optimizer.zero_grad() 不会影响 .grad 布局。
事实上,在每个积累阶段之前将所有 .grads 重置为 None,例如:
for iterations...
...
for param in model.parameters():
param.grad = None
loss.backward()
这样它们每次都根据 1 或 2 重新创建,是 model.zero_grad() 或 optimizer.zero_grad() 的有效替代方案,可以提高某些网络的性能。
如果您需要手动控制 .grad 的步幅,请在第一个backward()之前分配 param.grad = 一个具有所需步幅的归零张量,并且永远不要将其重置为 None。 3 保证只要 create_graph=False 就可以保留您的布局。 4 表示即使 create_graph=True 也可能保留您的布局。
在 autograd 中支持就地操作是一件困难的事情,我们不鼓励在大多数情况下使用它们。 Autograd 积极的缓冲区释放和重用使其非常高效,并且就地操作实际上很少显着降低内存使用量。 除非您在沉重的内存压力下运行,否则您可能永远不需要使用它们。
所有 Tensor 都会跟踪应用到它们的就地操作,如果实现检测到一个张量被保存在其中一个函数中用于向后,但之后它被就地修改,一旦向后传递,就会引发错误 开始了。 这确保如果您使用就地函数并且没有看到任何错误,您可以确保计算出的梯度是正确的。
变量 API 已被弃用:不再需要变量来将 autograd 与张量一起使用。 Autograd 自动支持将 requires_grad 设置为 True 的张量。 请在下面找到有关更改内容的快速指南:
1、Variable(tensor) 和 Variable(tensor, requires_grad) 仍然按预期工作,但它们返回的是张量而不是变量。
2、var.data 与 tensor.data 是一回事。
3、var.backward()、var.detach()、var.register_hook() 等方法现在可以处理具有相同方法名称的张量。
此外,现在可以使用工厂方法(例如 torch.randn()、torch.zeros()、torch.ones() 和其他类似的方法创建带有 requires_grad=True 的张量:
autograd_tensor = torch.randn((2, 3, 4), requires_grad=True)
|
This attribute is |
|
Is |
|
All Tensors that have |
|
Computes the gradient of current tensor w.r.t. |
|
Returns a new Tensor, detached from the current graph. |
|
Detaches the Tensor from the graph that created it, making it a leaf. |
|
Registers a backward hook. |
|
Enables .grad attribute for non-leaf Tensors. |
torch.autograd.
Function
(*args, **kwargs)
记录操作历史并定义区分操作的公式。
有关如何使用此类的更多详细信息,请参阅有关扩展 autograd 引擎的说明:https://pytorch.org/docs/stable/notes/extending.html#extending-torch-autograd
在 Tensor 上执行的每个操作都会创建一个新的函数对象,该对象执行计算并记录它发生的情况。
历史以函数 DAG 的形式保留,边表示数据依赖关系(输入 <- 输出)。然后,当backward 被调用时,通过调用每个Function 对象的backward() 方法,并将返回的梯度传递给下一个Function,按拓扑顺序处理图。
通常,用户与函数交互的唯一方式是创建子类和定义新操作。 这是扩展 torch.autograd 的推荐方式。
>>> class Exp(Function):
>>>
>>> @staticmethod
>>> def forward(ctx, i):
>>> result = i.exp()
>>> ctx.save_for_backward(result)
>>> return result
>>>
>>> @staticmethod
>>> def backward(ctx, grad_output):
>>> result, = ctx.saved_tensors
>>> return grad_output * result
>>>
>>> #Use it by calling the apply method:
>>> output = Exp.apply(input)
|
Defines a formula for differentiating the operation. |
|
Performs the operation. |
创建新的Function时,ctx可以使用以下方法。
|
Marks given tensors as modified in an in-place operation. |
|
Marks outputs as non-differentiable. |
|
Saves given tensors for a future call to |
|
Sets whether to materialize output grad tensors. |
|
Check gradients computed via small finite differences against analytical gradients w.r.t. |
|
Check gradients of gradients computed via small finite differences against analytical gradients w.r.t. |
Autograd 包含一个分析器,可让您检查模型中不同运算符的成本 - 在 CPU 和 GPU 上。 目前实现了两种模式 - 仅使用配置文件的 CPU。 和基于 nvprof(注册 CPU 和 GPU 活动)使用emit_nvtx。
torch.autograd.profiler.
profile
(enabled=True, *, use_cuda=False, record_shapes=False, with_flops=False, profile_memory=False, with_stack=False, use_kineto=False, use_cpu=True)
管理 autograd 分析器状态并保存结果摘要的上下文管理器。在幕后,它只记录在 C++ 中执行的函数的事件,并将这些事件暴露给 Python。您可以将任何代码包装到其中,它只会报告 PyTorch 函数的运行时。注意:探查器是线程本地的,会自动传播到异步任务中
Parameters
enabled (bool, optional) – 将此设置为 False 使此上下文管理器成为空操作。
use_cuda (bool, optional) – 使用 cudaEvent API 启用 CUDA 事件的计时。 为每个张量操作增加大约 4us 的开销。
profile_memory (bool, optional) – 跟踪张量内存分配/释放。
with_stack (bool, optional) – 记录操作的源信息(文件和行号)。
use_kineto (bool, optional) – 实验性的,使用 Kineto 分析器启用分析。
use_cpu (bool, optional) – 分析 CPU 事件; 设置为 False 需要 use_kineto=True 并且可用于降低仅 GPU 分析的开销。
Example
>>> x = torch.randn((1, 1), requires_grad=True) >>> with torch.autograd.profiler.profile() as prof: >>> for _ in range(100): # any normal python code, really! >>> y = x ** 2 >> y.backward() >>> # NOTE: some columns were removed for brevity >>> print(prof.key_averages().table(sort_by="self_cpu_time_total")) ----------------------------------- --------------- --------------- --------------- Name Self CPU total CPU time avg Number of Calls ----------------------------------- --------------- --------------- --------------- mul 32.048ms 32.048ms 200 pow 27.041ms 27.041ms 200 PowBackward0 9.727ms 55.483ms 100 torch::autograd::AccumulateGrad 9.148ms 9.148ms 100 torch::autograd::GraphRoot 691.816us 691.816us 100 ----------------------------------- --------------- --------------- ---------------
|
Exports an EventList as a Chrome tracing tools file. |
|
Averages all function events over their keys. |
|
Returns total time spent on CPU obtained as a sum of all self times across all the events. |
|
Averages all events. |
CLASStorch.autograd.profiler.
emit_nvtx
(enabled=True, record_shapes=False)
Context manager that makes every autograd operation emit an NVTX range.
It is useful when running the program under nvprof:
nvprof --profile-from-start off -o trace_name.prof --
不幸的是,没有办法强制 nvprof 将它收集到的数据刷新到磁盘,因此对于 CUDA 分析,必须使用此上下文管理器来注释 nvprof 跟踪并等待进程退出,然后再检查它们。然后,可以使用 NVIDIA Visual Profiler (nvvp) 来可视化时间线,或者 torch.autograd.profiler.load_nvprof() 可以加载检查结果,例如 在 Python REPL 中。
参数
enabled (bool, optional, default=True) – 设置 enabled=False 使这个上下文管理器成为一个空操作。 默认值:真。
record_shapes (bool, optional, default=False) – 如果 record_shapes=True,包装每个 autograd op 的 nvtx 范围将附加有关该 op 接收的 Tensor 参数大小的信息,格式如下:[[arg0.size(0) , arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...] 非张量参数将由 [] 表示。 参数将按照后端操作收到的顺序列出。 请注意,此顺序可能与在 Python 端传递这些参数的顺序不匹配。 另请注意,形状记录可能会增加 nvtx 范围创建的开销。
Example
>>> with torch.cuda.profiler.profile(): ... model(x) # Warmup CUDA memory allocator and profiler ... with torch.autograd.profiler.emit_nvtx(): ... model(x)
Forward-backward correlation
在 Nvidia Visual Profiler 中查看使用 emit_nvtx 创建的配置文件时,将每个向后传递操作与相应的前向传递操作相关联可能很困难。 为了简化此任务,emit_nvtx 将序列号信息附加到它生成的范围。
在前向传递期间,每个函数范围都用 seq= 修饰。 seq 是一个运行计数器,每次创建一个新的向后函数对象时都会递增,并为向后存储。 因此,与每个前向函数范围关联的 seq= 注释告诉您,如果此前向函数创建了后向 Function 对象,则后向对象将收到序列号 N。在向后传递期间,顶级范围包装 每个 C++ 后向函数的 apply() 调用都装饰有隐藏的 seq=。 M 是创建后向对象的序列号。 通过比较向后隐藏的 seq 数和向前的 seq 数,您可以追踪哪个前向操作创建了每个后向函数。
在向后传递期间执行的任何函数也用 seq= 修饰。 在默认向后(使用 create_graph=False)期间,此信息无关紧要,实际上,对于所有此类函数,N 可能只是 0。 只有与后向 Function 对象的 apply() 方法相关的顶级范围才有用,作为将这些 Function 对象与较早的前向传递相关联的一种方式。
Double-backward
另一方面,如果使用 create_graph=True 进行反向传递(换句话说,如果您正在设置双向后传递),则向后期间的每个函数的执行都会被赋予一个非零的、有用的 seq=。 这些函数本身可能会创建 Function 对象,以便稍后在双向后执行期间执行,就像前向传递中的原始函数所做的那样。 backward 和 double-backward 之间的关系在概念上与 forward 和 backward 之间的关系相同:函数仍然发出当前序列号标记的范围,它们创建的 Function 对象仍然存储这些序列号,并且在最终的双 向后,Function 对象的 apply() 范围仍然用隐藏的 seq 数字标记,可以将其与反向传递中的 seq 数字进行比较。
|
Opens an nvprof trace file and parses autograd annotations. |
CLASStorch.autograd.
detect_anomaly
为 autograd 引擎启用异常检测的上下文管理器。
这有两件事:
在启用检测的情况下运行前向传递将允许后向传递打印创建失败后向函数的前向操作的追溯。
任何生成“nan”值的反向计算都会引发错误。
WARNING
此模式应仅在调试时启用,因为不同的测试会减慢您的程序执行速度。
Example
>>> import torch
>>> from torch import autograd
>>> class MyFunc(autograd.Function):
... @staticmethod
... def forward(ctx, inp):
... return inp.clone()
... @staticmethod
... def backward(ctx, gO):
... # Error during the backward pass
... raise RuntimeError("Some error in backward")
... return gO.clone()
>>> def run_fn(a):
... out = MyFunc.apply(a)
... return out.sum()
>>> inp = torch.rand(10, 10, requires_grad=True)
>>> out = run_fn(inp)
>>> out.backward()
Traceback (most recent call last):
File "", line 1, in
File "/your/pytorch/install/torch/_tensor.py", line 93, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph)
File "/your/pytorch/install/torch/autograd/__init__.py", line 90, in backward
allow_unreachable=True) # allow_unreachable flag
File "/your/pytorch/install/torch/autograd/function.py", line 76, in apply
return self._forward_cls.backward(self, *args)
File "", line 8, in backward
RuntimeError: Some error in backward
>>> with autograd.detect_anomaly():
... inp = torch.rand(10, 10, requires_grad=True)
... out = run_fn(inp)
... out.backward()
Traceback of forward call that caused the error:
File "tmp.py", line 53, in
out = run_fn(inp)
File "tmp.py", line 44, in run_fn
out = MyFunc.apply(a)
Traceback (most recent call last):
File "", line 4, in
File "/your/pytorch/install/torch/_tensor.py", line 93, in backward
torch.autograd.backward(self, gradient, retain_graph, create_graph)
File "/your/pytorch/install/torch/autograd/__init__.py", line 90, in backward
allow_unreachable=True) # allow_unreachable flag
File "/your/pytorch/install/torch/autograd/function.py", line 76, in apply
return self._forward_cls.backward(self, *args)
File "", line 8, in backward
RuntimeError: Some error in backward
CLASStorch.autograd.
set_detect_anomaly
(mode)
上下文管理器,用于打开或关闭 autograd 引擎的异常检测。
set_detect_anomaly 将根据其参数模式启用或禁用 autograd 异常检测。 它可以用作上下文管理器或函数。
有关异常检测行为的详细信息,请参阅上面的 detect_anomaly。
Parameters
mode (bool) – 标记是否启用异常检测 (True) 或禁用 (False)。