Un réseau convolutif dont les blocs sont court-circuités par des raccourcis : chaque bloc n'apprend qu'une correction de ce qu'il reçoit. Ces connexions résiduelles ont permis d'entraîner des réseaux de plus de 100 couches. Les ResNet pré-entraînés sont aujourd'hui le point de départ le plus courant d'un projet de vision en entreprise.
Un document relu par 50 correcteurs à la suite. Plutôt que de réécrire le texte, chacun ne note que ses corrections en marge. Si un correcteur n'a rien à dire, le texte passe intact au suivant.
Au-delà d'une vingtaine de couches, un réseau classique apprend moins bien que sa version plus courte, même sur les données d'entraînement. Ce n'est pas du surapprentissage : l'optimisation peine à régler autant de couches empilées.
Chaque bloc de deux convolutions (trois dans ResNet-50 et au-delà) reçoit une entrée x et rend x + F(x) : son entrée, plus une correction apprise. Si le bloc n'est pas utile, il lui suffit d'apprendre une correction nulle.
Pendant l'apprentissage, l'erreur remonte aussi par les raccourcis, sans s'affaiblir. Les premières couches continuent d'apprendre, même à 150 couches de profondeur.
Un ResNet entraîné sur des millions d'images (ImageNet) sait déjà voir bords, textures et formes. On ne réentraîne que les dernières couches sur ses propres images : c'est le transfert d'apprentissage.
1 797 chiffres scannés en 8 × 8 pixels. Le code empile 8 blocs résiduels, soit 17 couches de convolution, pour montrer la mécanique du raccourci sur des données légères.
Chaque chiffre du code postal est lu avec sa probabilité. Sur des images aussi petites, un CNN simple suffit : l'intérêt d'un ResNet apparaît sur de vraies photos, plus grandes et plus variées.
L'exactitude sur des images jamais vues, puis la part de colis envoyés en lecture manuelle faute de confiance suffisante. Sur de vraies images, on compare toujours le ResNet pré-entraîné à un CNN simple avant de choisir.
En entreprise, on part presque toujours d'un ResNet existant. Les décisions portent sur la taille et l'adaptation.
ResNet-18 et 34 : légers, suffisants pour beaucoup de cas. ResNet-50 : le standard, environ 25 millions de paramètres. ResNet-101 et 152 : pour les cas difficiles et les gros volumes.
weights="imagenet" dans keras.applications, ou les poids de torchvision. De zéro seulement avec des centaines de milliers d'images.
Peu d'images : figer le réseau et n'entraîner que la dernière couche. Plus d'images : dégeler aussi les derniers blocs, avec un pas d'apprentissage faible.
Les ResNet pré-entraînés attendent des images en couleur, souvent 224 × 224, préparées avec la fonction preprocess_input du modèle. Une préparation différente de l'entraînement d'origine fait chuter la précision.
# Tri postal : ResNet (réseau résiduel) en Python (Keras)
import pandas as pd
import keras
from keras import layers
from sklearn.model_selection import train_test_split
chiffres = pd.read_csv("chiffres_manuscrits.csv")
X = (chiffres.drop(columns="chiffre").values / 16).reshape(-1, 8, 8, 1).astype("float32")
y = chiffres["chiffre"].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
def bloc_residuel(x):
h = layers.Conv2D(32, 3, padding="same", use_bias=False)(x)
h = layers.Activation("relu")(layers.BatchNormalization()(h))
h = layers.BatchNormalization()(layers.Conv2D(32, 3, padding="same", use_bias=False)(h))
return layers.Activation("relu")(layers.Add()([x, h])) # le raccourci : entrée du bloc + correction
keras.utils.set_random_seed(42)
entree = keras.Input((8, 8, 1))
x = layers.Conv2D(32, 3, padding="same", activation="relu")(entree)
for _ in range(8): # 8 blocs : 17 couches de convolution au total
x = bloc_residuel(x)
sortie = layers.Dense(10, activation="softmax")(layers.GlobalAveragePooling2D()(x))
resnet = keras.Model(entree, sortie)
resnet.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
resnet.fit(X_train, y_train, epochs=20, batch_size=32, validation_split=0.1, verbose=0)
print("Couches de convolution :", sum(isinstance(c, layers.Conv2D) for c in resnet.layers))
print("Exactitude test :", round(resnet.evaluate(X_test, y_test, verbose=0)[1], 3))
Les ResNet se pratiquent en Python (Keras, PyTorch) ; keras3 permet de les charger en R, mais l'usage en entreprise reste marginal.
C'est un raccourci qui ajoute l'entrée d'un bloc de couches à sa sortie : le bloc rend x + F(x). Le bloc n'a plus à reproduire tout le signal, seulement à apprendre une correction. Cette idée simple a permis de passer d'une vingtaine à plus de cent couches.
C'est le nombre de couches à poids du réseau : 50 couches, pour la plupart des convolutions. ResNet-18, 34, 50, 101 et 152 sont les versions publiées en 2015 par l'équipe de Microsoft Research, qui a gagné le concours ImageNet cette année-là.
Les Vision Transformers dépassent les ResNet quand ils sont pré-entraînés sur d'énormes volumes d'images. Avec peu de données ou un matériel modeste, un ResNet pré-entraîné reste un choix robuste, rapide et bien outillé. Le mieux est de comparer les deux sur un échantillon de ses propres images.
Quelques couches de convolution sans raccourci. Suffisant sur des images petites et simples.
Voir la fiche → l'usage courantRéutiliser un ResNet entraîné sur ImageNet et l'adapter à ses images avec peu d'exemples.
Voir la fiche → l'autre ingrédientPrésente dans chaque bloc résiduel. Avec les raccourcis, elle rend l'entraînement profond stable.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus