En 03-03 catalogamos las grandes arquitecturas de CNN —VGG, ResNet, MobileNet, EfficientNet— y cerramos con una promesa: no hace falta entrenarlas desde cero para usarlas. Esta lección cumple esa promesa. El transfer learning (aprendizaje por transferencia) consiste en tomar un modelo entrenado en un problema grande y genérico y reutilizar su conocimiento en tu problema pequeño y específico. Es, con diferencia, la técnica con mejor relación esfuerzo/resultado del deep learning práctico: es la razón por la que TecnoMarket puede tener un clasificador de categorías de producto de calidad profesional con unas decenas de fotos por categoría, en lugar de necesitar millones.
Contenido
- Por qué entrenar desde cero es un lujo
- La intuición: los rasgos genéricos se transfieren
- Dos estrategias: extracción de características y fine-tuning
- Cuándo usar cada estrategia
- Ejemplo completo en Keras: MobileNetV2 para el catálogo de TecnoMarket
- Fine-tuning: descongelar con cuidado
- Transfer learning más allá de las imágenes
Por qué entrenar desde cero es un lujo
Pongamos números concretos al problema. Las arquitecturas de 03-03 se entrenaron sobre ImageNet: ~1,28 millones de imágenes etiquetadas en 1000 clases. Entrenar una de esas redes desde cero implica:
- Datos: reunir y etiquetar del orden de un millón de imágenes. Etiquetar a mano, incluso a pocos céntimos por imagen, cuesta decenas de miles de euros y meses de trabajo.
- Cómputo: el entrenamiento original de una ResNet-50 sobre ImageNet requería del orden de semanas en una GPU de la época; hoy, con hardware moderno, sigue siendo horas o días de GPU cara (cientos o miles de euros en la nube por experimento — y rara vez sale bien al primer experimento).
- Experiencia: ajustar hiperparámetros de un entrenamiento así es un oficio en sí mismo.
Ahora la realidad de TecnoMarket: para clasificar fotos de productos en, digamos, 8 categorías, el equipo dispone de unas 200 fotos por categoría (~1600 imágenes). Con tan pocos datos, una CNN entrenada desde cero memorizará el conjunto de entrenamiento — el sobreajuste que ya asomó en 02-05, pero en versión severa.
La salida: alguien (Google, en el caso de MobileNet) ya pagó el lujo. Los pesos resultantes están publicados y Keras los descarga con un argumento (weights="imagenet"). La pregunta es cómo aprovecharlos.
La intuición: los rasgos genéricos se transfieren
Recuerda la jerarquía de representaciones de 03-01: una CNN aprende bordes → texturas → partes → objetos, de las primeras capas a las últimas. La observación clave del transfer learning es que esa jerarquía se vuelve específica solo al final:
- Las primeras capas detectan bordes, esquinas, gradientes de color, texturas básicas. Estos rasgos son universales: sirven igual para distinguir gatos que para distinguir cafeteras de tostadoras. Una red entrenada en ImageNet ya los tiene, y son esencialmente los mismos que aprendería con tus datos... si tuvieras suficientes.
- Las capas intermedias detectan motivos y partes (rejillas, asas, superficies metálicas, pantallas) — todavía bastante reutilizables para fotos de producto.
- Las últimas capas combinan todo en conceptos específicos de las 1000 clases de ImageNet ("husky siberiano", "teléfono de disco"). Estas son las menos transferibles: TecnoMarket no vende huskies.
Por tanto, la receta general: conservar la base convolucional (el conocimiento visual genérico, carísimo de obtener) y sustituir la cabeza clasificadora (lo específico del problema original) por una nueva adaptada a tus clases.
flowchart LR
subgraph Preentrenado en ImageNet
A[Primeras capas<br/>bordes y texturas<br/>MUY transferibles] --> B[Capas intermedias<br/>partes y motivos<br/>transferibles]
end
B --> C[Cabeza original<br/>1000 clases ImageNet<br/>se descarta]
B --> D[Cabeza NUEVA<br/>8 categorias TecnoMarket<br/>se entrena]
style C stroke-dasharray: 5 5
Dos estrategias
Hay dos formas de reutilizar la base, ordenadas de más conservadora a más ambiciosa:
1. Extracción de características (base congelada). La base convolucional se congela (trainable = False): sus pesos no se tocan. Actúa como una función fija que convierte cada imagen en un vector de rasgos —un embedding, exactamente el concepto de 03-04—, y solo se entrena la cabeza nueva encima. Ventajas: rapidísimo, imposible estropear el conocimiento preentrenado, funciona con muy pocos datos (la cabeza tiene pocos parámetros que ajustar).
2. Fine-tuning (ajuste fino). Tras entrenar la cabeza, se descongelan las últimas capas de la base y se sigue entrenando todo junto con un learning rate muy bajo. La base adapta sus rasgos de alto nivel al dominio nuevo (las fotos de producto tienen fondos blancos y encuadres frontales que ImageNet no enfatiza). Ventaja: más precisión potencial. Riesgo: con pocos datos o un learning rate alegre, puedes destruir los rasgos preentrenados (fenómeno conocido como catastrophic forgetting) y sobreajustar.
Cuándo usar cada estrategia
La decisión depende de dos ejes: cuántos datos tienes y cuánto se parece tu dominio a ImageNet.
| Dataset pequeño (cientos–pocos miles) | Dataset grande (decenas de miles+) | |
|---|---|---|
| Dominio similar a ImageNet (fotos naturales: productos, animales, escenas) | Extracción de características. Los rasgos ya sirven y no hay datos para más | Fine-tuning de las últimas capas (o de más capas): hay datos para afinar sin romper |
| Dominio distinto (radiografías, imágenes por satélite, espectrogramas) | El caso difícil: extraer características desde capas intermedias (las últimas son demasiado "ImageNet") y considerar aumento de datos agresivo (05-04) | Fine-tuning profundo, incluso de casi toda la red: los rasgos altos deben reaprenderse |
TecnoMarket cae en la celda superior izquierda-a-media: fotos naturales de productos (dominio similar) con ~1600 imágenes (pequeño). Empezaremos por extracción de características y aplicaremos un fine-tuning suave después.
Ejemplo completo en Keras: MobileNetV2 para el catálogo
Elegimos MobileNetV2 (de 03-03: la familia diseñada para ser ligera y rápida, ideal si el clasificador correrá en los servidores modestos de TecnoMarket o en el móvil de los operarios de almacén).
Supón las imágenes organizadas en carpetas por categoría (datos/cafeteras/, datos/tostadoras/, ...), el formato que image_dataset_from_directory lee directamente:
from tensorflow import keras
from tensorflow.keras import layers
TAM = (160, 160) # MobileNetV2 acepta varios tamaños; 160x160 es ligero
N_CLASES = 8
# 1. Cargar los datos con particion train/validacion
train_ds = keras.utils.image_dataset_from_directory(
"tecnomarket-dl/datos/productos", validation_split=0.2, subset="training",
seed=42, image_size=TAM, batch_size=32)
val_ds = keras.utils.image_dataset_from_directory(
"tecnomarket-dl/datos/productos", validation_split=0.2, subset="validation",
seed=42, image_size=TAM, batch_size=32)
# 2. Base preentrenada, SIN su cabeza de 1000 clases
base = keras.applications.MobileNetV2(
input_shape=TAM + (3,),
include_top=False, # descartamos la cabeza de ImageNet
weights="imagenet", # descargamos el conocimiento preentrenado
)
base.trainable = False # CONGELADA: extraccion de caracteristicas
# 3. Modelo completo: preprocesado + base + cabeza nueva
entradas = keras.Input(shape=TAM + (3,))
# Cada arquitectura espera su normalizacion concreta; usar SIEMPRE la suya
x = keras.applications.mobilenet_v2.preprocess_input(entradas) # a [-1, 1]
x = base(x, training=False) # training=False: fija tambien las BatchNorm
x = layers.GlobalAveragePooling2D()(x) # mapa 5x5x1280 -> vector de 1280
x = layers.Dropout(0.2)(x) # algo de regularizacion (05-04)
salidas = layers.Dense(N_CLASES, activation="softmax")(x)
modelo = keras.Model(entradas, salidas)
modelo.compile(optimizer=keras.optimizers.Adam(1e-3),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
# 4. Entrenar SOLO la cabeza (la base esta congelada)
historia = modelo.fit(train_ds, validation_data=val_ds, epochs=10)Desglose de las decisiones:
include_top=False: descarta las capas finales específicas de ImageNet; nos quedamos con la base convolucional, que emite un mapa de rasgos 5×5×1280.GlobalAveragePooling2D: promedia cada uno de los 1280 mapas a un solo número → vector de 1280. Es la versión "sin parámetros" de aplanar + densa, y reduce el riesgo de sobreajuste de la cabeza.preprocess_input: cada arquitectura se entrenó con su propia normalización (MobileNetV2 espera píxeles en [-1, 1]). Saltárselo es el error silencioso más común: la red "funciona" pero rinde mal.base(x, training=False): además de congelar pesos, fija las estadísticas de las capas BatchNormalization de la base (verás qué son en 05-04); es la forma correcta de usar una base congelada en Keras.- Si ejecutas
modelo.summary()(el hábito que adquiriste en 03-02) verás algo revelador: ~2,26 millones de parámetros no entrenables (la base) y solo ~10 000 entrenables (la cabeza). Estás entrenando el 0,5 % de la red.
Con este esquema, es habitual pasar de un 50-60 % de accuracy (CNN pequeña desde cero con 1600 imágenes) a un 85-90 %+ en pocas épocas. Ese salto es el conocimiento de ImageNet trabajando gratis.
Fine-tuning: descongelar con cuidado
Segunda fase, opcional pero habitual: descongelar la parte alta de la base para adaptarla al dominio "foto de producto".
# 1. Descongelar SOLO el tramo final de la base
base.trainable = True
for capa in base.layers[:-30]: # todas menos las ultimas ~30 capas
capa.trainable = False # siguen congeladas
# 2. RECOMPILAR con un learning rate MUY bajo (100x menor)
modelo.compile(optimizer=keras.optimizers.Adam(1e-5), # antes 1e-3
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
# 3. Pocas epocas mas, vigilando la curva de validacion
historia_ft = modelo.fit(train_ds, validation_data=val_ds, epochs=5)Las tres reglas de oro del fine-tuning:
- Primero la cabeza, luego la base. Si descongelas con la cabeza aún aleatoria, sus gradientes grandes y caóticos —el reparto de culpa de 02-03 en su versión más destructiva— arrasan los pesos preentrenados.
- Learning rate muy bajo (típicamente 10⁻⁵, dos órdenes por debajo del habitual). Estás retocando conocimiento valioso, no aprendiendo desde cero: pasos pequeños.
- Descongelar de arriba hacia abajo. Las últimas capas (las más específicas) primero; las primeras (bordes y texturas universales) casi nunca merece la pena tocarlas.
Si tras el fine-tuning la accuracy de validación cae mientras la de entrenamiento sube, has entrado en sobreajuste: vuelve al checkpoint anterior y quédate con la base congelada, o añade regularización (siguiente lección).
El proyecto guiado completo —con evaluación fina, matriz de confusión por categoría y análisis de errores— es la lección 07-05; allí llevaremos este mismo esquema hasta un modelo defendible en producción.
Transfer learning más allá de las imágenes
La idea no es exclusiva de la visión:
- Embeddings de palabras preentrenados: en 04-03 entrenamos la capa
Embeddingdesde cero; también pueden cargarse vectores ya entrenados sobre miles de millones de palabras (Word2Vec, GloVe) — es transfer learning para la primera capa de un modelo de texto. - Modelos de lenguaje preentrenados: la versión moderna y mucho más potente — modelos entrenados para "entender el idioma" en general que luego se afinan para sentimiento, clasificación de reseñas o búsqueda. Son los BERT y compañía que veremos en la próxima lección (05-05), donde esta idea de transferencia se encontrará con la arquitectura Transformer.
El patrón es siempre el mismo: conocimiento genérico caro, entrenado una vez por quien puede pagarlo; adaptación específica barata, al alcance de cualquiera. Es probablemente el concepto individual más importante para aplicar deep learning en una empresa real.
Errores Comunes y Consejos
- Olvidar el
preprocess_inputde la arquitectura elegida. Cada familia espera su rango/normalización. Con la normalización equivocada no hay error de ejecución, solo métricas mediocres e inexplicables. Es el primer sospechoso cuando un modelo preentrenado rinde raro. - Descongelar todo y entrenar con el learning rate de siempre. Resultado típico: en dos épocas la red olvida ImageNet y rinde peor que congelada. Base congelada primero, lr ~10⁻⁵ después.
- Olvidar recompilar tras cambiar
trainable. En Keras, cambiartrainableno tiene efecto hasta que llamas de nuevo acompile(). Si tus curvas no cambian tras "descongelar", casi seguro que es esto. - Evaluar solo la accuracy global. Con categorías desequilibradas (muchas fotos de móviles, pocas de freidoras) la accuracy engaña; mira el rendimiento por clase — lo haremos sistemáticamente en 07-05.
- Elegir una base gigante por defecto. Si el clasificador debe responder en milisegundos en producción, EfficientNet-B7 sobra; MobileNetV2 o EfficientNet-B0 (recuerda los tamaños relativos de 03-03) suelen ser el punto dulce.
- Ignorar la licencia y procedencia de los pesos. Para uso comercial en TecnoMarket, verifica que los pesos preentrenados permiten ese uso (los de
keras.applicationssí, pero no todo lo publicado en internet).
Ejercicios
Ejercicio 1. El equipo de TecnoMarket quiere clasificar radiografías de paquetes del escáner de seguridad del almacén en "normal" / "revisar", con solo 800 imágenes etiquetadas. Usando la tabla 2×2, razona qué estrategia de transfer learning aplicarías y qué precaución especial tomarías respecto a qué capas de la base usar.
Ejercicio 2. Un compañero ejecuta este código y se queja de que el fine-tuning "no hace nada" (las curvas son idénticas a las de la fase congelada). Encuentra los dos errores:
base.trainable = True
for capa in base.layers[:-30]:
capa.trainable = False
historia_ft = modelo.fit(train_ds, validation_data=val_ds, epochs=5)
# (el modelo se compilo antes de tocar trainable, con Adam(1e-3))Ejercicio 3. Explica por qué GlobalAveragePooling2D + Dense(8) produce una cabeza con muchos menos parámetros que Flatten() + Dense(8) sobre un mapa de salida de 5×5×1280, calculando aproximadamente los parámetros de la capa densa en cada caso, y por qué eso importa con un dataset pequeño.
Soluciones
Solución 1.
Es la celda dataset pequeño + dominio distinto (las radiografías no se parecen a las fotos naturales de ImageNet): el caso difícil. Estrategia: extracción de características, pero con la precaución de no fiarse de las últimas capas de la base, que codifican conceptos muy "ImageNet" (animales, objetos cotidianos) poco útiles para radiografías; conviene extraer rasgos de capas intermedias (texturas, formas, contrastes, que sí son universales) y entrenar la cabeza sobre ellos. Complementos sensatos: aumento de datos agresivo (05-04) y, si se consiguen más imágenes con el tiempo, migrar a fine-tuning profundo. Un fine-tuning agresivo de entrada, con 800 imágenes, sobreajustaría.
Solución 2.
- No se recompiló el modelo después de cambiar
trainable: en Keras el cambio no surte efecto hasta llamar acompile()de nuevo, así que la base sigue efectivamente congelada. Ese es el motivo de que "no haga nada". - Cuando lo recompile, debe bajar el learning rate: recompilar con el
Adam(1e-3)original haría lo contrario de "no hacer nada" — pasos demasiado grandes que degradarían los pesos preentrenados. Lo correcto:modelo.compile(optimizer=keras.optimizers.Adam(1e-5), ...)y entoncesfit.
Solución 3.
- Con
Flatten(): el mapa 5×5×1280 se convierte en un vector de 5·5·1280 = 32 000 valores; la densa de 8 salidas necesita 32 000·8 + 8 ≈ 256 000 parámetros. - Con
GlobalAveragePooling2D: cada uno de los 1280 mapas se promedia a un número → vector de 1280; la densa necesita 1280·8 + 8 ≈ 10 000 parámetros (25 veces menos).
Con solo ~1600 imágenes, una cabeza de 256 000 parámetros tiene capacidad de sobra para memorizar el conjunto de entrenamiento (sobreajuste); la de 10 000 se ve obligada a apoyarse en los rasgos de la base, que es exactamente lo que queremos. Además, el pooling global hace la cabeza independiente del tamaño espacial del mapa de entrada.
Conclusión
El transfer learning convierte el mayor obstáculo del deep learning —el coste de datos y cómputo— en un problema ya resuelto por otros: la base convolucional preentrenada aporta los rasgos genéricos (bordes, texturas, partes: la jerarquía de 03-01) y tú solo pagas la adaptación específica, eligiendo entre base congelada (pocos datos) y fine-tuning con learning rate bajo (más datos, más precisión). Con MobileNetV2 y unas 1600 fotos, el clasificador de catálogo de TecnoMarket saltó a otra liga, y en 07-05 lo llevaremos hasta la evaluación de nivel producción.
Pero tanto ese modelo como todos los anteriores comparten un enemigo que llevamos esquivando desde las curvas de 02-05: el sobreajuste. La próxima lección lo aborda de frente, con el arsenal completo — L1/L2, Dropout, Batch Normalization, Early Stopping y aumento de datos — para mejorar cualquier red de este curso.
Curso de Deep Learning
Módulo 1: Introducción a Deep Learning
- ¿Qué es Deep Learning?
- Historia y evolución del Deep Learning
- Aplicaciones de Deep Learning
- Conceptos básicos de redes neuronales
- Preparación del entorno de trabajo
Módulo 2: Fundamentos de Redes Neuronales
- Perceptrón y Perceptrón Multicapa
- Función de activación
- Propagación hacia adelante y hacia atrás
- Optimización y función de pérdida
- Tu primera red neuronal completa
Módulo 3: Redes Neuronales Convolucionales (CNN)
- Introducción a las CNN
- Capas convolucionales y de pooling
- Arquitecturas populares de CNN
- Aplicaciones de CNN en reconocimiento de imágenes
Módulo 4: Redes Neuronales Recurrentes (RNN)
- Introducción a las RNN
- LSTM y GRU
- Aplicaciones de RNN en procesamiento del lenguaje natural
- Secuencias y series temporales
Módulo 5: Técnicas Avanzadas en Deep Learning
- Redes Generativas Adversariales (GAN)
- Autoencoders
- Transfer Learning
- Regularización y técnicas de mejora
- Mecanismos de atención y Transformers
Módulo 6: Herramientas y Frameworks
- Introducción a TensorFlow
- Introducción a PyTorch
- Comparación de frameworks
- Entornos de desarrollo y recursos adicionales
- Guardar, cargar y desplegar modelos
Módulo 7: Proyectos Prácticos
- Clasificación de imágenes con CNN
- Generación de texto con RNN
- Detección de anomalías con Autoencoders
- Creación de una GAN para generación de imágenes
- Fine-tuning de un modelo preentrenado
