Funciones de activación y no linealidad

Funciones de activación y no linealidad

30 min de lectura

La lección anterior, sobre la neurona artificial, dejó una pieza sin elegir. Los pesos y el sesgo son la neurona —fijan el hiperplano, y con él todo lo que puede llegar a distinguir—, pero entre la preactivación zz y lo que la neurona entrega hay una función más, φ\varphi, que todavía no se ha elegido: la ocupa por defecto el escalón, con la etiqueta de provisional encima. Elegirla es el asunto de esta lección, y no es un remate cosmético. De φ\varphi dependen dos cosas: cuánto sobrevive del número que la neurona acaba de calcular, y qué se consigue al poner una neurona detrás de otra.

Mira lo que hace el escalón con un peso que se mueve. Toma una neurona cualquiera y sube uno solo de sus pesos de 1.01.0 a 1.11.1, a 1.21.2, a 1.31.3. La preactivación acompaña el movimiento: crece un poco cada vez, y todos los valores intermedios existen. La salida no se entera. Se queda en 00 mientras zz sea negativa, y en el instante en que cruza el cero salta a 11 y ahí se queda. Todo lo que había que saber sobre cuánto ha subido el peso se pierde por el camino, y siempre en el mismo sitio.

Antes de escribir una sola candidata conviene mirarlas juntas. El explorable dibuja cada una en [5,5][-5, 5], superpone su derivada como línea discontinua y sombrea en rojo los tramos donde esa derivada casi se anula.

Compara en cada función la curva continua con la discontinua, que es su derivada, y fíjate en el ancho de las bandas rojas: la de ReLU ocupa media gráfica. Mira también las cifras del eje vertical, porque cambian con cada función: la derivada de tanh llega a 1 donde la de la sigmoide se queda en 0.25. El último botón es el escalón de la lección anterior, y ahí el rojo lo cubre todo.

El botón «derivada f′» dibuja esa curva discontinua. Las cuatro primeras curvas continuas se parecen entre sí —suben, y más deprisa cerca del cero—, pero sus discontinuas no se parecen en nada: es la derivada, y no la función, la que separa a unas candidatas de otras. Y al final está el escalón, que enseña de golpe lo que le falta: su discontinua es una recta pegada al cero y el rojo cubre la gráfica entera.

Por qué la activación no puede ser una recta

Empecemos por la exigencia que no depende de ningún caso. Pon dos neuronas en cadena: la primera mira la entrada xRd\mathbf{x} \in \mathbb{R}^{d} y entrega un número, y la segunda mira ese número y entrega otro. Hay una neurona en cada nivel, así que los pesos del primero son un vector y los del segundo un escalar; el superíndice entre paréntesis dice el nivel, la misma marca que llevarán las capas cuando haya varias neuronas en cada una:

a(1)=φ((w(1))x+b(1)),a(2)=φ(w(2)a(1)+b(2)),a^{(1)} = \varphi\left(\left(\mathbf{w}^{(1)}\right)^{\top}\mathbf{x} + b^{(1)}\right), \qquad a^{(2)} = \varphi\left(w^{(2)} a^{(1)} + b^{(2)}\right),

con w(1)Rd\mathbf{w}^{(1)} \in \mathbb{R}^{d} y b(1),w(2),b(2)Rb^{(1)}, w^{(2)}, b^{(2)} \in \mathbb{R}. Ahora pon la identidad en las dos activaciones, φ(z)=z\varphi(z) = z, y sustituye la primera expresión dentro de la segunda:

a(2)=w(2)((w(1))x+b(1))+b(2)=(w(2)w(1))x+(w(2)b(1)+b(2)).a^{(2)} = w^{(2)}\left(\left(\mathbf{w}^{(1)}\right)^{\top}\mathbf{x} + b^{(1)}\right) + b^{(2)} = \left(w^{(2)}\mathbf{w}^{(1)}\right)^{\top}\mathbf{x} + \left(w^{(2)}b^{(1)} + b^{(2)}\right).

