游乐游手机版
首页/AI教程/文章详情

一文详解深度学习中的Softmax是什么?原理与应用

时间:2026-06-08 15:43
09aaab-Softmax是什么? 这篇文章会把 Softmax 函数彻底讲清楚。从最直观的类比,到严谨的数学定义,再到手算验证、核心性质、数值稳定性问题,最后还会附上 NumPy 和 PyTorch 的代码实现。如果你对 Transformer 里的注意力机制也感兴趣,那 Softmax 在其中

09aaab-Softmax是什么?

这篇文章会把 Softmax 函数彻底讲清楚。从最直观的类比,到严谨的数学定义,再到手算验证、核心性质、数值稳定性问题,最后还会附上 NumPy 和 PyTorch 的代码实现。如果你对 Transformer 里的注意力机制也感兴趣,那 Softmax 在其中扮演的关键角色这里也一并涵盖了。

09aaab-Softmax是什么?

阅读路线图如下:先从直观类比入手理解 Softmax 是什么,然后掌握核心公式并拆解每个部分的作用。接着用手算例子验证公式,再深入了解三大性质,最后攻克数值稳定性问题并看代码实战。

1. 什么是 Softmax?

1.1 直观类比:投票计数器

想象一下班级评选“最受欢迎的同学”。每个同学都可以给其他人打分——分数任意,正数代表喜欢,负数代表讨厌。但最终我们需要的是每个人的“得票百分比”,加起来正好 100%。

Softmax 函数干的活就和这个“投票计数器”差不多:输入是任意实数(同学们的“支持度打分”),输出则是 [0,1] 之间的概率值并且总和为 1(最终的“得票百分比”)。关键的区别在于,Softmax 不是简单按比例缩放,它通过指数函数 exe^x 放大了输入之间的差异,让得分高的获得更高权重,得分低的则被进一步压制。

1.2 基本定义

Softmax 函数,也叫 softargmax 或归一化指数函数,其作用是把任意实数向量转化为概率分布。给定一个 K 维实数向量 x=[x1,x2,,xK]mathbf{x} = [x_1, x_2, ldots, x_K],它对每个元素 xix_i 的输出为:

softmax(xi)=exij=1Kexjtext{softmax}(x_i) = frac{e^{x_i}}{sum_{j=1}^{K} e^{x_j}}

其中 e2.71828e approx 2.71828 是自然对数的底。输出自然满足两个条件,确保它成为一个合法的概率分布:每个值都在 (0,1) 之间,且所有值之和恰好为 1。

2. 核心公式

Softmax 的计算其实就分两步。第一步是“指数化”:对每个输入 xix_i 计算 exie^{x_i}。第二步是“归一化”:将每个指数值除以所有指数值的总和。

#### 2.1 为什么要用指数函数 exe^x? 指数函数在这里扮演了三个关键角色。首先,它把任意实数映射为正数—— ex>0e^x > 0 对任何实数 x 都成立,这保证了输出为正。其次,它放大了差异——指数函数的增长速度极快,e320.1e^3 approx 20.1e12.72e^1 approx 2.72,即使输入只差 2,输出已经差了将近 7 倍——这让高分者能脱颖而出。最后,它保持了单调性:exe^x 严格递增,输入的顺序被忠实地保留下来。

2.2 为什么分母要用求和?

分母 jexjsum_{j} e^{x_j} 的作用就是归一化。把所有指数值加起来作为“总基数”,每个指数值除以这个总基数,结果就是每个输出变成了相对占比,范围在 0 到 1 之间,而且所有输出加起来恰好等于 1——一个标准的概率分布。

3. 手算示例

光说不练假把式。假设输入向量 x=[2.0,1.0,0.1]mathbf{x} = [2.0, 1.0, 0.1],咱们一步步来算。

第一步,计算指数值:e2.0=7.389e^{2.0} = 7.389e1.0=2.718e^{1.0} = 2.718e0.1=1.105e^{0.1} = 1.105

第二步,计算分母:7.389+2.718+1.105=11.2127.389 + 2.718 + 1.105 = 11.212

第三步,计算每个 Softmax 值:softmax(x1)=7.389/11.212=0.659text{softmax}(x_1) = 7.389 / 11.212 = 0.659softmax(x2)=0.242text{softmax}(x_2) = 0.242softmax(x3)=0.099text{softmax}(x_3) = 0.099。验算一下,总和 0.659+0.242+0.099=1.0000.659 + 0.242 + 0.099 = 1.000,完美。

