softmax+cross-entropy的前向计算、反向传播的公式推导
本文主要是讲述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=∑jNeajeai
模型输出[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=∑jNeajeai=C⋅∑jNeajC⋅eai=elog(C)⋅∑jNeajelog(C)⋅eai=∑jNeaj+log(C)eai+log(C)=∑jNeaj−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∑Nyi⋅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∂(∑jNeajeai)
因为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∑Neaj=∑
当 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∑Nyipi1
根据链式法则(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∑yipi1)⋅∂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∑yipi1⋅pi⋅(1−pj)=−i=j∑yi⋅(1−pj)=−yi+yipj(因为只有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∑yipi1⋅(−pi⋅pj)=i=j∑yipj−−−③
因为②和③其实是①的互斥情况,所以可以合并:
①=②+③(记住在②中,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+yipj+i=j∑yipj=−yi+(i=j∑yipj+i=j∑yipj)=−yi+i∑Nyipj(因为yi是one−hot,i∑Nyi=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的前向计算、反向传播的公式推导相关推荐
- 4.6 前向和反向传播-深度学习-Stanford吴恩达教授
←上一篇 ↓↑ 下一篇→ 4.5 搭建深层神经网络快 回到目录 4.7 参数 vs. 超参数 前向和反向传播 (Forward and Backward Propagation) 之前我们学习了构成深 ...
- Pytorch 自定义激活函数前向与反向传播 Tanh
看完这篇,你基本上可以自定义前向与反向传播,可以自己定义自己的算子 文章目录 Tanh 公式 求导过程 优点: 缺点: 自定义Tanh 与Torch定义的比较 可视化 import matplotli ...
- 卷积神经网络前向及反向传播过程数学解析
卷积神经网络前向及反向传播过程数学解析 文章目录 <center>卷积神经网络前向及反向传播过程数学解析 1.卷积神经网络初印象 2.卷积神经网络性质 3.前向传播 3.1.卷积层层级间传 ...
- numpy实现简单的二层网络------前向和反向传播
会推导神经网络的前向和反向传播是深度学习的基础,也许大家在实验使用Tensorflow框架,只需要调用某一个损失函数,传入参数就可以得到损失,或者Mxnet框架,你都不需要调用任何函数,给个标志就可以 ...
- meanpool maxpool 前向和反向传播
mean max 前向和反向传播 感觉平均迟化对值不太公平,应该加个权重,让算法自动去决定哪个 cnn中关于平均池化和最大池化的理解 接触到pooling主要是在用于图像处理的卷积神经网络中,但随着深 ...
- 神经网络的前向和反向传播
1.前向传播 前向传播的作用就是为了获取误差损失:现在以示例来说明: 上图是一个典型的神经网络结构,包括了输入层.隐含层和输出层,为了更好的讲解,现在对其进行赋值: 目标:给出输入数据i1,i2(0. ...
- Pytorch 自定义激活函数前向与反向传播 sigmoid
文章目录 Sigmoid 公式 求导过程 优点: 缺点: 自定义Sigmoid 与Torch定义的比较 可视化 import matplotlib import matplotlib.pyplot a ...
- 反向传播算法公式推导,神经网络的推导
如何理解神经网络里面的反向传播算法 反向传播算法(Backpropagation)是目前用来训练人工神经网络(ArtificialNeuralNetwork,ANN)的最常用且最有效的算法. 其主要思 ...
- pytorch学习笔记(三十):RNN反向传播计算图公式推导
前言 本节将介绍循环神经网络中梯度的计算和存储方法,即 通过时间反向传播(back-propagation through time). 正向传播在循环神经网络中比较直观,而通过时间反向传播其实是反向 ...
最新文章
- kafka同一个gruopid下多个consumer订阅同一个topic,只有一个consumer能消费到数据
- Gentoo 安装日记 14 (配置内核 :设备驱动)
- PDF下载!《Python十大基础专题》《247个Python综合案例》《Pandas 20页学习笔记》...
- 【LeetCode】剑指 Offer 40. 最小的k个数
- blob clob区别
- Spring中的Bean是线程安全的么?
- 怎样提高你的Google Adsense收入
- WinForm界面开发教程:DevExpress WidgetView使用介绍
- 应用时间序列分析——有季节效应的非平稳序列分析-ARIMA加法模型-R语言
- VBlog项目代码理解之前端
- java汉诺塔5层攻略_史上最难智力游戏第5关汉诺塔图文通关攻略
- 使用WebDriver 登录163邮箱
- 今有物不知其数,三三数只剩其二,五五数只剩其三,七七数只剩其二
- 使用Python,SMTP发邮件到qq邮箱(文本/超链接/图片/表格/附件表格)
- 华为云、百度云 群控系统开发流程
- 对象流水线 -- 工厂模式介绍 使用案例及代码演示
- 书单 | 带你轻松度假的10本好书!
- NB模块-QS100-默认demo
- computehash在php怎么实现,卓象程序员:PHP实现基础区块链
- 数据科学与计算机学院凌云,陶钧(中山大学数据科学与计算机学院副教授)_百度百科...
热门文章
- C语言中,1U<<29的意思
- 与古人有关......
- URP——着色器和材质——灯光着色器 Lit
- pip安装matplotlib
- 计算机网络校园网服务器搭建,计算机网络校园网服务器搭建课程设计(绝对等级).doc...
- 基于SSM的高校课程评价系统
- 开发者实践丨Agora Home AI 音视频的未来
- QQ邮箱 接受 天气查询 阿里云自动运行学习记录
- mysql语句统计总数_一条sql语句实现统计查询_MySQL
- java二面烩面什么问题_小米Java面试题,一面二面面经分享