Векторизованный градиент softmax - PullRequest
1 голос
/ 11 декабря 2019

У меня есть слой 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,

, где equation

Я пытался вычислить производную как:

ds = np.diag(Y.flatten()) - np.outer(Y, Y) 

Но это приводит к матрице 8x8, которая не имеет смысла для следующего обратного распространения ... Как правильно написать это?

1 Ответ

0 голосов
/ 12 декабря 2019

Я нашел этот вопрос весьма полезным, когда писал свою функцию softmax: Производная Softmax в NumPy приближается к 0 (реализация) . Надеюсь, это поможет.

...