numpy:计算softmax函数的导数

时间:2016-11-13 16:02:55

标签: python numpy neural-network backpropagation softmax

我试图在backpropagation的简单3层神经网络中理解MNIST

输入图层包含weightsbias。标签为MNIST,因此它是10类向量。

第二层是linear tranform。第三层是softmax activation,以输出为概率。

Backpropagation计算每一步的导数并将其称为渐变。

之前的图层会将globalprevious渐变添加到local gradient。我无法计算local gradient

softmax

在线的几个资源通过对softmax及其衍生物的解释,甚至给出softmax本身的代码样本

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

关于何时i = j和何时i != 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.gradientlocal gradient,它是一个向量。它是否正确?有没有更好的方法来写这个?

3 个答案:

答案 0 :(得分:15)

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

enter image description here enter image description here

这是3层NN(输入层,只有一个隐藏层和一个输出层)的一般场景。您可以按照上述步骤计算易于计算的渐变!由于这篇文章的另一个答案已经指出了代码中的问题,我不会重复相同的内容。

答案 1 :(得分:9)

正如我所说,你有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)

答案 2 :(得分:5)

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是矩阵,请检查此笔记本中的softmax函数(https://github.com/rickiepark/ml-learn/blob/master/notebooks/5.%20multi-layer%20perceptron.ipynb