上一节我们把日志整理成了真正可用的数据集:样本定义了模型在决策时能看见什么,标签定义了它应当相信什么,数据分布则划定了它将面对怎样的世界。
但一份数据集放到模型面前,模型并不会自己"领会规律"。它首先得知道:自己的预测到底错在哪里,错得有多严重;然后还要知道,该把内部哪一部分往哪个方向改一点。
这正是损失函数与梯度下降要解决的事。前者把"做得不好"变成可度量的反馈,后者把这份反馈变成一次次参数修正。
文章摘要
本文以单关节机械臂的负载估计为例,解释模型如何把"预测错了"转化为可执行的学习信号。损失函数负责度量预测与真实结果之间的差距,同时把任务目标、误差偏好与安全边界写进训练过程;梯度则描述每个参数朝哪个方向微调,最能让损失下降。文章借助"在损失地形中下山"的直觉,说明前向计算、损失评估、反向传播与参数更新构成的训练闭环,并讨论学习率过小、过大和合适时的差别。最后结合控制系统的反馈思想,区分训练误差与真实泛化能力,提醒读者:损失下降并不自动代表模型理解了世界,数据质量、任务定义和测试边界仍决定模型能否可靠部署。
写在前面
继续回到那台单关节机械臂。
假设我们已经按上一节的原则,准备好了一批可靠样本:输入是过去一段时间的位置、速度、电流、温度与控制命令;标签则是经过标定的真实末端负载。现在,模型接收一条新样本后,给出了一个估计值:
- 真实负载是 3 kg;
- 模型第一次预测成了 4.2 kg;
- 下一次,它又预测成了 3.7 kg;
- 经过足够多轮训练后,才逐渐逼近真实值。
这里最值得追问的并不是"模型最后准不准",而是:它为什么会从 4.2 kg 改成 3.7 kg?它又凭什么知道该改哪几个参数,而不是随机地胡乱尝试?

