天天看點

HaaS AI之VSCode中搭建Pytorch簡單磁碟區積神經網絡1、Pytorch簡介2、Conda環境安裝3、建立Pytorch Python虛拟環境4、PyTorch之初體驗

1、Pytorch簡介

PyTorch是一個基于Torch的Python開源機器學習庫,用于自然語言處理等應用程式。它主要由Facebook的人工智能小組開發,不僅能夠實作強大的GPU加速,同時還支援動态神經網絡,這一點是現在很多主流架構如TensorFlow都不支援的。 PyTorch提供了兩個進階功能:

具有強大的GPU加速的張量計算(如Numpy)

包含自動求導系統的深度神經網絡

PyTorch大量使用了Python概念,例如類、結構和條件循環,允許使用者以純面向對象的方式建構深度學習算法。

除了Facebook之外,Twitter、GMU和Salesforce等機構都采用了PyTorch,包括達摩院PAI平台也有使用。

2、Conda環境安裝

參考

https://yuque.antfin-inc.com/yoznxz/gin3ds/rgeb8g

3、建立Pytorch Python虛拟環境

基于Python3.7版本,是以線建立一個PyTorch的Python虛拟環境。

conda create --name pytorch python=3.7

3.1 、激活環境

(tf2)$conda activate pytorch

3.2、安裝PyTorch

通路官網

https://pytorch.org/get-started/locally/

會根據目前系統提供合适的安裝指令:

HaaS AI之VSCode中搭建Pytorch簡單磁碟區積神經網絡1、Pytorch簡介2、Conda環境安裝3、建立Pytorch Python虛拟環境4、PyTorch之初體驗

指令中包含安裝視覺和聲音兩個部分,這裡隻安裝視覺部分:

(pytorch)$conda install pytorch torchvision -c pytorch

3.3、安裝Matplotlib

matplotlib,風格類似 Matlab 的基于 Python 的圖表繪圖系統。

matplotlib 是 Python最著名的繪圖庫,它提供了一整套和 matlab 相似的命 API,十分适合互動式地進行制圖。而且也可以友善地将它作為繪圖控件,嵌入 GUI 應用程式中,在模型訓練中常常用來繪制圖形。

(pytorch)$conda install matplotlib

4、PyTorch之初體驗

4.1、Python環境配置

建立一個test.ipynb,并配置Python環境為pytorch虛拟環境

HaaS AI之VSCode中搭建Pytorch簡單磁碟區積神經網絡1、Pytorch簡介2、Conda環境安裝3、建立Pytorch Python虛拟環境4、PyTorch之初體驗

4.2、Jupyter Kernel配置

在使用Jupyter時,需要連接配接到Jupyter kernel,按照下圖選擇Pytorch虛拟環境。

HaaS AI之VSCode中搭建Pytorch簡單磁碟區積神經網絡1、Pytorch簡介2、Conda環境安裝3、建立Pytorch Python虛拟環境4、PyTorch之初體驗

4.3、簡單手寫數字識别網絡

在VSCode中使用Pytorch實作LeNet-5進行手寫數字識别。

4.3.1、下載下傳MNIST資料集

在PyTorch中,下載下傳和導入MNIST資料集非常簡單,可以使用torchvision庫來完成。torchvision是一個專門進行圖形處理的庫,可加載比較常見的資料庫,如ImageNet、CIFAR10、MNIST等。使用torchvision的好處是避免了重複編寫資料集加載代碼,讓資料集的加載更加簡單。

import torch

import torchvision

import torchvision.transforms as transforms

import torch.nn as nn

import torch.nn.functional as F

import torch.optim as optim

import matplotlib.pyplot as plt

import numpy as np

#向量轉換

transform = transforms.Compose([transforms.ToTensor()])

#訓練集下載下傳

trainset = torchvision.datasets.MNIST(

       root = './datasets/ch08/pytorch',

       train= True,

       download= True,

       transform=transform)

#測試集下載下傳

testset = torchvision.datasets.MNIST(

       root='./datasets/ch08/pytorch',             # 選擇資料的根目錄

       train=False,

       download=True,                              # 從網絡上下載下傳圖檔

       transform=transform)

