Un réseau de neurones qui colorie une image pixel par pixel : chaque pixel reçoit une classe, défaut ou non, tumeur ou tissu sain, route ou champ. Sa forme en U combine une descente qui comprend l'image et une remontée qui retrouve la précision du contour. C'est l'architecture de référence de la segmentation, née en imagerie médicale.
Un expert qui regarde d'abord la radio de loin pour comprendre ce qu'il voit, puis reprend sa loupe et ses premières notes de détail pour tracer le contour exact de la zone suspecte.
Des convolutions et des réductions successives rétrécissent l'image (32, puis 16, puis 8 pixels de côté) et construisent des motifs de plus en plus abstraits : il y a une tache, elle est à peu près ici.
Des agrandissements successifs ramènent l'image à sa taille d'origine pour produire une carte de même format que l'entrée.
À chaque étage, la remontée reçoit aussi une copie des cartes de la descente. Elle récupère ainsi les détails fins perdus en rétrécissant : c'est ce qui rend les contours nets.
La dernière couche donne, pour chaque pixel, la probabilité d'appartenir au défaut. Un seuil à 50 % donne le masque final.
Simulation de 600 images de 32 × 32 pixels : une surface bruitée avec une tache de défaut de taille et de position variables. Pour chaque image, un masque indique les pixels du défaut.
Pour chaque nouvelle image, la carte des pixels défectueux. On en tire la surface et la position du défaut, pour décider du rebut, de la retouche ou du déclassement de la pièce.
Le défaut ne couvre qu'une petite part de l'image : un modèle qui ne voit jamais rien aurait plus de 95 % de pixels justes. L'IoU (intersection sur union) mesure le recouvrement entre le masque prédit et le vrai : 1 si parfait, 0 si aucun pixel commun.
Noms donnés pour Keras ; la bibliothèque segmentation_models_pytorch propose des U-Net prêts à l'emploi.
Le nombre d'étages de descente. Plus le U est profond, plus le réseau voit large. Il faut que l'objet à segmenter tienne dans ce que voit le fond du U.
L'entropie croisée binaire par pixel est le départ. Si l'objet est minuscule par rapport au fond, on ajoute une perte Dice, qui compte le recouvrement plutôt que les pixels justes.
Remplacer la descente par un ResNet pré-entraîné sur ImageNet. Avec peu d'images annotées, c'est souvent le gain le plus important.
Rotations, symétries, variations de luminosité appliquées à l'image et à son masque en même temps. Indispensable avec quelques centaines d'exemples.
# Défauts sur tôles : U-Net en Python (Keras)
import numpy as np
import keras
from keras import layers
# Simulation : 600 images 32 x 32 de tôle bruitée, chacune avec une tache de défaut
rng = np.random.default_rng(42)
n, t = 600, 32
yy, xx = np.mgrid[:t, :t]
cx, cy, r = rng.integers(6, 26, n), rng.integers(6, 26, n), rng.integers(2, 6, n)
masques = ((xx - cx[:, None, None]) ** 2 + (yy - cy[:, None, None]) ** 2 < r[:, None, None] ** 2).astype("float32")[..., None]
images = (0.5 * masques + rng.normal(0.3, 0.15, (n, t, t, 1))).astype("float32")
keras.utils.set_random_seed(42)
entree = keras.Input((t, t, 1))
c1 = layers.Conv2D(16, 3, padding="same", activation="relu")(entree) # 32 x 32
c2 = layers.Conv2D(32, 3, padding="same", activation="relu")(layers.MaxPooling2D()(c1)) # 16 x 16
c3 = layers.Conv2D(64, 3, padding="same", activation="relu")(layers.MaxPooling2D()(c2)) # 8 x 8, le fond du U
u2 = layers.Conv2D(32, 3, padding="same", activation="relu")(layers.Concatenate()([layers.UpSampling2D()(c3), c2]))
u1 = layers.Conv2D(16, 3, padding="same", activation="relu")(layers.Concatenate()([layers.UpSampling2D()(u2), c1]))
sortie = layers.Conv2D(1, 1, activation="sigmoid")(u1) # probabilité de défaut par pixel
unet = keras.Model(entree, sortie)
unet.compile(optimizer="adam", loss="binary_crossentropy")
unet.fit(images[:500], masques[:500], epochs=15, batch_size=32, verbose=0)
pred, vrai = unet.predict(images[500:], verbose=0) > 0.5, masques[500:] > 0.5
# IoU : pixels de défaut communs / pixels marqués par l'un ou l'autre
print("IoU sur 100 images test :", round((pred & vrai).sum() / (pred | vrai).sum(), 3))
Les U-Net se pratiquent en Python (Keras, PyTorch, segmentation_models_pytorch) : pas d'usage R courant en entreprise.
La détection encadre chaque objet par une boîte et lui donne une classe. La segmentation attribue une classe à chaque pixel et donne donc le contour exact. On détecte pour compter ou localiser ; on segmente pour mesurer une surface ou une forme.
Chaque image fournit des milliers d'exemples, un par pixel, et les convolutions partagent leurs poids sur toute l'image. Avec de l'augmentation de données, quelques dizaines à quelques centaines d'images annotées suffisent souvent. U-Net a été présenté en 2015 sur des jeux médicaux de quelques dizaines d'images.
Avec l'IoU (intersection sur union) ou le coefficient de Dice, qui mesurent le recouvrement entre le masque prédit et le masque réel. L'exactitude par pixel est trompeuse dès que l'objet est petit, car le fond domine le calcul.
Les convolutions de la descente du U. Seul, un CNN classe l'image entière, sans localiser.
Voir la fiche → encadrer plutôt que détourerDonne une boîte autour de chaque objet, sans le contour exact. Annotation bien plus rapide.
Voir la fiche → la même formeCompresse puis reconstruit l'image. U-Net en reprend la forme et ajoute les ponts entre les deux moitiés.
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