softmax函数
在二分类任务时,经常使用sigmoid激活函数。而在处理多分类问题的时候,需要使用softmax函数。
softmax函数公式
softmax函数的公式如下:
y
i
=
s
o
f
t
m
a
x
(
x
i
)
=
e
x
i
∑
k
=
1
N
e
x
k
{y_i}=softmax(x_i) = \frac{e^{x_{i}}}{\sum_{k=1}^{N}e^{x_{k}}}
yi=softmax(xi)=∑k=1Nexkexi
其中
x
i
{x_i}
xi是输入向量的第 i 个元素。softmax函数的作用是将输入向量中的每个元素转换为其作为概率值的形式。
softmax函数的导数公式
即求
y
i
=
e
x
i
∑
k
=
1
N
e
x
k
y_{i}=\frac{e^{x_{i}}}{\sum_{k=1}^{N}e^{x_{k}}}
yi=∑k=1Nexkexi 的导数。
观察可知,
y
i
{y_i}
yi 是形如
y
i
=
g
(
x
)
f
(
x
)
{y_i}=\frac{g(x)}{f(x)}
yi=f(x)g(x) 的函数。
求导公式: ∂ y i ∂ x = g ′ ( x ) h ( x ) − g ( x ) h ′ ( x ) [ h ( x ) ] 2 \frac{\partial y_i}{\partial x}=\frac{g^{\prime}(x)h(x)-g(x)h^{\prime}(x)}{[h(x)]^2} ∂x∂yi=[h(x)]2g′(x)h(x)−g(x)h′(x)
类比可知,
e
x
i
e^{x_i}
exi相当于
g
(
x
)
{g(x)}
g(x);
∑
k
=
1
N
e
x
k
{\sum_{k=1}^{N}e^{x_{k}}}
∑k=1Nexk相当于
h
(
x
)
h(x)
h(x)。
所以,要想得到softmax函数的导数,只需要分别求出
e
x
i
e^{x_i}
exi 和
∑
k
=
1
N
e
x
k
{\sum_{k=1}^{N}e^{x_{k}}}
∑k=1Nexk 的导数即可。
对于第
i
i
i个元素
x
i
{x_i}
xi,
(
∑
k
=
1
N
e
x
k
)
′
({\sum_{k=1}^{N}e^{x_{k}}})^{\prime}
(∑k=1Nexk)′
=
(
e
x
1
+
e
x
2
+
⋅
⋅
⋅
+
e
x
i
+
⋅
⋅
⋅
+
e
x
N
)
′
=({e^{x_1}}+{e^{x_2}}+···+{e^{x_i}}+···+{e^{x_N}})^{\prime}
=(ex1+ex2+⋅⋅⋅+exi+⋅⋅⋅+exN)′
=
e
x
i
={e^{x_i}}
=exi。
由于 k {k} k是从 1 1 1开始直到 N N N的,所以肯定能找到一个 k k k值与 i {i} i相等,使得 ( e x k ) ′ ({e^{x_k}})^{\prime} (exk)′ = ( e x i ) ′ ({e^{x_i}})^{\prime} (exi)′ = e x i {e^{x_i}} exi;
而对于其他不等于 i i i的 k k k值, e x k {e^{x_k}} exk相对于 x i {x_i} xi都是常数,求导变为0。
我们分两种情况来讨论softmax函数的求导。
设
i
i
i 表示输入向量的第
i
i
i个元素,
j
j
j 表示输入向量的第
j
j
j个元素。
当 i ≠ j i ≠ j i=j 时
我们关心的是第
i
i
i个输入变量
x
i
{x_i}
xi如何受到其他变量
x
j
{x_j}
xj的影响,计算的是
y
i
{y_i}
yi对第
j
j
j个元素的偏导数。
此时,
(
e
x
i
)
′
=
0
({e^{x_i}})^{\prime}=0
(exi)′=0,
(
e
x
j
)
′
=
x
j
({e^{x_j}})^{\prime}={x_j}
(exj)′=xj
∂
y
i
∂
x
j
=
∂
e
x
i
∑
k
=
1
N
e
x
k
∂
x
j
=
0
−
e
x
i
e
x
j
∑
2
=
−
e
x
i
∑
e
x
j
∑
=
−
y
i
y
j
\frac{\partial y_{i}}{\partial x_{j}}=\frac{\partial\frac{e^{x_{i}}}{\sum_{k=1}^{N}e^{x_{k}}}}{\partial x_{j}}=\frac{0-e^{x_{i}}e^{x_{j}}}{\sum^{2}}=-\frac{e^{x_{i}}}{\sum}\frac{e^{x_{j}}}{\sum}=-y_{i}y_{j}
∂xj∂yi=∂xj∂∑k=1Nexkexi=∑20−exiexj=−∑exi∑exj=−yiyj
这个结果表明,第
i
i
i个输出变量
y
i
{y_i}
yi对第
j
{j}
j个输入变量
x
j
{x_j}
xj的偏导数是负的,表示它们是相互抑制的关系。因此,在这种情况下,当其中一个变量的得分增加时,其他变量的相对概率就会减少,这就是所谓的“竞争效应”。
当 i = j i = j i=j 时
我们关心的是第
i
i
i个输入变量
x
i
{x_i}
xi如何受到自身变化的影响,计算的是
y
i
{y_i}
yi对第
i
(
或
j
)
i(或j)
i(或j) 个元素的偏导数。
此时,
(
e
x
i
)
′
=
(
e
x
j
)
′
=
x
i
=
x
j
({e^{x_i}})^{\prime}=({e^{x_j}})^{\prime}={x_i}={x_j}
(exi)′=(exj)′=xi=xj
∂
y
i
∂
x
j
=
∂
e
x
i
∑
k
=
1
N
e
x
k
∂
x
j
=
e
x
i
∑
−
e
x
i
e
x
j
∑
2
=
e
x
i
∑
∑
−
e
x
j
∑
=
y
i
(
1
−
y
j
)
\frac{\partial y_{i}}{\partial x_{j}}=\frac{\partial\frac{e^{x_{i}}}{\sum_{k=1}^{N}e^{x_{k}}}}{\partial x_{j}}=\frac{e^{x_{i}}\sum-e^{x_{i}}e^{x_{j}}}{\sum^{2}}=\frac{e^{x_{i}}}{\sum}\frac{\sum-e^{x_{j}}}{\sum}=y_{i}(1-y_{j})
∂xj∂yi=∂xj∂∑k=1Nexkexi=∑2exi∑−exiexj=∑exi∑∑−exj=yi(1−yj)
这个结果表明,第 i i i个输出变量 y i {y_i} yi对第 i {i} i个输入变量 x i {x_i} xi的偏导数是正的,表示它们是相互促进的关系。因此,在这种情况下,当 x i {x_i} xi的得分增加时,他的输出概率 y i {y_i} yi也会相应的增加,但同时其他变量的输出概率会减少,以保证所有输出概率的总和为1。
softmax溢出问题
参考文章
上溢出(overflow)和下溢出(underflow)
在使用softmax函数时,可能会出现两种数值问题:上溢出(overflow)和下溢出(underflow)。
上溢出发生在softmax函数的输入值非常大时。具体来说,当softmax函数的某个输入值非常大,以至于经过指数运算后得到的值大于数据类型容许的最大数字或者超出了计算机能够表示的范围时,就会出现上溢出(overflow)。这时,softmax函数的输出值会被表示为无穷大(inf),这在数值计算中可能导致一些问题,因为无穷大的值会导致后续的除法运算失败。
下溢出则发生在softmax函数的输入值非常小,接近于零时。由于计算机使用浮点数表示实数,当数值小到一定程度时,可能会被四舍五入为0。在softmax函数中,如果分母接近于0,那么在计算概率时可能会导致除以零的错误,进而引发数值不稳定或程序崩溃。
解决方法
令 M = m a x ( x i ) , i = 1 , 2 , 3 , . . . , N M = max({x_i}),i=1,2,3,...,N M=max(xi),i=1,2,3,...,N,即 M M M为所有 x i {x_i} xi中最大的值,那么只需要把计算 s o f t m a x ( x i ) softmax(x_i) softmax(xi)的值,改为计算 s o f t m a x ( x i − M ) softmax(x_i-M) softmax(xi−M)的值,就可以解决上溢出、下溢出的问题,并且计算结果理论上仍然和 s o f t m a x ( x i ) softmax(x_i) softmax(xi)保持一致。
举个例子
设
x
1
=
3
,
x
2
=
1
,
x
3
=
−
3
x_1=3,x_2=1,x_3=-3
x1=3,x2=1,x3=−3,我们常用“常规”的方法来计算
y
2
y_2
y2,即
e
x
2
e
x
1
+
e
x
2
+
e
x
3
=
e
1
e
3
+
e
1
+
e
−
3
=
2.7
20
+
2.7
+
0.05
≈
0.12
\begin{aligned}\frac{e^{x_2}}{e^{x_1}+e^{x_2}+e^{x_3}}&=\frac{e^1}{e^3+e^1+e^{-3}}=\frac{2.7}{20+2.7+0.05}\approx0.12\end{aligned}
ex1+ex2+ex3ex2=e3+e1+e−3e1=20+2.7+0.052.7≈0.12
现在我们改成:
e
x
2
−
M
e
x
1
−
M
+
e
x
2
−
M
+
e
x
3
−
M
=
e
1
−
3
e
3
−
3
+
e
1
−
3
+
e
−
3
−
3
≈
0.12
\begin{aligned}\frac{e^{x_2-M}}{e^{x_1-M}+e^{x_2-M}+e^{x_3-M}}&=\frac{e^{1-3}}{e^{3-3}+e^{1-3}+e^{-3-3}}\approx0.12\end{aligned}
ex1−M+ex2−M+ex3−Mex2−M=e3−3+e1−3+e−3−3e1−3≈0.12
其中,
M
=
3
M=3
M=3是
x
1
,
x
2
,
x
3
x_1,x_2,x_3
x1,x2,x3中的最大值。
可见计算结果并未改变。这是怎么做到的呢?通过简单的代数运算就可以参透其中的“秘密”:
e
x
2
e
x
1
+
e
x
2
+
e
x
3
=
e
x
2
e
M
e
x
1
+
e
x
2
+
e
x
3
e
M
=
e
x
2
e
M
e
x
1
e
M
+
e
x
2
e
M
+
e
x
3
e
M
=
e
(
x
2
−
M
)
e
(
x
1
−
M
)
+
e
(
x
2
−
M
)
+
e
(
x
3
−
M
)
\frac{e^{x_2}}{e^{x_1}+e^{x_2}+e^{x_3}}=\frac{\frac{e^{x_2}}{e^M}}{\frac{e^{x_1}+e^{x_2}+e^{x_3}}{e^M}}=\frac{\frac{e^{x_2}}{e^M}}{\frac{e^{x_1}}{e^M}+\frac{e^{x_2}}{e^M}+\frac{e^{x_3}}{e^M}}=\frac{e^{(x_2-M)}}{e^{\left(x_1-M\right)}+e^{\left(x_2-M\right)}+e^{\left(x_3-M\right)}}
ex1+ex2+ex3ex2=eMex1+ex2+ex3eMex2=eMex1+eMex2+eMex3eMex2=e(x1−M)+e(x2−M)+e(x3−M)e(x2−M)
通过这样的变换,对任何一个 xi,减去M之后,e 的指数的最大值为0,所以不会发生上溢出;同时,分母中也至少会包含一个值为1的项,所以分母也不会下溢出(四舍五入为0)。
延伸问题
如果softmax函数中的分子发生下溢出,也就是 x i {x_i} xi为负数,且 ∣ x i ∣ {|x_i|} ∣xi∣很大,此时分母是一个极小的正数,有可能四舍五入为0的情况。此时,如果我们把softmax函数的计算结果再拿去计算 log,即 log softmax,其实就相当于计算 log(0) ,所以会得到 −∞ ,但这实际上是错误的,因为它是由舍入误差造成的计算错误。
解决方法
log
[
y
i
]
=
log
(
e
x
i
e
x
1
+
e
x
2
+
⋯
e
x
n
)
=
log
(
e
x
i
e
M
e
x
1
e
M
+
e
x
2
e
M
+
⋯
e
x
n
e
M
)
=
log
(
e
(
x
i
−
M
)
∑
j
n
e
(
x
j
−
M
)
)
=
log
(
e
(
x
i
−
M
)
)
−
log
(
∑
j
n
e
(
x
j
−
M
)
)
=
(
x
i
−
M
)
−
log
(
∑
j
n
e
(
x
j
−
M
)
)
\begin{aligned} \log[y_i]&=\log\left(\frac{e^{x_i}}{e^{x_1}+e^{x_2}+\cdots e^{x_n}}\right)\\ &=\log\left(\frac{\frac{e^{x_i}}{e^M}}{\frac{e^{x_1}}{e^M}+\frac{e^{x_2}}{e^M}+\cdots\frac{e^{x_n}}{e^M}}\right)\\ &=\log\left(\frac{e^{(x_i-M)}}{\sum_j^ne^{(x_j-M)}}\right)\\ &=\log\Bigl(e^{(x_i-M)}\Bigr)-\log\left(\sum_j^ne^{(x_j-M)}\right)\\ &=(x_i-M)-\log\left(\sum_j^ne^{(x_j-M)}\right) \end{aligned}
log[yi]=log(ex1+ex2+⋯exnexi)=log(eMex1+eMex2+⋯eMexneMexi)=log(∑jne(xj−M)e(xi−M))=log(e(xi−M))−log(j∑ne(xj−M))=(xi−M)−log(j∑ne(xj−M))
可以看到,在最后的表达式中,避免计算了
e
(
x
i
−
M
)
{e^{(x_i-M)}}
e(xi−M),而仅仅是
x
i
−
M
x_i-M
xi−M难以超越数据类型容许的范围;后面的
log
(
∑
j
n
e
(
x
j
−
M
)
)
\log\left(\sum_j^ne^{(x_j-M)}\right)
log(∑jne(xj−M))实际上是一种类似"LogSumExp技巧"的聪明方式,他满足:
0
≤
log
(
∑
i
=
1
n
e
x
i
−
M
)
≤
log
(
n
)
\mathrm{0\leq\log(\sum_{i=1}^ne^{x_i-M})\leq\log(n)}
0≤log(i=1∑nexi−M)≤log(n)这样就解决了softmax的溢出问题。
softmax函数在多分类问题中的应用
softmax在多分类过程中,它将多个神经元的输出(比如 o 1 , o 2 , o 3 o_1,o_2,o_3 o1,o2,o3)映射到(0,1)区间内,转换为一组概率值(比如 y 1 , y 2 , y 3 y_1,y_2,y_3 y1,y2,y3),这些概率值的总和为1,每个概率值可以看作是每个类别的预测概率,我们选取概率值最大(也就是神经元输出值最大的)结点,作为预测目标。
其他激活函数的相关用法详见以下博客:
常见的激活函数(sigmoid、tanh、ReLU、Leaky ReLU、P-ReLU、R-ReLU、ELU、Swish、Mish、Maxout、softmax)