上面代碼中參數root設定資料集在本地存放的目錄,可自由選擇。注意,對于訓練集,參數train設定為True;對于測試集,參數train設定為False。關于參數download,如果是第一次運作該代碼,則将其設定為True,表示從網絡上下載下傳MNIST資料集;如果已經下載下傳了資料集,就可以将其設定為False。

4.3.2、加載資料集

#加載訓練集

trainloader = torch.utils.data.DataLoader(

   trainset,

   batch_size = 4,

   shuffle = True,

   num_workers = 2)

#加載測試集

testloader = torch.utils.data.DataLoader(

   testset,

   batch_size=4,

   shuffle=False,

   num_workers=2)

上面代碼中參數batch_size表示每個小批量樣本集中的樣本數量。參數shuffle表示是否在每個epoch中随機打亂資料集,這樣做的目的是使每個epoch資料集的次序都不一樣,保證每個小批量樣本集盡可能不一樣,提高接下來的訓練效果。參數num_workers表示使用多少個子程序來導入資料。

p​

rint(trainset)

print(testset)

列印訓練集和測試集路徑:

Dataset MNIST

   Number of datapoints: 60000

   Root location: ./datasets/ch08/pytorch

   Split: Train

   StandardTransform

Transform: Compose(

              ToTensor()

          )

Dataset MNIST

   Number of datapoints: 10000

   Root location: ./datasets/ch08/pytorch

   Split: Test

   StandardTransform

Transform: Compose(

              ToTensor()

          )

4.3.3、顯示訓練集

def imshow(img):

   npimg = img.numpy()

   plt.imshow(np.transpose(npimg, (1, 2, 0)))

dataiter = iter(trainloader)

images, labels = dataiter.next()

imshow(torchvision.utils.make_grid(images))

plt.show()

print(' '.join('%11s' % labels[j].numpy() for j in range(4)))

顯示訓練集:

HaaS AI之VSCode中搭建Pytorch簡單磁碟區積神經網絡1、Pytorch簡介2、Conda環境安裝3、建立Pytorch Python虛拟環境4、PyTorch之初體驗

4.3.4、搭建LeNet-5網絡模型

LeNet-5是卷積網絡用于識别的開山之作,由被譽為“卷積網絡之父”的Yann LeCun于1994年提出。雖然這網絡結構現在已經很少使用,但是它對後續卷積網絡的發展起到了奠基作用。這個網絡雖然很小,但是它包含了深度學習的基本子產品:卷積層,池化層,全連接配接層。是其他深度學習模型的基礎。

同時,其中也展現了前述的設計思想:局部感受野、權值共享、下采樣。  LeNet-5模型結構如下圖:

HaaS AI之VSCode中搭建Pytorch簡單磁碟區積神經網絡1、Pytorch簡介2、Conda環境安裝3、建立Pytorch Python虛拟環境4、PyTorch之初體驗

搭建網絡:

class Net(nn.Module):

   def __init__(self):

       super(Net, self).__init__()

       #第一層卷積

       self.conv1 = nn.Conv2d(1, 6, 5)         #1個輸入圖檔通道, 6個輸出通道, 5×5 卷積核

       #第一層池化層

       self.pool1 = nn.MaxPool2d(2, 2)         #max pooling, 2×2

       #第二層卷積

       self.conv2 = nn.Conv2d(6, 16, 5)        #6個輸入圖檔通道, 16個輸出通道, 5×5 卷積核

       #第二層池化

       self.pool2 = nn.MaxPool2d(2, 2)

       #全連接配接層

       self.fc1 = nn.Linear(16 * 4 * 4, 120)   #伸成一維向量

       #全連接配接層

       self.fc2 = nn.Linear(120, 84)           #120個特征圖, 84個神經元

       #全連接配接層, 輸出層

       self.fc3 = nn.Linear(84, 10)            #84個神經元輸入, Softmax輸出10個數字

   def forward(self, x):

       x = F.relu(self.conv1(x))

       x = self.pool1(x)

       x = F.relu(self.conv2(x))

       x = self.pool2(x)

       #拉伸為一維向量

       x = x.view(-1, 16 * 4 * 4)

       x = F.relu(self.fc1(x))

       x = F.relu(self.fc2(x))

       x = self.fc3(x)

       return x

