SenseiTeoría desde cero0/21

1 · Lo básico de MLLección 6 de 8

Redes neuronales y CNNs

Neural networks and CNNs

Qué hay dentro de la ResNet-50 de C01, desde una sola neurona hasta el modelo completo: cómo se cuentan sus parámetros y sus cuentas, cómo mira una foto y por qué se empieza con un modelo que ya vio más de un millón de fotos.

⏱ 61 min lo esencial · 86 min todo26 conceptos nuevos3 calculadoras9 ejerciciosModelo
Secciones14
  1. 01Una neurona y su límite
  2. 02Capas y MLP: la red completa y lo que cuesta
  3. 03Del perceptrón a la inicialización extra
  4. 04Convolución: un filtro que recorre la foto
  5. 05El campo receptivo: cuánto de la foto ve cada neurona extra
  6. 06La ResNet-50 por dentro: atajos, BatchNorm y model.eval()
  7. 07Backbone, cabeza y transfer learning
  8. 08Vision Transformers: la foto como una frase de parches extra
  9. 09Errores comunes
  10. 10En la vida real extra
  11. 11Ejercicios
  12. 12Lo que sigue
  13. 13Palabras que vas a oír
  14. 14Chequeo
La pregunta

¿Qué es exactamente una «red neuronal», qué cuentas hace por dentro y por qué funciona tan bien con fotos?

01

Una neurona y su límite

Esencial

One neuron and its limit

En las lecciones anteriores viste que un modelo es una función con parámetros y que entrenar es ajustarlos. Ahora vamos a abrir la caja: ¿qué cuentas hace por dentro?

La pieza más chica es la neurona. Hace tres cosas:

  1. 1

    Multiplica cada entrada por su peso

    Recibe varios números de entrada y a cada uno lo multiplica por un número propio, su peso (weight). El peso dice qué tanto le importa esa entrada, y si la cuenta a favor (positivo) o en contra (negativo).

  2. 2

    Suma todo y le agrega su sesgo

    Suma esos productos y les agrega otro número propio, el sesgo (bias), que mueve el resultado hacia arriba o hacia abajo.

  3. 3

    Pasa el resultado por una activación

    Al final aplica una función sencilla, la activación, que decide qué sale. La más usada es la ReLU: si el número es negativo, sale 0; si no, sale igual.

Una neurona con tres entradas: 0.5, 0.8 y 0.2, con pesos 2, menos 1 y 3. La neurona suma los productos y el sesgo 0.1: 1.0 menos 0.8 más 0.6 más 0.1 da 0.9. La ReLU deja pasar 0.9 porque no es negativo. Abajo, la gráfica de la ReLU: cero para los negativos y la misma recta para los positivos. ENTRADASNEURONA 0.5 × 2 0.8 × −1 0.2 × 3 Σ + 0.1 suma + sesgo = 0.9 ReLU → 0.9 3 pesos (amarillo) + 1 sesgo = 4 parámetros LA CUENTA 0.5 × 2 = 1.0 0.8 × (−1) = −0.8 0.2 × 3 = 0.6 1.0 − 0.8 + 0.6 + 0.1 = 0.9 → ReLU → 0.9 RELU neg. → 0
Una neurona con tres entradas. Los pesos (en amarillo) y el sesgo son sus parámetros: lo que el entrenamiento ajusta.

¿Para qué la activación?

Parece un detalle, pero sin ella nada funcionaría. Sin activación, una neurona solo multiplica y suma: es una función lineal, una recta. Y si apilas rectas, sale otra recta. Por ejemplo, si una capa hace y = 3x + 1 y la siguiente hace z = 2y − 1, juntas hacen z = 2 × (3x + 1) − 1 = 6x + 1. Otra recta. Cien capas sin activación valen lo mismo que una.

La activación dobla la recta. La ReLU la dobla en el 0: todo lo negativo se aplana. Con muchas neuronas, cada una doblada en un lugar distinto, la red puede formar curvas tan complicadas como haga falta, como la frontera entre «foto de tenis» y «foto de bota». Antes se usaban activaciones suaves, como la sigmoide, que aplasta cualquier número entre 0 y 1; la ReLU se impuso en la década de 2010 porque es baratísima y con ella las redes profundas aprenden más rápido.

Lo que una neurona sola no puede: el XOR

Pongamos a una neurona a contestar «sí» o «no» sobre dos entradas que valen 0 o 1. En vez de la ReLU usa una activación de escalón: si la suma pasa de 0 sale 1 («sí»), y si no, 0 («no»). Dos funciones para probarla: el AND vale 1 solo si las dos entradas valen 1; el XOR («o exclusivo») vale 1 si exactamente una vale 1.

La neurona responde 1 cuando w₁x₁ + w₂x₂ + b > 0 y 0 cuando no. La frontera entre las dos respuestas, w₁x₁ + w₂x₂ + b = 0, es una recta: una neurona sola parte el plano en dos con una recta, y nada más.

Tres paneles. Arriba, el AND: de los cuatro puntos (0,0), (1,0), (0,1) y (1,1), solo (1,1) vale 1, y una recta lo separa de los otros tres. En medio, el XOR: valen 1 los puntos (0,1) y (1,0), en esquinas opuestas; dos rectas punteadas de intento fallan, porque cualquier recta deja un cero del lado de los unos. Abajo, la capa oculta: con h1 igual a ReLU de x1 más x2 y h2 igual a ReLU de x1 más x2 menos 1, los puntos se mueven a (0,0), (1,0) dos veces y (2,1); los dos que valen 1 caen juntos en (1,0) y una recta azul ya los separa. AND · UNA RECTA BASTA vale 1 vale 0 0 1 0 1 x₁ x₂ Vale 1 solo en (1, 1). Una recta lo aparta de los otros tres. XOR · NINGUNA RECTA SIRVE 0 1 0 1 x₁ x₂ Vale 1 en (0, 1) y (1, 0), esquinas opuestas. Toda recta deja un ○ del lado de los ●. CON UNA CAPA OCULTA: (h₁, h₂) 0 1 2 0 1 h₁ h₂ ×2 h₁ = ReLU(x₁ + x₂) h₂ = ReLU(x₁ + x₂ − 1) (0, 1) y (1, 0) caen juntos en (1, 0): ahora una recta basta.
Arriba, el AND: el único punto que vale 1 queda solo de un lado de una recta. En medio, el XOR: los dos que valen 1 están en esquinas opuestas y ninguna recta los aparta de los otros dos. Abajo, la solución de la siguiente sección: una capa oculta mueve los puntos y ahí una recta sí sirve.

Pon los cuatro casos como puntos, con x₁ a lo ancho y x₂ a lo alto. En el AND, el único 1 es la esquina (1, 1), y una recta la aparta: con w₁ = 2, w₂ = 1 y b = −2, solo (1, 1) da una suma positiva (2 + 1 − 2 = 1). En el XOR, los unos están en esquinas opuestas, (0, 1) y (1, 0): cualquier recta que los deje del mismo lado deja también a alguno de los ceros. No es que falten pesos buenos: lo que le pides no se puede dibujar con una recta.

Una neurona así, con escalón, es el perceptrón que Frank Rosenblatt publicó en 1958, una de las primeras neuronas artificiales que aprendían solas. Aprendía el AND, pero nunca el XOR; su historia, con código, está en la sección extra «Del perceptrón a la inicialización». La salida es juntar varias neuronas, en capas.

02

Capas y MLP: la red completa y lo que cuesta

Esencial

Layers and MLPs: the whole network and its cost

Una neurona sola traza una recta. Se juntan muchas en una capa: todas reciben las mismas entradas, cada una con sus propios pesos, y cada una saca un número. Las salidas de una capa son las entradas de la siguiente. Eso es una red neuronal.

Cuando cada neurona de una capa ve todas las salidas de la anterior, la capa se llama densa (dense o fully connected). Una red de capas densas con activaciones entre ellas es un MLP (multilayer perceptron, perceptrón multicapa), un nombre que viene del perceptrón, aunque ya no usa escalón. Las capas de en medio se llaman capas ocultas (hidden layers).

El XOR, resuelto con una capa oculta

¿Qué hizo la capa oculta? Movió los puntos: con las coordenadas (h₁, h₂), los dos casos que valen 1 caen juntos en (1, 0), y ahí una recta sí los separa de los ceros (el panel de abajo de la figura). Esa es la idea de toda red neuronal: cada capa acomoda los datos para que a la siguiente le sea más fácil.

Aquí los pesos los puse a mano. En una red de verdad los encuentra el entrenamiento, con la backpropagation que viste en «Cómo aprende un modelo»: una forma de repartir la culpa del error entre todas las capas, también las ocultas. Es justo lo que le faltaba a la regla del perceptrón, que solo sabe corregir la neurona que da la respuesta.

Usar redes con muchas capas es el deep learning (aprendizaje profundo): «profundo» se refiere a la cantidad de capas. Cada capa trabaja sobre lo que encontró la anterior, así que más capas dan más pasos para combinar cosas simples en complicadas. La ResNet-50 de C01 tiene 50 capas con pesos.

Un forward pass con lápiz

Hacer pasar una entrada por todas las capas, de la primera a la última, se llama forward pass (pasada hacia adelante). Es lo que hace el modelo cada vez que responde. Hagamos uno a mano en una red de juguete: 2 entradas → 3 neuronas con ReLU → 2 salidas, una para «Tenis» y otra para «Botas».

Eso es todo lo que hace una red al responder: multiplicar, sumar y aplicar la activación, capa por capa. La ResNet-50 hace lo mismo con la foto de Ana, solo que con unos 4,100 millones de multiplicaciones (cada una con su suma) en lugar de una docena.

Contar parámetros y multiplicaciones

Los parámetros de una red son todos sus pesos y todos sus sesgos. En la red de juguete:

  • Capa 1: 2 entradas × 3 neuronas = 6 pesos, más 3 sesgos = 9
  • Capa 2: 3 entradas × 2 salidas = 6 pesos, más 2 sesgos = 8
  • Total: 9 + 8 = 17 parámetros

La regla sirve para cualquier capa densa: parámetros = entradas × salidas + salidas.

La otra cuenta es cuánto trabajo hace. Cada peso se usa una vez por ejemplo: se multiplica por su entrada y se suma a lo acumulado. Ese par «multiplica y suma» se llama MAC (multiply-accumulate) y es la unidad con que se mide el trabajo de una red. Una capa densa hace entradas × salidas MACs por ejemplo; la red de juguete, 2 × 3 + 3 × 2 = 12.

La última capa de la ResNet-50 de C01, contadaLa cuenta
Pesosrecibe 2,048 números y saca uno por categoría
2,048 × 500
1,024,000
Sesgos
uno por salida
500
Parámetros
1,024,000 + 500
1,024,500
Memoriaen float32, 4 bytes por número
1,024,500 × 4 B
≈ 4.1 MB
MACs por fotocada peso se usa una vez
2,048 × 500
1,024,000
Parte de los parámetros del modelo
1,024,500 ÷ 24,532,532
≈ 4.2 %
Parte de las MACs del modelo
1,024,000 ÷ ≈ 4,100 millones
≈ 0.025 %
Resultado
Esta capa guarda el 4 % de los números del modelo, pero hace solo el 0.025 % del trabajo. El resto de la red reutiliza cada peso miles de veces por foto: lo vas a ver en la convolución.

¿Y si le das la foto entera a un MLP? La calculadora empieza con el clásico de los años 90: dígitos escritos a mano de 28 × 28 píxeles en gris (el dataset MNIST), 128 neuronas ocultas y 10 salidas, una por dígito.

Un MLP que recibe la foto enteraCalculadora

Una capa oculta densa y una de salida. Mueve el tamaño de la foto y mira cómo crecen los parámetros de la primera capa: cada píxel de cada canal necesita un peso por cada neurona oculta.

Entradaslado × lado × canales784
Parámetros de la capa ocultaentradas × ocultas + ocultas100,480
Parámetros de la capa de salidaocultas × salidas + salidas1,290
Parámetros en total101,770
Tamaño contra la ResNet-50 de C01100 % = sus 24,532,532 parámetros0.4 %
Memoria en float324 bytes por parámetro407 KB
MACs por fotouna por peso101,632

Con 224 × 224 en color y solo 128 ocultas, la primera capa ya tiene 19.3 millones de parámetros, y cada peso conecta un solo número de la foto (un píxel de un color) con una sola neurona.

Después prueba lado 224, 3 canales y 500 salidas: la foto de C01.

Con los dígitos son 101,770 parámetros. Con la foto de C01 y apenas 128 neuronas ocultas, la primera capa ya tiene 150,528 × 128 + 128 = 19,267,712, tres cuartas partes de la ResNet-50 entera. Y como cada píxel tiene su propio peso, la red tendría que aprender a encontrar el tenis en cada posición por separado. La convolución arregla las dos cosas.

Contar parámetros dice cuánta memoria pide el modelo. Guardado como float32, cada uno ocupa 4 bytes: los 25.6 millones de una ResNet-50 son 25.6 M × 4 B ≈ 102 MB, la primera cuenta de la Ronda en M04 para saber cuánta memoria de GPU necesita.