El lado derecho es una neurona. Una sola, con vector de pesos w(2)w(1)w^{(2)}\mathbf{w}^{(1)} y sesgo w(2)b(1)+b(2)w^{(2)}b^{(1)} + b^{(2)}, y no hay entrada que la distinga de la cadena que la produjo: para toda x\mathbf{x} dan el mismo número. La lección anterior ya dijo qué significa eso: todo lo que una neurona distingue está en su frontera, y esa frontera es un hiperplano. La cadena de dos separa con un hiperplano también. Apilar no ha curvado la frontera.

Y la identidad no tenía nada de especial. Asigna a φ\varphi la recta general, φ(z)=αz+β\varphi(z) = \alpha z + \beta con α0\alpha \neq 0, y verás que α\alpha se absorbe en los pesos del nivel siguiente y β\beta en su sesgo: lo que sale vuelve a ser una preactivación. Cualquier recta hace lo mismo.

Conviene decirlo con el nombre exacto. La expresión wx+b\mathbf{w}^{\top}\mathbf{x} + b no es lineal en el sentido del álgebra —una aplicación lineal manda el cero al cero, y esta lo manda a bb—: es afín. Componer funciones afines vuelve a dar una función afín, y eso se encadena sin límite: cien neuronas seguidas con una recta en φ\varphi son una neurona. La propiedad que hay que romper —y hay que romperla en la activación, no en otro sitio— es la que da título a esta lección: no linealidad, aunque lo que se rompe con precisión sea la afinidad.

La misma cuenta con varias neuronas en cada nivel

Nada de lo anterior depende de que hubiera una neurona sola por nivel. Con varias, los pesos de cada nivel se agrupan en una matriz y los sesgos en un vector, y la cadena queda

W(2)(W(1)x+b(1))+b(2)=(W(2)W(1))x+(W(2)b(1)+b(2)),\mathbf{W}^{(2)}\left(\mathbf{W}^{(1)}\mathbf{x} + \mathbf{b}^{(1)}\right) + \mathbf{b}^{(2)} = \left(\mathbf{W}^{(2)}\mathbf{W}^{(1)}\right)\mathbf{x} + \left(\mathbf{W}^{(2)}\mathbf{b}^{(1)} + \mathbf{b}^{(2)}\right),

que vuelve a ser un solo nivel. La forma matricial completa, con sus tamaños, es una lección más adelante, la del forward pass; aquí sirve para una cosa: el colapso no era un artefacto de haber puesto una neurona en cada nivel.

La segunda exigencia se ve mejor por lo que le pasa al escalón. Su derivada vale cero en todos los puntos donde existe,

ddzescaloˊn(z)=0para todo z0,\frac{d}{dz}\,\text{escalón}(z) = 0 \quad \text{para todo } z \neq 0,

y en z=0z = 0 ni siquiera existe, porque ahí la función salta. Hay una deuda que digo en voz alta: cómo consigue una neurona sus propios pesos a partir de ejemplos es una lección más adelante, la del descenso de gradiente. Lo único que hace falta adelantar es de qué está hecho ese método: de derivadas de φ\varphi. Una activación cuya derivada es cero en todas partes no dice nada sobre en qué dirección mover los pesos, y el procedimiento se queda quieto. El escalón supera la primera exigencia —no es una recta, ni de lejos— y suspende la segunda.

Tres candidatas y su derivada

Las tres que siguen cumplen las dos exigencias, y las escribo con su derivada ya calculada: el resto del bloque vivirá de esas derivadas más que de las funciones.

La sigmoide ya tiene símbolo reservado en el curso, σ\sigma:

σ(z)=11+ez,\sigma(z) = \frac{1}{1 + e^{-z}},

