PyTorch 自動(dòng)差分包-Torch.Autograd

2020-09-14 18:06 更新

原文: PyTorch 自動(dòng)差分包-Torch.Autograd

torch.autograd提供了實(shí)現(xiàn)自動(dòng)區(qū)分任意標(biāo)量值函數(shù)的類和函數(shù)。 它需要對(duì)現(xiàn)有代碼進(jìn)行最小的更改-您只需要聲明Tensor,應(yīng)使用requires_grad=True關(guān)鍵字為其計(jì)算梯度。

torch.autograd.backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False, grad_variables=None)?

計(jì)算給定張量的梯度總和 w.r.t. 圖葉。

該圖使用鏈規(guī)則進(jìn)行區(qū)分。 如果tensors中的任何一個(gè)都是非標(biāo)量的(即,其數(shù)據(jù)具有多個(gè)元素)并且需要梯度,則將計(jì)算雅可比矢量積,在這種情況下,該函數(shù)還需要指定grad_tensors。 它應(yīng)該是長(zhǎng)度匹配的序列,其中包含雅可比向量積中的“向量”,通常是微分函數(shù) w.r.t 的梯度。 相應(yīng)的張量(對(duì)于不需要梯度張量的所有張量,None是可接受的值)。

此函數(shù)在樹葉中累積漸變-調(diào)用它之前可能需要將它們歸零。

參數(shù)

  • 張量(張量的序列)–將計(jì)算其導(dǎo)數(shù)的張量。
  • grad_tensors (( tensor 無(wú)序列)–雅可比向量積中的“向量”,通常是梯度 wrt 相應(yīng)張量的每個(gè)元素。 無(wú)法為標(biāo)量張量或不需要等級(jí)的張量指定任何值。 如果所有 grad_tensor 都可接受 None 值,則此參數(shù)是可選的。
  • keep_graph (bool , 可選)–如果False,則用于計(jì)算等級(jí)的圖形將被釋放。 請(qǐng)注意,幾乎在所有情況下都不需要將此選項(xiàng)設(shè)置為True,并且通??梢砸愿行У姆绞浇鉀Q它。 默認(rèn)為create_graph的值。
  • create_graph (bool 可選)–如果True,則將構(gòu)造導(dǎo)數(shù)圖,從而允許計(jì)算高階導(dǎo)數(shù) 產(chǎn)品。 默認(rèn)為False。

torch.autograd.grad(outputs, inputs, grad_outputs=None, retain_graph=None, create_graph=False, only_inputs=True, allow_unused=False)?

計(jì)算并返回輸出 w.r.t 的梯度總和。 輸入。

grad_outputs應(yīng)該是長(zhǎng)度匹配的序列output,其中包含 Jacobian 向量積中的“向量”,通常是預(yù)先計(jì)算的梯度 w.r.t。 每個(gè)輸出。 如果輸出不是 require_grad,則漸變可以為None

如果only_inputsTrue,則該函數(shù)將僅返回指定輸入的漸變列表。 如果是False,則漸變 w.r.t. 所有剩余的葉子仍將被計(jì)算,并將被累積到其.grad屬性中。

Parameters

  • 輸出(張量的序列)–微分功能的輸出。
  • 輸入(張量的序列)–輸入 w.r.t. 梯度將被返回(而不是累積到.grad中)。
  • grad_outputs (張量的序列)–雅可比向量積中的“向量”。 通常是漸變色 每個(gè)輸出。 無(wú)法為標(biāo)量張量或不需要等級(jí)的張量指定任何值。 如果所有 grad_tensor 都可接受 None 值,則此參數(shù)是可選的。 默認(rèn)值:無(wú)。
  • retain_graph (bool__, optional) – If False, the graph used to compute the grad will be freed. Note that in nearly all cases setting this option to True is not needed and often can be worked around in a much more efficient way. Defaults to the value of create_graph.
  • create_graph (bool , 可選)–如果True,則將構(gòu)造導(dǎo)數(shù)圖,從而允許計(jì)算高階導(dǎo)數(shù) 產(chǎn)品。 默認(rèn)值:False。
  • allow_unused (bool , 可選)–如果為False,則指定在計(jì)算輸出時(shí)未使用的輸入(及其等級(jí)) 始終為零)是錯(cuò)誤。 默認(rèn)為False。

局部禁用梯度計(jì)算

class torch.autograd.no_grad?

禁用梯度計(jì)算的上下文管理器。

當(dāng)您確定不會(huì)調(diào)用Tensor.backward()時(shí),禁用梯度計(jì)算對(duì)于推斷很有用。 它將減少用于具有 <cite>require_grad = True</cite> 的計(jì)算的內(nèi)存消耗。

在這種模式下,即使輸入具有 <cite>require_grad = True</cite> ,每個(gè)計(jì)算的結(jié)果也將具有 <cite>require_grad = False</cite> 。

使用 enable_grad 上下文管理器時(shí),此模式無(wú)效。

該上下文管理器是線程本地的; 它不會(huì)影響其他線程中的計(jì)算。

還用作裝飾器。

例:

>>> 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?

啟用梯度計(jì)算的上下文管理器。

如果已通過(guò) no_gradset_grad_enabled 禁用了梯度計(jì)算,則啟用梯度計(jì)算。

This context manager is thread local; it will not affect computation in other threads.

Also functions as a decorator.

Example:

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

將漸變計(jì)算設(shè)置為開或關(guān)的上下文管理器。

set_grad_enabled將根據(jù)其參數(shù)mode啟用或禁用 grads。 它可以用作上下文管理器或功能。

使用 enable_grad 上下文管理器時(shí),set_grad_enabled(False)不起作用。

This context manager is thread local; it will not affect computation in other threads.

Parameters

模式 (bool )–標(biāo)記是啟用 Grad(True)還是禁用(False)。 這可用于有條件地啟用漸變。

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 中支持就地操作很困難,并且在大多數(shù)情況下,我們不鼓勵(lì)使用它們。 Autograd 積極的緩沖區(qū)釋放和重用使其非常高效,就地操作實(shí)際上很少顯著降低內(nèi)存使用量的情況很少。 除非您在高內(nèi)存壓力下進(jìn)行操作,否則可能永遠(yuǎn)不需要使用它們。

就地正確性檢查

所有Tensor都跟蹤對(duì)其應(yīng)用的就地操作,并且如果實(shí)現(xiàn)檢測(cè)到在其中一個(gè)函數(shù)中保存了一個(gè)張量以用于后退,但此后對(duì)其進(jìn)行了修改,則一旦向后進(jìn)行修改,就會(huì)引發(fā)錯(cuò)誤 通行證開始。 這樣可以確保,如果您使用的是就地函數(shù)并且沒有看到任何錯(cuò)誤,則可以確保計(jì)算出的梯度是正確的。

變量(不建議使用)

警告

不推薦使用 Variable API:不再需要將變量用于帶有張量的 autograd。 Autograd 自動(dòng)將requires_grad設(shè)置為True的張量。 請(qǐng)?jiān)谙旅嬲业接嘘P(guān)更改的快速指南:

  • Variable(tensor)Variable(tensor, requires_grad)仍能按預(yù)期工作,但是它們返回張量而不是變量。
  • var.datatensor.data相同。
  • 現(xiàn)在,諸如var.backward(), var.detach(), var.register_hook()之類的方法可以在具有相同方法名稱的張量上使用。

此外,現(xiàn)在可以使用 torch.randn() , torch.zeros()torch.ones() 等工廠方法使用requires_grad=True創(chuàng)建張量 下列:

autograd_tensor = torch.randn((2, 3, 4), requires_grad=True)

張量自動(dòng)分級(jí)功能

class torch.Tensor


grad?

