- Softmax的实现
- Softmax的基础知识
在数学中,softmax函数,或称为“归一化指数函数”,是logistic函数的一种泛化;也就是说,它是logistic函数的一个子类。它把logistic函数的任意实数值的K维向量 z 变形为 一个实数值的K维向量,的每个元素的范围(0,1)且满足所有元素之和为1.因此,它变成了一个K-1维的空间,有一个维度丢失了。
在概率论中,softmax函数的输出可以用于标识一个分类器的分布,那就是,K个不同可能性的输出来标识概率的分布。实际上,它是分类概率分布的“gradient-log-normalizer”。Softmax函数也是LogSumExp函数的梯度。
Softmax被广泛用于大量的多类分类方法中,例如,多项logistic 回归也称为“softmax 回归”,多类线性判别分析,朴素贝叶斯分类器,和人工神经网络中。特别是,在多项logistic 回归和多类线性判别分析中,函数的输入是K个不同的线性函数的结果,在给定样本向量x和权重向量w时,对于第j个类别的预测的概率如下:
它可以被看做是K个线性函数与softmax函数的组合。这里,标识x和w的內积。
Softmax函数经常被用于基于神经网络的分类器的最后一层。这些网络通常在给定一个多项logistic 回归的非线性变量下,通过一个log loss 方法(或者交叉熵方法)来完成训练。
既然函数映射了一个向量和一个特定的index到一个实数值,那么,导数肯定要把index考虑进去,公式如下:
,其中,
-
- Caffe的Softmax层的实现
关于caffe的softmax和softmaxwithloss层的数学解释,下面这位作者写的很清晰,点赞!
https://www.zhihu.com/people/wang-jun-nan-72-19/answers
抄录如下:
***************************抄录的起始位置***************************
假设z是softmaxwithloss层的输入,f(z)是softmax的输出,即
y是输入样本z对应的类别,y=0,1,...,N对于z,其损失函数定义为
展开上式:
对上式求导,
有梯度下降方向即为
这就是logistic函数的特性,
增加关于softmax的反向传播说明如下:
设softmax的输出为a,输入为z,损失函数为l,则
其中,
- 在caffe中是top_diff,
- a为caffe中得top_data,
因此,需要计算的是。
对求导得,
, if i != k;
, if i == k.
于是,
;整理一下得到,
其中,表示将标量扩展为n维向量, 表示向量按元素相乘。
***************************抄录的结束位置***************************
Softmax层的前向和反向传播代码解析:
以10个class的分类器为例。
- 前向传播求概率向量
主要实现的过程如下:
- 从10个输入channels中获取最大值,赋给scale_data。
- 把10个输入的channel的值-scale_data,赋值给 top_data;(保证所有这10个值<=0)
- 对top_data做指数运算,赋值给top_data;(保证所有这10个值在区间[0,1])
- 对top_data求和,结果赋值给scale_data。(获取所有这10个值和)
- 对top_data这10个值分别除以scale_data,赋值给top_data;(保证这10个值的和为1;每个值对应于每个class的概率)。
- 反向传播求导数向量
- 对top_diff向量(10个值)与top_data向量(10个值)做点乘,公式如下,得到的值赋给scale_data。
- 对top_diff向量(10个值)每个都减去scale_data,得到的值赋值给bottom_diff向量。
- 把bottom_diff向量每个都乘以对应的top_data,赋值给bottom_diff向量。该向量就是bottom的导数。
基本公式如下:
SoftmaxWithLossLayer的前向传播和反向传播的解析
- 前向传播求loss
- 遍历所有batchSize内每个样本的10个输出channels的prob,找到与label对应的那个的概率进行损失计算,并跟之前的loss相加。
- 把得到的loss之和除以batchSize,得到loss。
- 把得到的loss保存到输出blob top[0]中。
- 反向传播求bottom_diff
- 遍历所有batchSize内每个样本的10个输出channels,找到与label对应的那个概率做减一操作,即
对于跟label不一致的channel求导,保持不变。
得到的结果就是bottom diff。