continua, creciente, con valores en (0,1)(0, 1): manda z=0z = 0 a σ(0)=1/2\sigma(0) = 1/2 y aplasta los extremos contra 00 y contra 11 sin llegar a tocarlos. Derivémosla. Escrita como σ(z)=(1+ez)1\sigma(z) = \left(1 + e^{-z}\right)^{-1}, la regla de la cadena y un reparto de la fracción dan

dσdz=(1+ez)2(ez)=ez(1+ez)2=11+ezez1+ez=σ(z)(1σ(z)),\begin{aligned} \frac{d\sigma}{dz} &= -\left(1 + e^{-z}\right)^{-2} \cdot \left(-e^{-z}\right) = \frac{e^{-z}}{\left(1 + e^{-z}\right)^{2}} \\[2pt] &= \frac{1}{1 + e^{-z}} \cdot \frac{e^{-z}}{1 + e^{-z}} = \sigma(z)\left(1 - \sigma(z)\right), \end{aligned}

donde el último paso sale de que ez1+ez=1+ez11+ez=1σ(z)\dfrac{e^{-z}}{1 + e^{-z}} = \dfrac{1 + e^{-z} - 1}{1 + e^{-z}} = 1 - \sigma(z). La derivada de la sigmoide se calcula con su propio valor, sin volver a exponenciar nada, y eso la hará barata cuando haya que evaluarla miles de veces.

La tangente hiperbólica tiene la misma silueta y otro recorrido. Es tanh(z)=(ezez)/(ez+ez)\tanh(z) = \left(e^{z} - e^{-z}\right) / \left(e^{z} + e^{-z}\right), toma valores en (1,1)(-1, 1) y cumple tanh(0)=0\tanh(0) = 0: está centrada en el cero, que es la diferencia que importa frente a la sigmoide, cuya salida es siempre positiva. Su derivada tiene una forma igual de cómoda,

dtanhdz=1tanh2(z),\frac{d\tanh}{dz} = 1 - \tanh^{2}(z),

y en el origen vale 11, cuatro veces lo que alcanza la sigmoide en su punto más alto.

De dónde sale 1 − tanh², y el parecido entre las dos curvas

Para la derivada, llamemos u=ezezu = e^{z} - e^{-z} y v=ez+ezv = e^{z} + e^{-z}: cada una es la derivada de la otra, dudz=v\frac{du}{dz} = v y dvdz=u\frac{dv}{dz} = u. La regla del cociente da entonces

dtanhdz=vvuuv2=1(uv)2=1tanh2(z).\frac{d\tanh}{dz} = \frac{v \cdot v - u \cdot u}{v^{2}} = 1 - \left(\frac{u}{v}\right)^{2} = 1 - \tanh^{2}(z).

El parecido entre las dos curvas tampoco es casualidad: la tangente hiperbólica es una sigmoide estirada al doble y desplazada, tanh(z)=2σ(2z)1\tanh(z) = 2\sigma(2z) - 1. Desarrolla el lado derecho y multiplica arriba y abajo por eze^{z},

2σ(2z)1=21+e2z1=1e2z1+e2z=ezezez+ez=tanh(z),2\sigma(2z) - 1 = \frac{2}{1 + e^{-2z}} - 1 = \frac{1 - e^{-2z}}{1 + e^{-2z}} = \frac{e^{z} - e^{-z}}{e^{z} + e^{-z}} = \tanh(z),

y de paso queda explicado el factor cuatro entre las dos derivadas: derivar 2σ(2z)12\sigma(2z) - 1 multiplica por 22 el factor de fuera y por otro 22 el de la regla de la cadena.

La tercera es la más joven y la que más se usa: ReLU, de rectified linear unit. Es ReLU(z)=max(0,z)\text{ReLU}(z) = \max(0, z) —deja pasar lo positivo tal cual y manda lo negativo a cero—, así que no aplasta nada por arriba: la magnitud de zz llega entera a la salida siempre que sea positiva. Su derivada es

