跳转至

P5-4.2 按问题类型区分的损失

Section ID: P5-4.2 Version: v2026.07.20

在 P5-4.1 里,我们已经把损失函数(loss function)理解成:把模型当前输出与目标之间偏离了多少变成数字的标准。接下来就会自然冒出下一个问题:

所有问题都使用同一种损失函数吗?

答案是否定的。

损失函数会随着问题类型而改变。因为回归(regression)、分类(classification)、生成(generation)这三类问题,错误长什么样本身就不同。

如果后面又开始把问题类型对应的损失标准混在一起,更适合回到英文概念词汇表里的 loss function 条目

问题类型改变损失的问题

  • 为什么回归与分类会使用不同的损失标准?
  • 匹配数字的问题,与匹配概率的问题,应该怎样用不同方式阅读?
  • 在生成问题里,下一个 token 预测得有多像样为什么会直接连到损失?
  • 损失函数的选择,会怎样改变学习方向?

这一节不会先堆很多公式,而是先解释:为什么不同问题会需要不同的损失。 损失的微分与学习更新流程,会在 P5-5.1、P5-5.2 再重新接回。也就是说,这一节要先闭合的是:为什么随着问题类型改变,什么会被算作错也必须跟着改变。

输出解释与损失选择的判断标准

  • 能区分回归、分类、生成三类问题的损失视角。
  • 能说明:回归看误差大小,分类看对正确类别的置信度,生成看下一个 token 的概率。
  • 能理解损失函数必须按问题里错误的形状来设计。
  • 能按问题类型解释:哪一种预测应该更早、更强地被修正。

为什么问题一变,损失也要变

问题类型不同,错了这句话的含义也会跟着不同。

例如:

  • 预测批次能耗时,重要的是离目标值有多远
  • 分类检测状态时,重要的是给正确类别多少把握
  • 生成运营提示语时,重要的是下一个词预测得有多像真正答案

也就是说,损失函数不是单纯的数学公式,而是规定:在这个问题里,到底什么应被视为错误。

把这个大流程压成一张图,就是下面这样:

flowchart TD
  A["问题类型"]
  B["什么应被视为误差?"]
  C["选择损失"]

  A --> B
  B --> C

这张图最核心的提醒是:在看模型之前,要先看清问题结构。

如果再按到底把什么读成错误来分支,同样的流程可以改写成下面这样:

flowchart TD
  A["问题类型"]
  B["回归"]
  C["分类"]
  D["生成"]
  E["离目标数字有多远?"]
  F["给正确类别多少置信度?"]
  G["给下一个正确 token 多高概率?"]

  A --> B
  A --> C
  A --> D
  B --> E
  C --> F
  D --> G

这张图最先要确认的结果是:当问题类型变化时,最先分岔的并不是“损失公式的名字”,而是究竟把哪种错误变成数字。

在回归(regression)里,什么最重要

回归通常是在预测连续数值。

  • 批次能耗
  • 压力稳定时间
  • 分时冷却水需求量
  • 设备搬运距离

对这类问题来说,真正重要的是:离正确数字偏了多远。

也就是说,回归损失会被设计成把误差(error)的大小聚成数字。

先这样理解就足够:

  • 只错一点,损失就小;
  • 错得很多,损失就大。

代表性的视角,通常会出现平均平方误差(mean squared error, MSE)或平均绝对误差(mean absolute error, MAE)。

在分类(classification)里,什么最重要

分类问题里,正确类别是固定的。

  • 立即停机 / 继续监控
  • 正常 / 细微划痕
  • 需要复测 / 自动通过

在这里,“对还是错”当然仍然重要,但学习需要比这更细的信号。

例如,模型:

  • 给正确类别 0.51 的概率,
  • 还是给正确类别 0.99 的概率,

最终都可能算“答对了”,但从学习角度看,这两者明显不一样。

也就是说,分类损失会被设计成更敏感地读取:对正确类别给了多高的置信度? 或者 有多自信地朝错误类别走过去了?

这也是为什么 cross-entropy 会经常作为代表性损失出现。

在生成(generation)里,什么最重要

