← Todo el material
Curso Avanzado 23 de agosto de 2026

Generación de imágenes — Módulo 10: de CNN a Vision Transformer (ViT) — la atención llega a la visión

Durante décadas la visión fue territorio de las CNN. El Vision Transformer cambió las reglas: parte la imagen en parches, los trata como tokens y los pasa por un encoder Transformer. Vemos el patch embedding, por qué el ViT necesita más datos que una CNN, y por qué a la larga escala mejor.

☰ Índice del contenido

En el Módulo 9 la U-Net hacía casi todo con convoluciones, y le colgamos atención por un costado (el cross-attention) para meterle el texto. Eso deja una pregunta flotando: si la atención es tan poderosa —tan poderosa que reinventó todo el procesamiento de lenguaje—, ¿por qué la usamos solo como accesorio en visión? ¿Y si construyéramos un modelo de visión que sea puro Transformer, sin convoluciones? Esa idea, que sonaba herética en su momento, es el Vision Transformer. Y funciona tan bien que hoy está detrás de buena parte de los modelos de visión y multimodales que veremos en el próximo módulo.

La tesis del módulo

Un Transformer no sabe qué es una imagen — pero sabe procesar secuencias de tokens. El truco del ViT es tramposo de puro simple: parte la imagen en parches, hace de cuenta que cada parche es una “palabra”, y deja que el mismo encoder Transformer del lenguaje haga el resto. Sin convoluciones, sin sesgo espacial incorporado. Solo atención.

El problema: el Transformer no traga píxeles

El Transformer que viste en La arquitectura completa procesa secuencias de tokens —trozos de texto convertidos en vectores. Una imagen no es una secuencia: es una grilla 2D. Y no puedes tratar cada píxel como un token: una imagen de 224×224 tendría 50.176 tokens, y como la atención compara cada token con todos los demás, el costo crece al cuadrado — más de 2.500 millones de comparaciones. Inviable.

La solución del ViT es partir la imagen en parches (patches): bloques cuadrados, típicamente de 16×16 píxeles. Una imagen de 224×224 se divide así en 14×14 = 196 parches. Eso sí es una secuencia manejable, del largo de una frase.

Patch embedding: de parche a token

Cada parche de 16×16×3 son 768 números. El patch embedding (embebido de parches) es el paso que convierte ese bloque de píxeles en un vector-token que el Transformer pueda digerir: se aplana el parche y se pasa por una capa lineal que lo proyecta al tamaño de vector que usa el modelo (por ejemplo 768 dimensiones). En la práctica esto se implementa como una sola convolución con stride igual al tamaño del parche — elegante, pero conceptualmente es “una proyección por parche”.

Falta un detalle crítico. El Transformer, por diseño, no tiene noción de orden: para él la secuencia de parches es un montón sin posición. Igual que en el texto, hay que sumarle a cada parche un positional encoding (codificación de posición): un vector que le dice “tú eres el parche de la fila 3, columna 5”. Sin eso, el modelo no distinguiría una cara de la misma cara con los ojos abajo.

   imagen 224x224              parches 16x16
   ┌───────────────┐          ┌──┬──┬──┬──┐
   │               │          │P1│P2│P3│..│
   │               │  ───►    ├──┼──┼──┼──┤
   │               │          │..│..│..│..│   14x14 = 196
   └───────────────┘          └──┴──┴──┴──┘

   cada parche ──► patch embedding ──► + posición
        │                                   │
        ▼                                   ▼
   ┌──────────────────────────────────────────┐
   │   T1  T2  T3  T4 ... T196  (196 tokens)  │
   └──────────────────────────────────────────┘
                       │
                       ▼
           ┌───────────────────────┐
           │   encoder Transformer │  ── atención
           │   (self-attention)    │     entre todos
           └───────────────────────┘     los parches
                       │
                       ▼
                clase / features

Una vez que la imagen es una secuencia de tokens con posición, el resto es un encoder Transformer idéntico al del lenguaje: capas de self-attention donde cada parche “mira” a todos los demás para armar contexto global.

El código: la parte que importa

La patchificación es el único paso realmente nuevo; el encoder es el Transformer de siempre. Así se ve en PyTorch:

import torch
import torch.nn as nn

class PatchEmbedding(nn.Module):
    def __init__(self, img=224, parche=16, canales=3, dim=768):
        super().__init__()
        self.n_parches = (img // parche) ** 2      # 14*14 = 196
        # Un conv con stride=parche corta la imagen en parches
        # y proyecta cada uno a un vector de 'dim' de una sola pasada.
        self.proj = nn.Conv2d(canales, dim,
                              kernel_size=parche, stride=parche)
        # Un vector de posición aprendible por cada parche.
        self.pos = nn.Parameter(torch.randn(1, self.n_parches, dim))

    def forward(self, x):                 # x: (batch, 3, 224, 224)
        x = self.proj(x)                  # (batch, 768, 14, 14)
        x = x.flatten(2).transpose(1, 2)  # (batch, 196, 768) -> tokens
        return x + self.pos               # le sumamos la posición

# A partir de aquí, x entra a un nn.TransformerEncoder normal:
# exactamente el mismo bloque del curso de Transformers.

Lo importante no es el detalle de las dimensiones, sino la idea: con estas pocas líneas una imagen se volvió una secuencia de tokens, y a partir de ahí el Transformer no sabe ni le importa que vino de una foto.

CNN vs ViT: la diferencia de fondo

Acá está el corazón del módulo. La CNN trae de fábrica un sesgo inductivo (inductive bias): supuestos sobre el mundo horneados en su arquitectura. Concretamente, asume locality (localidad: lo importante está en la vecindad de cada píxel) y que un patrón vale igual en cualquier posición. Ese supuesto es correcto para imágenes, así que la CNN aprende rápido y con pocos datos: le viene “gratis” saber que los píxeles vecinos se relacionan.

El ViT no trae ese supuesto. Para él, en la primera capa, el parche de arriba a la izquierda y el de abajo a la derecha están igual de “cerca”. Tiene que aprender desde los datos que los parches vecinos suelen relacionarse. Eso lo hace hambriento: con pocos datos, la CNN le gana. Pero con muchísimos datos, el ViT supera a la CNN — porque sin ese sesgo rígido puede aprender relaciones que la convolución jamás vería, como conectar dos objetos en esquinas opuestas de la imagen. Y escala mejor: agregarle capas y datos lo mejora de forma más limpia.

CNNViT
Unidad básicaFiltro que recorre parchesParche tratado como token
Sesgo inductivoFuerte (locality “gratis”)Casi nulo, lo aprende todo
Datos necesariosPocos: aprende rápidoMuchísimos para brillar
AlcanceLocal, crece capa a capaGlobal desde la primera capa
EscalaBuena, pero se estancaExcelente: más datos, mejor
Cuándo ganaDatasets chicos/medianosDatasets enormes

Ojo: “el ViT es mejor que la CNN” es una media verdad peligrosa. Es mejor cuando tienes datos masivos y cómputo de sobra. Para un problema con mil imágenes, una CNN sigue siendo la elección sensata. La arquitectura correcta depende de tu escala, no de la moda.

Errores comunes

  • Creer que el ViT abandona toda estructura. No la abandona: la recupera vía el positional encoding y la aprende de los datos. Lo que abandona es tenerla incorporada gratis.
  • Pensar que más parches = mejor. Parches más chicos dan más tokens y más detalle, pero el costo crece al cuadrado. Es un balance, no un “más es mejor”.
  • Olvidar el positional encoding. Sin él, el ViT no distingue el orden de los parches: una cara desarmada le parecería igual de válida.
  • Usar un ViT con pocos datos. Sin dataset masivo o sin pre-entrenamiento, el ViT rinde por debajo de una CNN simple. El sesgo inductivo de la CNN existe por algo.
  • Confundir ViT con Stable Diffusion. Son cosas distintas: el ViT analiza imágenes (entiende); Stable Diffusion las genera. Se cruzan en lo multimodal, tema del próximo módulo.

La frase para llevarse

“La CNN nace sabiendo que los píxeles vecinos importan; el ViT nace en blanco y lo aprende de los datos. Por eso la CNN gana con poco y el ViT gana con mucho — no hay arquitectura superior, hay escala apropiada.”

Qué viene

Módulo 11: multimodal — cómo ven los LLM. El ViT de hoy es la pieza que faltaba. Vamos a usarlo como los “ojos” de un modelo de lenguaje: una imagen entra por un vision encoder (un ViT/CLIP), se proyecta al espacio de tokens del LLM, y de pronto el modelo del curso de Transformers puede ver. Ahí se cruzan los dos cursos.

Material relacionado

Generación de imágenesVision TransformerViTCNNAtención

Preguntas sobre este curso

Regístrate gratis para hacer preguntas y guardar tu progreso.

✉ Entérate de lo nuevo

Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.