机器学习不是让机器第一次就答对,而是让它把每一次偏差都变成下一次改进的依据。
如果把控制系统看作"根据当前误差修正执行器输出"的快速反馈环,那么模型训练可以理解为一个更慢、也更抽象的反馈环:它不直接调节电机,而是调节自己内部的参数。
于是,这一节真正要回答的问题是:
损失函数怎样定义一次"犯错"?梯度下降又怎样把犯错转化为模型内部的持续改进?
一、先给结论:学习,本质上也是一个反馈闭环
先把结论说清楚。
一次典型的监督学习训练,并不是"把数据输入模型,答案自然出现"。它至少要经过下面四步:
- 预测:模型根据输入给出当前答案;
- 比较:损失函数将预测与真实标签比较,得到一个误差分数;
- 归因:梯度计算每个参数对误差的影响方向与敏感程度;
- 修正:优化器依据梯度,小幅更新参数后再尝试一次。
这四步不断循环,才形成了机器学习真正的训练过程。
| 训练环节 | 它回答的问题 | 对机械臂负载估计意味着什么 |
|---|---|---|
| 模型预测 | "按当前理解,我会给出什么答案?" | 根据位置、电流、速度等信号估计负载 |
| 损失函数 | "这个答案离目标有多远?" | 4.2 kg 与真实 3 kg 的差距应被记成多严重 |
| 梯度 | "改动哪里最可能让误差变小?" | 哪些内部权重对当前高估最敏感 |
| 参数更新 | "下一次该怎样调整?" | 略微改变权重后,再用相似样本检验 |
这和前面专栏里反复出现的反馈思想高度一致:没有比较,就没有误差;没有误差信号,就谈不上修正;没有持续修正,系统也无法逐步逼近目标。
不同只在于,控制器通常调整的是此刻的控制输入 uuu;而训练过程调整的是模型长期保留的参数 θ\thetaθ。前者要在毫秒级赶上物理过程,后者可以花几秒、几小时甚至更久,从大量历史经验中慢慢改变自身。
二、损失函数:先把"错得多严重"说清楚
模型的输出与真实标签之间,当然可以直接做差;但"做差"并不等于已经定义好了学习目标。
仍以负载估计为例。若真实负载为 yyy,模型预测为 y^\hat{y}y^,最朴素的误差是:
e=y^−y e = \hat{y} - y e=y^−y
问题在于,正负误差会互相抵消:高估 1 kg 与低估 1 kg 相加是 0,但两次预测显然都没有做好。因此,我们通常需要把"偏离目标"转换成一个始终非负、且可以比较的分数,这个分数就是损失(loss)。
1. 损失不是成绩单,而是模型的"改进方向盘"
常见的回归损失之一是均方误差:
L=1N∑i=1N(y^i−yi)2 L = \frac{1}{N} \sum_{i=1}^{N} (\hat{y}_i - y_i)^2 L=N1i=1∑N(y^i−yi)2
不必急着记住这个式子。它只表达了两个直觉:
- 每个样本的预测偏差都要算进去;
- 偏差越大,惩罚会增长得越快。
于是,把 3 kg 错估成 3.1 kg 与错估成 7 kg,不会被当作同样程度的问题。对机械臂这类系统而言,这种偏好常常是合理的:较大的负载误判可能带来更明显的轨迹误差、力控风险或安全余量不足。
但均方误差不是唯一选择。损失函数其实是在告诉模型:在这个任务里,哪种错误更不能接受。
| 任务或关注点 | 常用的损失思路 | 它表达的偏好 |
|---|---|---|
| 连续数值预测 | 均方误差、绝对误差 | 预测值应接近真实数值 |
| 少量极端异常不应主导训练 | 更稳健的误差函数 | 不让个别离群点牵着全部参数走 |
| 故障是否发生的分类 | 交叉熵一类的分类损失 | 对正确类别给出更高置信度 |
| 漏报风险远高于误报 | 加权损失、代价敏感损失 | 更严厉地惩罚漏掉关键风险 |
因此,损失函数不是训练之后才看的分数,而是训练开始时就写下的一条价值判断。若我们只最小化"平均误差",模型可能在常见工况下很好,却忽略重载、高温或临界故障这些更重要的少数场景;若把所有异常都赋予极高权重,模型又可能频繁误报。
这与 LQR、MPC 中的代价设计并没有本质差别:优化器只会认真完成我们写进目标里的事情。
2. 一个下降的损失,不一定代表问题被解决
这里需要保留一份警惕。
如果标签本身错位、训练数据几乎都是空载工况,或者损失函数只关心平均误差,那么训练损失完全可能持续下降;但模型学到的只是"在这一小块熟悉世界里,把这道题做得更像训练答案"。
上一节讨论的数据质量、时间泄漏和分布覆盖,并没有在进入训练后失效。它们决定了损失所比较的"正确答案"是否可信,也决定了这份下降能否代表未来真实任务中的进步。
更准确地说:
损失函数能度量模型相对既定目标的偏差;它不能替我们证明,既定目标、标签和数据世界本身就是正确的。
三、梯度:它不只告诉模型"错了",还告诉模型"该往哪儿改"
现在,模型已经拿到一个损失值。假如损失是 0.82,这个数字本身依然不够。
它只能说明"当前不好",却没有说明:模型内部成千上万、甚至上百万个参数中,究竟该动哪个?每个参数应该增大还是减小?动多大才合适?
这便轮到梯度登场。
1. 用"下山"理解梯度
可以把所有模型参数想象成我们在一片复杂地形中的位置。不同参数组合会得到不同损失,于是整片地形的高度就代表损失大小:高处意味着预测很差,低处意味着预测更接近目标。