生成问题和分类很像,但又不完全一样。特别是在 LLM 语境里,模型通常不是一次把整句都“对上”,而是通过不断预测下一个 token(next token)来学习。

也就是说,生成学习常常可以先读成下面这个结构:

  • 先看当前为止的上下文(context);
  • 对下一 token 的候选分配概率;
  • 再朝着“给真实正确 token 更高概率”的方向学习。

因此,生成问题所使用的损失,也常常是和分类接近的概率型损失。在实务与教材里,通常会计算每个位置上正确 token 的 cross-entropy 或 negative log-likelihood(NLL),然后再把这些值在整个序列(sequence)与整个 batch 上求和或取平均,形成最终的 objective。不同之处在于:这不是一次性的二元判断,而是在长序列上不断重复发生。

先这样理解就够了:

生成模型的损失,并不是一次把整句话背下来的损失,而是把每个位置上“下一个 token 预测得有多好”不断累积起来的损失。

把回归与分类并排比较

虽然都可以说“错了”,但回归和分类对这句话的读取方式完全不同。

问题类型 输出形式 阅读错误的核心
回归 连续值 离正确数字有多远
分类 类别概率 给正确类别多少置信度
生成 下一个 token 的概率分布 正确 token 被预测得有多像样

理解了这张表,就更容易看清:损失函数不是单纯的实现细节选择,而是在反映问题结构本身。

如果再把同样的内容往前推进一步,改成一旦用错了损失视角,会有什么东西变模糊,差别就更清楚:

问题类型 损失必须读清的东西 如果按别的问题类型去读,会变模糊的东西
回归 数值误差的大小 如果把它当成类别概率来读,真实距离感会变弱
分类 对正确类别的置信度、对错误类别的置信度 如果只看数字差,很自信地答错就不容易被充分惩罚
生成 每个位置上正确 token 的概率 如果把它当成一次性的对错表,序列级累积误差就会变模糊

也就是说,选择损失函数,首先不是在挑一个公式名字,而是在决定:这个问题里,哪种错误必须被最敏感地读出来。

如果再从图的横轴来理解,就更容易抓住差异。回归先看与正确数字的距离,分类先看给正确类别的概率,生成则先看多个位置上给正确 token 的概率。

回归损失阅读轴

分类损失阅读轴

生成损失阅读轴

因此,与其一上来就把不同问题类型的损失数字互相比大小,不如先在同一问题类型内部看清:到底哪一个预测更糟。这三张图所展示的核心就是:问题类型一变,损失所阅读的坐标轴也会跟着变。

案例与示例

案例 1. 回归

假设我们在估计一个混合批次的总能耗。人在这个场景里最先会看:它离正确用量有多远?

  • 真实用量:5.0kWh
  • 预测 1:4.9kWh
  • 预测 2:3.5kWh

这里显然是预测 1 错得更少。人也很容易直觉上感到:4.9kWh 已经相当接近,而 3.5kWh 明显偏得更远。 在回归问题里,核心标准并不是只看“对还是错”,而是看偏离了多少距离。因此,更自然的损失设计,会给预测 1 更小的数字,给预测 2 更强的警告信号。只有保留这层差异,能耗预测模型才有办法区分:这是一个只要稍微修一下就行的预测,还是一个需要更大幅度重看的预测。

人最容易先看的标准 用回归损失重新阅读后的标准
两个都不是正确答案,所以都只是错了 先看谁离正确数字更远
只看大致范围有没有猜到 把误差是 0.1kWh 还是 1.5kWh 更强地留成数字
只用语言判断偏差大小 把它变成损失数字,好让很多样本可以用同一标准比较

所以,这个案例里真正要确认的结果是:离正确答案更远的预测,是否真的会得到更大的损失。

人最容易先做的误读 为什么这样读不够好 更好的读法
4.9kWh3.5kWh 都笼统归成“错答” 那样就分不出“只需小修的预测”和“需要大修的预测” 在回归里先读误差距离,把更远的那个看成优先修正对象
把回归损失读成类似属于正确区间的概率 会把连续值问题误读成分类问题 回归损失应该被读成基于距离的误差信号,而不是概率

案例 2. 分类

