模型训练基础流程
深度学习模型训练核心流程(5 步)
-
数据准备
加载数据集 → 划分训练集 / 测试集 → 创建数据加载器(批处理)。 -
模型定义
设计网络结构(如 CNN) → 初始化模型参数。 -
训练配置
选择损失函数(如交叉熵) → 选择优化器(如 SGD) → 设置超参数(学习率、Epoch)。 -
训练循环
for epoch in range(epochs): # 训练 for data in train_dataloader: 前向传播 → 计算损失 → 反向传播 → 优化器更新参数 # 测试(每轮结束后) with torch.no_grad(): for data in test_dataloader: 前向传播 → 计算损失(不更新参数) -
模型保存与监控
保存模型(每轮或最优) → 使用 TensorBoard 等工具记录训练指标(损失、准确率)。
模型:
# 搭建神经网络
import torch
from torch import nn
class MyModule(nn.Module):
def __init__(self):
super().__init__()
self.module = 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.module(x)
return x
# 测试网络
if __name__ == '__main__':
model = MyModule()
input = torch.ones((64, 3, 32, 32))
output = model(input)
print(output.shape)
训练:
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from model import *
train_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,
transform=torchvision.transforms.ToTensor(),
download=True)
test_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,
transform=torchvision.transforms.ToTensor(),
download=False)
# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))
# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
# 创建网络模型
model = MyModule()
# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 设置训练网络的一些参数
# 训练次数
total_train_step = 0
# 测试次数
total_test_step = 0
# 训练轮数
epoch = 10
# 添加tensorboard
writer = SummaryWriter("logs")
for i in range(epoch):
print("---------第{}轮训练开始---------".format(i + 1))
# 训练
for data in train_dataloader:
imgs, targets = data
outputs = model(imgs)
loss = loss_fn(outputs, targets)
# 优化器优化模型
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
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
outputs = model(imgs)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item()
print("整体测试集上的loss:{}", format(total_test_loss))
writer.add_scalar("test_sum_loss", total_test_loss, total_test_step)
total_test_step = total_test_step + 1
# 保存每一次训练的结果
torch.save(model, "model_{}.pth".format(i))
print("模型已保存")
writer.close()
强调流程:
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriterfrom model import *
准备数据集
train_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,
transform=torchvision.transforms.ToTensor(),
download=True)test_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,
transform=torchvision.transforms.ToTensor(),
download=False)# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用DataLoader来加载数据集
加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
model = MyModule()# 损失函数
loss_fn = nn.CrossEntropyLoss()# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 训练次数
total_train_step = 0
# 测试次数
total_test_step = 0
# 训练轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("logs")
for i in range(epoch):
print("---------第{}轮训练开始---------".format(i + 1))# 训练
for data in train_dataloader:
imgs, targets = data 数据准备
outputs = model(imgs) 训练结果
loss = loss_fn(outputs, targets) 计算损失# 优化器优化模型
optimizer.zero_grad() 梯度清空
loss.backward() 反向传播
optimizer.step() 优化器工作(链式法则 计算梯度 优化参数)
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
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 数据准备
outputs = model(imgs) 训练结果
loss = loss_fn(outputs, targets) 计算损失
total_test_loss = total_test_loss + loss.item() 计算损失和print("整体测试集上的loss:{}", format(total_test_loss))
writer.add_scalar("test_sum_loss", total_test_loss, total_test_step)
total_test_step = total_test_step + 1# 保存每一次训练的结果
torch.save(model, "model_{}.pth".format(i)) 保存训练结果
print("模型已保存")writer.close()
运行后的目录列表:
Tensorboard的记录结果:

上述是通过 计算测试数据的损失函数的值的和,来判断训练的效果
适合 回归任务,生成任务等
若是分类等任务,用正确率来判断较合适:
分类问题的测试(看预测的准确率):
如输入两张图片

