PyTorch快速入門
概述
PyTorch快速入門
本教程通過十分鐘快速入門和代碼實踐帶你走入python的AI世界。
PyTorch代碼概述
model/net.py
:指定神經網絡架構,損失函數和評估指標model/data_loader.py:指定如何將數據饋送到網絡train.py:包含主要訓練循環evaluate.py:包含用於評估模型的主循環utils.py:用於處理hyperparams /日誌/存儲模型的實用程序函數建議您仔細閱讀
train.py
以獲得詳細認識。
摸熟後,您可能需要修改代碼,具體取決於您的任務和數據集
model/net.py改變模型,即如何將輸入轉換為預測以及損失等。model/data_loader.py更改將數據提供給模型的方式。train.py
evaluate.py一旦您獲得了適用於的數據集,可以隨意編輯代碼以滿足需求。繞不過的理論:張量和變量
在進一步討論之前,我強烈建議您使用PyTorch進行快速實踐,以了解PyTorch的基礎知識。這是一個潛行峰。
PyTorch張量的行為與NumPy的數組相似。
>>>importtorch>>>a=torch.Tensor([[1,2],[3,4]])>>>print(a)1234[torch.FloatTensorofsize2x2]>>>print(a**2)14916[torch.FloatTensorofsize2x2]
PyTorch變量允許您包裝Tensor並對其執行記錄操作。
>>>fromtorch.autogradimportVariable>>>a=Variable(torch.Tensor([[1,2],[3,4]]),requires_grad=True)>>>print(a)Variablecontaining:1234[torch.FloatTensorofsize2x2]>>>y=torch.sum(a**2)# 1 + 4 + 9 + 16>>>print(y)Variablecontaining:30[torch.FloatTensorofsize1]>>>y.backward()# compute gradients of y wrt a>>>print(a.grad)# print dy/da_ij = 2*a_ij for a_11, a_12, a21, a22Variablecontaining:2468[torch.FloatTensorofsize2x2]
這PyTorch以其極簡主義和直觀的語法包含優雅和表現力。在繼續之前,請先熟悉參考資料部分中的更多示例。
核心步驟
讓我們先來看看訓練算法的核心是什麼樣的。下面的五行通過模型傳遞一批輸入,計算損失,執行反向傳播並更新參數。
output_batch=model(train_batch)# compute model outputloss=loss_fn(output_batch,labels_batch)# calculate lossoptimizer.zero_grad()# clear previous gradientsloss.backward()# compute gradients of all variables wrt lossoptimizer.step()# perform updates using calculated gradients
每個變量
train_batch
,
labels_batch
,
output_batch
和
loss
是一個PyTorch變量,並且允許自動計。
我們編寫的所有其他代碼都是圍繞這個構建的 - 模型的確切規範,如何獲取一批數據和標籤,計算損失和優化器的細節。在這篇文章中,將介紹如何在PyTorch中編寫簡單模型,計算損失並定義優化器。
PyTorch中的模型
可以通過繼承類來在PyTorch中定義模型
torch.nn.Module
。該模型分為兩個步驟。首先指定模型的參數,然後概述它們如何應用於輸入。對於不涉及可訓練參數的操作(激活函數,如ReLU,像maxpool這樣的操作),我們通常使用該
torch.nn.functional
模塊。以下是從這裡借來的單個隱藏層神經網絡的示例:
importtorch.nnasnnimporttorch.nn.functionalasFclassTwoLayerNet(nn.Module):def__init__(self,D_in,H,D_out):""" In the constructor we instantiate two nn.Linear modules and assign them as member variables. D_in: input dimension H: dimension of hidden layer D_out: output dimension """super(TwoLayerNet,self).__init__()self.linear1=nn.Linear(D_in,H)self.linear2=nn.Linear(H,D_out)defforward(self,x):""" In the forward function we accept a Variable of input data and we must return a Variable of output data. We can use Modules defined in the constructor as well as arbitrary operators on Variables. """h_relu=F.relu(self.linear1(x))y_pred=self.linear2(h_relu)returny_pred該
__init__
函數初始化模型的兩個線性層。PyTorch負責始化您指定的參數。在
forward
函數中,我們首先應用第一個線性層,應用ReLU激活,然後應用第二個線性層。該模塊假定第一個維度
x
是批量大小。如果網絡的輸入只是維度為100的向量,批量大小為32,則維度為
x
32,100。讓我們看一個如何定義模型和計算正向傳遞的示例:
# N is batch size; D_in is input dimension;# H is the dimension of the hidden layer; D_out is output dimension.N,D_in,H,D_out=32,100,50,10# Create random Tensors to hold inputs and outputs, and wrap them in Variablesx=Variable(torch.randn(N,D_in))# dim: 32 x 100# Construct our model by instantiating the class defined abovemodel=TwoLayerNet(D_in,H,D_out)# Forward pass: Compute predicted y by passing x to the modely_pred=model(x)# dim: 32 x 10更複雜的模型遵循相同的布局,我們將在後續帖子中看到其中兩個。
損失函數
PyTorch提供了許多標準loss功能,可供您在
torch.nn
模塊中使用。這是一個如何計算交叉熵損失的簡單示例。假設我們的模型解決了帶
C
標籤的多類分類問題。然後對於一批大小
N
,
out
是
NxC
通過在模型中傳遞輸入批次獲得的PyTorch維度變量。我們還有一個
target
大小的變量
N
,其中每個元素都是該示例的類,即中的標籤
[0,...,C-1]
。您可以定義損失函數並計算損失,如下所示:
loss_fn=nn.CrossEntropyLoss()loss=loss_fn(out,target)
PyTorch可以很容易地擴展它並編寫自己的自定義損失函數。我們可以編寫自己的Cross Entropy Loss函數,如下所示(注意NumPy-esque語法):
defmyCrossEntropyLoss(outputs,labels):batch_size=outputs.size()[0]# batch_sizeoutputs=F.log_softmax(outputs,dim=1)# compute the log of softmax valuesoutputs=outputs[range(batch_size),labels]# pick the values corresponding to the labelsreturn-torch.sum(outputs)/num_examples
這是編寫自己的損失函數的一個相當簡單的例子。
優化
torch.optim
軟體包為常見的優化算法提供了易於使用的界面。定義優化器非常簡單:
# pick an SGD optimizeroptimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.9)# or pick ADAMoptimizer=torch.optim.Adam(model.parameters(),lr=0.0001)
傳遞了每次迭代需要更新的模型參數。還可以指定更複雜的方法,例如參數學習率。
一旦使用計算梯度
loss.backward()
,調用
optimizer.step()
更新優化算法定義的參數。
訓練與評估
在訓練模型之前,必須打調用
model.train()
。同樣,調用
model.eval()
在測試模型之前。這可以糾正培訓和測試過程中的丟失,批量標準化的差異。
計算指標
在這個階段,您應該能夠理解大部分代碼
train.py
和
evaluate.py
除了密切關注損失之外,監控其他指標(如準確性和精確度/召回率)也很有幫助。為此,您可以為文件中的一批模型輸出定義自己的度量標準函數
model/net.py
。為了使其更容易,我們將PyTorch變量轉換為NumPy數組,然後將它們傳遞給度量函數。對於在損失函數一節中設置的多類分類問題,我們可以使用NumPy編寫一個計算精度的函數:
defaccuracy(out,labels):outputs=np.argmax(out,axis=1)returnnp.sum(outputs==labels)/float(labels.size)
您可以在
model/net.py
文件中添加自己的指標。完成後,只需將它們添加到
metrics
中:
metrics={'accuracy':accuracy,# add your own custom metrics,}
保存和加載模型
我們定義實用程序函數來保存和加載模型
utils.py
。要保存模型,請執行:
state={'epoch':epoch+1,'state_dict':model.state_dict(),'optim_dict':optimizer.state_dict()}utils.save_checkpoint(state,is_best=is_best,# True if this is the model with best metricscheckpoint=model_dir)# path to folder
utils.py
在內部使用該
torch.save(state, filepath)
方法來保存上面定義的狀態。您可以向狀態中添加更多,例如指標。
model.state_dict()
存儲模型和參數
optimizer.state_dict()
存儲優化的狀態(如每個參數學習率)。
要從檢查點加載已保存的狀態,您可以使用:
utils.load_checkpoint(restore_path,model,optimizer)
該
optimizer
參數是可選的,你可以選擇一個新的優化器重新啟動。
load_checkpoint
內部加載保存的檢查點並恢復模型權重和優化程序的狀態。
使用GPU
通過代碼散布,你會發現如下行:
>model=net.Net(params).cuda()ifparams.cudaelsenet.Net(params)>ifparams.cuda:batch_data,batch_labels=batch_data.cuda(),batch_labels.cuda()
PyTorch使用這些命令使GPU顯式透明。調用
.cuda()
模型/ Tensor / Variable將其發送到GPU。為了在GPU上訓練模型,必須將所有相關參數和變量發送到GPU
.cuda()
。
調試
憑藉其簡潔的設計,PyTorch使調試變得輕而易舉。您可以
pdb.set_trace()
在代碼中的任何行使用斷點。然後,您可以執行進一步的計算,檢查PyTorch張量/變量並查明錯誤的根本原因。
以上就是使用PyTorch的基本套路。大家感覺如何?歡迎評論交流。