pytorch笔记——autograd和Variable
1 autograd
1.1?requires_grad
tensor中會有一個屬性requires_grad 來記錄之前的操作(為之后計算梯度用)。
1.2?調(diào)整tensor的requires_grad
1.3 with torch.no_grad
?在這個環(huán)境里面里面生成的式子將無requires_grad
1.4 detach
?內(nèi)容不變,但是requires_grad將變?yōu)镕alse
2 Variable
一般pytorch里面的運算,都是Variable級別的運算
Variable 計算時, 它一步步默默地搭建著一個龐大的系統(tǒng), 叫做計算圖(computational graph)。
這個圖是將所有的計算步驟 (節(jié)點) 都連接起來。最后進(jìn)行誤差反向傳遞的時候, 一次性將所有 variable 里面的修改幅度 (梯度) 都計算出來, 而 普通的tensor 就沒有這個能力。
2.1?獲取variable里面的數(shù)據(jù)
直接print(variable)只會輸出 Variable 形式的數(shù)據(jù), 在很多時候是用不了的(比如想要用 plt 畫圖), 所以我們要轉(zhuǎn)換一下, 將它變成 tensor 形式,或者ndarray形式等。
3 autograd 流程
3.1 無梯度的葉子節(jié)點
import torch a = torch.tensor(2.0) b = torch.tensor(3.0) c = a*b c.backward() a.grad,b.grad ''' RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn '''前項的計算圖如下:
每個方框代表一個tensor,其中列出一些屬性(還有其他很多屬性):
| data? | tensor的data |
| grad | 當(dāng)計算gradient的時候?qū)嫒氪撕瘮?shù)對應(yīng)情況下,這個tensor的gradient |
| grad_fn | 指向用于backward的函數(shù)的節(jié)點 |
| is_leaf | 判斷是否是葉節(jié)點 |
| requires_grad | 如果是設(shè)為True,那么在做backward時候?qū)⒆鳛閳D的一部分參與backwards運算, 如果為False則不參加backwards運算 在上圖中,此時由于requires_grad都為False,因此沒有backwards的graph. |
3.2 有梯度的葉子節(jié)點
?
a = torch.tensor(2.0,requires_grad=True) b = torch.tensor(3.0) c = a*b c.backward() a.grad,b.grad #(tensor(3.), None)前饋流程圖如下:
?3.2.1 backward 后饋流程圖
1)? ??當(dāng)我們調(diào)用tensor的乘法函數(shù)時,同時調(diào)用了隱性變量 ctx (context)變量的save_for_backward 函數(shù)。這樣就把此函數(shù)做backward時所需要的從forward函數(shù)中獲取的相關(guān)的一些值存到了ctx中。
? ? ? ? ?ctx起到了緩存相關(guān)參數(shù)的作用,變成連接forward與backward之間的緩存站。
?????????ctx中的值將會在c 做backwards時傳遞給對應(yīng)的Mulbackward 操作.
2)? ? ?由于c是通過?c=a*b運算得來的, c的grad_fn中存了做backwards時候?qū)?yīng)的函數(shù).且把這個對應(yīng)的backward 叫做 “MulBackward”? ??
3)? ?當(dāng)進(jìn)行c的backwards的時候,其實也就相當(dāng)于執(zhí)行了 c = a*b這個函數(shù)分別對 a 與b 做的偏導(dǎo)。?
????????那么理應(yīng)對應(yīng)兩組backwards的函數(shù),這兩組backwards的函數(shù)打包存在 MulBackward的 next_functions 中。
????????next_function為一個 tuple list, AccumulateGrad 將會把相應(yīng)得到的結(jié)果送到 a.grad中和b.grad中
4)? ?于是在進(jìn)行 c.backward() 后, c進(jìn)行關(guān)于a以及關(guān)于b進(jìn)行求導(dǎo)。
????????由于b的requires_grad為False,因此b項不參與backwards運算(所以,next_function中l(wèi)ist的第二個tuple即為None)。
????????c關(guān)于a的梯度為3,因此3將傳遞給AccumulaGrad進(jìn)一步傳給a.grad
????????因此,經(jīng)過反向傳播之后,a.grad 的結(jié)果將為3
3.3?稍微復(fù)雜一點的
a = torch.tensor(2.0,requires_grad = True) b = torch.tensor(3.0,requires_grad = True) c = a*b d = torch.tensor(4.0,requires_grad = True) e = c*d e.backward() a.grad,b.grad,d.grad #(tensor(12.), tensor(8.), tensor(6.))- e的grad_fn 指向節(jié)點 MulBackward, c的grad_fn指向另一個節(jié)點 MulBackward
- c 為中間值is_leaf 為False,因此并不包含 grad值,在backward計算中,并不需要再重新獲取c.grad的值, backward的運算直接走相應(yīng)的backward node 即可
- MulBackward 從 ctx.saved_tensor中調(diào)用有用信息, e= c+d中 e關(guān)于c的梯度通過MulBackward 獲取得4. 根據(jù)鏈?zhǔn)揭?guī)則, 4再和上一階段的 c關(guān)于 a和c關(guān)于b的兩個梯度值3和2相乘,最終得到了相應(yīng)的值12 和8
- 因此經(jīng)過backward之后,a.grad 中存入12, b.grad中存入 8
參考資料:【one way的pytorch學(xué)習(xí)筆記】(四)autograd的流程機(jī)制原理_One Way的博客-CSDN博客
總結(jié)
以上是生活随笔為你收集整理的pytorch笔记——autograd和Variable的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pytorch 笔记——tensor
- 下一篇: pytorch笔记——简易回归问题