梯度并不是"最低点的位置",而是站在当前位置时,地形上升最快的方向。要让损失下降,就朝它的反方向走一小步。
在山坡上,若你想尽快下山,最有用的信息不是"你现在海拔 820 米",而是"此处哪个方向最陡"。梯度提供的正是这种局部方向信息。
对于某个参数 θ\thetaθ:
- 梯度为正,意味着把它再增大一点,损失倾向于变大;
- 梯度为负,意味着把它增大一点,损失倾向于变小;
- 梯度接近零,意味着当前位置附近已较平缓,或这个参数暂时对损失不敏感。
因此,最基本的更新形式是:
θ←θ−η∇θL \theta \leftarrow \theta - \eta \nabla_\theta L θ←θ−η∇θL
其中 ∇θL\nabla_\theta L∇θL 是损失对参数的梯度,η\etaη 是稍后要讨论的学习率。这个式子最重要的只有一句话:减号意味着朝让损失下降的方向移动。
2. 梯度是局部建议,不是全知地图
梯度并不会告诉模型"全局最低点在哪"。它只能根据当前位置附近的地形,给出一次局部建议。
这也解释了训练为什么必须迭代:走一步后,位置变了,地形的局部方向也变了;模型再重新计算梯度、再走下一步。很多微小修正叠加起来,才构成从粗糙预测到较好预测的过程。
在深度神经网络中,一个输出往往经过多层计算才得到。最终损失要想影响靠前层的参数,就需要把"这次误差对后面每层的影响"逐层传回去。这个高效的梯度计算过程,就是常说的反向传播。
要注意,反向传播并不等于训练的全部:它负责算清梯度;而究竟怎样使用梯度、是否加入动量、是否为不同参数调整步长,则属于优化器的职责。
四、从一次样本到一次训练:模型怎样完成"预测---犯错---修正"
为了更直观地看清训练闭环,可以先忽略网络内部的复杂结构,只看一次小批量训练发生了什么。
python
# 1. 用当前参数做预测
prediction = model(features)
# 2. 把预测与真实标签比较
loss = loss_function(prediction, target)
# 3. 清除上一次残留的梯度,再反向计算本次梯度
optimizer.zero_grad()
loss.backward()
# 4. 按优化规则更新参数
optimizer.step()
这几行代码背后,其实仍是熟悉的反馈闭环:
| 代码动作 | 训练中的含义 | 控制系统中的相似角色 |
|---|---|---|
model(features) |
当前参数下的预测输出 | 被控对象对输入的响应 |
loss_function(...) |
衡量预测与目标的偏差 | 误差计算环节 |
loss.backward() |
找出各参数对偏差的影响 | 误差如何传播、如何归因 |
optimizer.step() |
据此更新模型内部状态 | 控制律给出修正动作 |
真正的训练并不会只看一条样本。通常,模型会同时处理一个小批量(mini-batch)数据,再用这批样本的平均损失更新一次。这样做既能降低单条样本噪声造成的偶然影响,又不必每次都等待整个数据集计算完毕。
一轮把训练集大致遍历一次的过程,常被称作一个 epoch。随着 epoch 增加,训练损失通常会先快速下降、后逐渐放缓;但我们仍应同步观察验证集表现,因为"训练集越来越熟"不等于"面对新工况越来越可靠"。
五、学习率:每一步走多远,决定模型是在靠近目标还是来回震荡
梯度给出了方向,学习率 η\etaη 则决定一次更新迈出多大的步子。
这很像控制系统里增益的选择:太小,修正极慢;太大,可能冲过目标、来回摆动,甚至彻底发散。