此屬性默認(rèn)為None,并在首次調(diào)用 backward() 計(jì)算self的梯度時(shí)成為張量。 然后,該屬性將包含計(jì)算出的梯度,將來(lái)對(duì) backward() 的調(diào)用將在其中累積(添加)梯度。

requires_grad?

如果需要為此張量計(jì)算梯度,則為True,否則為False。

注意

需要為張量計(jì)算梯度的事實(shí)并不意味著將填充 grad 屬性,有關(guān)更多詳細(xì)信息, is_leaf 。

is_leaf?

按照慣例,所有具有 requires_gradFalse的張量將是葉張量。

對(duì)于具有 requires_grad (即True)的張量,如果它們是由用戶創(chuàng)建的,則它們將是葉張量。 這意味著它們不是運(yùn)算的結(jié)果,因此grad_fn為“無(wú)”。

在調(diào)用 backward() 期間,僅葉子張量會(huì)填充其 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

backward(gradient=None, retain_graph=None, create_graph=False)?

計(jì)算電流張量 w.r.t. 圖葉。

該圖使用鏈規(guī)則進(jìn)行區(qū)分。 如果張量是非標(biāo)量的(即其數(shù)據(jù)具有多個(gè)元素)并且需要梯度,則該函數(shù)還需要指定gradient。 它應(yīng)該是匹配類型和位置的張量,其中包含微分函數(shù) w.r.t 的梯度。 self

此函數(shù)在樹葉中累積漸變-調(diào)用它之前可能需要將它們歸零。

Parameters

  • 梯度 (tensor 無(wú))–梯度 w.r.t. 張量。 如果它是張量,除非create_graph為 True,否則它將自動(dòng)轉(zhuǎn)換為不需要 grad 的張量。 無(wú)法為標(biāo)量張量或不需要等級(jí)的張量指定任何值。 如果 None 值可以接受,那么此參數(shù)是可選的。
  • keep_graph (bool , 可選)–如果False,則用于計(jì)算等級(jí)的圖形將被釋放。 請(qǐng)注意,幾乎在所有情況下都不需要將此選項(xiàng)設(shè)置為 True,并且通??梢砸愿行У姆绞浇鉀Q它。 默認(rèn)為create_graph的值。
  • create_graph (bool 可選)–如果True,則將構(gòu)造導(dǎo)數(shù)圖,從而允許計(jì)算高階導(dǎo)數(shù) 產(chǎn)品。 默認(rèn)為False

detach()?

返回與當(dāng)前圖形分離的新 Tensor。

結(jié)果將永遠(yuǎn)不需要漸變。

Note

返回的 Tensor 與原始 Tensor 共享相同的存儲(chǔ)。 可以看到對(duì)它們中的任何一個(gè)的就地修改,并且可能觸發(fā)正確性檢查中的錯(cuò)誤。 重要說(shuō)明:以前,就地大小/步幅/存儲(chǔ)更改(例如 <cite>resize</cite> / <cite>resizeas</cite> / <cite>set</cite> / <cite>transpose</cite> ) 返回的張量也會(huì)更新原始張量。 現(xiàn)在,這些就地更改將不再更新原始張量,而將觸發(fā)錯(cuò)誤。 對(duì)于稀疏張量:原位索引/值更改(例如 <cite>zero</cite> / <cite>copy</cite> / <cite>add</cite> )將不會(huì)再更新原始張量, 而是觸發(fā)錯(cuò)誤。

detach_()?

從創(chuàng)建它的圖形中分離張量,使其成為一片葉子。 視圖不能就地分離。

register_hook(hook)?

注冊(cè)一個(gè)倒鉤。

每當(dāng)計(jì)算相對(duì)于張量的梯度時(shí),都會(huì)調(diào)用該掛鉤。 掛鉤應(yīng)具有以下簽名:

hook(grad) -> Tensor or None

