学习目标
- 解释模型训练与普通预测的区别。
- 区分损失函数、单个样本的损失值和平均经验损失。
- 计算一组简单预测的 MSE。
- 从直观和数学角度解释梯度下降。
- 阅读并运行一个使用 Python 训练线性模型的示例。
- 指出所选损失函数和优化算法的局限。
1. 从模型到训练
在 1.4.1 中,模型表示为 ŷ = f(x; θ)。其中 θ 表示参数,x 表示输入特征,ŷ 表示预测。当 θ 固定时,模型只是将规则应用于新对象。训练要回答另一个问题:如何选择 θ,使模型在已知训练样本上的预测尽可能符合目标值 y?
设想一个预测设备维修时长的模型。每个已完成工单都包含特征——设备类型、使用年限、故障次数——以及实际维修时长。模型给出预测。如果预测与实际值持续存在偏差,可以调整参数。但“调整后变好”必须有明确标准:什么算误差?如何比较不同参数组合?
2. 误差与损失函数
对于一个样本,可以比较预测值 ŷᵢ 与已知目标值 yᵢ。两者之差表示误差方向,但直接求和时,正误差和负误差可能相互抵消。因此常使用绝对值或平方,而不是带符号的原始差值。
损失函数规定如何用数值评价预测与目标之间的不一致。它将单次预测的偏差转化为一个数字。数值取决于任务和所选函数:在不同问题中,相同偏差可能代表不同代价。
回归任务常使用平方误差。平方使误差贡献非负,并对较大的偏差施加更强惩罚。例如,误差 4 的平方为 16,而误差 1 的平方为 1。当大误差尤其不可接受时,这种方式很有用,但也会使方法对异常值更加敏感。
3. 从单个误差到训练目标
训练集包含 n 个样本。损失函数为每个样本计算一个 ℓᵢ。平均经验损失就是这些数值的平均值。训练通常被表述为寻找能够使该平均值最小的参数。
请注意:我们最小化的是训练数据上的一个数学目标,并没有证明模型在真实世界中不会出错。结果取决于训练数据能否代表未来场景、可用特征是什么,以及损失函数是否反映错误的实际后果。
不要把 loss 与最终评估指标混为一谈。Loss 是训练过程中用于更新参数的准则。模型评估指标和验证流程将在主题 1.5 中详细学习。训练损失低,并不能单独保证模型在新数据上表现良好。
4. 如何寻找最小值:梯度下降
如果我们稍微改变参数,并能计算损失如何变化,就可以朝着损失减小的方向移动。导数描述函数相对于某个参数的局部变化率。梯度汇总所有参数的偏导数,指向局部增长最快的方向。因此,要降低目标函数,就沿相反方向迈出一步。
每一步中,算法计算当前损失函数的梯度并更新参数。步长由 learning rate(学习率)控制。步长过大可能越过最小值或发散;过小则会使训练变慢。学习率、batch size 等超参数的详细调整属于 1.4.5 课。
在线性回归与 MSE 的标准设定下,目标函数是凸函数:不存在多个局部最小值,在适当条件下梯度方法可以到达全局最小值。复杂神经网络的损失曲面通常是非凸的,因此优化过程更加复杂。
5. 完整示例:线性模型
假设模型根据设备运行时间预测能耗:ŷ = wx + b。我们有四条教学样本。初始设置 w = 0、b = 0,因此模型最初对所有样本都预测 0。先计算 MSE,再计算关于 w 和 b 的梯度,并更新参数。
关于 w 的梯度表示平均平方误差如何随直线斜率变化;关于 b 的梯度表示误差如何随直线整体平移而变化。更新后参数发生改变,因此需要重新计算预测值和 loss。重复这些步骤,模型逐渐找到更符合训练点的直线。
下面的代码实现了不依赖第三方库的简单 batch gradient descent。每次迭代使用全部四条样本。这是用于理解机制的教学实现,并不能替代生产级机器学习库。
x_values = [1.0, 2.0, 3.0, 4.0]
y_values = [3.0, 5.0, 7.0, 9.0]
w = 0.0
b = 0.0
learning_rate = 0.01
epochs = 2000
n = len(x_values)
for epoch in range(epochs):
predictions = [w * x + b for x in x_values]
errors = [pred - target for pred, target in zip(predictions, y_values)]
mse = sum(error ** 2 for error in errors) / n
grad_w = (2 / n) * sum(error * x for error, x in zip(errors, x_values))
grad_b = (2 / n) * sum(errors)
w -= learning_rate * grad_w
b -= learning_rate * grad_b
print(f"w = {w:.3f}, b = {b:.3f}")
print(f"MSE = {mse:.6f}")
print("predictions =", [round(w * x + b, 2) for x in x_values])预期结果:w 接近 2,b 接近 1,MSE 接近 0。由于迭代次数有限,结果可能存在微小差异。
代码解析:先计算预测值,再计算 errors = prediction − target;随后计算 MSE 以及关于 w、b 的导数;最后更新参数。梯度在更新前计算,而下一轮的 loss 反映更新后的参数。
6. 其他损失函数与局限
MSE 并非万能。MAE 使用绝对偏差,因此较少受到单个大误差的影响,但在零点存在折角。Huber loss 对小误差采用平方形式,对大误差采用线性形式。分类任务常用 cross-entropy(交叉熵),将预测概率与真实标签进行比较。
选择 loss 是实质性的建模决策,而不是表面设置。如果 10 个单位的误差比 5 个单位的误差代价高一倍,平方惩罚可能合理。如果罕见异常值来自测量错误,MSE 可能会过度拟合它们。如果低估和高估的后果不同,对称损失函数可能并不合适。
优化过程也存在局限:对特征尺度、初始参数、噪声和缺失值敏感;可能过度拟合训练样本;并且依赖算法和超参数。过拟合与欠拟合将在 1.4.3 讲解,泛化能力在 1.4.4 讲解,参数调整在 1.4.5 讲解。
7. 本课要点
训练将数据、模型、损失函数和优化器连接起来。数据提供样本;模型生成预测;loss 衡量不一致程度;优化器更新参数。这些角色彼此不同,理解它们有助于分析模型行为。
训练集上的最小 loss 是所选训练过程的目标,并不保证公平性、因果有效性、鲁棒性或新数据上的良好表现。始终要问:使用了什么数据?loss 惩罚什么?哪些错误没有体现出来?结果是如何评估的?
在教学数据集中加入一个目标值明显偏大的样本。使用 MSE 训练线性模型,并与 MAE 进行比较。
- 记录训练前后的 loss。
- 比较新增样本对 MSE 和 MAE 的影响。
- 调大学习率和调小学习率,观察 loss 的变化。
- 解释为什么训练损失本身不能证明模型在新数据上的表现。
完成标准:代码和计算可复现,结论明确说明实验局限。
核心概念
参考资料与延伸阅读
本课词汇表
将预测误差转换为数值惩罚的规则。
对一个或多个样本应用损失函数得到的数值。
有限训练样本上的平均损失。
预测误差平方的平均值。
预测绝对误差的平均值。
表示函数局部增长方向的导数向量。
逐步降低目标函数的迭代方法。
负责更新模型参数的算法。
更新参数时使用的步长。
训练过程完整遍历一次训练集。
自我检测
问题 1
已训练模型进行普通预测时会发生什么?
问题 2
为什么需要损失函数?
问题 3
预测值为 [2, 4],目标值为 [3, 2]。MSE 是多少?
问题 4
梯度下降沿哪个方向迈步?
问题 5
学习率过大可能发生什么?
问题 6
关于 MSE,哪些说法正确?
问题 7
优化器的作用是什么?
问题 8
训练损失较低,是否证明模型在新数据上表现良好?