參考一
該博文分為以下6個部分:
- tensor.requires_grad
- torch.no_grad()
- 反向傳播及網絡的更新
- tensor.detach()
- CPU and GPU
- tensor.item()
torch.detach()和torch.data的區別是,在求導時,torch.detach()會檢查張量的數據是否發生變化,而torch.data則不會去檢查。
參考二
該博文講了backward()、葉子張量、inplace操作、動態圖和靜態圖的區別等,概要如下:
- 在我們做正向傳播的時候,需要求導的變量除了執行
forward()
操作之外,還會同時會為反向傳播做一些准備,為反向計算圖添加一個Function節點。 - 如何判斷是否是葉子張量:當這個tensor是用戶創建的時候,它是一個葉子節點,當這個tensor是由其他運算操作產生的時候,它就不是一個葉子節點。
- 只有葉子張量的導數結果才會被最后保留下來,其他張量的導數用完就被釋放。也就是說,在整個計算圖的backward()完成之后,葉子張量的grad是有數值的,而其他張量的grad是None。
- inplace指的是在不更改變量的內存地址的情況下,直接修改變量的值。
- 如果一個變量同時參與了正向傳播和反向傳播,那么最好不要對它使用inplace操作,因為inplace操作可能會引起反響傳播時報錯。
- 所謂動態圖,就是每次當我們搭建完一個計算圖,然后在反向傳播結束之后,整個計算圖就在內存中被釋放了。如果想再次使用的話,必須從頭再搭一遍。而以TensorFlow為代表的靜態圖,每次都先設計好計算圖,需要的時候實例化這個圖,然后送入各種輸入,重復使用,只有當會話結束的時候創建的圖才會被釋放。
- 變量.grad_fn表明該變量是怎么來的,用於指導反向傳播。例如loss = a+b,則loss.gard_fn為<AddBackward0 at 0x7f2c90393748>,這個grad_fn可指導怎么求a和b的導數。
實例
import torch input = torch.tensor([[1., 2.], [3., 4.]], requires_grad=False) w1 = torch.tensor(2.0, requires_grad=True) w2 = torch.tensor(3.0, requires_grad=True) l1 = input * w1 l2 = l1 + w2 loss = l2.mean() loss.backward() print(input.grad) # 輸出:None print(w1.grad) # 輸出:tensor(2.5) print(w2.grad) # 輸出:tensor(1.) print(l1.grad, l2.grad, loss.grad) # 輸出: None None None # 因為l1, l2, loss都是非葉子張量,所以它們的導數不會被保存,即它們的.grad為None print(l1.grad_fn) # 輸出:<MulBackward0 object at 0x7f10feeb1a20> 表明l1是由相乘得來的,用於指導向后求導 print(loss.grad_fn) # 輸出:<MeanBackward1 object at 0x7f10feeb1a20>
我們可以手動求導驗證一下w1和w2的導數對不對:
說明程序求導結果是對的。
如果我們把input的requires_grad改為True,則input也變為葉子張量了,loss需要對齊求導,並且導數會被保存:
import torch input = torch.tensor([[1., 2.], [3., 4.]], requires_grad=True) w1 = torch.tensor(2.0, requires_grad=True) w2 = torch.tensor(3.0, requires_grad=True) l1 = input * w1 l2 = l1 + w2 loss = l2.mean() loss.backward() print(input.grad) # 輸出:tensor([[0.5000, 0.5000], # [0.5000, 0.5000]]) print(w1.grad) # 輸出:tensor(2.5000) print(w2.grad) # 輸出:tensor(1.) print(l1.grad, l2.grad, loss.grad) # 輸出: None None None # 因為l1, l2, loss都是非葉子張量,所以它們的梯度不會被保存,即它們的.grad為None
我們可以手動求導驗證一下:
說明程序求導結果是對的。