Funciones de activación y no linealidad
30 min read
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 y lo que la neurona entrega hay una función más, , 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 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 a , a , a . 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 mientras sea negativa, y en el instante en que cruza el cero salta a 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 , superpone su derivada como línea discontinua y sombrea en rojo los tramos donde esa derivada casi se anula.
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 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:
con y . Ahora pon la identidad en las dos activaciones, , y sustituye la primera expresión dentro de la segunda:
El lado derecho es una neurona. Una sola, con vector de pesos y sesgo , y no hay entrada que la distinga de la cadena que la produjo: para toda 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 la recta general, con , y verás que se absorbe en los pesos del nivel siguiente y 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 no es lineal en el sentido del álgebra —una aplicación lineal manda el cero al cero, y esta lo manda a —: 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 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
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,
y en 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 . 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, :
continua, creciente, con valores en : manda a y aplasta los extremos contra y contra sin llegar a tocarlos. Derivémosla. Escrita como , la regla de la cadena y un reparto de la fracción dan
donde el último paso sale de que . 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 , toma valores en y cumple : 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,
y en el origen vale , 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 y : cada una es la derivada de la otra, y . La regla del cociente da entonces
El parecido entre las dos curvas tampoco es casualidad: la tangente hiperbólica es una sigmoide estirada al doble y desplazada, . Desarrolla el lado derecho y multiplica arriba y abajo por ,
y de paso queda explicado el factor cuatro entre las dos derivadas: derivar multiplica por el factor de fuera y por otro 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 —deja pasar lo positivo tal cual y manda lo negativo a cero—, así que no aplasta nada por arriba: la magnitud de llega entera a la salida siempre que sea positiva. Su derivada es
y en no existe: por la izquierda la pendiente vale y por la derecha vale , y una función con un pico no tiene una sola tangente ahí. El curso toma 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 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 vale , de modo que su derivada allí es : casi cuarenta veces menos que en el origen. La tangente hiperbólica se apaga antes y más deprisa —, 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 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 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.
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)))
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 con aproxima la derivada sin saber nada de la fórmula, y las tres coinciden hasta unos . 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 en el origen a en , cuatro órdenes de magnitud; la de la tangente hiperbólica recorre ocho en el mismo tramo. La fila de ReLU no decae: en las tres últimas columnas, tan lejos como se quiera ir. El 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 cumple la identidad
sean cuales sean e —desarróllala y verás que los cuatro sesgos se cancelan—. Con la identidad en , la cadena de dos neuronas da : cero, hasta donde llega la aritmética del ordenador. Con la sigmoide da . 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 rotundo a , y las cuatro negativas, que recibían todas el mismo , se reparten ahora en dos valores: la que estaba a , las tres que estaban a . La magnitud de 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 . ¿Cuánto vale en ese mismo punto?
A margin of ±0.001 is accepted.
Encadenas dos neuronas: la primera calcula y la segunda , con la identidad en las dos activaciones. ¿Qué función de resulta?
Marca todo lo que sea cierto sobre las derivadas de las activaciones de esta lección.
Select every correct option. This is graded all-or-nothing: there is no partial credit.
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 coordenada a coordenada.d_relu(z)devuelve su derivada: donde y en el resto, tomando también en .
Ninguna de las dos puede modificar el array que recibe.
The first run downloads the Python interpreter (~15 MB); after that it stays in the browser cache. This challenge is much easier to solve on a physical keyboard: on a phone, read it and come back later.
Queda algo por decir sobre lo que 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 cruza es preguntar por dónde cruza , porque es creciente y : 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.
Further reading2 sources · 1 paper, 1 book
Where this lesson comes from, and where to go next. None of it is needed to carry on with the course.
- Deep Learning, cap. 6: Deep Feedforward Networks
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)
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.