backward()函數中的參數解析

Backward()函數

Backward函數實際上是通過傳遞參數(默認情況下是1x1單位張量)來計算梯度的,它通過Backward圖一直到每個葉節點,每個葉節點都可以從調用的根張量追溯到葉節點。然後將計算出的梯度存儲在每個葉節點的.grad中。請記住,在正向傳遞過程中已經動態生成了後向圖。backward函數僅使用已生成的圖形計算梯度,並將其存儲在葉節點中。

讓我們分析以下代碼:

 import torch
 # Creating the graph
 x = torch.tensor(1.0, requires_grad = True)
 z = x ** 3
 z.backward() #Computes the gradient
 print(x.grad.data) #Prints '3' which is dz/dx

需要注意的一件重要事情是,當調用z.backward()時,一個張量會自動傳遞爲z.backward(torch.tensor(1.0))torch.tensor(1.0)是用來終止鏈式法則梯度乘法的外部梯度。這個外部梯度作爲輸入傳遞給MulBackward函數,以進一步計算x的梯度。傳遞到.backward()中的張量的維數必須與正在計算梯度的張量的維數相同。例如,如果梯度支持張量x和y如下:

 x = torch.tensor([0.0, 2.0, 8.0], requires_grad = True)
 y = torch.tensor([5.0 , 1.0 , 7.0], requires_grad = True)
 z = x * y

然後,要計算z關於x或者y的梯度,需要將一個外部梯度傳遞給z.backward()函數,如下所示:

 z.backward(torch.FloatTensor([1.0, 1.0, 1.0])

z.backward() 會給出 RuntimeError: grad can be implicitly created only for scalar outputs

反向函數傳遞的張量就像梯度加權輸出的權值。從數學上講,這是一個向量乘以非標量張量的雅可比矩陣(本文將進一步討論),因此它幾乎總是一個維度的單位張量,與 backward張量相同,除非需要計算加權輸出。

tldr :向後圖是由autograd類在向前傳遞過程中自動動態創建的。Backward()只是通過將其參數傳遞給已經生成的反向圖來計算梯度。

更多請看:https://mlog.club/article/25034

數學—雅克比矩陣和向量

從數學上講,autograd類只是一個雅可比向量積計算引擎。雅可比矩陣是一個非常簡單的單詞,它表示兩個向量所有可能的偏導數。它是一個向量相對於另一個向量的梯度。

注意:在這個過程中,PyTorch從不顯式地構造整個雅可比矩陣。直接計算JVP (Jacobian vector product)通常更簡單、更有效。

如果一個向量X = [x1, x2,…xn]通過f(X) = [f1, f2,…fn]來計算其他向量,則雅可比矩陣(J)包含以下所有偏導組合:

 

雅克比矩陣

上面的矩陣表示f(X)相對於X的梯度。

假設一個啓用PyTorch梯度的張量X

X = [x1,x2,…,xn](假設這是某個機器學習模型的權值)

X經過一些運算形成一個向量Y

Y = f(X) = [y1, y2,…,ym]

然後使用Y計算標量損失l。假設向量v恰好是標量損失l關於向量Y的梯度,如下:

 

向量v稱爲grad_tensor,並作爲參數傳遞給backward() 函數。

爲了得到損失的梯度l關於權重X的梯度,雅可比矩陣J是向量乘以向量v

 

這種計算雅可比矩陣並將其與向量v相乘的方法使PyTorch能夠輕鬆地爲非標量輸出提供外部梯度。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章