假设一个表面检测模型正在读取一帧图像。人最先通常会看答对了吗,但在真实运行里,答得有多有把握也很关键。设正确类别是细微划痕

  • 预测 1:细微划痕 0.55,正常 0.45
  • 预测 2:细微划痕 0.95,正常 0.05

两者都预测对了,但从学习角度看,把预测 2 读成更好的状态会更自然。人可能会觉得两者都把细微划痕放在第一名,所以差不多;但分类问题里非常重要的是:它到底是多强地把正确答案推到第一名。 在一个会直接决定是否自动放行的检测系统里,虽然答对了但几乎还在犹豫很有把握地答对了,如果被看成同一种状态,下一步学习方向就会变模糊。例如在自动确认阈值策略下,0.55 可能还要送人工复核,而 0.95 则可能直接送入返工队列。因此,分类损失必须比一张简单对错表更细致地去看概率分布。

人最容易先看的标准 用分类损失重新阅读后的标准
两者都把细微划痕排第一,所以差不多 还要一起看它把正确答案推到第一有多强
觉得一格对 / 错表就够了 把 0.55 与 0.95 看成完全不同强度的学习信号
觉得置信度差异只在运营策略里才重要 看到这种差异从损失阶段开始就会影响更新大小

所以,这个案例里真正要确认的是:即便两个预测都答对了,置信度更低的那个是否仍然会留下更大的损失。

输出场景 不那么差的误读 更危险的误读 更好的读法
细微划痕 0.55,正常 0.45 读成“勉强答对,但还不稳定” 直接以“答对了,就不用再看了”结束 读成:即便答对了,只要置信度低,仍会留下更大的损失与额外学习信号
细微划痕 0.95,正常 0.05 读成更好的预测 0.95 直接误当成运营策略本身 更好的读法是:高置信度意味着更小的损失,但策略阈值仍然要单独制定

案例 3. 生成

再想象一个会生成运营提示语或作业指令文本的模型,在选择下一个 token。人往往会觉得,只要看正确词有没有排到第一就够了;但在真实学习里,更重要的是它把正确 token 推得有多强。假设正确的下一个 token 是 确认

  • 预测 1:确认 0.40,复测 0.35,保留 0.25
  • 预测 2:确认 0.85,复测 0.10,保留 0.05

这里同样更自然的读法,是把预测 2 看成更好。人很容易觉得两者都把确认排第一,所以差不多;但在真实生成里,给正确 token 的概率大小会改变下一步更新的强弱。例如在生成摘要句子或运营提示时,这种差异如果在多个位置上反复累积,就会变成整句质量的差异。也就是说,生成损失比起只看有没有把正确答案排第一,会更细地读它到底有多强地把正确 token 推上去。

人最容易先看的标准 用生成损失重新阅读后的标准
只要两者都把确认排第一,就差不多 还要看给正确 token 的概率到底有多大
觉得只看某一个位置答没答对就够了 看到这种概率差异会在序列的多个位置上累积
容易觉得只看最终整句质量就够了 学习实际上是把每个位置的 next-token 损失不断累积到整句质量上

所以,这个案例里要确认的是:即便两个预测都把正确 token 放在第一,给正确 token 更高概率的那个,是否真的会在学习里带来更小的损失与更清晰的更新。

也就是说,生成损失和给下一个正确 token 多少概率是紧密绑在一起的。

输出场景 不那么差的误读 更危险的误读 更好的读法
确认 0.40,复测 0.35,保留 0.25 读成“正确 token 虽然排第一,但还很弱” 只因为第一名是对的,就觉得已经足够 读成:生成损失不只看第一名,还会强烈看“正确 token 的概率仍然有多弱”
确认 0.85,复测 0.10,保留 0.05 读成更好的预测 直接断定整句质量已经完全有保证 更好的读法是:单个位置损失确实更小,但整句稳定还要靠这种判断在很多位置上持续累积

把这三个案例并排摆在一起看,就会发现:问题类型对应的损失差异,并不是停在“公式名字不同”。

