softmax 函数首先是一个函数,它将含有K 个实值的向量转换为 K 个总和为1的实值向量。向量的K个输入值可以是正数、负数、零或大于 1,但 softmax 能将它们转换为介于0 和 1,因此它们可以被解释为概率。如果其中一个输入较小或为负,则softmax将其变成小概率,如果输入较大,则将其变成大概率,但始终保持在0和1之间。
softmax 函数有时称为 softargmax 函数,或多类逻辑回归。这是因为 softmax 是逻辑回归的泛化(逻辑回归只是softmax的一种特殊情况,属于二分类),可用于多类分类,其公式与逻辑回归中使用的 sigmoid 函数非常相似。 softmax 函数只能在类互斥时用于分类器。
在多层神经网络中,网络的倒数第二层通常输出一组数字,如果不将这组数字适当缩放,那么这组数字将难以使用和理解。这里 softmax 非常有用,因为它将倒数第二层输出的实值向量转换为归一化的概率分布,可以向用户显示或用作其他系统的输入。出于这个原因,通常会附加一个 softmax 函数作为神经网络的最后一层,作为网络的输出层,用于多分类学习问题。
softmax 公式如下:
σ ( z ⃗ ) i = e z i ∑ j = 1 K e z j \sigma(\vec{z})_{i}=\frac{e^{z_{i}}}{\sum_{j=1}^{K} e^{z_{j}}} σ(z)i=∑j=1Kezjezi
参数 | 意义 |
---|---|
z ⃗ \vec{z} z | softmax 函数的输入向量,由 (z0, … zK) 组成 |
z i z_{i} zi | 所有的 z i z_i zi 值都是 softmax 函数的输入向量的元素,它们可以取任何实数值,正、零或负。例如,神经网络可能会输出一个向量,例如 (-0.62, 8.12, 2.53),这不是有效的概率分布,因此需要使用 softmax。 |
e z i e^{z_{i}} ezi | 标准指数函数应用于输入向量的每个元素。这给出了一个大于 0 的正值,如果输入为负,它会非常小,如果输入很大,它会非常大。然而,它仍然没有固定在 (0, 1) 范围内,这是概率所要求的。 |
∑ j = 1 K e z j \sum_{j=1}^{K} e^{z_{j}} ∑j=1Kezj | 公式底部的项是归一化项。它确保函数的所有输出值总和为 1,并且每个值都在 (0, 1) 范围内,从而构成有效的概率分布。 |
K K K | 多类分类器中的类数。 |
想象一下,我们有一个包含三个实数的数组。这些值通常可以是机器学习模型(例如神经网络)的输出。我们想将这些值转换为概率分布。
[ 8 5 0 ] \left[\begin{array}{l} 8 \\ 5 \\ 0 \end{array}\right] ⎣⎡850⎦⎤
首先我们可以计算输入数组的每个元素的指数。这是 softmax 方程上半部分。
e z 1 = e 8 = 2981.0 e z 2 = e 5 = 148.4 e z 3 = e 0 = 1.0 \begin{gathered} e^{z_{1}}=e^{8}=2981.0 \\ e^{z_{2}}=e^{5}=148.4 \\ e^{z_{3}}=e^{0}=1.0 \end{gathered} ez1=e8=2981.0ez2=e5=148.4ez3=e0=1.0
这些值看起来不像概率。注意在输入元素中,虽然8只比5大一点,但由于指数的影响,2981比148大很多。我们可以通过对所有三个指数项求和来获得归一化项,即 softmax 方程的下半部分:
∑ j = 1 K e z j = e z 1 + e z 2 + e z 3 = 2981.0 + 148.4 + 1.0 = 3130.4 \sum_{j=1}^{K} e^{z_{j}}=e^{z_{1}}+e^{z_{2}}+e^{z_{3}}=2981.0+148.4+1.0=3130.4 j=1∑Kezj=ez1+ez2+ez3=2981.0+148.4+1.0=3130.4
我们看到归一化项一直由 z1 主导。
最后,除以归一化项,我们得到三个元素中每一个的 softmax 输出。请注意,没有单个输出值,因为 softmax 将数组转换为相同长度的数组,在本例中为 3。
σ ( z ⃗ ) 1 = 2981.0 3130.4 = 0.9523 σ ( z ⃗ ) 2 = 148.4 3130.4 = 0.0474 σ ( z ⃗ ) 3 = 1.0 3130.4 = 0.0003 \begin{aligned} \sigma(\vec{z})_{1} &=\frac{2981.0}{3130.4}=0.9523 \\ \sigma(\vec{z})_{2} &=\frac{148.4}{3130.4}=0.0474 \\ \sigma(\vec{z})_{3} &=\frac{1.0}{3130.4}=0.0003 \end{aligned} σ(z)1σ(z)2σ(z)3=3130.42981.0=0.9523=3130.4148.4=0.0474=3130.41.0=0.0003
从计算结果,我们可以看出有三个输出值,而且都是有效的概率,即它们位于 0 和 1 之间,并且它们的总和为 1。
还要注意,由于指数运算,第一个元素 8 主导了 softmax 函数,并将 5 和 0 挤出为非常低的概率值。
如果在机器学习模型中使用 softmax 函数,在将其解释为真实概率之前应该小心,因为它倾向于产生非常接近 0 或 1 的值。如果神经网络的输出为 [8, 5, 0],就像在这个例子中一样,那么 softmax 函数会将 95% 的概率分配给第一类,而实际上神经网络的预测可能会有更多的不确定性。这可能给人的印象是神经网络预测具有很高的置信度,而事实并非如此。
如上所述,softmax函数和sigmoid函数类似。 softmax 对向量进行操作,而 sigmoid 则采用标量。
Softmax σ ( z ⃗ ) i = e z i ∑ j = 1 K e z j \operatorname{Softmax} \sigma(\vec{z})_{i}=\frac{e^{z_{i}}}{\sum_{j=1}^{K} e^{z_{j}}} Softmaxσ(z)i=∑j=1Kezjezi
Sigmoid S ( x ) = 1 1 + e − x \operatorname{Sigmoid} S(x)=\frac{1}{1+e^{-x}} SigmoidS(x)=1+e−x1
实际上,对于只有两个输入类的分类器,sigmoid 函数是 softmax 函数的特例。如果我们将输入向量设置为 [x, 0] 并使用通常的 softmax 公式计算第一个输出元素,我们可以证明这一点:
σ ( z ⃗ ) 1 = e z 1 e z 1 + e z 2 = e x e x + e 0 = e x e x + 1 \sigma(\vec{z})_{1}=\frac{e^{z_{1}}}{e^{z_{1}}+e^{z_{2}}}=\frac{e^{x}}{e^{x}+e^{0}}=\frac{e^{x}}{e^{x}+1} σ(z)1=ez1+ez2ez1=ex+e0ex=ex+1ex
将顶部和底部除以 ex,我们得到:
σ ( z ⃗ ) 1 = 1 1 + e − x \sigma(\vec{z})_{1}=\frac{1}{1+e^{-x}} σ(z)1=1+e−x1
这表明当我们有两个类时,sigmoid 函数变得等价于 softmax 函数。没有必要显式计算第二个向量分量,因为当有两个概率时,它们的和必须为 1。所以,如果我们开发一个带有逻辑回归的二分类分类器,我们可以使用 sigmoid 函数,不需要使用向量。但是如果我们有两个以上的互斥类,应该使用 softmax。
如果有两个以上的类并且它们不是互斥的(多标签分类器),则可以将分类器拆分为多个二元分类器,每个分类器使用自己的 sigmoid 函数。
如果我们采用输入向量 [3, 0],我们可以将其放入 softmax 和 sigmoid 函数中。由于 sigmoid 采用标量值,我们只将第一个元素放入 sigmoid 函数中。
Softmax
σ ( z ⃗ ) 1 = σ ( 3 ) = e 3 e 3 + e 0 = 0.953 σ ( z ⃗ ) 2 = σ ( 0 ) = e 0 e 3 + e 0 = 0.0474 \begin{gathered} \sigma(\vec{z})_{1}=\sigma(3)=\frac{e^{3}}{e^{3}+e^{0}}=0.953 \\ \sigma(\vec{z})_{2}=\sigma(0)=\frac{e^{0}}{e^{3}+e^{0}}=0.0474\\ \end{gathered} σ(z)1=σ(3)=e3+e0e3=0.953σ(z)2=σ(0)=e3+e0e0=0.0474
Sigmoid
S ( x ) = S ( 3 ) = 1 1 + e − 3 = 1 1 + e − 3 = 0.953 \begin{gathered} S(x)=S(3)=\frac{1}{1+e^{-3}}=\frac{1}{1+e^{-3}}=0.953 \end{gathered} S(x)=S(3)=1+e−31=1+e−31=0.953
sigmoid 函数给出与第一个元素的 softmax 相同的值,前提是第二个输入元素设置为 0。 由于 sigmoid 给了我们一个概率,并且两个概率必须相加为 1,因此没有必要显式计算第二个元素的值。
softmax 函数被开发为 argmax 函数的平滑且可微的替代方案。因此,有时更明确地将 softmax 函数称为 softargmax 函数。与 softmax 一样,argmax 函数对向量进行操作,并将除最大值外的每个值都转换为零,在最大值出则返回 1。
argmax ( [ z 1 z 2 . . z n ] ) = [ y 1 y 2 ⋅ ⋅ y n ] = [ 0 . . 1 . . 0 ] \operatorname{argmax}\left(\left[\begin{array}{c} z_{1} \\ z_{2} \\ . . \\ z_{n} \end{array}\right]\right)=\left[\begin{array}{c} y_{1} \\ y_{2} \\ \cdot \cdot \\ y_{n} \end{array}\right]=\left[\begin{array}{c} 0 \\ . . \\ 1 \\ . . \\ 0 \end{array}\right] argmax⎝⎜⎜⎛⎣⎢⎢⎡z1z2..zn⎦⎥⎥⎤⎠⎟⎟⎞=⎣⎢⎢⎡y1y2⋅⋅yn⎦⎥⎥⎤=⎣⎢⎢⎢⎢⎡0..1..0⎦⎥⎥⎥⎥⎤
where y i = 1 y_{i}=1 yi=1 if z i z_{i} zi is the unique maximum value of z ⃗ \vec{z} z
让我们再次假设输入向量 [3, 0]。我们像以前一样计算 softmax。最大值是第一个元素,因此 argmax 将为第一个元素返回 1,为其余元素返回 0。
Softmax
σ ( z ⃗ ) 1 = σ ( 3 ) = e 3 e 3 + e 0 = 0.953 σ ( z ⃗ ) 2 = σ ( 0 ) = e 0 e 3 + e 0 = 0.0474 \begin{gathered} \sigma(\vec{z})_{1}=\sigma(3)=\frac{e^{3}}{e^{3}+e^{0}}=0.953 \\ \sigma(\vec{z})_{2}=\sigma(0)=\frac{e^{0}}{e^{3}+e^{0}}=0.0474 \\ \end{gathered} σ(z)1=σ(3)=e3+e0e3=0.953σ(z)2=σ(0)=e3+e0e0=0.0474
Argmax
argmax ( z ⃗ ) = argmax ( [ 3 0 ] ) = [ 1 0 ] argmax ( z ⃗ ) 1 = 1 argmax ( z ⃗ ) 2 = 0 \begin{gathered} \operatorname{argmax}(\vec{z})=\operatorname{argmax}\left(\left[\begin{array}{l} 3 \\ 0 \end{array}\right]\right)=\left[\begin{array}{l} 1 \\ 0 \end{array}\right] \\ \operatorname{argmax}(\vec{z})_{1}=1 \\ \operatorname{argmax}(\vec{z})_{2}=0 \end{gathered} argmax(z)=argmax([30])=[10]argmax(z)1=1argmax(z)2=0
从这个例子中可以清楚地看出,softmax 的行为类似于 argmax 的“软”近似:它返回 0 到 1 之间的非整数值,可以解释为概率。如果我们使用机器学习模型进行推理,而不是训练它,我们可能希望系统的整数输出代表我们将用模型输出做出的艰难决定,例如治疗肿瘤、验证用户或将文档分配给主题。从这个意义上说,argmax 值更容易使用,可用于构建混淆矩阵并计算分类器的精度和召回率。
神经网络中的 Softmax 函数
softmax 函数的一种用途是在神经网络的末尾。让我们考虑一个卷积神经网络,它可以识别图像是猫还是狗。请注意,图像必须是猫或狗,不能两者都是,因此这两个类是互斥的。通常,该网络的最终全连接层会产生 [-7.98, 2.39] 之类的值,这些值未归一化且不能解释为概率。如果我们在网络中添加一个 softmax 层,就可以将数字转换为概率分布。这意味着可以向用户显示输出,例如应用程序 95% 确定这是一只猫。这也意味着输出可以输入其他机器学习算法而无需标准化,因为它保证位于 0 和 1 之间。
请注意,如果网络将图像分类为狗和猫,并且配置为只有两个输出类,那么它会被迫将每个图像分类为狗或猫,即使两者都不是。如果我们需要考虑到这种可能性,那么我们必须重新配置神经网络以具有用于杂项的第三个输出。
神经网络中 Softmax 的示例计算
当我们训练神经网络时,softmax 是必不可少的。想象一下,我们有一个卷积神经网络,它正在学习区分猫和狗。我们将 cat 设置为 1 类,将 dog 设置为 2 类。
理想情况下,当我们将猫的图像输入我们的网络时,网络将输出向量 [1, 0]。当我们输入狗图像时,我们想要一个输出 [0, 1]。
神经网络图像处理在最后的全连接层结束。该层输出 cat 和 dog 的两个分数,它们不是概率。通常的做法是在神经网络的末尾添加一个 softmax 层,将输出转换为概率分布。在训练开始时,神经网络权重是随机配置的。因此,猫图像经过图像处理阶段并转换为分数 [1.2, 0.3]。将 [1.2, 0.3] 传入 softmax 函数,我们可以得到初始概率 [0.71, 0.29]
[ P ( c a t ) P ( d o g ) ] = σ ( [ 1.2 0.3 ] ) = [ e 1.2 e 1.2 − e 0.3 e 0.3 e 1.2 + e 0.3 ] = [ 0.71 0.29 ] \begin{aligned} \left[\begin{array}{c} P(\mathrm{cat}) \\ P(\mathrm{dog}) \end{array}\right] &=\sigma\left(\left[\begin{array}{l} 1.2 \\ 0.3 \end{array}\right]\right) \\ &=\left[\begin{array}{c} \frac{e^{1.2}}{e^{1.2} \frac{-e^{0.3}}{}}{e^{0.3}} \\ {e^{1.2}+e^{0.3}} \end{array}\right] \\ &=\left[\begin{array}{l} 0.71 \\ 0.29 \end{array}\right] \end{aligned} [P(cat)P(dog)]=σ([1.20.3])=[e1.2−e0.3e1.2e0.3e1.2+e0.3]=[0.710.29]
显然这是不可取的。在这种情况下,完美的网络将输出 [1, 0]。
我们可以制定网络的损失函数,量化网络的输出概率与期望值的距离。损失函数越小,输出向量越接近正确的类别。在这种情况下,最常见的损失函数是交叉熵损失,在这种情况下是:
L = − ( 1 log 0.71 + 0 log 0.29 ) = − 0.71 L=-(1 \log 0.71+0 \log 0.29)=-0.71 L=−(1log0.71+0log0.29)=−0.71
由于 softmax 是一个连续可微函数,因此可以针对训练集中的每个图像计算损失函数对网络中每个权重的导数。
这个属性允许我们调整网络的权重以减少损失函数并使网络输出更接近期望值并提高网络的准确性。经过几次训练迭代后,我们更新网络的权重。现在当同样的猫图像输入到网络中时,全连接层输出一个 [1.9, 0.1] 的得分向量。再次通过 softmax 函数,我们得到输出概率:
[ P ( c a t ) P ( d o g ) ] = σ ( [ 1.9 0.1 ] ) = [ e 1.9 e 1.9 + e 0.1 e 0.1 e 1.9 + e 0.1 ] = [ 0.86 0.14 ] \begin{aligned} \left[\begin{array}{c} P(\mathrm{cat}) \\ P(\mathrm{dog}) \end{array}\right] &=\sigma\left(\left[\begin{array}{l} 1.9 \\ 0.1 \end{array}\right]\right) \\ &=\left[\begin{array}{c} \frac{e^{1.9}}{e^{1.9}+e^{0.1}} \\ \frac{e^{0.1}}{e^{1.9}+e^{0.1}} \end{array}\right] \\ &=\left[\begin{array}{l} 0.86 \\ 0.14 \end{array}\right] \end{aligned} [P(cat)P(dog)]=σ([1.90.1])=[e1.9+e0.1e1.9e1.9+e0.1e0.1]=[0.860.14]
这显然是一个更好的结果,更接近于 [1, 0] 的期望输出。重新计算交叉熵损失,
L = − ( 1 log 0.86 + 0 log 0.14 ) = − 0.86 L=-(1 \log 0.86+0 \log 0.14)=-0.86 L=−(1log0.86+0log0.14)=−0.86
我们看到损失减少了,说明神经网络有所改善。
如果我们使用 argmax 函数,则无法求导损失函数以确定如何调整网络权重的方法,因为它是不可微的。可微性的特性使 softmax 函数可用于训练神经网络。
softmax 函数的第一个已知用途早于机器学习。 softmax 函数实际上是从物理学和统计力学中借来的,在那里它被称为 Boltzmann 分布或 Gibbs 分布。它是由奥地利物理学家和哲学家路德维希·玻尔兹曼于 1868 年提出的。
Boltzmann 正在研究处于热平衡状态的气体的统计力学。他发现,给定状态的能量和系统的温度,玻尔兹曼分布可以描述在特定状态下找到系统的概率。他的公式版本类似于强化学习中使用的公式。事实上,参数 τ 在强化学习领域被称为温度,以向玻尔兹曼致敬。
1902 年,美国物理学家和化学家乔赛亚·威拉德·吉布斯 (Josiah Willard Gibbs) 用玻尔兹曼分布为热力学和他的熵定义奠定了基础,从而普及了它。它还构成了光谱学的基础,即通过观察材料吸收和反射的光来分析材料。
1959 年,Robert Duncan Luce 在他的著作《个人选择行为:理论分析》中提出了使用 softmax 函数进行强化学习。最后在 1989 年,John S. Bridle 建议前馈神经网络中的 argmax 应该被 softmax 取代,因为它“保留其输入值的排名顺序,并且是“赢家通吃”操作的可微推广最大值”。近年来,随着神经网络的广泛使用,softmax 由于这些特性而广为人知。
参考资料:
deepai What is the Softmax Function?