torch.autograd提供实现任意标量值函数的自动微分的类和函数。它只需要对现有代码进行最小的更改—您只需要声明张量s,对于该张量,应该使用requires_grad=True关键字计算梯度。
torch.autograd.backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False, grad_variables=None)[source]
计算给定张量w.r.t.图叶的梯度和。用链式法则对图求导。如果任何张量是非标量的(即它们的数据有多个元素),并且需要梯度,那么将计算雅可比向量积,在这种情况下,函数还需要指定grad_tensors。它应该是一个长度匹配的序列,包含雅可比向量积中的“向量”,通常是微分函数w.r.t.对应的张量的梯度(对于所有不需要梯度张量的张量,None都是可接受的值)。这个函数在叶子中积累梯度——您可能需要在调用它之前将它们归零。
参数
torch.autograd.grad(outputs, inputs, grad_outputs=None, retain_graph=None, create_graph=False, only_inputs=True, allow_unused=False)[source]
计算并返回输出梯度和输入梯度的和。grad_output应该是包含Jacobian-vector积中的“向量”的长度匹配输出序列,通常是预先计算的梯度w.r.t。如果输出不需要require_grad,则梯度可以为None)。如果only_input为真,函数将只返回梯度w.r的列表。t指定的输入。如果为False,那么梯度w.r.t.仍然会计算所有剩余的叶子,并将其累积到.grad属性中。
Parameters
class torch.autograd.no_grad
[source]
上下文管理器,禁用梯度计算。当您确信不会调用tensor.backr()时,禁用梯度计算对于推断非常有用。它将减少计算的内存消耗,否则,requires_grad=True。在这种模式下,即使输入requires_grad=True,每个计算的结果都将是requires_grad=False。当使用enable_grad上下文管理器时,此模式没有效果。它不会影响其他线程中的计算。还可以用作装饰器。
Example:
>>> x = torch.tensor([1], requires_grad=True)
>>> with torch.no_grad():
... y = x * 2
>>> y.requires_grad
False
>>> @torch.no_grad()
... def doubler(x):
... return x * 2
>>> z = doubler(x)
>>> z.requires_grad
False
class torch.autograd.enable_grad
[source]
上下文管理器,支持梯度计算。如果通过no_grad或set_grad_enabled禁用梯度计算,则启用梯度计算。这个上下文管理器是线程本地的;它不会影响其他线程中的计算。还可以用作装饰器。
例:
>>> x = torch.tensor([1], requires_grad=True)
>>> with torch.no_grad():
... with torch.enable_grad():
... y = x * 2
>>> y.requires_grad
True
>>> y.backward()
>>> x.grad
>>> @torch.enable_grad()
... def doubler(x):
... return x * 2
>>> with torch.no_grad():
... z = doubler(x)
>>> z.requires_grad
True
class torch.autograd.set_grad_enabled
(mode)[source]
将梯度计算设置为on或off.set_grad_enabled的上下文管理器将根据其参数模式启用或禁用梯度。它可以用作上下文管理器或函数。当使用enable_grad上下文管理器时,set_grad_enabled(False)没有效果。这个上下文管理器是线程本地的;它不会影响其他线程中的计算。
Parameters
mode (bool) – Flag whether to enable grad (True
), or disable (False
). This can be used to conditionally enable gradients.
Example:
>>> x = torch.tensor([1], requires_grad=True)
>>> is_train = False
>>> with torch.set_grad_enabled(is_train):
... y = x * 2
>>> y.requires_grad
False
>>> torch.set_grad_enabled(True)
>>> y = x * 2
>>> y.requires_grad
True
>>> torch.set_grad_enabled(False)
>>> y = x * 2
>>> y.requires_grad
False
在autograd中支持就地操作是一件困难的事情,我们在大多数情况下不鼓励使用它们。Autograd积极的缓冲区释放和重用使其非常高效,并且很少有就地操作实际降低内存使用量的情况。除非您在沉重的内存压力下操作,否则您可能永远都不需要使用它们。
所有张量都跟踪应用于它们的就地操作,如果实现检测到一个张量在其中一个函数中被保存为倒向操作,但随后对其进行了就地修改,那么一旦开始倒向传递,就会产生错误。这确保了如果您使用的是就地函数而没有看到任何错误,那么您可以确保计算出的梯度是正确的。
Warning
变量API已经被弃用:变量不再需要与张量一起使用autograd。Autograd自动支持requires_grad设置为True的张量。请在下面找到一个快速指南,了解发生了什么变化:
此外,现在可以使用工厂方法创建requires_grad=True的张量,如torch.randn()、torch.zeros()、torch.ones()和其他类似的方法:
autograd_tensor = torch.randn((2, 3, 4), requires_grad=True)
class torch.Tensor
backward
(gradient=None, retain_graph=None, create_graph=False)[source]
计算电流张量w.r.t.图叶的梯度。用链式法则对图求导。如果张量是非标量的(即它的数据有多个元素),并且需要梯度,那么函数还需要指定梯度。它应该是一个匹配类型和位置的张量,包含微分函数w.r.t. self的梯度。这个函数在叶子中积累梯度——您可能需要在调用它之前将它们归零。
Parameters
detach
()
返回一个与当前图分离的新张量。结果不需要梯度。
Note
返回的张量与原张量共享相同的存储空间。将看到对其中任何一个进行的就地修改,并可能在正确性检查中引发错误。重要注意:以前,对返回张量的就地大小/步长/存储更改(例如resize_ / resize_as_ / set_ / transpose_)也会更新原始张量。现在,这些到位的改变将不再更新原来的张量,而是会触发一个错误。对于稀疏张量:对返回张量的就地索引/值更改(如zero_ / copy_ / add_)将不再更新原始张量,而是触发一个错误。
detach_
()
将张量从生成它的图中分离出来,使它成为一片叶子。视图不能在适当位置分离。
grad
这个属性在默认情况下是None,并且在第一次调用reverse()为self计算梯度时变成一个张量。然后,该属性将包含计算得到的梯度,未来对reverse()的调用将在其中累积(添加)梯度。
is_leaf
所有有requires_grad为假的张量都是叶张量。对于requires_grad为真的张量,如果它们是由用户创建的,那么它们就是叶张量。这意味着它们不是操作的结果,因此grad_fn是None。只有叶张量在调用back()期间才会填充它们的grad。要为非叶张量填充grad,可以使用retain_grad()。
Example:
>>> a = torch.rand(10, requires_grad=True)
>>> a.is_leaf
True
>>> b = torch.rand(10, requires_grad=True).cuda()
>>> b.is_leaf
False
# b was created by the operation that cast a cpu Tensor into a cuda Tensor
>>> c = torch.rand(10, requires_grad=True) + 2
>>> c.is_leaf
False
# c was created by the addition operation
>>> d = torch.rand(10).cuda()
>>> d.is_leaf
True
# d does not require gradients and so has no operation creating it (that is tracked by the autograd engine)
>>> e = torch.rand(10).cuda().requires_grad_()
>>> e.is_leaf
True
# e requires gradients and has no operations creating it
>>> f = torch.rand(10, requires_grad=True, device="cuda")
>>> f.is_leaf
True
# f requires grad, has no operation creating it
register_hook
(hook)[source]
注册一个向后的钩子。每次计算关于张量的梯度时,都会调用这个钩子。钩子应该有以下签名:
hook(grad) -> Tensor or None
钩子不应该修改它的参数,但是它可以选择返回一个新的渐变,这个渐变将代替grad。该函数返回一个句柄和一个方法handle.remove(),该方法从模块中删除钩子。
Example:
>>> v = torch.tensor([0., 0., 0.], requires_grad=True)
>>> h = v.register_hook(lambda grad: grad * 2) # double the gradient
>>> v.backward(torch.tensor([1., 2., 3.]))
>>> v.grad
2
4
6
[torch.FloatTensor of size (3,)]
>>> h.remove() # removes the hook
requires_grad
如果需要计算这个张量的梯度,则为真,否则为假。
Note
需要为张量计算梯度的事实并不意味着将填充grad属性,更多细节请参见is_leaf。
retain_grad
()[source]
为非叶张量启用.grad属性。
class torch.autograd.Function
[source]
记录操作历史并定义微分操作系统的公式。对张量s执行的每一个操作都会创建一个新的函数对象,这个函数对象执行计算并记录它的发生。历史记录以函数DAG的形式保留,边缘表示数据依赖关系(输入<-输出)。然后,当调用倒向时,通过调用每个函数对象的倒向()方法,并将返回的梯度传递给下一个函数s,按拓扑顺序处理图。通常,用户与函数交互的唯一方式是创建子类和定义新操作。这是一个推荐的扩展火炬。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
static backward
(ctx, *grad_outputs)[source]
定义微分运算的公式。这个函数将被所有子类覆盖。它必须接受上下文ctx作为第一个参数,后面跟随着许多forward()返回的输出,并且它应该返回与forward()输入一样多的张量。每个参数都是梯度w.r。t为给定的输出,每个返回值为梯度w.r.t为对应的输入。上下文可用于检索前向传递期间保存的张量。它还有一个属性ctx。needs_input_grad作为布尔值的元组,表示每个输入是否需要梯度。例如,back()将有ctx。如果forward()的第一个输入需要梯度计算w.r.t.,则needs_input_grad[0] = True。
static forward
(ctx, *args, **kwargs)[source]
执行操作。这个函数将被所有子类覆盖。它必须接受上下文ctx作为第一个参数,然后是任意数量的参数(张量或其他类型)。上下文可用于存储张量,然后在向后传递期间检索张量。
torch.autograd.gradcheck(func, inputs, eps=1e-06, atol=1e-05, rtol=0.001, raise_exception=True, check_sparse_nnz=False, nondet_tol=0.0)[source]
在浮点类型的输入中,使用requires_grad=True,通过与解析梯度w.r.t.张量之间的有限差分计算梯度,检查梯度。数值梯度和解析梯度之间的检查使用allclose()。
Note
默认值是为双精度输入设计的。如果输入精度较低,例如,浮动器,这种检查可能会失败。
Warning
如果输入中的任何校验张量有重叠的内存,即,指向相同内存地址的不同索引(例如,从torch.expand()),此检查可能会失败,因为在这些索引处由点扰动计算的数值梯度将更改共享相同内存地址的所有其他索引的值。
Parameters
Returns
True if all differences satisfy allclose condition
torch.autograd.gradgradcheck
(func, inputs, grad_outputs=None, eps=1e-06, atol=1e-05, rtol=0.001, gen_non_contig_grad_outputs=False, raise_exception=True, nondet_tol=0.0)[source]
在输入和输出为浮点类型且requires_grad=True的grad_output中,通过与解析梯度w.r.t.张量之间的有限差分计算梯度的梯度梯度,检查梯度梯度的梯度梯度。此函数检查通过计算到给定grad_output的梯度反向传播是否正确。数值梯度和解析梯度之间的检查使用allclose()。
Note
默认值是为双精度的输入和grad_output设计的。如果这种检查不太精确,例如,浮动器,则很可能会失败。
Warning
如果输入和输出中的任何检查过的张量有重叠的内存,即,指向相同内存地址的不同索引(例如,从torch.expand()),此检查可能会失败,因为在这些索引处由点扰动计算的数值梯度将更改共享相同内存地址的所有其他索引的值。
Parameters
返回值:
如果所有的差异满足所有封闭条件,则为真
Autograd包括一个分析器,它可以让你检查模型中不同操作符的成本-在CPU和GPU上。目前有两种模式实现—仅使用cpu的profile。和基于nvprof(注册CPU和GPU活动)使用emit_nvtx。
class torch.autograd.profiler.profile
(enabled=True, use_cuda=False, record_shapes=False)[source]
上下文管理器,管理autograd分析器状态并保存结果摘要。在底层,它只记录在c++中执行的函数的事件,并将这些事件公开给Python。您可以将任何代码封装到其中,它将只报告PyTorch函数的运行时。
Parameters
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
----------------------------------- --------------- --------------- ---------------
export_chrome_trace
(path)[source]
将事件列表导出为Chrome跟踪工具文件。检查点稍后可以在chrome:// tracking URL下加载和检查。
参数
path (str) – Path where the trace will be written.
key_averages
(group_by_input_shape=False)[source]
对键上的所有函数事件求平均值。@param group_by_input_shapes键将变成(事件名称、输入维度),而不仅仅是事件名称。这有助于了解哪个维度对运行时的影响最大,并可能有助于进行特定维度的优化或选择最佳量化候选项(即拟合屋顶线)
返回值:
包含FunctionEventAvg对象的事件列表。
property self_cpu_time_total
返回所有事件中所有self时间之和在CPU上花费的总时间。
table
(sort_by=None, row_limit=100, header=None)[source]
将EventList打印为格式良好的表。
参数
sort_by (str, optional) – 属性,用于对项进行排序。默认情况下,它们按照与注册时相同的顺序打印。有效密钥包括:cpu_time、cuda_time、cpu_time_total、cuda_time_total、count。
返回值
包含表的字符串。
total_average
()[source]
Averages all events.
Returns
平均所有事件。
class torch.autograd.profiler.emit_nvtx
(enabled=True, record_shapes=False)[source]
上下文管理器,使每个autograd操作发出NVTX范围。这是有用的,当运行程序下的nvprof:
nvprof --profile-from-start off -o trace_name.prof -- <regular command here>
不幸的是,没有办法强制nvprof将它收集的数据刷新到磁盘,因此对于CUDA分析,必须使用这个上下文管理器来注释nvprof跟踪,并等待进程退出后再检查它们。然后,NVIDIA Visual Profiler (nvvp)可以用来可视化时间轴,或者torch.autograd.profiler.load_nvprof()可以加载结果以供检查,例如在Python REPL中。
Parameters
例
>>> 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=<N>装饰。seq是一个运行计数器,每次创建一个新的后向函数对象并为后向保存时,seq都会递增。因此,seq = < N >注释与每个向前关联函数范围告诉你,如果一个向前向后创建函数对象的函数,落后的对象将会收到序列号N在向后传递,顶级包装向后每个c++函数的应用范围()调用装饰着藏seq = < M >。M是用来创建向后对象的序列号。通过比较向后隐藏的seq号和向前隐藏的seq号,您可以跟踪哪个正向op创建了每个向后函数。在向后传递期间执行的任何函数也用seq=<N>装饰。在默认的向后(使用create_graph=False)期间,这个信息是不相关的,事实上,对于所有这样的函数,N可能只是0。只有与后向函数对象的apply()方法关联的顶级范围才有用,这是将这些函数对象与前面的前向传递关联起来的一种方法。
Double-backward
另一方面,如果正在执行create_graph=True的向后传递(换句话说,如果您正在设置双向后传递),那么在向后传递期间,每个函数的执行都会得到一个非零的、有用的seq=<N>。这些函数本身可以创建函数对象,稍后在双向后期间执行,就像前向传递中的原始函数所做的那样。落后和double-backward之间概念上的关系之间的关系一样向前和向后:功能仍然发出current-sequence-number-tagged范围,他们创造的函数对象仍然隐藏这些序列号,在最终double-backward,函数对象的适用范围()仍用藏seq数字标记,它可以被比作seq向后传递的数字。
torch.autograd.profiler.load_nvprof
(path)[source]
打开一个nvprof跟踪文件并解析autograd注释。
参数
path (str) – path to nvprof trace
class torch.autograd.detect_anomaly
[source]
上下文管理器,为autograd引擎启用异常检测。这做了两件事:-在启用检测的情况下运行前向传递将允许后向传递打印创建失败后向函数的前向操作的回溯。-任何产生“nan”值的向后计算都会产生错误。
例
>>> 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 "<stdin>", line 1, in <module>
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 "<stdin>", 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 <module>
out = run_fn(inp)
File "tmp.py", line 44, in run_fn
out = MyFunc.apply(a)
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
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 "<stdin>", line 8, in backward
RuntimeError: Some error in backward
class torch.autograd.set_detect_anomaly
(mode)[source]
设置autograd引擎异常检测on或off. set_detect_exception的上下文管理器将根据其参数模式启用或禁用autograd异常检测。它可以用作上下文管理器或函数。有关异常检测行为的详细信息,请参见上面的detect_exception。
参数
mode (bool) – Flag whether to enable anomaly detection (True
), or disable (False
).