У меня есть слой softmax (только сама активация, без линейной части умножения входных данных на весовые коэффициенты), и я хочу сделать для него обратный проход.
Я нашел много уроков / ответов поТАК, что имеет дело с этим, но все они, кажется, использовали X
как (1, n_inputs)
вектор. Я хочу использовать его как массив (n_samples, n_inputs)
, и все же иметь правильную векторизованную реализацию прямого / обратного прохода.
Я написал следующий прямой проход, нормализуя выходные данные для каждой строки / образца (это правильно?):
import numpy as np
X = np.asarray([
[0.0, 0.0],
[0.0, 1.0],
[1.0, 0.0],
[1.0, 1.0]], dtype=np.float32)
def prop(self, X):
s = np.exp(X)
s = s.T / np.sum(s, axis=1)
return s.T
Это дает мне окончательный результат прямого распространения (включая другие слои) как:
Y = np.asarray([
[0.5 , 0.5 ],
[0.87070241, 0.12929759],
[0.97738616, 0.02261384],
[0.99200957, 0.00799043]], dtype=np.float32))
Итак, это вывод softmax, есливерно. Теперь, как мне написать обратный проход?
Я получил производную от softmax:
1) если i=j
: p_i*(1 - p_j)
,
2) если i!=j
: -p_i*p_j
,
, где
Я пытался вычислить производную как:
ds = np.diag(Y.flatten()) - np.outer(Y, Y)
Но это приводит к матрице 8x8, которая не имеет смысла для следующего обратного распространения ... Как правильно написать это?