本文主要是讲述Softmax和CrossEntropy的公式推导,并用代码进一步佐证。

1. Softmax前向计算

我们把SoftmaxSoftmaxSoftmax输出的概率定义为 pip_ipi​:
Softmax(ai)=pi=eai∑jNeajSoftmax(a_i) = p_i = \frac {e^{a_i}} {\sum_j^N e^{a_j}} Softmax(ai​)=pi​=∑jN​eaj​eai​​
模型输出[a1,a2,...,aN][a_1, a_2, ..., a_N][a1​,a2​,...,aN​],共N个值。
其中aia_iai​代表第iii个输出值,pip_ipi​代表第iii个输出值经过SoftmaxSoftmaxSoftmax计算过后的概率。
且 p1+p2+...+pN=1p_1+p_2+...+p_N=1p1​+p2​+...+pN​=1

1.1 数值稳定

因为Softmax涉及到指数函数,且底数 eee 大于1,在计算机中是可能会有溢出风险的。结合指数、对数函数的转换规则,我们可以制定一些数值稳定的优化策略。(当然这些是在框架中实现的,学习更多是为了扩展视野)

数值稳定的主要思路在于aia_iai​减去A=[a1,a2,...,aN]A=[a_1, a_2, ..., a_N]A=[a1​,a2​,...,aN​]中的最大值max(A)max(A)max(A)
pi=eai∑jNeaj=C⋅eaiC⋅∑jNeaj=elog⁡(C)⋅eaielog⁡(C)⋅∑jNeaj=eai+log⁡(C)∑jNeaj+log⁡(C)=eai−max(A)∑jNeaj−max(A)\begin{aligned} p_i & = \frac {e^{a_i}} {\sum_j^N e^{a_j}}\\ & = \frac {C \cdot e^{a_i}} {C \cdot \sum_j^N e^{a_j}}\\ & = \frac {e^{\log(C)} \cdot e^{a_i}} {e^{\log(C)} \cdot \sum_j^N e^{a_j}}\\ & = \frac {e^{a_i + \log(C)}} {\sum_j^N e^{a_j + \log(C)}}\\ & = \frac {e^{a_i - max(A)}} {\sum_j^N e^{a_j - max(A)}}\\ \end{aligned} pi​​=∑jN​eaj​eai​​=C⋅∑jN​eaj​C⋅eai​​=elog(C)⋅∑jN​eaj​elog(C)⋅eai​​=∑jN​eaj​+log(C)eai​+log(C)​=∑jN​eaj​−max(A)eai​−max(A)​​
因为C是常数,log(C)log(C)log(C)也是常数,所以我们可以类比到分子分母同时加上 -max(A),并不会改变pip_ipi​的计算结果。
A中各项均减去最大值,就能确保A中所有项都不会上溢出。

2. Cross-Entropy前向计算

我们把交叉熵损失(Cross Entropy Loss)定义为 HHH,同时传入Softmax得出的概率pip_ipi​及其对应的Label yiy_iyi​:
CELoss(yi,pi)=H(yi,pi)=−∑iNyi⋅log⁡(pi)CELoss(y_i, p_i) = H(y_i, p_i) = -\sum_i^Ny_i \cdot \log (p_i) CELoss(yi​,pi​)=H(yi​,pi​)=−i∑N​yi​⋅log(pi​)
在多分类问题中,我们的 Label 通常以独热码(one-hot)的形式展现和训练,因此在 Y=[y1,y2,...,yN]Y=[y_1, y_2, ..., y_N]Y=[y1​,y2​,...,yN​] 中,只有一项为 111,其余项为 000,即 [0,0,...,1,...,0,0][0, 0, ..., 1, ..., 0, 0][0,0,...,1,...,0,0]。
所以 H(yi,pi)H(y_i, p_i)H(yi​,pi​) 也等于 −yi⋅log⁡(pi)-y_i \cdot \log(p_i)−yi​⋅log(pi​),yi=1y_i=1yi​=1 对应Label的类别。

3. Softmax反向传播求导