掛鉤不應(yīng)修改其自變量,但可以選擇返回一個(gè)新的漸變,該漸變將代替 grad 使用。

此函數(shù)返回帶有方法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

retain_grad()?

為非葉張量啟用.grad 屬性。

功能

class torch.autograd.Function?

記錄操作歷史并定義用于區(qū)分操作的公式。

Tensor上執(zhí)行的每個(gè)操作都會(huì)創(chuàng)建一個(gè)新的函數(shù)對(duì)象,該對(duì)象執(zhí)行計(jì)算并記錄其發(fā)生。 歷史記錄以 DAG 函數(shù)的形式保留,其邊緣表示數(shù)據(jù)依賴性(input <- output)。 然后,當(dāng)調(diào)用向后時(shí),通過(guò)調(diào)用每個(gè) Function 對(duì)象的 backward() 方法,并將返回的梯度傳遞到下一個(gè),以拓?fù)漤樞蛱幚韴D形 ] Function s。

通常,用戶與函數(shù)交互的唯一方法是創(chuàng)建子類并定義新操作。 這是擴(kuò)展 torch.autograd 的推薦方法。

每個(gè)功能對(duì)象只能使用一次(在向前傳遞中)。

例子:

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

定義用于區(qū)分操作的公式。

該功能將被所有子類覆蓋。

它必須接受上下文ctx作為第一個(gè)參數(shù),然后返回 forward() 返回的輸出數(shù)量,并且它應(yīng)該返回與 [forward()的輸入一樣多的張量 。 每個(gè)參數(shù)都是給定輸出的梯度 w.r.t,每個(gè)返回值都應(yīng)該是梯度 w.r.t。 相應(yīng)的輸入。

上下文可用于檢索在前向傳遞過(guò)程中保存的張量。 它還具有屬性ctx.needs_input_grad,它是一個(gè)布爾元組,表示每個(gè)輸入是否需要漸變。 例如,如果 forward() 的第一個(gè)輸入需要進(jìn)行 w.r.t.的梯度計(jì)算,則 backward() 將具有ctx.needs_input_grad[0] = True。 輸出。

static forward(ctx, *args, **kwargs)?

執(zhí)行操作。

This function is to be overridden by all subclasses.

它必須接受上下文 ctx 作為第一個(gè)參數(shù),后跟任意數(shù)量的參數(shù)(張量或其他類型)。

上下文可用于存儲(chǔ)張量,然后可以在向后傳遞過(guò)程中檢索這些張量。

上下文方法混合

創(chuàng)建新的 Function 時(shí), <cite>ctx</cite> 可使用以下方法。

class torch.autograd.function._ContextMethodMixin?

mark_dirty(*args)?

將給定張量標(biāo)記為在就地操作中已修改。

僅應(yīng)從 forward() 方法內(nèi)部調(diào)用一次,并且所有自變量均應(yīng)為輸入。

在調(diào)用forward()時(shí)在原位修改的每個(gè)張量都應(yīng)提供給此函數(shù),以確保檢查的正確性。 在修改之前或之后調(diào)用該函數(shù)都沒有關(guān)系。

mark_non_differentiable(*args)?

將輸出標(biāo)記為不可微分。

僅應(yīng)從 forward() 方法內(nèi)部調(diào)用一次,并且所有自變量均應(yīng)為輸出。

這會(huì)將輸出標(biāo)記為不需要梯度,從而提高了向后計(jì)算的效率。 您仍然需要為backward()中的每個(gè)輸出接受一個(gè)漸變,但是它始終將是零張量,其形狀與相應(yīng)輸出的形狀相同。

例如使用 用于從最大值Function返回的索引。

save_for_backward(*tensors)?

保存給定的張量以供將來(lái)調(diào)用backward()。

最多只能調(diào)用一次,并且只能從 forward() 方法內(nèi)部調(diào)用。

以后,可以通過(guò)saved_tensors屬性訪問(wèn)已保存的張量。 在將它們退還給用戶之前,應(yīng)進(jìn)行檢查以確保未在修改其內(nèi)容的任何就地操作中使用它們。

參數(shù)也可以是None

數(shù)值梯度檢查

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

檢查相對(duì)于分析梯度 w.r.t 的小有限差分計(jì)算出的梯度。 inputs中的浮點(diǎn)類型為requires_grad=True的張量。

在數(shù)值梯度和解析梯度之間的檢查使用 allclose() 。

Note

默認(rèn)值是為雙精度的input設(shè)計(jì)的。 如果input的精度較低,例如FloatTensor,則此檢查可能會(huì)失敗。

Warning

如果input中的任何已檢查張量具有重疊的內(nèi)存,即,不同的索引指向相同的內(nèi)存地址(例如,來(lái)自torch.expand()的索引),則此檢查可能會(huì)失敗,因?yàn)樵谶@些索引處通過(guò)點(diǎn)擾動(dòng)計(jì)算出的數(shù)值梯度將改變值 共享相同內(nèi)存地址的所有其他索引。

