分析与拓展:多分类模型的输出为什么使用softmax?
多分类模型的输出为什么使用softmax?最近在知乎上看到类似的回答,我觉得都没有说到本质上去,都是在回答why之后的side effect。这里给出我认为满意的解释。
数学的语言是最清晰的,这里解释多分类模型的输出为什么使用softmax直接使用数学推导,不做过多的文字表述。
基础说明
神经网络要做的事情就是根据输入样本x,拟合输出y,
y=f(x)计算softmax的输入\boldsymbol{x}称为\operatorname{logits},假设其取值\boldsymbol{x} = [x_1, x_2, \dots, x_n]。
\max(x_{1},x_{2},\dots,x_{n})的光滑近似为,
通常取\alpha = 1,该函数由一个形如其名的称呼logsumexp,
对于类别编码C_k, k=0, 1, \dots, n-1,其对应的概率分布可以用catagorical distribution表示,
对其使用极大似然估计,能够导出其Loss是交叉熵形式,也就是说catagorical distribution对应优化上的Loss是交叉熵损失,这里不展开讨论。写直白点如下,
类别编码的one-hot形式是离散取值的向量化,
该向量第k个元素取值为1,其他为0。
label smooth给其他类别添加噪声,
其中\epsilon \in [0, \frac{1}{2})是一个较小的数,因此有one-hot的label smooth版本,
相当于给one-hot添加一个随机噪声向量,
这种操作改变不了one-hot的本质,
推导
one-hot作为标签相当便捷,从概率分布的角度看就是标签分布服从伯努利分布或多维伯努利分布(分类分布),但是如果让模型也输出one-hot,即\operatorname{one-hot}(\arg\max(\boldsymbol{x})),这个形式并不可导,不便模型训练,需要其光滑版本,
需要说明几点:
- 引入\big[x_i - \max(\boldsymbol{x}) \big]使得最大值为0,使得e^0 = 1,对应one-hot中的1
- 引入e^x是考虑到e^0=1, 0 \lt e^{x|_{x \lt 0}} \lt 1,并拉大[x_1, x_2, \dots, x_n]间的距离,更好适配one-hot特点
- max不具有光滑性,被替换为其光滑近似logsumexp,可以看logsumexp函数分析
理解好这三点就明白上述推导过程。说白了就是,对于分类问题来说,标签分布服从伯努利分布或多维伯努利分布(分类分布),为模型优化需要寻找光滑的分布去逼近它。
这样引入\operatorname{softmax}(\boldsymbol{x})后会带来一些好的side effect:
- \operatorname{softmax}(\boldsymbol{x})是光滑的,具有良好的梯度特性,便于模型训练
- 加性不变性,\operatorname{softmax}(\boldsymbol{x}) = \operatorname{softmax}(\boldsymbol{x}+c),于是对上游添加bias不会影响输出
\operatorname{softmax}(\boldsymbol{x})本身的梯度相当优雅,可以使用克罗内克\delta函数表示。令,
那么,
其中,
使用\operatorname{softmax}(\boldsymbol{x})作为输出,交叉熵为,
其中涉及函数Logsumexp,对其求梯度又重新回到softmax形式上。以上的推导说明,softmax输出配合交叉熵损失带来梯度计算的优良性。
softmax的问题
假设softmax前的网络层的输出logit为\boldsymbol{x} = [x_1, x_2, \dots, x_n],一般的操作是计算\operatorname{softmax}(\boldsymbol{x})获得归一化向量,会后完成n多分类问题。这个操作很常规,是分类问题必备的,但等等,我们再深入分析这一个过程。
假设有一样本,标签为\operatorname{one-hot}(C_j) = [0, \dots, 1, \dots, 0],类别C_j的onehot形式,向量的第j个位置取值为1,其他为0。对于模型来说,样本的logit为\boldsymbol{x} = [x_1,\dots, x_j, \dots, x_n],这里有x_{\text{max}} = x_j = \max_i \boldsymbol{x},同时令x_{\text{min}} = \min_i \boldsymbol{x}。
那么有交叉熵及其不等式推导,
把x_{\text{max}} - x_{\text{min}}解出来有,
这个公式说明,为让交叉熵损失下降到l,需要logit输出\boldsymbol{x} = [x_1, x_2, \dots, x_n]中x_{\text{max}} - x_{\text{min}}距离拉大到大于\log\left(n-1 \right) - \log\left(e^l - 1 \right)。比如取l = \ln2, n=100,那么x_{\text{max}} - x_{\text{min}} \ge 4.61。想一想参数初始化时,随机变量也是极小概率出现如此大的差距,对于模型来说容易造成过拟合。
为完成n多分类问题,其实logit间没有必要拉开如此大的间隔,理想情况下只需要x_{\text{max}}比其他x_i大一点即可。解决方案就是在
计算上。取\boldsymbol{x} = [x_1, x_2, \dots, x_n]中的topk来计算上式,假设为\Omega = {x’_1, \dots, x’_k },有
这里k作为超参数存在。
融入先验信息
通过在输出logit为\boldsymbol{x} = [x_1, x_2, \dots, x_n]上叠加一个向量可以让softmax融入先验信息,假设这个向量为(称为先验信息)
那么获得的softmax值为,
在先验信息\boldsymbol{p}的作用下,能够让模型更加关注logit中某些x_i。类似地,可以按照一定的比例缩放,
还有就是计算完softmax后再叠加先验信息,
这种方法在Attention矩阵中引入先验信息有应用。
总结
以上通过简单的基础信息,通过清晰的数学推导,解释了为什么多分类模型的输出使用softmax。并分析softmax优缺点,提供一种解决方案。最后介绍softmax上融入先验信息的技巧。
转载请包括本文地址:https://allenwind.github.io/blog/15110
更多文章请参考:https://allenwind.github.io/blog/archives/