问题类型 人最容易先做的判断 损失会更细地揭示什么 应该优先更强修正哪一个预测
回归 离真实值更远的预测更差 会把误差距离到底大多少拉成更明显的损失数字 3.5kWh 这个预测
分类 只要都答对,容易觉得差不多 会进一步区分对正确类别到底有多高置信度 细微划痕 0.55 这个预测
生成 只要都把正确 token 放第一,容易觉得差不多 会显示正确 token 概率差异如何在各位置累积成损失 确认 0.40 这个预测

这张表最先该抓住的结果是:回归重新筛的是距离,分类重新筛的是对正确类别的置信度,生成重新筛的是各位置正确 token 的概率

机器学习与深度学习课程里,之所以要单独讲“按问题类型分开的损失”,原因就在于:只理解模型结构,还不足以理解学习。

同样是神经网络:

  • 如果最后输出的是连续值,就要按回归损失去读;
  • 如果最后输出的是类别概率,就要按分类损失去读;
  • 如果最后输出的是 token 分布,就要按生成损失去读。

也就是说,神经网络内部结构与损失函数不是彼此独立的话题。最后输出到底意味着什么,会直接决定损失应该怎样一起被理解。

这个流程在后面读 LLM 时尤其关键。因为只有理解:LLM 的学习损失并不是直接测量整句质量,而是把很多位置上的 next-token 预测损失不断累积起来,后面的说明才不会显得突兀。这也会直接连到外部文献里经常出现的 next-token cross-entropytoken-level NLLsequence loss 这些表达。

练习与示例

这次练习的目标,是用非常小的数字确认:回归、分类、生成在阅读损失时,到底是怎样走上不同路径的。这一次不是只看某个单独数字,而是先固定各自的比较标准:回归看误差距离,分类看正确类别概率,生成看正确 token 概率

这一次也把生成一起放进来,目的是确认:即便都是“把正确答案排到第一”的预测,损失仍然会继续读出更细的差别。

输入:

  • 2 个回归预测与目标值
  • 2 个分类里的正确类别概率
  • 2 个生成里的正确 token 概率

输出:

  • 2 个基于回归误差的损失
  • 2 个基于分类概率的损失
  • 2 个基于生成位置概率的损失
  • 每种问题内部“哪一个预测更糟”的比较结果

问题场景:

  • 回归、分类、生成虽然都会使用损失,但由于它们把错误变成数字的方式不同,不能拿同一套“坏的标准”直接横着读

要确认的概念:

  • 回归损失看的是数值差距,分类损失看的是给正确类别的概率大小;
  • 生成损失看的是每个位置上给正确 token 的概率大小;
  • 即便在同一种问题内部,也必须能继续分出“没那么糟的预测”与“更糟的预测”;
  • 问题类型一变,损失计算方式也必须一起变化。

输入(input):

使用上面整理过的回归预测值与目标值、分类正确类别概率、生成正确 token 概率。

在看表之前,可以先自己猜一猜哪一个会变成更大的损失。

比较场景 可以先猜的更大损失 这样猜的理由
回归:pred_close=4.7 vs pred_far=3.8 pred_far 因为它离正确答案 5.0 更远。
分类:scratch_prob=0.80 vs scratch_prob=0.35 0.35 这一边 因为给正确类别的概率更低。
生成:confirm_token_prob=0.75 vs confirm_token_prob=0.30 0.30 这一边 因为即便都是正确 token,给得更低的概率也会带来更大的更新损失。

这张表的目的,不是把回归、分类、生成的损失数字直接互相比大小,而是先抓住:在各自的问题内部,判断哪个预测更糟的标准并不一样。

如果把同样的比较整理成损失结果,就会读成下面这样:

问题类型 没那么糟的预测 更糟的预测 损失结果 现在要读到的核心
回归 pred_close=4.7 pred_far=3.8 0.09 vs 1.44 离正确数字更远的那一个,会得到更大的损失。
分类 scratch_prob=0.80 scratch_prob=0.35 0.223 vs 1.05 给正确类别更少概率的那一个,会得到更大的损失。
生成 confirm_token_prob=0.75 confirm_token_prob=0.30 0.288 vs 1.204 给正确 token 的概率更弱的那一个,会得到更大的损失。

