神经网络可以用于处理分类问题以及回归问题,一般而言,如果是二分类问题,则从隐藏层到输出层使用Sigmoid函数作为激活函数,如果是多分类问题,则从隐藏层到输出层使用Softmax函数;
对于回归问题我们一般不使用激活函数。下面我们就来介绍Softmax函数。
Sigmoid函数主要用于解决二分类问题,在图像分类问题上,大部分情况下,我们面对的还是多分类问题,对于多分类我们需要使用Softmax分类器。
Softmax分类器的输出是每个类别的概率。 在Logistic regression二分类问题中,我们可以使用Sigmoid函数将输入W*x+b映射到(0,1)区间中,从而得到属于某个类别的概率。
这里我们将这个问题进行泛化;在处理多分类(C>2)的问题上,分类器最后的输出单元需要使用Softmax函数进行数值处理。
Softmax函数的定义如下所示: 其中,Vi表示的是分类器前级输出单元的输出。i表示类别索引,总的类别个数为C。
Si表示的是当前元素的指数与所有元素指数和的比值。Softmax将多分类的输出数值转化为相对概率,因此更容易理解和比较。
将每一个类别求出的除以类别总和,就可以得到概率,通过上式可以输出一个向量,其中,每个元素值均在0到1之间,且所有元素的概率之和为1。在Python中,Softmax函数可以写为:
#x为输入的向量
def _softmax(x):
exp_x = np.exp(x)
return exp_x / np.sum(exp_x)
接下来看一下下面这个例子:一个多分类问题,C=4。线性分类器模型最后的输出层包含了4个输出值,分别是:
经过Softmax处理后,数值转化为如下所示的相对概率: 很明显,Softmax的输出表征了不同类别之间的相对概率。
我们可以清晰地看出,S1=0.8390,其对应的概率最大,因此可以清晰地判断出预测为第1类的可能性更大。
Softmax将连续数值转化成相对概率,更有利于我们进行理解。 当我们运算的值比较小的时候是不会有什么问题的,但是如果运算的值很大或很小的时候,直接计算就会出现上溢出或下溢出,从而导致严重问题。
举个例子,对于[3,1,-3],直接计算是可行的,我们可以得到(0.88,0.12,0)。但是对于[1000,1001,1002],却并不可行,我们会得到inf(这也是深度学习训练过程常见的一个错误);
对于[-1000,-999,-1000],还是不行,我们会得到-inf。 实际应用中,需要对V进行一些数值处理:即V中的每个元素减去V中的最大值。
相应的Python示例代码如下:
#x为输入的向量
def _softmax(x):
c = np.max(x)
exp_x = np.exp(x-c)
return exp_x / np.sum(exp_x)
scores = np.array([123, 456, 789]) # example with 3 classes and each having large scores
p = _softmax(scores)
print(p)
下面我们来举例说明,
我们把猫分为类1,狗分为类2小鸡分为类3,如果不属于以上任何一类就分到“其他”(或者说,“以上均不符合”)这一类,我们将这一类称为类0。
假设我们输入了一张猫的图片,其对应的真实标签是0100(类别已经转换成one-hot编码形式)。 真值y为其中,yi=1是1,其余都是0,经过Softmax计算之后得到的是预测值y_predict,假设预测值为,它是一个包括总和为1的概率的向量,对于这个样本,神经网络的表现不佳,这实际上是一只猫但是猫的概率只分配到20%,那么需要使用什么损失函数来训练这个神经网络呢?在Softmax分类中,我们用到的损失函数一般是交叉熵(后续篇章我们会详细讲解交叉熵,本节我们将主要关注输出层本身)。
一般来说,神经网络是将输出值最大的神经元所对应的类别作为识别结果,而且即使使用Softmax函数也只会改变值的大小而不能改变神经元的位置;
另外指数函数的运算也需要一定的计算机运算量,因此可以考虑在多分类问题中省去Softmax函数。