Softmax函数求导与梯度计算
描述:
Softmax函数是机器学习和深度学习中用于多分类问题的核心函数。它将一个包含任意实数的K维向量(通常称为“logits”)映射成一个K维概率分布,其中每个元素的值在(0,1)区间内,且所有元素之和为1。理解Softmax函数的求导过程,即计算其输出对输入的梯度,对于使用梯度下降法训练神经网络至关重要,因为这是反向传播算法中的关键一步。
知识点详解:
我们将分步讲解Softmax函数的定义及其求导过程。
第一步:理解Softmax函数的定义
假设我们有一个包含K个类别的分类问题。对于一个输入样本,神经网络最后一层会输出一个K维向量 z = [z1, z2, ..., zK],其中zj是第j个类别的得分(logit)。
Softmax函数将这个得分向量转换成一个概率分布向量 a = [a1, a2, ..., aK]。向量a中的每个元素aj(代表样本属于第j类的概率)的计算公式如下:
aj = e^{zj} / (e^{z1} + e^{z2} + ... + e^{zK})
为了简化书写,我们引入一个求和符号S,令 S = Σ_{k=1}^{K} e^{zk}。这样,公式可以简写为:
aj = e^{zj} / S
第二步:明确求导的目标
在反向传播中,我们需要计算损失函数L对网络每一层参数(包括Softmax层的输入z)的梯度。具体到Softmax层,我们需要计算每一个输出概率ai对每一个输入得分zj的偏导数,即 ∂ai / ∂zj。
这里的关键点是:ai是z向量中所有元素的函数,而不仅仅是zi的函数。因此,当我们对某个特定的zj求导时,会出现两种情况:
- 当 i = j 时:我们计算
ai对zi的偏导(∂ai / ∂zi)。 - 当 i ≠ j 时:我们计算
ai对zj的偏导(∂ai / ∂zj)。
第三步:情况一推导(当 i = j 时)
我们要计算 ∂ai / ∂zi。
已知 ai = e^{zi} / S,且 S = Σ_{k=1}^{K} e^{zk}。这里,e^{zi}是分子,S是分母,并且S中也包含了e^{zi}这一项。因此,我们需要使用商的求导法则:(u/v)' = (u'v - uv') / v²。
- 令
u = e^{zi},则u' = ∂u/∂zi = e^{zi}。 - 令
v = S,则v' = ∂S/∂zi = ∂(e^{z1} + ... + e^{zi} + ... + e^{zK})/∂zi = e^{zi}。因为对zi求导时,只有e^{zi}这一项的导数不为零。
代入商的求导法则:
∂ai / ∂zi = (u'v - uv') / v² = (e^{zi} * S - e^{zi} * e^{zi}) / S²
提取公因子 e^{zi}:
= e^{zi} (S - e^{zi}) / S²
将分子分母同时除以S,并将其拆分为两项:
= (e^{zi} / S) * ((S - e^{zi}) / S)
根据定义 ai = e^{zi} / S,并且 (S - e^{zi}) / S = 1 - e^{zi}/S = 1 - ai。
因此,我们得到最终结果:
∂ai / ∂zi = ai (1 - ai)
第四步:情况二推导(当 i ≠ j 时)
我们要计算 ∂ai / ∂zj。
已知 ai = e^{zi} / S。现在,我们对zj求导,其中j ≠ i。
- 分子
e^{zi}中不包含zj,因此将其视为常数,∂(e^{zi})/∂zj = 0。 - 分母
S中包含e^{zj},所以∂S/∂zj = e^{zj}。
再次使用商的求导法则:
∂ai / ∂zj = (u'v - uv') / v² = (0 * S - e^{zi} * e^{zj}) / S² = (- e^{zi} e^{zj}) / S²
将其重新组合:
= - (e^{zi} / S) * (e^{zj} / S)
根据定义 ai = e^{zi} / S 和 aj = e^{zj} / S。
因此,我们得到最终结果:
∂ai / ∂zj = -ai * aj
第五步:总结梯度公式
现在,我们可以将Softmax函数的梯度写成一个完整的、简洁的公式:
∂ai / ∂zj = ai (δij - aj)
其中 δij 是Kronecker delta函数,其定义为:
δij = 1当i = jδij = 0当i ≠ j
这个公式完美地概括了我们在第三步和第四步推导的两种情形:
- 当
i = j时,δij = 1,公式变为ai (1 - aj),即ai (1 - ai)。 - 当
i ≠ j时,δij = 0,公式变为ai (0 - aj) = -ai aj。
第六步:结合交叉熵损失函数(实际应用)
在绝大多数分类任务中,Softmax函数会与交叉熵损失函数结合使用。假设真实的标签是one-hot编码,即只有一个类别t为1,其余为0。那么交叉熵损失为:
L = - Σ_{k=1}^{K} tk * log(ak)
由于只有一个tk=1(设tt=1),其余为0,所以损失简化为:
L = - log(at)
现在,我们来计算损失L对Softmax输入zj的梯度,这是反向传播中实际需要传递的梯度。
∂L / ∂zj = ∂(-log(at)) / ∂zj = - (1/at) * (∂at / ∂zj)
根据我们刚刚推导的Softmax梯度公式 ∂at / ∂zj = at (δtj - aj),代入上式:
∂L / ∂zj = - (1/at) * [at (δtj - aj)] = - (δtj - aj) = aj - δtj
这个结果非常简洁优美:
- 如果
j就是真实类别t(即j = t),那么δtj = 1,梯度为aj - 1。 - 如果
j不是真实类别t(即j ≠ t),那么δtj = 0,梯度为aj - 0 = aj。
这意味着,在计算损失函数对Softmax输入的梯度时,我们不需要一步步地回溯Softmax复杂的内部求导过程。我们只需要用模型预测的概率分布a减去真实标签的分布t(one-hot向量)即可:
∂L / ∂z = a - t
这个简洁的梯度形式是Softmax与交叉熵损失结合使用所带来的巨大便利,也是其在多分类问题中如此流行的主要原因之一。