Visualización de la divergencia KL — cuánto difieren dos distribuciones
Ajusta los parámetros de dos distribuciones gaussianas, calcula y compara KL(P||Q) y KL(Q||P), y siente intuitivamente la asimetría de la divergencia KL.
Después de completar este caso, entenderás:La divergencia KL no es una «distancia»: desde P hacia Q y desde Q hacia P, la pérdida de información es diferente.
Introducción desde la vida real
Usar un mapa de Pekín para encontrar el camino en Nueva York
Tienes dos mapas: el mapa real de Nueva York (P) y el mapa de Pekín (Q). Si usas el mapa de Pekín en Nueva York, necesitas gastar mucha energía adicional para «corregir» la información errónea del mapa; ese gasto adicional es KL(P||Q). A la inversa, si usas el mapa de Nueva York en Pekín, el gasto adicional es KL(Q||P). Estos dos gastos adicionales son evidentemente diferentes, porque la «forma de error» de los dos mapas es distinta.
Comprensión intuitiva
Escenario A: P~N(0,1), Q~N(2,1): medias diferentes pero misma forma, KL es casi simétrica.
Escenario B: P~N(0,1), Q~N(0,3): mismo centro pero varianzas diferentes. KL(P||Q) = 1.10 (de estrecha a ancha, fácil), KL(Q||P) = 1.55 (de ancha a estrecha, difícil). Claramente asimétrica: «cubrir una estrecha con una ancha» es mucho más fácil que «cubrir una ancha con una estrecha».
Definición matemática
\[ D_{KL}(P \parallel Q) = \sum_{x} P(x) \cdot \log\frac{P(x)}{Q(x)} \] \[ D_{KL}(P \parallel Q) = H(P, Q) - H(P) \]La entropía de P en sí misma es constante, por lo que minimizar la entropía cruzada = minimizar la divergencia KL.
Práctica con Python
Ejemplo
def gaussian_pdf(x, mu, sigma):
return (1 / (sigma * np.sqrt(2 * np.pi))) * \
np.exp(-(x - mu) ** 2 / (2 * sigma ** 2))
def kl_divergence(p, q, eps=1e-12):
p = np.clip(p, eps, None)
q = np.clip(q, eps, None)
return np.sum(p * np.log(p / q))
x = np.linspace(-10, 10, 2000)
dx = x[1] - x[0]
# Escenario A: medias diferentes
P_A = gaussian_pdf(x, mu=0, sigma=1) * dx
Q_A = gaussian_pdf(x, mu=2, sigma=1) * dx
# Escenario B: varianzas diferentes
P_B = gaussian_pdf(x, mu=0, sigma=1) * dx
Q_B = gaussian_pdf(x, mu=0, sigma=3) * dx
print("EJEMPLO Verificación de la asimetría de la divergencia KL:\n")
print("Escenario A: P~N(0,1) vs Q~N(2,1)")
print(f" KL(P||Q) = {kl_divergence(P_A, Q_A):.4f}")
print(f" KL(Q||P) = {kl_divergence(Q_A, P_A):.4f}")
print(f"\nEscenario B: P~N(0,1) vs Q~N(0,3)")
print(f" KL(P||Q) = {kl_divergence(P_B, Q_B):.4f} (estrecha->ancha, fácil)")
print(f" KL(Q||P) = {kl_divergence(Q_B, P_B):.4f} (ancha->estrecha, difícil)")
print(f"\nEJEMPLO Intuición: «cubrir una estrecha con una ancha» es fácil (KL pequeño), «cubrir una ancha con una estrecha» es difícil (KL grande)")
EJEMPLO KL 散度不对称性验证: 场景 A:P~N(0,1) vs Q~N(2,1) KL(P||Q) = 2.0000 KL(Q||P) = 1.9960 场景 B:P~N(0,1) vs Q~N(0,3) KL(P||Q) = 1.0990 (窄->宽,容易) KL(Q||P) = 1.5490 (宽->窄,困难) EJEMPLO 直觉:'用宽覆盖窄'容易(KL小),'用窄覆盖宽'困难(KL大)
Escenarios de aplicación en IA
| Escenario | Cómo usar la divergencia KL |
|---|---|
| VAE | Hacer que la distribución codificada se acerque a una normal estándar: pérdida = error de reconstrucción + KL(codificación||N(0,1)) |
| Destilación de conocimiento | Hacer que la distribución de predicción del modelo estudiante se acerque al modelo profesor: minimizar KL(profesor||estudiante) |
| PPO aprendizaje por refuerzo | Usar la divergencia KL para restringir la diferencia entre la política nueva y la anterior, evitando actualizaciones excesivamente grandes. |