numpy :计算 softmax 函数的导数

numpy : calculate the derivative of the softmax function

我正在尝试通过 MNIST.

在一个简单的 3 层神经网络中理解 backpropagation

输入层 weightsbias。标签是 MNIST 所以它是一个 10 class 向量。

第二层是linear tranform。第三层是 softmax activation 得到概率的输出。

Backpropagation 计算每一步的导数,称之为梯度。

前面的图层将 globalprevious 渐变附加到 local gradient。我无法计算 softmax

local gradient

一些在线资源解释了 softmax 及其导数,甚至给出了 softmax 本身的代码示例

def softmax(x):
    """Compute the softmax of vector x."""
    exps = np.exp(x)
    return exps / np.sum(exps)

关于i = ji != j时的导数进行了解释。这是我想出的一个简单的代码片段,希望能验证我的理解:

def softmax(self, x):
    """Compute the softmax of vector x."""
    exps = np.exp(x)
    return exps / np.sum(exps)

def forward(self):
    # self.input is a vector of length 10
    # and is the output of 
    # (w * x) + b
    self.value = self.softmax(self.input)

def backward(self):
    for i in range(len(self.value)):
        for j in range(len(self.input)):
            if i == j:
                self.gradient[i] = self.value[i] * (1-self.input[i))
            else: 
                 self.gradient[i] = -self.value[i]*self.input[j]

那么self.gradient就是local gradient,它是一个向量。这个对吗?有没有更好的写法?

正如我所说,你有 n^2 个偏导数。

如果你计算一下,你会发现 dSM[i]/dx[k]SM[i] * (dx[i]/dx[k] - SM[i]) 所以你应该有:

if i == j:
    self.gradient[i,j] = self.value[i] * (1-self.value[i])
else: 
    self.gradient[i,j] = -self.value[i] * self.value[j]

而不是

if i == j:
    self.gradient[i] = self.value[i] * (1-self.input[i])
else: 
     self.gradient[i] = -self.value[i]*self.input[j]

顺便说一下,这可能会像这样更简洁地计算(矢量化):

SM = self.value.reshape((-1,1))
jac = np.diagflat(self.value) - np.dot(SM, SM.T)

我假设您有一个 3 层 NN,其中 W1b1 与从输入层到隐藏层的线性变换以及 W2b2 与从隐藏层到输出层的线性变换相关联。 Z1Z2是隐藏层和输出层的输入向量。 a1a2代表隐藏层和输出层的输出。 a2 是您的预测输出。 delta3delta2 是误差(反向传播),您可以看到损失函数相对于模型参数的梯度。

这是一个 3 层 NN(输入层,只有一个隐藏层和一个输出层)的一般场景。您可以按照上述过程计算梯度,这应该很容易计算!由于此 post 的另一个答案已经指出了您代码中的问题,因此我不再重复。

np.exp 不稳定,因为它有 Inf。 所以你应该在 x.

中减去最大值
def softmax(x):
    """Compute the softmax of vector x."""
    exps = np.exp(x - x.max())
    return exps / np.sum(exps)

如果x是矩阵,请检查this notebook中的softmax函数。