Ja saps construir capes Conv2D i MaxPooling2D, predir les seves formes de sortida i comptar-ne els paràmetres. La pregunta natural següent és: com es combinen aquestes peces en xarxes que funcionen de debò? La bona notícia és que no cal inventar-ho des de zero: entre 1998 i avui, una sèrie d'arquitectures cèlebres va anar resolent, una a una, les dificultats d'entrenar CNN cada vegada més profundes, i els seus patrons de disseny s'han convertit en el vocabulari estàndard del camp. En aquesta lliçó recorrerem aquesta evolució —LeNet-5, AlexNet, VGG, GoogLeNet/Inception, ResNet i les famílies eficients per a mòbil— entenent la idea clau de cadascuna, i l'aterrarem implementant a Keras una mini-VGG i un bloc residual. Conèixer aquestes arquitectures no és cultura general: són exactament els models que TecnoMarket (i tu) reutilitzareu a la pràctica.

Contingut

  1. LeNet-5: la pionera (1998)
  2. AlexNet: el despertar (2012)
  3. VGG: l'elegància de la profunditat (2014)
  4. GoogLeNet/Inception: mòduls en paral·lel (2014)
  5. ResNet: connexions residuals (2015)
  6. Eficiència per a mòbil i edge: MobileNet i EfficientNet
  7. Taula comparativa
  8. Mans a l'obra: una mini-VGG i un bloc residual a Keras

LeNet-5: la pionera (1998)

Molt abans del boom del deep learning, Yann LeCun va dissenyar LeNet-5 per llegir dígits manuscrits en xecs bancaris — el mateix problema MNIST que vas resoldre a 02-05, però quinze anys abans i amb maquinari dels 90. La seva estructura et resultarà familiar perquè és exactament l'anatomia que vam veure a 03-01:

Entrada 32×32×1 → Conv 5×5 (6 filtres) → Pooling → Conv 5×5 (16 filtres) → Pooling → Densa 120 → Densa 84 → Sortida 10
  • Uns 60 000 paràmetres en total: menys que la nostra xarxa densa de 02-05 (~110 000), i tanmateix més precisa en dígits, perquè respecta l'estructura espacial.
  • Va establir el patró canònic conv → pool → conv → pool → denses que continuem fent servir.
  • La seva limitació no era conceptual sinó d'època: sense GPUs, sense grans datasets i amb activacions sigmoide/tanh (amb el seu vanishing gradient, com vas veure a 02-03), no es podia escalar.

AlexNet: el despertar (2012)