这里并不是要把这些数字跨类型直接比较谁更大。真正重要的是:在每一种问题内部,到底哪一个预测应该先被读成更差。

  • 回归损失看的是数值距离;
  • 因此偏得更远的 pred_far 会得到更大的损失。
  • 分类损失看的是给正确类别的概率;
  • 因此给得更少的 scratch_prob=0.35 会得到更大的损失。
  • 生成损失看的是每个位置上给正确 token 的概率;
  • 因此即便都把正确 token 排在第一,confirm_token_prob=0.30 仍然会得到更大的损失。

把这个结果重新压成一句话,就是:

问题类型 用来区分“更糟预测”的核心 这次例子里得到更大损失的是谁
回归 与正确数字的距离 pred_far=3.8
分类 给正确类别的概率 scratch_prob=0.35
生成 给正确 token 的概率 confirm_token_prob=0.30

也就是说,损失数字的意义会随着问题结构改变。

读完输出之后,最好再把它直接接到到底该先更强地修哪个预测这一步。

问题类型 这次输出里应该优先更强修正的预测 这样读的理由 紧接着更好的下一步判断
回归 pred_far=3.8 因为它离正确值 5.0 更远,误差距离大得多 先看为什么输入特征与权重会让它偏到这么远
分类 scratch_prob=0.35 因为它给正确类别的概率较低,更容易在边界附近摇摆向错误类别 先看它是不是边界样本,以及 logits 差距为什么这么窄
生成 confirm_token_prob=0.30 因为它对正确 token 的确信度弱,更容易把后续位置也一起带偏 先看上下文是否不足,以及竞争 token 为什么会这么强

把这张表也读完之后,就会更清楚:按问题类型区分损失,并不是“会算数字”就结束,而是在重新划分:到底哪种预测应该更早、更强地被修正。

从学习的角度,这里真正闭合的核心不是“公式名字”,而是错误的形状。回归里是距离,分类里是正确类别概率不足,生成里是各位置正确 token 概率不足。只有能自己把这三者说清楚,后面才有办法把反向传播与 LLM 训练损失读成同一条连续流程。

换值后重新阅读的轴 会变得更清楚的损失差异 此时可以继续问的问题
在回归里,把 pred_far 往正确答案再挪近一些 会更容易看出基于距离的损失是怎样快速下降的 回归里真正的核心误差区间是哪一段?
在分类里,把 scratch_prob=0.35 提高到 0.55 会更清楚看出正确类别概率不足是怎样被缓和的 边界附近置信度不足到底会把学习信号放大多少?
在生成里,把 confirm_token_prob=0.30 放到多个位置重复观察 会更清楚看到小的概率不足怎样累积成序列级损失 为什么 LLM 的损失更像“下一个 token 的不断累积”,而不是整句一次打分?

如果用 Python 做同样的比较,关键也不在于让三个问题的绝对损失值彼此竞争。下面的例子会把回归、分类、生成里各自一个“薄弱预测”单独修正,然后观察:到底是哪一种损失在下降。

# 这个例子比较在回归、分类、生成中修正一个较弱预测时,各自的 loss 如何下降。
import math


def regression_loss(prediction, target):
    error = prediction - target
    return error * error


def probability_loss(true_probability):
    return -math.log(true_probability)


def summarize(label, *, energy_prediction, scratch_probability, token_probability):
    print(f"[{label}]")
    print(
        "regression_loss=",
        f"{regression_loss(energy_prediction, target=5.0):.3f}",
    )
    print(
        "classification_loss=",
        f"{probability_loss(scratch_probability):.3f}",
    )
    print(
        "generation_loss=",
        f"{probability_loss(token_probability):.3f}",
    )
    print()


summarize(
    "current",
    energy_prediction=3.8,
    scratch_probability=0.35,
    token_probability=0.30,
)

summarize(
    "fix_regression_only",
    energy_prediction=4.7,
    scratch_probability=0.35,
    token_probability=0.30,
)

summarize(
    "fix_classification_only",
    energy_prediction=3.8,
    scratch_probability=0.80,
    token_probability=0.30,
)