注意到输入最高的 2.0 获得了 65.9% 的权重,而最低的 0.1 只拿到了 9.9%。输入之间的原始差距是 1.9,而输出权重的差距被放大到了 0.56。这就是指数函数在起作用。

4. 核心性质

4.1 保序性(Order Preservation)

这个性质很好理解:如果 xi>xjx_i > x_j,那么 softmax(xi)>softmax(xj)text{softmax}(x_i) > text{softmax}(x_j)。简单说,打分最高的同学,最终得票率也是最高的。Softmax 不会“碘伏”排名。数学上这是因为指数函数严格单调递增,而且除以同一个正分母不会改变大小关系。

4.2 平移不变性(Translation Invariance)

这个性质非常有用:如果对输入向量的所有元素同时加上同一个常数 c,Softmax 的输出不变。证明也很直接,分子分母同时提取出一个 ece^c 约掉就行了。直观理解就是,假设所有同学的分数都加了 10 分,大家加的一样多,最终得票百分比不变。这个性质是后面数值稳定性技巧的理论基础——我们可以安全地减去最大值来防止溢出,而不改变结果。

4.3 非缩放不变性(Non-Scaling Invariance)

和平移不同,如果对所有元素同时乘以一个正数 a(且 a≠1),Softmax 的输出会改变。当 a>1 时,所有分数被“拉大”,高分的优势被进一步放大,输出分布更“尖锐”。当 0

这一点在 Transformer 的注意力机制中体现得很直接。缩放因子 1dkfrac{1}{sqrt{d_k}} 正是通过缩小点积分数,防止 Softmax 输出过于尖锐,从而避免进入梯度很小的饱和区。

5. 数值稳定性

5.1 问题:直接计算可能产生 NaN

考虑输入 x=[1000,2000,4000]mathbf{x} = [1000, 2000, -4000],直接按公式计算 e2000e^{2000} 直接就超出 float64 的可表示范围,变成无穷大,分子分母都是无穷大,结果是 NaN,计算直接失败。

5.2 解决方案:减去最大值

利用平移不变性,从每个元素中减去最大值 max(x)max(x) 即可。公式变成 softmax(xi)=eximax(x)jexjmax(x)text{softmax}(x_i) = frac{e^{x_i - max(x)}}{sum_{j} e^{x_j - max(x)}}

5.3 数学证明

这个技巧的数学基础就是平移不变性。通过引入一个常数 C,可以推导出这个形式。令 logC=max(x)log C = -max(x),就得到上面的形式。这个变换在数学上是完全等价的。

5.4 为什么这样就稳定了?

减去最大值后,所有指数输入都小于等于 0,因此 eximax(x)e^{x_i - max(x)} 严格在 0 到 1 之间。最大值对应的指数是 e0=1e^0 = 1,所以分母至少是 1,不会出现除以零的情况。这样就彻底解决了溢出问题。

6. 代码示例

理论说完了,看代码最直观。

6.1 NumPy 手动实现

import numpy as np

# 朴素实现(不推荐,数值不稳定)
def softmax_naive(x):
    exp_x = np.exp(x)
    return exp_x / np.sum(exp_x)

# 数值稳定实现(推荐)
def softmax(x):
    x_shifted = x - np.max(x)  # 利用平移不变性
    exp_x = np.exp(x_shifted)  # 所有值 ≤ 1,不会溢出
    return exp_x / np.sum(exp_x)

# 测试
x_small = np.array([2.0, 1.0, 0.1])
print("普通输入:", softmax(x_small))  # [0.659, 0.242, 0.099]
print("和:", np.sum(softmax(x_small)))  # 1.0

x_large = np.array([1000.0, 2000.0, -4000.0])
print("大数值输入(稳定版):", softmax(x_large))  # [0., 1., 0.]
print("和:", np.sum(softmax(x_large)))  # 1.0

6.2 PyTorch 原生实现

import torch
import torch.nn as nn

x = torch.tensor([2.0, 1.0, 0.1])

# 方式1:函数式 API
output = torch.softmax(x, dim=0)
print("torch.softmax 输出:", output)  # [0.659, 0.242, 0.099]
print("和:", output.sum())  # 1.0

# 方式2:模块化 API
softmax_layer = nn.Softmax(dim=0)
output2 = softmax_layer(x)