Parameters

  • 函數(shù)(函數(shù))–一個(gè) Python 函數(shù),接受 Tensor 輸入并返回 Tensor 或 Tensors 元組
  • 輸入(張量 tensor 的元組)–該功能的輸入
  • eps (python:float , 可選)–有限差分?jǐn)z動(dòng)
  • atol (python:float 可選)–絕對(duì)公差
  • rtol (python:float , 可選)–相對(duì)公差
  • raise_exception (bool , 可選)–指示如果檢查失敗,是否引發(fā)異常。 該異常提供有關(guān)故障確切性質(zhì)的更多信息。 這在調(diào)試 gradchecks 時(shí)很有用。
  • check_sparse_nnz (bool , 可選)–如果為 True,則 gradcheck 允許輸入 SparseTensor,對(duì)于輸入的任何 SparseTensor,gradcheck 將執(zhí)行 僅在 nnz 位置檢查。
  • nondet_tol (python:float 可選)–對(duì)不確定性的容忍度。 通過(guò)微分運(yùn)行相同的輸入時(shí),結(jié)果必須完全匹配(默認(rèn)值為 0.0)或在此公差范圍內(nèi)。

退貨

如果所有差異均滿足全封閉條件,則為真

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

檢查相對(duì)于分析梯度 w.r.t 的,通過(guò)小的有限差分計(jì)算出的梯度的梯度。 inputsgrad_outputs中的張量是浮點(diǎn)型且?guī)в?code>requires_grad=True的張量。

此函數(shù)檢查通過(guò)向給定grad_outputs計(jì)算的梯度進(jìn)行反向傳播是否正確。

The check between numerical and analytical gradients uses allclose().

Note

默認(rèn)值是為雙精度的inputgrad_outputs設(shè)計(jì)的。 如果它們的精度較低,例如FloatTensor,則此檢查可能會(huì)失敗。

Warning

如果inputgrad_outputs中的任何已檢查張量具有重疊的內(nèi)存,即指向同一內(nèi)存地址的不同索引(例如,來(lái)自torch.expand()的索引),則此檢查可能會(huì)失敗,因?yàn)樵谶@種情況下通過(guò)點(diǎn)攝動(dòng)計(jì)算出的數(shù)值梯度 索引將更改共享同一內(nèi)存地址的所有其他索引的值。

