欢迎关注公众号:DeepL Newer

MENU

Softmax

December 29, 2019 • Read: 1672 • Deep Learning阅读设置

Softmax函数概述

  • soft version of max
  • 大的越来越大,小的越来越小

Softmax常与crossentropy(交叉熵)搭配连用

上图中假设有三个输出,分别是2.0,1.0和0.1,如果将数值转换成概率的话,我们希望概率最大的值作为预测的label。即我们希望将最大值2.0所对应的索引作为相应的label输出,那么如何作为probilities输出呢?

sigmoid函数可以将input压缩到[0,1]的范围,但是对于分类问题来说,我们不仅要求概率范围是[0,1],还要求所有的概率和为1,即$\sum p_i = 1$

为了解决此类问题,就有了Softmax函数,具体的函数表达式为

$$ S(y_i) = \frac{e^{y_i}}{\sum_j e^{y_j}} $$

另外有一点要注意,Softmax具有差距放大功能,例如原来2.0和1.0是两倍关系,经过Softmax压缩后,变为0.7和0.2,增大到3.5倍关系

Softmax求导

对Softmax函数进行求导,首先写出其函数表达式

$$ p_i = \frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}} $$

根据除法求导法则,若$f(x)=\frac{g(x)}{h(x)}$,则$f'(x) = \frac{g'(x)h(x)-h'(x)g(x)}{h^2(x)}$

当$i=j$时

$$ \begin{align*} \frac{\nabla\frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}}}{\nabla{a_j}} &= \frac{e^{a_i}\sum_{k=1}^{N} a_k - e^{a_j}e^{a_i}}{(\sum_{k=1}^N e^{a_k})^2} \\ &= \frac{e^{a_i}(\sum_{k=1}^{N} a_k - e^{a_j})}{(\sum_{k=1}^N e^{a_k})^2} \\ &= \frac{e^{a_j}}{\sum_{k=1}^N e^{a_k}}*\frac{(\sum_{k=1}^N e^{a_k}-e^{a_j})}{\sum_{k=1}^N e^{a_k}} \\ &= p_i(1-p_j) \end{align*} $$

当$i\neq j$时

$$ \begin{align*} \frac{\nabla\frac{e^{a_i}}{\sum_{k=1}^Ne^{a_k}}}{\nabla{a_j}} &= \frac{0 - e^{a_j}e^{a_i}}{(\sum_{k=1}^N e^{a_k})^2} \\ &= \frac{-e^{a_j}}{\sum_{k=1}^N e^{a_k}}*\frac{e^{a_i}}{\sum_{k=1}^N e^{a_k}} \\ &= -p_j * p_i \end{align*} $$

对以上求导过程进行总结

$$ \frac{\nabla p_i}{\nabla{a_j}}=\begin{cases}p_i(1-p_j) & i = j \cr -p_j*p_i &i \neq j\end{cases} $$

需要注意的一点是,由于$p_j$和$p_j$均在$[0,1]$范围内,故$p_i(1-p_j)>0$,$-p_i*p_j<0$

下面使用代码举例

import torch
import torch.nn.functional as F
a = torch.rand(3, requires_grad=True) # dim=1, len=3 tensor
p = F.softmax(a, dim=0)# 需要指定进行sfotmax操作的dim维度
print('softmax:', p)
torch.autograd.grad(p[0],[a], retain_graph=True)
# 注意Loss必须是长度为1的值,由于p是dim=1,len=3的值,因此取必须取p中的一个

输出

softmax: tensor([0.2732, 0.3780, 0.3489], grad_fn=<SoftmaxBackward>)
(tensor([ 0.1985, -0.1033, -0.0953]),)

这里进行了$\frac{\nabla p_0}{\nabla{a_i}}$的操作,由于$a$是$[0,2]$的tensor,所以返回了一个$1*3$的tensor。并且仔细观察会发现,当$i=0$时,梯度信息为正

参数retain_graph=True需要解释一下。由于PyTorch在求导一次之后,就会将这个图的梯度信息清除掉,如果第二次再求导,就会报错。但如果写上这个参数,就可以保留梯度信息,就能再求一次导

Last Modified: September 11, 2020
Archives Tip
QR Code for this page
Tipping QR Code