Ir al contenido

Softmax (más de dos clases)

En simple: lee esto primero

Softmax = la versión de la logística para más de dos opciones: reparte el 100 % de probabilidad entre todas las clases.

Imagínalo así

Como una encuesta: cada candidato recibe un «puntaje de popularidad», y softmax los convierte en porcentajes que suman 100 %.

Lo que tienes que llevarte
  • Cada clase tiene su propio puntaje; el más alto se lleva la mayor probabilidad.
  • Con solo dos clases, softmax es exactamente la sigmoide.
Palabras raras de esta página
logit / score
el puntaje crudo de cada clase antes de convertirlo en probabilidad.
one-hot
escribir la clase correcta como [0, 1, 0]: un 1 en su lugar y 0 en el resto.

Más abajo viene la versión completa, con fórmulas. Si una palabra aparece subrayada con puntos, pasa el mouse (o tócala) para ver qué significa.

Para KK clases, cada una tiene sus propios pesos y score lineal zk=wk⊤x+bkz_k = \mathbf{w}_k^\top\mathbf{x}+b_k. La softmax los convierte en probabilidades positivas que suman 1:

pk=ezk∑j=1Kezj,∑kpk=1,y^=arg⁡max⁡kpkp_k = \frac{e^{z_k}}{\sum_{j=1}^K e^{z_j}},\qquad \sum_k p_k = 1,\qquad \hat y = \arg\max_k p_k

Cada frontera entre un par de clases sigue siendo una recta (donde zi=zjz_i = z_j): el plano queda partido en regiones convexas.

  • Pérdida: cross-entropy con la etiqueta en one-hot (yk=1y_k = 1 solo para la clase verdadera): ℓ=−∑kyklog⁡pk=−log⁡pverdadera\ell = -\sum_k y_k\log p_k = -\log p_{\text{verdadera}}.
  • Gradiente: ∂ℓ/∂zk=pk−yk\partial\ell/\partial z_k = p_k - y_k: otra vez la forma «residual» p−y\mathbf{p}-\mathbf{y}.

Softmax: un score por clase

Cada clase tiene su propio score lineal zk=wk⊤x+bkz_k=\mathbf{w}_k^\top\mathbf{x}+b_k. La softmax los exponencia y normaliza para que sumen 1. Cambia los logits y la temperatura.

claseprobabilidad p_kp_k∂ℓ/∂z_k = p−ygato
0.690-0.310perro
0.2540.254ave
0.0570.057
predicción arg maxgato
Σ p_k1.000
cross-entropy −log p_y0.372
pk=ezk/T∑jezj/Tℓ=−∑kyklog⁡pk=−log⁡pgato=0.372p_k=\frac{e^{z_k/T}}{\sum_j e^{z_j/T}}\qquad \ell = -\sum_k y_k\log p_k = -\log p_{\text{gato}} = 0.372
Suma la misma constante a los tres logits: las probabilidades no cambian (solo importan las diferencias). Con 2 clases, softmax se reduce exactamente a la sigmoide de z1−z0z_1-z_0. El gradiente vuelve a ser p − y, la misma forma «residual» de la regresión lineal y la logística.

Regiones de softmax: arrastra los vectores de pesos

Cada clase tiene su vector wₖ (la flecha). El score es zₖ = wₖᵀx: gana la clase cuya flecha apunta más «hacia» x. La intensidad del color es la confianza (max pₖ). Haz clic en el plano para consultar un punto.

-3-2-10123-3-2-10123x₁x₂w gatow perrow ave
gato
0.169
perro
0.722
ave
0.108
La frontera entre dos clases i, j es donde zᵢ = zⱼ, es decir (wᵢ − wⱼ)ᵀx = 0: una recta perpendicular a wᵢ − wⱼ. Por eso softmax (sin features extra) parte el plano en regiones convexas con bordes rectos. La temperatura no mueve las fronteras: solo cambia qué tan seguras son las probabilidades (T alto ⇒ más difusas).

Con dos clases: p1=ez1ez0+ez1=11+e−(z1−z0)=σ(z1−z0)p_1 = \frac{e^{z_1}}{e^{z_0}+e^{z_1}} = \frac{1}{1+e^{-(z_1-z_0)}} = \sigma(z_1-z_0). Solo importa la diferencia de scores (sumar una constante a todos no cambia nada), así que la logística binaria con z=z1−z0z = z_1 - z_0 es el caso particular. Un score por clase, softmax, cross-entropy: todo se traslada.

Logits z=(2, 1, 0)z = (2,\ 1,\ 0), clase verdadera = la primera. Calcula pp, la pérdida y el gradiente.

Ver solución

ez=(7.389, 2.718, 1)e^z = (7.389,\ 2.718,\ 1), suma =11.107= 11.107. p=(0.665, 0.245, 0.090)p = (0.665,\ 0.245,\ 0.090).

ℓ=−log⁡0.665=0.408\ell = -\log 0.665 = 0.408. Gradiente p−y=(−0.335, 0.245, 0.090)p-y = (-0.335,\ 0.245,\ 0.090): sube el logit correcto y baja los demás, en proporción a cuánta probabilidad les dio el modelo.

Autoevaluación

0/3 correctas · 0 respondidas
1. Sumar 5 a todos los logits…
2. Con K=2K=2, softmax equivale a…
3. El gradiente de la cross-entropy respecto al logit zkz_k es…
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.metrics import confusion_matrix
X, y = load_digits(return_X_y=True) # 1797 imágenes, 64 píxeles
X_tr, X_te, y_tr, y_te = train_test_split(X, y, stratify=y, random_state=0)
clf = make_pipeline(StandardScaler(), LogisticRegression(max_iter=2000)) # multinomial
clf.fit(X_tr, y_tr)
print(clf.score(X_te, y_te)) # ≈ 0.96
P = clf.predict_proba(X_te[:1]) # 10 probabilidades que suman 1
W = clf[-1].coef_.reshape(10, 8, 8) # cada fila = «plantilla» 8×8

Fuente ·ML_Course_Logistic_Regression_and_Classification.pdf (slide 37) · ML_Course/session-04d-softmax-multiclass.ipynb