numpy: вычислить производную функции softmax

я пытаюсь понять backpropagation в простой 3-х слоистой нейронной сети с MNIST.

есть входной слой с weights и bias. Этикетки MNIST это 10 вектор класса.

второй слой-это linear tranform. Третий слой -softmax activation чтобы получить результат Как вероятности.

Backpropagation вычисляет производную на каждом шаге и называете это градиент.

предыдущие слои добавляет global или previous градиент к 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)

производная объясняется относительно when 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.gradient - это local gradient, который является вектором. Правильно ли это? Есть ли лучший способ написания этого?

3 ответов


Я предполагаю, что у вас есть 3-слойный NN с W1, b1 for связано с линейным преобразованием из входного слоя в скрытый слой и W2, b2 связан с линейным преобразованием из скрытого слоя в выходной слой. Z1 и Z2 - это входной вектор для скрытого слоя и выходного слоя. a1 и a2 представляет выход скрытого слоя и выходного слоя. a2 ваш прогнозируемый выход. delta3 и delta2 несколько ошибок (backpropagated), и вы можете увидеть градиенты функции потерь относительно параметров модели.

enter image description here enter image description here

это общий сценарий для 3-слойного NN (входной слой, только один скрытый слой и один выходной слой). Вы можете выполнить описанную выше процедуру для вычисления градиентов, которые должны быть легко вычислены! С другой ответ на этот пост уже указал на проблему в коде, я не повторяюсь тот же.


как я уже сказал, У вас есть n^2 частные производные.

если вы делаете математику, вы увидите, что dSM[i]/dx[k] is 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.diag(self.value) - np.dot(SM, SM.T)

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 в этом notebook(https://github.com/rickiepark/ml-learn/blob/master/notebooks/5.%20multi-layer%20perceptron.ipynb)