天天看點

Pytorch中的backward

首先聲明Pytorch的backward機制:

y.backward()

時,如果

y

是标量(scalar),則不需要為

backward()

傳入任何參數;

如果

y

是張量(tensor),需要傳入一個與

y

同形的

Tensor(張量)

①y是scalar标量

Pytorch中的backward

②y是Tensor張量

①如果直接像标量那樣計算

Pytorch中的backward

就會報錯顯示:

RuntimeError: grad can be implicitly created only for scalar outputs。

翻譯過來就是,grad隻能隐式地為标量輸出建立。

②y調用

backward

時需要傳入一個和

y

同形的權重向量進行權重求和得到一個标量。

Pytorch中的backward

是以要謹記:在Pytorch中,調用

backward

時,一定是标量對張量求導。

③續

1.為什麼不能Tensor 對 Tensor 求導

舉個例子,假設形狀為 

m x n

 的矩陣 X 經過運算得到了 

p x q

 的矩陣 Y,Y 又經過運算得到了 

s x t

 的矩陣 Z。那麼按照前面講的規則,dZ/dY 應該是一個 

s x t x p x q

 四維張量,dY/dX 是一個 

p x q x m x n

的四維張量。問題來了,怎樣反向傳播?怎樣将兩個四維張量相乘???這要怎麼乘???就算能解決兩個四維張量怎麼乘的問題,四維和三維的張量又怎麼乘?導數的導數又怎麼求,這一連串的問題,感覺要瘋掉…… 為了避免這個問題,我們不允許張量對張量求導,隻允許标量對張量求導,求導結果是和自變量同形的張量。

2.  y.backward(w)

前面提高的都是直接

y.backward()

,那麼如果是

y.backward(w)

呢?

y.backward(w) 求的就不是 y 對 x 的導數,而是 l = torch.sum(y*w) 對 x 的導數,即dl/dx = d(y*w)/dx。

舉個例子:

Pytorch中的backward

Pytorch中的backward
Pytorch中的backward

t.backward(z)

,即

l = torch.sum(t*z)

是以x.grad = dl/dx = d(t * z)/dx = d((x +y) * z)/dx = z;

y.grad = dl/dy = d(t * z)/dy = d((x +y) * z)/dy = z;

【參考資料:①Dive-into-DL-PyTorch-master   ②https://zhuanlan.zhihu.com/p/29923090】

繼續閱讀