Softmax Cross Entropy Loss笔记

Softmax函数

Softmax函数是在机器学习做分类预测中一个重要的工具函数。Softmax函数的数学定义如下:

σ(z)j=ezjk=1Nezk for j=1,...,N and z=(z1,z2,...,zk)

如果用神经网络做一个分类手写数字预测,那么神经网络的最后一层有10个输出,分别作为预测为 0 ~ 9 的概率。那么怎么判断预测结果到底是哪个数字呢? 一个简单的方法是找到10个输出里最大的那个作为预测结果。 但是这10个输出是相互独立的,其和不等于1。所以一个更好的办法是将所有的输出的和缩放到1,然后看每个输出占的比重,将这个值作为预测概率,而 Softmax 函数恰好可以做到这一点。对于分类 i 的预测概率为 $$p_i =\sigma(z)_i$$

Softmax 函数非常好实现,下面是用 numpy 实现的 Softmax

1
2
3
def softmax(X):
exps = np.exp(X)
return exps / np.sum(exps)

在实现 Softmax 函数的时候,由于涉及到指数运算,在输出比较大的时候,非常容易造成结果溢出。
为了使得 softmax 函数在数值上更加稳定,我们可以先对 z 进行 normalization 。 Normalization 除了统计学上的标准分( $$\frac{\mathbf{X} - \mu}{\sigma}$$ ) , 机器学习中还常用三种其他的方法: L1, L2 和 max

L1: $$\frac{\mathbf{z}}{\sum_{i=1}^n{\vert z_i \vert }}$$

L2: $$\frac{\mathbf{z}}{\sqrt{\sum_{i=1}^n{z_i^2}}}$$

max: $$\frac{\mathbf{z}}{\max{\mathbf{z}}}$$

于是可以把上面的代码改写为

1
2
3
def stable_softmax(X):
exps = np.exp(X - np.max(X))
return exps / np.sum(exps)

Softmax 求导

由于 softmax 的良好性质,在用神经网络做分类任务时,通常直接将最后一层设置为 softmax, 这个时候就要考虑如何对 softmax 进行求导。神经网络输出 z 长度为 k ,那么要对这个 k 个输出进行求偏导。

σ(z)z=[σ(z)0z0σ(z)1z0...σ(z)Nz0σ(z)0z1σ(z)1z1...σ(z)Nz1...σ(z)0zNσ(z)1zN...σ(z)NzN]

对于矩阵中的元素 $$\frac{\partial\sigma(z)_i}{\partial z_j}$$ , 如果 $$i \neq j$$ :

ezik=1Nezkzj=0eziezj(k=1Nezk)2=ezik=1Nezk×ezjk=1Nezk=pi×pj

如果 i = j :

ezik=1Nezkzi=ezik=1Nezke2zi(k=1Nezk)2=ezi(k=1Nekezi)(k=1Nezk)2=pi(1pi)

求导矩阵可以改写为:

σ(z)z=[p0(1p0)p1×p0...pNp0p0×p1p1(1p1)...pNp1...p0×pNp1×pN...pN(1pN)]

Softmax Cross Entropy Loss笔记
https://mengman.github.io/2019/02/22/01-技术积累/ml/softmax-cross-entropy-loss/
作者
ycli
发布于
2019年2月22日
许可协议