损失函数(loss function)是机器学习里用来衡量「模型预测得有多不准」的一个数:预测离真实答案越远,这个数越大;完全猜中,这个数最小(通常是 0)。它还有个近义名叫代价函数(cost function),日常基本混用。
打个比方:模型在参加一场「预测考试」,每道题它给出答案,损失函数就是阅卷老师——不直接告诉你正确答案是什么,只给你扣分。答案离谱就狠狠扣,接近正确就少扣。模型的目标,就是反复练习,把这份扣分压到最低。
它在 AI 体系里的位置
损失函数属于机器学习的核心基石之一,和它形影不离的两个伙伴是:
- 梯度下降——告诉模型「往哪个方向调,扣分才能变小」。它需要损失函数先算出扣分,再倒推出每个参数该怎么动。
- 优化器(optimizer)——决定「每次具体走多大一步、怎么走」,是执行调整动作的角色。常见的有 SGD、Adam。
这里有个词叫参数(parameter),可以理解为模型内部的「旋钮」——训练就是在拧这些旋钮,让预测变准。而梯度(gradient)就是损失对每个旋钮「往哪个方向拧会变小」的指示。
三者串起来就是一次训练:损失函数打分 → 梯度下降指方向 → 优化器迈步子,循环往复直到扣分不再下降。可以说,损失函数是整个训练流程的「发令枪」——没有它,模型根本不知道该往哪儿学。
图 1:一次训练就是「损失函数打分 → 梯度下降指方向 → 优化器迈步子」的循环。
两种最常用的损失函数
任务不同,阅卷标准也不同。深度学习里最常用的有两类。
MSE:回归任务的标尺
回归(预测一个连续的数值,比如房价、气温)最常用均方误差(Mean Squared Error, MSE):
符号解读:
—— 第 个样本的真实值(标准答案) —— 模型对这个样本的预测值(头顶的帽子 是「估计」的意思) —— 误差的平方。平方有两个作用:① 让正负误差不抵消 ② 错得越离谱罚得越狠,平方把大误差放大 —— 样本总数, 就是求平均
通俗理解:把每个预测的偏差平方后求平均。对应「扣分」——偏差越大,平方后扣分涨得越快,是「非线性加重处罚」。
图 2:MSE 的抛物线——误差被平方,大误差的罚分不成比例地放大。
交叉熵:分类任务的标尺
分类(预测属于哪一类,比如识别图片是猫还是狗)最常用交叉熵损失(Cross-Entropy Loss)。二分类的版本是:
符号解读:
—— 真实标签,1 表示正类(比如真是猫),0 表示负类 —— 模型预测「是正类」的概率(0 到 1 之间) —— 对数函数,作用是「概率越接近 0,惩罚越趋于无穷大」 - 最前面的负号
—— 因为 在 0~1 之间时 是负数,外层加负号把损失翻成非负值,完全猜对时为 0 - 整个式子用
和 做开关:真实是 1 时只算前半段,真实是 0 时只算后半段
通俗理解:模型把真答案的概率压得越低,扣分越狠(对数让低概率被重罚)。比如真是猫(
图 3:两把标尺的分工——MSE 量连续数值差(回归),交叉熵量概率分布差(分类)。
一个计算示例:MSE 怎么算
假设预测 3 套房子的价格(万元):
| 样本 | 真实价 | 预测价 | 误差 | 误差平方 |
|---|---|---|---|---|
| 房 1 | 300 | 280 | 20 | 400 |
| 房 2 | 500 | 550 | -50 | 2500 |
| 房 3 | 200 | 210 | -10 | 100 |
代入公式:
自检:所有误差平方都非负,平均 1000 也非负 ✓。房 2 偏差最大(-50),贡献了 2500 的扣分——平方放大了大错,符合「错得越离谱罚越重」。
PyTorch 里怎么写
在 PyTorch 里,损失函数是 torch.nn 模块下现成的类,直接实例化就能用:
import torch
import torch.nn as nn
# MSE:回归任务用
mse_loss = nn.MSELoss() # 均方误差,nn.MSELoss 是 PyTorch 内置类
# 交叉熵:分类任务用(注意:它内部自带 softmax,直接喂原始得分 logits 即可)
ce_loss = nn.CrossEntropyLoss() # 交叉熵,传预测的原始得分和真实类别编号穿插在训练里就一行 loss = loss_fn(预测, 真实),算出损失后交给 backward() 自动算梯度,再由优化器更新参数——上一节讲的「打分 → 指方向 → 迈步」就落地了。
完整代码
下面用 MSE 训练一个极小的线性模型,让它学会「一个数的两倍」这个规律。整体流程是:造数据 → 搭模型 → 反复练习(预测→扣分→反向→更新)→ 考试看学会没。
import torch
import torch.nn as nn
# ===== 任务:教模型学会「y = 2x」这个规律 =====
torch.manual_seed(42)
x_train = torch.linspace(1, 10, 20).reshape(-1, 1) # 输入:1 到 10 的 20 个数
y_train = 2 * x_train # 真实答案:每个数的两倍
# ===== 定义模型:一个最简单的线性层 y = w·x + b =====
model = nn.Linear(1, 1) # nn.Linear(输入维度1, 输出维度1):最简单的线性变换
opt = torch.optim.SGD(model.parameters(), lr=0.01) # 优化器:根据梯度调整参数,lr 是步长
loss_fn = nn.MSELoss() # 损失函数:均方误差(本文讲的那把回归标尺)
# ===== 训练:反复看样本、扣分、调整,直到学会 =====
for epoch in range(300):
pred = model(x_train) # 模型预测
loss = loss_fn(pred, y_train) # 用 MSE 算「扣分」(损失函数的核心作用)
opt.zero_grad() # 清空上一轮的梯度
loss.backward() # 反向传播:自动算每个参数该往哪调(梯度下降的依据)
opt.step() # 优化器迈一步:用梯度更新 w 和 b
# ===== 测试:模型学会「两倍」了吗?=====
test_x = torch.tensor([[5.0]])
print(f"输入 5,模型预测:{model(test_x).item():.2f}(标准答案 10)")
print(f"训练结束时的 loss:{loss.item():.4f}")运行输出约为 输入 5,模型预测:10.00(标准答案 10)——读者能看到模型真的从随机参数学到了「两倍」规律,而损失函数(loss_fn)一直在背后打分、驱动每一次调整。
小结
一句话浓缩:损失函数是给模型预测「扣分」的阅卷老师,它把「有多不准」变成一个数,驱动整个学习过程。 回归找 MSE,分类找交叉熵,记住这两把标尺,就抓住了 90% 的日常用法。
参考资料
- Deep Learning (Goodfellow 等) 第 5/6 章:基于似然的损失函数 - 经典教材,从最大似然推出 MSE 与交叉熵的统一根源 https://ickma2311.github.io/ML/likelihood-loss-functions.html
- Loss Functions in Deep Learning: A Comprehensive Review - arXiv 2025 综述论文 https://arxiv.org/html/2504.04242v1
- PyTorch 官方文档:Loss Functions - torch.nn 模块下所有损失函数的 API 说明 https://pytorch.org/docs/stable/nn.html#loss-functions