A 01-02 vam explicar que AlexNet va guanyar ImageNet 2012 reduint l'error de manera tan brutal que va reactivar tot el camp. Ara pots entendre què era AlexNet: en essència, una LeNet a l'engròs més tres ingredients nous.

  • Estructura: 5 capes convolucionals + 3 denses, ~60 milions de paràmetres, entrada 224×224×3 (la imatge del nostre càlcul d'explosió de paràmetres a 03-01!).
  • Ingredient 1: ReLU en comptes de sigmoide/tanh — entrenament molt més ràpid i menys vanishing (02-02).
  • Ingredient 2: GPUs — es va entrenar en dues GPUs domèstiques durant ~una setmana.
  • Ingredient 3: dades massives (1.2 milions d'imatges d'ImageNet) i trucs contra el sobreajust com dropout i augment de dades (els sistematitzarem a 05-04).
  • Resultat: 15.3 % d'error top-5 a ImageNet davant del 26.2 % del segon classificat. L'era moderna del deep learning comença aquí.

La seva lliçó de disseny: escala (més dades, més còmput, més capes) + ReLU. Però AlexNet era artesanal: filtres d'11×11, 5×5 i 3×3 barrejats sense cap criteri clar. L'arquitectura següent hi va posar ordre.

VGG: l'elegància de la profunditat (2014)

VGG (Universitat d'Oxford, 2014) es construeix sobre una única regla de disseny radicalment simple:

Fes servir sempre filtres 3×3 amb padding same, apila'ls en blocs, i després de cada bloc fes max pooling 2×2 duplicant el nombre de filtres.

VGG-16 (16 capes amb pesos) queda així: blocs de 64, 128, 256, 512 i 512 filtres, i la imatge es redueix 224 → 112 → 56 → 28 → 14 → 7.

Per què filtres 3×3 i no més grans? Dos filtres 3×3 apilats "veuen" una zona de 5×5 (el segon mira una finestra de resultats que al seu torn van mirar finestres), i tres d'apilats veuen 7×7. Però comparem paràmetres per a C canals d'entrada i sortida:

Opció Camp receptiu Paràmetres (sense biaixos)
1 conv de 7×7 7×7 49 C²
3 convs de 3×3 7×7 3 × 9 C² = 27 C²

Les tres capes 3×3 veuen el mateix amb gairebé la meitat de paràmetres i, a més, intercalen tres ReLU en comptes d'una: més no-linealitat, més capacitat de representació. Aquesta observació va consagrar el 3×3 com a estàndard (per això el fem servir per defecte a 03-02).

El preu: VGG-16 té 138 milions de paràmetres, dels quals ~102 milions són a la primera capa densa després del Flatten (7×7×512 = 25 088 entrades × 4096 neurones) — la patologia que ja vam diagnosticar en llegir el summary() a 03-02, portada a l'extrem.

GoogLeNet/Inception: mòduls en paral·lel (2014)

El mateix any, Google va atacar la pregunta "quina mida de filtre faig servir a cada capa?" amb una resposta lateral: no triïs — fes-ne servir diversos alhora. El mòdul Inception aplica en paral·lel, sobre la mateixa entrada, convolucions 1×1, 3×3, 5×5 i un max pooling, i concatena tots els mapes resultants per l'eix de canals: la xarxa decideix durant l'entrenament a quina branca donar pes.

flowchart TB
    E["Entrada del modul"] --> A["Conv 1x1"]
    E --> B["Conv 1x1 -> Conv 3x3"]
    E --> C["Conv 1x1 -> Conv 5x5"]
    E --> D["MaxPool 3x3 -> Conv 1x1"]
    A --> F["Concatenar canals"]
    B --> F
    C --> F
    D --> F

Dues idees d'aquest disseny es van convertir en patrimoni comú:

  • La convolució 1×1 ("bottleneck"): un filtre 1×1×C no mira veïns espacials, però barreja i comprimeix canals (p. ex. de 256 canals a 64) abans de les convolucions cares. És una capa densa aplicada píxel a píxel sobre el vector de canals, i abarateix dràsticament el mòdul.
  • Global average pooling al final: en comptes de Flatten + denses gegants, es fa la mitjana de cada mapa de característiques complet a un sol número. GoogLeNet va aconseguir així 22 capes amb només ~7 milions de paràmetres — 20 vegades menys que VGG amb millor error.

ResNet: connexions residuals (2015)

Amb ReLU, GPUs i bons dissenys, seria d'esperar que apilar més capes sempre millorés. Però els experiments mostraven el contrari: a partir d'una certa profunditat (~20 capes), afegir capes empitjorava fins i tot l'error d'entrenament. No era sobreajust (això empitjoraria només la validació): era un problema d'optimització — la degradació. El gradient, després de travessar desenes de capes multiplicant derivades (la regla de la cadena i el "repartiment de la culpa" de 02-03), arribava a les primeres capes esvaït, i la xarxa profunda ni tan sols aconseguia aprendre el que la superficial ja sabia.

ResNet (Microsoft Research, 2015) ho va resoldre amb un canvi mínim i genial: la connexió residual (skip connection). En comptes de demanar a un bloc de capes que aprengui una transformació completa H(x), se li demana que aprengui només la correcció F(x) sobre la identitat, i l'entrada se suma directament a la sortida:

sortida = F(x) + x
flowchart LR
    X["x"] --> C1["Conv 3x3 + ReLU"]
    C1 --> C2["Conv 3x3"]
    C2 --> S(("+"))
    X -->|"drecera (identitat)"| S
    S --> R["ReLU"] --> Y["sortida"]

Per què funciona, en dues lectures:

  • Lectura d'aprenentatge: si un bloc no aporta res d'útil, en té prou d'aprendre F(x) = 0 (pesos a zero, fàcil) i el bloc es converteix en la identitat: la xarxa de 50 capes mai no pot ser pitjor que la de 20, perquè les capes sobrants poden "apartar-se". Aprendre una correcció petita és més fàcil que aprendre una transformació sencera.
  • Lectura del gradient: en derivar F(x) + x, la branca + x té derivada 1, així que en la retropropagació el gradient disposa d'una autopista directa cap a les capes primerenques, sense travessar (i sense ser encongit per) totes les multiplicacions intermèdies. És la solució arquitectònica al vanishing gradient que vam analitzar a 02-03.

Amb això, la profunditat es va desbloquejar: ResNet-152 (152 capes) va guanyar ImageNet 2015 amb un error top-5 del 3.6 %, per sota de l'humà de referència (~5 %), i ResNet-50 continua sent avui un dels cavalls de batalla de la visió per computador. Les connexions residuals apareixen des de llavors gairebé a tot arreu, inclosos els transformers (05-05).

Eficiència per a mòbil i edge: MobileNet i EfficientNet

Menció breu, perquè te'ls creuaràs constantment: no tot és guanyar ImageNet. Si TecnoMarket volgués que la seva app mòbil classifiqués la foto al telèfon del venedor (sense pujar-la a un servidor), necessitaria xarxes petites i ràpides:

  • MobileNet (2017): substitueix la convolució estàndard per la convolució separable en profunditat (primer un filtre espacial per canal, després una conv 1×1 que barreja canals), reduint el còmput ~8-9 vegades amb poca pèrdua de precisió. Ideal per a mòbil i dispositius edge.
  • EfficientNet (2019): parteix d'una base eficient i defineix una regla d'escalat compost (augmentar alhora profunditat, amplada i resolució d'entrada en proporcions equilibrades), generant una família B0...B7 que cobreix des de mòbil fins a servidor amb precisió capdavantera per a cada nivell de còmput.

Taula comparativa

Arquitectura Any Capes (amb pesos) Paràmetres Idea clau Error top-5 ImageNet
LeNet-5 1998 7 ~60 K Patró conv→pool→denses — (dígits, no ImageNet)
AlexNet 2012 8 ~60 M Escala + ReLU + GPU 15.3 %
VGG-16 2014 16 ~138 M Profunditat amb només filtres 3×3 7.3 %
GoogLeNet 2014 22 ~7 M Mòduls Inception en paral·lel, convs 1×1 6.7 %
ResNet-152 2015 152 ~60 M Connexions residuals 3.6 %
MobileNetV2 2018 ~53 ~3.5 M Convs separables (mòbil/edge) ~9 % (top-5, model petit)
EfficientNet-B7 2019 ~200+ ~66 M Escalat compost ~1.9 %

La tendència que explica la taula: l'error cau del 15 % a menys del 2 % en set anys, i no a base d'inflar paràmetres (GoogLeNet i MobileNet els redueixen), sinó a base de millors idees d'arquitectura.

Mans a l'obra: una mini-VGG i un bloc residual a Keras

No implementarem VGG-16 ni ResNet-50 senceres (no tindria sentit entrenar-les des de zero aquí, i de seguida veurem per què tampoc no cal). Implementarem els patrons a escala reduïda, que és el que de debò es transfereix.

Mini-VGG per a fotos de producte

El patró VGG en miniatura per a imatges 64×64×3 de TecnoMarket, amb la regla "dues convs 3×3 same + pooling, duplicant filtres" i tancament modern amb global average pooling en lloc del Flatten golafre:

from tensorflow import keras
from tensorflow.keras import layers

def bloc_vgg(x, filtres):
    """Dues convs 3x3 'same' + ReLU, i un max pooling que redueix a la meitat."""
    x = layers.Conv2D(filtres, (3, 3), padding="same", activation="relu")(x)
    x = layers.Conv2D(filtres, (3, 3), padding="same", activation="relu")(x)
    return layers.MaxPooling2D((2, 2))(x)

entrada = keras.Input(shape=(64, 64, 3))
x = bloc_vgg(entrada, 32)      # 64x64 -> 32x32, 32 canals
x = bloc_vgg(x, 64)            # 32x32 -> 16x16, 64 canals
x = bloc_vgg(x, 128)           # 16x16 -> 8x8, 128 canals
x = layers.GlobalAveragePooling2D()(x)   # 8x8x128 -> vector de 128 (mitjana de cada mapa)
sortida = layers.Dense(4, activation="softmax")(x)  # 4 categories de producte

mini_vgg = keras.Model(entrada, sortida, name="mini_vgg")
mini_vgg.summary()

Detalls que convé notar:

  • Fem servir l'API funcional de Keras (keras.Input, capes aplicades com a funcions, keras.Model) en comptes del Sequential de 02-05 i 03-02. Per a VGG tant se valdria, però és imprescindible per al bloc residual de sota, perquè Sequential només sap encadenar capes en línia recta i una drecera no és una línia recta.
  • Cada bloc_vgg apila dues convs abans del pooling: camp receptiu 5×5 amb paràmetres de 3×3+3×3 i dues ReLU — l'argument de VGG.
  • GlobalAveragePooling2D converteix els 128 mapes de 8×8 en un vector de 128 mitjanes: la sortida densa només necessita 128×4+4 = 516 paràmetres. El model sencer queda en ~300 K paràmetres, sense la densa monstruosa que a 03-02 concentrava el 85 % del total.

Un bloc residual

El patró ResNet mínim — dues convs i la suma de la drecera:

def bloc_residual(x, filtres):
    """Bloc residual basic: sortida = ReLU( F(x) + x )."""
    drecera = x                                              # guardem l'entrada
    y = layers.Conv2D(filtres, (3, 3), padding="same", activation="relu")(x)
    y = layers.Conv2D(filtres, (3, 3), padding="same")(y)    # sense activacio encara
    y = layers.Add()([y, drecera])                           # F(x) + x
    return layers.Activation("relu")(y)                      # ReLU despres de la suma

entrada = keras.Input(shape=(16, 16, 64))
sortida = bloc_residual(entrada, 64)
bloc = keras.Model(entrada, sortida)
bloc.summary()

Lectura del codi, línia a línia:

  • drecera = x: la connexió de salt no és cap capa, és simplement conservar la referència a l'entrada per fer-la servir després.
  • La segona conv va sense activació: primer se suma la drecera i després s'aplica la ReLU. Si activéssim abans de sumar, F(x) només podria afegir valors positius i la correcció perdria la meitat del seu rang.
  • layers.Add()([y, drecera]) exigeix que tots dos tensors tinguin la mateixa forma — per això fem servir padding same i els mateixos 64 filtres que porta l'entrada. Quan un bloc canvia el nombre de canals o redueix la mida (stride 2), la drecera s'adapta amb una conv 1×1 (el truc bottleneck d'Inception reutilitzat); les ResNet reals alternen tots dos tipus de bloc.
  • Apilar bloc_residual desenes de vegades és, literalment, com es construeix una ResNet: cada bloc afegeix la seva petita correcció i el gradient sempre té la seva autopista de tornada.

Errors Comuns i Consells

  • Intentar entrenar VGG-16 o ResNet-50 des de zero amb poques dades. Aquestes xarxes es van entrenar amb 1.2 milions d'imatges; amb les desenes de milers de fotos de TecnoMarket (o menys) sobreajustarien massivament. La solució és reutilitzar-les preentrenades (vegeu la conclusió).
  • Confondre degradació amb sobreajust. El sobreajust empitjora la validació però millora l'entrenament; la degradació que va motivar ResNet empitjorava també l'entrenament. Són mals diferents amb remeis diferents (05-04 per al primer, skip connections per al segon).
  • Oblidar que Add suma, no concatena. layers.Add() suma element a element (formes idèntiques, patró ResNet); layers.Concatenate() apila canals (patró Inception). Triar l'equivocat canvia el disseny per complet.
  • Posar la ReLU abans de la suma residual. L'ordre canònic és conv → conv → sumar drecera → ReLU. Activa-ho abans i estaràs restringint la correcció F(x) a valors no negatius.
  • Memoritzar arquitectures en comptes d'idees. D'aquí a tres anys hi haurà una altra arquitectura de moda; el que perdura és el repertori: 3×3 apilats, convs 1×1 per comprimir canals, global average pooling, connexions residuals. Aprèn el vocabulari, no l'enciclopèdia.

Exercicis

Exercici 1: ordenar la història

Sense mirar la taula, assigna cada idea a la seva arquitectura i ordena-les cronològicament: (a) mòduls amb diverses convolucions en paral·lel, (b) dreceres que sumen l'entrada a la sortida, (c) només filtres 3×3 apilats en blocs, (d) primer gran èxit amb ReLU + GPU a ImageNet, (e) patró original conv→pool→denses per a dígits.

Exercici 2: l'argument de VGG amb números

Una capa rep i produeix 128 canals. Compara els paràmetres (ignora biaixos) de (a) una sola conv 7×7 davant de (b) tres convs 3×3 apilades. Quin avantatge addicional a la reducció de paràmetres aporten les tres capes?

Exercici 3: depurar un bloc residual

Aquest bloc llança un error en construir-se. Explica per què i proposa dos arranjaments diferents:

def bloc_erroni(x):                      # x arriba amb forma (8, 8, 64)
    drecera = x
    y = layers.Conv2D(128, (3, 3), padding="same", activation="relu")(x)
    y = layers.Conv2D(128, (3, 3), padding="same")(y)
    return layers.Activation("relu")(layers.Add()([y, drecera]))

Solucions

Exercici 1: (e) LeNet-5, 1998 → (d) AlexNet, 2012 → (c) VGG, 2014 → (a) GoogLeNet/Inception, 2014 → (b) ResNet, 2015.

Exercici 2:

  • (a) Una conv 7×7: 7 × 7 × 128 × 128 = 802 816 paràmetres.
  • (b) Tres convs 3×3: 3 × (3 × 3 × 128 × 128) = 442 368 paràmetres — un 45 % menys amb el mateix camp receptiu de 7×7.
  • Avantatge addicional: les tres capes intercalen tres ReLU en comptes d'una, així que la transformació és més no lineal i expressiva (i el raonament de 02-02 explica per què això importa).

Exercici 3: L'entrada x té 64 canals però F(x) en produeix 128; layers.Add() exigeix formes idèntiques i falla amb (8, 8, 64) davant de (8, 8, 128). Arranjaments: (1) fer servir 64 filtres a les dues convs del bloc, de manera que F(x) conservi la forma de l'entrada; (2) adaptar la drecera amb una conv 1×1 de 128 filtres — drecera = layers.Conv2D(128, (1, 1), padding="same")(x) — que projecta els 64 canals a 128 abans de la suma (és el que fan les ResNet reals en canviar d'etapa).

Conclusió

Has recorregut vint anys d'evolució en una lliçó: LeNet va fixar el patró conv→pool→denses; AlexNet va demostrar que escala + ReLU + GPU canviaven les regles; VGG va destil·lar el disseny a blocs de filtres 3×3; Inception va introduir les branques paral·leles, les convs 1×1 i el global average pooling; ResNet va desbloquejar la profunditat arbitrària amb connexions residuals que donen al gradient una autopista contra el vanishing de 02-03; i MobileNet/EfficientNet optimitzen el cost per arribar al telèfon del venedor. A més, has implementat els dos patrons més reutilitzats —el bloc VGG i el bloc residual— amb l'API funcional de Keras.

Queda una observació amb conseqüències pràctiques enormes: totes aquestes arquitectures estan disponibles ja entrenades sobre ImageNet (a Keras, a una línia de distància: keras.applications.ResNet50(...)). Les seves primeres capes van aprendre detectors de vores, textures i formes que serveixen per a qualsevol imatge — també per a les fotos de productes de TecnoMarket. Reutilitzar aquest coneixement en comptes d'entrenar des de zero es diu transfer learning, i és la tècnica que estudiarem a 05-03 (i aplicarem amb fine-tuning a 07-05). Abans d'arribar-hi, a la propera lliçó aixecarem la vista de la classificació pura: veurem tot el que les CNN saben fer amb imatges — localitzar, detectar, segmentar, llegir i buscar per similitud — i com encaixa cada tasca en l'operativa de TecnoMarket.

Curs de Deep Learning

Mòdul 1: Introducció al Deep Learning

Mòdul 2: Fonaments de Xarxes Neuronals

Mòdul 3: Xarxes Neuronals Convolucionals (CNN)

Mòdul 4: Xarxes Neuronals Recurrents (RNN)

Mòdul 5: Tècniques Avançades en Deep Learning

Mòdul 6: Eines i Frameworks

Mòdul 7: Projectes Pràctics

Mòdul 8: Consideracions Ètiques i Futur del Deep Learning

© Copyright 2026. Tots els drets reservats