1. 程式人生 > >Pytorch進行MNIST分類總結

Pytorch進行MNIST分類總結

Pytorch進行分類任務總結

作為Pytorch初學者,利用MNIST資料集作為基本資料集,使用Pytorch進行搭建模型訓練,本文件目的在記錄Pytorch進行深度學習系統搭建流程,使用時能隨時查閱。

文章目錄

1. 資料獲取

匯入必要的庫

import numpy as
np import torch from torchvision.datasets import mnist # 匯入 pytorch 內建的 mnist 資料 from torch import nn from torch.autograd import Variable
def data_tf(x):
    x = np.array(x, dtype='float32') / 255
    x = (x - 0.5) / 0.5 # 標準化處理
    x = x.reshape((-1,)) # 拉平
    x = torch.from_numpy(x)
    return x

train_set =
mnist.MNIST('data/mnist', train=True, transform=data_tf, download=False) # 載入資料集,申明定義的資料變換 test_set = mnist.MNIST('data/mnist', train=False, transform=data_tf, download=False)

可以先將MNIST資料集下載到本地,直接匯入資料即可,本文建立的是全連線網路,因此輸入影象資料需要實用reshape拉成一個一維向量。

資料量太大時,使用資料迭代器,每次生成一個批次的資料。

from torch.utils.data import
DataLoader # 使用 pytorch 自帶的 DataLoader 定義一個數據迭代器 train_data = DataLoader(train_set, batch_size=64, shuffle=True) test_data = DataLoader(test_set, batch_size=128, shuffle=False)

獲取一個批次的資料命令:

data, data_label = next(iter(train_data))

2.模型定義

Pytorch 中支援兩種方式構建模型:Sequential和Module

使用Sequential建立模型

# 使用 Sequential 定義 4 層神經網路
net = nn.Sequential(
    nn.Linear(784, 400),
    nn.ReLU(),
    nn.Linear(400, 200),
    nn.ReLU(),
    nn.Linear(200, 100),
    nn.ReLU(),
    nn.Linear(100, 10)
)
#檢視網路結構
print(net)

3.損失函式和優化器設定

定義損失函式:

Pytorch中提供了一些常用的損失函式

criterion = nn.CrossEntropyLoss()

定義優化器:

optimizer = torch.optim.SGD(net.parameters(), 1e-1) # 使用隨機梯度下降,學習率 0.1

4.模型訓練,驗證

開始模型訓練

# 開始訓練
losses = [] #記錄訓練誤差,用於作圖分析
acces = []
eval_losses = []
eval_acces = []

for e in range(20):
    train_loss = 0
    train_acc = 0
    net.train()
    for im, label in train_data:
        im = Variable(im)
        label = Variable(label)
        # 前向傳播
        out = net(im)
        loss = criterion(out, label)
        # 反向傳播
        ## 梯度清零
        optimizer.zero_grad()
        ## 梯度反向傳播
        loss.backward()
        ## 引數更新
        optimizer.step()
        # 記錄誤差
        train_loss += float(loss)
        # 計算分類的準確率
        _, pred = out.max(1)
        num_correct = (pred == label).sum()
        acc = int(num_correct) / im.shape[0]
        train_acc += acc
        
    losses.append(train_loss / len(train_data))
    acces.append(train_acc / len(train_data))
    
    # 在測試集上檢驗效果
    eval_loss = 0
    eval_acc = 0
    net.eval() # 將模型改為預測模式
    for im, label in test_data:
        im = Variable(im)
        label = Variable(label)
        out = net(im)
        loss = criterion(out, label)
        # 記錄誤差
        eval_loss += float(loss)
        # 記錄準確率
        _, pred = out.max(1)
        num_correct = (pred == label).sum()
        acc = int(num_correct) / im.shape[0]
        eval_acc += acc
        
    eval_losses.append(eval_loss / len(test_data))
    eval_acces.append(eval_acc / len(test_data))
    print('epoch: {}, Train Loss: {:.6f}, Train Acc: {:.6f}, Eval Loss: {:.6f}, Eval Acc: {:.6f}'
          .format(e, train_loss / len(train_data), train_acc / len(train_data), 
                     eval_loss / len(test_data), eval_acc / len(test_data)))

5.acc和loss視覺化

上述模型訓練完成後,可將保持的loss和accy通過作圖直觀的顯示出來,如下是單獨顯示,也可以放在一張圖上顯示;

import matplotlib.pyplot as plt
%matplotlib inline
plt.title('train loss')
plt.plot(np.arange(len(losses)), losses)
plt.plot(np.arange(len(acces)), acces)
plt.title('train acc')

6.儲存模型

Pytorch 儲存模型提供兩種方式:一,將模型和引數都儲存在一起,二,只將引數儲存下來。

  1. 將模型和引數儲存在一起
# 將引數和模型儲存在一起
torch.save(net, 'save_net.pth')

​ 載入剛剛儲存的模型和引數:

# 讀取儲存的模型
seq_net1 = torch.load('save_net.pth')
  1. 儲存模型引數
# 儲存模型引數
torch.save(net.state_dict(), 'save_net_params.pth')

​ 載入模型引數,注意:載入模型引數之前需要重新定義一次模型:

net2.load_state_dict(torch.load('save_net_params.pth')) #net2為新定義的模型

7.模型和引數檢視

檢視模型的每一層:

#方法一
print(net)
#方法二
for layer in net:
    print(layer)

檢視模型的引數:

#檢視第1層的weight
net[0].weight
#檢視第1層的bias
net[0].bias

8.參考

  1. https://pytorch-cn.readthedocs.io/zh/latest/#pytorch
  2. https://github.com/L1aoXingyu/pytorch-beginner

如有問題,請指正,謝謝!