输出层所用的激活函数,要根据求解问题的性质决定。一般地,
- 回归问题可以使用恒等函数,也就是说会将输入按原样输出;
- 二元分类问题可以使用
sigmoid
函数; - 多元分类问题可以使用
softmax
函数;
1. softmax 函数定义
用图表示 softmax
函数的话,如图 3-22所示。图 3-22中,softmax
函数
的输出通过箭头与所有的输入信号相连。这是因为,从式(3.10)可以看出,输出层的各个神经元都受到所有输入信号的影响。
2. softmax 函数实现
在 IPython 中实现过程:
In [1]: import numpy as np
In [2]: a = np.array([0.3, 2.9, 4.0])
In [3]: exp_a = np.exp(a)
In [4]: exp_a
Out[4]: array([ 1.34985881, 18.17414537, 54.59815003])
In [5]: sum_exp_a = np.sum(exp_a)
In [6]: sum_exp_a
Out[6]: 74.1221542101633
In [7]: y = exp_a/sum_exp_a
In [8]: y
Out[8]: array([0.01821127, 0.24519181, 0.73659691])
In [9]:
将其封装成函数显示为:
In [9]: def softmax(x):
...: exp_x = np.exp(x)
...: sum_exp_x = np.sum(exp_x)
...: y = exp_x/sum_exp_x
...: return y
...:
In [10]: a = np.array([0.3, 2.9, 4.0])
In [11]: softmax(a)
Out[11]: array([0.01821127, 0.24519181, 0.73659691])
In [12]:
3. softmax 函数缺陷
softmax
函数的实现中要进行指数函数的运算,但是此时指数函数的值很容易变得非常大。比如,e10 的值会超过 20000,e100 会变成一个后面有 40 多个 0 的超大值,e1000 的结果会返回一个表示无穷大的 inf
。如果在这些超大值之间进行除法运算,结果会出现“不确定”的情况,也就是人们常说的发生溢出问题。
4. softmax 函数改进
式(3.11)说明,在进行 softmax
的指数函数的运算时,加上(或者减去)某个常数并不会改变运算的结果。这里的 C
可以使用任何值,但是为了防止溢出,一般会使用输入信号中的最大值。我们来看一个具体的例子。
In [13]: a = np.array([1010, 1000, 990])
In [14]: np.exp(a)/ np.sum(np.exp(a))
Out[14]: array([nan, nan, nan])
In [16]: c = np.max(a)
In [17]: c
Out[17]: 1010
In [18]: a - c
Out[18]: array([ 0, -10, -20])
In [19]: np.exp(a-c)/np.sum(np.exp(a-c))
Out[19]: array([9.99954600e-01, 4.53978686e-05, 2.06106005e-09])
In [20]:
如该例所示,通过减去输入信号中的最大值(上例中的 c
),我们发现原本为 nan
(not a number
,不确定)的地方,现在被正确计算了。综上,我们可以像下面这样实现 softmax
函数。
In [22]: def softmax(a):
...: c = np.max(a)
...: exp_a = np.exp(a-c)
...: sum_exp_a = np.sum(exp_a)
...: y = exp_a / sum_exp_a
...: return y
...:
In [23]:
5. softmax 函数特征
使用 softmax()
函数,可以按如下方式计算神经网络的输出。
In [5]: a = np.array([0.3, 2.9 ,4.0])
In [6]: y = softmax(a)
In [7]: y
Out[7]: array([0.01821127, 0.24519181, 0.73659691])
In [8]: np.sum(y)
Out[8]: 1.0
In [9]:
如上所示,softmax
函数的输出是 0.0 到 1.0之间的实数。并且,softmax
函数的输出值的总和是 1。输出总和为 1 是 softmax
函数的一个重要性质。正
因为有了这个性质,我们才可以把 softmax
函数的输出解释为“概率”。
比如,上面的例子可以解释成 y[0] 的概率是 0.018(1.8%),y[1] 的概率
是 0.245(24.5%),y[2] 的概率是0.737(73.7%)。
这里需要注意的是,即便使用了 softmax
函数,各个元素之间的大小关系也不会改变。这是因为指数函数(y = exp(x)
)是单调递增函数。实际上,上例中 a
的各元素的大小关系和 y
的各元素的大小关系并没有改变。比如,a
的最大值是第 2 个元素,y
的最大值也仍是第 2 个元素。
一般而言,神经网络只把输出值最大的神经元所对应的类别作为识别结果。
并且,即便使用 softmax
函数,输出值最大的神经元的位置也不会变。
因此,神经网络在进行分类时,输出层的 softmax
函数可以省略。在实际的问题中,由于指数函数的运算需要一定的计算机运算量,因此输出层的 softmax
函数
一般会被省略。
6. 输出层神经元数量
输出层的神经元数量需要根据待解决的问题来决定。
对于分类问题,输出层的神经元数量一般设定为类别的数量。比如,对于某个输入图像,预测是图中的数字 0 到 9 中的哪一个的问题(10 类别分类问题),可以像图3-23 这样,将输出层的神经元设定为 10 个。
如图 3-23 所示,在这个例子中,输出层的神经元从上往下依次对应数字 0, 1, . . ., 9。此外,图中输出层的神经元的值用不同的灰度表示。这个例子中神经元 y2
颜色最深,输出的值最大。这表明这个神经网络预测的是 y2
对应的类别,也就是“2”。
参考:《深度学习入门:基于Python的理论与实现》