scratch少兒編程網(wǎng)站如何開通網(wǎng)站
pytorch完整的模型訓練流程
- 1. 流程
- 1. 整理訓練數(shù)據(jù) 使用CIFAR10數(shù)據(jù)集
- 2. 搭建網(wǎng)絡結構
- 3. 構建損失函數(shù)
- 4. 使用優(yōu)化器
- 5. 訓練模型
- 6. 測試數(shù)據(jù) 計算模型預測正確率
- 7. 保存模型
- 2. 代碼
- 1. model.py
- 2. train.py
- 3. 結果
- tensorboard結果
- 以下圖片 顏色較淺的線是真實計算的值,顏色較深的線是做了平滑處理的值
- 訓練loss
- 測試loss
- 測試集正確率
- 4. 需要注意的細節(jié)
1. 流程
1. 整理訓練數(shù)據(jù) 使用CIFAR10數(shù)據(jù)集
train_data = torchvision.datasets.CIFAR10(root='./dataset', train=True, transform=torchvision.transforms.ToTensor(),download=True)
2. 搭建網(wǎng)絡結構
model.py
3. 構建損失函數(shù)
loss_fn = nn.CrossEntropyLoss()
4. 使用優(yōu)化器
learing_rate = 1e-2 # 0.01
optimizer = torch.optim.SGD(net.parameters(), lr=learing_rate)
5. 訓練模型
output = net(imgs) # 數(shù)據(jù)輸入模型
loss = loss_fn(output, targets) # 損失函數(shù)計算損失 看計算的輸出和真實的標簽誤差是多少
# 優(yōu)化器開始優(yōu)化模型 1.梯度清零 2.反向傳播 3.參數(shù)優(yōu)化
optimizer.zero_grad() # 利用優(yōu)化器把梯度清零 全部設置為0
loss.backward() # 設置計算的損失值的鉤子,調(diào)用損失的反向傳播,計算每個參數(shù)結點的參數(shù)
optimizer.step() # 調(diào)用優(yōu)化器的step()方法 對其中的參數(shù)進行優(yōu)化
6. 測試數(shù)據(jù) 計算模型預測正確率
output = net(imags)
# 計算測試集的正確率
preds = (output.argmax(1)==targets).sum()
accuracy += preds
rate = accuracy/len(test_data)
調(diào)用模型輸出tensor 數(shù)據(jù)類型的 argmax方法, argmax或獲取一行或者一列數(shù)值中最大數(shù)值的下標位置,argmax(0) 是從列的維度取一列數(shù)值的最大值的下標,argmax(1) 是從行的維度取一行數(shù)值的最大值的下標
output.argmax(1)==targets 會輸出如下圖最后一行 [false, ture], 對應位置相同則為true,對應位置不同則為false;
調(diào)用sum()方法,計算求和,false值為0,true值為1.
最后計算得出測試集整體正確率: rate = accuracy/len(test_data)
7. 保存模型
torch.save(net, './net_epoch{}.pth'.format(i))
2. 代碼
1. model.py
import torch
from torch import nn# 2. 搭建模型網(wǎng)絡結構--神經(jīng)網(wǎng)絡
class Cifar10Net(nn.Module):def __init__(self):super(Cifar10Net, self).__init__()self.net = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=32, kernel_size=5, stride=1, padding=2),nn.MaxPool2d(kernel_size=2),nn.Conv2d(32, 32, 5, 1, 2),nn.MaxPool2d(kernel_size=2),nn.Conv2d(32, 64, 5, 1, 2),nn.MaxPool2d(kernel_size=2),nn.Flatten(),nn.Linear(64*4*4, 64),nn.Linear(64, 10))def forward(self, x):x = self.net(x)return xif __name__ == '__main__':net = Cifar10Net()input = torch.ones((64, 3, 32, 32))output = net(input)print(output.shape)
2. train.py
import torch
import torchvision
from torch import nn
from torch.utils.tensorboard import SummaryWriterfrom p24_model import *# 1. 準備數(shù)據(jù)集
# 訓練數(shù)據(jù)
from torch.utils.data import DataLoadertrain_data = torchvision.datasets.CIFAR10(root='./dataset', train=True, transform=torchvision.transforms.ToTensor(),download=True)
# 測試數(shù)據(jù)
test_data = torchvision.datasets.CIFAR10(root='./dataset', train=False, transform=torchvision.transforms.ToTensor(),download=True)# 查看數(shù)據(jù)大小--size
print("訓練數(shù)據(jù)集大小:", len(train_data))
print("測試數(shù)據(jù)集大小:", len(test_data))
# 利用DataLoader來加載數(shù)據(jù)集
train_loader = DataLoader(dataset=train_data, batch_size=64)
test_loader = DataLoader(dataset=test_data, batch_size=64)# 2. 導入模型結構 創(chuàng)建模型
net = Cifar10Net()# 3. 創(chuàng)建損失函數(shù) 分類問題--交叉熵
loss_fn = nn.CrossEntropyLoss()# 4. 創(chuàng)建優(yōu)化器
# learing_rate = 0.01
# 1e-2 = 1 * 10^(-2) = 0.01
learing_rate = 1e-2
print(learing_rate)
optimizer = torch.optim.SGD(net.parameters(), lr=learing_rate)# 設置訓練網(wǎng)絡的一些參數(shù)
epoch = 10 # 記錄訓練的輪數(shù)
total_train_step = 0 # 記錄訓練的次數(shù)
total_test_step = 0 # 記錄測試的次數(shù)# 利用tensorboard顯示訓練loss趨勢
writer = SummaryWriter('./train_logs')for i in range(epoch):# 訓練步驟開始net.train() # 可以加可以不加 只有當模型結構有 Dropout BatchNorml層才會起作用for data in train_loader:imgs, targets = data # 獲取數(shù)據(jù)output = net(imgs) # 數(shù)據(jù)輸入模型loss = loss_fn(output, targets) # 損失函數(shù)計算損失 看計算的輸出和真實的標簽誤差是多少# 優(yōu)化器開始優(yōu)化模型 1.梯度清零 2.反向傳播 3.參數(shù)優(yōu)化optimizer.zero_grad() # 利用優(yōu)化器把梯度清零 全部設置為0loss.backward() # 設置計算的損失值,調(diào)用損失的反向傳播,計算每個參數(shù)結點的參數(shù)optimizer.step() # 調(diào)用優(yōu)化器的step()方法 對其中的參數(shù)進行優(yōu)化# 優(yōu)化一次 認為訓練了一次total_train_step += 1if total_train_step % 100 == 0:print('訓練次數(shù): {} loss: {}'.format(total_train_step, loss))# 直接打印loss是tensor數(shù)據(jù)類型,打印loss.item()是打印的int或float真實數(shù)值, 真實數(shù)值方便做數(shù)據(jù)可視化【損失可視化】# print('訓練次數(shù): {} loss: {}'.format(total_train_step, loss.item()))writer.add_scalar('train-loss', loss.item(), global_step=total_train_step)# 利用現(xiàn)有模型做模型測試# 測試步驟開始total_test_loss = 0accuracy = 0net.eval() # 可以加可以不加 只有當模型結構有 Dropout BatchNorml層才會起作用with torch.no_grad():for data in test_loader:imags, targets = dataoutput = net(imags)loss = loss_fn(output, targets)total_test_loss += loss.item()# 計算測試集的正確率preds = (output.argmax(1)==targets).sum()accuracy += preds# writer.add_scalar('test-loss', total_test_loss, global_step=i+1)writer.add_scalar('test-loss', total_test_loss, global_step=total_test_step)writer.add_scalar('test-accracy', accuracy/len(test_data), total_test_step)total_test_step += 1print("---------test loss: {}--------------".format(total_test_loss))print("---------test accuracy: {}--------------".format(accuracy))# 保存每一個epoch訓練得到的模型torch.save(net, './net_epoch{}.pth'.format(i))writer.close()
3. 結果
訓練數(shù)據(jù)集大小: 50000
測試數(shù)據(jù)集大小: 10000
0.01
訓練次數(shù): 100 loss: 2.2905373573303223
訓練次數(shù): 200 loss: 2.2878968715667725
訓練次數(shù): 300 loss: 2.258394718170166
訓練次數(shù): 400 loss: 2.1968581676483154
訓練次數(shù): 500 loss: 2.0476632118225098
訓練次數(shù): 600 loss: 2.002145767211914
訓練次數(shù): 700 loss: 2.016021728515625
---------test loss: 316.382279753685--------------
訓練次數(shù): 800 loss: 1.8957302570343018
訓練次數(shù): 900 loss: 1.8659226894378662
訓練次數(shù): 1000 loss: 1.9004186391830444
訓練次數(shù): 1100 loss: 1.9708642959594727
......
tensorboard結果
安裝tensorboard運行環(huán)境
pip install tensorboard
pip install opencv-python
pip install six
tensorboard --logdir=train_logs
以下圖片 顏色較淺的線是真實計算的值,顏色較深的線是做了平滑處理的值
訓練loss
測試loss
測試集正確率
4. 需要注意的細節(jié)
https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module
所有網(wǎng)絡層繼承于torch.nn.Module, net.train() net.eval() 在模型訓練或測試之初 可以加可以不加 只有當模型結構有 Dropout BatchNorml層才會起作用,當模型有這兩個網(wǎng)絡層的時候,兩個代碼需要加上。