亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

pytorch .detach() .detach_() 和 .data用于切斷反向傳播的實(shí)現(xiàn)

 更新時(shí)間:2019年12月27日 14:36:44   作者:慢行厚積  
這篇文章主要介紹了pytorch .detach() .detach_() 和 .data用于切斷反向傳播的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

當(dāng)我們再訓(xùn)練網(wǎng)絡(luò)的時(shí)候可能希望保持一部分的網(wǎng)絡(luò)參數(shù)不變,只對其中一部分的參數(shù)進(jìn)行調(diào)整;或者值訓(xùn)練部分分支網(wǎng)絡(luò),并不讓其梯度對主網(wǎng)絡(luò)的梯度造成影響,這時(shí)候我們就需要使用detach()函數(shù)來切斷一些分支的反向傳播

1   detach()[source]

返回一個(gè)新的Variable,從當(dāng)前計(jì)算圖中分離下來的,但是仍指向原變量的存放位置,不同之處只是requires_grad為false,得到的這個(gè)Variable永遠(yuǎn)不需要計(jì)算其梯度,不具有g(shù)rad。

即使之后重新將它的requires_grad置為true,它也不會(huì)具有梯度grad

這樣我們就會(huì)繼續(xù)使用這個(gè)新的Variable進(jìn)行計(jì)算,后面當(dāng)我們進(jìn)行反向傳播時(shí),到該調(diào)用detach()的Variable就會(huì)停止,不能再繼續(xù)向前進(jìn)行傳播

源碼為:

def detach(self):
    """Returns a new Variable, detached from the current graph.
    Result will never require gradient. If the input is volatile, the output
    will be volatile too.
    .. note::
     Returned Variable uses the same data tensor, as the original one, and
     in-place modifications on either of them will be seen, and may trigger
     errors in correctness checks.
    """
    result = NoGrad()(self) # this is needed, because it merges version counters
    result._grad_fn = None
     return result

可見函數(shù)進(jìn)行的操作有:

  • 將grad_fn設(shè)置為None
  • 將Variable的requires_grad設(shè)置為False

如果輸入 volatile=True(即不需要保存記錄,當(dāng)只需要結(jié)果而不需要更新參數(shù)時(shí)這么設(shè)置來加快運(yùn)算速度),那么返回的Variable volatile=True。(volatile已經(jīng)棄用)

注意:

返回的Variable和原始的Variable公用同一個(gè)data tensor。in-place函數(shù)修改會(huì)在兩個(gè)Variable上同時(shí)體現(xiàn)(因?yàn)樗鼈児蚕韉ata tensor),當(dāng)要對其調(diào)用backward()時(shí)可能會(huì)導(dǎo)致錯(cuò)誤。

舉例:

比如正常的例子是:

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()

out.sum().backward()
print(a.grad)

返回:

(deeplearning) userdeMBP:pytorch user$ python test.py
None
tensor([0.1966, 0.1050, 0.0452])

當(dāng)使用detach()但是沒有進(jìn)行更改時(shí),并不會(huì)影響backward():

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)

#添加detach(),c的requires_grad為False
c = out.detach()
print(c)

#這時(shí)候沒有對c進(jìn)行更改,所以并不會(huì)影響backward()
out.sum().backward()
print(a.grad)

返回:

(deeplearning) userdeMBP:pytorch user$ python test.py
None
tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward>)
tensor([0.7311, 0.8808, 0.9526])
tensor([0.1966, 0.1050, 0.0452])

可見c,out之間的區(qū)別是c是沒有梯度的,out是有梯度的

如果這里使用的是c進(jìn)行sum()操作并進(jìn)行backward(),則會(huì)報(bào)錯(cuò):

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)

#添加detach(),c的requires_grad為False
c = out.detach()
print(c)

#使用新生成的Variable進(jìn)行反向傳播
c.sum().backward()
print(a.grad)

返回:

(deeplearning) userdeMBP:pytorch user$ python test.py
None
tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward>)
tensor([0.7311, 0.8808, 0.9526])
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    c.sum().backward()
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/tensor.py", line 102, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/autograd/__init__.py", line 90, in backward
    allow_unreachable=True)  # allow_unreachable flag
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

如果此時(shí)對c進(jìn)行了更改,這個(gè)更改會(huì)被autograd追蹤,在對out.sum()進(jìn)行backward()時(shí)也會(huì)報(bào)錯(cuò),因?yàn)榇藭r(shí)的值進(jìn)行backward()得到的梯度是錯(cuò)誤的:

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)