Parameters

  • func (function) – a Python function that takes Tensor inputs and returns a Tensor or a tuple of Tensors
  • inputs (tuple of Tensor or Tensor) – inputs to the function
  • grad_outputs (張量元組 tensor , 可選)–相對(duì)于函數(shù)輸出的漸變。
  • eps (python:float__, optional) – perturbation for finite differences
  • atol (python:float__, optional) – absolute tolerance
  • rtol (python:float__, optional) – relative tolerance
  • gen_non_contig_grad_outputs (bool 可選))–如果grad_outputsNone,gen_non_contig_grad_outputsTrue,則隨機(jī) 使生成的梯度輸出不連續(xù)
  • raise_exception (bool__, optional) – indicating whether to raise an exception if the check fails. The exception gives more information about the exact nature of the failure. This is helpful when debugging gradchecks.
  • nondet_tol (python:float 可選)–對(duì)不確定性的容忍度。 通過(guò)微分運(yùn)行相同的輸入時(shí),結(jié)果必須完全匹配(默認(rèn)值為 0.0)或在此公差范圍內(nèi)。 注意,梯度中的少量不確定性將導(dǎo)致二階導(dǎo)數(shù)的較大誤差。

Returns

True if all differences satisfy allclose condition

探查器

Autograd 包括一個(gè)探查器,可讓您檢查模型中不同運(yùn)算符的成本-包括 CPU 和 GPU。 目前有兩種模式-僅使用 profile 的 CPU。 并使用 emit_nvtx 基于 nvprof(注冊(cè) CPU 和 GPU 活動(dòng))。

class torch.autograd.profiler.profile(enabled=True, use_cuda=False, record_shapes=False)?

上下文管理器,用于管理 autograd profiler 狀態(tài)并保存結(jié)果摘要。 在后臺(tái),它僅記錄正在 C ++中執(zhí)行的函數(shù)的事件,并將這些事件公開給 Python。 您可以將任何代碼包裝到其中,并且它只會(huì)報(bào)告 PyTorch 函數(shù)的運(yùn)行時(shí)。

Parameters

  • 啟用 (bool , 可選)–將其設(shè)置為 False 會(huì)使此上下文管理器變?yōu)闊o(wú)操作。 默認(rèn)值:True。
  • use_cuda (bool , 可選)–以及使用 cudaEvent API 啟用 CUDA 事件的計(jì)時(shí)。 每個(gè)張量操作會(huì)增加大約 4us 的開銷。 默認(rèn)值:False
  • record_shapes (bool , 可選)–如果設(shè)置了形狀記錄,將收集有關(guān)輸入尺寸的信息。 這樣一來(lái),您可以查看引擎蓋下使用了哪些尺寸,并使用 prof.key_averages(group_by_input_shape = True)將它們進(jìn)一步分組。 請(qǐng)注意,形狀記錄可能會(huì)歪曲您的輪廓數(shù)據(jù)。 建議使用帶有和不帶有形狀記錄的單獨(dú)運(yùn)行來(lái)驗(yàn)證計(jì)時(shí)。 對(duì)于最底層的事件(在嵌套函數(shù)調(diào)用的情況下),偏斜很可能會(huì)忽略不計(jì)。 但是對(duì)于較高級(jí)別的功能,由于形狀收集,可能會(huì)人為地增加總的自體 cpu 時(shí)間。

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

將 EventList 導(dǎo)出為 Chrome 跟蹤工具文件。

稍后可以在chrome://tracing URL 下加載和檢查檢查點(diǎn)。

Parameters

路徑 (str )–將寫入跟蹤的路徑。

key_averages(group_by_input_shape=False)?

平均所有功能事件的鍵。

@param group_by_input_shapes 該鍵將變?yōu)?事件名稱,輸入維度),而不僅僅是事件名稱。 這對(duì)于查看哪個(gè)維度對(duì)運(yùn)行時(shí)間的貢獻(xiàn)最大是很有用的,并且可以幫助進(jìn)行特定于維度的優(yōu)化或選擇最佳的量化候選對(duì)象(也就是擬合屋頂線)

Returns

一個(gè)包含 FunctionEventAvg 對(duì)象的 EventList。

property self_cpu_time_total?

返回花費(fèi)在 CPU 上的總時(shí)間,作為所有事件中所有自身時(shí)間的總和。

table(sort_by=None, row_limit=100, header=None)?

將 EventList 打印為格式正確的表。

Parameters

sort_by (str 可選)–用于對(duì)條目進(jìn)行排序的屬性。 默認(rèn)情況下,它們以與注冊(cè)時(shí)相同的順序打印。 有效密鑰包括:cpu_time,cuda_time,cpu_time_totalcuda_time_total,count。

Returns

包含表的字符串。

total_average()?

平均所有事件。

Returns

FunctionEventAvg 對(duì)象。

class torch.autograd.profiler.record_function(name)?

上下文管理器,在運(yùn)行 autograd profiler 時(shí)將標(biāo)簽添加到 Python 代碼塊中。 在跟蹤代碼配置文件時(shí)很有用。

Parameters

名稱 (str )–分配給代碼塊的標(biāo)簽。

Example

>>> x = torch.randn((1, 1), requires_grad=True)
>>> with torch.autograd.profiler.profile() as prof:
...     y = x ** 2
...     with torch.autograd.profiler.record_function("label-z"): # label the block
...         z = y ** 3
...     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
-----------------------------------  ---------------  ---------------  ---------------
pow                                  60.77%           47.470us         3
mul                                  21.73%           25.465us         2
PowBackward0                         12.03%           121.891us        1
torch::autograd::AccumulateGrad      2.70%            6.324us          1
label-z                              2.13%            12.421us         1
torch::autograd::GraphRoot           0.64%            1.503us          1
-----------------------------------  ---------------  ---------------  ---------------
Self CPU time total: 234.344us
CUDA time total: 0.000us

class torch.autograd.profiler.emit_nvtx(enabled=True, record_shapes=False)?

使每個(gè)自動(dòng)分級(jí)操作發(fā)出 NXTX 范圍的上下文管理器。

在 nvprof 下運(yùn)行程序時(shí),它很有用:

nvprof --profile-from-start off -o trace_name.prof -- <regular command here>

不幸的是,無(wú)法強(qiáng)制 nvprof 將收集到的數(shù)據(jù)刷新到磁盤,因此對(duì)于 CUDA 分析,必須使用此上下文管理器注釋 nvprof 跟蹤并等待進(jìn)程退出后再檢查它們。 然后,可以使用 NVIDIA Visual Profiler(nvvp)可視化時(shí)間軸,或者 torch.autograd.profiler.load_nvprof() 可以加載結(jié)果以進(jìn)行檢查,例如 在 Python REPL 中。

Parameters

  • 啟用 (bool 可選 , 默認(rèn)= True )–設(shè)置enabled=False使此上下文管理器成為禁止操作。 默認(rèn)值:True
  • record_shapes (bool , 可選 , 默認(rèn)=假)–如果record_shapes=True,包裝每個(gè) autograd 操作的 nvtx 范圍將以以下格式附加有關(guān)該操作接收的 Tensor 參數(shù)的大小的信息:[[arg0.size(0), arg0.size(1), ...], [arg1.size(0), arg1.size(1), ...], ...]非張量參數(shù)將由[]表示。 參數(shù)將按照后端操作接收到的順序列出。 請(qǐng)注意,此順序可能與在 Python 端傳遞這些參數(shù)的順序不匹配。 還要注意,形狀記錄可能會(huì)增加 nvtx 范圍創(chuàng)建的開銷。

Example

>>> with torch.cuda.profiler.profile():
...     model(x) # Warmup CUDA memory allocator and profiler
...     with torch.autograd.profiler.emit_nvtx():
...         model(x)

前向后相關(guān)

當(dāng)在 Nvidia Visual Profiler 中查看使用 emit_nvtx 創(chuàng)建的配置文件時(shí),將每個(gè)后向操作與相應(yīng)的前向操作相關(guān)聯(lián)可能很困難。 為了簡(jiǎn)化此任務(wù), emit_nvtx 將序列號(hào)信息附加到它生成的范圍。

