Pytorch Detach學習筆記

2021-09-29 07:37:29 字數 1888 閱讀 4655

detach:

官方文件介紹:

返回乙個新的 從當前圖中分離的 variable。

返回的 variable 永遠不會需要梯度

如果 被 detach 的variable volatile=true, 那麼 detach 出來的 volatile 也為 true

還有乙個注意事項,即:返回的 variable 和 被 detach 的variable 指向同乙個 tensor

import torch

from torch.nn import init

from torch.autograd import variable

t1 = torch.floattensor([1

.,2.

])v1 = variable(t1)

t2 = torch.floattensor([2

.,3.

])v2 = variable(t2)

v3 = v1 + v2

v3_detached = v3.detach(

)v3_detached.data.add_(t1)

# 修改了 v3_detached variable中 tensor 的值

print

(v3, v3_detached)

# v3 中tensor 的值也會改變

# detach 的原始碼

defdetach

(self)

: result = nograd(

)(self)

# this is needed, because it merges version counters

result._grad_fn =

none

return result

detach_:

官網文件:

將 variable 從建立它的 graph 中分離,把它作為葉子節點。

將 variable 的grad_fn 設定為 none,這樣,bp 的時候,到這個 variable 就找不到 它的 grad_fn,所以就不會再往後bp了。

將 requires_grad 設定為 false。這個感覺大可不必,但是既然原始碼中這麼寫了,如果有需要梯度的話可以再手動 將 requires_grad 設定為 true

# detach_ 的原始碼

defdetach_

(self)

:"""detaches the variable from the graph that created it, ****** it a

leaf.

"""self._grad_fn =

none

self.requires_grad =

false

具體應用:阻斷反向傳播

如果我們有兩個網路 a,b兩個關係是這樣的 y=a(x), z=b(y)現在我們想用 z.backward()來為 b網路的引數來求梯度,但是又不想求 a網路引數的梯度。我們可以這樣:

# y=a(x), z=b(y) 求b中引數的梯度,不求a中引數的梯度

# 第一種方法

y = a(x)

z = b(y.detach())

z.backward(

)# 第二種方法

y = a(x)

y.detach_(

)z = b(y)

z.backward(

)

在這種情況下,detach 和 detach_ 都可以用。但是如果 你也想用 y 來對 aa進行 bp 呢?那就只能用第一種方法了。因為 第二種方法 已經將 a 模型的輸出 給 detach(分離)了。

參考

學習學習再學習

如果乙個技能足夠複雜 比如從零學程式設計 那就不要指望讀完一本書就可以打天下。多買幾本書同類的書 因為每個作者的出發點是不一樣的,哪怕對同乙個概念都有不同的解釋說明。理解知識的重要過程之一就如牛的反芻一樣,要嚼一遍 嚥下去 再吐出來 再嚼一遍 再嚥下去 所以,既然一本書可以讀幾遍,那麼同一話題多應該...

學習 學習 再學習

原本要使用vs2005開發乙個b s專案的,沒有想到只能先暫時停停了,居然跟不上技術的發展了,呵呵,一直使用delphi delphi也沒能跟上 沒有想到轉到vs2005上竟然有這麼多要學的東西,當然目的是了做乙個好的系統。最近一直在學習asp.net ajax,雖然專案停了,但是我覺得值得,有很多...

只是學習 學習 再學習

通過做 讓我學會了很多東西 什麼 flash div css html js as 雖然都只是皮毛 不過 算是了解那麼一點點吧 哈哈 我還突然發現 我的 數學和英語 進步了不少 而且還都是很實用的 比在學校的進步可快多了 那句話說的很不錯 在你了解了一些皮毛之後你會發現很多東西你都必須去學。因為少一...