#添加detach(),c的requires_grad為False
c = out.detach()
print(c)
c.zero_() #使用in place函數(shù)對其進(jìn)行修改

#會(huì)發(fā)現(xiàn)c的修改同時(shí)會(huì)影響out的值
print(c)
print(out)

#這時(shí)候?qū)進(jìn)行更改,所以會(huì)影響backward(),這時(shí)候就不能進(jìn)行backward(),會(huì)報(bào)錯(cuò)
out.sum().backward()
print(a.grad)

返回:

(deeplearning) userdeMBP:pytorch user$ python test.py
None
tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward>)
tensor([0.7311, 0.8808, 0.9526])
tensor([0., 0., 0.])
tensor([0., 0., 0.], grad_fn=<SigmoidBackward>)
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    out.sum().backward()
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/tensor.py", line 102, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/anaconda3/envs/deeplearning/lib/python3.6/site-packages/torch/autograd/__init__.py", line 90, in backward
    allow_unreachable=True)  # allow_unreachable flag
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation

2   .data

如果上面的操作使用的是.data,效果會(huì)不同:

這里的不同在于.data的修改不會(huì)被autograd追蹤,這樣當(dāng)進(jìn)行backward()時(shí)它不會(huì)報(bào)錯(cuò),回得到一個(gè)錯(cuò)誤的backward值

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid()
print(out)


c = out.data
print(c)
c.zero_() #使用in place函數(shù)對其進(jìn)行修改

#會(huì)發(fā)現(xiàn)c的修改同時(shí)也會(huì)影響out的值
print(c)
print(out)

#這里的不同在于.data的修改不會(huì)被autograd追蹤,這樣當(dāng)進(jìn)行backward()時(shí)它不會(huì)報(bào)錯(cuò),回得到一個(gè)錯(cuò)誤的backward值
out.sum().backward()
print(a.grad)

返回:

(deeplearning) userdeMBP:pytorch user$ python test.py
None
tensor([0.7311, 0.8808, 0.9526], grad_fn=<SigmoidBackward>)
tensor([0.7311, 0.8808, 0.9526])
tensor([0., 0., 0.])
tensor([0., 0., 0.], grad_fn=<SigmoidBackward>)
tensor([0., 0., 0.])

上面的內(nèi)容實(shí)現(xiàn)的原理是:

In-place 正確性檢查

所有的Variable都會(huì)記錄用在他們身上的 in-place operations。如果pytorch檢測到variable在一個(gè)Function中已經(jīng)被保存用來backward,但是之后它又被in-place operations修改。當(dāng)這種情況發(fā)生時(shí),在backward的時(shí)候,pytorch就會(huì)報(bào)錯(cuò)。這種機(jī)制保證了,如果你用了in-place operations,但是在backward過程中沒有報(bào)錯(cuò),那么梯度的計(jì)算就是正確的。

⚠️下面結(jié)果正確是因?yàn)楦淖兊氖莝um()的結(jié)果,中間值a.sigmoid()并沒有被影響,所以其對求梯度并沒有影響:

import torch

a = torch.tensor([1, 2, 3.], requires_grad=True)
print(a.grad)
out = a.sigmoid().sum() #但是如果sum寫在這里,而不是寫在backward()前,得到的結(jié)果是正確的
print(out)


c = out.data
print(c)
c.zero_() #使用in place函數(shù)對其進(jìn)行修改

#會(huì)發(fā)現(xiàn)c的修改同時(shí)也會(huì)影響out的值
print(c)
print(out)

#沒有寫在這里
out.backward()
print(a.grad)

返回:

(deeplearning) userdeMBP:pytorch user$ python test.py
None
tensor(2.5644, grad_fn=<SumBackward0>)
tensor(2.5644)
tensor(0.)
tensor(0., grad_fn=<SumBackward0>)
tensor([0.1966, 0.1050, 0.0452])

3   detach_()[source]

將一個(gè)Variable從創(chuàng)建它的圖中分離,并把它設(shè)置成葉子variable

其實(shí)就相當(dāng)于變量之間的關(guān)系本來是x -> m -> y,這里的葉子variable是x,但是這個(gè)時(shí)候?qū)進(jìn)行了.detach_()操作,其實(shí)就是進(jìn)行了兩個(gè)操作:

  • 將m的grad_fn的值設(shè)置為None,這樣m就不會(huì)再與前一個(gè)節(jié)點(diǎn)x關(guān)聯(lián),這里的關(guān)系就會(huì)變成x, m -> y,此時(shí)的m就變成了葉子結(jié)點(diǎn)
  • 然后會(huì)將m的requires_grad設(shè)置為False,這樣對y進(jìn)行backward()時(shí)就不會(huì)求m的梯度

這么一看其實(shí)detach()和detach_()很像,兩個(gè)的區(qū)別就是detach_()是對本身的更改,detach()則是生成了一個(gè)新的variable

比如x -> m -> y中如果對m進(jìn)行detach(),后面如果反悔想還是對原來的計(jì)算圖進(jìn)行操作還是可以的

但是如果是進(jìn)行了detach_(),那么原來的計(jì)算圖也發(fā)生了變化,就不能反悔了

參考:https://pytorch-cn.readthedocs.io/zh/latest/package_references/torch-autograd/#detachsource

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Python中四種關(guān)系圖數(shù)據(jù)可視化的效果對比

    詳解Python中四種關(guān)系圖數(shù)據(jù)可視化的效果對比

    python關(guān)系圖的可視化主要就是用來分析一堆數(shù)據(jù)中,每一條數(shù)據(jù)的節(jié)點(diǎn)之間的連接關(guān)系從而更好的分析出人物或其他場景中存在的關(guān)聯(lián)關(guān)系。本文將制作四個(gè)不同的關(guān)系圖的可視化效果,感興趣的可以了解一下
    2022-11-11
  • 創(chuàng)建虛擬環(huán)境打包py文件的實(shí)現(xiàn)步驟

    創(chuàng)建虛擬環(huán)境打包py文件的實(shí)現(xiàn)步驟

    使用虛擬環(huán)境,可以為每個(gè)項(xiàng)目創(chuàng)建一個(gè)獨(dú)立的Python環(huán)境,每個(gè)環(huán)境都有自己的庫和版本,從而避免了依賴沖突,本文主要介紹了創(chuàng)建虛擬環(huán)境打包py文件的實(shí)現(xiàn)步驟,感興趣的可以了解一下
    2024-04-04
  • 基于python二叉樹的構(gòu)造和打印例子

    基于python二叉樹的構(gòu)造和打印例子

    今天小編就為大家分享一篇基于python二叉樹的構(gòu)造和打印例子,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Linux系統(tǒng)(CentOS)下python2.7.10安裝

    Linux系統(tǒng)(CentOS)下python2.7.10安裝

    這篇文章主要為大家詳細(xì)介紹了Linux系統(tǒng)(CentOS)下python2.7.10安裝圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • python3 中使用urllib問題以及urllib詳解

    python3 中使用urllib問題以及urllib詳解

    這篇文章主要介紹了python3 中使用urllib問題以及urllib詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Python matplotlib繪制實(shí)時(shí)數(shù)據(jù)動(dòng)畫

    Python matplotlib繪制實(shí)時(shí)數(shù)據(jù)動(dòng)畫

    Matplotlib作為Python的2D繪圖庫,它以各種硬拷貝格式和跨平臺(tái)的交互式環(huán)境生成出版質(zhì)量級別的圖形。本文將利用Matplotlib庫繪制實(shí)時(shí)數(shù)據(jù)動(dòng)畫,感興趣的可以了解一下
    2022-03-03
  • python安裝cx_Oracle和wxPython的方法

    python安裝cx_Oracle和wxPython的方法

    這篇文章主要介紹了python安裝cx_Oracle和wxPython的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • python網(wǎng)絡(luò)爬蟲 CrawlSpider使用詳解

    python網(wǎng)絡(luò)爬蟲 CrawlSpider使用詳解

    這篇文章主要介紹了python網(wǎng)絡(luò)爬蟲 CrawlSpider使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Tensorflow 實(shí)現(xiàn)將圖像與標(biāo)簽數(shù)據(jù)轉(zhuǎn)化為tfRecord文件

    Tensorflow 實(shí)現(xiàn)將圖像與標(biāo)簽數(shù)據(jù)轉(zhuǎn)化為tfRecord文件

    今天小編就為大家分享一篇Tensorflow 實(shí)現(xiàn)將圖像與標(biāo)簽數(shù)據(jù)轉(zhuǎn)化為tfRecord文件,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python將文本去空格并保存到txt文件中的實(shí)例

    Python將文本去空格并保存到txt文件中的實(shí)例

    今天小編就為大家分享一篇Python將文本去空格并保存到txt文件中的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07

最新評論