Derivada de la Capa Softmax

Derivada de la función Softmax respecto a su entrada

Queremos calcular la derivada de la salida de la softmax con respecto a cada entrada
Para simplificar, vamos a llamar yy a la salida y xx a la entrada
y=Softmax(x) y = Softmax(x) \\
Entonces yy es un vector:
y=[ex1,...,exc]ex1+...+exc=[ex1,...,exc]Ny= \frac{[e^{x_1},...,e^{x_c}]}{e^{x_1}+...+e^{x_c}} = \frac{[e^{x_1},...,e^{x_c}]}{N}
Y cada elemento de yy se define como
yi(x)=exiex1+...+excy_i(x) = \frac{e^{x_i}}{e^{x_1}+...+e^{x_c}}
Cada entrada afecta a varias salidas, por la normalización (NN). Entonces la derivada de la salida yy respecto a una entrada entrada xjx_j es un vector:
dydxj=[dy1dxj,...,dyidxj,...,dycdxj]=[dex1Ndxj,...,dexiNdxj,...dexcNdxj]\frac{dy}{dx_j} = [\frac{dy_1}{dx_j},..., \frac{dy_i}{dx_j} , ..., \frac{dy_c}{dx_j}] = [\frac{d\frac{e^{x_1}}{N}}{dx_j}, ..., \frac{d\frac{e^{x_i}}{N}}{dx_j},... \frac{ d\frac{e^{x_c}}{N}}{dx_j} ]

Entonces, buscamos dyidxj\frac{dy_i}{dx_j}. Para eso tenemos que separar en dos casos:

En ambos casos usaremos la Regla del cociente para derivar, donde si f(x)=g(x)h(x)f(x) = \frac{g(x)}{h(x)}, entonces f(x)=g(x)h(x)g(x)h(x)h(x)²f'(x) = \frac{g'(x)h(x)-g(x)h'(x)}{h(x)²}.

En el 2do caso es más fácil porque el numerador es constante con respecto a xjx_j, entonces $f(x)=g(x)h(x)h(x)²f'(x) = g(x) \frac{-h'(x)}{h(x)²}. Empezamos con este caso más simple:

dyidxj=exjN2exi=exjNexiN=yiyjif ij \frac{dy_i}{dx_j} = \frac{-e^{x_j}}{N^2} e^{x_i} = \frac{-e^{x_j}}{N} \frac{e^{x_i} }{N} = -y_i y_j \qquad \text{if $i\ne j$}

En el caso i=ji=j, tenemos entonces:
dyidxj=exiNexiexjN2=exiNN2exiexjN2=exiNexiNexjN=yiyiyj=(1yj)yi=(1yi)yiif i=j\frac{dy_i}{dx_j} = \frac{ e^{x_i} N - e^{x_i} e^{x_j} }{N^2} =\frac{ e^{x_i} N}{N^2} - \frac{ e^{x_i} e^{x_j} }{N^2} \\ =\frac{ e^{x_i} }{N} - \frac{e^{x_i}}{N} \frac{e^{x_j} }{N} \\ = y_i - y_i y_j = (1-y_j) y_i = (1-y_i) y_i \qquad \text{if $i=j$}\\

Finalmente entonces

