快速理解Softmax和Sigmoid

快速理解Softmax和Sigmoid

Softmax 函数,或称归一化指数函数,能将一个含任意实数的K维向量z压缩到另一个K维实向量σ(z)中,使得每一个元素的范围都在(0,1)之间,并且所有元素的和为1。Sigmoid 函数则是一个在我们高中生物课上常见的S形函数,它是由皮埃尔在1844或1845年在研究它与人口增长的关系时命名的,它能将一个实数映射到(0,1)区间。

Softmax函数

首先,Softmax 实际上是有限项离散概率分布的梯度对数归一化,即把一个k维的实值向量 (a1, a2, a3, a4...) 映射成 (b1, b2, b3, b4...)(其中 bi 是一个0-1的常数),输出的神经元之和为1.0,相当于概率值。所以我们可以根据归一化后 bi 的概率大小来进行多分类的任务,如取权重最大的一堆。因此,Softmax 函数在包括多项逻辑回归、多项线性判别分析、朴素贝叶斯分类器和人工神经网络等的多种基于概率的多分类问题方法中都有着广泛应用。

\[ \bold{\sigma(z)_j=\frac{e^{z_j}}{\sum_{k=1}^K e^{z_k}}} \]

代码实现

我们可以利用 numpy 库去手动实现 Softmax 函数,代码如下:

Softmax.py
1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
np.set_printoptions(linewidth=100) # 设定print输出每行最大长度为100个字符防止自动换行

m = np.random.randn(5,5) * 10 + 1000
print('Origin:\n', m, '\n')
m_row_max = m.max(axis = 1)
print('Row max value:\n', m_row_max.reshape(5, 1), '\n')
m = m - m_row_max.reshape(5,1) # 每行元素减去本行的最大值(防止出现 INF)
m_exp = np.exp(m)
m_exp_row_sum = m_exp.sum(axis=1).reshape(5,1)
softmax = m_exp / m_exp_row_sum
print('Softmax:\n', softmax, '\n') # 校验softmax数组是否正确的方法是查看每一行的和是否是1
print('Verification:\n', softmax.sum(axis=1).reshape(5, 1))
Print Outout false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Origin:
[[1018.88530262 1006.22202787 1002.92417964 1006.66411112 993.50807315]
[1002.07186358 1006.65337717 994.00807884 998.88322569 996.86766223]
[1010.49755903 1003.59425561 1011.24615962 985.340456 1002.84793862]
[ 996.72309341 1000.96508103 1000.68554367 999.95427562 992.33465082]
[ 998.27143628 1010.75280609 1010.08282038 1000.27492978 1004.09157195]]

Row max value:
[[1018.88530262]
[1006.65337717]
[1011.24615962]
[1000.96508103]
[1010.75280609]]

Softmax:
[[9.99991793e-01 3.16523596e-06 1.16995404e-07 4.92493391e-06 9.52370014e-12]
[1.01307741e-02 9.89392713e-01 3.18849265e-06 4.17671454e-04 5.56527599e-05]
[3.20973684e-01 3.22405797e-04 6.78551054e-01 3.80959141e-12 1.52855648e-04]
[6.73609588e-03 4.68468157e-01 3.54224457e-01 1.70487627e-01 8.36626969e-05]
[2.50936115e-06 6.60926559e-01 3.38206625e-01 1.86066994e-05 8.45699312e-04]]

Verification:
[[1.]
[1.]
[1.]
[1.]
[1.]]

由输出结果我们可以看出,原数组经过 Softmax 化后,每行的最大值元素和其它元素的差距被明显放大。因此,我们可以认为 Softmax 这个函数的通常意义是: 对向量进行归一化,凸显其中的最大值并抑制远低于最大值的其他分量。

Sigmoid函数

sigmoid 函数也叫 logistic 函数,值域范围为(0,1)。因为它可以将一个实数映射到(0,1)区间,因此一般被用来做二分类和隐层神经元输出。

\[ \bold{\sigma(z)=\frac{1}{1+e^{-z}}} \]

代码实现

用 numpy 实现 sigmoid 其实也非常简单,代码如下:

1
2
3
4
5
6
import numpy as np

def logistic(x):
return 1/(1+np.exp(-x))

print(logistic(6.666666))
Print Outout false
1
0.9987289828906512

总结

本质上来说,Softmax 属于离散概率分布而 Sigmoid 是非线性映射。分类其实就是设定一个阈值,然后我们将想要分类的对象与这个阈值进行比较,根据比较结果来决定分类。Softmax 函数能够将一个K维实值向量归一化,所以它主要被用于多分类任务;Sigmoid 能够将一个实数归一化,因此它一般用于二分类任务。特别地,当 Softmax 的维数 K=2 时,Softmax 会退化为 Sigmoid 函数。

参考资料

  1. 机器学习之sigmoid函数
  2. sigmoid和softmax总结
  3. Softmax函数 - 百度百科
  4. Sigmoid函数 - 百度百科
  5. python:logistic,softmax函数