图中从左到右依次对应:步子过小、步子合适、步子过大。训练不是"每次改得越多越好",而是在速度与稳定性之间寻找可控的尺度。
| 学习率状态 | 常见现象 | 背后的直觉 |
|---|---|---|
| 过小 | 损失缓慢下降,训练耗时很长 | 每次只挪动极小距离,方向虽然正确却推进不足 |
| 合适 | 损失总体下降,偶有波动但能逐步稳定 | 每一步既能获得进展,也没有越过太多 |
| 过大 | 损失剧烈震荡、变大或出现数值异常 | 每次都越过低点,甚至被推向更高处 |
现实中的损失地形远比一个规则碗面复杂:有的方向陡,有的方向平;有的参数尺度很大,有的很小;小批量数据还会给梯度带来噪声。因此,常见优化器会在基础梯度下降上加入动量、自动调整步长或学习率衰减等机制。
不过这些技巧不应遮住核心。无论使用 SGD、Momentum、Adam 还是其他优化方法,始终都在完成同一件事:根据当前误差的局部反馈,选择一次更稳妥的参数修正。
六、为什么"训练损失下降"仍不足以宣布成功?
看到损失曲线往下走,确实值得高兴;但在真实工程中,还不能立刻把模型交给生产系统。
因为损失的下降至少可能混合了两类完全不同的原因:
- 模型真正抓住了输入与目标之间可迁移的关系;
- 模型只是记住了训练数据中的偶然模式、设备个性或错误标签。
下面这些现象尤其值得在训练时主动检查。
| 现象 | 可能原因 | 应先检查什么 |
|---|---|---|
| 训练损失下降,验证损失上升 | 过拟合,模型记住训练集细节 | 划分是否按时间/批次隔离,模型是否过复杂 |
| 损失长期不降 | 学习率不合适、输入无有效信息或标签噪声过大 | 基线模型、标签对齐、特征量纲与数据管道 |
| 损失突然变成异常值 | 学习率过大、数值溢出、数据中混入非法值 | 输入范围、梯度范围、数据缺失和归一化 |
| 平均损失很好,关键工况很差 | 常态样本占比过高,目标函数未体现风险 | 重载/高温/异常分组指标与加权策略 |
| 离线指标很好,上线效果变差 | 训练与部署的信息边界不一致 | 时间泄漏、传感器差异、分布偏移 |
例如,模型可能把"某台机械臂的序列号"或某个特定时段的温度背景,当成负载的捷径;在同一台设备、相近日期的测试集上表现很好,换到另一台设备却立刻失效。损失函数并不会自动识破这件事------它只会尽力把当前喂给它的数据拟合得更好。
所以,训练过程至少应同时查看三组信息:
- 训练损失:模型是否能从现有样本中学习;
- 验证损失与分组指标:它是否能面对未参与更新的新数据,以及在关键工况下是否仍可靠;
- 部署边界:在线输入是否与训练时一致,模型输出是否仍受到原有控制器和安全逻辑约束。
这里的重点并非追求一条绝对平滑、绝对低的曲线,而是让每一个分数都有明确的任务语义与可追溯边界。
七、把损失函数放回五层知识框架:它是慢时间尺度上的误差反馈
从专栏开篇提出的"反馈回路进化"来看,损失函数与梯度下降并不是突然出现的一套陌生语言。
| 层次 | 被比较的偏差 | 被修正的对象 | 时间尺度 |
|---|---|---|---|
| 基础闭环控制 | 参考值与测量值之间的控制误差 | 控制输入、执行器输出 | 微秒到毫秒 |
| 状态估计与最优控制 | 预测、测量与代价之间的偏差 | 状态估计或控制序列 | 毫秒到秒 |
| 嵌入式实现 | 任务执行与截止时间、数值范围之间的偏差 | 调度、限幅、保护动作 | 微秒到秒 |
| 机器学习训练 | 预测值与标签之间的损失 | 模型参数 | 秒到小时甚至更久 |
| 大模型与 Agent | 行动结果、目标与人类偏好之间的差距 | 策略、工具调用与后续规划 | 秒到天 |
它们都包含"观察结果---计算偏差---据此修正"的结构,只是优化对象和反应速度不同。
控制系统在运行中不断修正输出,是为了让机械臂此刻不偏离轨迹;机器学习在离线训练中不断修正参数,是为了让模型在未来面对类似但未见的数据时,能给出更好的估计。两者不能相互替代:训练模型无法取代毫秒级安全控制环,而一个固定控制律也很难独自吸收长期积累的复杂数据规律。
因此,在具身系统中更合理的分工往往是:底层控制环负责稳定、限幅和安全;学习模型负责预测、估计或补偿;损失函数则把"我们希望模型在哪些方面更可靠"明确写入训练反馈中。
In the end:下一步该看什么
到这里,我们已经知道模型如何得到误差信号、如何据此计算梯度,又如何通过一小步一小步的更新降低损失。
但新的问题也随之出现:如果只是线性地组合位置、电流、速度和温度,模型能表达的规律终究有限。面对接触摩擦、非线性温升或多传感器耦合时,机器为什么能够从原始数据中逐层抽取出更有用的特征?
下一节,我们将继续沿着这条反馈线进入神经网络内部:神经网络与表征:为什么层层变换能让模型学会特征?