91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Pytorch中backward()多個loss函數怎么用

發布時間:2021-05-25 14:06:02 來源:億速云 閱讀:438 作者:小新 欄目:開發技術

這篇文章主要介紹Pytorch中backward()多個loss函數怎么用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

Pytorch的backward()函數

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

 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函數的使用方法詳細解析,具體例子分析

backward函數

官方定義:

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.

翻譯和解釋:

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

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

每次backward之前,需要注意葉子梯度節點是否清零,如果沒有清零,第二次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)  #求向量的內積

在調用 backward 之前,可以先手動求一下導數,應該是:

Pytorch中backward()多個loss函數怎么用

用代碼實現求導:

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

結果和預期一致:

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

敲重點:

注意到前面函數的解釋中,在參數tensors不是標量的情況下,tensor.backward(grad_tensors)實現的是代價函數(torch.sum(tensors*grad_tensors))關于葉子節點的導數。

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

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

運行結果如下:

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

上面的結果中,出現了一個問題,雖然loss關于x和y的導數正確,但是z不再是葉子節點了。

問題1:

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

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

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

運行結果:

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:

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

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

問題1:

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

問題2:

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

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

簡單的代碼可以看出:

#測試1,:對比上兩次單獨執行backward,此處連續執行兩次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)
# 結果x.grad,y.grad本應該是None,因為保留了第一次backward的結果而打印出上一次梯度的結果
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,:連續執行兩次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])

pytorch的優點

1.PyTorch是相當簡潔且高效快速的框架;2.設計追求最少的封裝;3.設計符合人類思維,它讓用戶盡可能地專注于實現自己的想法;4.與google的Tensorflow類似,FAIR的支持足以確保PyTorch獲得持續的開發更新;5.PyTorch作者親自維護的論壇 供用戶交流和求教問題6.入門簡單

以上是“Pytorch中backward()多個loss函數怎么用”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

田阳县| 南宫市| 大兴区| 神农架林区| 任丘市| 娄烦县| 石屏县| 三河市| 沙洋县| 武隆县| 隆林| 建平县| 会同县| 永平县| 丰宁| 元氏县| 赞皇县| 营口市| 交口县| 中阳县| 新闻| 左权县| 喀什市| 安平县| 富蕴县| 瑞丽市| 苍梧县| 玉田县| 泽普县| 泌阳县| 财经| 湘阴县| 女性| 麻城市| 阿瓦提县| 江门市| 黔西| 大庆市| 荣昌县| 金昌市| 恩平市|