学习随笔|softmax函数及交叉熵损失函数求导

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)?
这样就保证了数据不会计算出来太大。
计算过程图示(搬运)如下:学习随笔|softmax函数及交叉熵损失函数求导
文章图片

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?有两种情况,这两种情况的导数是不一样的。分别是:

  1. 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
  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?
然后两种情况相加 ? C ? a i = ( ? ∑ j y j 1 p j ) ? p j ? a i = ? y i p i p i ( 1 ? p i ) + ∑ j = ≠ i y j p j p i p j = ? y i + y i p i + ∑ j = ≠ i y j p i = ? y i + p i ∑ j y j \frac{\partial C}{\partial a_{i}}=\left(-\sum_{j} y_{j} \frac{1}{p_{j}}\right) \frac{\partial p_{j}}{\partial a_{i}}=-\frac{y_{i}}{p_{i}} p_{i}\left(1-p_{i}\right)+\sum_{j =\neq i} \frac{y_{j}}{p_{j}} p_{i} p_{j}=-y_{i}+y_{i} p_{i}+\sum_{j =\neq i} y_{j} p_{i}=-y_{i}+p_{i} \sum_{j} y_{j} ?ai??C?=(?j∑?yj?pj?1?)?ai??pj??=?pi?yi??pi?(1?pi?)+j=??=i∑?pj?yj??pi?pj?=?yi?+yi?pi?+j=??=i∑?yj?pi?=?yi?+pi?j∑?yj?
因为 ∑ 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交叉熵损失函数求导

    推荐阅读