1.先把 输出的概率tensor形式变成预测对应的结果preds(用Argmax函数)
2.在和各个的targets进行比较,得到true/false的列表
3.求这个列表的和 true=1,false=0
Argmax 函数:
argmax 函数(argument of the maximum)是一种常用的数学函数,核心作用是返回数组(或序列)中最大值所在的 “位置索引”,而非最大值本身。
-
“arg” 表示 “参数”(即位置索引),“max” 表示 “最大值”,合起来就是 “最大值对应的参数(索引)”。
-
例如:对于数组
[3, 1, 5, 2],最大值是 5,它在数组中的索引是 2(从 0 开始计数),因此argmax([3, 1, 5, 2]) = 2。
关键细节:索引规则与多维数组
索引从 0 开始
在编程(如 Python、NumPy)中,数组索引默认从 0 开始,argmax 返回的索引也遵循这一规则。
例:arr = [10, 20, 5] → argmax(arr) = 1(因为 20 是最大值,位于索引 1
argmax 函数:定义与核心作用
argmax 函数(argument of the maximum)是一种常用的数学函数,核心作用是返回数组(或序列)中最大值所在的 “位置索引”,而非最大值本身。
-
“arg” 表示 “参数”(即位置索引),“max” 表示 “最大值”,合起来就是 “最大值对应的参数(索引)”。
-
例如:对于数组
[3, 1, 5, 2],最大值是 5,它在数组中的索引是 2(从 0 开始计数),因此argmax([3, 1, 5, 2]) = 2。
关键细节:索引规则与多维数组
-
索引从 0 开始
在编程(如 Python、NumPy)中,数组索引默认从 0 开始,argmax 返回的索引也遵循这一规则。
例:arr = [10, 20, 5]→argmax(arr) = 1(因为 20 是最大值,位于索引 1)。 -
多维数组的处理
对于二维及以上的数组,argmax 可以指定 “轴(axis)”,返回对应轴上最大值的索引。
例:二维数组[[3, 7], [2, 8]]-
若按行(axis=1)计算:每行的最大值索引分别是 1(第一行 7 在索引 1)和 1(第二行 8 在索引 1),结果为
[1, 1]。 -
若按列(axis=0)计算:每列的最大值索引分别是 0(第一列 3>2)和 1(第二列 8>7),结果为
[0, 1]。
-
代码案例:


上述代码修改为用准确率看训练效果:
# 测试过程中,参数不需要调整了,临时把梯度去除 total_test_loss = 0 total_accuracy = 0 with torch.no_grad(): for data in test_dataloader: imgs, targets = data outputs = model(imgs) loss = loss_fn(outputs, targets) total_test_loss = total_test_loss + loss.item() accuracy = (outputs.argmax(1) == targets).sum() total_accuracy = total_accuracy + accuracy # 预测对的总数量 print("整体测试集上的loss:{}", format(total_test_loss)) print("整体测试集上的准确率:{}", format(total_accuracy / test_data_size)) # 准确率 writer.add_scalar("test_sum_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
Tensorboard的记录结果:
一个要点
在一些训练时候会用model.train() 和 model.eval()两个方法表示阶段
for i in range(epoch):
print("---------第{}轮训练开始---------".format(i + 1))
# 训练
model.train()
for data in train_dataloader:
imgs, targets = data
outputs = model(imgs)
loss = loss_fn(outputs, targets)
# 优化器优化模型
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_train_step = total_train_step + 1
if total_train_step % 100 == 0:
print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
writer.add_scalar("train_loss", loss.item(), total_train_step)
# 评估模型训练效果 - 跑一个测试数据查看正确率
# 测试过程中,参数不需要调整了,临时把梯度去除
model.eval()
total_test_loss = 0
total_accuracy = 0
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
outputs = model(imgs)
loss = loss_fn(outputs, targets)
total_test_loss = total_test_loss + loss.item()
accuracy = (outputs.argmax(1) == targets).sum()
total_accuracy = total_accuracy + accuracy # 预测对的总数量
在 PyTorch 中,model.train() 和 model.eval() 是用于切换模型 “训练模式” 和 “评估模式” 的核心方法。它们的本质作用是控制模型中特定层的行为(如 Dropout、BatchNorm),以适配 “训练” 和 “评估” 两个不同阶段的需求。
但不是必须的,在有需要管理的层时候必须要有
如:
一、依赖训练 / 评估模式的层
-
Dropout 层(含 Dropout1d、Dropout2d 等)
-
Batch Normalization 层(含 BatchNorm1d、BatchNorm2d 等)
-
DropPath 层(随机路径丢弃)
二、有 “记忆” 或状态的层
-
RNN 层(循环神经网络)
-
LSTM 层(长短期记忆网络)
-
GRU 层(门控循环单元)
三、其他特殊计算逻辑的层
-
Layer Normalization 层(LayerNorm)
-
Instance Normalization 层(InstanceNorm)
-
Group Normalization 层(GroupNorm)
更多推荐
所有评论(0)