MNIST圖檔的尺寸為28×28×1,經過第一層卷積層和池化層後,尺寸為:

28-5/1+4 = 24, 24/2 = 12

經過第二層卷積層和池化層後,尺寸為:

12-5/1+1 = 8, 8/2 = 4 由于該池化層濾波器組個數為16,則拉伸一維數組的長度就是1644。函數forward(self, x)定義了卷積神經網絡的前向傳播過程。

net = Net()

print(net)

列印網絡:

Net(

 (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))

 (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)

 (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))

 (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)

 (fc1): Linear(in_features=256, out_features=120, bias=True)

 (fc2): Linear(in_features=120, out_features=84, bias=True)

 (fc3): Linear(in_features=84, out_features=10, bias=True)

)

整個Net結構非常直覺,可以完整、清晰地檢視我們建構的卷積神經網絡模型的結構。

4.3.5、模型優化

PyTorch中用nn.MSELoss表示均方差。 該項目是一個分類問題,是以損失函數使用交叉熵,PyTorch中用nn.CrossEntropyLoss表示交叉熵。如果是回歸問題,損失函數一般使用均方差, 在卷積神經網絡模型的反向傳播中,仍然是基于梯度下降算法來優化參數的。

梯度優化算法同樣可以應用到卷積神經網絡模型中。使用方法非常簡單,直接調用PyTorch中的torch.optim子產品即可。例如,torch.optim. RMSprop表示RMSprop優化,torch.optim.Adam表示Adam優化。

criterion = nn.CrossEntropyLoss()

optimizer = optim.Adam(net.parameters(), lr = 0.0001)   #梯度優化算法是Adam,學習率設定為0.0001

4.3.6、模型訓練

每次疊代訓練時都要先把所有梯度清零,即執行optimizer.zero_grad()。否則,梯度會累加,造成訓練錯誤和失效。PyTorch中的.backward()可自動完成所有梯度計算。

num_epoches = 5                 #設定epoch 數目

cost = []                       #損失函數累

for epoch in range(num_epoches):

   running_loss = 0.0

   for i, data in enumerate(trainloader, 0):

       inputs, labels = data    #輸入樣本和标簽

       optimizer.zero_grad()    #每次訓練梯度清零

       # 正向傳播、反向傳播和優化過程

       outputs = net(inputs)

       loss = criterion(outputs, labels)

       loss.backward()

       optimizer.step()

       running_loss += loss.item()

       if (i+1) % 2000 == 0:  # 每隔2000個小批量樣本列印一次

           print('[epoch: %d, mini-batch: %5d] loss: %.3f' %

           (epoch + 1, i + 1, running_loss / 2000))

           cost.append(running_loss / 2000)

           running_loss = 0.0

訓練結果:

[epoch: 1, mini-batch:  2000] loss: 1.032

[epoch: 1, mini-batch:  4000] loss: 0.424

[epoch: 1, mini-batch:  6000] loss: 0.339

[epoch: 1, mini-batch:  8000] loss: 0.272

...

[epoch: 5, mini-batch: 10000] loss: 0.049

[epoch: 5, mini-batch: 12000] loss: 0.056

[epoch: 5, mini-batch: 14000] loss: 0.044

4.3.7、模型預測

訓練集驗證

correct = 0

total = 0

with torch.no_grad():

   for data in trainloader:

       images, labels = data

       outpus = net(images)

       _,predicted = torch.max(outpus.data, 1)

       total += labels.size(0)

       correct += (predicted == labels).sum().item()

print('Accuracy on the 60000 train images: %.3f %%' % (100 * correct / total))

訓練精度結果:

Accuracy on the 10000 test images: 98.370 %

4.3.8、測試代碼

快速體驗請直接下載下傳完整測試代碼 lenet5.ipynb