交叉熵损失函数到底在惩罚什么:3个NumPy实验实战讲透,ML数学基础第4期

上一期我们手算了 softmax:把一堆分数变成概率,加起来等于 1。概率有了,新的问题来了:训练的时候,怎么判断模型"猜得好不好"?光看答对没答对太粗糙。90% 把握答对,和 51% 把握蒙对,都是"答对",能一样吗?今天讲交叉熵损失,它就是干这个的:专门衡量模型给出的概率"有多靠谱"。

先给直觉。交叉熵只盯一件事:正确答案那个位置,模型给了多少概率。公式长这样:loss = -Σ y log p。分类任务里 y 是 one-hot,正确答案的位置是 1,其余是 0,公式就塌缩成 loss = -log(p_正确)。模型在正确答案上给的概率越高,loss 越小;给的概率越低,loss 越大。就这么简单粗暴。

环境还是 numpy 一个包。今天 3 个实验,全部手算,跑一遍就记住。

实验一:同样的正确答案,模型"自信答对"和"自信答错",loss 差多少。正确答案是第 0 类。第一种情况模型押对了,分数 [3.0, 1.0, 0.2],softmax 之后概率大约是 [0.836, 0.113, 0.051]。第二种情况模型押错了,分数 [0.2, 1.0, 3.0],概率大约是 [0.051, 0.113, 0.836]。注意看,两种情况只是把最大概率从第 0 类挪到了第 2 类

import numpy as np def softmax(z): z = np.asarray(z, dtype=float) z = z - z.max() # 数值稳定:先减最大值 e = np.exp(z) return e / e.sum() def cross_entropy(p, y): eps = 1e-12 p = np.clip(p, eps, 1.0) # 避开 log(0),后面讲为什么 return -np.sum(y * np.log(p)) y = np.array([1, 0, 0]) p_right = softmax([3.0, 1.0, 0.2]) p_wrong = softmax([0.2, 1.0, 3.0]) print("答对:", np.round(p_right, 3), "loss =", round(float(cross_entropy(p_right, y)), 4)) print("答错:", np.round(p_wrong, 3), "loss =", round(float(cross_entropy(p_wrong, y)), 4))

输出:答对 loss = 0.1791,答错 loss = 2.9791。差了 16 倍还多。交叉熵最狠的地方就在这:它不只看你答没答对,还看你错的时候有多自信。51% 把握答错,loss 也就 0.67;83% 把握答错,loss 直接干到 2.98。训练就是在逼模型:没把握就别瞎自信。

实验二:训练时梯度长什么样。交叉熵配 softmax 有个漂亮的结论:loss 对原始分数(logits)的梯度,就是 p - y,一行搞定。直觉很好懂:正确答案的位置 y=1,梯度是 p-1,永远是负数,梯度下降会把这个分数往上推;答错的位置 y=0,梯度是 p,正数,往下压。推拉之间,概率分布就往正确答案靠。不信可以数值验证:

z = np.array([2.0, 1.0, 0.1]) y2 = np.array([0, 1, 0]) p = softmax(z) analytic = p - y2 # 解析梯度:一行 h = 1e-6 numeric = np.zeros_like(z) for i in range(len(z)): # 数值梯度:硬算验证 zp, zm = z.copy(), z.copy() zp[i] += h; zm[i] -= h numeric[i] = (cross_entropy(softmax(zp), y2) - cross_entropy(softmax(zm), y2)) / (2 * h) print("解析梯度:", np.round(analytic, 6)) print("数值梯度:", np.round(numeric, 6)) print("最大误差:", float(np.abs(analytic - numeric).max()))

输出两行梯度完全一致,最大误差 2e-10,基本就是浮点噪声。这个 p - y 的结论,面试被问烂了,但自己手算验证过一次,比背一百遍管用。

实验三:一个 batch 怎么算。实际训练一次喂几十上百个样本,每个样本一个 loss,最后要合成一个数。有两种合法规:mean(取平均)和 sum(求和)。我跑了个 3 样本的 batch,逐样本 loss 是 [0.1791, 0.22, 0.1323],mean 得到 0.1772,sum 得到 0.5315。选哪个?推荐 mean。mean 不随 batch size 变化,学习率调好一次就行;sum 的话,batch 从 32 换成 128,loss 直接翻 4 倍,学习率得重调。新手最常见的坑就是换了 batch size 忘了这茬,训练直接崩

还有个经典坑:log(0)。softmax 的概率可能被压到非常接近 0,log(0) 是负无穷,loss 直接变 inf,接着就是满屏 nan。上面代码里 np.clip(p, 1e-12, 1.0) 就是干这个的,把概率钳在 [1e-12, 1] 之间。PyTorch 的 CrossEntropyLoss 内部也是这么处理的,你手写的时候别漏了。

几个新手必踩的坑再点一遍。第一,忘记先 softmax,直接拿原始分数算交叉熵,公式里 log 的对象都不是概率,算出来全是错的。第二,mean 和 sum 混用还不调学习率,batch size 一换训练就崩。第三,标签不是 one-hot 的情况,比如 label smoothing 把标签抹成 [0.9, 0.05, 0.05],公式照样能用,y 直接换成这个概率分布就行,交叉熵本来衡量的就是两个分布的距离。

