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), и вы можете увидеть градиенты функции потерь относительно параметров модели.
это общий сценарий для 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)