本文以 CIFAR10數(shù)據(jù)集為例,介紹一個完整的模型訓練套路。
CIFAR10數(shù)據(jù)集簡介
CIFAR-10數(shù)據(jù)集包含60000張32x32彩色圖像,分為10個類,每類6000張。有50000張訓練圖片和10000張測試圖片。
數(shù)據(jù)集分為五個訓練batches和一個測試batch,每個batch有10000張圖像。測試batch包含從每個類中隨機選擇的1000個圖像。訓練batches以隨機順序包含剩余的圖像,但有些訓練batches可能包含一個類的圖像多于另一個類的圖像。在它們之間,訓練batches包含來自每個類的5000張圖像。
下面是數(shù)據(jù)集中的類,以及每個類的10張隨機圖片:
一共包含10 個類別的RGB 彩色圖片:飛機( airplane )、汽車( automobile )、鳥類( bird )、貓( cat )、鹿( deer )、狗( dog )、蛙類( frog )、馬( horse )、船( ship )和卡車( truck )。
訓練模型套路
1、準備數(shù)據(jù)集
# 準備數(shù)據(jù)集
train_data = torchvision.datasets.CIFAR10(root="./source", train=True, transform=torchvision.transforms.ToTensor(), download=True)
test_data = torchvision.datasets.CIFAR10(root="./source", train=False, transform=torchvision.transforms.ToTensor(), download=True)
# length 長度
train_data_size = len(train_data)
test_data_size = len(test_data)
print(f"訓練數(shù)據(jù)集的長度為:{train_data_size}")
print(f"測試數(shù)據(jù)集的長度為:{test_data_size}")
2、加載數(shù)據(jù)集
# 利用 DataLoader 來加載數(shù)據(jù)集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
3、搭建神經(jīng)網(wǎng)絡(luò)
我們準備搭建一個這樣的網(wǎng)絡(luò)模型結(jié)構(gòu):
# 搭建神經(jīng)網(wǎng)絡(luò)
class Aniu(nn.Module):
def __init__(self):
super(Aniu, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
if __name__ == '__main__':
aniu = Aniu()
input = torch.ones((64, 3, 32, 32))
output = aniu(input)
print(output.shape)
我們在一個新的文件下搭建并簡單測試神經(jīng)網(wǎng)絡(luò)。
4、創(chuàng)建網(wǎng)絡(luò)模型、定義損失函數(shù)、優(yōu)化器
# 創(chuàng)建網(wǎng)絡(luò)模型
aniu = Aniu()
# 損失函數(shù)
loss_fn = nn.CrossEntropyLoss()
# 優(yōu)化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(aniu.parameters(), lr=learning_rate)
5、訓練網(wǎng)絡(luò)
# 設(shè)置訓練網(wǎng)絡(luò)的一些參數(shù)
# 記錄訓練的次數(shù)
total_train_step = 0
# 記錄測試的次數(shù)
total_test_step = 0
# 訓練的輪數(shù)
epoch = 10
for i in range(epoch):
print(f"----------第{i+1}輪訓練開始-----------")
# 訓練開始
for data in train_dataloader:
imgs, targets = data
output = aniu(imgs)
loss = loss_fn(output, targets)
# 優(yōu)化器優(yōu)化模型
optimizer.zero_grad() # 優(yōu)化器梯度清零
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
print(f"訓練次數(shù):{total_train_step},loss:{loss.item()}") # .item()可以將tensor數(shù)據(jù)類型轉(zhuǎn)化
6、測試數(shù)據(jù)集
我們可以通過with torch.mo_grad():
來測試
for i in range(epoch):
print(f"----------第{i+1}輪訓練開始-----------")
# 訓練開始
for data in train_dataloader:
imgs, targets = data
output = aniu(imgs)
loss = loss_fn(output, targets)
# 優(yōu)化器優(yōu)化模型
optimizer.zero_grad() # 優(yōu)化器梯度清零
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print(f"訓練次數(shù):{total_train_step},loss:{loss.item()}") # .item()可以將tensor數(shù)據(jù)類型轉(zhuǎn)化
# 測試步驟開始
total_test_loss = 0
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
output = aniu(imgs)
loss = loss_fn(output, targets)
total_test_loss = total_test_loss + loss.item()
print(f"整體測試集上的Loss:{total_test_loss}")
7、添加tensorboard
我們在以上的代碼基礎(chǔ)上添加tensorboard,并通過tensorboard畫圖進行觀察:
# 添加tensorboard
writer = SummaryWriter("./log_train")
for i in range(epoch):
print(f"----------第{i+1}輪訓練開始-----------")
# 訓練開始
for data in train_dataloader:
imgs, targets = data
output = aniu(imgs)
loss = loss_fn(output, targets)
# 優(yōu)化器優(yōu)化模型
optimizer.zero_grad() # 優(yōu)化器梯度清零
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print(f"訓練次數(shù):{total_train_step},loss:{loss.item()}") # .item()可以將tensor數(shù)據(jù)類型轉(zhuǎn)化
writer.add_scalar("train_loss", loss.item(), total_train_step)
# 測試步驟開始
total_test_loss = 0
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
output = aniu(imgs)
loss = loss_fn(output, targets)
total_test_loss = total_test_loss + loss.item()
print(f"整體測試集上的Loss:{total_test_loss}")
writer.add_scalar("test_loss", total_test_loss, total_test_step)
total_test_step = total_test_step + 1
writer.close()
運行并在終端輸入:
tensorboard --logdir="log_train"
可以觀察到圖像:
8、轉(zhuǎn)化為正確率
添加一段代碼,算出測試集上的正確率:
# 整體正確的個數(shù)
total_accuracy = 0
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
output = aniu(imgs)
loss = loss_fn(output, targets)
total_test_loss = total_test_loss + loss.item()
accuracy = (output.argmax(1) == targets).sum()
total_accuracy = total_accuracy + accuracy
print(f"整體測試集上的Loss:{total_test_loss}")
print(f"整體測試集上的正確率:{total_accuracy/test_data_size}")
writer.add_scalar("test_loss", total_test_loss, total_test_step)
writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
total_test_step = total_test_step + 1
9、保存模型
每輪保存一下模型:
torch.save(aniu, f"aniu_{i}.pth")
print("模型已保存")
完整代碼
train.py文件:文章來源:http://www.zghlxwxcb.cn/news/detail-468637.html
import torch.cuda
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from model import *
# 準備數(shù)據(jù)集
train_data = torchvision.datasets.CIFAR10(root="./source", train=True,
transform=torchvision.transforms.ToTensor(), download=True)
test_data = torchvision.datasets.CIFAR10(root="./source", train=False,
transform=torchvision.transforms.ToTensor(), download=True)
# length 長度
train_data_size = len(train_data)
test_data_size = len(test_data)
print(f"訓練數(shù)據(jù)集的長度為:{train_data_size}")
print(f"測試數(shù)據(jù)集的長度為:{test_data_size}")
# 利用 DataLoader 來加載數(shù)據(jù)集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
# 創(chuàng)建網(wǎng)絡(luò)模型 搭建神經(jīng)網(wǎng)絡(luò)
class Aniu(nn.Module):
def __init__(self):
super(Aniu, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
aniu = Aniu()
# if torch.cuda.is_available():
# aniu = aniu.cuda()
# 損失函數(shù)
loss_fn = nn.CrossEntropyLoss()
# if torch.cuda.is_available():
# loss_fn = loss_fn.cuda()
# 優(yōu)化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(aniu.parameters(), lr=learning_rate)
# 設(shè)置訓練網(wǎng)絡(luò)的一些參數(shù)
# 記錄訓練的次數(shù)
total_train_step = 0
# 記錄測試的次數(shù)
total_test_step = 0
# 訓練的輪數(shù)
epoch = 10
# 添加tensorboard
writer = SummaryWriter("./log_train")
for i in range(epoch):
print(f"----------第{i+1}輪訓練開始-----------")
# 訓練開始
aniu.train()
for data in train_dataloader:
imgs, targets = data
# if torch.cuda.is_available():
# imgs = imgs.cuda()
# targets = targets.cuda()
output = aniu(imgs)
loss = loss_fn(output, targets)
# 優(yōu)化器優(yōu)化模型
optimizer.zero_grad() # 優(yōu)化器梯度清零
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print(f"訓練次數(shù):{total_train_step},loss:{loss.item()}") # .item()可以將tensor數(shù)據(jù)類型轉(zhuǎn)化
writer.add_scalar("train_loss", loss.item(), total_train_step)
# 測試步驟開始
aniu.eval()
total_test_loss = 0
# 整體正確的個數(shù)
total_accuracy = 0
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
# if torch.cuda.is_available():
# imgs = imgs.cuda()
# targets = targets.cuda()
output = aniu(imgs)
loss = loss_fn(output, targets)
total_test_loss = total_test_loss + loss.item()
accuracy = (output.argmax(1) == targets).sum()
total_accuracy = total_accuracy + accuracy
print(f"整體測試集上的Loss:{total_test_loss}")
print(f"整體測試集上的正確率:{total_accuracy/test_data_size}")
writer.add_scalar("test_loss", total_test_loss, total_test_step)
writer.add_scalar("test_accuracy", total_accuracy/test_data_size, total_test_step)
total_test_step = total_test_step + 1
# torch.save(aniu.state_dict(), f"aniu_{}.pth") 官方推薦保存方式
torch.save(aniu, f"aniu_{i}.pth")
print("模型已保存")
writer.close()
model.py:文章來源地址http://www.zghlxwxcb.cn/news/detail-468637.html
import torch
from torch import nn
# 搭建神經(jīng)網(wǎng)絡(luò)
class Aniu(nn.Module):
def __init__(self):
super(Aniu, self).__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64 * 4 * 4, 64),
nn.Linear(64, 10)
)
def forward(self, x):
x = self.model(x)
return x
if __name__ == '__main__':
aniu = Aniu()
input = torch.ones((64, 3, 32, 32))
output = aniu(input)
print(output.shape)
到了這里,關(guān)于pytorch完整模型訓練套路的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!