【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析
1 Variable類型與自動微分模塊概述
1.1 Variable類型
Variable是由Autograd模塊對張量進行進一步封裝實現的,具有自動求導的功能
1.2 Autograd模塊(自動求導模塊)
Autograd模塊:在神經網絡的反向傳播中,基于正向計算的結果進行微分計算,從而實現對于網絡權重的更新與迭代,提供了張量的自動求微分功能,可以通過代碼來實現對反向過程的控制,使得權重參數朝著目標結果進行更新與發展。
2 Variable類型與自動微分模塊實戰
2.1 Variable類型對象與張量對象之間的轉化
2.1.1 代碼實現
import torch from torch.autograd import Variablea = torch.FloatTensor([4]) #創建張量 print(Variable(a)) # 將張量轉化為Variable對象 # 輸出 tensor([4.]) print(Variable(a,requires_grad=True)) # requires_grad允許自動求導 # 輸出 tensor([4.], requires_grad=True) print(a.data) #將Variable對象轉化為張量 # 輸出 tensor([4.])2.1.2?注意
import torch from torch.autograd import Variable### 使用requires_grad時,要求張量的值必須為浮點型 x = torch.tensor([1],requires_grad=True) #報錯 x = torch.tensor([1.],requires_grad=True) #正確寫法2.2 torch.no_grad()
2.2.1 概述
torch.no_grad():使Variable類型變量的requires_grad失效
torch.enable_grad():使Variable類型變量的requires_grad有效
2.2.2 使用torch.no_grad()配合with語句限制requires_grad的作用域
import torch from torch.autograd import Variablex = torch.ones(2,2,requires_grad=True) # 定義一個需要梯度計算的Variable類型對象 with torch.no_grad():y = x * 2 print(y.requires_grad) # 輸出 False2.2.3 使用裝飾器@實現
import torch from torch.autograd import Variable### 在神經網絡中將網絡模型進行封裝,使用裝飾器方便實現開發的便捷性x = torch.ones(2,2,requires_grad=True) # 定義一個需要梯度計算的Variable類型對象 @torch.no_grad() def doubler(x):return x * 2 z = doubler(x) print(z.requires_grad) # 輸出 False2.3 函數enable_grad()與no_grad()的嵌套使用
2.3.1 enable_grad()配合with語句限制requires_grad的作用域
import torch x = torch.ones(2,2,requires_grad=True) # 定義一個需要梯度計算的Variable類型對象 with torch.no_grad():with torch.enable_grad():y = x * 2print(y.requires_grad) # Trueprint(y.requires_grad) # True print(y.requires_grad) # True2.3.2 使用enable_grad裝飾器
import torch x = torch.ones(2,2,requires_grad=True) # 定義一個需要梯度計算的Variable類型對象 @torch.enable_grad() def doubler(x): #封裝到函數中return x * 2 with torch.no_grad(): #使得計算梯度失效z = doubler(x) print(z.requires_grad) #True2.3.3 作用在沒有requires_grad的Variable類型變量上將會失效,不能使其重新獲得計算梯度的屬性
import torch x = torch.ones(2,2) # 定義一個不需要梯度計算的Variable類型對象 with torch.enable_grad():y = x * 2 print(y.requires_grad) # False2.3 set_grad_enabled()實現統一管理梯度計算
import torch x = torch.ones(2,2,requires_grad=True) # 定義一個需要梯度計算的Variable類型對象 torch.set_grad_enabled(False) # 統一關閉梯度計算 y = x * 2 print(y.requires_grad) # False torch.set_grad_enabled(True) # 統一開啟梯度計算 y = x * 2 print(y.requires_grad) # True2.4?Variable類型對象的grad_fn屬性
2.4.1 grad_fn屬性概述
Variable類型對象在經過前向傳播后,將會增加一個grad_fn屬性,該屬性隨著backward()方法進行自動的梯度計算。沒有經過計算的Variable類型對象是沒有這個屬性的,在requires_grad=False的情況下,無論如何計算他都不會有grad_fn屬性。
2.4.2?grad_fn屬性代碼實現
import torch from torch.autograd import Variablex = Variable(torch.ones(2,2),requires_grad=True) print(x) # 輸出 tensor([[1., 1.],[1., 1.]], requires_grad=True) print(x.grad_fn) # 輸出 Nonem = x + 2 # 經過正向計算,獲得grad_fn屬性 print(m.grad_fn) # 輸出 <AddBackward0 object at 0x0000024E1AA14D00> print(m.grad_fn(x)) #對x變量進行求梯度計算 # 輸出 (tensor([[1., 1.],[1., 1.]], requires_grad=True), None)x2 = torch.ones(2,2) # 創建一個不需要梯度計算的張量 m = x2 + 2 print(m.grad_fn) # 輸出 None2.5?Variable類型對象的is_leaf函數
2.5.1?is_leaf()概述
1、定義Variable類型對象時,若將requires_grad設為True,則將該Variable類型對象稱為種子節點,其?is_leaf的屬性為True。
2、若Variable類型對象不是通過自定義生成的,而是通過其他張量計算所得時,則不是葉子節點,則該該Variable類型對象稱為葉子節點,其?is_leaf的屬性為False。
3、Pytorch會記錄每個張量的由來,由此來在內存中行程樹狀結構實現反向鏈式計算,葉子節點主要在求導過程為遞歸循環提供信號指示,當反向鏈式計算遇到葉子節點則終止遞歸循環。
2.5.2?is_leaf()代碼
import torch from torch.autograd import Variablex = Variable(torch.ones(2,2),requires_grad=True) print(x.is_leaf) # True m = x + 2 print(m.is_leaf) # False2.6 backward()實現自動求導
2.6.1?backward()概述
backward():必須在當前變量內容是標量的情況下使用,否則會報錯。
2.6.3 自動求導的作用
從復雜的神經網絡中,自動將每一層中的每個參數的梯度計算出來,實現訓練過程中的反向傳播。
2.6.2 代碼
import torch from torch.autograd import Variable### y = (x + 2)/4 x = Variable(torch.ones(2,2),requires_grad=True) m = x + 2 f = m.mean() #得到一個標量 f.backward() # 自動求導 print(f) #輸出 tensor(3., grad_fn=<MeanBackward0>) print(x.grad) # 輸出 tensor([[0.2500, 0.2500],[0.2500, 0.2500]])2.7 detach()將Variable類型對象分離成種子節點
2.7.1 將需要求梯度的Variable類型對象轉化為Numpy對象
import torch from torch.autograd import Variable### 如果被分離的Variable對象的volatile屬性為True,那么被分離出的volatile屬性也為True ### 被返回的Variable對象和被分離的Variable對象指向同一個張量,并且永遠不會需要梯度 x = Variable(torch.ones(2,2),requires_grad=True) # x.numpy() # 報錯Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead. x1 = x.detach().numpy() print(x1)# 輸出 [[1.,1.],[1.,1.]]2.7.2 實現對網絡中的部分參數求梯度
?2.8 volatile屬性
早期代碼中可以通過設置Variable類型對象的volatile屬性為True的方法來實現停止梯度更新。
總結
以上是生活随笔為你收集整理的【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构链表之单链表的快慢指针——3
- 下一篇: 西北大学计算机考试,西北大学计算机技术