Phase 07 - Lesson 09

Vision Transformers (ViT)

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Una imagen es una cuadrícula de parches. Una oración es una cuadrícula de tokens. El mismo transformer consume ambos.

Tipo: Build Lenguajes: Python Requisitos previos: Fase 7 · 05 (Transformer Completo), Fase 4 · 03 (CNNs), Fase 4 · 14 (Introducción a Vision Transformers) Tiempo: ~45 minutos

El Problema

Antes de 2020, la visión computacional significaba convoluciones. Cada SOTA en ImageNet, COCO y los benchmarks de detección utilizaba un backbone CNN. Los transformers eran para el lenguaje.

Dosovitskiy et al. (2020) — "An Image is Worth 16x16 Words" — demostraron que se pueden descartar las convoluciones por completo. Corta una imagen en parches de tamaño fijo, proyecta linealmente cada parche en un embedding y alimenta la secuencia a un encoder de transformer vanilla. A una escala suficiente (preentrenamiento en ImageNet-21k o superior), ViT iguala o supera a los modelos basados en ResNet.

ViT fue el inicio de un patrón más amplio en 2026: una arquitectura, múltiples modalidades. Whisper tokeniza audio. ViT tokeniza imágenes. Tokens de acción para robótica. Tokens de píxel para video. Al transformer no le importa — aliméntalo con una secuencia y aprenderá.

Para 2026, ViT y sus descendientes (DeiT, Swin, DINOv2, ViT-22B, SAM 3) dominan la mayor parte de la visión. Las CNN aún ganan en dispositivos de borde (edge) y tareas sensibles a la latencia. Todo lo demás tiene un ViT en alguna parte del stack.

El Concepto

Imagen → parches → tokens → transformer

Paso 1 — patchify (crear parches)

Divide una imagen de H × W × C en una secuencia N × (P·P·C) de parches aplanados. Configuración típica: imagen de 224 × 224, parches de 16 × 16 → 196 parches de 768 valores cada uno.

image (224, 224, 3) → 14 × 14 grid of 16x16x3 patches → 196 vectors of length 768

El tamaño del parche es la palanca. Parches más pequeños = más tokens, mejor resolución, costo de atención cuadrático. Parches más grandes = más gruesos, más económicos.

Paso 2 — linear embedding (embedding lineal)

Una única matriz aprendida proyecta cada parche aplanado a d_model. Equivalente a una convolución con un tamaño de kernel P y un stride P. En PyTorch, esto es literalmente nn.Conv2d(C, d_model, kernel_size=P, stride=P) — una implementación de 2 líneas.

Paso 3 — prepended del token [CLS], agregar embeddings posicionales

  • Agrega al principio (prepend) un token [CLS] aprendible. Su estado oculto final es la representación de la imagen utilizada para la clasificación.
  • Agrega embeddings posicionales aprendibles (ViT original) o sinusoidales 2D (variantes posteriores).
  • En 2024+ RoPE se extendió a 2D para la posición, a veces sin embeddings explícitos.

Paso 4 — encoder de transformer estándar

Apila L bloques de LayerNorm → Self-Attention → + → LayerNorm → MLP → +. Idéntico a BERT. Sin capas específicas de visión. Este es el punto clave pedagógico del artículo.

Paso 5 — cabeza (head)

Para clasificación: toma el estado oculto de [CLS] → lineal → softmax. Para DINOv2 o SAM, descarta [CLS] y usa los embeddings de parches directamente.

Variantes que importaron

Modelo Año Cambio
ViT 2020 El original. Tamaño de parche fijo, atención global completa.
DeiT 2021 Destilación; entrenable únicamente en ImageNet-1k.
Swin 2021 Jerárquico con ventanas desplazadas (shifted windows). Costo subcuadrático fijo.
DINOv2 2023 Autossupervisado (sin etiquetas). Mejores características (features) generales de visión.
ViT-22B 2023 22B de parámetros; se aplican las leyes de escala.
SigLIP 2023 ViT + par de lenguaje, pérdida contrastiva sigmoide.
SAM 3 2025 Segment anything; ViT-Large + decoder de máscara basado en prompts.

Por qué tomó un tiempo

ViT necesita muchos datos para igualar a las CNN porque no tiene ninguno de los sesgos inductivos de las CNN (invariancia de traslación, localidad). Sin más de 100M de imágenes etiquetadas o un fuerte preentrenamiento autossupervisado, las CNN siguen ganando con el mismo presupuesto de cómputo. DeiT solucionó esto en 2021 con trucos de destila-ción; DINOv2 lo solucionó de forma permanente en 2023 con autossupervisión.

Construye

Consulta code/main.py. Patchify puro con stdlib + linear embedding + controles de sanidad. Sin entrenamiento — ViT a cualquier escala realista necesita PyTorch y horas de GPU.

Paso 1: imagen falsa

Una imagen RGB de 24 × 24 como una lista de filas de tuplas (R, G, B). Usamos parches de 6×6 → 16 parches, con un vector de embedding de 108 dimensiones cada uno.

Paso 2: patchify

def patchify(image, P):
    H = len(image)
    W = len(image[0])
    patches = []
    for i in range(0, H, P):
        for j in range(0, W, P):
            patch = []
            for di in range(P):
                for dj in range(P):
                    patch.extend(image[i + di][j + dj])
            patches.append(patch)
    return patches

Orden raster: por filas (row-major) a lo largo de la cuadrícula. Todos los ViT utilizan este orden.

Paso 3: linear embed

Multiplica cada parche aplanado por una matriz aleatoria de (patch_flat_size, d_model). Verifica que la forma de salida sea (N_patches + 1, d_model) después de agregar el token [CLS] al principio.

Paso 4: contar parámetros para un ViT realista

Imprime el conteo de parámetros para ViT-Base: 12 capas, 12 cabezas, d=768, patch=16. Compáralo con ResNet-50 (~25M). ViT-Base se sitúa en ~86M. ViT-Large ~307M. ViT-Huge ~632M.

Úsalo

from transformers import ViTImageProcessor, ViTModel
import torch
from PIL import Image

processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k")
model = ViTModel.from_pretrained("google/vit-base-patch16-224-in21k")

img = Image.open("cat.jpg")
inputs = processor(img, return_tensors="pt")
out = model(**inputs).last_hidden_state   # (1, 197, 768): [CLS] + 196 patches
cls_emb = out[:, 0]                       # image representation

Los embeddings de DINOv2 son el estándar de 2026 para características de imagen. Congela el backbone, entrena una cabeza diminuta. Funciona para clasificación, recuperación (retrieval), detección y generación de leyendas (captioning). Los checkpoints de DINOv2 de Meta superan a CLIP en cada tarea de visión no textual.

Selección del tamaño de parche. Los modelos pequeños usan 16×16 (ViT-B/16). La predicción densa (segmentación) usa 8×8 o 14×14 (SAM, DINOv2). Los modelos muy grandes usan 14×14.

Entrégalo

Consulta outputs/skill-vit-configurator.md. La skill selecciona una variante de ViT y un tamaño de parche para una nueva tarea de visión según el tamaño del conjunto de datos, la resolución y el presupuesto de cómputo.

Ejercicios

  1. Fácil. Ejecuta code/main.py. Verifica que el número de parches sea igual a (H/P) * (W/P) y que la dimensión del parche aplanado sea igual a P*P*C.
  2. Medio. Implementa embeddings posicionales sinusoidales 2D — dos códigos sinusoidales independientes para la fila (row) y la columna (col) de cada parche, concatenados. Aliméntalos a un ViT diminuto en PyTorch y compara la precisión vs. los embeddings posicionales aprendibles en CIFAR-10.
  3. Difícil. Construye un ViT de 3 capas (PyTorch), entrénalo en 1,000 imágenes de MNIST con parches de 4×4. Mide la precisión de prueba. Ahora añade el preentrenamiento de DINOv2 en las mismas 1,000 imágenes (simplificado: solo entrena el encoder para predecir embeddings de parches a partir de parches enmascarados). ¿Mejora la precisión?

Términos Clave

Término Lo que la gente dice Lo que realmente significa
Parche (Patch) "El token del vision-transformer" Vector plano de valores de píxeles para una región de P × P × C de la imagen.
Patchify "Cortar + aplanar" Cortar la imagen en parches que no se solapan y aplanar cada uno en un vector.
Token [CLS] "El resumen de la imagen" Token aprendible agregado al principio; su embedding final es la representación de la imagen.
Sesgo inductivo "Lo que el modelo asume" ViT tiene menos supuestos previos que las CNN; necesita más datos para compensar la diferencia.
DINOv2 "ViT autossupervisado" Entrenado sin etiquetas mediante aumento de imágenes + profesor de momentum (momentum teacher). Mejores características de imagen generales en 2026.
SigLIP "El sucesor de CLIP" ViT + encoder de texto entrenado con pérdida contrastiva sigmoide; mejor que CLIP con el mismo presupuesto de cómputo.
Swin "ViT en ventanas" ViT jerárquico con atención local + ventanas desplazadas (shifted windows); subcuadrático.
Tokens de registro "Truque de 2023" Algunos tokens aprendibles adicionales que absorben los sinks de atención; mejora las características de DINOv2.

Lectura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).