7、TORCH.AUTOGRAD

torch.autograd 提供了实现任意标量值函数自动微分的类和函数。它需要对现有代码进行最少的更改 - 您只需要声明 Tensors,应使用 requires_grad=True 关键字为其计算梯度。截至目前,我们仅支持浮点张量类型(half、float、double 和 bfloat16)和复杂张量类型(cfloat、cdouble)的 autograd。

backward

计算给定张量相对于图叶的梯度总和。

grad

计算并返回输出相对于输入的梯度总和。

Functional higher level API

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)。

functional.jacobian

计算给定函数的雅可比的函数。

functional.hessian

计算给定标量函数的 Hessian 的函数。

functional.vjp

计算向量 v 与给定函数在输入给定点的雅可比矩阵之间的点积的函数。

functional.jvp

计算给定函数在输入给定点处的雅可比矩阵与向量 v 之间的点积的函数。

functional.vhp

计算向量 v 与给定标量函数的 Hessian 之间的点积的函数,该函数在输入给定的点处。

functional.hvp

计算给定标量函数的 Hessian 与输入给定点处的向量 v 之间的点积的函数。

Locally disabling gradient computation

有关 no-grad 和推理模式之间差异的更多信息,以及可能与两者混淆的其他相关机制,请参阅本地禁用梯度计算。

no_grad

禁用梯度计算的上下文管理器。

enable_grad

启用梯度计算的上下文管理器。

set_grad_enabled

将梯度计算设置为开或关的上下文管理器。

inference_mode

启用或禁用推理模式的上下文管理器

Default gradient layouts

当非稀疏参数在 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() 的有效替代方案,可以提高某些网络的性能。

Manual gradient layouts

如果您需要手动控制 .grad 的步幅,请在第一个backward()之前分配 param.grad = 一个具有所需步幅的归零张量,并且永远不要将其重置为 None。 3 保证只要 create_graph=False 就可以保留您的布局。 4 表示即使 create_graph=True 也可能保留您的布局。

In-place operations on Tensors

在 autograd 中支持就地操作是一件困难的事情,我们不鼓励在大多数情况下使用它们。 Autograd 积极的缓冲区释放和重用使其非常高效,并且就地操作实际上很少显着降低内存使用量。 除非您在沉重的内存压力下运行,否则您可能永远不需要使用它们。

In-place correctness checks

所有 Tensor 都会跟踪应用到它们的就地操作,如果实现检测到一个张量被保存在其中一个函数中用于向后,但之后它被就地修改,一旦向后传递,就会引发错误 开始了。 这确保如果您使用就地函数并且没有看到任何错误,您可以确保计算出的梯度是正确的。

Variable (deprecated)

变量 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)

Tensor autograd functions

torch.Tensor.grad

This attribute is None by default and becomes a Tensor the first time a call to backward() computes gradients for self.

torch.Tensor.requires_grad

Is True if gradients need to be computed for this Tensor, False otherwise.

torch.Tensor.is_leaf

All Tensors that have requires_grad which is False will be leaf Tensors by convention.

torch.Tensor.backward([gradient, …])

Computes the gradient of current tensor w.r.t.

torch.Tensor.detach

Returns a new Tensor, detached from the current graph.

torch.Tensor.detach_

Detaches the Tensor from the graph that created it, making it a leaf.

torch.Tensor.register_hook(hook)

Registers a backward hook.

torch.Tensor.retain_grad()

Enables .grad attribute for non-leaf Tensors.

Function

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)

Function.backward

Defines a formula for differentiating the operation.

Function.forward

Performs the operation.

Context method mixins

创建新的Function时,ctx可以使用以下方法。

function._ContextMethodMixin.mark_dirty

Marks given tensors as modified in an in-place operation.

function._ContextMethodMixin.mark_non_differentiable

Marks outputs as non-differentiable.

function._ContextMethodMixin.save_for_backward

Saves given tensors for a future call to backward().

function._ContextMethodMixin.set_materialize_grads

Sets whether to materialize output grad tensors.

Numerical gradient checking

gradcheck

Check gradients computed via small finite differences against analytical gradients w.r.t.

gradgradcheck

Check gradients of gradients computed via small finite differences against analytical gradients w.r.t.

Profiler

Autograd 包含一个分析器,可让您检查模型中不同运算符的成本 - 在 CPU 和 GPU 上。 目前实现了两种模式 - 仅使用配置文件的 CPU。 和基于 nvprof(注册 CPU 和 GPU 活动)使用emit_nvtx。

torch.autograd.profiler.profile(enabled=True*use_cuda=Falserecord_shapes=Falsewith_flops=Falseprofile_memory=Falsewith_stack=Falseuse_kineto=Falseuse_cpu=True)

管理 autograd 分析器状态并保存结果摘要的上下文管理器。在幕后,它只记录在 C++ 中执行的函数的事件,并将这些事件暴露给 Python。您可以将任何代码包装到其中,它只会报告 PyTorch 函数的运行时。注意:探查器是线程本地的,会自动传播到异步任务中

Parameters

  • enabled (bool, optional) – 将此设置为 False 使此上下文管理器成为空操作。

    use_cuda (bool, optional) – 使用 cudaEvent API 启用 CUDA 事件的计时。 为每个张量操作增加大约 4us 的开销。

  • record_shapes (bool, optional) – 如果设置了形状记录,将收集有关输入维度的信息。 这允许人们查看引擎盖下使用了哪些维度,并使用 prof.key_averages(group_by_input_shape=True) 对它们进行进一步分组。 请注意,形状记录可能会扭曲您的分析数据。 建议使用带和不带形状记录的单独运行来验证时间。 对于最底部的事件(在嵌套函数调用的情况下),偏差很可能可以忽略不计。 但是对于更高级别的功能,由于形状集合,总的自 CPU 时间可能会人为地增加。
  • with_flops (bool, optional) – 如果设置了 with_flops,分析器将使用算子的输入形状和总时间估计 FLOPS(每秒浮点数操作)值。 这允许人们估计硬件性能。 目前,此选项仅适用于矩阵乘法和 2D 卷积算子。
  • 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
-----------------------------------  ---------------  ---------------  ---------------

profiler.profile.export_chrome_trace

Exports an EventList as a Chrome tracing tools file.

profiler.profile.key_averages

Averages all function events over their keys.

profiler.profile.self_cpu_time_total

Returns total time spent on CPU obtained as a sum of all self times across all the events.

profiler.profile.total_average

Averages all events.

CLASStorch.autograd.profiler.emit_nvtx(enabled=Truerecord_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 数字进行比较。

profiler.load_nvprof

Opens an nvprof trace file and parses autograd annotations.

Anomaly detection

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)。

你可能感兴趣的:(pytorch)