本文参考https://blog.csdn.net/cassiePython/article/details/80089760
非常好的文章
基础概念
Softmax函数的输入是N维的随机真值向量,输出是另一个N维的真值向量,
且值的范围是(0,1),和为1.0。即映射:S(a)= R N \mathbb{R}^{N} RN→ R N \mathbb{R}^{N} RN:
S ( a ) : [ a 1 a 2 … a N ] → [ S 1 S 2 ⋯ S N ] S(\mathbf{a}):\left[\begin{array}{c}{a_{1}} \\ {a_{2}} \\ {\dots} \\ {a_{N}}\end{array}\right] \rightarrow\left[\begin{array}{c}{S_{1}} \\ {S_{2}} \\ {\cdots} \\ {S_{N}}\end{array}\right] S(a):⎣⎢⎢⎡a1a2…aN⎦⎥⎥⎤→⎣⎢⎢⎡S1S2⋯SN⎦⎥⎥⎤
其中每一个元素的公式为:
S j = e a j ∑ k = 1 N e a k ∀ j ∈ 1 … N S_{j}=\frac{e^{a_{j}}}{\sum_{k=1}^{N} e^{a_{k}}} \quad \forall j \in 1 \ldots N Sj=∑k=1Neakeaj∀j∈1…N
显然 S j S_{j} Sj总是正的~(因为指数);因为所有的 S j S_{j} Sj的和为1,所以有 S j S_{j} Sj<1,因此它的范围是(0,1)。
向量计算的准备
在深入理解计算softmax的导数之前,我们先了解向量计算的一些基础知识。
Softmax从根本上来说是一种向量函数。它将向量作为输入并输出另一个向量。换言之,它有多个输入和输出,因此我们不能直接就尝试求”softmax的导数”,我们首先要明确:
- 我们想要计算softmax的哪个组成成分(输出的某元素)的导数。
- 由于softmax具有多个输入,所以要计算关于哪个输入元素的偏导数。
听起来好像很复杂,但这正是为什么定义向量计算的原因。 我们正在寻找的偏导数是: ∂ S i ∂ a j \frac{\partial S_{i}}{\partial a_{j}} ∂aj∂Si
其中 i i i是我们要计算的组成成分(即训练数据中正确的分类),我们要使正确的分类的softmax值最大。
∂ S i ∂ a j = ∂ e a i ∑ k = 1 N e a k ∂ a j \frac{\partial S_{i}}{\partial a_{j}}=\frac{\partial \frac{e^{a_{i}}}{\sum_{k=1}^{N} e^{a_{k}}}}{\partial a_{j}} ∂aj∂Si=∂aj∂∑k=1Neakeai
当 j j j= i i i时
∂ e a i ∑ k = 1 N e a k ∂ a j = e a i ∑ − e a j e a i ∑ 2 \frac{\partial \frac{e^{a_{i}}}{\sum_{k=1}^{N} e^{a_{k}}}}{\partial a_{j}}=\frac{e^{a_{i}} \sum-e^{a_{j}} e^{a_{i}}}{\sum^{2}} ∂aj∂∑k=1Neakeai=∑2eai∑−eajeai
简单起见,我们使用 ∑ \sum ∑表示 ∑ k = 1 N e a k \sum_{k=1}^{N} e^{a_{k}} ∑k=1Neak。继续化简下:
∂ e a i ∑ k = 1 N e a k ∂ a j = e a i ∑ − e a j e a i ∑ 2 \frac{\partial \frac{e^{a_{i}}}{\sum_{k=1}^{N} e^{a_{k}}}}{\partial a_{j}}=\frac{e^{a_{i}} \sum-e^{a_{j}} e^{a_{i}}}{\sum^{2}} ∂aj∂∑k=1Neakeai=∑2eai∑−eajeai
= e a i ∑ ∑ − e a i ∑ = S i ( 1 − S j ) \begin{aligned} &=\frac{e^{a_{i}}}{\sum} \frac{\sum-e^{a_{i}}}{\sum} \\ &=S_{i}\left(1-S_{j}\right) \end{aligned} =