softmax是机器学习中难以避开的知识点之一,可以用来多分类,不是不是还在疑问,zm
把lr的二分类扩展到多分类,那么就和我这个菜鸟一起学习softmax吧。
softmax不仅仅把 多个输出构造成概率分布,而且起到了归一化的作用,适用于很多需要进行归一化处理的分类问题。
(1)softmax函数
softmax函数主要用于多分类,他将多个神经元的输出,映射到(0,1)区间内,也可以看成概率,从而进行多分类。假设我们有一个数组,V,Vi 表示v中的第i个元素,那么这个元素的softmax值就是:
eg:
本质上,softmax把一系列输出(3,1,-3)通过softmax函数的作用,映射在(0,1)之间,而且累加和为1,且原先值的大的元素,映射之后,依然是大的,那么我们就可以选择概率大的作为我们的预测目标。
(2)softmax求导
softmax求导,是比较重要的知识点,很多分类和深度学习在反向传播更新参数的时候都会用到,如果你不明白其中的过程,你总会有一种感觉:这个模型总感觉那有不太懂,就像我一样,哈哈。
当我们对分类的loss 进行改进的时候,我们要通过梯度下降,每次优化一个step大小的梯度,这个时候我们就要求LOSS对每个权重矩阵求偏导,然后应用链式法则。第一步,就是对softmax求导,并传回去。
假设,我们有三个输入:
z4 = w41*o1+w42*o2+w43*o3
z5 = w51*o1+w52*o2+w53*o3
z6 = w61*o1+w62*o2+w63*o3
z4,z5,z6分别代表结点4,5,6的输出,01,02,03代表是结点1,2,3往后传的输入.
那么我们可以经过softmax函数得到
要使用梯度下降,肯定就需要有损失函数,这里我们使用交叉熵损失函数:
交叉熵函数形式如下:
其中y代表我们的真实值,ai代表我们的softmax求出的值,i代表的是输出结点。在实际中,预测的结果只有一个结点为1,其余为0,那么我们的loss就变成了:
累加和已经去掉了,现在我们开始求导。
我们在整理一下上面公式,为了更加明白的看出相关变量的关系:
其中
那么形式越来越简单了,求导分析如下:
参数的形式在该例子中,总共分为w41,w42,w43,w51,w52,w53,w61,w62,w63.这些,那么比如我要求出w41,w42,w43的偏导,就需要将Loss函数求偏导传到结点4,然后再利用链式法则继续求导即可,举个例子此时求w41的偏导为:
w51.....w63等参数的偏导同理可以求出,那么我们的关键就在于Loss函数对于结点4,5,6的偏导怎么求,如下:
第一种情况:
那么由上面求导结果再乘以交叉熵损失函数求导
第二种情况:
那么由上面求导结果再乘以交叉熵损失函数求导
(3)举例:
举个例子,通过若干层的计算,最后得到的某个训练样本的向量的分数是[ 2, 3, 4 ], 那么经过softmax函数作用后概率分别就是=[
到这里,这篇文章的内容就讲完了,我希望根据自己的理解,通过列出大量例子,直白的给大家讲解softmax的相关内容,让大家少走弯路,真心希望对大家的理解有帮助!欢迎交流指错!画图整理不易,觉得有帮助的给个赞呗,哈哈!
参考:
忆臻:详解softmax函数以及相关求导过程zhuanlan.zhihu.com###########################补充 一篇 ##############
上面的推导有取巧的嫌疑,下面这一偏,我觉得推导的很好
深度学习中分类问题常用到softmax函数、并将交叉熵函数作为损失函数。
Softmax定义如下:
交叉熵定义如下:
Softmax求导过程:
对于i=j
对于i≠j
交叉熵函数求导过程:
将softmax函数求导结果带入上式:
以上都来源于上面的文章,已备注,不涉及侵权嫌疑,仅作为学习笔记使用!
#######新补充一篇############
- softmax函数
numpy代码:
import numpy as np
def softmax(x):
x = np.exp(x)/np.sum(np.exp(x))
return x
print(softmax([2,3]))
结果:[ 0.26894142 0.73105858]
2.softmax函数求导
(1)当
(2)当
综上所述:
所以
3.softmax 函数的一个性质
这里X是向量,c是一个常数。下面证明左右两边的每一个分量相等。
实际应用:为了防止溢出,事先把x减去最大值。最大值是有效数据,其他值溢不溢出可管不了,也不关心。
import numpy as np
def softmax(x):
#减去最大值
x-=np.max(x)
x = np.exp(x)/np.sum(np.exp(x))
return x
print(softmax([2,3]))
结果还是:[ 0.26894142 0.73105858]
4.作为中间层的激活函数
经过上面的讨论,已经可以把softmax激活层的代码写出来:
class Softmax(object):
def __init__(self):
pass
def forward(self, x):
self.out = np.copy(x)
self.out -= np.max(self.out)
self.out = np.exp(self.out)
s = np.sum(self.out)
self.out= self.out / s
return self.out
def backward(self, eta):
dout=np.diag(self.out)-np.outer(self.out,self.out)
return np.dot(dout,eta)
结果怎样呢?可以说是非常糟糕,开始表现还不错,准确率可以冲到80%,但很快又回到原点。当然只要想想,一堆全部小于1的数不停的数乘来乘去,结果会怎样!而且可以看出,它求导的计算量也非常大,所以softmax很特殊,没有谁把它作为中间层的激活函数。都是放在最后一层,而且都是和交叉熵损失函数结合起来用。
5.softmax函数+交叉熵(log似然)代价函数
这里的
log似然代价函数C对每一个
当使用独热(onehot)编码时,
毫无疑问,这是一个无比优美的结果!!!
6.交叉熵是个什么鬼?为什么用交叉熵作为代价函数可以起到训练作用?
简单来说,训练的目的是让
但等于的可能性不大,至少
而交叉熵的最小值是信息熵,当
反过来讲,当我们训练使得C达到最小值的时候,
就是说方法是求C的最小值,目的是