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 雖然都只是皮毛 不過 算是了解那麼一點點吧 哈哈 我還突然發現 我的 數學和英語 進步了不少 而且還都是很實用的 比在學校的進步可快多了 那句話說的很不錯 在你了解了一些皮毛之後你會發現很多東西你都必須去學。因為少一...