從基礎概念到實現,小白如何快速入門PyTorch
文章選自analyticsvidhya
機器之心編譯
參與:思源
PyTorch 是一個有潛力能改變深度學習實現面貌的 Python 庫,它的使用非常靈活與輕鬆。在本文中,我們將以更實用的方式探索 PyTorch,包括基礎知識和案例研究等。此外,本文還將比較使用 NumPy 和 PyTorch 從頭構建神經網路的方式,以了解它們在實現中的相似之處。
PyTorch 的構建者表明,PyTorch 的哲學是解決當務之急,也就是說即時構建和運行我們的計算圖。這恰好適合 Python 的編程方法,因為我們不需等待整個代碼都被寫入才能知道是否起作用。我們很容易運行部分代碼,並實時檢查它。
PyTorch 是一個基於 Python 的庫,旨在為深度學習提供一個靈活的開發平台。PyTorch 的工作流程非常接近於 Python 的科學計算庫 NumPy。那麼為什麼我們需要使用 PyTorch 構建深度學習模型?以下作者根據實際經驗提供了三個理由:
- 便於使用的 API:它的使用如同 Python 那樣簡單。
- 支持 Python:正如上文所述,PyTorch 可以平滑地與 Python 數據科學棧相結合。它與 NumPy 一樣簡單,甚至我們都感覺不出它們的區別。
- 動態計算圖:PyTorch 不再採用特定的函數預定義計算圖,而是提供構建動態計算圖的框架,甚至我們可以在運行時修正它們。這種動態框架在我們不知道所構建的神經網路需要多少內存時非常有用。
其它一些使用 PyTorch 的優點還有多 GPU 支持、自定義數據載入器和極簡的預處理過程等。自從它在 2016 年 1 月份發布以來,許多研究者將其採用為標準的實現庫,因為它構建新穎的、極其複雜的計算圖同樣非常簡單。即使這樣,PyTorch 被主流數據科學家和研究員接收還是花了很長時間,因為它目前仍然是新的項目,且還有很多地方需要構建與完善。
PyTorch 基礎
在討論 PyTorch 的各個組件前,我們需要了解它的工作流。PyTorch 使用一種稱之為 imperative / eager 的範式,即每一行代碼都要求構建一個圖以定義完整計算圖的一個部分。即使完整的計算圖還沒有完成構建,我們也可以獨立地執行這些作為組件的小計算圖,這種動態計算圖被稱為「define-by-run」方法。
更多介紹請查看:http://pytorch.org/about/
安裝 PyTorch 非常簡單,我們可以按照自己的系統跟隨官方文檔的步驟輕鬆完成。例如以下選擇在 Linux、Python 3.5 和 CUDA 9.1 的環境下安裝 PyTorc
conda install pytorch torchvision cuda91 -c pytorch
我們在基礎部分主要需要了解的 PyTorch 元素有 PyTorch 張量、數學運算、自動求導模塊、最優化模塊和神經網路模塊。下面本文會依次對這些模塊進行簡要的介紹:
PyTorch 張量
正如 PyTorch 文檔所說,如果我們熟悉 NumPy 的多維數組,那麼 Torch 張量的很多操作我們能輕易地掌握。PyTorch 提供了 CPU 張量和 GPU 張量,並且極大地加速了計算的速度。
從張量的構建與運行就能體會到 PyTorch 相比 TensorFLow 需要聲明張量、初始化張量要簡潔地多。以下語句將隨機初始化一個 5×3 的二維張量,因為 PyTorch 是一種動態圖,所以它聲明和真實賦值是同時進行的。
torch.Tensor(5, 3)---------------------------------------2.4878e+04 4.5692e-41 2.4878e+044.5692e-41 -2.9205e+19 4.5691e-411.2277e-02 4.5692e-41 -4.0170e+194.5691e-41 1.2277e-02 4.5692e-410.0000e+00 0.0000e+00 0.0000e+00[torch.FloatTensor of size 5x3]
若我們希望隨機初始化的張量服從某些分布,那麼我們可以直接對張量對象使用一些方法。如下初始化的張量將服從均勻分布:
torch.Tensor(5, 3).uniform_(-1, 1)----------------------------------------------0.2767 -0.1082 -0.1339-0.6477 0.3098 0.1642-0.1125 -0.2104 0.8962-0.6573 0.9669 -0.38060.8008 -0.3860 0.6816[torch.FloatTensor of size 5x3]
在 PyTorch 中,torch.Tensor 是一種多維矩陣,其中每個元素都是一個單一的數據類型,且該構造函數默認的為 torch.FloatTensor。以下是具體張量的類型:
除了直接定義維度,一般我們還可以從 Python 列表或 NumPy 數組中創建張量。而且根據 Python 列表和元組等數據結構的習慣,我們可以使用相似的索引方式進行取值或賦值等。以下通過 Python 列表創建一個 Torch 張量,並通過索引賦值:
>>> torch.FloatTensor([[1, 2, 3], [4, 5, 6]])1 2 34 5 6[torch.FloatTensor of size 2x3]>>> print(x[1][2])6.0>>> x[0][1] = 8>>> print(x)1 8 34 5 6[torch.FloatTensor of size 2x3]
若 x 為我們定義的 5×3 Torch 張量,且初始化數值服從-1 到 1 的均勻分布,那麼我們可以執行很多基礎的數學運算。以下執行了一個簡單的矩陣間對應元素乘積。
x = torch.Tensor(5, 3).uniform_(-1, 1)y = x * torch.randn(5, 3)print(y)---------------------------------------------0.2200 -0.0368 0.4494-0.2577 -0.0343 0.1587-0.7503 -0.1729 0.04530.9296 -0.1067 -0.6402-0.3276 0.0158 -0.0552[torch.FloatTensor of size 5x3]
PyTorch 同樣支持廣播(Broadcasting)操作,一般它會隱式地把一個數組的異常維度調整到與另一個運算元相匹配的維度以實現維度兼容。為了定義兩個形狀是否是可兼容的,PyTorch 會從最後開始往前逐個比較它們的維度大小。在這個過程中,如果兩者的對應維度相同,或者其一(或者全是)等於 1,則繼續進行比較,直到最前面的維度。若不滿足這兩個條件,程序就會報錯。如下展示了 PyTorch 的廣播操作:
print (x.size())y = x + torch.randn(5, 1)print(y)---------------------------------------------torch.Size([5, 3])0.1919 -0.5006 -1.2410-0.8080 0.1407 -0.6193-1.6629 -0.1580 -0.39211.0395 0.7069 -0.14591.9027 1.4343 1.2299[torch.FloatTensor of size 5x3]
正如 PyTorch 在官網上所說,PyTorch 是一個張量和動態神經網路 Python 庫,它有著極其強大的 GPU 加速性能。我們一般可以直接定義 GPU 張量,也可以由 CPU 張量轉化為 GPU 張量。如下,我們定義了兩個 GPU 張量,並對這兩個張量執行矩陣乘法。當然,我們也可以如下所示將 CPU 張量轉換為 GPU 張量。
x = torch.cuda.HalfTensor(5, 3).uniform_(-1, 1)y = torch.cuda.HalfTensor(3, 5).uniform_(-1, 1)torch.matmul(x, y)-----------------------------------------------------0.2456 1.1543 0.5376 0.4358 -0.03690.8247 -0.4143 -0.7188 0.3953 0.2573-0.1346 0.7329 0.5156 0.0864 -0.1349-0.3555 0.3135 0.3921 -0.1428 -0.1368-0.4385 0.5601 0.6533 -0.2793 -0.5220[torch.cuda.HalfTensor of size 5x5 (GPU 0)]# 以下轉化CPU張量為GPU張量x = torch.FloatTensor(5, 3).uniform_(-1, 1)print(x)x = x.cuda(device=0)print(x)x = x.cpu()print(x)
數學運算
如 NumPy 一樣,高效地實現數學函數對於科學計算庫至關重要。PyTorch 提供了一個簡單的介面,並支持 200 多種數學運算,以下是 PyTorch 實現簡單加運算的過程:
a = torch.FloatTensor([2])b = torch.FloatTensor([3])a + b 5[torch.FloatTensor of size 1]
這種運算與 Python 非常像,我們可以在定義的 PyTorch 張量上執行多種矩陣運算。例如我們可以轉置二維張量:
matrix = torch.randn(3, 3)matrix-1.3531 -0.5394 0.8934 1.7457 -0.6291 -0.0484-1.3502 -0.6439 -1.5652[torch.FloatTensor of size 3x3]matrix.t()-2.1139 1.8278 0.1976 0.6236 0.3525 0.2660-1.4604 0.8982 0.0428[torch.FloatTensor of size 3x3]
AutoGrad 模塊
TensorFlow、Caffe 和 CNTK 等大多數框架都是使用的靜態計算圖,開發者必須建立或定義一個神經網路,並重複使用相同的結構來執行模型訓練。改變網路的模式就意味著我們必須從頭開始設計並定義相關的模塊。
但 PyTorch 使用的技術為自動微分(automatic differentiation)。在這種機制下,系統會有一個 Recorder 來記錄我們執行的運算,然後再反向計算對應的梯度。這種技術在構建神經網路的過程中十分強大,因為我們可以通過計算前向傳播過程中參數的微分來節省時間。
from torch.autograd import Variablex = Variable(train_x)y = Variable(train_y, requires_grad=False)
從概念上來說,Autograd 會維護一個圖並記錄對變數執行的所有運算。這會產生一個有向無環圖,其中葉結點為輸入向量,根結點為輸出向量。通過從根結點到葉結點追蹤圖的路徑,我們可以輕易地使用鏈式法則自動計算梯度。
在內部,Autograd 將這個圖表徵為 Function 對象的圖,並且可以應用 apply() 計算評估圖的結果。在計算前向傳播中,當 Autograd 在執行請求的計算時,它還會同時構建一個表徵梯度計算的圖,且每個 Variable 的 .grad_fn 屬性就是這個圖的輸入單元。在前向傳播完成後,我們可以在後向傳播中根據這個動態圖來計算梯度。
以下展示了通過 backward() 和 torch.autograd.grad 計算梯度的方法,其中 torch.eq() 評估表達式是不是相等,即 x.grad 的計算結果是不是等於 2x。
x = Variable(torch.Tensor(5, 3).uniform_(-1, 1), requires_grad=True)y = Variable(torch.Tensor(5, 3).uniform_(-1, 1), requires_grad=True)z = x ** 2 + 3 * yz.backward(gradient=torch.ones(5, 3))# eq computes element-wise equalitytorch.eq(x.grad, 2 * x)----------------------------------------------------------------------Variable containing:1 1 11 1 11 1 11 1 11 1 1[torch.ByteTensor of size 5x3]
以下展示了對 y 求導的結果,即 dz/dy。從上面 z 的定義可知結果應該是 3,那麼以下展示了該計算過程:
y.grad-------------------------------Variable containing:3 3 33 3 33 3 33 3 33 3 3[torch.FloatTensor of size 5x3]
前面是使用 backward() 求解變數的梯度,後面我們也可以使用 torch.autograd.grad 計算梯度。如下所示,我們使用另外一種方式求解同一個函數的梯度。
x = Variable(torch.Tensor(5, 3).uniform_(-1, 1), requires_grad=True)y = Variable(torch.Tensor(5, 3).uniform_(-1, 1), requires_grad=True)z = x ** 2 + 3 * ydz_dx = torch.autograd.grad(z, x, grad_outputs=torch.ones(5, 3))dz_dy = torch.autograd.grad(z, y, grad_outputs=torch.ones(5, 3))
最優化模塊
torch.optim 是實現神經網路中多種優化演算法的模塊,它目前已經支持大多數一般的方法,所以我們不需要從頭構建優化演算法。以下展示了使用 Adam 優化器的基本代碼:
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
神經網路模塊
PyTorch AutoGrad 使得計算圖的定義和梯度的計算十分簡單,但原版的 AutoGrad 可能對定義複雜的神經網路顯得太底層,因此我們需要神經網路模塊幫助簡化工作。該 nn 包定義了一組函數,我們可以將其視為有一些可訓練權重的神經網路層級。我們也可以將該神經網路模塊視為類似於 Keras 的 PyTorch 組件。
我們一般可以使用 torch.nn 包構建神經網路,下面提供了一些 API 的表達及意義:
- 線性層- nn.Linear、nn.Bilinear
- 卷積層 - nn.Conv1d、nn.Conv2d、nn.Conv3d、nn.ConvTranspose2d
- 非線性激活函數- nn.Sigmoid、nn.Tanh、nn.ReLU、nn.LeakyReLU
- 池化層 - nn.MaxPool1d、nn.AveragePool2d
- 循環網路 - nn.LSTM、nn.GRU
- 歸一化 - nn.BatchNorm2d
- Dropout - nn.Dropout、nn.Dropout2d
- 嵌入 - nn.Embedding
- 損失函數 - nn.MSELoss、nn.CrossEntropyLoss、nn.NLLLoss
import torch# define modelmodel = torch.nn.Sequential( torch.nn.Linear(input_num_units, hidden_num_units), torch.nn.ReLU(), torch.nn.Linear(hidden_num_units, output_num_units),)loss_fn = torch.nn.CrossEntropyLoss()
以上就是 PyTorch 的基本組件,我們可以使用它們快速構建神經網路。當然以上只是簡單的概念介紹,每一個模塊都有非常多的函數與方法,讀者可詳細查閱 PyTorch 文檔了解更多。
構建神經網路(NumPy vs. PyTorch)
在這一部分中,我們分別使用 NumPy 和 PyTorch 構建簡單的神經網路以實現二元分類問題,本文的後面會對這一部分的代碼進行解釋。
## Neural network in numpyimport numpy as np#Input arrayX=np.array([[1,0,1,0],[1,0,1,1],[0,1,0,1]])#Outputy=np.array([[1],[1],[0]])#Sigmoid Functiondef sigmoid (x): return 1/(1 + np.exp(-x))#Derivative of Sigmoid Functiondef derivatives_sigmoid(x): return x * (1 - x)#Variable initializationepoch=5000 #Setting training iterationslr=0.1 #Setting learning rateinputlayer_neurons = X.shape[1] #number of features in data sethiddenlayer_neurons = 3 #number of hidden layers neuronsoutput_neurons = 1 #number of neurons at output layer#weight and bias initializationwh=np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons))bh=np.random.uniform(size=(1,hiddenlayer_neurons))wout=np.random.uniform(size=(hiddenlayer_neurons,output_neurons))bout=np.random.uniform(size=(1,output_neurons))for i in range(epoch): #Forward Propogation hidden_layer_input1=np.dot(X,wh) hidden_layer_input=hidden_layer_input1 + bh hiddenlayer_activations = sigmoid(hidden_layer_input) output_layer_input1=np.dot(hiddenlayer_activations,wout) output_layer_input= output_layer_input1+ bout output = sigmoid(output_layer_input) #Backpropagation E = y-output slope_output_layer = derivatives_sigmoid(output) slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations) d_output = E * slope_output_layer Error_at_hidden_layer = d_output.dot(wout.T) d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer wout += hiddenlayer_activations.T.dot(d_output) *lr bout += np.sum(d_output, axis=0,keepdims=True) *lr wh += X.T.dot(d_hiddenlayer) *lr bh += np.sum(d_hiddenlayer, axis=0,keepdims=True) *lrprint(actual :
, y,
)print(predicted :
, output)
現在,我們會發現使用 PyTorch 實現相同的網路會非常簡單。以下的代碼同樣也用粗體表示出它與 NumPy 的不同之處:
## neural network in pytorch*import torch*#Input arrayX = *torch.Tensor*([[1,0,1,0],[1,0,1,1],[0,1,0,1]])#Outputy = *torch.Tensor*([[1],[1],[0]])#Sigmoid Functiondef sigmoid (x): return 1/(1 + *torch.exp*(-x))#Derivative of Sigmoid Functiondef derivatives_sigmoid(x): return x * (1 - x)#Variable initializationepoch=5000 #Setting training iterationslr=0.1 #Setting learning rateinputlayer_neurons = X.shape[1] #number of features in data sethiddenlayer_neurons = 3 #number of hidden layers neuronsoutput_neurons = 1 #number of neurons at output layer#weight and bias initializationwh=*torch.randn*(inputlayer_neurons, hiddenlayer_neurons)*.type(torch.FloatTensor)*bh=*torch.randn*(1, hiddenlayer_neurons)*.type(torch.FloatTensor)*wout=*torch.randn*(hiddenlayer_neurons, output_neurons)bout=*torch.randn*(1, output_neurons)for i in range(epoch): #Forward Propogation hidden_layer_input1 = *torch.mm*(X, wh) hidden_layer_input = hidden_layer_input1 + bh hidden_layer_activations = sigmoid(hidden_layer_input) output_layer_input1 = *torch.mm*(hidden_layer_activations, wout) output_layer_input = output_layer_input1 + bout output = sigmoid(output_layer_input1) #Backpropagation E = y-output slope_output_layer = derivatives_sigmoid(output) slope_hidden_layer = derivatives_sigmoid(hidden_layer_activations) d_output = E * slope_output_layer Error_at_hidden_layer = *torch.mm*(d_output, wout.t()) d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer wout += *torch.mm*(hidden_layer_activations.t(), d_output) *lr bout += d_output.sum() *lr wh += *torch.mm*(X.t(), d_hiddenlayer) *lr bh += d_output.sum() *lrprint(actual :
, y,
)print(predicted :
, output)
對比其它深度學習庫
在一份基準腳本中,它展示出 PyTorch 在訓練長短期記憶(LSTM)網路上比其它主要框架的表現都要好,因為它運行一個 Epoch 有最少的中位數時間。
PyTorch 中的數據載入 API 經過了優良的設計,介面是針對特定數據集、採樣器和數據載入器而構建的。對比於 TensorFlow 的數據載入工具(readers, queues 等),我發現 PyTorch 的數據載入模塊更易於使用。同時它們還能無縫對接神經網路構建模塊,所以我們不需要第三方高級庫。
然而,我並不推薦使用使用 PyTorch 部署模型,因為 PyTorch 仍然不是那麼成熟。正如 PyTorch 開發者所說:「我們經常看到用戶首先創建一個 PyTorch 模型來測試是否可行,然後當需要部署模型到生產中時,他們會轉化為 Caffe 2 等其他框架,並將其部署到移動端或其它平台。」
案例研究
前面我們已經了解了PyTorch的基本組成元素與特性,下面我們會通過線性回歸與手寫字體識別兩個具體的案例探討如何使用 PyTorch 構建高效地模型。
PyTorch 線性回歸
定義數據:
import torchfrom torch.autograd import Variablex_data = Variable(torch.Tensor([[1.0], [2.0], [3.0]]))y_data = Variable(torch.Tensor([[2.0], [4.0], [6.0]]))
定義模型,在 PyTorch 中,我們可以使用高級 API 來定義相關的模型或層級。如下定義了「torch.nn.Linear(1, 1)」,即一個輸入變數和一個輸出變數。
class Model(torch.nn.Module): def __init__(self): """ In the constructor we instantiate two nn.Linear module """ super(Model, self).__init__() self.linear = torch.nn.Linear(1, 1) # One in and one out def forward(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. """ y_pred = self.linear(x) return y_pred
構建損失函數和優化器,構建損失函數也可以直接使用「torch.nn.MSELoss(size_average=False)」調用均方根誤差函數。優化器可以使用「torch.optim.SGD()」提到用隨機梯度下降,其中我們需要提供優化的目標和學習率等參數。
# Construct our loss function and an Optimizer. The call to model.parameters()# in the SGD constructor will contain the learnable parameters of the two# nn.Linear modules which are members of the model.criterion = torch.nn.MSELoss(size_average=False)optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
訓練模型,執行前向傳播計算損失函數,並優化參數:
# Training loopfor epoch in range(500): # Forward pass: Compute predicted y by passing x to the model y_pred = model(x_data) # Compute and print loss loss = criterion(y_pred, y_data) print(epoch, loss.data[0]) # Zero gradients, perform a backward pass, and update the weights. optimizer.zero_grad() loss.backward() optimizer.step()
用 PyTorch 解決圖像識別問題
為了進一步熟悉 PyTorch,我們將使用它解決 Analytics Vidhya 的深度學習實踐問題:識別手寫數字。我們的問題是給定一張 28 x 28 的圖像,利用模型識別其所代表的手寫數字。
所以首先我們需要下載訓練集與測試集,數據集包含了一個壓縮文件以儲存所有的圖像。其中 train.csv 和 test.csv 分別儲存了訓練和測試圖像,且圖像的格式為 png。下面我們將一步步構建簡單的神經網路以實現手寫數字識別功能。
第 0 步:準備工作
a)導入必要的函數庫
# import modules%pylab inlineimport osimport numpy as npimport pandas as pdfrom scipy.misc import imreadfrom sklearn.metrics import accuracy_score
b)設置隨機的 Seed,因此我們能控制模型產生的隨機數基本不變(偽隨機數)。
# To stop potential randomnessseed = 128rng = np.random.RandomState(seed)
c)設置工作目錄的路徑。
root_dir = os.path.abspath(.)data_dir = os.path.join(root_dir, data)# check for existenceos.path.exists(root_dir), os.path.exists(data_dir)
第 1 步:載入與預處理數據
a)現在讀取 CSV 格式的數據集,並獲取文件名與對應的標註。
# load datasettrain = pd.read_csv(os.path.join(data_dir, Train, train.csv))test = pd.read_csv(os.path.join(data_dir, Test.csv))sample_submission = pd.read_csv(os.path.join(data_dir, Sample_Submission.csv))train.head(
b)接下來可以列印準備好的圖片。
# print an imageimg_name = rng.choice(train.filename)filepath = os.path.join(data_dir, Train, Images, train, img_name)img = imread(filepath, flatten=True)pylab.imshow(img, cmap=gray)pylab.axis(off)pylab.show()
c)對於更簡單的數據操作,我們可以儲存所有的圖像作為 NumPy 數組。
# load images to create train and test settemp = []for img_name in train.filename: image_path = os.path.join(data_dir, Train, Images, train, img_name) img = imread(image_path, flatten=True) img = img.astype(float32) temp.append(img)train_x = np.stack(temp)train_x /= 255.0train_x = train_x.reshape(-1, 784).astype(float32)temp = []for img_name in test.filename: image_path = os.path.join(data_dir, Train, Images, test, img_name) img = imread(image_path, flatten=True) img = img.astype(float32) temp.append(img)test_x = np.stack(temp)test_x /= 255.0test_x = test_x.reshape(-1, 784).astype(float32)train_y = train.label.values
d)因為這個是一個典型的機器學習問題,所以我們可以創建驗證集以監控模型的運行情況。下面我們以 7:3 的比例分割訓練集與驗證集。
# create validation setsplit_size = int(train_x.shape[0]*0.7)train_x, val_x = train_x[:split_size], train_x[split_size:]train_y, val_y = train_y[:split_size], train_y[split_size:]
第 2 步:構建模型
a)下面是模型的主體,我們定義的神經網路共有三層,即輸入層、隱藏層和輸出層。輸入層和輸出層的神經元數量是固定的,即 28 x 28 和 10 x 1,它們分別代表了輸入圖像的像素和類別。我們在隱藏層採用了 50 個神經元,並採用 Adam 作為最優化演算法。
import torchfrom torch.autograd import Variable# number of neurons in each layerinput_num_units = 28*28hidden_num_units = 500output_num_units = 10# set remaining variablesepochs = 5batch_size = 128learning_rate = 0.001
b)以下將開始訓練模型。
# define modelmodel = torch.nn.Sequential( torch.nn.Linear(input_num_units, hidden_num_units), torch.nn.ReLU(), torch.nn.Linear(hidden_num_units, output_num_units),)loss_fn = torch.nn.CrossEntropyLoss()# define optimization algorithmoptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)## helper functions# preprocess a batch of datasetdef preproc(unclean_batch_x): """Convert values to range 0-1""" temp_batch = unclean_batch_x / unclean_batch_x.max() return temp_batch# create a batchdef batch_creator(batch_size): dataset_name = train dataset_length = train_x.shape[0] batch_mask = rng.choice(dataset_length, batch_size) batch_x = eval(dataset_name + _x)[batch_mask] batch_x = preproc(batch_x) if dataset_name == train: batch_y = eval(dataset_name).ix[batch_mask, label].values return batch_x, batch_y# train networktotal_batch = int(train.shape[0]/batch_size)for epoch in range(epochs): avg_cost = 0 for i in range(total_batch): # create batch batch_x, batch_y = batch_creator(batch_size) # pass that batch for training x, y = Variable(torch.from_numpy(batch_x)), Variable(torch.from_numpy(batch_y), requires_grad=False) pred = model(x) # get loss loss = loss_fn(pred, y) # perform backpropagation loss.backward() optimizer.step() avg_cost += loss.data[0]/total_batch print(epoch, avg_cost)# get training accuracyx, y = Variable(torch.from_numpy(preproc(train_x))), Variable(torch.from_numpy(train_y), requires_grad=False)pred = model(x)final_pred = np.argmax(pred.data.numpy(), axis=1)accuracy_score(train_y, final_pred)# get validation accuracyx, y = Variable(torch.from_numpy(preproc(val_x))), Variable(torch.from_numpy(val_y), requires_grad=False)pred = model(x)final_pred = np.argmax(pred.data.numpy(), axis=1)accuracy_score(val_y, final_pred)
- 訓練準確度為:0.8779008746355685
- 測試準確度為:0.867482993197279
這些分數非常令人滿意,因為我們只是用簡單的神經網路訓練了 5 個 Epoch。以上,本文介紹了簡單的 PyTorch 入門概念,並利用簡單的案例熟悉 PyTorch 的使用。讀者可以繼續閱讀 PyTorch 的文檔以了解更多信息。
原文鏈接:https://www.analyticsvidhya.com/blog/2018/02/pytorch-tutorial/
推薦閱讀:
※今天不如來複習下Python基礎
※python 中文亂碼出現,不知道是什麼原因?
※C/C++ 這類更底層的語言,如果把平時常用的高級函數和功能都實現,能否達到 Python 的開發效率?
※為解決工作中的實際問題,python和c#應該選擇學習哪一種?