Contar MACs dice cuánto cálculo pide cada foto: la ResNet-50 hace ≈ 4,100 millones, 4.1 GMACs (G es «giga», mil millones). Cuánto tarda eso en una GPU de verdad lo ves con la T4 de C01 en «En la vida real».

03

Del perceptrón a la inicialización

Extra

From the perceptron to initialization

Esta sección es para una segunda pasada: cómo aprendía una de las primeras neuronas artificiales, por qué las redes se atoraron durante años y con qué números empiezan los pesos de una red de hoy.

El perceptrón: una neurona que aprendía de sus errores

En 1958, el psicólogo estadounidense Frank Rosenblatt publicó el perceptrón: una neurona con escalón, como la del XOR de la primera sección. Lo nuevo era que aprendía solo, con una regla simple. Si acierta, no cambia nada. Si dijo 0 y era 1, le suma cada entrada a su peso (y 1 al sesgo), para que la próxima vez su suma salga más alta; si dijo 1 y era 0, se las resta.

Probémoslo con el AND y el XOR de la primera sección. Cada «vuelta» es una pasada por los cuatro casos.

python
# El perceptrón de Rosenblatt: si se equivoca, mueve sus pesos hacia la respuesta
def entrenar(datos, vueltas=20):
    w1, w2, b = 0, 0, 0
    for vuelta in range(1, vueltas + 1):
        errores = 0
        for x1, x2, y in datos:
            pred = 1 if w1 * x1 + w2 * x2 + b > 0 else 0   # el escalón
            if pred != y:
                errores += 1
                w1 += (y - pred) * x1          # dijo 0 y era 1: suma la entrada
                w2 += (y - pred) * x2          # dijo 1 y era 0: la resta
                b += (y - pred)
        if errores == 0:
            return f"aprendió en la vuelta {vuelta}: w1={w1}, w2={w2}, b={b}"
    return f"tras {vueltas} vueltas sigue fallando {errores} de 4"

AND = [(0, 0, 0), (0, 1, 0), (1, 0, 0), (1, 1, 1)]
XOR = [(0, 0, 0), (0, 1, 1), (1, 0, 1), (1, 1, 0)]
print("AND:", entrenar(AND))
print("XOR:", entrenar(XOR))
Salida
AND: aprendió en la vuelta 6: w1=2, w2=1, b=-2
XOR: tras 20 vueltas sigue fallando 4 de 4

Con el AND, a la sexta vuelta ya no se equivoca: llega a w₁ = 2, w₂ = 1 y b = −2, los pesos que viste en la primera sección. Con el XOR se queda en un ciclo en el que cada corrección deshace la anterior; ni con mil vueltas aprende.

Rosenblatt llegó a construir una máquina, la Mark I Perceptron, que veía con una cámara de 20 × 20 = 400 fotoceldas, y un periódico de 1958 contó que la Marina de Estados Unidos esperaba que una máquina así llegara a caminar, hablar y ver. No pasó: el perceptrón tenía un límite que ninguna cantidad de vueltas arregla, el del XOR.

En 1969, Marvin Minsky y Seymour Papert publicaron Perceptrons, un libro que convirtió este tipo de límites en teoremas. Se le suele culpar de que el interés y el dinero para las redes neuronales se enfriaran durante años; la historia real tiene más causas (computadoras lentas, pocos datos), pero el límite es real. La salida fueron las capas ocultas y una forma de entrenarlas, la backpropagation.

Para ir más hondoDe 1958 a hoy, en ocho fechas
AñoQué pasó
1958Rosenblatt publica el perceptrón, una neurona que aprende de sus errores.
1969Minsky y Papert publican Perceptrons: una sola capa no puede con el XOR.
1986Rumelhart, Hinton y Williams popularizan la backpropagation: ya se entrenan capas ocultas.
1989–1998Yann LeCun y su equipo entrenan CNNs que leen dígitos escritos a mano; a finales de los 90 una lee cheques en bancos de Estados Unidos.
2009Se publica ImageNet. De 2010 a 2017 hay una competencia anual con su versión de 1,000 categorías.
2012AlexNet, una CNN entrenada en dos GPUs, gana con 15.3 % de error top-5 contra 26.2 % del segundo lugar. Despega el deep learning.
2015Gana la ResNet, con atajos y 152 capas. Salen también la BatchNorm y la U-Net.
2020El Vision Transformer muestra que un transformer, la arquitectura de los LLMs, también ve fotos.

Desde 1986 la idea básica casi no cambió. Cambiaron tres cosas: muchos más datos, GPUs para hacer las cuentas y trucos para entrenar redes profundas. La ReLU y el Dropout ya los usó AlexNet en 2012; una buena inicialización, la BatchNorm y los atajos se sumaron entre 2010 y 2015. Están todos en esta lección.

Inicialización: con qué números empieza una red

Antes del primer paso del entrenamiento, cada peso necesita un valor. Elegirlo se llama inicialización (initialization). Parece un detalle, pero durante años fue una de las razones por las que las redes profundas no aprendían.

¿Por qué no empezar todo en cero? Piensa en dos neuronas ocultas que empiezan con los mismos pesos. Reciben las mismas entradas, así que calculan lo mismo; la backpropagation les reparte la misma culpa, así que se mueven igual. Paso tras paso siguen siendo gemelas: dos neuronas que valen por una. Es el problema de la simetría. Con todo en cero es peor: las ocultas sacan 0, la salida las multiplica por pesos que valen 0, la culpa regresa multiplicada por esos mismos ceros y nada se mueve.

python
# Dos neuronas ocultas que empiezan iguales: ¿se separan al entrenar?
r = lambda fila: [round(a, 4) for a in fila]

def entrenar(w0, pasos=3, lr=0.01):
    x, y = [1.0, 2.0], 1.0                   # un ejemplo y su respuesta
    W = [[w0, w0], [w0, w0]]                 # pesos de las 2 neuronas ocultas
    v = [w0, w0]                             # pesos de la salida
    for paso in range(1, pasos + 1):
        h = [max(0.0, W[i][0] * x[0] + W[i][1] * x[1]) for i in range(2)]  # ReLU
        err = v[0] * h[0] + v[1] * h[1] - y  # la pérdida es err²
        for i in range(2):                   # backpropagation, a mano
            culpa = 2 * err * v[i] * (1 if h[i] > 0 else 0)
            v[i] -= lr * 2 * err * h[i]
            W[i] = [W[i][j] - lr * culpa * x[j] for j in range(2)]
        print(f"  paso {paso}: neurona 1 {r(W[0])}   neurona 2 {r(W[1])}")

print("Todo en 0.5:"); entrenar(0.5)
print("Todo en 0:");   entrenar(0.0)
Salida
Todo en 0.5:
  paso 1: neurona 1 [0.495, 0.49]   neurona 2 [0.495, 0.49]
  paso 2: neurona 1 [0.4908, 0.4816]   neurona 2 [0.4908, 0.4816]
  paso 3: neurona 1 [0.4873, 0.4746]   neurona 2 [0.4873, 0.4746]
Todo en 0:
  paso 1: neurona 1 [0.0, 0.0]   neurona 2 [0.0, 0.0]
  paso 2: neurona 1 [0.0, 0.0]   neurona 2 [0.0, 0.0]
  paso 3: neurona 1 [0.0, 0.0]   neurona 2 [0.0, 0.0]

Con 0.5, las dos neuronas se mueven, pero en cada paso tienen exactamente los mismos pesos. Con 0, ni se mueven. La salida es romper la simetría con números al azar: cada neurona empieza distinta, recibe una culpa distinta y termina aprendiendo algo distinto.

¿Qué tan grandes?

Al azar, sí, pero ¿de qué tamaño? Si los pesos son un poco grandes, los números crecen un poco en cada capa y después de 20 o 50 capas explotan; si son un poco chicos, se encogen hasta casi 0. Lo mismo le pasa a la culpa del entrenamiento, que viaja de regreso por los mismos pesos.

El tamaño justo depende de cuántas entradas suma cada neurona: entre más entradas, más chicos los pesos, para que la suma no crezca. La regla más usada con ReLU es la de He (Kaiming He y otros, 2015, el mismo primer autor de la ResNet): pesos al azar alrededor de 0 con una desviación estándar de √(2 ÷ entradas). La desviación estándar mide qué tan lejos de 0 caen: es la raíz del promedio de sus cuadrados, la misma cuenta que hace tamano en el código de abajo. El 2 compensa que la ReLU apaga más o menos la mitad de los números, los negativos.

python
# ¿Qué le pasa a la señal después de 20 capas, según el tamaño de los pesos?
import math, random
random.seed(0)
n, capas = 100, 20                            # 100 neuronas por capa

def tamano(x):                                # qué tan grandes son los números
    return math.sqrt(sum(v * v for v in x) / len(x))

for nombre, sigma in [("chicos, 0.05", 0.05), ("He, √(2/100)", math.sqrt(2 / n)), ("grandes, 0.3", 0.3)]:
    x = [random.gauss(0, 1) for _ in range(n)]
    for capa in range(capas):
        W = [[random.gauss(0, sigma) for _ in range(n)] for _ in range(n)]
        x = [max(0.0, sum(w * xi for w, xi in zip(fila, x))) for fila in W]  # ReLU
    print(f"pesos {nombre:<14} tamaño tras {capas} capas: {tamano(x):.3g}")
Salida
pesos chicos, 0.05   tamaño tras 20 capas: 3.45e-09
pesos He, √(2/100)   tamaño tras 20 capas: 1.48
pesos grandes, 0.3   tamaño tras 20 capas: 1.34e+06

La entrada empieza con números de tamaño ≈ 1. 3.45e-09 es como Python escribe 3.45 × 10⁻⁹ (0.00000000345), y 1.34e+06 es 1.34 millones. Con 0.05 la señal casi desaparece; con 0.3 se dispara; con la regla de He, √(2 ÷ 100) ≈ 0.141, llega viva. No es un ajuste fino: es la diferencia entre aprender y no aprender.

Con qué desviación empieza una convolución de 3 × 3La cuenta
Entradas de cada neuronaun filtro de 3 × 3 que mira 64 canales
3 × 3 × 64
576
Desviación de He
√(2 ÷ 576)
≈ 0.059
Con 512 canales de entrada
√(2 ÷ (3 × 3 × 512)) = √(2 ÷ 4,608)
≈ 0.021
Resultado
Más entradas, pesos más chicos: así la suma de cada neurona se queda del mismo tamaño en toda la red.

En la práctica no lo escribes tú: PyTorch inicializa cada capa con una regla de este tipo al crearla, y la ResNet de torchvision usa la de He en sus convoluciones. En C01 casi ni importa, porque la red llega ya entrenada con ImageNet, más de un millón de fotos (lo ves en «Backbone, cabeza y transfer learning»): solo la capa nueva de 2,048 → 500 empieza al azar, con números entre −1/√2,048 y +1/√2,048, o sea entre −0.022 y +0.022.

04

Convolución: un filtro que recorre la foto

Esencial

Convolution: a filter that slides over the photo

Ya viste el problema del MLP: una foto de 224 × 224 píxeles con 3 colores son 150,528 números, y una sola capa densa de 1,000 neuronas sobre ellos necesitaría 150,528 × 1,000 ≈ 150 millones de pesos, casi 6 veces la ResNet-50 entera. Además desperdicia algo obvio: en una foto lo que importa son los píxeles cercanos entre sí. Un píxel de la esquina tiene poco que decirle a uno del centro.

La solución es la convolución. En vez de que cada neurona vea toda la foto, un filtro chico, por ejemplo de 3 × 3, se va deslizando por la foto. En cada posición mira solo 9 píxeles, los multiplica por sus 9 pesos, suma todo y escribe un número; luego se mueve un lugar y repite.

Una convolución. Arriba, una cuadrícula de 5 por 5 píxeles: las tres columnas de la izquierda claras (8 y 9) y las dos de la derecha oscuras (0 y 1). Un filtro de 3 por 3 con columnas de pesos 1, 0 y menos 1 está sobre las filas 1 a 3 y columnas 2 a 4. Multiplica cada píxel por su peso y suma: 8 más 8 más 8 da 24, que se escribe en la salida. La salida completa es de 3 por 3: 0, 24, 25 en cada fila, aproximadamente. Los números grandes marcan el borde entre lo claro y lo oscuro. ENTRADA 5 × 5FILTRO 3 × 3 8 9 9 1 0 9 8 9 0 1 9 9 8 1 0 8 9 9 0 0 9 8 9 1 1 ×1 ×0 ×−1 ×1 ×0 ×−1 ×1 ×0 ×−1 1 0 −1 1 0 −1 1 0 −1 9 pesos queaprende la red LA VENTANA MARCADA fila 1: 9×1 + 9×0 + 1×(−1) = 8 fila 2: 8×1 + 9×0 + 0×(−1) = 8 fila 3: 9×1 + 8×0 + 1×(−1) = 8 suma: 8 + 8 + 8 = 24 SALIDA 3 × 3 0 24 25 0 25 25 0 24 25 0 = parejo24–25 = borde
Un filtro de 3 × 3 sobre una cuadrícula de 5 × 5. En la ventana marcada, cada píxel se multiplica por el peso que le cae encima; la suma, 24, se escribe en la salida.

Nadie programó ese filtro. En una red de verdad, los 9 pesos los encuentra el entrenamiento, y muchos filtros de las primeras capas terminan pareciéndose a detectores de bordes como este.

Canales y mapas de activaciones

Una foto de color no es una cuadrícula sino tres, una por color: rojo, verde y azul. Cada una es un canal. Por eso, un filtro de verdad no es de 3 × 3 sino de 3 × 3 × 3: mira los tres canales a la vez. Son 27 pesos más 1 sesgo = 28 parámetros.

Y una capa no tiene un solo filtro, sino muchos: uno busca bordes verticales, otro horizontales, otro un cambio de color. Cada filtro produce su propia cuadrícula de salida, su mapa de activaciones (feature map), que dice dónde encontró lo que busca. Una capa con 64 filtros produce 64 mapas, y esos son los 64 canales de entrada de la capa siguiente.

Una capa de 64 filtros de 3 × 3 sobre la foto de colorLa cuenta
Pesos de un filtromira los 3 canales a la vez
3 × 3 × 3
27
Parámetros de un filtro
27 pesos + 1 sesgo
28
Parámetros de la capa
64 filtros × 28
1,792
Posiciones del filtrocon un marco de ceros la salida mide lo mismo que la entrada (lo ves abajo)
224 × 224
50,176
MACs de la capa
50,176 posiciones × 64 filtros × 27 pesos = 86,704,128
≈ 87 millones
Veces que se usa cada peso
una por posición
50,176
Resultado
1,792 parámetros, 84,000 veces menos que los ≈ 150 millones de la capa densa, pero ≈ 87 millones de MACs: cada peso se reutiliza en las 50,176 posiciones.

Esa es la diferencia de fondo: en una capa densa cada peso se usa una vez por foto; en una convolución, una vez por posición. Por eso la Ronda, en M04, dice que una CNN en GPU, con batches moderados, suele estar limitada por el cálculo y no por la memoria (compute-bound): la GPU pasa más tiempo haciendo cuentas que esperando números de la memoria, porque cada peso que lee lo usa miles de veces.

Stride y padding: el tamaño de la salida

En el ejemplo, la entrada era de 5 × 5 y la salida de 3 × 3: en una fila de 5, una ventana de 3 cabe en 5 − 3 + 1 = 3 posiciones. Dos perillas cambian esa cuenta:

  • El stride (paso): cuántos píxeles salta el filtro de una posición a la siguiente. Con stride 2 salta de dos en dos, y la salida queda más o menos de la mitad de ancho y de alto.
  • El padding (relleno): un marco de ceros alrededor de la entrada, para que el filtro también se centre en las orillas y la salida no se encoja.

Con las dos, el lado de la salida es:

lado de salida = (n + 2p − k) ÷ s + 1, redondeando la división hacia abajo

Aquí n es el lado de la entrada, k el del filtro, p el padding (filas de ceros por lado) y s el stride. ¿De dónde sale? Con el marco, la entrada mide n + 2p; la primera ventana ocupa k píxeles y caben (n + 2p − k) ÷ s saltos más antes de salirse, más la posición de arranque. Si la división no es exacta, la última ventana no cabe completa y esas columnas se quedan sin visitar.

Padding y stride. Arriba a la izquierda, la foto de 5 por 5 del ejemplo de convolución, rodeada por un marco de ceros que la vuelve de 7 por 7. Una ventana de 3 por 3 marcada en amarillo está en la esquina de arriba a la izquierda, y otra punteada está dos columnas a la derecha: con stride 2 la ventana salta de dos en dos. A la derecha, la salida de 3 por 3: menos 17, 16 y 1; menos 26, 25 y 1; menos 17, 16 y 1. La columna izquierda sale negativa porque el filtro confunde el marco de ceros con un borde. Abajo, la cuenta: n más 2p menos k, entre s, más 1; con n = 5, k = 3, p = 1 y s = 2 da 3. PADDING 1 Y STRIDE 2 0 0 0 0 0 0 0 0 8 9 9 1 0 0 0 9 8 9 0 1 0 0 9 9 8 1 0 0 0 8 9 9 0 0 0 0 9 8 9 1 1 0 0 0 0 0 0 0 0 marco de ceros la foto de 5 × 5 SALIDA 3 × 3 -17 16 1 -26 25 1 -17 16 1 Salta de 2 en 2: caben 3 por lado. La columna izquierda sale negativa: el filtro confunde el marco con un borde. LA CUENTA (n + 2p − k) ÷ s + 1 n = 5, k = 3, p = 1, s = 2: (5 + 2 − 3) ÷ 2 + 1 = 3 si la división no es exacta, redondea hacia abajo
Padding 1 y stride 2 sobre la entrada de 5 × 5: el marco de ceros la vuelve de 7 × 7 y la ventana de 3 × 3 salta de dos en dos, así que la salida es de 3 × 3. Su columna izquierda sale negativa: el filtro confunde el marco de ceros con un borde.

El stride es la forma barata de achicar: con stride 2 queda la cuarta parte de las posiciones, así que la capa siguiente hace cuatro veces menos cuentas por filtro.

La primera capa de la ResNet-50La cuenta
Lado de salidafiltros de 7 × 7, padding 3, stride 2
(224 + 6 − 7) ÷ 2 = 111.5, baja a 111; más 1
112
Parámetrossin sesgo: la capa que sigue, una BatchNorm (la ves más adelante), ya suma su propio número
7 × 7 × 3 × 64
9,408
MACscada posición usa los 7 × 7 × 3 = 147 pesos de cada filtro
112 × 112 × 64 × 147 = 118,013,952
≈ 118 millones
Después, el max poolinglo ves en un momento: ventana de 3 × 3, padding 1, stride 2
(112 + 2 − 3) ÷ 2 = 55.5, baja a 55; más 1
56
Resultado
La foto de 224 × 224 × 3 sale de las dos primeras capas como 64 mapas de 56 × 56: 16 veces menos posiciones, por apenas el 2.9 % de las MACs de toda la red.
Una capa convolucional por dentroCalculadora

Empieza en la primera capa de la ResNet-50: 64 filtros de 7 × 7 con padding 3 y stride 2 sobre la foto de 224 × 224 × 3. El lado de la salida es (n + 2p − k) ÷ s + 1, con la división redondeada hacia abajo.

Lado de la salida(n + 2p − k) ÷ s + 1, hacia abajo112
Columnas que se quedan sin visitarcuando la división no es exacta1
Parámetrosk × k × canales × filtros, más los sesgos9,408
MACs por fotoposiciones × filtros × pesos por filtro118,013,952
Veces que se usa cada pesouna por posición de la salida12,544
Salida de una foto en float32lado × lado × filtros × 4 bytes3.21 MB

Con k = 3, p = 1 y s = 1 la salida mide lo mismo que la entrada. Cada stride de 2 deja la cuarta parte de las posiciones, y con ellas, la cuarta parte de las MACs.

Prueba n = 5, k = 3, p = 1 y s = 1: la salida mide 5, como la entrada. Luego sube el stride a 2.

Pooling: resumir para achicar

La otra forma de achicar es el pooling. El más común, el max pooling de 2 × 2, parte el mapa en cuadritos de 2 × 2 y de cada uno se queda con el número más grande. Su tamaño sale de la misma fórmula, con k = 2, s = 2 y p = 0.

Hoy muchas redes achican con convoluciones de stride 2, porque así el achique también aprende. La ResNet-50 usa un solo max pooling, al principio; el resto lo hace con stride 2, y al final un pooling global promedia cada mapa entero en un número.

Por qué las CNNs sirven tan bien para fotos

Una red hecha de convoluciones, activaciones y pooling es una CNN (convolutional neural network, red neuronal convolucional). Les va bien a las fotos por tres razones:

  1. Mira de cerca. Cada filtro mira un pedacito, y en una foto el significado está en los píxeles vecinos: un borde, una textura, una agujeta.
  2. Usa el mismo filtro en todas partes. El filtro que encuentra una agujeta la encuentra en la esquina o en el centro. El tenis de Ana puede estar en cualquier lugar de la foto y no hay que aprenderlo una vez por cada lugar. Por eso tiene tan pocos parámetros.
  3. Arma lo complicado con lo simple. Las primeras capas encuentran bordes y manchas de color. Las de en medio combinan bordes en texturas y formas (una suela, una costura). Las últimas combinan partes en objetos (un tenis). Funciona porque cada capa ve un pedazo de la foto más grande que la anterior: su campo receptivo crece, como verás en la sección extra que sigue. Nadie programa esa jerarquía: sale del entrenamiento.
05

El campo receptivo: cuánto de la foto ve cada neurona

Extra

Receptive field: how much of the photo a neuron sees

Una neurona de la primera capa, con un filtro de 3 × 3, ve 3 × 3 píxeles. Una de la segunda ve 3 × 3 neuronas de la primera, cada una con su propio cuadro de 3 × 3; como se enciman, juntas cubren 5 × 5 píxeles. La de la tercera cubre 7 × 7. El pedazo de la foto que puede influir en una neurona es su campo receptivo (receptive field).

El campo receptivo. Arriba, visto de lado: una neurona de la capa 3 se conecta con 3 neuronas de la capa 2, que juntas se conectan con 5 de la capa 1, que juntas ven 7 píxeles de la foto. Abajo, visto de frente sobre una cuadrícula de 7 por 7: el cuadro de 3 por 3 que ve una neurona de la capa 1, el de 5 por 5 de la capa 2 y el de 7 por 7 de la capa 3, todos centrados en el mismo píxel. Con stride 2 crece más rápido: 3, 7 y 15. En la ResNet-50 llega a 427 por 427 píxeles. DE LADO: UNA FILA DE PÍXELES CAPA 3 CAPA 2 CAPA 1 FOTO la neurona de la capa 3 ve 7 píxeles DE FRENTE: 3 × 3, 5 × 5 Y 7 × 7 capa 1 · 3 × 3 capa 2 · 5 × 5 capa 3 · 7 × 7 CON STRIDE 2 crece más rápido: 3 → 7 → 15 RESNET-50 427 × 427 píxeles
Arriba, de lado: la neurona de la capa 3 depende de 3 neuronas de la capa 2, de 5 de la capa 1 y de 7 píxeles. Abajo, de frente: los cuadros de 3 × 3, 5 × 5 y 7 × 7 que ven las neuronas de las capas 1, 2 y 3, todas centradas en el mismo píxel.

Con stride 1, cada capa de 3 × 3 le suma 2 píxeles al lado: 3, 5, 7, 9… Para ver 224 píxeles harían falta más de 100 capas. El stride lo acelera: después de una capa con stride 2, dos neuronas vecinas están separadas por 2 píxeles de la foto, así que un filtro de 3 × 3 en la capa siguiente abarca más terreno.

La cuenta, capa por capa, lleva dos números: el campo receptivo r y el salto j, cuántos píxeles de la foto hay entre dos neuronas vecinas de esa capa. Se empieza con r = 1 y j = 1 (un píxel se ve a sí mismo), y en cada capa con filtro k y stride s:

r nuevo = r + (k − 1) × j · j nuevo = j × s

Con tres capas de 3 × 3 y stride 1: r = 1 + 2 = 3, luego 3 + 2 = 5, luego 5 + 2 = 7, como en la figura. Si las tres tienen stride 2: 1 + 2 × 1 = 3 (salto 2), 3 + 2 × 2 = 7 (salto 4), 7 + 2 × 4 = 15 (salto 8).

Cuánto de la foto ve una neuronaCalculadora

Una pila de capas iguales, todas con el mismo filtro y el mismo stride. En cada capa, el campo crece (k − 1) × salto, y el salto se multiplica por el stride.

Campo receptivo de la última capapíxeles de lado7
Salto entre dos neuronas vecinasstride elevado al número de capas1
Lado del último mapacon el padding que conserva el tamaño224
Parte del lado de la foto que ve3.1 %

Con stride 1, cada capa de 3 × 3 suma apenas 2 píxeles. Con stride 2 en todas, 5 capas ya ven 63 píxeles y el último mapa de una foto de 224 mide 7: el mismo que el de la ResNet-50.

La calculadora usa el mismo filtro y el mismo stride en todas las capas. Las redes reales mezclan, pero la fórmula de arriba sirve igual, capa por capa.

En la ResNet-50 las capas son distintas. La primera es de 7 × 7. Después vienen 16 bloques, cada uno con dos convoluciones de 1 × 1 (que no suman nada, porque k − 1 = 0) y una de 3 × 3, repartidos en cuatro etapas; cada etapa a partir de la segunda empieza con stride 2:

El campo receptivo de la ResNet-50, etapa por etapaLa cuenta
Primera capa7 × 7, stride 2
1 + 6 × 1
7 (salto 2)
Max pooling3 × 3, stride 2
7 + 2 × 2
11 (salto 4)
Etapa 13 bloques, una conv de 3 × 3 en cada uno
11 + 3 × 2 × 4
35 (salto 4)
Etapa 2la primera de 3 × 3 con stride 2, luego 3 más
35 + 2 × 4 + 3 × 2 × 8
91 (salto 8)
Etapa 36 bloques
91 + 2 × 8 + 5 × 2 × 16
267 (salto 16)
Etapa 43 bloques
267 + 2 × 16 + 2 × 2 × 32
427 (salto 32)
Resultado
Cada número del último mapa de 7 × 7 puede depender de un cuadro de 427 × 427 píxeles, más grande que la foto de 224. Y el salto de 32 cuadra con el tamaño del mapa: 224 ÷ 32 = 7.
Para ir más hondoEl campo que de verdad se usa

Los 427 píxeles son un máximo teórico: dicen qué píxeles pueden influir. Los del centro pesan muchísimo más que los de la orilla, porque llegan a la neurona por muchos más caminos. Un estudio de 2016 (Luo y otros) lo midió: el campo «efectivo» es una mancha que se desvanece del centro hacia afuera y ocupa solo una parte del teórico. Que algo «quepa» en el campo receptivo no garantiza que la red lo note.

¿Para qué sirve en producción? Para dos preguntas de diseño: ¿la red alcanza a ver un objeto grande entero?, y ¿lo chico sobrevive? Con un salto de 32, dos números vecinos del último mapa están a 32 píxeles uno del otro: a cada uno le toca una celda de 32 × 32 píxeles, y un defecto de 3 píxeles es casi nada en ella. Lo verás con números en la inspección de C03.

06

La ResNet-50 por dentro: atajos, BatchNorm y model.eval()

Esencial

Inside ResNet-50: shortcuts, BatchNorm and model.eval()

Ya tienes todas las piezas: convoluciones, ReLU, stride y pooling. La ResNet-50 de C01 las junta así. Las dos franjas del diagrama son las dos partes de toda CNN que clasifica: el backbone, que convierte la foto en 2,048 números, y la cabeza, la última capa, que decide la categoría (las ves a fondo en la sección que sigue).

La ResNet-50 de C01, de la foto a las sugerencias · La ResNet-50 de C01, de la foto a las 5 sugerencias. Toca cada caja; el recorrido sigue a la foto de Ana.
  • Foto · 3 × 224 × 224
    La foto de Ana, ya preprocesada: 3 canales (rojo, verde y azul) de 224 × 224 píxeles, 150,528 números. Está aquí porque es lo único que el modelo sabe leer: números, no imágenes.
  • Primera capa · conv 7 × 7
    Una convolución con 64 filtros de 7 × 7 y stride 2 deja la foto en 112 × 112, y un max pooling la baja a 56 × 56: 64 mapas que ya no son colores, son respuestas a filtros. Está aquí para achicar pronto la foto y que lo que sigue cueste menos: solo hace el 2.9 % de las cuentas.
  • 16 bloques · residuales
    Casi todo vive aquí: ≈ 23.5 millones de parámetros y ≈ 97 % de las multiplicaciones-sumas. Cuatro etapas de 3, 4, 6 y 3 bloques, cada uno con su atajo (resnet). Los mapas se achican (56 → 28 → 14 → 7 de lado) mientras los canales crecen (256 → 512 → 1,024 → 2,048). Aquí la red combina bordes en texturas y texturas en partes: es lo que sabe «ver».
  • Pooling global · un promedio por mapa
    Cada uno de los 2,048 mapas de 7 × 7 se promedia en un solo número. Ya no importa dónde estaba algo en la foto, solo qué tanto hay. Está aquí para que la cabeza reciba siempre una lista fija de 2,048 números, sin importar el tamaño de la foto.
  • Features · 2,048 números
    Lo que el backbone entrega: una descripción de la foto en 2,048 números. Es la frontera entre lo que se aprendió con ImageNet y lo nuevo de C01. Fotos parecidas dan listas parecidas; por eso también sirven como embedding.
  • Cabeza · 2,048 → 500
    Una sola capa densa: 2,048 × 500 pesos + 500 sesgos = 1,024,500 parámetros, el 4.2 % del modelo, pero solo el 0.025 % de las cuentas. Está aquí porque es la única parte que sabe de las categorías de C01: es la que se cambia con transfer learning (la original de ImageNet sacaba 1,000).
  • Softmax · → probabilidades
    Convierte los 500 logits en probabilidades que suman 100 % (el softmax). No tiene parámetros. Está aquí para que los números se puedan ordenar y leer como «qué tan seguro está».
  • Top-5 · Tenis 94 % …
    Se ordenan las 500 probabilidades y se le muestran a Ana las 5 más altas. Está aquí porque la app muestra 5 sugerencias: si la correcta está entre ellas, funcionó (top-5).

El atajo que permitió ir profundo

Durante años, apilar más capas parecía la forma obvia de mejorar. Pero a partir de cierta profundidad, una red más profunda acertaba menos, incluso en las fotos de entrenamiento. No era overfitting (que empeora la validación, no el entrenamiento): la red más profunda simplemente era más difícil de entrenar.

En 2015, Kaiming He y sus colegas de Microsoft Research propusieron una solución sencilla, la ResNet (residual network, red residual). Cada grupo de capas, un bloque, tiene un atajo, la conexión residual (skip connection): la entrada del bloque se le suma a su salida.

salida = bloque(x) + x

Un bloque residual. La entrada x entra por arriba y se divide en dos caminos: uno pasa por las capas del bloque (convolución, BatchNorm y ReLU) y calcula una corrección; el otro es un atajo que lleva x sin cambios. Abajo los dos se suman: la salida es bloque de x más x. UN BLOQUE RESIDUAL x CAPAS DEL BLOQUE convolución + BatchNorm + ReLU, tres veces calcula una corrección atajo: x pasa tal cual + salida = bloque(x) + x
Un bloque residual. La entrada x va por las capas del bloque y también por el atajo; al final, las dos se suman. (En la ResNet, la tercera ReLU va justo después de la suma.)

¿Por qué ayuda tanto? Dos intuiciones:

  • Cada bloque solo aprende una corrección. No tiene que reconstruir todo lo que ya traía la entrada, solo lo que hay que agregarle. Si un bloque no sirve, le basta aprender a sacar casi 0, y la entrada pasa por el atajo sin daño. Agregar bloques ya no puede empeorar tanto las cosas.
  • El aprendizaje llega hasta abajo. Al entrenar, la corrección del error viaja de la última capa hacia la primera (es la backpropagation). Con 50 capas apiladas, esa señal se debilita en el camino; los atajos le dan una vía directa.

Con esa idea, el equipo entrenó en ImageNet redes de hasta 152 capas y ganó la competencia de 2015.

La ResNet-50, en números

QuéCuánto
Capas con pesos50 en el camino principal: 49 convolucionales y la densa del final
Bloques residuales16, en cuatro etapas de 3, 4, 6 y 3 bloques
EntradaUna foto de 3 × 224 × 224; con el batch al frente, el tensor [1, 3, 224, 224]
Salida del backbone2,048 números
Parámetros, versión original (1,000 categorías de ImageNet)≈ 25.6 millones
Parámetros en C01 (500 categorías)≈ 24.5 millones
Pesos de la versión original en memoria≈ 102 MB en float32 · ≈ 51 MB en float16 (2 bytes por número)
Cuentas por foto≈ 4,100 millones de MACs (4.1 GMACs)
Campo receptivo de un número del último mapa427 × 427 píxeles (teórico)

BatchNorm

Hay dos tipos de capa que se portan distinto al entrenar y al responder. Si se te olvida decirle a la red en qué momento está, en producción da respuestas raras sin ningún error: uno de los bugs más clásicos de llevar un modelo a producción.

La primera vive dentro de cada bloque de la ResNet. Los números pueden crecer o achicarse mucho de capa en capa, y eso hace difícil entrenar. La BatchNorm (batch normalization, Ioffe y Szegedy, 2015) los acomoda: en cada canal les resta su promedio y los divide entre su desviación estándar, para que queden alrededor de 0 con una dispersión de más o menos 1. Después los escala y los mueve con dos parámetros propios, que también se entrenan.

La pregunta clave es: ¿el promedio de qué?

  • Al entrenar, el de las fotos del batch actual. Y de paso va guardando, a lo largo de todo el entrenamiento, un promedio de esos promedios y de esas desviaciones (un promedio móvil, que pesa más los batches recientes): sus running stats (estadísticas acumuladas).
  • Al responder, debe usar esas estadísticas acumuladas, que ya no cambian.

Dropout

El dropout (Srivastava, Hinton y otros, 2014) es una traba contra el overfitting. Al entrenar, en cada paso apaga al azar una fracción de las neuronas, por ejemplo la mitad, y multiplica las que quedan para compensar (con la mitad apagada, por 2). Así la red no puede depender de unas pocas neuronas que memorizaron algo: tiene que repartir lo que sabe. Al responder no apaga nada.

Si se queda en modo entrenamiento en producción, cada request apaga neuronas distintas: la misma foto, enviada dos veces, da dos respuestas diferentes.

El interruptor: model.eval()

En PyTorch, un modelo tiene un interruptor con dos posiciones: model.train() y model.eval(). En modo eval, la BatchNorm usa sus estadísticas acumuladas y el Dropout no apaga nada. Un modelo recién creado o cargado está en modo train, así que el servidor lo cambia una vez, al arrancar (ilustración: necesita PyTorch y un archivo de pesos):

python
import torch
from torchvision.models import resnet50

model = resnet50(num_classes=500)
model.load_state_dict(torch.load("pesos.pt", weights_only=True))
model.eval()                      # BatchNorm y Dropout en modo inferencia

with torch.inference_mode():      # y además: no guardes nada para aprender
    logits = model(x)

Lo traicionero de este bug es que nada truena: no hay error, la respuesta tiene el formato correcto y en tu notebook la accuracy se veía bien (porque ahí sí llamaste a model.eval()). Solo baja la calidad, en silencio. Por eso la Ronda insiste en la prueba de paridad: comparar, foto por foto, las respuestas del modelo que se sirve contra las del modelo que se evaluó.

07

Backbone, cabeza y transfer learning

Esencial

Backbone, head and transfer learning

Una CNN que clasifica tiene dos partes:

  • El backbone («columna vertebral»): todas las capas convolucionales. Recibe la foto y la convierte en una lista de números que describen lo que hay en ella, sus features. Al final del backbone de la ResNet-50, un pooling global promedia cada uno de sus 2,048 mapas de 7 × 7 en un solo número: salen 2,048 números por foto.
  • La cabeza (head): lo que convierte esas features en la respuesta de la tarea. En C01 es una sola capa densa que da un logit por categoría: 500 logits. Luego el softmax los vuelve probabilidades y se toman las 5 más altas.

Separarlo así sirve mucho en producción. El backbone es lo caro y lo que sabe «ver»; la cabeza es chica y es la que sabe de tus categorías. Además, esos 2,048 números sirven solos: fotos parecidas dan listas parecidas, útiles para buscar productos similares. Una lista así, donde lo parecido queda cerca, es un embedding, el tema de la siguiente lección.

¿De dónde sale la diferencia entre los 25.6 millones de parámetros de la ResNet-50 original y los 24.5 de la de C01? Solo de la cabeza. Con 1,000 categorías: 2,048 × 1,000 + 1,000 = 2,049,000. Con 500: 2,048 × 500 + 500 = 1,024,500. La diferencia es 1,024,500: 25,557,032 − 1,024,500 = 24,532,532. El backbone, que es casi todo, es idéntico.

Transfer learning y fine-tuning

Entrenar una ResNet-50 desde cero pide muchísimas fotos etiquetadas y mucho tiempo de GPU. Pero hay un atajo: alguien ya la entrenó. ImageNet es un dataset público de fotos etiquetadas; su versión más usada tiene ≈ 1.28 millones de fotos de entrenamiento en 1,000 categorías (perros, coches, frutas, instrumentos…). Un modelo entrenado con ImageNet ya aprendió en su backbone lo que sirve para casi cualquier foto: bordes, texturas, formas, partes de objetos. Y esos pesos se pueden descargar.

Usar lo que un modelo aprendió en una tarea para resolver otra se llama transfer learning (aprendizaje por transferencia). En C01 se hace así:

  1. 1

    Partir de un modelo preentrenado

    Se carga la ResNet-50 con los pesos de ImageNet. Su backbone ya sabe «ver».

  2. 2

    Cambiar la cabeza

    La cabeza original saca 1,000 logits, uno por cada categoría de ImageNet, que no son las del marketplace. Se quita y se pone una nueva de 2,048 → 500, con pesos al azar.

  3. 3

    Seguir entrenando con las fotos propias

    Se entrena con las fotos de C01, con un learning rate chico para no destruir lo que el backbone ya sabía. Eso es el fine-tuning (ajuste fino). En la Ronda, el de C01 usa un learning rate de 0.0003, 8 épocas y batches de 64 fotos, y cabe en una sola GPU en unas horas.

En código, los dos primeros pasos son dos líneas (otra ilustración que necesita PyTorch):

python
import torch
from torchvision.models import resnet50, ResNet50_Weights

model = resnet50(weights=ResNet50_Weights.IMAGENET1K_V2)   # backbone que ya vio ImageNet
model.fc = torch.nn.Linear(2048, 500)                       # cabeza nueva: 500 categorías

El fine-tuning se puede hacer de dos formas, y se pueden combinar: congelar el backbone (no mover sus pesos) y entrenar solo la cabeza, que es rápido y sirve con pocos datos; o entrenar todo con learning rate chico, que es más lento y suele dar mejor resultado cuando hay muchas fotos, como en C01. Congelado, el entrenamiento solo mueve 1,024,500 de los 24,532,532 parámetros: el 4.2 %.

¿Por qué C01 empieza así? Porque con un modelo preentrenado hacen falta muchas menos fotos y horas de GPU para llegar a una buena top-5. Y como C01 se reentrena cada mes, cada reentrenamiento parte de pesos que ya saben ver.

08

Vision Transformers: la foto como una frase de parches

Extra

Vision Transformers: the photo as a sentence of patches

Las CNNs no son la única forma de ver fotos. En 2020, un equipo de Google (Dosovitskiy y otros) tomó el transformer, la arquitectura de los LLMs (los modelos de lenguaje de los chats), y le dio una foto como si fuera una frase. Lo llamaron ViT (Vision Transformer).

Un transformer recibe una lista de tokens (en un LLM, pedazos de texto: palabras o partes de palabras), cada uno convertido en un vector (una lista de números). El ViT parte la foto en cuadritos de 16 × 16 píxeles, los parches (patches), y cada parche se vuelve un token.

De la foto a los tokens de un ViT-B/16La cuenta
Parches por lado
224 ÷ 16
14
Parches en total
14 × 14
196
Números por parche16 × 16 píxeles × 3 colores
16 × 16 × 3
768
Parámetros para volver vector un parcheuna capa densa de 768 → 768
768 × 768 + 768
590,592
Tokens que entranmás uno extra, [CLS], que al final resume la foto
196 + 1
197
Pares que compara la atención en cada bloque
197 × 197
38,809
Resultado
197 tokens de 768 números cada uno. «B/16» quiere decir tamaño Base, con parches de 16 píxeles.
Cómo lee una foto un ViT-B/16. La foto de 224 por 224 píxeles se parte en una cuadrícula de 14 por 14, 196 parches. Un parche marcado en amarillo se amplía: 16 por 16 píxeles por 3 colores, 768 números, que una capa densa de 768 a 768 convierte en un token. Abajo, la fila de tokens: CLS, 1, 2, 3 y así hasta 196, en total 197 tokens de 768 números, entra a un transformer de 12 bloques donde cada parche mira a todos. La respuesta sale del token CLS. UN VIT-B/16 LEE LA FOTO EN PARCHES 224 × 224 píxeles 14 × 14 = 196 parches 16 × 16 píxeles × 3 = 768 números densa 768 → 768 UN TOKEN 197 TOKENS DE 768 NÚMEROS CLS 1 2 3 … 196 Transformer · 12 bloques CADA PARCHE MIRA A TODOS la respuesta sale del token [CLS]
Un ViT-B/16 lee la foto de 224 × 224 como 14 × 14 = 196 parches. Cada parche, de 768 números, se vuelve un token; con el token [CLS] entran 197 al transformer.

Después, el ViT es un transformer como el de los LLMs: 12 bloques, cada uno con atención (cada parche mira a todos los demás y decide cuáles le importan; la ves en la lección de transformers y LLMs) y con un MLP de dos capas que procesa cada token por separado. Dos detalles:

  • La posición se suma aparte. Al convertir los parches en una lista, se pierde dónde estaba cada uno. Por eso a cada token se le suma un vector aprendido que dice «soy el parche 37»: un embedding posicional.
  • La respuesta sale del token [CLS]. Al final, una cabeza densa convierte su vector de 768 números en los logits, como la de la ResNet.
ResNet-50ViT-B/16
Parámetros≈ 25.6 millones≈ 86 millones
MACs por foto de 224 × 224≈ 4,100 millones≈ 17,600 millones
Qué mira al principiocada filtro de la primera capa, 7 × 7 píxelescada parche, de 16 × 16; desde el primer bloque, todos los parches a la vez
Lo que trae de fábricaver de cerca y el mismo filtro en todas partescasi nada: lo tiene que aprender
Cuántas fotos necesitale basta ImageNetbrilla con preentrenamientos de decenas o cientos de millones de fotos

La CNN trae dos ideas metidas en su diseño; el ViT tiene que aprenderlas de los datos. Con pocos datos eso es una desventaja: en el artículo original, entrenado solo con ImageNet, el ViT quedaba unos puntos por debajo de una ResNet de tamaño parecido; preentrenado con muchísimas más fotos (14 millones en un caso, 300 millones en otro), la superaba.

¿Y para C01? La Ronda, en M04, cuenta el ViT-B/16 entre los modelos que hay que saber medir: ≈ 172 MB en float16. Para sugerir 500 categorías a ≈ 2.5 millones de publicaciones al día, la ResNet-50 sigue siendo una elección sólida, con 3.5 veces menos parámetros y unas 4 veces menos cuentas por foto. Donde los ViT dominan es en los modelos que ponen fotos y textos en el mismo espacio (multimodales), que verás en la lección de embeddings.

09

Errores comunes

Esencial

Common mistakes

1. Olvidar model.eval() en el servidor

La BatchNorm normaliza con las estadísticas del batch y el Dropout, si lo hay, apaga neuronas al azar. La misma foto da respuestas distintas según con qué otras llegó, y nada truena.

Cómo evitarlo: que la función que carga el modelo termine en model.eval(), una prueba que revise que model.training sea False y la prueba de paridad de la Ronda (M08).

2. Una normalización distinta a la del entrenamiento

Si en el servidor olvidas dividir entre 255, el rojo de un píxel que vale 236 entra como (236 − 0.485) ÷ 0.229 ≈ 1,028 en vez de (0.925 − 0.485) ÷ 0.229 ≈ 1.92. Si cargas la foto en orden azul-verde-rojo (BGR), los canales se cruzan. El modelo no truena: ve una foto «rara» y se equivoca más, en silencio.

Cómo evitarlo: el mismo código de preprocesamiento al entrenar y al servir (lo contrario es el training-serving skew) y una prueba que compare, número por número, el tensor del servidor con el de la evaluación.

3. Confundir el padding y el redondeo

«Padding 1 deja el mapa igual» solo es cierto con filtro de 3 × 3 y stride 1. Y con stride 2 la salida no siempre es la mitad exacta: una entrada de 56 sale de 28, pero una de 57 sale de (57 + 2 − 3) ÷ 2 + 1 = 29, no de 28.5. Un error de uno en el tamaño basta para que dos ramas que se suman (como el atajo de una ResNet) no cuadren.

Cómo evitarlo: hacer la cuenta con la fórmula antes de escribir la capa y, en código, pasar un tensor de prueba e imprimir su forma (shape) después de cada capa.

4. Contar mal los parámetros

Los resbalones típicos: olvidar los canales de entrada (un filtro de 3 × 3 sobre 64 canales tiene 576 pesos, no 9); poner sesgos donde no hay (las convoluciones de la ResNet no llevan); contar como parámetros las estadísticas acumuladas de la BatchNorm (se guardan con el modelo, pero el gradiente no las ajusta); o confundir parámetros (memoria) con MACs (cálculo).

Cómo evitarlo: contar con las fórmulas y compararlo con lo que dice PyTorch, sum(p.numel() for p in model.parameters()). Para la ResNet-50 debe dar 25,557,032, o 24,532,532 con 500 categorías.

5. Cargar pesos con la cabeza equivocada

Los pesos de un modelo de 1,000 categorías no caben en uno de 500: PyTorch truena con un error de size mismatch en la capa final. Para quitárselo de encima, lo común es borrar la capa final de los pesos guardados y cargar el resto con strict=False, que deja pasar sin avisar las capas cuyos nombres no coinciden (un tamaño distinto sigue tronando). El peligro es que no avisa: si los nombres no coinciden (por ejemplo, porque al guardar se les pegó el prefijo module.), el modelo se queda con sus pesos al azar y responde basura sin un solo error.

Cómo evitarlo: crear el modelo con el número correcto de categorías antes de cargar; si usas strict=False, revisar la lista de capas que no se cargaron, que devuelve la misma función; y evaluar con el golden set después de cargar.

6. Achicar la foto y perder lo chico

El resize del preprocesamiento es parte del modelo, aunque viva en otro archivo. Si un defecto mide 3 píxeles y achicas la foto a menos de la mitad, ya no está cuando la red la ve, y ninguna capa lo recupera.

Cómo evitarlo: antes de elegir el tamaño de entrada, calcula cuántos píxeles mide lo más chico que hay que ver. Si son pocos, no achiques: corta la imagen en tiles (cuadros que la red procesa por separado) a resolución completa.

10

En la vida real

Extra

In real life

Un backbone, tres cabezas

El backbone no sabe de categorías: solo describe la foto. Por eso sirve para tareas distintas, cambiando solo la cabeza:

  • Clasificación (C01): promedia cada mapa en un número y una capa densa da un logit por categoría. Ya no importa dónde estaba algo, solo qué tanto hay.
  • Detección (C02): no puede promediar, porque necesita saber dónde. Su cabeza mira cada posición de los mapas y propone ahí una caja (4 números: dónde está y de qué tamaño) con un puntaje por clase.
  • Segmentación (C04): quiere una respuesta por píxel, así que su cabeza es un decoder, una red que agranda los mapas de regreso al tamaño de la foto. A la parte que achica, el backbone, en este contexto se le dice encoder.
Un backbone, tres cabezas · Un mismo backbone y tres cabezas. Elige un recorrido para seguir una tarea.
  • Foto · ya preprocesada
    La imagen ya convertida en tensor: 224 × 224 en C01, 640 × 640 en el detector de C02, tiles de 512 × 512 en C04. Las convoluciones aceptan tamaños distintos, así que el tipo de backbone puede ser el mismo.
  • Backbone · convoluciones
    Todas las capas convolucionales, casi siempre preentrenadas con ImageNet. Es lo caro: en la ResNet-50, el 99.97 % de las MACs. Es la parte que se reutiliza de una tarea a otra (transfer learning).
  • Mapas · las features
    Lo que entrega el backbone: mapas de activaciones. En C01, 2,048 mapas de 7 × 7. Detección y segmentación toman también mapas de capas anteriores, más grandes, porque necesitan saber dónde está cada cosa.
  • Clasificación · pooling + densa
    Promedia cada mapa en un número (2,048) y una capa densa da un logit por categoría: 2,048 × 500 + 500 = 1,024,500 parámetros. Promediar borra el dónde: aquí solo importa el qué.
  • Detección · una caja por posición
    En cada posición de los mapas propone una caja (4 números: dónde está y de qué tamaño) y un puntaje por clase. Un detector como YOLOv8 a 640 × 640 lo hace en 80 × 80 + 40 × 40 + 20 × 20 = 8,400 posiciones.
  • Segmentación · decoder que agranda
    Un decoder agranda los mapas de regreso al tamaño de la entrada y da una respuesta por píxel. Como en la U-Net, recibe atajos desde el backbone (ahí llamado encoder) para no perder los bordes finos.
  • Top-5 · C01 · 500 categorías
    El softmax vuelve los 500 logits probabilidades y Ana ve las 5 más altas (top-5).
  • Cajas · C02 · tras el NMS
    Casi todas las candidatas se tiran por puntaje bajo, y varias marcan el mismo objeto. El NMS (non-maximum suppression) deja la de puntaje más alto y borra las que se enciman mucho con ella. Quedan unas cuantas cajas, cada una con su clase.
  • Máscara · C04 · una por píxel
    Una probabilidad por píxel: en un tile de 512 × 512 son 262,144 respuestas. En C04, la probabilidad de que cada píxel sea tumor.

C01: la línea del caso, leída

El caso C01 resume su modelo en una frase: «ResNet-50 con una capa final de 500 clases: 24.5 M parámetros (…) y ≈ 4.1 GMACs a 224×224». Ya sabes leerla: memoria, cálculo, cabeza y preprocesamiento.

La ResNet-50 se arma con 16 bloques (grupos de tres convoluciones) repartidos en cuatro etapas. Dentro de una etapa los mapas no cambian de tamaño, y a partir de la segunda, cada etapa los achica a la mitad de lado. Con la fórmula del lado de salida se puede contar la red capa por capa. En Python, la primera capa, el max pooling y una convolución de 3 × 3 de cada etapa:

python
def lado(n, k, s, p):
    return (n + 2 * p - k) // s + 1    # // divide y redondea hacia abajo

def conv(nombre, n, c_in, c_out, k, s, p):
    m = lado(n, k, s, p)
    params = k * k * c_in * c_out          # sin sesgo, como en la ResNet
    macs = m * m * c_out * k * k * c_in    # posiciones × filtros × pesos por filtro
    print(f"{nombre:<24}{n:>4} -> {m:<4}{params:>12,}{macs:>15,}")

print(f"{'capa':<24}{'lado':>4}{'':8}{'parámetros':>12}{'MACs':>15}")
conv("primera, 7x7 stride 2", 224, 3, 64, 7, 2, 3)
print(f"{'max pooling 3x3 s2':<24}{112:>4} -> {lado(112, 3, 2, 1)}")
conv("3x3 de la etapa 1", 56, 64, 64, 3, 1, 1)
conv("3x3 de la etapa 2", 28, 128, 128, 3, 1, 1)
conv("3x3 de la etapa 3", 14, 256, 256, 3, 1, 1)
conv("3x3 de la etapa 4", 7, 512, 512, 3, 1, 1)
Salida
capa                    lado          parámetros           MACs
primera, 7x7 stride 2    224 -> 112        9,408    118,013,952
max pooling 3x3 s2       112 -> 56
3x3 de la etapa 1         56 -> 56        36,864    115,605,504
3x3 de la etapa 2         28 -> 28       147,456    115,605,504
3x3 de la etapa 3         14 -> 14       589,824    115,605,504
3x3 de la etapa 4          7 -> 7      2,359,296    115,605,504

Fíjate en las últimas cuatro filas. Cada vez que la ResNet achica el mapa a la mitad de lado, duplica los canales: las posiciones bajan 4 veces y los filtros y los pesos por filtro suben 2 veces cada uno. Las MACs quedan idénticas, pero los parámetros se multiplican por 4 en cada etapa: el trabajo se reparte parejo y los parámetros se amontonan al final.

¿Dónde viven los parámetros y dónde el trabajo? Contando capa por capa toda la ResNet-50 de C01, con su capa final de 500:

ParteMapa que saleParámetrosMACs por foto
Primera capa y max pooling64 × 56 × 569,536 (< 0.1 %)118 millones (2.9 %)
Etapa 1 · 3 bloques256 × 56 × 560.2 millones (0.9 %)668 millones (16.3 %)
Etapa 2 · 4 bloques512 × 28 × 281.2 millones (5.0 %)1,028 millones (25.1 %)
Etapa 3 · 6 bloques1,024 × 14 × 147.1 millones (28.9 %)1,464 millones (35.8 %)
Etapa 4 · 3 bloques2,048 × 7 × 715.0 millones (61.0 %)809 millones (19.8 %)
Capa final (500)5001.0 millones (4.2 %)1 millón (0.025 %)
Total24.5 millones≈ 4,088 millones

La etapa 4 guarda el 61 % de los parámetros, pero hace menos de una quinta parte del trabajo; la etapa 1, al revés, casi no tiene parámetros y hace el 16 % del trabajo, porque sus mapas son grandes. Para la memoria (M04) mandan las últimas etapas; el cálculo (M03) se reparte entre todas.

Y el cálculo cabe de sobra en una GPU. Cada MAC son dos operaciones, así que una foto son 8.2 GFLOPs (FLOPs: operaciones con números decimales). La Ronda, en M03, lo usa como chequeo de cordura: una GPU T4 hace a lo mucho ≈ 65 × 10¹² operaciones por segundo en float16, así que nunca pasará de 65 × 10¹² ÷ 8.2 × 10⁹ ≈ 7,900 fotos por segundo. Lo que se mide de verdad es mucho menos (la Ronda supone ≈ 1,200 fotos por segundo para C01): el techo dice qué es imposible, no qué vas a obtener.

El presupuesto de C01 es un p99 ≤ 200 ms del lado del servidor: 99 de cada 100 respuestas en menos de 200 ms. La Ronda estima ≈ 3–6 ms de cómputo en la GPU T4 (la mediana, con batches de 1 a 8 fotos), así que el modelo es una parte chica de ese tiempo. Si el servicio no contesta en 300 ms, la app le muestra a Ana el selector manual de categorías.

C02: detectar en video, una caja por posición

C02 vigila zonas restringidas con 1,000 cámaras en 25 centros de distribución, con un detector ligero tipo YOLO (≈ 10–30 millones de parámetros) que recibe cada frame a 640 × 640 y busca personas y vehículos.

Su cabeza no promedia, porque necesita saber dónde. En detectores como YOLOv8 mira tres mapas, con saltos de 8, 16 y 32 píxeles: a 640 son 80 × 80 + 40 × 40 + 20 × 20 = 8,400 posiciones, y en cada una propone una caja y un puntaje por clase. Las de puntaje bajo se tiran, y de las que marcan el mismo objeto, el NMS (non-maximum suppression) deja la de puntaje más alto y borra las que se enciman mucho con ella (lo mide el IoU).

¿Por qué tres tamaños? Por el campo receptivo: el mapa de salto 8 tiene celdas chicas, buenas para una persona lejana; el de salto 32, un campo enorme para un camión que llena el cuadro. Y como 640 × 640 son 8.2 veces los píxeles de 224 × 224, la Ronda (M04) nota que en detección lo que más crece con la resolución son las activaciones.

C03: inspección en la línea, defectos de 3 píxeles

C03 revisa soportes metálicos en una planta de autopartes de Nuevo León, con una cámara de 2,448 × 2,048 píxeles por línea, y tiene que encontrar fisuras de 0.2 mm. Aquí manda la aritmética de esta lección:

La fisura de C03, en píxelesLa cuenta
Resolución sobre la piezasupuesto de la Ronda: 150 mm de campo de visión
150 mm ÷ 2,448 px
≈ 0.061 mm/px
Fisura de 0.2 mm
0.2 ÷ 0.061
≈ 3.3 px
Si achicas la imagen a 1,024 de anchola fisura casi desaparece
0.2 ÷ (150 ÷ 1,024)
≈ 1.4 px
Tiles de 512 × 512 sin achicarredondeando hacia arriba
2,448 ÷ 512 → 5 · 2,048 ÷ 512 → 4
5 × 4 = 20
Último mapa de un tilebackbone con salto 32: 512 ÷ 32 = 16 por lado
16 × 16
256 celdas
La fisura dentro de una celdaqué parte de su ancho ocupa
3.3 ÷ 32
≈ 10 %
Resultado
La fisura apenas ocupa una de 256 celdas. Si la cabeza promediara el mapa entero, como en C01, su señal quedaría diluida 256 veces.

Por eso la Ronda no achica la imagen: la procesa en 20 tiles, como un batch de tamaño fijo. Si 3 píxeles resultan pocos, la solución es óptica (un campo de visión más chico o más resolución), no un modelo más grande. Y para que lo chico no se diluya, muchos métodos de inspección usan mapas de salto 8 o 16 y califican cada posición: la pieza es mala si alguna posición es mala (el máximo, no el promedio).

C03 usa también la otra idea de esta lección: un solo engine (el modelo ya convertido para la GPU) con un backbone compartido y dos cabezas, una con un puntaje de anomalía y otra con un puntaje por tipo de defecto. Dos backbones casi duplicarían el tiempo, y la inferencia tiene que caber en ≤ 120 ms en el Jetson, la computadora con GPU que va junto a cada línea.

C04: segmentación, un decoder que agranda

C04 marca tumor en laminillas de patología escaneadas a tan alta resolución que se procesan en tiles de 512 × 512. Un modelo tipo U-Net, de ≈ 30 millones de parámetros, da para cada píxel la probabilidad de que sea tumor: 512 × 512 = 262,144 respuestas por tile, en vez de 500 por foto.

La U-Net (Ronneberger y otros, 2015) se diseñó para imágenes médicas. Es un encoder-decoder: el encoder es un backbone que achica el mapa (por ejemplo, 512 → 256 → 128 → 64 → 32 de lado) y el decoder hace el camino de regreso. El mapa de 32 × 32 sabe qué hay, pero ya no dónde están los bordes; por eso, en cada tamaño, el decoder recibe por un atajo largo el mapa del encoder de ese tamaño, que los conserva. Dibujada, parece una U.

Los tiles avanzan de 448 en 448 píxeles (un stride, otra vez), así que se enciman 64: cerca de la orilla de un tile la red ve ceros de padding en vez de tejido, y el solape evita depender de esas orillas.

Fuera de ML: los filtros de tu editor de fotos

El «desenfocar» más simple de un editor de fotos es una convolución con un filtro de 3 × 3 cuyos 9 pesos valen 1/9: cada píxel se vuelve el promedio de sus vecinos. «Enfocar» usa un 5 en el centro y −1 arriba, abajo y a los lados. Y el detector de bordes del ejemplo (columnas de 1, 0 y −1) es el filtro de Prewitt, de los años 70. La diferencia con una CNN es quién elige los pesos: ahí una persona; en la red, el entrenamiento.

11

Ejercicios

Esencial

Exercises

Resuélvelos con lápiz antes de abrir la solución; los de tamaños y parámetros se pueden comprobar con las calculadoras.

  1. 1Fácil

    Una neurona tiene entradas 1, 2 y 3, pesos 0.5, −1 y 1, y sesgo 0.5. ¿Qué sale después de la ReLU? ¿Y si el sesgo fuera −3?

    Ver la solución paso a paso
    • Productos: 1 × 0.5 = 0.5, 2 × (−1) = −2 y 3 × 1 = 3.
    • Suma con el sesgo: 0.5 − 2 + 3 + 0.5 = 2. No es negativo: la ReLU deja salir 2.
    • Con sesgo −3: 0.5 − 2 + 3 − 3 = −1.5, negativo: sale 0. El sesgo decide qué tan fácil se activa la neurona.
  2. 2Fácil

    Un MLP para dígitos de 28 × 28 en gris tiene 784 entradas, una capa oculta de 128 neuronas y 10 salidas. ¿Cuántos parámetros tiene y cuántas MACs hace por imagen?

    Ver la solución paso a paso
    • Capa oculta: 784 × 128 + 128 = 100,352 + 128 = 100,480.
    • Capa de salida: 128 × 10 + 10 = 1,290.
    • Parámetros: 100,480 + 1,290 = 101,770.
    • MACs: una por peso, 784 × 128 + 128 × 10 = 100,352 + 1,280 = 101,632 por imagen.
  3. 3Fácil

    Una entrada de 32 × 32 pasa por una convolución de 5 × 5 sin padding y con stride 1. ¿De qué tamaño sale? ¿Qué padding necesitas para que salga de 32 × 32?

    Ver la solución paso a paso
    • Sin padding: (32 + 0 − 5) ÷ 1 + 1 = 28, como en la primera capa de LeNet-5, la CNN de dígitos de 1998.
    • Para 32: (32 + 2p − 5) + 1 = 32, así que 2p = 4 y p = 2: la regla (k − 1) ÷ 2.
  4. 4Fácil

    Un max pooling de 2 × 2 con stride 2 recibe 256 mapas de 56 × 56. ¿Qué sale y cuántos parámetros tiene?

    Ver la solución paso a paso
    • Lado: (56 + 0 − 2) ÷ 2 + 1 = 28. Salen 256 mapas de 28 × 28: el pooling actúa en cada mapa por separado y no cambia la cantidad de canales.
    • Números: de 802,816 a 200,704, cuatro veces menos.
    • Parámetros: 0. Solo toma el máximo.
  5. 5Medio

    Una convolución de 3 × 3 recibe 64 canales, tiene 128 filtros, no lleva sesgo y su salida es de 28 × 28. ¿Cuántos parámetros tiene, cuántas MACs hace y cuántas veces se usa cada peso?

    Ver la solución paso a paso
    • Pesos por filtro: 3 × 3 × 64 = 576. Parámetros: 576 × 128 = 73,728.
    • MACs: 28 × 28 posiciones × 128 filtros × 576 = 784 × 128 × 576 = 57,802,752, unos 58 millones.
    • Cada peso se usa una vez por posición: 784 veces, y por eso hay 784 veces más MACs que parámetros.
  6. 6Medio

    Alguien olvida el center crop y le pasa a la ResNet-50 fotos de 256 × 256. ¿De qué tamaño sale la primera capa (7 × 7, padding 3, stride 2) y después el max pooling (3 × 3, padding 1, stride 2)? ¿De qué tamaño queda el último mapa? ¿Truena el modelo?

    Ver la solución paso a paso
    • Primera capa: (256 + 6 − 7) ÷ 2 = 127.5, que baja a 127; más 1: 128.
    • Max pooling: (128 + 2 − 3) ÷ 2 = 63.5, que baja a 63; más 1: 64.
    • Último mapa: con salto 32, 256 ÷ 32 = 8: mapas de 8 × 8 en vez de 7 × 7.
    • No truena: el pooling global promedia cada mapa, sea de 7 × 7 o de 8 × 8, y la cabeza recibe siempre 2,048 números. Por eso es peligroso: la respuesta cambia un poco y nada avisa, un caso de training-serving skew.
  7. 7Medio

    (Usa la sección extra del campo receptivo.) Cuatro capas de 3 × 3: la segunda tiene stride 2 y las demás stride 1. ¿Cuál es el campo receptivo de una neurona de la cuarta capa? ¿Y si las cuatro tuvieran stride 1?

    Ver la solución paso a paso
    • Empieza con r = 1 y j = 1. Capa 1 (k = 3, s = 1): r = 1 + 2 × 1 = 3, j = 1.
    • Capa 2 (s = 2): r = 3 + 2 × 1 = 5, y el salto pasa a j = 2.
    • Capa 3: r = 5 + 2 × 2 = 9. Capa 4: r = 9 + 2 × 2 = 13.
    • Todas con stride 1: 1 + 4 × 2 = 9. El stride de en medio le ganó 4 píxeles al campo.
  8. 8Reto

    (Usa el salto de la sección extra del campo receptivo y el caso C03.) Una cámara de inspección cubre 300 mm con 2,448 píxeles y hay que ver defectos de 0.3 mm. (a) ¿Cuántos píxeles mide un defecto? (b) Si la red recibe tiles de 512 y su backbone tiene salto 32, ¿qué fracción del ancho de una celda del último mapa ocupa el defecto? (c) ¿Qué cambiarías para verlo mejor?

    Ver la solución paso a paso
    • (a) 300 ÷ 2,448 ≈ 0.1225 mm por píxel, así que 0.3 ÷ 0.1225 ≈ 2.45 píxeles. Menos que la fisura de C03.
    • (b) 2.45 ÷ 32 ≈ 7.7 % del ancho de una celda de 32 × 32. Y el tile de 512 tiene 16 × 16 = 256 celdas.
    • (c) Primero la óptica: un campo de visión más chico (por ejemplo, dos cámaras de 150 mm) duplica los píxeles por defecto. Después, no achicar la imagen; usar mapas de salto 8, donde el defecto ocupa ≈ 31 % del ancho de una celda; y calificar cada posición y tomar el máximo en vez de promediar.
  9. 9Reto

    La capa final de la ResNet-50 de C01 guarda ≈ 4 % de los parámetros pero hace ≈ 0.025 % de las MACs; la primera capa tiene 9,408 parámetros pero hace 118 millones de MACs. Explica las dos cosas con números: ¿cuántas veces se usa cada peso en cada capa?

    Ver la solución paso a paso
    • Capa final, densa: cada peso se usa una vez por foto, así que sus MACs (1,024,000) son casi sus parámetros (1,024,500); contra ≈ 4,100 millones del modelo, son ≈ 0.025 %.
    • Primera capa, convolucional: cada peso se usa en cada posición de la salida, 112 × 112 = 12,544 veces; 9,408 × 12,544 = 118,013,952 MACs.
    • La conclusión: los parámetros dicen cuánta memoria pide un modelo y las MACs cuánto cálculo. En una CNN no van de la mano, porque cada peso se reutiliza miles de veces.
12

Lo que sigue

Esencial

What comes next

En la Ronda:

  • M03 · Latencia y capacidad hace el chequeo de cordura de esta lección: 8.2 GFLOPs por foto contra ≈ 65 TFLOPS de una T4, un techo de ≈ 7,900 fotos por segundo.
  • M04 · Hardware para inferencia arranca con la cuenta de los parámetros: 25.6 M × 4 bytes ≈ 102 MB en float32 (la Ronda le dice FP32) y ≈ 51 MB en float16 (FP16); para C01, ≈ 49 MB en float16. Ahí verás también por qué una CNN suele estar limitada por el cálculo, y cuánto pesan YOLOv8m (≈ 25.9 M parámetros) y ViT-B/16 (≈ 86 M).
  • M07 · Servidores de modelos carga el modelo una vez al arrancar, con model.eval() y torch.inference_mode(): sin lo primero, la BatchNorm usa las estadísticas del batch.
  • M08 · Optimización muestra que algunas herramientas que capturan el modelo para acelerarlo (torch.export, torch.compile) conservan la BatchNorm en modo train si olvidaste eval(), mientras que la exportación a ONNX (un formato estándar para guardar el modelo y correrlo fuera de PyTorch) te protege; y que al convertir el modelo a un formato rápido la BatchNorm se «pliega» dentro de la convolución anterior.
  • Los casos. C01 da el modelo por hecho («ResNet-50 con una capa final de 500 clases»); C02 usa un detector a 640 × 640 con NMS; C03, 20 tiles con un backbone y dos cabezas; C04, una U-Net sobre tiles que se enciman. Ahora sabes qué quiere decir cada palabra.

En el Dojo: la estación 7, Empaquetado, usa la cuenta de esta lección, 25.6 M parámetros × 2 bytes ≈ 51 MB, para decidir que el modelo puede ir dentro del paquete del servidor (la imagen de Docker). Cuando abran las estaciones 3 (Entrenamiento) y 5 (Export, engine y paridad), ahí vas a practicar el fine-tuning y la prueba de paridad con model.eval().

En Sensei: la siguiente lección, «Embeddings: el significado como coordenadas», usa los 2,048 números del backbone. «Transformers y LLMs» explica la atención que usa el ViT. Más adelante, «Cómo guarda números una computadora» explica float32 y float16, y «Matrices, FLOPs y qué tan rápido calcula una GPU» convierte las MACs de esta lección en milisegundos.

13

Palabras que vas a oír

Esencial

Words you will hear

Estos son los conceptos que presentó esta lección. Cada uno tiene su tarjeta con la definición completa.

Neuronaneuron · unitLa pieza más chica de una red neuronal: multiplica cada entrada por un peso, suma todo más un sesgo y pasa el resultado por una activación.Más

Sus pesos y su sesgo son parámetros: los ajusta el entrenamiento. Una neurona con 3 entradas tiene 4 parámetros. Se juntan muchas en una capa. El nombre viene de las neuronas del cerebro, pero es solo una multiplicación y una suma.

Ejemplo. Entradas 0.5, 0.8 y 0.2; pesos 2, −1 y 3; sesgo 0.1: 1.0 − 0.8 + 0.6 + 0.1 = 0.9, y la ReLU deja pasar 0.9.

Ver en el glosario →

Activaciónactivation functionLa función sencilla que una neurona aplica al final de su suma. Sin ella, apilar capas no serviría de nada: todo seguiría siendo una recta.Más

Una capa sin activación solo multiplica y suma, y dos así juntas equivalen a una sola. La activación «dobla» la recta, y con muchas neuronas la red puede formar curvas tan complicadas como haga falta. La más usada es la ReLU; antes se usaban activaciones suaves, como la sigmoide, que aplasta el número entre 0 y 1. También se le dice «activación» al número que sale de una neurona.

Ejemplo. Sin activación, y = 3x + 1 seguida de z = 2y − 1 da z = 6x + 1: otra recta. Con una ReLU en medio, la red se dobla en el 0.

Ver en el glosario →

ReLUrectified linear unitLa activación más usada: si el número es negativo, sale 0; si no, sale igual. ReLU(−0.3) = 0 y ReLU(0.9) = 0.9.Más

Es barata de calcular y funciona muy bien en redes profundas; se impuso en la década de 2010. Cuando una neurona saca 0 se dice que «no se activó». Como apaga más o menos la mitad de los números, la regla de inicialización de He usa un 2 para compensar.

Ejemplo. En la red que calcula el XOR, h₂ = ReLU(x₁ + x₂ − 1) vale 0 en tres casos y 1 solo cuando las dos entradas valen 1.

Ver en el glosario →

PerceptrónperceptronUna de las primeras neuronas artificiales que aprendían solas (Frank Rosenblatt, 1958): suma sus entradas con pesos y responde 1 si la suma pasa de 0. Solo puede separar lo que se separa con una recta.Más

Su regla de aprendizaje es corregirse solo cuando se equivoca: si dijo 0 y era 1, le suma cada entrada a su peso; si dijo 1 y era 0, se la resta. Aprende el AND en unas cuantas vueltas, pero nunca el XOR, porque su frontera es una recta y los casos del XOR no se separan con una. Minsky y Papert convirtieron ese límite en teorema en 1969; se resolvió con capas ocultas, el MLP.

Ejemplo. Con w₁ = 2, w₂ = 1 y b = −2 calcula el AND: solo la entrada (1, 1) da una suma positiva, 2 + 1 − 2 = 1.

Ver en el glosario →

CapalayerUn grupo de neuronas que reciben las mismas entradas, cada una con sus propios pesos. Lo que sale de una capa entra a la siguiente.Más

En una capa densa (dense, fully connected o linear) cada neurona ve todas las entradas: tiene entradas × salidas pesos más un sesgo por salida, y hace entradas × salidas multiplicaciones-sumas por ejemplo. En una capa convolucional cada filtro ve solo un pedacito (convolución). Una red de capas densas es un MLP.

Ejemplo. Una capa densa de 2,048 entradas y 500 salidas tiene 2,048 × 500 + 500 = 1,024,500 parámetros: es la cabeza de la ResNet-50 de C01.

Ver en el glosario →

Red neuronalneural networkUn modelo hecho de capas de neuronas, una tras otra. Por dentro solo multiplica, suma y aplica activaciones, capa por capa, millones de veces.Más

Sus parámetros son todos sus pesos y sesgos. Responder es hacer un forward pass; aprender es ajustar los parámetros con backpropagation y descenso de gradiente. Cada capa acomoda los datos para que a la siguiente le sea más fácil.

Ejemplo. Una red de juguete de 2 entradas, 3 neuronas y 2 salidas tiene (2 × 3 + 3) + (3 × 2 + 2) = 17 parámetros.

Ver en el glosario →

MLPmultilayer perceptron · perceptrón multicapaUna red neuronal hecha solo de capas densas, con activaciones entre ellas: cada neurona de una capa ve todas las salidas de la anterior.Más

Las capas de en medio se llaman ocultas. Con una sola capa oculta ya resuelve problemas que una neurona sola no puede, como el XOR. Cada capa tiene entradas × salidas + salidas parámetros. Sobre fotos desperdicia parámetros (cada píxel lleva su propio peso), por eso para imágenes se usan CNNs; pero dentro de cada bloque de un transformer hay un MLP de dos capas.

Ejemplo. 784 entradas (un dígito de 28 × 28), 128 ocultas y 10 salidas: (784 × 128 + 128) + (128 × 10 + 10) = 101,770 parámetros.

Ver en el glosario →

Deep learningdeep learning · aprendizaje profundoUsar redes neuronales con muchas capas. «Profundo» se refiere a la cantidad de capas, no a nada filosófico.Más

Cada capa trabaja sobre lo que encontró la anterior, así que con muchas capas la red combina cosas simples (bordes) en cosas complicadas (un tenis). No hay un número oficial de capas a partir del cual algo es «deep». Despegó en 2012, cuando se juntaron muchos datos (ImageNet), GPUs y trucos para entrenar redes profundas.

Ejemplo. La ResNet-50 tiene 50 capas con pesos; la red de juguete de la lección, 2. Las dos son redes neuronales, pero solo la primera se llamaría profunda.

Ver en el glosario →

Inicializacióninitialization · weight initLos valores con que empiezan los pesos de una red antes de entrenar: al azar y chiquitos, con un tamaño que depende de cuántas entradas suma cada neurona.Más

No pueden empezar todos iguales, ni en cero: las neuronas de una capa calcularían lo mismo, recibirían la misma culpa y seguirían siendo gemelas para siempre. Y el tamaño importa: pesos un poco grandes hacen que los números exploten capa tras capa, y un poco chicos, que se apaguen. Con ReLU se usa la regla de He: desviación estándar √(2 ÷ entradas). PyTorch inicializa cada capa al crearla; en un fine-tuning, solo la cabeza nueva empieza al azar.

Ejemplo. Una convolución de 3 × 3 sobre 64 canales suma 576 entradas por neurona: sus pesos empiezan con desviación √(2 ÷ 576) ≈ 0.059.

Ver en el glosario →

ConvoluciónconvolutionPasar un filtro chico (por ejemplo de 3 × 3) por toda la foto: en cada posición multiplica los píxeles que cubre por sus pesos, suma y escribe un número.Más

El mismo filtro se usa en todas las posiciones, así que una capa convolucional tiene muy pocos parámetros, encuentra un patrón esté donde esté y reutiliza cada peso miles de veces por foto. Cada filtro produce un mapa de activaciones, cuyo tamaño depende del stride y del padding. (En matemáticas, una convolución voltea el filtro antes de aplicarlo; las redes no lo voltean, pero se le sigue llamando así.)

Ejemplo. Un filtro con columnas 1, 0 y −1 sobre una ventana con filas 9 · 9 · 1, 8 · 9 · 0 y 9 · 8 · 1 da 8 + 8 + 8 = 24: hay un borde de claro a oscuro.

Ver en el glosario →

Filtrofilter · kernelLa cuadrícula chica de pesos que recorre la foto en una convolución. Cada filtro busca un patrón: un borde, un cambio de color, una textura.Más

Sobre una entrada de varios canales, un filtro de 3 × 3 mira todos a la vez: sobre una foto de color es de 3 × 3 × 3, 27 pesos más 1 sesgo. Sus pesos los aprende el entrenamiento; nadie los escribe a mano.

Ejemplo. Una capa de 64 filtros de 3 × 3 sobre una foto de color: 64 × (27 + 1) = 1,792 parámetros.

Ver en el glosario →

Mapa de activacionesfeature map · activation mapLa cuadrícula que produce un filtro al recorrer la foto. Dice dónde de la foto encontró lo que busca ese filtro.Más

Una capa con 64 filtros produce 64 mapas, que son los 64 canales de entrada de la capa siguiente. En una CNN los mapas se van achicando y multiplicando: la ResNet-50 termina con 2,048 mapas de 7 × 7.

Ejemplo. La primera capa de la ResNet-50 convierte la foto de 3 × 224 × 224 en 64 mapas de 112 × 112.

Ver en el glosario →

Stridestride · pasoCuántos píxeles salta un filtro de una posición a la siguiente. Con stride 2, la salida queda más o menos de la mitad de ancho y de la mitad de alto.Más

Entra en la fórmula del tamaño de salida de una convolución o de un pooling: lado = (n + 2p − k) ÷ s + 1, redondeando la división hacia abajo, con n el lado de la entrada, k el del filtro, p el padding y s el stride. Cada capa con stride 2 deja la cuarta parte de las posiciones y hace crecer más rápido el campo receptivo.

Ejemplo. La primera capa de la ResNet-50 (7 × 7, padding 3, stride 2) convierte la foto de 224 × 224 en mapas de 112 × 112: (224 + 6 − 7) ÷ 2 = 111.5, que baja a 111, más 1.

Ver en el glosario →

Paddingpadding · rellenoUn marco de ceros alrededor de la entrada de una convolución, para que el filtro también se centre en las orillas y la salida no se encoja.Más

Con un filtro de k × k (k impar), padding (k − 1) ÷ 2 y stride 1, la salida mide lo mismo que la entrada: por eso casi todas las convoluciones de 3 × 3 llevan padding 1. Cerca de la orilla el filtro ve ceros en vez de imagen, así que las respuestas de la orilla suelen ser peores.

Ejemplo. Una entrada de 5 × 5 con un filtro de 3 × 3: sin padding sale de 3 × 3; con padding 1, (5 + 2 − 3) ÷ 1 + 1 = 5, del mismo tamaño.

Ver en el glosario →

Poolingpooling · max pooling · average poolingResumir cada cuadrito de un mapa en un solo número (el mayor, o el promedio) para achicarlo. No tiene parámetros: no aprende nada.Más

Un max pooling de 2 × 2 con stride 2 deja los mapas con la cuarta parte de los números; su tamaño sale de la misma fórmula que el de una convolución. Se pierde exactamente dónde estaba algo dentro del cuadrito, pero se conserva que sí estaba. Al final de la ResNet-50, un pooling global promedia cada mapa entero en un número.

Ejemplo. El cuadrito 5, 6, 7, 3 con max pooling da 7.

Ver en el glosario →

CNNconvolutional neural networkUna red neuronal hecha sobre todo de convoluciones, activaciones y pooling. Es la familia clásica para imágenes.Más

Le va bien a las fotos por tres razones: cada filtro mira cerca (el significado está en los píxeles vecinos), usa el mismo filtro en todas partes (reconoce un tenis esté donde esté, con pocos parámetros) y arma lo complicado con lo simple, capa tras capa, porque su campo receptivo crece. La ResNet-50 de C01 es una CNN.

Ejemplo. Una capa convolucional de 64 filtros de 3 × 3 sobre la foto de color tiene 1,792 parámetros; una capa densa de 1,000 neuronas sobre los mismos 150,528 números tendría ≈ 150 millones.

Ver en el glosario →

Campo receptivoreceptive fieldEl pedazo de la foto original que puede influir en una neurona. Crece con cada capa, y más rápido con stride.Más

Se calcula capa por capa con dos números, el campo r y el salto j (píxeles de la foto entre dos neuronas vecinas): r nuevo = r + (k − 1) × j y j nuevo = j × s, empezando con r = 1 y j = 1. Es un máximo teórico: los píxeles del centro pesan mucho más que los de la orilla. Decide si una red alcanza a ver un objeto grande y si un detalle chico sobrevive.

Ejemplo. Tres capas de 3 × 3 con stride 1 ven 3, 5 y 7 píxeles. Un número del último mapa de la ResNet-50 puede depender de 427 × 427 píxeles.

Ver en el glosario →

ResNetresidual network · ResNet-50Una familia de CNNs (He y otros, Microsoft Research, 2015) en la que cada bloque tiene un atajo: su entrada se le suma a su salida. Eso permitió entrenar redes muy profundas.Más

Con el atajo (skip connection), salida = bloque(x) + x: cada bloque solo aprende una corrección, y la señal del aprendizaje llega bien hasta las primeras capas. Ganó la competencia de ImageNet de 2015. La ResNet-50 tiene 50 capas con pesos en su camino principal, 16 bloques residuales en cuatro etapas y hace ≈ 4.1 mil millones de multiplicaciones-sumas por foto de 224 × 224.

Ejemplo. La ResNet-50 original (1,000 categorías) tiene ≈ 25.6 millones de parámetros: ≈ 102 MB en float32. La de C01, con 500 categorías, ≈ 24.5 millones.

Ver en el glosario →

BatchNormbatch normalizationUna capa que acomoda los números de cada canal para que queden alrededor de 0 y con dispersión parecida a 1. Se porta distinto al entrenar y al responder.Más

Al entrenar usa el promedio y la desviación del batch actual y va guardando un promedio acumulado (running stats). Al responder, en modo eval, usa esos valores acumulados. Si el modelo se queda en modo entrenamiento en producción, la respuesta de una foto depende de las otras fotos de su batch. Cada bloque de la ResNet lleva varias.

Ejemplo. Un canal da 2, 4, 6 y 8 en un batch: promedio 5, desviación ≈ 2.24. La foto que dio 4 queda en ≈ −0.45. Con las estadísticas acumuladas da eso siempre; con las de otro batch, otra cosa.

Ver en el glosario →

DropoutdropoutUna traba contra el overfitting: al entrenar, apaga al azar una fracción de las neuronas en cada paso. Al responder no apaga nada.Más

Obliga a la red a repartir lo que sabe en lugar de depender de unas pocas neuronas. Las que quedan se multiplican para compensar (con la mitad apagada, por 2). Si el modelo se queda en modo entrenamiento en producción, la misma foto da respuestas distintas cada vez. La ResNet-50 estándar no tiene Dropout; muchos otros modelos sí.

Ejemplo. Con dropout de 0.5, una capa de 4 neuronas que saca 1, 2, 3 y 4 podría sacar al entrenar 2, 0, 6 y 0: la mitad apagada y el resto multiplicado por 2. Al responder saca 1, 2, 3 y 4.

Ver en el glosario →

Modo evaleval mode · model.eval()El interruptor de PyTorch que le dice al modelo «ahora vas a responder, no a entrenar». BatchNorm usa sus estadísticas guardadas y Dropout deja de apagar neuronas.Más

Un modelo recién creado o cargado está en modo entrenamiento (model.train()). Olvidar model.eval() en el servidor es un bug clásico: no da error, solo baja la calidad. No apaga el cálculo para aprender: para eso es torch.inference_mode(). En producción van los dos.

Ejemplo. En modo eval, la foto del ejemplo de BatchNorm da −0.45 llegue sola o acompañada. En modo train, sola en su batch, daría 0.

Ver en el glosario →

Backbonebackbone · feature extractor · encoderLa parte de la red que «ve»: recibe la foto y la convierte en una lista de números (features) que describen lo que hay en ella. Después va la cabeza, que decide.Más

Es la parte grande y cara (en la ResNet-50, el 99.97 % de las multiplicaciones-sumas), y casi siempre viene preentrenada (transfer learning). La cabeza es chica y es la que sabe de la tarea: el mismo backbone sirve para clasificar, detectar o segmentar cambiando solo la cabeza. Sus features también sirven solas, como embedding.

Ejemplo. En la ResNet-50 de C01, el backbone entrega 2,048 números por foto y la cabeza los convierte en 500 logits.

Ver en el glosario →

CabezaheadLa parte final de una red, chica, que convierte lo que entrega el backbone en la respuesta de la tarea: un logit por categoría, cajas o una máscara.Más

Es lo que se cambia al reutilizar un backbone para otra tarea (transfer learning). En clasificación es un pooling más una capa densa; en detección, una capa que propone una caja y un puntaje por clase en cada posición; en segmentación, un decoder que agranda los mapas hasta dar una respuesta por píxel. No confundir con las «cabezas de atención» de un transformer, que son otra cosa.

Ejemplo. La cabeza de C01 es una capa densa de 2,048 → 500: 2,048 × 500 + 500 = 1,024,500 parámetros. La original de ImageNet, de 1,000 categorías, tiene 2,049,000.

Ver en el glosario →

Transfer learningtransfer learning · aprendizaje por transferenciaUsar lo que un modelo ya aprendió en una tarea para resolver otra. Se parte de un modelo preentrenado en vez de empezar de cero.Más

Lo típico en visión: un backbone entrenado con ImageNet (≈ 1.28 millones de fotos, 1,000 categorías) ya sabe ver bordes, texturas y formas. Se le cambia la cabeza por una con las categorías propias y se sigue entrenando (fine-tuning). Hacen falta muchos menos datos y tiempo. Ayuda menos cuando las imágenes se parecen poco a las del preentrenamiento, como radiografías.

Ejemplo. C01 parte de una ResNet-50 preentrenada en ImageNet y cambia su cabeza de 1,000 a 500 categorías.

Ver en el glosario →

Fine-tuningfine-tuning · ajuste finoSeguir entrenando un modelo preentrenado con tus propios datos, con un learning rate chico para no borrar lo que ya sabía.Más

Se puede congelar el backbone y entrenar solo la cabeza (rápido, sirve con pocos datos) o entrenar todo con learning rate chico (más lento, suele dar mejor resultado con muchos datos). Es la forma más común de transfer learning.

Ejemplo. En la Ronda, el fine-tuning de C01 usa learning rate 0.0003, 8 épocas y batches de 64, y cabe en una GPU en horas. Con el backbone congelado, solo se moverían 1,024,500 de los 24,532,532 parámetros.

Ver en el glosario →

ViTVision TransformerUn modelo de visión que parte la foto en parches de 16 × 16 píxeles y los trata como los tokens de una frase, con un transformer.Más

Lo presentaron Dosovitskiy y otros en 2020. Cada parche (16 × 16 × 3 = 768 números) se convierte en un vector, se le suma su posición y entra a un transformer junto con un token extra, [CLS], de donde sale la respuesta. No trae de fábrica las ideas de una CNN (mirar de cerca, el mismo filtro en todas partes): las aprende de los datos, así que brilla con preentrenamientos enormes. El ViT-B/16 tiene ≈ 86 millones de parámetros.

Ejemplo. Una foto de 224 × 224 con parches de 16: 224 ÷ 16 = 14 por lado, 14 × 14 = 196 parches; con el [CLS], 197 tokens.

Ver en el glosario →

14

Chequeo

Esencial

Check

Intenta responder en tu cabeza antes de abrir cada respuesta.

  1. 1¿Por qué un perceptrón no puede aprender el XOR, y qué lo resuelve?Ver respuesta

    Una neurona con escalón separa el plano con una recta, y en el XOR los dos casos que valen 1 están en esquinas opuestas: ninguna recta los aparta de los ceros. Lo resuelve una capa oculta (un MLP), que mueve los puntos para que una recta sí sirva.

  2. 2¿Cuántos parámetros tiene una capa densa con 2,048 entradas y 500 salidas, y cuántas MACs hace por foto?Ver respuesta

    2,048 × 500 pesos + 500 sesgos = 1,024,500 parámetros, y 2,048 × 500 = 1,024,000 MACs: cada peso se usa una vez. Es la capa final de la ResNet-50 de C01.

  3. 3¿Por qué una CNN necesita tan pocos parámetros comparada con una red densa sobre los mismos píxeles?Ver respuesta

    Porque cada filtro mira solo un pedacito y se usa en todas las posiciones de la foto. Una capa de 64 filtros de 3 × 3 × 3 tiene 1,792 parámetros; una densa de 1,000 neuronas sobre los mismos 150,528 números tendría ≈ 150 millones.

  4. 4Una entrada de 56 × 56 pasa por una convolución de 3 × 3 con padding 1 y stride 2. ¿De qué tamaño sale?Ver respuesta

    (56 + 2 − 3) ÷ 2 = 27.5, que baja a 27; más 1: 28. Con stride 1 habría salido de 56.

  5. 5¿Qué hace la conexión residual de una ResNet?Ver respuesta

    Le suma al bloque su propia entrada: salida = bloque(x) + x. Cada bloque solo aprende una corrección y la señal del aprendizaje llega bien hasta las primeras capas; eso permitió entrenar en ImageNet redes de hasta 152 capas.

  6. 6En producción, la misma foto da respuestas distintas según qué otras fotos venían en su batch. ¿Qué revisas primero?Ver respuesta

    Que el modelo esté en modo eval (model.eval()). En modo train, la BatchNorm normaliza con las estadísticas del batch actual, así que la respuesta depende de las otras fotos.

  7. 7¿Por qué C01 parte de una ResNet-50 preentrenada en ImageNet en vez de entrenar desde cero?Ver respuesta

    Porque su backbone ya aprendió a ver bordes, texturas y formas con ≈ 1.28 millones de fotos. Basta cambiar la cabeza a 500 categorías y hacer fine-tuning, con muchas menos fotos y horas de GPU.

Sigue · 07Embeddings: el significado como coordenadasLo básico de ML Léelo en la RondaM03 · Latencia y capacidadLo que acabas de leer, con el ojo del entrevistador. ← 05 · ¿Aprendió de verdad?