dyidxj={yiyjif ij(1yi)yiif i=j \frac{dy_i}{dx_j} = \begin{cases} -y_i y_j &\text{if } i \ne j \\ (1-y_i) y_i &\text{if } i=j \end{cases}

Derivada de la Softmax respecto a su entrada (formato matricial)

Dado que tenemos cc entradas y cc salidas, podemos escribir una matriz (la matriz Jacobiana) con las derivadas parciales de cada elemento de yy con respecto a cada elemento de xx
dydx=(dy1dx1dy1dx2...dy1dxcdy2dx1dy2dx2...dy2dxc............dycdx1dycdx2...dycdxc)=((1y1)y1y1y2...y1ycy2y1(1y2)y2...y2yc............ycy1ycy2...(1yc)yc)=((1y1)y1...y1y2(1y2)...y2............ycyc...(1yc))(y1y2...ycy1y2...yc............y1y2...yc)=(I(y1y1...y1y2y2...y2............ycyc...yc))(y1y2...ycy1y2...yc............y1y2...yc) \frac{dy}{dx} = \left(\begin{matrix} \frac{dy_1}{dx_1} & \frac{dy_1}{dx_2} & ... & \frac{dy_1}{dx_c}\\ \frac{dy_2}{dx_1} & \frac{dy_2}{dx_2} & ... & \frac{dy_2}{dx_c}\\ ... & ... & ... & ...\\ \frac{dy_c}{dx_1} & \frac{dy_c}{dx_2} & ... & \frac{dy_c}{dx_c}\\ \end{matrix}\right) \\ = \left(\begin{matrix} (1-y_1)y_1 & - y_1y_2 & ... & -y_1y_c\\ -y_2y_1 & - (1-y_2)y_2 & ... & -y_2y_c\\ ... & ... & ... & ...\\ -y_cy_1 & - y_cy_2 & ... & (1-y_c)y_c\\ \end{matrix}\right)\\ \footnotesize = \left(\begin{matrix} (1-y_1) & -y_1 & ... & -y_1\\ -y_2 & (1-y_2) & ... & -y_2\\ ... & ... & ... & ...\\ -y_c & - y_c & ... & (1-y_c)\\ \end{matrix}\right)* \left(\begin{matrix} y_1 & y_2 & ... & y_c\\ y_1 & y_2 & ... & y_c\\ ... & ... & ... & ...\\ y_1 & y_2 & ... & y_c\\ \end{matrix}\right)\\ =\tiny \left(I -\left(\begin{matrix} y_1 & y_1 & ... & y_1\\ y_2 & y_2 & ... & y_2\\ ... & ... & ... & ...\\ y_c & y_c & ... & y_c\\ \end{matrix}\right) \right)* \left(\begin{matrix} y_1 & y_2 & ... & y_c\\ y_1 & y_2 & ... & y_c\\ ... & ... & ... & ...\\ y_1 & y_2 & ... & y_c\\ \end{matrix}\right)

Si bien es posible calcular las derivadas en forma matricial, en general este enfoque puede utilizar mucha memoria. En lugar de eso, se puede calcular cada columna de esta matriz por separado, utilizando O(c)O(c) espacio en lugar de O(c²)O(c²), y de esa forma ir calculando la derivada de yy con respecto a cada xjx_j por separado.

Derivada del Error respecto de la entrada a la Softmax

En una Capa Softmax, para realizar backpropagation debemos poder calcular dEdx\frac{dE}{dx} es decir, las derivadas del error respecto de las entradas. Podemos hacerlo en base a dEdy\frac{dE}{dy}, las derivadas del error respecto de la salida, y la fórmula que derivamos para dydx\frac{dy}{dx}.

Podemos de nuevo enfocarnos en una entrada xjx_j. Como cada entrada afecta a varias salidas, vamos a tener que sumar todas las contribuciones de dy1xj\frac{dy_1}{x_j}, dy2xj\frac{dy_2}{x_j}, … dycxj\frac{dy_c}{x_j}.

Cada uno de estos términos indica la derivada de yiy_i respecto de xjx_j, pero no la derivada de EE respecto de xjx_j. Para eso, vamos a tener que usar la regla de la cadena:

dExj=dEdydyxj=i=1cdEdyidyixj \frac{dE}{x_j} = \frac{dE}{dy} \frac{dy}{x_j} = \sum_{i=1}^c \frac{dE}{dy_i} \frac{dy_i}{x_j}

En donde dEdyi\frac{dE}{dy_i} es simplemente el elemento i-ésimo del vector dEdy\frac{dE}{dy} que recibimos, y ya tenemos una fórmula para dyixj\frac{dy_i}{x_j}:

dyidxj={yiyjif ij(1yi)yiif i=j \frac{dy_i}{dx_j} = \begin{cases} -y_i y_j &\text{if } i \ne j \\ (1-y_i) y_i &\text{if } i=j \end{cases}

Notemos también que esta igualdad nos dice que podemos calcular el producto punto o matricial entre dEdy\frac{dE}{dy} y dyxj\frac{dy}{x_j} para obtener dEdxj\frac{dE}{dx_j}:

dEdydyxj=np.dot(dEdy,dyxj) \frac{dE}{dy} \frac{dy}{x_j} = np.dot(\frac{dE}{dy}, \frac{dy}{x_j})

Otros recursos

Podés consultar también otros recursos complementarios para entender la derivada. Cuidado porque algunos no solo tratan la derivada de la softmax respecto de su entrada, sino que tratan también la derivada de Softmax(wx+b)Softmax(wx+b) respecto de ww y bb, o la derivada de CrossEntropy(Softmax(x))CrossEntropy(Softmax(x)) respecto de xx, que son otros casos. Nosotros, en cambio, seguimos un enfoque modular aplicable al diseño de redes por capas.