欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Pytorch中.detach()與.data的用法小結(jié)

 更新時(shí)間:2023年07月26日 08:22:17   作者:新生代農(nóng)民工  
這篇文章主要介紹了Pytorch中.detach()與.data的用法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Pytorch中.detach()與.data的用法

這里是官方文檔對(duì)detach的定義

實(shí)際上,detach()就是返回一個(gè)新的tensor,并且這個(gè)tensor是從當(dāng)前的計(jì)算圖中分離出來(lái)的。但是返回的tensor和原來(lái)的tensor是共享內(nèi)存空間的。

import torch
a = torch.tensor([1.0, 2.0, 3.0], requires_grad = True)
a = a.detach() # 會(huì)將requires_grad 屬性設(shè)置為False
print(a.requires_grad)

舉個(gè)例子來(lái)說(shuō)明一下detach有什么用。 如果A網(wǎng)絡(luò)的輸出被喂給B網(wǎng)絡(luò)作為輸入, 如果我們希望在梯度反傳的時(shí)候只更新B中參數(shù)的值,而不更新A中的參數(shù)值,這時(shí)候就可以使用detach()

a = A(input)
a = a.deatch() # 或者a.detach_()進(jìn)行in_place操作
out = B(a)
loss = criterion(out, labels)
loss.backward()

如果希望修改A的參數(shù), 而不希望修改B的參數(shù), 那么就需要手動(dòng)將B中參數(shù)的requires_grad屬性設(shè)置為False

for param in B.parameters():
    param.requires_grad = False

還有一點(diǎn)需要注意的是Tensor.detach()和Tensor.data的區(qū)別

Tensor.data和Tensor.detach()一樣, 都會(huì)返回一個(gè)新的Tensor, 這個(gè)Tensor和原來(lái)的Tensor共享內(nèi)存空間,一個(gè)改變,另一個(gè)也會(huì)隨著改變,且都會(huì)設(shè)置新的Tensor的requires_grad屬性為False。這兩個(gè)方法只取出原來(lái)Tensor的tensor數(shù)據(jù), 丟棄了grad、grad_fn等額外的信息。區(qū)別在于Tensor.data不能被autograd追蹤到,如果你修改了Tensor.data返回的新Tensor,原來(lái)的Tensor也會(huì)改變, 但是這時(shí)候的微分并沒(méi)有被追蹤到,那么當(dāng)你執(zhí)行l(wèi)oss.backward()的時(shí)候并不會(huì)報(bào)錯(cuò),但是求的梯度就是錯(cuò)誤的!因此, 如果你使用了Tensor.data,那么切記一定不要隨便修改返回的新Tensor的值。如果你使用的是Tensor.detach()方法,當(dāng)你修改他的返回值并進(jìn)行求導(dǎo)操作,會(huì)報(bào)錯(cuò)。 因此,Tensor.detach()是安全的。

pytorch中的.detach和.data深入詳解

前言:這兩個(gè)方法都可以用來(lái)從原有的計(jì)算圖中分離出某一個(gè)tensor,有相似的地方,也有不同的地方,下面來(lái)比較性的看一看。PyTorch0.4以及之后的版本中,.data 仍保留,但建議使用 .detach()

一、tensor.data的使用

先直接看一段代碼:

import torch
a = torch.tensor([1,2,3.], requires_grad = True)
out = a.sigmoid()
c = out.data  # 需要走注意的是,通過(guò).data “分離”得到的的變量會(huì)和原來(lái)的變量共用同樣的數(shù)據(jù),而且新分離得到的張量是不可求導(dǎo)的,c發(fā)生了變化,原來(lái)的張量也會(huì)發(fā)生變化
c.zero_()     # 改變c的值,原來(lái)的out也會(huì)改變
print(c.requires_grad)
print(c)
print(out.requires_grad)
print(out)
print("----------------------------------------------")
out.sum().backward() # 對(duì)原來(lái)的out求導(dǎo),
print(a.grad)  # 不會(huì)報(bào)錯(cuò),但是結(jié)果卻并不正確
'''運(yùn)行結(jié)果為:
False
tensor([0., 0., 0.])
True
tensor([0., 0., 0.], grad_fn=<SigmoidBackward>)
----------------------------------------------
tensor([0., 0., 0.])
'''

tensor.data的兩點(diǎn)總結(jié):

(1)tensor .data 返回和 x 的相同數(shù)據(jù) tensor,而且這個(gè)新的tensor和原來(lái)的tensor是共用數(shù)據(jù)的,一者改變,另一者也會(huì)跟著改變,而且新分離得到的tensor的require s_grad = False, 即不可求導(dǎo)的。(這一點(diǎn)其實(shí)detach是一樣的)

(2)使用tensor.data的局限性。文檔中說(shuō)使用tensor.data是不安全的, 因?yàn)?x.data 不能被 autograd 追蹤求微分 。什么意思呢?從上面的例子可以看出,由于我更改分離之后的變量值c,導(dǎo)致原來(lái)的張量out的值也跟著改變了,但是這種改變對(duì)于autograd是沒(méi)有察覺(jué)的,它依然按照求導(dǎo)規(guī)則來(lái)求導(dǎo),導(dǎo)致得出完全錯(cuò)誤的導(dǎo)數(shù)值卻渾然不知。它的風(fēng)險(xiǎn)性就是如果我再任意一個(gè)地方更改了某一個(gè)張量,求導(dǎo)的時(shí)候也沒(méi)有通知我已經(jīng)在某處更改了,導(dǎo)致得出的導(dǎo)數(shù)值完全不正確,故而風(fēng)險(xiǎn)大。

二、tensor.detach()的使用

同樣是使用上面的案例代碼,將.data 更改成 .detach,如下:

import torch
a = torch.tensor([1,2,3.], requires_grad = True)
out = a.sigmoid()
c = out.detach()  # 需要走注意的是,通過(guò).detach() “分離”得到的的變量會(huì)和原來(lái)的變量共用同樣的數(shù)據(jù),而且新分離得到的張量是不可求導(dǎo)的,c發(fā)生了變化,原來(lái)的張量也會(huì)發(fā)生變化
c.zero_()     # 改變c的值,原來(lái)的out也會(huì)改變
print(c.requires_grad)
print(c)
print(out.requires_grad)
print(out)
print("----------------------------------------------")
out.sum().backward() # 對(duì)原來(lái)的out求導(dǎo),
print(a.grad)  # 此時(shí)會(huì)報(bào)錯(cuò),錯(cuò)誤結(jié)果參考下面,顯示梯度計(jì)算所需要的張量已經(jīng)被“原位操作inplace”所更改了。
'''
False
tensor([0., 0., 0.])
True
tensor([0., 0., 0.], grad_fn=<SigmoidBackward>)
----------------------------------------------
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation
'''

tensor.detach()的兩點(diǎn)總結(jié):

(1)tensor .detach() 返回和 x 的相同數(shù)據(jù) tensor,而且這個(gè)新的tensor和原來(lái)的tensor是共用數(shù)據(jù)的,一者改變,另一者也會(huì)跟著改變,而且新分離得到的tensor的require s_grad = False, 即不可求導(dǎo)的。(這一點(diǎn)其實(shí) .data是一樣的)

(2)使用tensor.detach()的優(yōu)點(diǎn)。從上面的例子可以看出,由于我更改分離之后的變量值c,導(dǎo)致原來(lái)的張量out的值也跟著改變了,這個(gè)時(shí)候如果依然按照求導(dǎo)規(guī)則來(lái)求導(dǎo),由于out已經(jīng)更改了,所以不會(huì)再繼續(xù)求導(dǎo)了,而是報(bào)錯(cuò),這樣就避免了得出完全牛頭不對(duì)馬嘴的求導(dǎo)結(jié)果。

三、總結(jié)

相同點(diǎn):tensor.data和tensor.detach() 都是變量從圖中分離,但而這都是“原位操作 inplace operation”。

不同點(diǎn):

(1).data 是一個(gè)屬性,二.detach()是一個(gè)方法;

(2).data 是不安全的,.detach()是安全的。

到此這篇關(guān)于Pytorch中.detach()與.data的用法的文章就介紹到這了,更多相關(guān)Pytorch中.detach()與.data內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論