本文你將會了解到
1、如何使用PyTorch對數據集進行導入
2、如何使用PyTorch搭建一個簡易的深度學習模型
3、如何優化和訓練我們搭建好的模型
註:本案例使用的PyTorch為0.4版本
簡介
Pytorch是目前非常流行的深度學習框架,因為它具備了Python的特性所以極易上手和使用,同時又兼具了NumPy的特性,因此在性能上也並不遜於任何一款深度學習框架。現在PyTorch又和Caffe2進行了融合,在今年暑期整和了Caffe2的PyTorch1.0版本將受到更多專業人士的關注和重視。下面我們通過使用PyTorch實現一個手寫數字識別的模型來簡單的入門一下PyTorch。
如何使用PyTorch對數據集進行導入
在進行數據導入之前我們需要先導入一些在之後需要用的包,代碼如下:
import torch
import torchvision
from torch.autograd import Variable
from torchvision import transforms,datasets
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
手寫數字的數據集我們可以使用PyTorch中自帶的torchvision.datasets方法進行下載。另外這個方法還可以方便的下載COCO,ImageNet,CIFCAR等常用的數據集。代碼如下:
transform = transforms.ToTensor() train_dataset = datasets.MNIST(root ="./data",
train = True,
transform = transform,
download = True)
test_dataset = datasets.MNIST(root = "./data",
train = False,
transform = transform,
download = True)
train_data_loader = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size=64,
shuffle = True)
test_data_loader = torch.utils.data.DataLoader(dataset=test_dataset,
batch_size=64,
shuffle = True)
通過這幾段代碼我們就實現了數據的載入和裝載。其中batch_size指定我們每次裝載的數據個數,這裡使用的值是64即我們每次裝載到模型中的圖片個數是64張。shuffle設置為True表明我們裝載到模型中的輸入數據是被隨機打亂順序的。
如何使用PyTorch搭建一個簡易的深度學習模型
定義好了數據載入和裝載的方法之後,我們就可以開始搭建深度學習模型,這裡使用卷積層、最大池化層和全連接層來搭建一個簡易的卷積神經網絡模型,代碼如下:
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
self.Conv=torch.nn.Sequential(
torch.nn.Conv2d(1,28,kernel_size=3,padding=1,stride=1),
torch.nn.Conv2d(28,64,kernel_size=3,padding=1,stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=2), torch.nn.Conv2d(64,64,kernel_size=3,padding=1,stride=1), torch.nn.Conv2d(64,64,kernel_size=3,padding=1,stride=1), torch.nn.MaxPool2d(kernel_size=2, stride=2)
)
self.Dense = torch.nn.Linear(7*7*64, 10)
def forward(self, input):
x = self.Conv(input)
x = x.view(-1, 7*7*64)
x = self.Dense(x)
return x ```
模型使用的是4層卷積、2層池化和1層全連接的卷積神經網絡結構。雖然結構簡單,但是對於處理手寫數字識別問題這個模型已經綽綽有餘了。搭建好模型之後我們可以對模型進行列印輸出,查看具體的模型細節,如下:
model = Model()
model = model.cuda()
print(model)
輸出的結果為:
Model(
(Conv): Sequential(
(0): Conv2d(1, 28, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): Conv2d(28, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(4): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(Dense): Linear(in_features=3136, out_features=10, bias=True)
)
如何優化和訓練我們搭建好的模型
模型已經搭建好了,數據的裝載方式也已經完成了定義,下面就差最後一步了,對我們的模型進行訓練並優化模型內部的參數。代碼如下:
epoch_n = 5
loss_f = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
for epoch in range(epoch_n):
epoch_loss = 0.0
epoch_acc = 0.0
for batch in train_data_loader:
X_train,y_train = batch
X_train,y_train=Variable(X_train.cuda()),Variable(y_train.cuda())
y_pred = model(X_train)
_,pred =torch.max(y_pred, 1)
optimizer.zero_grad()
loss = loss_f(y_pred, y_train)
loss.backward()
optimizer.step()
epoch_loss += loss.item()
epoch_acc += torch.sum(pred == y_train.data)
epoch_loss = epoch_loss*64/len(train_dataset)
epoch_acc = epoch_acc.double()/len(train_dataset)
print("Epoch{}: Loss is:{:.4f},Acc is:{:4f}".format(epoch, epoch_loss, epoch_acc))
我們定義了5次訓練,所以在整個訓練過程中會進行5次後向傳播對模型的參數進行更新,其中定義的優化函數是Adam方法,損失函數是CrossEntropyLoss(交叉熵損失)。我們來看訓練過程中輸出的結果,如下所示:
Epoch0: Loss is:0.1550,Acc is:0.953250
Epoch1: Loss is:0.0663,Acc is:0.979433
Epoch2: Loss is:0.0525,Acc is:0.984133
Epoch3: Loss is:0.0462,Acc is:0.985567
Epoch4: Loss is:0.0386,Acc is:0.987950
從結果上非常不錯了,訓練的準確率已經逼近了99%,而且還有上升的趨勢,如果繼續進行訓練還能有更好的表現,不過也有可能會有過擬合的風險。下面我們使用測試集來驗證模型對手寫數字識別的效果如何。 隨機抽取64張測試集的圖片,它們的真實標籤和圖片顯示如下:
[ 7, 4, 0, 3, 3, 8, 9, 7, 9, 1, 6, 0, 4, 4,
3, 6, 2, 3, 7, 1, 6, 0, 6, 5, 9, 9, 8, 7,
9, 7, 6, 7, 8, 6, 6, 9, 4, 9, 3, 6, 1, 3,
5, 7, 6, 2, 7, 8, 8, 9, 8, 3, 0, 1, 1, 2,
8, 8, 5, 3, 3, 1, 1, 4]
我們訓練好的模型預測結果如下:
[ 7, 4, 0, 3, 3, 8, 9, 7, 9, 1, 6, 0, 4, 4,
3, 6, 2, 3, 7, 1, 6, 0, 6, 5, 9, 9, 8, 7,
9, 7, 6, 9, 8, 6, 6, 9, 4, 9, 3, 6, 1, 3,
5, 7, 6, 2, 7, 8, 8, 9, 8, 3, 0, 1, 1, 2,
8, 8, 5, 3, 3, 1, 1, 4]
可以看到預測的結果中只出現了一個錯誤,總體來說這組測試數據的準確率仍然高達98%以上。完整的測試部分代碼如下:
X_test,y_test = next(iter(test_data_loader))
print("Test dataset label is:{}".format(y_test))
X = torchvision.utils.make_grid(X_test)
X = X.numpy().transpose(1,2,0)
plt.imshow(X)
X_test = X_test.cuda()
y = model(X_test)
_,y = torch.max(y,1)
print(y)
本文介紹的只是一個簡單的小案例,整個過程基於PyTorch進行完成非常的簡單。當然面對較為複雜的問題我們依然可以遵循這三個步驟來搭建出我們基礎的模型。
本文作者:唐進民(Guilin Tang),Python中文社區專欄作者。《深度學習之PyTorch實戰計算機視覺》圖書作者,知乎專欄地址:https://zhuanlan.zhihu.com/c_135203221
讚賞作者
最近熱門文章
用Python更加了解微信好友
如何用Python做一個騷氣的程式設計師
用Python爬取陳奕迅新歌《我們》10萬條評論的新發現
用Python分析蘋果公司股價數據
Python自然語言處理分析倚天屠龍記
百度AI開發者免費實戰營深圳站(主會場)活動時間:2018年5月11日 13:30-17:00
活動地點:深圳科興科學園國際會議中心三層
活動地址:廣東省深圳市南山區科苑路15號科興科學園B4座3層
▼ 長按掃描下方二維碼或者點擊閱讀原文報名!