训练模型数据集划分
数据集通常会被划分为训练集(Training Set)、验证集(Validation Set)和测试集(Test Set),这样可以有效地训练、优化和评估模型的性能。
1. 训练集(Training Set)
- 作用:用于模型的学习,即让模型调整参数(权重和偏置)。
- 占比:一般占 60%-80% 的总数据。
- 细节:模型在这个数据集上不断计算损失 → 反向传播 → 更新参数,以最小化误差。
2. 验证集(Validation Set)
- 作用:在训练过程中监测模型的表现,用于调整超参数(如学习率、层数、神经元数量等),防止过拟合。
- 占比:一般占 10%-20% 的总数据。
- 细节:
- 训练过程中不会对验证集进行梯度更新,仅用于计算指标(如准确率、损失)。
- 用于超参数调优,选择最优模型配置。
3. 测试集(Test Set)
- 作用:在模型完全训练好后,用于最终评估模型的泛化能力。
- 占比:一般占 10%-20% 的总数据。
- 细节:
- 不能用于训练,也不能用于超参数调优,完全独立。
- 反映模型对未见过的数据的表现,确保模型不会仅仅记住训练数据(过拟合)。
为什么要区分验证集和测试集?
很多人会问:“为什么不直接用测试集来调优超参数?”
原因:
- 如果我们用测试集来调整超参数,模型就会对测试集产生信息泄露,测试集就不再是真正的未知数据,评估结果会有偏差。
- 验证集的作用是提供反馈,而测试集的作用是提供最终评分。
数据集划分方法
1. 直接划分
from sklearn.model_selection import train_test_split
# 生成示例数据
X = [[i] for i in range(1000)] # 1000 个样本
y = [i % 2 for i in range(1000)] # 二分类标签
# 先划分为训练集 + 剩余集(80% 训练,20% 剩余)
X_train, X_rem, y_train, y_rem = train_test_split(X, y, test_size=0.2, random_state=42)
# 再划分验证集和测试集(各 10%)
X_val, X_test, y_val, y_test = train_test_split(X_rem, y_rem, test_size=0.5, random_state=42)
print(f"训练集大小: {len(X_train)}, 验证集大小: {len(X_val)}, 测试集大小: {len(X_test)}")
输出:
训练集大小: 800, 验证集大小: 100, 测试集大小: 100
2. K 折交叉验证(适用于小数据集)
如果数据集较小,可以使用 K 折交叉验证(K-Fold Cross Validation):
from sklearn.model_selection import KFold
import numpy as np
X = np.array(range(100))
kf = KFold(n_splits=5, shuffle=True, random_state=42) # 5 折交叉验证
for train_index, val_index in kf.split(X):
print(f"训练集: {train_index}, 验证集: {val_index}")
总结
数据集 | 作用 | 是否参与训练 | 用于超参数调优 | 何时使用 |
---|---|---|---|---|
训练集 | 训练模型 | ✅ | ❌ | 训练时 |
验证集 | 调整超参数,监测过拟合 | ❌ | ✅ | 训练过程中 |
测试集 | 评估最终性能 | ❌ | ❌ | 训练结束后 |
🚀 最佳实践:
✅ 80%-10%-10% 划分(训练-验证-测试)
✅ K 折交叉验证(当数据较少时)
神经网络模型训练的原理
神经网络模型训练的本质是一个 优化过程,核心目标是 最小化损失函数(Loss Function),使得模型对训练数据的预测尽可能准确。训练过程主要包括 前向传播(Forward Propagation)、损失计算(Loss Calculation)、反向传播(Backward Propagation)、参数更新(Parameter Update) 四个关键步骤。
1. 前向传播(Forward Propagation)
计算从输入到输出的结果
- 输入数据 ( X ) 经过 加权求和 和 激活函数 处理,得到 预测值 ( Y_{\text{pred}} )。
- 数学公式:
[
Z = W \cdot X + b
]
[
Y_{\text{pred}} = \sigma(Z)
]
其中:
- ( W ) 是 权重(Weights)
- ( b ) 是 偏置(Bias)
- ( \sigma(Z) ) 是 激活函数(如 ReLU、Sigmoid)
2. 计算损失函数(Loss Calculation)
衡量模型的预测值与真实值之间的差距
- 损失函数(Loss Function) 用来量化误差,常见损失函数:
- 回归任务(预测连续值):使用 均方误差(MSE) [ L = \frac{1}{N} \sum (Y_{\text{true}} - Y_{\text{pred}})^2 ]
- 分类任务(预测类别):使用 交叉熵损失(CrossEntropy) [ L = -\sum Y_{\text{true}} \log(Y_{\text{pred}}) ]
3. 反向传播(Backward Propagation)
计算梯度,调整参数
- 通过 链式求导法则(Chain Rule) 计算每个参数对损失函数的贡献: [ \frac{\partial L}{\partial W} ]
- 反向传播的本质是 梯度下降(Gradient Descent):
[
W = W - \alpha \cdot \frac{\partial L}{\partial W}
]
其中:
- ( \alpha ) 是 学习率(Learning Rate)
- ( \frac{\partial L}{\partial W} ) 是 梯度(Gradient)
4. 参数更新(Parameter Update)
使用优化算法(如 SGD、Adam)调整权重,使损失减少:
- 随机梯度下降(SGD): [ W = W - \alpha \cdot \frac{\partial L}{\partial W} ]
- Adam(自适应学习率优化)
- 计算梯度的指数加权平均
- 适用于 非平稳数据和稀疏梯度
完整示例:用 PyTorch 训练神经网络
import torch
import torch.nn as nn
import torch.optim as optim
# 1. 准备数据
X = torch.tensor([[1.0], [2.0], [3.0], [4.0]]) # 输入
Y = torch.tensor([[2.0], [4.0], [6.0], [8.0]]) # 真实值
# 2. 构建模型
class LinearRegressionModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(1, 1) # 一层线性回归模型(y = Wx + b)
def forward(self, x):
return self.linear(x)
model = LinearRegressionModel()
# 3. 选择损失函数和优化器
loss_fn = nn.MSELoss() # 均方误差
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 4. 训练模型
for epoch in range(100):
Y_pred = model(X) # 前向传播
loss = loss_fn(Y_pred, Y) # 计算损失
optimizer.zero_grad() # 清除梯度
loss.backward() # 反向传播
optimizer.step() # 参数更新
if (epoch + 1) % 10 == 0:
print(f'Epoch {epoch+1}, Loss: {loss.item():.4f}')
# 5. 预测新数据
new_X = torch.tensor([[5.0]])
predicted_Y = model(new_X).item()
print(f"预测 5 对应的值: {predicted_Y:.2f}")
总结
步骤 | 说明 |
---|---|
前向传播 | 计算从输入到输出的预测值 |
计算损失 | 计算预测值与真实值的误差 |
反向传播 | 计算梯度,优化参数 |
参数更新 | 使用梯度下降调整权重 |
在 PyTorch 中,梯度下降(Gradient Descent)是优化模型参数的核心方法之一。PyTorch 提供了 torch.optim 模块,其中包含了多种优化算法,包括最基本的 随机梯度下降(SGD),以及更高级的优化算法(如 Adam、RMSprop 等)。 |
1. PyTorch 梯度下降的基本流程
梯度下降的核心步骤如下:
- 前向传播(Forward Propagation) 计算损失函数(Loss)。
- 反向传播(Backward Propagation) 计算梯度,即对参数求导。
- 更新参数(Parameter Update) 使用优化器(如 SGD)更新模型参数。
2. PyTorch 实现梯度下降
torch.optim.SGD
(1) 使用 import torch
# 创建模型参数(需要计算梯度)
w = torch.tensor(2.0, requires_grad=True)
# 定义损失函数 L = (w-3)²
def loss_fn(w):
return (w - 3) ** 2
# 定义优化器(学习率 lr=0.1)
optimizer = torch.optim.SGD([w], lr=0.1)
# 梯度下降迭代
for i in range(10):
loss = loss_fn(w) # 计算损失
optimizer.zero_grad() # 清空梯度
loss.backward() # 计算梯度
optimizer.step() # 更新参数
print(f"Step {i+1}: w = {w.item()}, Loss = {loss.item()}")
流程解析
optimizer.zero_grad()
: 清空梯度,避免梯度累积。loss.backward()
: 计算损失对w
的梯度∂L/∂w
。optimizer.step()
: 使用SGD
更新参数:
[ w = w - \text{lr} \times \frac{\partial L}{\partial w} ]
(2) 手动实现梯度下降
如果不使用 torch.optim
,可以手动更新参数:
w = torch.tensor(2.0, requires_grad=True)
lr = 0.1 # 学习率
for i in range(10):
loss = loss_fn(w) # 计算损失
loss.backward() # 计算梯度
with torch.no_grad(): # 关闭梯度计算,防止 PyTorch 记录计算图
w -= lr * w.grad # 参数更新
w.grad.zero_() # 清空梯度
print(f"Step {i+1}: w = {w.item()}, Loss = {loss.item()}")
这里手动计算 w -= lr * w.grad
,效果等同于 optimizer.step()
。
3. PyTorch 支持的优化算法
除了 SGD,PyTorch 还提供了更高级的优化器:
- Adam (
torch.optim.Adam
):适用于大多数任务,收敛快。 - RMSprop (
torch.optim.RMSprop
):适用于非平稳目标函数(如强化学习)。 - Adagrad (
torch.optim.Adagrad
):适用于稀疏数据。
示例(使用 Adam):
optimizer = torch.optim.Adam([w], lr=0.1)
4. 选择合适的梯度下降算法
优化器 | 适用场景 | 主要特点 |
---|---|---|
SGD | 经典梯度下降 | 适用于凸优化,学习率难以调整 |
SGD + Momentum | 加速收敛 | 可减少振荡,适用于深度网络 |
Adam | 通用 | 结合了 RMSprop 和 Momentum,适用性强 |
RMSprop | 适用于非平稳目标 | 适用于强化学习和递归神经网络 |
Adagrad | 适用于稀疏数据 | 适合 NLP 任务,梯度会逐渐减小 |
在深度学习任务中,Adam 是默认的首选优化器。
5. 结论
- 梯度下降是优化模型的核心方法,PyTorch 提供了自动求导和优化器。
- 使用
torch.optim
可以方便地管理优化算法,如SGD
和Adam
。 - 对于深度学习任务,
Adam
通常是更好的选择。
评论