Saltar al contenido

¿Cómo implementar la derivada Softmax independientemente de cualquier función de pérdida?

Presta atención ya que en esta reseña vas a encontrar el hallazgo que buscas.

Solución:

Debería ser así: (x es la entrada a la capa softmax y dy es el delta proveniente de la pérdida por encima de ella)

    dx = y * dy
    s = dx.sum(axis=dx.ndim - 1, keepdims=True)
    dx -= y * s

    return dx

Pero la forma de calcular el error debería ser:

    yact = activation.compute(x)
    ycost = cost.compute(yact)
    dsoftmax = activation.delta(x, cost.delta(yact, ycost, ytrue)) 

Explicación: porque el delta La función es parte del algoritmo de retropropagación, su responsabilidad es multiplicar el vector dy (en mi código, outgoing en su caso) por el jacobiano del compute(x) función evaluada en x. Si averigua cómo se ve este jacobiano para softmax [1]y luego multiplícalo desde la izquierda por un vector dydespués de un poco de álgebra, descubrirá que obtiene algo que corresponde a mi código de Python.

[1] https://stats.stackexchange.com/questions/79454/softmax-layer-in-a-neural-network

Matemáticamente, la derivada de Softmax σ(j) con respecto al logit Zi (por ejemplo, Wi*X) es

ingrese la descripción de la imagen aquí

donde el delta rojo es un delta de Kronecker.

Si implementa iterativamente:

def softmax_grad(s):
    # input s is softmax value of the original input x. Its shape is (1,n) 
    # i.e.  s = np.array([0.3,0.7]),  x = np.array([0,1])

    # make the matrix whose size is n^2.
    jacobian_m = np.diag(s)

    for i in range(len(jacobian_m)):
        for j in range(len(jacobian_m)):
            if i == j:
                jacobian_m[i][j] = s[i] * (1 - s[i])
            else: 
                jacobian_m[i][j] = -s[i] * s[j]
    return jacobian_m

Prueba:

In [95]: x
Out[95]: array([1, 2])

In [96]: softmax(x)
Out[96]: array([ 0.26894142,  0.73105858])

In [97]: softmax_grad(softmax(x))
Out[97]: 
array([[ 0.19661193, -0.19661193],
       [-0.19661193,  0.19661193]])

Si implementa en una versión vectorizada:

soft_max = softmax(x)    

# reshape softmax to 2d so np.dot gives matrix multiplication

def softmax_grad(softmax):
    s = softmax.reshape(-1,1)
    return np.diagflat(s) - np.dot(s, s.T)

softmax_grad(soft_max)

#array([[ 0.19661193, -0.19661193],
#       [-0.19661193,  0.19661193]])

Puedes añadir valor a nuestro contenido contribuyendo tu veteranía en las críticas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *