Esta nota explica los tres conceptos que sostienen lic-lab, mi banco de pruebas de compresión de imágenes aprendida (learned image compression): cómo las convoluciones aprenden a comprimir, qué son las aproximaciones de bajo rango, y por qué "lossy" y "lossless" no son dos técnicas rivales sino dos capas de un mismo pipeline.
Convoluciones como codificador y decodificador
En un códec aprendido, dos redes convolucionales hacen el trabajo que en JPEG hace la
transformada DCT: la transformada de análisis (gₐ) convierte la imagen en una
representación latente más compacta, y la transformada de síntesis (g_s) la
reconstruye de vuelta a píxeles.
gₐ: (B, 3, H, W) → (B, M, H/16, W/16) # imagen → latente y
g_s: (B, M, h, w) → (B, 3, H, W) # latente ŷ → imagen reconstruida
gₐ apila varias convoluciones con stride 2, reduciendo la resolución espacial en cada
capa (H/16 tras 4 etapas) mientras aumenta el número de canales — igual que una CNN de
clasificación, pero sin capas totalmente conectadas al final: la salida sigue siendo un
mapa espacial, solo que mucho más chico y con muchos más canales (M = 192 o 320 en los
modelos que replico). En vez de ReLU, estas capas usan GDN (Generalized Divisive
Normalization) — una no linealidad diseñada específicamente para imágenes naturales,
que normaliza cada canal dividiendo por una combinación aprendida de la energía de los
canales vecinos, y que empíricamente da mejores curvas rate-distortion que ReLU/GDN en
este dominio.
Los modelos más recientes (gmm_attn, tcm) añaden bloques residuales y, en el caso de
tcm, una rama con atención en ventanas (estilo Swin) en paralelo a la rama
convolucional — la misma idea de Transformers aplicada
aquí a nivel de parche de imagen, no de token de texto.
Aproximaciones de bajo rango
Una imagen (o un parche, o los pesos de una capa) es una matriz X. La idea del bajo
rango es que gran parte de esa matriz es información redundante, y se puede aproximar
con el producto de dos matrices mucho más chicas:
X (n×n) ≈ U (n×r) · Vᵀ (r×n) donde r ≪ n
En vez de guardar n² números, se guardan 2·n·r — y cuanto menor el rango r, mayor
la compresión (y mayor la pérdida de detalle).
X (parche 8×8) se factoriza en U (8×2) por V (2×8) — rango 2. Su producto (derecha, pulsando) es una aproximación de X, no una copia exacta: guarda 32 números en vez de 64, a cambio de perder algo de detalle.
lic-lab implementa tres variantes de esta idea:
- SVD truncada — la descomposición clásica en valores singulares, quedándose solo
con los
rcomponentes de mayor energía. Es el baseline de referencia contra el que se comparan las demás. - QMF (Quantization-aware Matrix Factorization) — en vez de factores continuos,
restringe
UyVa enteros acotados (int8, rango[-128, 127]), optimizados con BCD (block coordinate descent: se fija una matriz, se resuelve la otra en forma cerrada, y se alterna) inicializado con la SVD truncada. Al ser enteros desde el diseño, los factores se codifican directamente como imágenes de 8 bits sin pérdida adicional — es una técnica pensada para producir un bitstream real, no solo para aproximar. - LLoRMA (bajo rango local) — en vez de una única SVD global sobre toda la imagen, agrupa regiones similares con k-means y les aplica SVD por separado a cada clúster. La idea es que distintas zonas de una imagen (cielo liso vs. textura de una hoja) tienen estructuras de rango muy distintas, y forzarlas a compartir un único rango global desperdicia capacidad.
En lic-lab estos operadores no compiten solo contra JPEG: también se aplican sobre
el latente y de un modelo hyperprior (en vez de, o además de, la cuantización
escalar habitual), y sobre los pesos de gₐ/g_s para comprimir el modelo mismo,
no la imagen.
Compresión con pérdida (lossy) vs. sin pérdida (lossless)
Es fácil pensar que "lossy" y "lossless" son dos categorías de formato (JPEG vs. PNG), pero en un códec aprendido moderno conviven en el mismo pipeline, en dos pasos distintos:
- La pérdida ocurre en la cuantización. El latente
yque producegₐes continuo (números reales). Para poder transmitirlo hace falta discretizarlo aŷ— ahí, y solo ahí, se pierde información irrecuperablemente.lic-labprueba tres estrategias de cuantización en entrenamiento (ruido uniforme aditivo, straight-through estimator, redondeoround(y−μ)+μ), porque el redondeo no es diferenciable y hay que aproximarlo de alguna forma para poder entrenar con descenso de gradiente. - La codificación de ese resultado ya discreto es sin pérdida. Una vez que
ŷson enteros, convertirlos a bytes es un problema de codificación entrópica — y ahí no se pierde nada más: un codificador rANS (o aritmético) usa las probabilidades que predice el modelo de entropía (factorizado, gaussiano condicional, o una mezcla de gaussianas) para asignar menos bits a los valores más probables.decompress( compress(x))tiene que ser bit-exacto — ese es el invariante que se testea en cada módulo de entropía nuevo antes de aceptarlo en el repo.
En otras palabras: toda la pérdida de un códec aprendido vive en un único punto (la cuantización), y todo lo que pasa después — incluida la factorización de bajo rango de QMF, cuyos factores enteros también se codifican sin pérdida adicional — es compresión sin pérdida sobre una representación que ya es, deliberadamente, una versión con pérdida de la imagen original.
Esto es lo mismo que hace JPEG clásico, solo que con una transformada aprendida en vez de la DCT fija: DCT → cuantización (con pérdida, ahí está el parámetro de calidad) → Huffman (sin pérdida). La diferencia de fondo es que en un códec aprendido tanto la transformada como el modelo de probabilidad que alimenta al codificador entrópico se entrenan de punta a punta para minimizar la distorsión a una tasa de bits dada — en vez de estar fijados de antemano por un estándar.
Cómo se mide si vale la pena la pérdida
lic-lab reporta cada modelo como un punto en una curva rate-distortion (RD): bits
por píxel (bpp) en el eje x, PSNR o MS-SSIM en el eje y. Un modelo es mejor que otro si,
a la misma tasa de bits, reconstruye con menos distorsión — y esa curva se compara
siempre primero contra JPEG, JPEG2000, WebP, BPG y SVD truncada como baselines clásicos,
sobre el dataset Kodak (el mismo que usan los papers originales), para que la
comparación sea real y no un número aislado.
Ver también: overview del proyecto lic-lab, fundamentos de CNN y fundamentos de Transformers.