因为Softmax+Cross-Entropy的反向传播包含基于Softmax的求导公式,所以我们先推导Softmax的导数。
据 SoftmaxSoftmaxSoftmax 公式可知,每个 pip_ipi​ 均是所有 aaa 都有参与运算的(在分母的累加中体现),因此梯度的形式为:
∂pi∂aj=∂(eai∑jNeaj)∂aj\frac {\partial p_i} {\partial a_j} = \frac{\partial (\frac {e^{a_i}}{\sum_j^N e^{a_j}})}{\partial a_j}∂aj​∂pi​​=∂aj​∂(∑jN​eaj​eai​​)​
因为iii和jjj可能不相同,所以iii 和 jjj 的关系要分类讨论。

这里要先复习下含分母的求导公式:
(h(x)g(x))′=h′(x)⋅g(x)−h(x)⋅g′(x)g(x)2(\frac{h(x)}{g(x)})^\prime = \frac{h'(x)\cdot g(x)-h(x)\cdot g'(x)}{g(x)^2} (g(x)h(x)​)′=g(x)2h′(x)⋅g(x)−h(x)⋅g′(x)​
并且简化一下符号:
∑jNeaj=∑\sum_j^Ne^{a_j} = \sum j∑N​eaj​=∑
当 i=ji=ji=j:
∂pi∂aj=eai⋅∑−eai⋅eaj∑⋅∑=eai⋅(∑−eaj)∑⋅∑=pi⋅(1−pj)\begin{aligned} \frac {\partial p_i} {\partial a_j} & = \frac{e^{a_i} \cdot \sum - e^{a_i} \cdot e^{a_j}}{\sum \cdot \sum} \\ & = \frac{e^{a_i} \cdot (\sum - e^{a_j})}{\sum \cdot \sum}\\ & = p_i \cdot (1 - p_j)\\ \end{aligned} ∂aj​∂pi​​​=∑⋅∑eai​⋅∑−eai​⋅eaj​​=∑⋅∑eai​⋅(∑−eaj​)​=pi​⋅(1−pj​)​
当i≠ji \neq ji​=j(对aja_jaj​求导,相当于eaie^{a_i}eai​是常数,导数为 0):
∂pi∂aj=0⋅∑−eai⋅eaj∑⋅∑=−pi⋅pj\begin{aligned} \frac {\partial p_i} {\partial a_j} & = \frac{0 \cdot \sum - e^{a_i} \cdot e^{a_j}}{\sum \cdot \sum} \\ & = - p_i \cdot p_j \end{aligned} ∂aj​∂pi​​​=∑⋅∑0⋅∑−eai​⋅eaj​​=−pi​⋅pj​​

4. Cross-Entropy + Softmax反向传播求导