ddzReLU(z)={1si z>00si z<0,\frac{d}{dz}\,\text{ReLU}(z) = \begin{cases} 1 & \text{si } z > 0 \\ 0 & \text{si } z < 0 \end{cases},

y en z=0z = 0 no existe: por la izquierda la pendiente vale 00 y por la derecha vale 11, y una función con un pico no tiene una sola tangente ahí. El curso toma 00 ahí: es una convención, no un teorema, y la elección no cambia nada medible.

Dónde se apaga cada una

Las tres derivadas comparten un problema y lo reparten distinto. Llamemos saturación a la región donde la derivada de φ\varphi está tan cerca de cero que la entrada puede moverse mucho y la salida apenas se mueve: son las bandas rojas del explorable.

Para la sigmoide la cuenta es directa. En z=5z = 5 vale σ(5)0.9933\sigma(5) \approx 0.9933, de modo que su derivada allí es 0.99330.00670.00660.9933 \cdot 0.0067 \approx 0.0066: casi cuarenta veces menos que en el origen. La tangente hiperbólica se apaga antes y más deprisa —1tanh2(5)1.8×1041 - \tanh^{2}(5) \approx 1.8 \times 10^{-4}, más de treinta veces por debajo de la sigmoide en el mismo punto—, y por eso sus bandas rojas empiezan más cerca del origen aunque su derivada arranque cuatro veces más alta: empezar más arriba y caer más deprisa son compatibles.

ReLU rompe ese reparto, y su banda roja de media gráfica no lo contradice. A la derecha su derivada vale 11 exactamente, tan lejos como quieras ir: ahí no satura, y ese es todo su atractivo. A la izquierda tampoco satura —saturar es acercarse a cero—: está apagada, con la derivada valiendo 00 en medio eje entero. De ahí sale un defecto con nombre propio, la ReLU muerta (dying ReLU): si la preactivación se queda negativa para todos los ejemplos que ve, la derivada vale cero en todos ellos, nada la mueve, y nunca sale de ahí.

Queda el cuarto botón. GELU, de Gaussian error linear unit, es la de los Transformers del bloque 5; su definición pide la función de distribución de una normal, y queda fuera de esta lección. Se parece a ReLU salvo cerca del origen, donde en vez de doblarse en un pico se curva.

Las activaciones y sus derivadas en NumPy

La celda escribe las cuatro funciones y las tres derivadas, y las somete a cuatro pruebas. Ejecútala y mira, en este orden: si las derivadas resisten una comprobación numérica, cuánto queda de cada una lejos del origen, qué le pasa a la cadena al cambiar la identidad por la sigmoide, y qué hace la sigmoide con las diez reseñas de la lección anterior.

import numpy as np

np.random.seed(0)

# --- Las cuatro candidatas, y la derivada de las tres que la tienen.
def escalon(z):
return (z >= 0).astype(float)


def sigmoide(z):
return 1.0 / (1.0 + np.exp(-z))


def d_sigmoide(z):
s = sigmoide(z)
return s * (1.0 - s)


def d_tanh(z):
t = np.tanh(z)
return 1.0 - t * t


def relu(z):
return np.maximum(z, 0.0)


def d_relu(z):
return (z > 0).astype(float)


# 1. ¿Están bien derivadas? Diferencia central contra la fórmula cerrada.
h = 1e-5
zs = np.array([-3.0, -0.5, 0.7, 2.5])
print("z =", zs, " forma", zs.shape)
for nombre, f, df in [("sigmoide", sigmoide, d_sigmoide),
("tanh", np.tanh, d_tanh),
("ReLU", relu, d_relu)]:
central = (f(zs + h) - f(zs - h)) / (2 * h)
print(" ", nombre.ljust(9), "max |formula - diferencia central| =",
"%.1e" % np.abs(df(zs) - central).max())
print()

# 2. Cuánto queda de cada derivada según nos alejamos del origen.
lejos = np.array([0.0, 2.0, 5.0, 10.0])
print(" z:", " ".join("%9.1f" % v for v in lejos))
print(" dσ/dz:", " ".join("%9.2e" % v for v in d_sigmoide(lejos)))
print(" dtanh/dz:", " ".join("%9.2e" % v for v in d_tanh(lejos)))
print(" dReLU/dz:", " ".join("%9.2e" % v for v in d_relu(lejos)))
print()

# 3. Dos neuronas en cadena. Toda función afín anula f(x+y) - f(x) - f(y) + f(0).
d = 8
w1 = np.random.randn(d)
b1 = 0.4
w2 = -1.3
b2 = 0.7


def identidad(z):
return z


def cadena(x, phi):
return w2 * phi(w1 @ x + b1) + b2


x = np.random.randn(d)
y = np.random.randn(d)
cero = np.zeros(d)
for nombre, phi in [("identidad", identidad), ("sigmoide ", sigmoide)]:
defecto = cadena(x + y, phi) - cadena(x, phi) - cadena(y, phi) + cadena(cero, phi)
print("φ =", nombre, " f(x+y) - f(x) - f(y) + f(0) =", "%+.2e" % defecto)

w_eq = w2 * w1
b_eq = w2 * b1 + b2
print("con la identidad, una sola neurona la reproduce:",
bool(np.isclose(cadena(x, identidad), w_eq @ x + b_eq)))
print()

# 4. Las diez preactivaciones de la neurona de reseñas de la lección anterior.
z_resenas = np.array([2.0, -2.0, 2.0, -2.0, 2.0, -1.0, -2.0, 1.0, 0.0, 2.0])
print(" z:", " ".join("%6.1f" % v for v in z_resenas))
print(" escalón:", " ".join("%6.0f" % v for v in escalon(z_resenas)))
print(" σ:", " ".join("%6.3f" % v for v in sigmoide(z_resenas)))
numpy

La primera ejecución descarga el intérprete de Python (~15 MB). Después queda en la caché del navegador.

La primera prueba da derecho a usar todo lo demás. La diferencia central (φ(z+h)φ(zh))/2h\left(\varphi(z+h) - \varphi(z-h)\right) / 2h con h=105h = 10^{-5} aproxima la derivada sin saber nada de la fórmula, y las tres coinciden hasta unos 101110^{-11}. Si derivas mal una activación, esto te lo dice en dos líneas.

La segunda tabla pone números a la saturación. La derivada de la sigmoide pasa de 2.50×1012.50 \times 10^{-1} en el origen a 4.54×1054.54 \times 10^{-5} en z=10z = 10, cuatro órdenes de magnitud; la de la tangente hiperbólica recorre ocho en el mismo tramo. La fila de ReLU no decae: 11 en las tres últimas columnas, tan lejos como se quiera ir. El 00 de la primera es la convención de arriba puesta en código.

La tercera prueba decide la cuestión sin entrenar nada. Toda función afín ff cumple la identidad

f(x+y)f(x)f(y)+f(0)=0,f(\mathbf{x} + \mathbf{y}) - f(\mathbf{x}) - f(\mathbf{y}) + f(\mathbf{0}) = 0,

sean cuales sean x\mathbf{x} e y\mathbf{y} —desarróllala y verás que los cuatro sesgos se cancelan—. Con la identidad en φ\varphi, la cadena de dos neuronas da 6.66×1016-6.66 \times 10^{-16}: cero, hasta donde llega la aritmética del ordenador. Con la sigmoide da 0.564-0.564. Es el mismo par de neuronas y las mismas entradas; lo único que ha cambiado es la activación.

La última tabla vuelve sobre la lección anterior: las diez preactivaciones de aquella neurona de reseñas, con sus pesos intactos, pasadas por el escalón y por la sigmoide. El escalón entrega la columna de siempre; la sigmoide separa lo que él juntaba. La reseña que caía justo encima de la frontera pasa de un 11 rotundo a 0.5000.500, y las cuatro negativas, que recibían todas el mismo 00, se reparten ahora en dos valores: 0.2690.269 la que estaba a 1-1, 0.1190.119 las tres que estaban a 2-2. La magnitud de zz ha vuelto, y sin tocar ni un peso.

Comprueba tu intuición

Cuatro preguntas —una derivada, el colapso de la cadena, dónde se apaga cada activación y una salida de NumPy— y un desafío con ReLU.

Para cierta entrada, una neurona con sigmoide da σ(z)=0.9\sigma(z) = 0.9. ¿Cuánto vale dσdz\dfrac{d\sigma}{dz} en ese mismo punto?

Se acepta un margen de ±0.001.

Encadenas dos neuronas: la primera calcula a(1)=(w(1))x+b(1)a^{(1)} = \left(\mathbf{w}^{(1)}\right)^{\top}\mathbf{x} + b^{(1)} y la segunda a(2)=w(2)a(1)+b(2)a^{(2)} = w^{(2)} a^{(1)} + b^{(2)}, con la identidad en las dos activaciones. ¿Qué función de x\mathbf{x} resulta?

Marca todo lo que sea cierto sobre las derivadas de las activaciones de esta lección.

Marca todas las opciones correctas. Se corrige todo o nada: no hay puntuación parcial.

Esta es la derivada de ReLU tal como la escribe la celda. ¿Qué imprime?

import numpy as np
 
z = np.array([-2., 0., 3.])
print((z > 0).astype(float))
 

Escribe las dos funciones con las que la celda maneja ReLU, sobre un array de NumPy de la forma que sea y sin bucles de Python:

  • relu(z) devuelve max(0,z)\max(0, z) coordenada a coordenada.
  • d_relu(z) devuelve su derivada: 11 donde z>0z > 0 y 00 en el resto, tomando 00 también en z=0z = 0.

Ninguna de las dos puede modificar el array que recibe.

La primera comprobación descarga el intérprete de Python (~15 MB); después queda en la caché del navegador. Este desafío se resuelve mejor con un teclado físico: en el móvil puedes leerlo y volver luego.


Queda algo por decir sobre lo que φ\varphi no ha cambiado, antes de que parezca que la sigmoide ha resuelto más de lo que resuelve. La frontera de decisión sigue exactamente donde estaba. Preguntar por dónde σ(z)\sigma(z) cruza 0.50.5 es preguntar por dónde zz cruza 00, porque σ\sigma es creciente y σ(0)=1/2\sigma(0) = 1/2: el hiperplano de la lección anterior sobrevive intacto a todas las sustituciones de esta. Lo que ha cambiado es lo que la neurona informa sobre su decisión, no cuál es.

Así que apilar neuronas ya puede construir algo que una sola no construye —sin la no linealidad ni siquiera podía—, pero nadie ha enseñado todavía un problema que obligue a apilarlas. Falta una pregunta anterior y más incómoda: ¿hay algo que una neurona, con la activación que sea, no pueda hacer nunca? Lo hay, cabe en cuatro puntos dibujados en una hoja, y es la siguiente lección, sobre XOR —el o exclusivo— y las capas ocultas.

Para profundizar2 fuentes · 1 paper, 1 libro

De dónde sale lo de esta lección, y dónde seguir si quieres más. Nada de aquí hace falta para continuar el curso.

  • Deep Learning, cap. 6: Deep Feedforward Networks
    libroGoodfellow, Bengio y Courville, 2016deeplearningbook.orgEN

    Su §6.3, «Hidden Units», ordena las tres activaciones —ReLU, sigmoide, tangente hiperbólica— y argumenta por qué ReLU es hoy la opción por defecto. Elige por lo que funciona, no por lo que se demuestra; la saturación la toca de pasada.

  • Gaussian Error Linear Units (GELUs)
    paperHendrycks y Gimpel, 2016arXiv:1606.08415EN

    Define la GELU que la lección nombra sin desarrollar: la entrada multiplicada por la función de distribución de una normal. La mide contra ReLU y ELU en visión, texto y voz; no dice nada de la saturación ni de la ReLU muerta.