训练方法
Mini-batch训练方法将整个训练数据集划分为多个小批量(mini-batches),每个小批量包含一定数量的样本。在训练过程中,模型依次对每个mini-batch进行前向传播以计算输出和损失,然后通过反向传播计算梯度,并根据这些梯度更新模型参数。这样循环进行,直到所有mini-batch均被遍历完。
优缺点
使用mini-batch训练的主要原因是它结合了全批量训练和随机梯度下降的优点,能够在加速收敛的同时提高模型的泛化能力。相比于全批量训练,mini-batch训练在每次参数更新时考虑到部分数据,能够更频繁地调整学习方向,且引入的随机性使得模型更有可能逃离局部最优解。然而,选择不当的batch size可能导致训练过程的不稳定,甚至影响最终模型的性能。
Batch Size的选择方法
选择合适的batch size通常取决于可用的计算资源和具体任务的性质。一般来说,可以从常用的大小(如32、64、128等)开始尝试,通过实验观察模型的训练速度和性能。如果内存允许,可以尝试较大的batch size以加快训练速度;如果面临过拟合问题,则可以考虑减小batch size,同时注意监测训练和验证的损失曲线,以便找到最佳的batch size。
示例
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 定义超参数
batch_size = 64 # 每个mini-batch的大小
epochs = 5 # 训练的轮数
# 数据预处理:将MNIST数据集中的图片转换为Tensor并进行归一化
transform = transforms.Compose([
transforms.ToTensor(), # 转换为Tensor格式
transforms.Normalize((0.5,), (0.5,)) # 归一化到[-1, 1]
])
# 下载并加载训练和测试数据集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
# 使用DataLoader创建mini-batch数据加载器
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# 定义神经网络模型,使用nn.Sequential
model = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3), # 卷积层:输入通道1,输出通道32,卷积核大小3
nn.ReLU(), # ReLU激活函数
nn.MaxPool2d(kernel_size=2), # 池化层:2x2最大池化
nn.Flatten(), # 展平操作
nn.Linear(32 * 13 * 13, 64), # 全连接层:输入特征数为32*13*13,输出特征数为64
nn.ReLU(), # ReLU激活函数
nn.Linear(64, 10) # 输出层:10个类(数字0-9)
)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss() # 损失函数
optimizer = optim.Adam(model.parameters()) # 优化器
# 训练模型
for epoch in range(epochs):
model.train() # 设置模型为训练模式
running_loss = 0.0
for images, labels in train_loader:
optimizer.zero_grad() # 清空梯度
outputs = model(images) # 前向传播
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新模型参数
running_loss += loss.item() # 累加损失
print(f'Epoch [{epoch+1}/{epochs}], Loss: {running_loss/len(train_loader):.4f}')
# 测试模型
model.eval() # 设置模型为评估模式
total_correct = 0
with torch.no_grad(): # 不需要计算梯度
for images, labels in test_loader:
outputs = model(images) # 前向传播
_, predicted = torch.max(outputs.data, 1) # 获取预测结果
total_correct += (predicted == labels).sum().item() # 统计正确预测的数量
# 输出测试准确率
test_accuracy = total_correct / len(test_dataset)
print(f'Test accuracy: {test_accuracy:.4f}')
前一种是土方法,主要是为了演示其原理,一般在load数据的时候分批次加载训练