1. 程式人生 > 其它 >在MATPool矩池雲完成Pytorch訓練MNIST資料集

在MATPool矩池雲完成Pytorch訓練MNIST資料集

本文為矩池雲入門手冊的補充:Pytorch訓練MNIST資料集程式碼執行過程。

案例程式碼和對應資料集,以及在矩池雲上的詳細操作可以在矩池雲入門手冊中檢視,本文基於矩池雲入門手冊,預設使用者已經完成了機器租用,上傳解壓好了資料、程式碼,並使用jupyter lab進行程式碼執行。

在MATPool矩池雲完成Pytorch訓練MNIST資料集

1. 安裝自己需要的第三方包

以tqdm包為例子,如果在執行程式碼過程出現了ModuleNotFoundError: No module named 'tqdm',說明我們選擇的系統映象中沒有預裝這個包,我們只需要再JupyterLab的Terminal輸入pip install tqdm

即可安裝相關包。

其他自己需要的第三方包安裝方法也類似。

2. 在JupyterLab中執行程式碼

JupyterLab目錄裡面,我們依次點選mnt->MyMNIST進入到專案資料夾,在專案資料夾下雙擊pytorch_mnist.ipynb檔案,即可開啟程式碼檔案。

開啟程式碼檔案後,我們就可以直接運行了,截圖中給大家說明了幾個常用的JupyteLab 按鈕功能。

接下來我們開始執行程式碼~

2.1 匯入需要的Python包

首先執行下面程式碼匯入需要的模組,如:

  • pytorch相關:torch、torchvision
  • 訓練輸出進度條視覺化顯示:tqdm
  • 訓練結果圖表視覺化顯示:matplotlib.pyplot
# 匯入相關包
# 測試環境 K80 pytorch1.10
import torch
import torchvision 
from tqdm import tqdm
import matplotlib.pyplot as plt

測試下機器中的pytorch版本和GPU是否可用。

# 檢視pytorch版本和gpu是否可用
print(torch.__version__)
print(torch.cuda.is_available())

'''
輸出:
1.10.0+cu113
True 
'''

上面輸出表示pytorch版本為1.10.0,機器GPU可用。

2.2 資料預處理
設定device、BATCH_SIZE和EPOCHS

# 如果網路能在GPU中訓練,就使用GPU;否則使用CPU進行訓練
device = "cuda:0" if torch.cuda.is_available() else "cpu"

# 這個函式包括了兩個操作:將圖片轉換為張量,以及將圖片進行歸一化處理
transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor(),
                                torchvision.transforms.Normalize(mean = [0.5],std = [0.5])])
                                
# 設定了每個包中的圖片資料個數
BATCH_SIZE = 64
EPOCHS = 10

載入構建訓練和測試資料集

# 從專案檔案中載入訓練資料和測試資料
train_dataset = torchvision.datasets.MNIST('/mnt/MyMNIST/',train = True,transform = transform)
test_dataset = torchvision.datasets.MNIST('/mnt/MyMNIST/',train = False,transform = transform)

# 建立一個數據迭代器
# 裝載訓練集
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                           batch_size=BATCH_SIZE,
                                           shuffle=True)
# 裝載測試集
test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                          batch_size=BATCH_SIZE,
                                          shuffle=True)

2.3 構建資料訓練模型並建立例項
構建資料訓練模型

# 一個簡單的卷積神經網路
class Net(torch.nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.model = torch.nn.Sequential(
            #The size of the picture is 28x28
            torch.nn.Conv2d(in_channels = 1,out_channels = 16,kernel_size = 3,stride = 1,padding = 1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size = 2,stride = 2),
            
            #The size of the picture is 14x14
            torch.nn.Conv2d(in_channels = 16,out_channels = 32,kernel_size = 3,stride = 1,padding = 1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size = 2,stride = 2),
            
            #The size of the picture is 7x7
            torch.nn.Conv2d(in_channels = 32,out_channels = 64,kernel_size = 3,stride = 1,padding = 1),
            torch.nn.ReLU(),
            
            torch.nn.Flatten(),
            torch.nn.Linear(in_features = 7 * 7 * 64,out_features = 128),
            torch.nn.ReLU(),
            torch.nn.Linear(in_features = 128,out_features = 10),
            torch.nn.Softmax(dim=1)
        )
        
    def forward(self,input):
        output = self.model(input)
        return output

構建模型例項

# 構建模型例項
net = Net()
# 將模型轉換到device中,並將其結構顯示出來
print(net.to(device))

2.4 構建迭代器與損失函式

# 交叉熵損失來作為損失函式
# Adam迭代器
loss_fun = torch.nn.CrossEntropyLoss() 
optimizer = torch.optim.Adam(net.parameters())

2.5 構建並執行訓練迴圈

history = {'Test Loss':[],'Test Accuracy':[]}
for epoch in range(1,EPOCHS + 1):
    process_bar = tqdm(train_loader,unit = 'step')
    net.train(True)
    for step,(train_imgs,labels) in enumerate(process_bar):
        train_imgs = train_imgs.to(device)
        labels = labels.to(device)

        net.zero_grad()
        outputs = net(train_imgs)
        loss = loss_fun(outputs,labels)
        predictions = torch.argmax(outputs, dim = 1)
        accuracy = torch.true_divide(torch.sum(predictions == labels), labels.shape[0])
        loss.backward()

        optimizer.step()
        process_bar.set_description("[%d/%d] Loss: %.4f, Acc: %.4f" % 
                                   (epoch,EPOCHS,loss.item(),accuracy.item()))

        if step == len(process_bar)-1:
            correct,total_loss = 0,0
            net.train(False)
            with torch.no_grad():
                for test_imgs,labels in test_loader:
                    test_imgs = test_imgs.to(device)
                    labels = labels.to(device)
                    outputs = net(test_imgs)
                    loss = loss_fun(outputs,labels)
                    predictions = torch.argmax(outputs,dim = 1)

                    total_loss += loss
                    correct += torch.sum(predictions == labels)

                test_accuracy = torch.true_divide(correct, (BATCH_SIZE * len(test_loader)))
                test_loss = torch.true_divide(total_loss, len(test_loader))
                history['Test Loss'].append(test_loss.item())
                history['Test Accuracy'].append(test_accuracy.item())

            process_bar.set_description("[%d/%d] Loss: %.4f, Acc: %.4f, Test Loss: %.4f, Test Acc: %.4f" % 
                                   (epoch,EPOCHS,loss.item(),accuracy.item(),test_loss.item(),test_accuracy.item()))
    process_bar.close()

2.6 訓練結果視覺化

#對測試Loss進行視覺化
plt.plot(history['Test Loss'],label = 'Test Loss')
plt.legend(loc='best')
plt.grid(True)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

#對測試準確率進行視覺化
plt.plot(history['Test Accuracy'],color = 'red',label = 'Test Accuracy')
plt.legend(loc='best')
plt.grid(True)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.show()

2.7 儲存模型

# 儲存訓練好的模型
torch.save(net,'/mnt/MyMNIST/torch_mnist_model.pth')

儲存成功後,JupyterLab 中對應資料夾會出現該檔案,在矩池雲網盤對應目錄下也會存在。


參考文章