1.softmax函数 使用softmax函数主要是为了解决多分类问题,在一个分类神经网络中,该函数能够将多个神经元的输出转换到(0,1)之间,可以当概率来理解,这样就可以取其中最大值当做被分到哪一类。
假设一组神经元的输出为 a [ n ] a[n] a[n],那么 p i p_i pi?就可以表示为:
p i = e a i ∑ j = 1 n e a j p_{i}=\frac{e^{a_i}}{\sum_{j=1}^{n} e^{a_j}} pi?=∑j=1n?eaj?eai??
这里有个问题,这样的式子,由于存在指数函数,在计算中可能会出现不稳定情况(数据可能非常非常大)
所以一般我们计算过程中是做如下变换:
p i = e a i ? m a x ( a ) ∑ j = 1 n e a j ? m a x ( a ) p_{i}=\frac{e^{a_i-max(a)}}{\sum_{j=1}^{n} e^{a_j-max(a)}} pi?=∑j=1n?eaj??max(a)eai??max(a)?
因为
e a i ? m a x ( a ) ∑ j = 1 n e a j ? m a x ( a ) = e a i / e m a x ( a ) ∑ j = 1 n e a j / e m a x ( a ) = e a i ? m a x ( a ) ∑ j = 1 n e a j ? m a x ( a ) \frac{e^{a_i-max(a)}}{\sum_{j=1}^{n} e^{a_j-max(a)}}=\frac{e^{a_i}/e^{max(a)}}{\sum_{j=1}^{n} e^{a_j}/e^{max(a)}}=\frac{e^{a_i-max(a)}}{\sum_{j=1}^{n} e^{a_j-max(a)}} ∑j=1n?eaj??max(a)eai??max(a)?=∑j=1n?eaj?/emax(a)eai?/emax(a)?=∑j=1n?eaj??max(a)eai??max(a)?
这样就保证了数据不会计算出来太大。
计算过程图示(搬运)如下:
文章图片
2.softmax函数相关求导 一般分类任务中,我们使用交叉熵损失函数:
C = ? ∑ i n y i ln ? p i C=-\sum_{i}^n y_{i} \ln p_{i} C=?i∑n?yi?lnpi?
然后我们要明确一下我们要求什么,我们要求的是我们的 l o s s loss loss对于神经元输出 a i a_i ai?的梯度,即:
? C ? a i \frac{\partial C}{\partial a_{i}} ?ai??C?
根据链式求导法则:
? C ? a i = ? C ? p j ? p j ? a i \frac{\partial C}{\partial a_{i}}=\frac{\partial C}{\partial p_{j}} \frac{\partial p_{j}}{\partial a_{i}} ?ai??C?=?pj??C??ai??pj??
其中 ? C ? p j = ? ( ? ∑ j n y j ln ? p j ) ? p j = ? ∑ j n y j 1 p j \frac{\partial C}{\partial p_{j}}=\frac{\partial\left(-\sum_{j}^{n} y_{j} \ln p_{j}\right)}{\partial p_{j}}=-\sum_{j}^{n} y_{j} \frac{1}{p_{j}} ?pj??C?=?pj??(?∑jn?yj?lnpj?)?=?j∑n?yj?pj?1?
注意这里的 p j p_j pj?有两种情况,这两种情况的导数是不一样的。分别是:
- j = i 时: ? p j ? a i = ? p i ? a i = ? e a i ∑ k = 1 n e a k ? a i = e a i ∑ k = 1 n e a k ? e a i e a i ( ∑ k = 1 n e a k ) 2 = p i ? p i 2 \frac{\partial p_{j}}{\partial a_{i}} = \frac{\partial p_{i}}{\partial a_{i}} = \frac{\partial{ \frac{e^{a_i}}{\sum_{k=1}^{n} e^{a_k}}}}{\partial a_{i}} = \frac{{e^{a_i}}{\sum_{k=1}^{n} e^{a_k}}-e^{a_i}e^{a_i}}{({\sum_{k=1}^{n} e^{a_k}})^2} = p_i-{p_i}^2 ?ai??pj??=?ai??pi??=?ai??∑k=1n?eak?eai???=(∑k=1n?eak?)2eai?∑k=1n?eak??eai?eai??=pi??pi?2
- j ≠ i 时: ? p j ? a i = ? e a j ∑ k = 1 n e a k ? a i = ? e a j e a i ( ∑ k = 1 n e a k ) 2 = ? p j p i \frac{\partial p_{j}}{\partial a_{i}} = \frac{\partial{ \frac{e^{a_j}}{\sum_{k=1}^{n} e^{a_k}}}}{\partial a_{i}} = \frac{-e^{a_j}e^{a_i}}{({\sum_{k=1}^{n} e^{a_k}})^2} = -p_jp_i ?ai??pj??=?ai??∑k=1n?eak?eaj???=(∑k=1n?eak?)2?eaj?eai??=?pj?pi?
因为 ∑ y i = 1 \sum y_i = 1 ∑yi?=1,所以:
? C ? a i = p i ? y i \frac{\partial C}{\partial a_{i}}=p_{i}-y_{i} ?ai??C?=pi??yi?
参考链接 【学习随笔|softmax函数及交叉熵损失函数求导】[1] softmax函数详解与推导
[2] 简单易懂的softmax交叉熵损失函数求导
推荐阅读
- R语言从入门到机器学习|R语言对dataframe的行数据进行排序(Ordering rows)实战(使用R原生方法、data.table、dplyr等方案)
- R语言入门课|R语言使用reshape包的rename函数修改数据变量的名称、例如、使用rename函数自定义修改dataframe数据列的名称
- 人脸识别|推荐 6 个 yyds 的人脸识别系统
- 深度学习|神经网络中的激活函数与损失函数&深入理解推导softmax交叉熵
- R语言入门课|R语言使用dim函数查看数据维度、例如、使用dim函数查看dataframe数据有多少行多少列
- 软件|一个让你觉得相见恨晚的工具——utools
- 大数据|谷歌大神Jeff Dean领衔,万字展望5大AI趋势
- 算法|腾讯图像超分辨率算法RealSR,开源了
- 神经网络|Real-SR算法,实现真实图像超高分辨率处理