Cross-Entropy的导数为:
H′(yi,pi)=−∑iNyi1piH'(y_i, p_i) = -\sum_i^Ny_i\frac{1}{p_i} H′(yi​,pi​)=−i∑N​yi​pi​1​
根据链式法则(Chain Rule),整体损失对于aja_jaj​的导数为:
∂H∂aj=∂H∂pi⋅∂pi∂aj=(−∑iyi1pi)⋅∂pi∂aj−−−①\frac {\partial H}{\partial a_j} = \frac {\partial H}{\partial p_i} \cdot \frac {\partial p_i}{\partial a_j} = (-\sum_iy_i\frac{1}{p_i}) \cdot \frac {\partial p_i}{\partial a_j}---① ∂aj​∂H​=∂pi​∂H​⋅∂aj​∂pi​​=(−i∑​yi​pi​1​)⋅∂aj​∂pi​​−−−①
当 i=ji=ji=j:
①=−∑i=jyi1pi⋅pi⋅(1−pj)=−∑i=jyi⋅(1−pj)=−yi+yipj(因为只有i,可以把∑去掉)−−−②\begin{aligned} ① & = -\sum_{i=j}y_i\frac{1}{p_i} \cdot p_i \cdot (1 - p_j) \\ & = -\sum_{i=j}y_i\cdot (1 - p_j) \\ & = -y_i + y_ip_j (因为只有i,可以把\sum去掉)---② \end{aligned} ①​=−i=j∑​yi​pi​1​⋅pi​⋅(1−pj​)=−i=j∑​yi​⋅(1−pj​)=−yi​+yi​pj​(因为只有i,可以把∑去掉)−−−②​
当i≠ji \neq ji​=j:
①=−∑i≠jyi1pi⋅(−pi⋅pj)=∑i≠jyipj−−−③\begin{aligned} ① & = -\sum_{i \neq j}y_i\frac{1}{p_i} \cdot (-p_i \cdot p_j) \\ & = \sum_{i \neq j}y_i p_j --- ③ \end{aligned} ①​=−i​=j∑​yi​pi​1​⋅(−pi​⋅pj​)=i​=j∑​yi​pj​−−−③​
因为②和③其实是①的互斥情况,所以可以合并:
①=②+③(记住在②中,i=j)=−yi+yipj+∑i≠jyipj=−yi+(∑i=jyipj+∑i≠jyipj)=−yi+∑iNyipj(因为yi是one−hot,∑iNyi=1)=pj−yj(因为②中i=j,则yi=yj)\begin{aligned} ① & = ②+③(记住在②中,i=j) \\ & = -y_i + y_ip_j + \sum_{i \neq j}y_i p_j \\ & = -y_i + (\sum_{i=j}y_ip_j + \sum_{i \neq j}y_i p_j) \\ & = -y_i + \sum_i^N y_ip_j(因为y_i是one-hot,\sum_i^N y_i=1) \\ & = p_j - y_j(因为②中i=j,则y_i=y_j) \end{aligned} ①​=②+③(记住在②中,i=j)=−yi​+yi​pj​+i​=j∑​yi​pj​=−yi​+(i=j∑​yi​pj​+i​=j∑​yi​pj​)=−yi​+i∑N​yi​pj​(因为yi​是one−hot,i∑N​yi​=1)=pj​−yj​(因为②中i=j,则yi​=yj​)​
整个Softmax+CrossEntropy的求导推导下来发现,HHH对于aja_jaj​的梯度值,就是让他的pjp_jpj​去减对应的label值(yjy_jyj​)。
举例P = [0.5, 0.3, 0.2],Y=[1, 0, 0],对应的导数就是 [-0.5, 0.3, 0.2]。

5. 代码验证

先看下x在softmax+cross entorpy前向计算并且BP后,所产生的梯度是多少,即∂H∂aj\frac{\partial H}{\partial a_j}∂aj​∂H​,在这个例子中分别对a1,a2,a3求梯度:

x = torch.randn((1, 3), requires_grad=True)
# tensor([[-0.3876,  0.2697, -1.6527]], requires_grad=True)
y = torch.randint(3, (1,), dtype=torch.int64)
# tensor([1])loss = F.cross_entropy(x, y)
# F.cross_entropy含了softmax+cross_entropy
# 因此直接调用即可,无需先使用F.softmax
print(loss)
# tensor(0.5095, grad_fn=<NllLossBackward>)loss.backward()
print(x.grad)
# tensor([[ 0.3113, -0.3992,  0.0879]])

下面再看下 pip_ipi​ 的值:

F.softmax(x, dim=1)
# tensor([[0.3113, 0.6008, 0.0879]], grad_fn=<SoftmaxBackward>)

发现没有!发现没有!除了 a1.grada_1.grada1​.grad 比 p1p_1p1​ 减了1之外,其他都没变!正正验证了上面的公式推导!

6. 总结

总结一下,在多分类问题中,softmax+cross entropy是比较普遍,且计算速度较快的损失函数(loss function),因为它的梯度仅仅只用把概率值(pi)减去标签(yi)即可!
这在训练的初期,可以提供较快的训练速度,以提供后续优化的方向。当然,后续也包括对损失函数的优化!

