Digamos que tenemos la expresión $z = x_1x_2 + \sin(x_1)$ y quiere encontrar derivados $\frac{dz}{dx_1}$ y $\frac{dz}{dx_2}$ . El modo inverso de AD divide esta tarea en 2 partes, a saber, pases hacia adelante y pases hacia atrás.
Pase hacia adelante
En primer lugar, descomponemos nuestra expresión compleja en un conjunto de expresiones primitivas, es decir, expresiones que constan como máximo de una sola llamada a una función. Observa que también cambio el nombre de las variables de entrada y salida por coherencia, aunque no es necesario:
$$w_1 = x_1$$ $$w_2 = x_2$$ $$w_3 = w_1w_2$$ $$w_4 = \sin(w_1)$$ $$w_5 = w_3 + w_4$$ $$z = w_5$$
La ventaja de esta representación es que ya se conocen las reglas de diferenciación de cada expresión por separado. Por ejemplo, sabemos que la derivada de $\sin$ es $\cos$ y así $\frac{dw_4}{dw_1} = \cos(w_1)$ . A continuación, utilizaremos este hecho en el paso inverso.
Esencialmente, el forward pass consiste en evaluar cada una de estas expresiones y guardar los resultados. Digamos que nuestras entradas son $x_1 = 2$ y $x_2 = 3$ . Entonces tenemos:
$$w_1 = x_1 = 2$$ $$w_2 = x_2 = 3$$ $$w_3 = w_1w_2 = 6$$ $$w_4 = \sin(w_1) ~= 0.9$$ $$w_5 = w_3 + w_4 = 6.9$$ $$z = w_5 = 6.9$$
Pase de reversa
Aquí es donde empieza la magia, y comienza con la regla de la cadena . En su forma básica, la regla de la cadena establece que si se tiene una variable $t(u(v))$ que depende de $u$ que, a su vez, depende de $v$ Entonces:
$$\frac{dt}{dv} = \frac{dt}{du}\frac{du}{dv}$$
o, si $t$ depende de $v$ a través de varias vías / variables $u_i$ Por ejemplo:
$$u_1 = f(v)$$ $$u_2 = g(v)$$ $$t = h(u_1, u_2)$$
entonces (ver prueba ici ):
$$\frac{dt}{dv} = \sum_i \frac{dt}{du_i}\frac{du_i}{dv}$$
En términos de gráfico de expresión, si tenemos un nodo final $z$ y los nodos de entrada $w_i$ y el camino desde $z$ a $w_i$ pasa por nodos intermedios $w_p$ (es decir $z = g(w_p)$ donde $w_p = f(w_i)$ ), podemos encontrar la derivada $\frac{dz}{dw_i}$ como
$$\frac{dz}{dw_i} = \sum_{p \in parents(i)} \frac{dz}{dw_p} \frac{dw_p}{dw_i}$$
En otras palabras, para calcular la derivada de la variable de salida $z$ con respecto a cualquier variable intermedia o de entrada $w_i$ sólo necesitamos conocer las derivadas de sus padres y la fórmula para calcular la derivada de la expresión primitiva $w_p = f(w_i)$ .
El pase inverso comienza al final (es decir $\frac{dz}{dz}$ ) y se propaga hacia atrás a todas las dependencias. Aquí tenemos (expresión para "semilla"):
$$\frac{dz}{dz} = 1$$
Esto puede leerse como "cambio en $z$ da como resultado exactamente el mismo cambio en $z$ ", lo cual es bastante obvio.
Entonces sabemos que $z = w_5$ y así:
$$\frac{dz}{dw_5} = 1$$
$w_5$ depende linealmente de $w_3$ y $w_4$ Así que $\frac{dw_5}{dw_3} = 1$ y $\frac{dw_5}{dw_4} = 1$ . Usando la regla de la cadena encontramos:
$$\frac{dz}{dw_3} = \frac{dz}{dw_5} \frac{dw_5}{dw_3} = 1 \times 1 = 1$$ $$\frac{dz}{dw_4} = \frac{dz}{dw_5} \frac{dw_5}{dw_4} = 1 \times 1 = 1$$
De la definición $w_3 = w_1w_2$ y las reglas de las derivadas parciales, encontramos que $\frac{dw_3}{dw_2} = w_1$ . Así:
$$\frac{dz}{dw_2} = \frac{dz}{dw_3} \frac{dw_3}{dw_2} = 1 \times w_1 = w_1$$
Lo cual, como ya sabemos por el pase de avance, es:
$$\frac{dz}{dw_2} = w_1 = 2$$
Finalmente, $w_1$ contribuye a $z$ a través de $w_3$ y $w_4$ . Una vez más, por las reglas de las derivadas parciales sabemos que $\frac{dw_3}{dw_1} = w_2$ y $\frac{dw_4}{dw_1} = \cos(w_1)$ . Así:
$$\frac{dz}{dw_1} = \frac{dz}{dw_3} \frac{dw_3}{dw_1} + \frac{dz}{dw_4} \frac{dw_4}{dw_1} = w_2 + \cos(w_1)$$
Y, de nuevo, dadas las entradas conocidas, podemos calcularlo:
$$\frac{dz}{dw_1} = w_2 + \cos(w_1) = 3 + \cos(2) ~= 2.58$$
Desde $w_1$ y $w_2$ no son más que alias para $x_1$ y $x_2$ obtenemos nuestra respuesta:
$$\frac{dz}{dx_1} = 2.58$$ $$\frac{dz}{dx_2} = 2$$
¡Y ya está!
Esta descripción se refiere únicamente a entradas escalares, es decir, números, pero en realidad también puede aplicarse a matrices multidimensionales como vectores y matrices. Hay dos cosas que hay que tener en cuenta a la hora de diferenciar expresiones con este tipo de objetos:
- Las derivadas pueden tener una dimensionalidad mucho mayor que las entradas o salidas, por ejemplo, la derivada de un vector con respecto a un vector es una matriz y la derivada de una matriz con respecto a una matriz es una matriz de 4 dimensiones (a veces denominada tensor). En muchos casos, estas derivadas son muy dispersas.
- Cada componente de la matriz de salida es una función independiente de 1 o más componentes de la(s) matriz(s) de entrada. Por ejemplo, si $y = f(x)$ y ambos $x$ y $y$ son vectores, $y_i$ nunca depende de $y_j$ pero sólo en un subconjunto de $x_k$ . En particular, esto significa que encontrar la derivada $\frac{dy_i}{dx_j}$ se reduce a seguir cómo $y_i$ depende de $x_j$ .
El poder de la diferenciación automática es que puede tratar con estructuras complicadas de los lenguajes de programación como las condiciones y los bucles. Sin embargo, si todo lo que necesitas son expresiones algebraicas y tienes un marco de trabajo lo suficientemente bueno para trabajar con representaciones simbólicas, es posible construir expresiones totalmente simbólicas. De hecho, en este ejemplo podríamos producir la expresión $\frac{dz}{dw_1} = w_2 + \cos(w_1) = x_2 + \cos(x_1)$ y calcular esta derivada para las entradas que queramos.