收藏这篇,交叉熵这套东西,面试、调模型、看论文天天见。公式背下来没用,3 个实验跑一遍,下次看到 loss 曲线抖一下,你大概能猜到是哪里的问题。

下期预告:ML数学基础第5期,讲"反向传播的链式法则"。p - y 只是最后一层的梯度,前面几十层的梯度怎么一层层传回去?NumPy 手写一个两层网络,亲眼看梯度流动。关注我,下期不错过。

留个问题:你有没有遇到过 loss 突然变成 nan 的情况?最后查出来是什么原因?评论区说说,看看大家踩的是不是同一个坑。

Cyrus

相关新闻

「记忆越少反而越聪明」:Hy-Memory 的反直觉设计为什么被全网热议

「记忆越少反而越聪明」:Hy-Memory 的反直觉设计为什么被全网热议

「记忆越少反而越聪明」:Hy-Memory 的反直觉设计为什么被全网热议 【免费下载链接】Hy-Memory 项目地址: https://gitcode.com/gh_mirrors/hy/Hy-Memory 2026 年 10 月 16 日,腾讯混元将 Hy Memory 2.0 整体开源:hy-memory SDK&#…

2026/10/20 2:21:27 阅读更多 →
【C++/Qt 进阶】设计模式系列(5):适配器模式——给“不兼容的接口“贴一层翻译膜

【C++/Qt 进阶】设计模式系列(5):适配器模式——给“不兼容的接口“贴一层翻译膜

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 2:21:27 阅读更多 →
【沃思智能景观照明节能控制:点亮城市夜色,守护每一度电】

【沃思智能景观照明节能控制:点亮城市夜色,守护每一度电】

亮化工程是城市夜景的点睛之笔,从地标建筑到滨水步道,从主题公园到商业街区,景观照明用光与影塑造着城市的夜间表情。然而,璀璨夺目的背后,往往伴随着高昂的电费账单、繁重的运维压力以及日益受关注的光污染问题。如何…

2026/10/20 2:20:27 阅读更多 →

最新新闻

本地推理实战:用llama.cpp与ollama部署LFM2.5-1.2B小模型

本地推理实战:用llama.cpp与ollama部署LFM2.5-1.2B小模型

1. 上手前的心里话:为什么大家都盯着小模型本地推理最近圈子里聊本地大模型,基本绕不开两个东西:llama.cpp 和 ollama。而我这段时间一直在折腾的主角,是 LFM2.5-1.2B 这个模型。别看它只有 1.2B 参数,实测下来每秒能跑…

2026/10/20 3:51:14 阅读更多 →
CPU推理LFM2.5-1.2B:llama.cpp与ollama的15token/s实战

CPU推理LFM2.5-1.2B:llama.cpp与ollama的15token/s实战

). To avoid truncated thinking or repeated loops, set appropriate stop sequences; generate_enough tokens because thinking consumes budget; temperature lower (0.6-0.7); maybe set--no-cnv? Simpler: stop attags if present; handle "过度思考" issue b…

2026/10/20 3:51:14 阅读更多 →
PyTorch 2.1神经网络构建核心:计算图、编译与内存控制

PyTorch 2.1神经网络构建核心:计算图、编译与内存控制

1. 这不是“Hello World”式教学:为什么从PyTorch 2.1开始构建神经网络,必须绕开90%初学者踩过的坑你点进来的这个标题——“【PyTorch】2.1 使用Pytorch构建一个神经网络”——看起来平平无奇,甚至有点过时。毕竟PyTorch都出到2.3了&#xf…

2026/10/20 3:51:14 阅读更多 →
LiteLLM实战:统一大模型网关的部署与路由策略

LiteLLM实战:统一大模型网关的部署与路由策略

1. 项目概述:LiteLLM 到底是什么,凭什么值得关注干了这些年大模型应用开发,我最大的痛感就是“供应商锁定”和“接口碎片化”。今天调这家模型用一套参数,明天换那家模型又是另一套鉴权和超时策略,光适配层代码就写到手…

2026/10/20 3:51:14 阅读更多 →
OpenClaw Agent日均成本从50元到0.48元:AI工具调用优化实战

OpenClaw Agent日均成本从50元到0.48元:AI工具调用优化实战

1. 一天50块是怎么烧掉的:一次天气查询的完整计费分解先说个真实的场景。某位朋友在群里截图问我:他给OpenClaw配好了工具链,让它每天早上9点自动查一次当天的天气,顺便提醒要不要带伞。结果月底一看账单,光这一条自动…

2026/10/20 3:51:14 阅读更多 →
技能管理实战:识别、组合与迁移,打造个人核心竞争力

技能管理实战:识别、组合与迁移,打造个人核心竞争力

有一次帮一位朋友梳理简历,他接到一个面试问题——“你最擅长的三项技能是什么”。他愣了半天,最后写的是"Excel、PPT、沟通"。写完连他自己都不信,觉得这跟没说一样。那一刻我突然意识到一件事:我们几乎每天都在提&quo…

2026/10/20 3:50:14 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →