Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

🏛️ VGG16 / VGG19 – Le Guide Ultime

Deep Dive : Architecture (3x3), ILSVRC 2014, VGG16 vs VGG19, Transfer Learning & Perceptual Loss.

1.1 Facile

1. C'est quoi VGG ?

Visual Geometry Group (Oxford). CNN "très profond" (ILSVRC 2014).

VGG CNN
1.2 Moyen

2. Philosophie : "La Profondeur"

L'innovation clé : petits filtres (3x3) empilés très profondément (vs gros filtres AlexNet).

3x3 Filter Architecture
1.3 Moyen

3. 📊 VGG16 vs VGG19

16 couches vs 19 couches. VGG19 est plus lourd (144M params) pour un gain de mAP minime.

VGG16 VGG19
1.4 Avancé

4. 📈 Architecture (Blocs)

Une pile simple de blocs [Conv 3x3 - Conv 3x3 - MaxPool 2x2]. 138M params.

Architecture Diagramme
1.5 Avancé

5. Le Filtre 3x3 (Magie)

2x (3x3 Conv) a le même champ réceptif que 1x (5x5 Conv) avec moins de poids.

3x3 Filter Receptive Field
1.6 Moyen

6. Limites (Taille & Vitesse)

Obsolète pour la classif. ~140M params, >500MB sur disque. Très lent (vs ResNet).

Params Vitesse
2.1 Avancé

7. Code (PyTorch)

torchvision.models.vgg16(pretrained=True). model.features vs model.classifier.

PyTorch torchvision
2.2 Avancé

8. Code (Keras)

tf.keras.applications.VGG16(). include_top=False (pour Transfer Learning).

Keras TensorFlow
2.3 Avancé

9. 🚀 Cas: Transfer Learning

L'usage moderne. Geler features, remplacer classifier (FC layers).

Transfer Learning Feature Extractor
3.1 Avancé

10. Projet: Neural Style Transfer

Le "plugin" artistique. Utilise les "features" VGG pour séparer "contenu" et "style".

Style Transfer Gatys
3.2 Avancé

11. Addon: VGG Loss

Perceptual Loss. Utiliser VGG comme "juge" (plugin) pour les GANs, Super-Resolution.

Perceptual Loss GAN
3.3 Moyen

12. Héritage & Liens

L'ancêtre de ResNet et Vision Transformer (ViT). Liens (Papier, Roboflow).

ResNet ViT
1.1 C'est quoi VGG ? (Visual Geometry Group)

VGG (Visual Geometry Group) est le nom d'une famille de Réseaux de Neurones Convolutifs (CNN) créée par l'Université d'Oxford (K. Simonyan & A. Zisserman) en 2014.

L'Événement : C'est le "dauphin" (runner-up) du concours ILSVRC 2014 (gagné par GoogLeNet). Bien qu'il n'ait pas gagné, VGG est devenu *plus influent* que GoogLeNet en raison de sa simplicité architecturale.

VGG est la suite directe d'AlexNet (2012). Il a répondu à la question : "Que se passe-t-il si nous prenons AlexNet, que nous retirons ses "hacks" (gros filtres 11x11, LRN) et que nous le rendons *beaucoup, beaucoup plus profond* (deep) ?".

Chiffres Clés (ILSVRC 2014)
ModèleProfondeurErreur Top-5Innovation
GoogLeNet (Gagnant)22 couches6.7%Module "Inception" (efficacité)
VGG (Dauphin)16-19 couches7.3%Simplicité (Filtres 3x3 uniformes)
AlexNet (Référence 2012)8 couches15.3%Le "Big Bang"
1.2 Philosophie : L'importance des petits filtres (3x3)

L'innovation *majeure* de VGG n'est pas un "plugin" compliqué, c'est une simplification extrême.

AlexNet (2012) utilisait un "chaos" de tailles de filtres (11x11, 5x5, 3x3).
VGG (2014) a posé la question : "Peut-on *uniquement* utiliser le plus petit filtre possible (3x3) et l'empiler ?".

Le "Champ Réceptif" (Receptive Field)

L'astuce est que deux couches de filtres 3x3 (empilées) ont le *même* "champ réceptif" (la zone de l'image qu'elles "voient") qu'une seule couche 5x5.
...et trois couches 3x3 équivalent à une couche 7x7.

Pourquoi est-ce mieux ? (Diagramme)
1x Filtre 5x5 (Ancienne méthode)
(Image 5x5) -> [Conv 5x5] -> (Output 1x1)
- Nb de Poids (Params) : 5*5 = 25
- Nb de "Non-linéarités" (ReLU) : 1
2x Filtres 3x3 (Méthode VGG)
(Image 5x5) -> [Conv 3x3] -> (Image 3x3) -> [ReLU]
            -> [Conv 3x3] -> (Output 1x1) -> [ReLU]
- Nb de Poids (Params) : (3*3) + (3*3) = 18
- Nb de "Non-linéarités" (ReLU) : 2

Résultat : Un stack de 3x3 (style VGG) est plus profond (plus de ReLU, donc plus "intelligent") et a moins de paramètres (18 vs 25) pour le *même* champ réceptif. C'est le "plugin" architectural de VGG.

1.3 📊 VGG16 vs VGG19 (Chiffres)

VGG16 et VGG19 sont les deux architectures principales du papier. La seule différence est que VGG19 ajoute 3 couches de convolution (Conv 3x3) supplémentaires.

ModèleCouches (Poids)Paramètres (Total)Taille (.pth)Erreur Top-5 (ImageNet)
VGG1613 Conv + 3 FC = 16~138 Millions~528 MB7.15% (Keras)
VGG1916 Conv + 3 FC = 19~144 Millions~549 MB7.13% (Keras)
Conclusion (Le "Trade-off")

VGG19 n'est *pas* meilleur que VGG16.

L'ajout de couches (et de 6M de paramètres) n'apporte (presque) aucun gain de précision (7.13% vs 7.15%). En fait, il "overfit" (sur-apprend) *davantage* que VGG16 sur de nombreux datasets.

Règle : Dans 99% des cas (surtout en Transfer Learning), on utilise VGG16. C'est le "sweet spot" (point d'équilibre) entre la profondeur et le sur-apprentissage.

1.4 📈 Architecture (Les Blocs VGG)

L'architecture de VGG16 est belle de simplicité. C'est juste un empilement de "blocs" Conv-Conv-Pool.
La seule chose qui change est le nombre de filtres (profondeur), qui *double* après chaque MaxPool (64 -> 128 -> 256 -> 512).

Diagramme (Architecture VGG16)
(Input: Image 224x224x3)
     |
     ▼
[ Bloc 1: Conv(64) x2 + MaxPool(2x2, S2) ] (-> 112x112x64)
     |
     ▼
[ Bloc 2: Conv(128) x2 + MaxPool(2x2, S2) ] (-> 56x56x128)
     |
     ▼
[ Bloc 3: Conv(256) x3 + MaxPool(2x2, S2) ] (-> 28x28x256)
     |
     ▼
[ Bloc 4: Conv(512) x3 + MaxPool(2x2, S2) ] (-> 14x14x512)
     |
     ▼
[ Bloc 5: Conv(512) x3 + MaxPool(2x2, S2) ] (-> 7x7x512)
     |
     | (Flatten -> 7*7*512 = 25088)
     ▼
[ FC 6 (Fully Connected) (4096 neurones) + ReLU + Dropout ]
     |
     ▼
[ FC 7 (Fully Connected) (4096 neurones) + ReLU + Dropout ]
     |
     ▼
[ FC 8 (Output) (1000 neurones) + Softmax ]
     |
     ▼
(Sortie: 1000 classes ImageNet)

VGG19 ? C'est la même chose, mais les Blocs 3, 4, et 5 ont 4 couches Conv au lieu de 3.

1.5 Le Filtre 3x3 (La "Magie")

L'innovation *majeure* de VGG n'est pas un "plugin" compliqué, c'est une simplification extrême.

AlexNet (2012) utilisait un "chaos" de tailles de filtres (11x11, 5x5, 3x3).
VGG (2014) a posé la question : "Peut-on *uniquement* utiliser le plus petit filtre possible (3x3) et l'empiler ?".

Le "Champ Réceptif" (Receptive Field)

L'astuce est que deux couches de filtres 3x3 (empilées) ont le *même* "champ réceptif" (la zone de l'image qu'elles "voient") qu'une seule couche 5x5.
...et trois couches 3x3 équivalent à une couche 7x7.

Pourquoi est-ce mieux ? (Diagramme)
1x Filtre 5x5 (Ancienne méthode)
(Image 5x5) -> [Conv 5x5] -> (Output 1x1)
- Nb de Poids (Params) : 5*5 = 25
- Nb de "Non-linéarités" (ReLU) : 1
2x Filtres 3x3 (Méthode VGG)
(Image 5x5) -> [Conv 3x3] -> (Image 3x3) -> [ReLU]
            -> [Conv 3x3] -> (Output 1x1) -> [ReLU]
- Nb de Poids (Params) : (3*3) + (3*3) = 18
- Nb de "Non-linéarités" (ReLU) : 2

Résultat : Un stack de 3x3 (style VGG) est plus profond (plus de ReLU, donc plus "intelligent") et a moins de paramètres (18 vs 25) pour le *même* champ réceptif. C'est le "plugin" architectural de VGG.

1.6 Limites (Taille, Vitesse, Obsolescence)

VGG a été une étape cruciale, mais il est aujourd'hui obsolète pour la *classification* (SOTA - State-of-the-Art) en raison de deux défauts majeurs :

1. Le Poids (138M+ Paramètres)

La quasi-totalité des paramètres de VGG (~120M sur 138M) ne sont *pas* dans les convolutions (le "Backbone"), mais dans les dernières couches "Fully Connected" (FC).

Le (7x7x512) est "aplati" (flatten) en 25 088 neurones, qui sont connectés à 4096, qui sont connectés à 4096.
Rien que la première couche FC (25088 * 4096) représente 102 millions de poids.

Conséquence : Le fichier .pth (poids) de VGG16 pèse ~528 MB.
En comparaison, ResNet-50 (qui est *plus* précis) ne pèse que ~98 MB.

2. La Vitesse (Compute)

138M de paramètres, c'est *beaucoup* de multiplications. VGG est lent à l'entraînement et lent à l'inférence par rapport aux architectures modernes (ResNet, MobileNet).

3. Le "Vanishing Gradient" (Obsolète)

VGG (19 couches) était la *limite* de ce qu'on pouvait entraîner. Plus profond (ex: 30 couches), le "vanishing gradient" (voir AlexNet 1.4) revenait.
L'arrivée de ResNet (2015) et ses "Skip Connections" (voir AlexNet 3.2) a résolu ce problème et a rendu VGG obsolète pour la classification.

2.1 Code : Inférence & "Addon" (PyTorch)

Le "plugin" torchvision (l'addon officiel de PyTorch pour la vision) fournit le modèle VGG pré-entraîné sur ImageNet.

Exemple (Inférence simple)
import torch
from torchvision import models, transforms
from PIL import Image

# 1. Charger VGG16 pré-entraîné
# (Télécharge 528MB la 1ère fois)
model = models.vgg16(pretrained=True)
model.eval() # IMPORTANT: Mode évaluation (désactive Dropout)

# 2. Définir les transforms (standard VGG)
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], 
                         std=[0.229, 0.224, 0.225]),
])

# 3. Charger & Pré-processer l'image
img = Image.open("mon_chien.jpg")
img_t = preprocess(img)
batch_t = torch.unsqueeze(img_t, 0) # (Ajoute la dimension batch)

# 4. Inférence
with torch.no_grad():
    output = model(batch_t) # (Output: [1, 1000])

# 5. Interpréter
probabilities = torch.nn.functional.softmax(output[0], dim=0)
top5_prob, top5_catid = torch.topk(probabilities, 5)

# (Charger les labels ImageNet...)
print(f"Classe prédite (ID): {top5_catid[0]}")
2.2 Code : Inférence & "Addon" (Keras/TensorFlow)

L'écosystème Keras (intégré à TensorFlow) fournit également VGG comme "plugin" (keras.applications).

include_top=False (Le "Plugin" Transfer Learning)

Keras rend le Transfer Learning (voir 2.3) *très* facile avec l'argument include_top.

import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input, decode_predictions
from tensorflow.keras.preprocessing import image
import numpy as np

# --- 1. Inférence Simple (Avec la "Tête") ---
model_full = VGG16(weights='imagenet', include_top=True)

img = image.load_img('mon_chien.jpg', target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x) # (Normalisation Keras)

preds = model_full.predict(x)
print(decode_predictions(preds, top=3)[0])
# (Affiche les 3 top prédictions ImageNet)


# --- 2. Mode "Feature Extractor" (Sans la "Tête") ---
# (C'est la base du Transfer Learning, voir 2.3)
model_features = VGG16(weights='imagenet', include_top=False)

# 'preds_features' n'est PAS (1, 1000), 
# c'est la sortie du "Backbone" (1, 7, 7, 512)
preds_features = model_features.predict(x)
2.3 🚀 Cas: Transfer Learning (Feature Extractor)

C'est l'usage n°1 de VGG16 aujourd'hui.
Le Problème : Je veux classer "Hotdog" vs "Not Hotdog", mais je n'ai que 500 images.
La Solution : Le Transfer Learning (Apprentissage par Transfert).

Les premières couches d'un CNN (comme VGG) apprennent des features *génériques* (détection de bords, textures, coins). Ces "yeux" (entraînés sur 1.1M d'images ImageNet) sont *plus performants* que tout ce qu'on peut entraîner sur 500 images.

Le Workflow (Keras)
  1. Charger le "Backbone" : On charge VGG16 *sans* sa tête (include_top=False).
  2. Geler (Freeze) : On dit à Keras de ne *pas* ré-entraîner les 138M de poids (trainable = False).
  3. Ajouter notre "Tête" : On ajoute *nos propres* couches (Dense) à la fin (ex: Dense(2) pour "hotdog" / "not_hotdog").
  4. Entraîner : On n'entraîne *que* notre (petite) tête sur nos 500 images.
import tensorflow as tf
from tensorflow.keras import layers, models

# 1. Charger VGG16 (le "backbone") pré-entraîné
vgg_base = tf.keras.applications.VGG16(
    weights='imagenet',
    include_top=False, # (Important !)
    input_shape=(224, 224, 3)
)

# 2. Geler (Freeze) le backbone
vgg_base.trainable = False

# 3. Créer notre nouveau modèle (le "plugin" par-dessus)
model = models.Sequential([
    vgg_base, # (Le backbone gelé)
    
    # 4. Notre "Tête" (Classifier)
    layers.Flatten(),
    layers.Dense(256, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(1, activation='sigmoid') # (1 neurone: hotdog/not_hotdog)
])

# 5. Compiler et entraîner
# (On n'entraîne QUE les 3 couches Dense)
model.compile(optimizer='adam', ...)
model.fit(mon_dataset_hotdog, ...)
3.1 Projet: Neural Style Transfer (Gatys et al.)

C'est le projet (l' "addon" artistique) qui a rendu VGG célèbre *en dehors* de la classification. C'est l'algorithme "Deep Dream" (Gatys et al., 2015) qui permet de "peindre" une photo avec le style d'un Van Gogh.

Pourquoi VGG ? (Contenu vs Style)

Les chercheurs ont découvert que les différentes couches d'un CNN (comme VGG) séparent le "contenu" du "style" :

  • Couches "Basses" (ex: conv1_1) : Les features sont simples (bords, couleurs). Elles représentent le Style.
  • Couches "Hautes" (ex: conv4_2) : Les features sont sémantiques (formes, "visage", "maison"). Elles représentent le Contenu.
Le Processus (Simplifié)
  1. On prend 3 images : Contenu (une photo), Style (ex: Van Gogh), Résultat (un bruit blanc).
  2. On charge un VGG19 pré-entraîné (gelé).
  3. On lance une "boucle d'optimisation" (des milliers de fois) :
  4. a. (Content Loss) : On passe Contenu et Résultat dans VGG. On calcule la "distance" (MSE) entre les "features hautes" (conv4_2). On ajuste Résultat.
  5. b. (Style Loss) : On passe Style et Résultat dans VGG. On calcule la "distance" entre les "features basses" (via une "Matrice de Gram"). On ajuste Résultat.

Résultat : Le Résultat (le bruit blanc) "devient" l'image de Contenu, mais "peinte" avec la texture (Style) de Van Gogh.

3.2 Addon: VGG Loss (Perceptual Loss)

C'est l'utilisation "plugin" la plus avancée de VGG. VGG (ou "Perceptual") Loss est une "fonction de coût" (Loss Function) utilisée pour entraîner *d'autres* réseaux (ex: des GANs, ou des réseaux de Super-Résolution).

Le Problème (Loss L1 / L2)

Objectif : Apprendre à une IA à "déflouter" (deblur) une image.
Loss Classique (L2/MSE) : loss = (image_predite - image_reelle) ** 2.
Problème : Le L2 encourage les images *floues* (c'est la "moyenne" la plus sûre). Le résultat est "correct" mais visuellement moche.

La Solution (VGG Loss)

L'idée : "Ne pas comparer les *pixels* (L2), mais comparer ce que *VGG pense* des images."

Diagramme (Entraînement de "MonModele")
(Image Floue)
      |
      ▼
+-----------------+
| MonModele (Générateur)
| (Apprend)
+-----------------+
      |
      ▼
(Image Prédite) ----+
                    |
(Image Réelle) -----|
                    ▼
            +----------------+
            | VGG16 (Gelé)   | (Le "Juge")
            | (N'apprend PAS)|
            +----------------+
                    |
                    ▼
            (Features Prédites)
            (Features Réelles)
                    |
                    ▼
            (Calcul de la "Distance" L2 entre les *features*)
                    |
                    ▼
                 (Loss) -> (Backpropagation vers "MonModele")

On "force" le générateur (MonModele) à produire une image qui, pour VGG, *ressemble* (perceptuellement) à l'image réelle. Cela produit des résultats beaucoup plus nets et réalistes.

3.3 Héritage & Liens

AlexNet (2012) a prouvé que "Deep" (profond) était la voie. VGG (2014) a prouvé que "Très Profond" (Very Deep) avec des filtres *uniformes* (3x3) l'était encore plus.

VGG a été le "Backbone" standard (le "plugin" feature extractor) de 2014 à 2016, jusqu'à l'arrivée de ResNet (2015), qui a résolu le problème de la profondeur (Vanishing Gradient) et reste le roi aujourd'hui.

Généalogie (Backbones) :
LeNet (1998) -> AlexNet (2012) -> VGG (2014) -> GoogLeNet (2014) -> ResNet (2015) -> Vision Transformer (ViT) (2020)