softmax+cross-entropy的前向计算、反向传播的公式推导相关推荐

  1. 4.6 前向和反向传播-深度学习-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 4.5 搭建深层神经网络快 回到目录 4.7 参数 vs. 超参数 前向和反向传播 (Forward and Backward Propagation) 之前我们学习了构成深 ...

  2. Pytorch 自定义激活函数前向与反向传播 Tanh

    看完这篇,你基本上可以自定义前向与反向传播,可以自己定义自己的算子 文章目录 Tanh 公式 求导过程 优点: 缺点: 自定义Tanh 与Torch定义的比较 可视化 import matplotli ...

  3. 卷积神经网络前向及反向传播过程数学解析

    卷积神经网络前向及反向传播过程数学解析 文章目录 <center>卷积神经网络前向及反向传播过程数学解析 1.卷积神经网络初印象 2.卷积神经网络性质 3.前向传播 3.1.卷积层层级间传 ...

  4. numpy实现简单的二层网络------前向和反向传播

    会推导神经网络的前向和反向传播是深度学习的基础,也许大家在实验使用Tensorflow框架,只需要调用某一个损失函数,传入参数就可以得到损失,或者Mxnet框架,你都不需要调用任何函数,给个标志就可以 ...

  5. meanpool maxpool 前向和反向传播

    mean max 前向和反向传播 感觉平均迟化对值不太公平,应该加个权重,让算法自动去决定哪个 cnn中关于平均池化和最大池化的理解 接触到pooling主要是在用于图像处理的卷积神经网络中,但随着深 ...

  6. 神经网络的前向和反向传播

    1.前向传播 前向传播的作用就是为了获取误差损失:现在以示例来说明: 上图是一个典型的神经网络结构,包括了输入层.隐含层和输出层,为了更好的讲解,现在对其进行赋值: 目标:给出输入数据i1,i2(0. ...

  7. Pytorch 自定义激活函数前向与反向传播 sigmoid

    文章目录 Sigmoid 公式 求导过程 优点: 缺点: 自定义Sigmoid 与Torch定义的比较 可视化 import matplotlib import matplotlib.pyplot a ...

  8. 反向传播算法公式推导,神经网络的推导

    如何理解神经网络里面的反向传播算法 反向传播算法(Backpropagation)是目前用来训练人工神经网络(ArtificialNeuralNetwork,ANN)的最常用且最有效的算法. 其主要思 ...

  9. pytorch学习笔记(三十):RNN反向传播计算图公式推导

    前言 本节将介绍循环神经网络中梯度的计算和存储方法,即 通过时间反向传播(back-propagation through time). 正向传播在循环神经网络中比较直观,而通过时间反向传播其实是反向 ...

最新文章

  1. kafka同一个gruopid下多个consumer订阅同一个topic,只有一个consumer能消费到数据
  2. Gentoo 安装日记 14 (配置内核 :设备驱动)
  3. PDF下载!《Python十大基础专题》《247个Python综合案例》《Pandas 20页学习笔记》...
  4. 【LeetCode】剑指 Offer 40. 最小的k个数
  5. blob clob区别
  6. Spring中的Bean是线程安全的么?
  7. 怎样提高你的Google Adsense收入
  8. WinForm界面开发教程:DevExpress WidgetView使用介绍
  9. 应用时间序列分析——有季节效应的非平稳序列分析-ARIMA加法模型-R语言
  10. VBlog项目代码理解之前端
  11. java汉诺塔5层攻略_史上最难智力游戏第5关汉诺塔图文通关攻略
  12. 使用WebDriver 登录163邮箱
  13. 今有物不知其数,三三数只剩其二,五五数只剩其三,七七数只剩其二
  14. 使用Python,SMTP发邮件到qq邮箱(文本/超链接/图片/表格/附件表格)
  15. 华为云、百度云 群控系统开发流程
  16. 对象流水线 -- 工厂模式介绍 使用案例及代码演示
  17. 书单 | 带你轻松度假的10本好书!
  18. NB模块-QS100-默认demo
  19. computehash在php怎么实现,卓象程序员:PHP实现基础区块链
  20. 数据科学与计算机学院凌云,陶钧(中山大学数据科学与计算机学院副教授)_百度百科...

热门文章

  1. C语言中,1U<<29的意思
  2. 与古人有关......
  3. URP——着色器和材质——灯光着色器 Lit
  4. pip安装matplotlib
  5. 计算机网络校园网服务器搭建,计算机网络校园网服务器搭建课程设计(绝对等级).doc...
  6. 基于SSM的高校课程评价系统
  7. 开发者实践丨Agora Home AI 音视频的未来
  8. QQ邮箱 接受 天气查询 阿里云自动运行学习记录
  9. mysql语句统计总数_一条sql语句实现统计查询_MySQL
  10. java二面烩面什么问题_小米Java面试题,一面二面面经分享