4 pytorch基礎
書《深度學習之PyTorch實戰計算機視覺》第六章
這次主要記錄三部分內容:
自動梯度
- 向後傳播自動化
自定義傳播函式
- 重寫向前傳播和向後傳播
模型搭建和引數優化
自動梯度
實現對模型中後向傳播梯度的自動計算,後向傳播自動化(loss.backward)
torch.autograd實現後向傳播中的鏈式求導
Variable類對我們定義的Tensor資料型別進行封裝。用X代表我們選中的節點,是一個Variable物件,那麼X.data代表Tensor資料型別的變數,X.grad是Variable型別的變數,想要訪問梯度值需要使用X.grad.data
loss.backward()是後向傳播計算部分,自動計算每個節點的梯度並根據需求進行保留
import torch from torch.autograd import Variable batch_n = 100 hidden_layer = 100 input_data = 1000 output_data = 10 x = Variable(torch.randn(batch_n, input_data), requires_grad = False) y = Variable(torch.randn(batch_n, output_data), requires_grad = False) w1 = Variable(torch.randn(input_data, hidden_layer), requires_grad = True) #權重1是1000*100 w2= Variable(torch.randn(hidden_layer, output_data), requires_grad = True)#權重2是100*10 epoch_n = 20 learning_rate = le-6 for epoch in range(epoch_n): y_pred = x.mm(w1).clamp(min=0).mm(w2) loss = (y_pred-y).pow(2).sum() print("Epoch:{}, Loss:{:.4f}".format(epoch, loss.data[0])) loss.backward() w1.data-=learning_rate*w1.grad.data w2.data -=learning_rate*w2.grad.data w1.grad.data.zero_() w2.grad.data.zero_()
自定義傳播函式
torch.nn.Module重寫前向傳播forward和後向傳播backward
import torch from torch.autograd import Variable batch_n = 100 hidden_layer = 100 input_data = 1000 output_data = 10 '''相比於前面程式碼新增部分''' class Model(torch.nn.module): def __init__(self): super(Module, self).__init__() def forward(self, input, w1, w2): #實現向前傳播矩陣運算 x = torch.mm(x, w1) x = torch.clamp(x, min=0) x = torch.mm(x, w2) return x def backward(self): #實現向後傳播自動梯度計算 pass model = Model() ''' 上面模型搭建好了,下面對模型進行訓練和引數優化 ''' x = Variable(torch.randn(batch_n, input_data), requires_grad = False) y = Variable(torch.randn(batch_n, output_data), requires_grad = False) w1 = Variable(torch.randn(input_data, hidden_layer), requires_grad = True) w2 = Variable(torch.randn(hidden_layer, output_data), requires_grad = True) epoch_n = 20 learning_rate = le-6 for epoch in range(epoch_n): y_pred = model(x, w1, w2) #有改動,原來是x.mm(w1).clamp(min=0).mm(w2) loss = (y_pred-y).pow(2).sum() print("Epoch:{}, Loss:{:.4f}".format(epoch, loss.data[0])) loss.backward() w1.data -=learning_rate*w1.grad.data w2.data -=learning_rate*w2.grad.data w1.grad.data.zero_() w2.grad.data.zero_()
模型搭建和引數優化
torch.nn包
- torch.nn.Sequential
序列容器,通過巢狀各種類,實現對網路模型的搭建,引數會按照我們定義好的序列自動傳遞下去
- torch.nn.Linear
線性層。引數有三個,分別是輸入特徵數,輸出特徵數和是否使用偏置,偏置引數是一個布林值,預設為True,即使用偏置。
- torch.nn.ReLU
非線性啟用函式,在定義時預設不需要傳入引數。除此之外,還包括PReLU,LeakyReLU,Tanh,Sigmod,Softmax等。
- 損失函式
包括:
(1)torch.nn.MSELoss:使用均方誤差函式計算損失值
(2)torch.nn.L1Loss:使用平均絕對誤差計算損失值
(3)torch.nn.CrossEntropyLoss:計算交叉熵
資訊量:它是用來衡量一個事件的不確定性的;一個事件發生的概率越大,不確定性越小,則它所攜帶的資訊量就越小。熵:它是用來衡量一個系統的混亂程度的,代表一個系統中資訊量的總和;資訊量總和越大,表明這個系統不確定性就越大交叉熵:它主要刻畫的是實際輸出(概率)與期望輸出(概率)的距離,也就是交叉熵的值越小,兩個概率分佈就越接近。假設概率分佈p為期望輸出,概率分佈q為實際輸出,為交叉熵,則
但是Pytorch中計算的交叉熵並不是採用上式,而是下面這個
torch.optim包
實現神經網路權重引數優化更新自動化。該包提供了許多方法,SGD,AdaGrad,RMSProp,Adam等。
接下來使用自動化的優化函式對前面的程式碼進行替換
import torch from torch.autograd import Variable #設定引數 batch_n = 100 hidden_layer = 100 input_data = 1000 output_data = 10 x = Variable(torch.randn(batch_n, input_data), requires_grad = False) y = Variable(torch.randn(batch_n, output_data), requires_grad = False) #構建模型 models = torch.nn.Sequential( torch.nn.Linear(input_data, hidden_layer), torch.nn.ReLU(), torch.nn.Linear(hidden_layer, output_data) ) #設定超引數 epoch_n = 20 learning_rate = le-6 #定義損失函式和權重優化引數 loss_fn = torch.nn.MSELoss() optimzer = torch.optim.Adam(models.parameters(), lr = learning_rate) for epoch in range(epoch_n): y_pred = models(x) loss = loss_fn(y_pred, y) #有改動 loss = (y_pred-y).pow(2).sum() print("Epoch:{}, Loss:{:.4f}".format(epoch, loss.data[0])) optimer.zero_grad() #實現模型引數梯度歸零,代替前面w1.grad.data.zero_()和w2 loss.backward() optimer.step() #實現梯度更新,代替前面w1.data -=learning_rate*w1.grad.data和w2
這一部分就記錄到這裡。