# 二维输入示例
x_batch = torch.randn(2, 3)  # 2个样本,3个类别
output_batch = torch.softmax(x_batch, dim=1)
print("每行和:", output_batch.sum(dim=1))  # [1.0, 1.0]

6.3 PyTorch 内置的数值稳定处理

PyTorch 的 torch.softmaxF.softmax 内部已经实现了 xmax(x)x - max(x) 的数值稳定技巧,开发者直接调用即可。此外,F.log_softmax 使用了更稳定的 log-sum-exp 技巧,避免了 log(0) 的问题,推荐与 NLLLoss 配合使用。

import torch.nn.functional as F

x = torch.tensor([2.0, 1.0, 0.1])
log_probs = F.log_softmax(x, dim=0)
print("log_softmax:", log_probs)  # [-0.4170, -1.4170, -2.3170]
print("exp(log_softmax):", torch.exp(log_probs))  # 还原为 Softmax

7. 总结

回顾一下核心要点:Softmax 将任意实数向量转为概率分布,输出在 (0,1) 间且和为 1。它具有保序性、平移不变性(这是数值稳定技巧的数学基础)和非缩放不变性(这是注意力缩放因子的理论依据)。数值稳定计算时先减去最大值,在 Transformer 中它让注意力能够“聚焦”。

最后记住几个关键理解:Softmax 的本质就是“指数化 + 归一化”;数值稳定的 xmax(x)x - max(x) 不是取巧,而是平移不变性的直接推论;在 Transformer 中,Softmax 是注意力“聚焦”能力的数学核心——没有它,模型无法区分该关注谁。

来源:https://juejin.cn/post/7644244414396563465
上一篇Claude Code 进阶用法全面高效实战技巧案例深入解析 下一篇超级能力工具结合克劳德代码的初步实战
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Kimi App手机电脑联动下载安装及浏览器兼容教程
AI教程 · 2026-06-09

Kimi App手机电脑联动下载安装及浏览器兼容教程

本文介绍了Kimi智能助手从手机端到电脑端的下载与安装方法,重点阐述了不同平台(包括iOS、Android、Windows、macOS)的获取途径。同时,详细说明了如何通过浏览器直接访问网页版,并针对主流浏览器的兼容性进行了分析,旨在帮助用户根据自身设备选择最便捷、稳定的使用方式。

HeyGen稳定安装步骤:先配置创意团队环境再注册开通
AI教程 · 2026-06-09

HeyGen稳定安装步骤:先配置创意团队环境再注册开通

HeyGen的稳定安装与高效使用,关键在于前期团队环境的统一规划与后期账号流程的顺畅完成。团队需明确设计规范、素材管理及权限分工,为工具运行打下基础。随后,通过官方渠道完成注册、验证及订阅开通,确保服务稳定。最后进行基础功能测试与团队培训,即可快速投入实际创作流程。

Mochi 1从零搭建本地服务与工作流导入指南
AI教程 · 2026-06-09

Mochi 1从零搭建本地服务与工作流导入指南

本文介绍了在成功完成Mochi1本地服务的基础搭建后,如何继续处理工作流导入这一关键后续步骤。内容涵盖工作流文件准备、导入操作的具体流程、常见问题的排查与解决,以及导入后的配置优化与测试验证,旨在帮助用户将预设的自动化流程顺利集成到本地环境中,确保工具发挥完整效能。

InvokeAI Linux用户安装配置与节点处理指南
AI教程 · 2026-06-09

InvokeAI Linux用户安装配置与节点处理指南

本文详细介绍了在Linux系统上安装和配置InvokeAI的完整流程。内容涵盖从环境准备、依赖安装到模型下载与加载的关键步骤,并重点解析了核心组件“处理节点”的安装与使用方法。指南旨在帮助用户顺利完成部署,并理解其工作流程,以便更好地利用这一AI图像生成工具进行创作。

Dify保姆级部署指南:服务安装与模型接入下载
AI教程 · 2026-06-09

Dify保姆级部署指南:服务安装与模型接入下载

本文详细介绍了开源AI应用开发平台Dify的部署流程。内容涵盖从服务器环境准备、Docker安装、Dify核心服务启动,到如何接入OpenAI、Azure等云端大模型API,以及如何配置Ollama等本地模型。最后,还提供了使用ModelScope社区下载特定模型文件并集成到本地环境中的具体操作方法,旨在帮助用户快速搭建属于自己的AI应用开发与测试平台。