đïž GoogleNet (Inception v1) â Le Guide Ultime
Deep Dive : ILSVRC 2014, Module Inception (1x1 Bottleneck), Global Avg Pooling & Dérivés (v3).
1. C'est quoi GoogleNet ?
Le CNN (Deep Learning) qui a *gagné* ILSVRC 2014. (VGG était 2Úme). 6.7% d'erreur.
GoogleNet ILSVRC 20142. Philosophie : Efficacité
VGG = "Profond & Lourd". GoogleNet = "Profond & Efficace". 7M params (vs 138M VGG).
EfficacitĂ© Params3. đ Le 1x1 "Bottleneck"
L'innovation "plugin" clé. Réduction de dimension (filtres) avant les Conv 3x3/5x5.
1x1 Bottleneck Dimension Reduction4. Le Module Inception (v1)
Le "bloc" de base. Convolutions parallÚles (1x1, 3x3, 5x5) concaténées.
Inception Concat5. đ Architecture (22 couches)
Un "stem" (tige) suivi d'une pile de 9 modules Inception.
Architecture Diagramme6. Global Average Pooling (GAP)
La 2e innovation. Tue les couches FC (Fully Connected) lourdes de VGG.
GAP FC Layers7. "Addon": Classifieurs Auxiliaires
Des "tĂȘtes" de classification (plugins) au milieu du rĂ©seau pour combattre le "Vanishing Gradient".
Auxiliary Vanishing Gradient8. đ GoogleNet vs VGG
Le "choc" de 2014. Efficacité (7M params) vs Simplicité (138M params).
VGG Params9. Code (PyTorch)
torchvision.models.googlenet(pretrained=True). Implémenter un InceptionBlock.
10. Code (Keras)
tf.keras.applications.InceptionV3(). (v3 est le standard, pas v1).
11. Frameworks Dérivés
Inception v2/v3 (BatchNorm!), v4, Inception-ResNet (le "plugin" ResNet).
InceptionV3 BatchNorm12. Héritage & Liens
Les "1x1 Bottlenecks" sont partout (ResNet, YOLO...). Liens (Papier, Blog).
Legacy LinksGoogleNet (aussi appelé Inception v1) est l'architecture de Réseau de Neurones Convolutif (CNN) qui a gagné le concours ILSVRC 2014 (ImageNet).
Il a été créé par une équipe de Google (Szegedy, Ioffe, Vanhoucke...). Son nom est un hommage à "LeNet" (de Yann LeCun) et au film "Inception" (à cause de ses modules imbriqués).
L'Impact (Les Chiffres ILSVRC 2014)
2014 a été la "bataille" entre la profondeur "brute" (VGG) et la profondeur "efficace" (GoogleNet).
| ModĂšle | Taux d'Erreur (Top-5) | Nb. ParamĂštres (Poids) |
|---|---|---|
| GoogleNet (Inception v1) | 6.7% (Gagnant) | ~7 Millions |
| VGG-16 | 7.3% (2Ăšme) | ~138 Millions |
| AlexNet (Réf. 2012) | 15.3% | ~61 Millions |
Conclusion : GoogleNet a prouvĂ© qu'un rĂ©seau pouvait ĂȘtre profond (22 couches) tout en Ă©tant extrĂȘmement efficace (20x moins de paramĂštres que VGG !). Il a introduit des "plugins" (concepts) que *tous* les rĂ©seaux modernes (ResNet, MobileNet, YOLO) utilisent aujourd'hui.
Le ProblÚme (Post-AlexNet) : "Plus profond = mieux" (VGG). Mais la profondeur a un coût :
1. Coût de Calcul : Des convolutions 5x5 ou 7x7 sont *trÚs* chÚres (beaucoup de multiplications).
2. Coût Mémoire : VGG-16 (138M params) pÚse > 500 MB. Inutilisable sur mobile.
3. Overfitting : Plus de paramĂštres = plus de risque de sur-apprentissage.
La Solution (GoogleNet) : Approximer un réseau "clairsemé" (sparse) par des blocs "denses".
L'idée (inspirée du cerveau) est qu'un neurone ne devrait se connecter qu'à *quelques* neurones précédents (sparse), pas à *tous* (dense). Mais le "sparse" est inefficace pour les GPUs.
Le "plugin" Inception (voir 1.4) est la solution : il utilise des filtres parallÚles (1x1, 3x3, 5x5) et des "bottlenecks" (goulots) 1x1 (voir 1.3) pour simuler un réseau "sparse" tout en restant "dense" (efficace) pour le GPU.
C'est le "plugin" le plus important de GoogleNet, utilisé *partout* aujourd'hui (y compris dans ResNet et YOLO).
Une Convolution 1x1 (appelée "Pointwise Convolution") est un filtre qui "regarde" 1 seul pixel, mais à travers *toute la profondeur* (tous les canaux). Son seul but est de réduire (ou augmenter) le nombre de filtres (canaux).
Le ProblÚme : Le coût d'un Conv 5x5
Imaginez une entrée (Input) de 28x28x192 (192 filtres).
Si je fais une Convolution 5x5 (pour 32 filtres) :
Nb. de Calculs (Poids) = (5*5 * 192) * 32 = 153 600. (TrĂšs cher).
La Solution : Le "Bottleneck" (Goulot)
Au lieu de faire 5x5 directement, on "triche" :
- Ătape 1 (RĂ©duction 1x1) : On rĂ©duit 192 filtres Ă 16.
Calcul :(1*1 * 192) * 16 = 3 072. (EntrĂ©e: 28x28x192 -> Sortie: 28x28x16) - Ătape 2 (Conv 5x5) : On fait le 5x5 sur la *petite* version.
Calcul :(5*5 * 16) * 32 = 12 800. (Entrée: 28x28x16 -> Sortie: 28x28x32)
Total : 3 072 + 12 800 = 15 872 poids.
RĂ©sultat : On a *divisĂ©* le coĂ»t de calcul par 10 (153k vs 15k) pour (presque) le mĂȘme rĂ©sultat sĂ©mantique.
Le Module Inception (le "plugin" de base) est le bloc qui utilise le "Bottleneck 1x1".
L'idée : "Pourquoi choisir (1x1, 3x3, ou 5x5) ? Faisons *tout* en parallÚle, et laissons le réseau apprendre."
Diagramme (Inception v1, avec Bottlenecks)
(Input)
|
+--------------------+--------------------+--------------------+
| | | |
⌠⌠⌠âŒ
[ Conv 1x1 ] [ Conv 1x1 (Bottleneck) ] [ Conv 1x1 (Bottleneck) ] [ MaxPool 3x3 ]
| | | |
| ⌠⌠âŒ
| [ Conv 3x3 ] [ Conv 5x5 ] [ Conv 1x1 (Bottleneck) ]
| | | |
+--------------------+--------------------+--------------------+
|
âŒ
[ CONCATENATE (par Filtre/Canal) ]
|
(Output)
Le "Bottleneck" 1x1 est utilisé *avant* les Conv 3x3 et 5x5 (pour réduire le coût) et *aprÚs* le MaxPool (pour aligner les filtres).
L'architecture complĂšte de GoogleNet (Inception v1) est un "Stem" (tige) de convolutions classiques, suivi d'une pile de 9 modules Inception.
Diagramme (Architecture GoogleNet)
(Input: Image 224x224x3)
|
âŒ
[ STEM (Conv 7x7 + MaxPool 3x3) ]
|
âŒ
[ Conv 1x1 + Conv 3x3 + MaxPool 3x3 ]
|
âŒ
[ Inception(3a) x 1 ]
[ Inception(3b) x 1 ]
|
âŒ
[ MaxPool 3x3 ]
|
âŒ
[ Inception(4a) x 1 ]
[ Inception(4b) x 1 ]
[ Inception(4c) x 1 ]
[ Inception(4d) x 1 ]
[ Inception(4e) x 1 ]
|
âŒ
[ MaxPool 3x3 ]
|
âŒ
[ Inception(5a) x 1 ]
[ Inception(5b) x 1 ]
|
âŒ
[ Global Average Pooling (GAP) ] (voir 1.6)
|
âŒ
[ Dropout (40%) ]
|
âŒ
[ FC (Fully Connected) (1000 neurones) ]
|
âŒ
[ Softmax ]
|
âŒ
(Sortie: 1000 classes ImageNet)
C'est la deuxiÚme innovation majeure (aprÚs le "1x1 bottleneck"). ResNet l'a ensuite copiée et popularisée.
Le ProblĂšme : Les couches "Fully Connected" (FC) de VGG
VGG (voir VGG 1.6) "aplatit" (Flatten) sa derniÚre sortie (7x7x512) en un vecteur géant (25088). Il le connecte ensuite à deux couches FC (4096 neurones).
Ces couches FC représentent > 80% des 138M de paramÚtres de VGG. Elles sont *trÚs* lourdes et causent de l'overfitting.
La Solution : Global Average Pooling (GAP)
GoogleNet *supprime* ces couches FC.
à la fin du réseau (aprÚs Inception(5b)), la sortie est 7x7x1024 (1024 filtres/canaux).
Le GAP (un "plugin" de pooling) prend *chaque* canal (7x7) et le réduit à 1 seul pixel (sa moyenne).
Résultat : 7x7x1024 -> 1x1x1024.
Ce vecteur (1024) est *directement* connecté à la couche de sortie Dense(1000).
Bénéfices :
1. Zéro (ou presque) paramÚtre (comparé aux 100M+ de VGG).
2. Réduit massivement l'overfitting.
3. Le modÚle est beaucoup plus "léger" (7M de params au total).
Le ProblÚme : GoogleNet (22 couches) est *trÚs* profond. Les créateurs avaient peur que le "Vanishing Gradient" (voir 1.2) soit un problÚme (ResNet n'existait pas encore).
La Solution (Plugin) : Ajouter des "sorties" (tĂȘtes de classification) au *milieu* du rĂ©seau.
Ces "classifieurs auxiliaires" sont des petites tĂȘtes FC (branchĂ©es aprĂšs Inception(4a) et Inception(4d)) qui tentent de prĂ©dire la classe (avec un "poids" de 0.3 sur la loss totale).
Diagramme (Flux du Gradient)
(Input) -> [STEM] -> [INCEPTION 3] -> [INCEPTION 4a] ----> (TĂȘte Auxiliaire 1) -> (Loss 1)
|
âŒ
[INCEPTION 4d] ----> (TĂȘte Auxiliaire 2) -> (Loss 2)
|
âŒ
[INCEPTION 5] -> [GAP] -> (TĂȘte Principale) -> (Loss 3)
(Loss Totale = 1.0 * Loss_3 + 0.3 * Loss_2 + 0.3 * Loss_1)
But : "Injecter" du gradient (signal d'erreur) directement dans les couches du milieu, pour les forcer Ă apprendre (combattre le vanishing gradient).
Important : Ces tĂȘtes auxiliaires ne sont utilisĂ©es que pendant l'ENTRAĂNEMENT (training). Elles sont *retirĂ©es* pendant l'INFĂRENCE (production).
Le concours ILSVRC 2014 a opposé deux philosophies :
| CritĂšre | VGG-16 (Oxford) | GoogleNet (Google) |
|---|---|---|
| Philosophie | Simplicité & Uniformité | Efficacité & Complexité |
| Bloc de base | Pile de Conv 3x3 | Module "Inception" (parallĂšle) |
| Profondeur | 16 couches | 22 couches |
| TĂȘte (Classifier) | 2x couches FC-4096 (Lourd) | Global Average Pooling (GAP) (LĂ©ger) |
| ParamĂštres (Poids) | ~138 Millions | ~7 Millions (20x moins !) |
| Taille (Disque) | ~528 MB | ~27 MB |
| Résultat (ILSVRC) | 7.3% (2Úme) | 6.7% (Gagnant) |
Conclusion : GoogleNet a gagné, mais VGG (plus simple) est devenu le "Backbone" (plugin) préféré pour le *Transfer Learning* (voir 2.3) pendant plusieurs années, car son architecture "linéaire" était plus facile à découper et à réutiliser.
Le "plugin" torchvision (l'addon officiel de PyTorch pour la vision) fournit le modÚle GoogleNet (Inception v1) pré-entraßné sur ImageNet.
Exemple (Inférence simple)
import torch
from torchvision import models, transforms
from PIL import Image
# 1. Charger GoogleNet pré-entraßné
# (Note: torchvision.models.googlenet)
model = models.googlenet(pretrained=True)
model.eval() # IMPORTANT: Mode Ă©valuation (dĂ©sactive les tĂȘtes auxiliaires)
# 2. Définir les transforms (standard ImageNet)
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_chat.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)
top_class_index = torch.argmax(probabilities).item()
# (Charger les 1000 labels d'ImageNet...)
print(f"Prédiction: Classe {top_class_index}") # (ex: 281, 'tabby cat')
L'écosystÚme Keras (intégré à TensorFlow) fournit également GoogleNet, mais sous son nom "dérivé" le plus populaire : InceptionV3 (voir 3.2).
InceptionV3 est la version "moderne" de GoogleNet (elle inclut Batch Normalization et autres améliorations).
include_top=False (Le "Plugin" Transfer Learning)
Keras rend le Transfer Learning (l'usage n°1) trÚs facile avec l'argument include_top.
import tensorflow as tf
from tensorflow.keras.applications.inception_v3 import InceptionV3, preprocess_input, decode_predictions
from tensorflow.keras.preprocessing import image
import numpy as np
# --- 1. InfĂ©rence Simple (Avec la "TĂȘte") ---
# (Note: InceptionV3 attend du 299x299)
model_full = InceptionV3(weights='imagenet', include_top=True)
img = image.load_img('mon_chat.jpg', target_size=(299, 299))
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)
model_features = InceptionV3(weights='imagenet', include_top=False)
# 'preds_features' n'est PAS (1, 1000),
# c'est la sortie du "Backbone"
preds_features = model_features.predict(x)
GoogleNet (v1) n'était que le début. Les auteurs ont continué d'améliorer le "plugin" Inception.
| ModÚle (Dérivé) | Innovation (Le "Plugin") |
|---|---|
| Inception v2 (2015) | Batch Normalization (BN). L'ajout de BatchNorm (normalisation des activations) aprÚs chaque Conv. (C'est l'autre "grande" idée de 2015, avec ResNet). |
| Inception v3 (2015) | Factorisation des Convolutions. Le "plugin" VGG : Remplacer Conv 5x5 par 2x Conv 3x3. Et (nouveau) : remplacer Conv 7x7 par 1x7 + 7x1. (Encore moins de calculs). (C'est le InceptionV3 standard de Keras/PyTorch). |
| Inception v4 (2016) | Nettoyage de l'architecture (Stem). |
| Inception-ResNet (2016) | L'hybride. Combine les "plugins" : Inception Blocks (efficacité) + Residual (Skip) Connections (stabilité). ( Sortie = Inception(x) + x). |
Héritage
GoogleNet n'est (presque) plus utilisé "tel quel" (InceptionV1). Il a été remplacé par InceptionV3 (mieux) ou ResNet-50 (plus simple et performant).
Mais son héritage ("plugin") est *fondamental* :
- Le "1x1 Bottleneck" : C'est la brique de base de ResNet (voir 1.5), MobileNet, et de tous les "necks" (YOLO, ...).
- Global Average Pooling (GAP) : A tué les couches FC, permettant des réseaux beaucoup plus profonds et légers.
- Idée "ParallÚle" : L'idée d'avoir plusieurs "branches" (paths) dans un bloc est revenue en force (ex:
C2fde YOLOv8).