summarize(
    "fix_generation_only",
    energy_prediction=3.8,
    scratch_probability=0.35,
    token_probability=0.75,
)

运行后会出现下面这样的结果。

[current]
regression_loss= 1.440
classification_loss= 1.050
generation_loss= 1.204

[fix_regression_only]
regression_loss= 0.090
classification_loss= 1.050
generation_loss= 1.204

[fix_classification_only]
regression_loss= 1.440
classification_loss= 0.223
generation_loss= 1.204

[fix_generation_only]
regression_loss= 1.440
classification_loss= 1.050
generation_loss= 0.288

这个例子里真正被操作的值,是 energy_predictionscratch_probabilitytoken_probability。把回归预测移近正确答案时,只有回归损失会下降;提高正确类别概率时,只有分类损失会下降;提高正确 token 概率时,只有生成损失会下降。因此,与其把这三个数字摆成一排后硬要判断“谁更糟”,不如先在同一种问题内部确认:改了什么值,哪一种损失才真的下降了。

回归预测修正前后的损失

分类正确类别概率修正前后的损失

生成正确 token 概率修正前后的损失

这三张图不会把不同问题类型硬塞进同一张图里,而是分别展示:在各自的问题内部,从当前 -> 修正后,损失怎样下降。回归是在把预测值挪近正确答案时下降,分类是在提高正确类别概率时下降,生成是在提高正确 token 概率时下降。因此,读图时也不应该先比较三张图柱子的绝对高度,而应该先看每一张图内部修正前后的变化。

这里还要再小心一层:目的并不是直接比较三个数字的绝对值。

问题类型 不那么糟的误读 更危险的误读 现在更该先确认的东西
回归 只看到 0.09 很小,所以大概已经不错 直接把回归损失 1.44 和分类损失 1.05 横着比较,断言谁更糟 先在同一种回归问题内部确认:它离正确值还有多远
分类 只觉得 scratch_prob=0.35 比较差 把概率型损失数字当成与回归误差相同单位来读 先看正确类别概率到底少了多少
生成 只觉得 confirm_token_prob=0.30 比较差 只靠一个生成损失数字就断定整句质量 先看各位置的正确 token 概率差距是怎样反复累积的

连到生成模型之后,会多看到什么

一旦把这一节继续连到生成模型,就会更容易看出:生成损失在结构上其实很像“把分类问题在长序列上不断重复”。

因此,LLM 也可以先被读成:一个非常大的分类问题,正在每个位置上不断重复“下一个 token 是谁”。

只要读者先掌握这条连接,后面 Part 5 再出现 token、next-token prediction、cross-entropy、perplexity 这些词时,就不会那么突兀。

也就是说,Part 5 对损失函数的说明,同时也是后面理解 LLM 训练方式的准备。

什么时候要按问题类型拆开看损失

在先理解了损失的一般角色之后,下一步就应该按当前问题里什么会被视为错来拆开看。

先出现的问题场景 应先想到的损失视角 理由
在预测连续数字 回归损失 因为核心是离正确数字有多远
必须答对正确类别 分类损失 因为核心是对正确类别给了多少置信度
要连续生成下一个 token 生成损失 因为核心是每个位置上对正确 token 给了多少概率
同样是错答,但置信度差异很重要 基于概率的分类 / 生成损失 因为必须比简单对错表更细地读分布差异

检查清单

  • 能说明为什么回归、分类、生成会使用不同的损失标准吗?
  • 能说清:问题类型一变,什么会被看成错误也会跟着改变吗?
  • 能说明损失函数会随着问题类型而改变吗?
  • 能解释:回归读数字误差,分类读正确类别概率,生成读下一个 token 概率吗?
  • 能说明:即便神经网络结构相同,只要最后输出的意义不同,损失标准也会跟着改变吗?
  • 在分类或生成里,如果只是简单对 / 错不够用,能重新拿出基于概率的损失解释吗?
  • 能把 next-token prediction 为什么会直接连到损失结构,说成“反复出现的分类式判断”吗?
  • 能掌握:下一节之后会继续看损失怎样被传回前面各层,也就是反向传播(backpropagation)吗?

出处与参考资料