最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Pytorch中的backward()多個loss函數(shù)用法

 更新時間:2021年05月25日 08:37:07   作者:haoxue2011  
這篇文章主要介紹了Pytorch中的backward()多個loss函數(shù)用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Pytorch的backward()函數(shù)

假若有多個loss函數(shù),如何進行反向傳播和更新呢?

 x = torch.tensor(2.0, requires_grad=True)                                                    
 y = x**2                                                                                     
 z = x                                                                                        
# 反向傳播
 y.backward()                                                                                 
 x.grad                                                                                       
 tensor(4.)
 z.backward()                                                                                 
 x.grad                                                                                       
 tensor(5.) ## 累加

補充:Pytorch中torch.autograd ---backward函數(shù)的使用方法詳細解析,具體例子分析

backward函數(shù)

官方定義:

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

Computes the sum of gradients of given tensors w.r.t. graph leaves.The graph is differentiated using the chain rule. If any of tensors are non-scalar (i.e. their data has more than one element) and require gradient, the function additionally requires specifying grad_tensors. It should be a sequence of matching length, that contains gradient of the differentiated function w.r.t. corresponding tensors (None is an acceptable value for all tensors that don't need gradient tensors). This function accumulates gradients in the leaves - you might need to zero them before calling it.

翻譯和解釋:

參數(shù)tensors如果是標量,函數(shù)backward計算參數(shù)tensors對于給定圖葉子節(jié)點的梯度( graph leaves,即為設(shè)置requires_grad=True的變量)。

參數(shù)tensors如果不是標量,需要另外指定參數(shù)grad_tensors,參數(shù)grad_tensors必須和參數(shù)tensors的長度相同。在這一種情況下,backward實際上實現(xiàn)的是代價函數(shù)(loss = torch.sum(tensors*grad_tensors); 注:torch中向量*向量實際上是點積,因此tensors和grad_tensors的維度必須一致 )關(guān)于葉子節(jié)點的梯度計算,而不是參數(shù)tensors對于給定圖葉子節(jié)點的梯度。如果指定參數(shù)grad_tensors=torch.ones((size(tensors))),顯而易見,代價函數(shù)關(guān)于葉子節(jié)點的梯度,也就等于參數(shù)tensors對于給定圖葉子節(jié)點的梯度。

每次backward之前,需要注意葉子梯度節(jié)點是否清零,如果沒有清零,第二次backward會累計上一次的梯度。

下面給出具體的例子:

import torch
x=torch.randn((3),dtype=torch.float32,requires_grad=True)
y = torch.randn((3),dtype=torch.float32,requires_grad=True)
z = torch.randn((3),dtype=torch.float32,requires_grad=True)
t = x + y
loss = t.dot(z)  #求向量的內(nèi)積

在調(diào)用 backward 之前,可以先手動求一下導(dǎo)數(shù),應(yīng)該是:

用代碼實現(xiàn)求導(dǎo):

loss.backward(retain_graph=True)
print(z,x.grad,y.grad)  #預(yù)期打印出的結(jié)果都一樣
print(t,z.grad)    #預(yù)期打印出的結(jié)果都一樣
print(t.grad)    #在這個例子中,x,y,z就是葉子節(jié)點,而t不是,t的導(dǎo)數(shù)在backward的過程中求出來回傳之后就會被釋放,因而預(yù)期結(jié)果是None

結(jié)果和預(yù)期一致:

tensor([-2.6752, 0.2306, -0.8356], requires_grad=True) tensor([-2.6752, 0.2306, -0.8356]) tensor([-2.6752, 0.2306, -0.8356])

tensor([-1.1916, -0.0156, 0.8952], grad_fn=<AddBackward0>) tensor([-1.1916, -0.0156, 0.8952]) None

敲重點:

注意到前面函數(shù)的解釋中,在參數(shù)tensors不是標量的情況下,tensor.backward(grad_tensors)實現(xiàn)的是代價函數(shù)(torch.sum(tensors*grad_tensors))關(guān)于葉子節(jié)點的導(dǎo)數(shù)。

在上面例子中,loss = t.dot(z),因此用t.backward(z),實現(xiàn)的就是loss對于所有葉子結(jié)點的求導(dǎo),實際運算結(jié)果和預(yù)期吻合。

t.backward(z,retain_graph=True)
print(z,x.grad,y.grad)
print(t,z.grad)

運行結(jié)果如下:

tensor([-0.7830, 1.4468, 1.2440], requires_grad=True) tensor([-0.7830, 1.4468, 1.2440]) tensor([-0.7830, 1.4468, 1.2440])

tensor([-0.7145, -0.7598, 2.0756], grad_fn=<AddBackward0>) None

上面的結(jié)果中,出現(xiàn)了一個問題,雖然loss關(guān)于x和y的導(dǎo)數(shù)正確,但是z不再是葉子節(jié)點了。

問題1:

當使用t.backward(z,retain_graph=True)的時候, print(z.grad)結(jié)果是None,這意味著z不再是葉子節(jié)點,這是為什么呢?

另外一個嘗試,loss = t.dot(z)=z.dot(t),但是如果用z.backward(t)替換t.backward(z,retain_graph=True),結(jié)果卻不同。

z.backward(t)
print(z,x.grad,y.grad)
print(t,z.grad)

運行結(jié)果:

tensor([-1.0716, -1.3643, -0.0016], requires_grad=True) None None

tensor([-0.7324, 0.9763, -0.4036], grad_fn=<AddBackward0>) tensor([-0.7324, 0.9763, -0.4036])

問題2:

上面的結(jié)果中可以看到,使用z.backward(t),x和y都不再是葉子節(jié)點了,z仍然是葉子節(jié)點,且得到的loss相對于z的導(dǎo)數(shù)正確。

上述仿真出現(xiàn)的兩個問題,我還不能解釋,希望和大家交流。

問題1:

當使用t.backward(z,retain_graph=True)的時候, print(z.grad)結(jié)果是None,這意味著z不再是葉子節(jié)點,這是為什么呢?

問題2:

上面的結(jié)果中可以看到,使用z.backward(t),x和y都不再是葉子節(jié)點了,z仍然是葉子節(jié)點,且得到的loss相對于z的導(dǎo)數(shù)正確。

另外強調(diào)一下,每次backward之前,需要注意葉子梯度節(jié)點是否清零,如果沒有清零,第二次backward會累計上一次的梯度。

簡單的代碼可以看出:

#測試1,:對比上兩次單獨執(zhí)行backward,此處連續(xù)執(zhí)行兩次backward
t.backward(z,retain_graph=True)
print(z,x.grad,y.grad)
print(t,z.grad)
z.backward(t)
print(z,x.grad,y.grad)
print(t,z.grad)
# 結(jié)果x.grad,y.grad本應(yīng)該是None,因為保留了第一次backward的結(jié)果而打印出上一次梯度的結(jié)果
tensor([-0.5590, -1.4094, -1.5367], requires_grad=True) tensor([-0.5590, -1.4094, -1.5367]) tensor([-0.5590, -1.4094, -1.5367])tensor([-1.7914,  0.8761, -0.3462], grad_fn=<AddBackward0>) Nonetensor([-0.5590, -1.4094, -1.5367], requires_grad=True) tensor([-0.5590, -1.4094, -1.5367]) tensor([-0.5590, -1.4094, -1.5367])tensor([-1.7914,  0.8761, -0.3462], grad_fn=<AddBackward0>) tensor([-1.7914,  0.8761, -0.3462])
#測試2,:連續(xù)執(zhí)行兩次backward,并且清零,可以驗證第二次backward沒有計算x和y的梯度
t.backward(z,retain_graph=True)
print(z,x.grad,y.grad)
print(t,z.grad)
x.grad.data.zero_()
y.grad.data.zero_()
z.backward(t)
print(z,x.grad,y.grad)
print(t,z.grad)
tensor([ 0.8671, 0.6503, -1.6643], requires_grad=True) tensor([ 0.8671, 0.6503, -1.6643]) tensor([ 0.8671, 0.6503, -1.6643])tensor([1.6231e+00, 1.3842e+00, 4.6492e-06], grad_fn=<AddBackward0>) Nonetensor([ 0.8671,  0.6503, -1.6643], requires_grad=True) tensor([0., 0., 0.]) tensor([0., 0., 0.])tensor([1.6231e+00, 1.3842e+00, 4.6492e-06], grad_fn=<AddBackward0>) tensor([1.6231e+00, 1.3842e+00, 4.6492e-06])

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python+Delorean實現(xiàn)時間格式智能轉(zhuǎn)換

    Python+Delorean實現(xiàn)時間格式智能轉(zhuǎn)換

    DeLorean是一個Python的第三方模塊,基于?pytz?和?dateutil?開發(fā),用于處理Python中日期時間的格式轉(zhuǎn)換。本文將詳細講講DeLorean的使用,感興趣的可以了解一下
    2022-04-04
  • python如何壓縮新文件到已有ZIP文件

    python如何壓縮新文件到已有ZIP文件

    這篇文章主要為大家詳細介紹了python如何壓縮新文件到已有ZIP文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Python處理文本數(shù)據(jù)的方法詳解

    Python處理文本數(shù)據(jù)的方法詳解

    學(xué)習(xí)Python時,它總能讓人深刻體會到這款語言的魅力。今天小編為大家?guī)硪粋€有趣的項目,用Python處理文本數(shù)據(jù),一起來看看今天的問題吧
    2022-06-06
  • Python 單例設(shè)計模式用法實例分析

    Python 單例設(shè)計模式用法實例分析

    這篇文章主要介紹了Python 單例設(shè)計模式用法,結(jié)合實例形式分析了Python單例模式的具體定義與使用操作技巧,需要的朋友可以參考下
    2019-09-09
  • 利用Python實現(xiàn)端口掃描器的全過程

    利用Python實現(xiàn)端口掃描器的全過程

    這篇文章主要給大家介紹了關(guān)于如何利用Python實現(xiàn)端口掃描器的相關(guān)資料,用來檢測目標服務(wù)器上有哪些端口開放,本文適用于有 Python和計算機網(wǎng)絡(luò)語言基礎(chǔ)的用戶,需要的朋友可以參考下
    2021-08-08
  • 對python中數(shù)據(jù)集劃分函數(shù)StratifiedShuffleSplit的使用詳解

    對python中數(shù)據(jù)集劃分函數(shù)StratifiedShuffleSplit的使用詳解

    今天小編就為大家分享一篇對python中數(shù)據(jù)集劃分函數(shù)StratifiedShuffleSplit的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • 一文教你使用Python繪制絲滑的K線圖

    一文教你使用Python繪制絲滑的K線圖

    K線圖是將各種股票某一時間單位內(nèi)的開盤價,收盤價,最高價,最低價,通過繪圖方式表現(xiàn)出來的一種圖形,下面我們來看看如何使用Python實現(xiàn)絲滑繪制K線圖吧
    2025-04-04
  • Python數(shù)組定義方法

    Python數(shù)組定義方法

    這篇文章主要介紹了Python數(shù)組定義方法,結(jié)合實例形式分析了Python一維數(shù)組與二維數(shù)組的定義方法與相關(guān)注意事項,需要的朋友可以參考下
    2016-04-04
  • Python基于滑動平均思想實現(xiàn)缺失數(shù)據(jù)填充的方法

    Python基于滑動平均思想實現(xiàn)缺失數(shù)據(jù)填充的方法

    今天小編就為大家分享一篇關(guān)于Python基于滑動平均思想實現(xiàn)缺失數(shù)據(jù)填充的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • Python對文件和目錄進行操作的方法(file對象/os/os.path/shutil 模塊)

    Python對文件和目錄進行操作的方法(file對象/os/os.path/shutil 模塊)

    下面小編就為大家?guī)硪黄狿ython對文件和目錄進行操作的方法(file對象/os/os.path/shutil 模塊)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05

最新評論

房产| 桂阳县| 晋中市| 平潭县| 杭锦后旗| 台州市| 通山县| 焉耆| 麦盖提县| 呼和浩特市| 建湖县| 茂名市| 郎溪县| 嵊州市| 三穗县| 调兵山市| 淅川县| 平远县| 广宁县| 忻城县| 河西区| 灵石县| 正安县| 阜康市| 山丹县| 桐庐县| 大姚县| 施秉县| 防城港市| 芜湖县| 化德县| 普兰店市| 农安县| 鸡西市| 休宁县| 三台县| 辽阳市| 九江县| 达尔| 贡觉县| 黄陵县|