在前進(jìn)過(guò)程中,每個(gè)功能范圍均以seq=<N>裝飾。 seq是一個(gè)運(yùn)行計(jì)數(shù)器,每次創(chuàng)建一個(gè)新的向后功能對(duì)象時(shí)都將遞增并存放以用于向后。 因此,與每個(gè)前向功能范圍相關(guān)聯(lián)的seq=<N>注釋告訴您,如果通過(guò)此前向功能創(chuàng)建后向功能對(duì)象,則后向?qū)ο髮⒔邮招蛄刑?hào) N。在后向傳遞過(guò)程中,包裝每個(gè) C ++的頂級(jí)范圍 向后函數(shù)的apply()調(diào)用裝飾有stashed seq=<M>。 M是創(chuàng)建反向?qū)ο蟮男蛄刑?hào)。 通過(guò)比較后向的stashed seq數(shù)字和正向的seq數(shù)字,您可以跟蹤哪個(gè)正向運(yùn)算符創(chuàng)建了每個(gè)向后功能。

向后傳遞過(guò)程中執(zhí)行的所有功能也都用seq=<N>裝飾。 在默認(rèn)向后(使用create_graph=False)期間,此信息無(wú)關(guān)緊要,實(shí)際上,對(duì)于所有此類功能,N可能只是 0。 只有與向后功能對(duì)象的apply()方法關(guān)聯(lián)的頂級(jí)范圍才有用,可以將這些功能對(duì)象與更早的向前傳遞相關(guān)聯(lián)。

雙向

另一方面,如果正在進(jìn)行create_graph=True的向后傳遞(換句話說(shuō),如果您要進(jìn)行雙向后退),則向后執(zhí)行過(guò)程中每個(gè)函數(shù)的執(zhí)行都將被賦予非零且有用的seq=<N>。 這些函數(shù)本身可以創(chuàng)建 Function 對(duì)象,以便稍后在雙向后執(zhí)行時(shí),就像向前傳遞中的原始函數(shù)一樣。 向后和雙向后之間的關(guān)系在概念上與向前和向后之間的關(guān)系相同:這些函數(shù)仍會(huì)發(fā)出帶有當(dāng)前序列號(hào)標(biāo)記的范圍,它們創(chuàng)建的 Function 對(duì)象仍會(huì)存儲(chǔ)這些序列號(hào),并且在最終 double- 向后,功能對(duì)象的apply()范圍仍標(biāo)記有stashed seq數(shù)字,可以將其與從后向傳遞的 <cite>seq</cite> 數(shù)字進(jìn)行比較。

torch.autograd.profiler.load_nvprof(path)?

打開 nvprof 跟蹤文件并解析 autograd 批注。

Parameters

路徑 (str )– nvprof 跟蹤的路徑

異常檢測(cè)

class torch.autograd.detect_anomaly?

上下文管理器,可為 autograd 引擎啟用異常檢測(cè)。

這有兩件事:-在啟用檢測(cè)的情況下運(yùn)行正向傳遞,將允許反向傳遞打印創(chuàng)建失敗的反向函數(shù)的正向操作的回溯。 -任何產(chǎn)生“ nan”值的向后計(jì)算都會(huì)引發(fā)錯(cuò)誤。

Warning

僅在調(diào)試時(shí)才應(yīng)啟用此模式,因?yàn)椴煌臏y(cè)試會(huì)減慢程序的執(zhí)行速度。

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 "<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)?

上下文管理器,用于打開或關(guān)閉 autograd 引擎的異常檢測(cè)。

set_detect_anomaly將基于其參數(shù)mode啟用或禁用自動(dòng)求導(dǎo)異常檢測(cè)。 它可以用作上下文管理器或功能。

有關(guān)異常檢測(cè)行為的詳細(xì)信息,請(qǐng)參見上面的detect_anomaly

Parameters

模式 (bool )–標(biāo)記是啟用異常檢測(cè)(True)還是禁用(False)。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)