Détection de défauts sur pont roulant sans données annotées
Approche : pré-entraînement auto-supervisé par apprentissage contrastif + ajustement avec peu d'exemples
En utilisant 5 000 images non annotées de composants de pont roulant (câble métallique, roue, rail, crochet, frein), un backbone ResNet-18 est pré-entraîné par apprentissage contrastif avec SimCLR (perte NT-Xent, coefficient de température τ=0,5, Batch=256) et MoCo v2 (codeur à momentum m=0,999, longueur de file d'attente 4 096). Après le pré-entraînement, la tête de classification est ajustée avec 100 images annotées : SimCLR + 100 annotations F1=0,89, MoCo v2 + 100 annotations F1=0,90. Ces résultats surpassent le pré-entraînement ImageNet (F1=0,85, soit +4~5 %) et l'entraînement from scratch (F1=0,62, soit +27 %). Avec 500 annotations, l'apprentissage contrastif atteint F1=0,93, proche de la limite supérieure supervisée (F1=0,94).
Le principal goulot d'étranglement pour la détection des défauts sur les composants de pont roulant n'est pas la conception du modèle, mais les données annotées : 5 000 images non annotées peuvent être capturées en 1 à 2 jours, alors que l'annotation de données équivalentes nécessite 2 à 3 semaines. L'apprentissage contrastif (Contrastive Learning) consiste à construire des « paires positives-négatives » sur des données non annotées pour une tâche de pré-entraînement auto-supervisée, apprenant ainsi des représentations visuelles génériques. Seules 100 à 500 images annotées sont ensuite nécessaires pour un ajustement (fine-tuning) avant déploiement. Cet article prend pour exemples SimCLR (2020, Google) et MoCo v2 (2020, FAIR), deux méthodes d'apprentissage contrastif populaires, et évalue l'efficacité d'un pré-entraînement auto-supervisé suivi d'un ajustement avec peu d'annotations sur un jeu de données de défauts de composants de pont roulant, en comparaison avec un pré-entraînement ImageNet et un entraînement from scratch. Environnement expérimental : PyTorch 2.1.0 + NVIDIA A10 (48 Go) + 4×RTX 4090 (pour les grands Batchs SimCLR).
Principe de l'apprentissage contrastif
L'idée centrale de l'apprentissage contrastif est la suivante : « différentes versions augmentées d'une même image doivent être proches dans l'espace des caractéristiques, tandis que des images différentes doivent en être éloignées ». Avec SimCLR par exemple : ① pour chaque image d'un Batch, deux augmentations de données sont appliquées aléatoirement (recadrage aléatoire avec zoom 0,08~1,0, variation de couleur, flou gaussien, conversion en niveaux de gris), générant 2N vues augmentées ; ② un codeur ResNet-18 extrait les vecteurs de caractéristiques (128 dimensions) ; ③ la perte NT-Xent (cross-entropie à température normalisée) est calculée : L=-log(exp(sim(z_i,z_j)/τ)/Σexp(sim(z_i,z_k)/τ)), où sim() est la similarité cosinus, τ=0,5 est le coefficient de température (plus τ est petit, plus la distinction des échantillons négatifs est stricte). Améliorations de MoCo v2 : utilisation d'un codeur à momentum (momentum=0,999) et d'une file d'attente (Queue=4 096) pour remplacer le grand Batch de SimCLR, atténuant ainsi le problème de taille de Batch insuffisante.
Données expérimentales et méthode d'évaluation
Jeu de données : images de défauts de surface pour 5 types de composants de pont roulant (rupture de fils de câble métallique / usure de la surface de roulement des roues / fissure du rail / déformation du crochet / fissure de la garniture de frein + classe normale, soit 6 classes au total). Le jeu comprend 1 875 images annotées (pour l'ajustement et l'évaluation), plus 5 000 images non annotées collectées pour le pré-entraînement par apprentissage contrastif. Chaque classe compte environ 312 images. Quatre niveaux de volume d'échantillons sont testés pour l'ajustement : 50/100/300/500 images par classe. Métriques d'évaluation : précision Top-1, score F1 (macro-moyenne). Modèle de base : ResNet-18 (lr=0,0001 pour l'ajustement complet du modèle, lr=0,001 pour le gel de la couche FC).
| schéma de pré-entraînement | données de pré-entraînement | durée de pré-entraînement | 50annotation | 100annotation | 300annotation | 500annotation | pleine échelle1,500 |
|---|---|---|---|---|---|---|---|
| entraînement from scratch | — | — | 41.8% | 62.3% | 80.5% | 87.2% | 93.8% |
| Image Netpré-entraînement | 1,400dizaines de milliers d | —(poids publics) | 64.8% | 85.2% | 91.1% | 93.0% | 94.0% |
| Sim CLR | 5,000images industrielles | ~4h | 68.5% | 89.2% | 92.3% | 93.5% | 94.2% |
| Mo Co v2 | 5,000images industrielles | ~6h | 70.1% | 90.3% | 92.8% | 93.8% | 94.3% |
Conclusions clés : ① Avec 50 annotations, l'apprentissage contrastif (F1 = 68,5~70,1 %) surpasse nettement ImageNet (64,8 %) et l'entraînement from scratch (41,8 %) ; ② Avec 100 annotations, l'apprentissage contrastif (F1 = 89,2~90,3 %) ≈ ImageNet avec 300 annotations (F1 = 91,1 %), soit un gain d'efficacité d'annotation multiplié par 3 ; ③ À partir de 500 annotations, l'écart se resserre (93,0~93,8 %), et avec 1 500 annotations, les trois approches convergent (94,0~94,3 %) ; ④ MoCo v2 surpasse légèrement SimCLR à tous les niveaux d'annotation (+0,6~1,8 %), grâce à la stabilité de son codeur à momentum.
Comparaison approfondie : SimCLR vs MoCo v2
| Critère de comparaison | Sim CLR | Mo Co v2 | recommandé pour les scénarios industriels |
|---|---|---|---|
| mécanisme central | apprentissage contrastif de bout en bout, même Batchconstruction d | momentum Codeur+file d, découplage des échantillons positifs/négatifs | Mo Co v2(industriel Batchpetit) |
| Batchdépend de | nécessite une grande Batch≥256(sinon échantillons négatifs insuffisants) | petit Batch=64disponible(compléter les échantillons négatifs via la file d) | Mo Co v2(industriel GPUgénéralement sur une seule carte GPU) |
| température Coefficientτ | τ=0.5(contrôle la netteté du contraste, nécessite un réglage des hyperparamètres) | τ=0.2(par défaut, plus robuste) | Mo Co v2(moins de réglage) |
| gestion de la file d | sans file d(construction d=même Batchautres échantillons) | file d FIFO 4,096échantillons négatifs, mise à jour dynamique | Mo Co v2(diversité des échantillons négatifs plus élevée) |
| industriel Batch=64durée de pré-entraînement F1(100annotation) | 86.5%(échantillons négatifs uniquement63unités, quantité d) | 90.3%(file d4,096échantillons négatifs) | Sim CLRpetit Batchdégradation significative |
| généralement sur une seule carte GPUA10temps d(5,000images) | ~4h(Batch=256nécessite une grande mémoire GPU) | ~6h(Batch=64, mise à jour lente de la file d) | Sim CLR(si la mémoire GPU est suffisante) |
| complexité du code | simple(version originale Py Torch 150lignes) | moyen(momentum Codeur+gestion de la file d~300lignes) | Sim CLR(prototypage rapide) |
Recommandation pour le déploiement industriel : si la mémoire GPU est suffisante (≥24 Go, permettant un Batch ≥256) et que la priorité est l'itération rapide, optez pour SimCLR (entraînement rapide, code simple). Si la mémoire GPU est limitée (≤16 Go) ou si la précision maximale est recherchée, choisissez MoCo v2. Pour une application sur pont roulant, MoCo v2 est recommandé — car la limite de Batch sur une seule carte Jetson AGX Orin (64 Go) est d'environ 128, et MoCo v2 s'avère plus adapté aux petits Batch.
Comparaison des stratégies d'augmentation de données
L'augmentation de données est la clé du succès de l'apprentissage contrastif. Dans cette expérience, avec la configuration MoCo v2 + 100 annotations, chaque composant d'augmentation a été désactivé individuellement pour évaluer sa contribution :
| augmentation Composant | F1(100annotation) | changement par rapport à l | classement de contribution |
|---|---|---|---|
| augmentation complète(Normeconfiguration) | 0.903 | référence | — |
| désactiver le recadrage aléatoire | 0.814 | -0.089 | 1(le plus critique) |
| désactiver le tremblement de couleur | 0.852 | -0.051 | 2 |
| désactiver le flou gaussien | 0.876 | -0.027 | 3 |
| désactiver la conversion en niveaux de gris | 0.891 | -0.012 | 4 |
| désactiver le retournement horizontal | 0.897 | -0.006 | 5 |
Le recadrage aléatoire est l'augmentation de données la plus déterminante en apprentissage contrastif : il contraint le modèle à apprendre les motifs texturaux locaux de la cible plutôt que de s'appuyer sur la disposition globale de l'image (dans les scénarios industriels, les défauts n'occupent généralement que 5 à 20 % de l'image). La perturbation chromatique arrive en deuxième position : bien que la variation chromatique des pièces industrielles soit limitée (souvent en niveaux de gris ou en tons métalliques), elle renforce la robustesse face aux variations d'éclairage. Le flou gaussien, quant à lui, filtre le bruit haute fréquence et améliore la généralisation aux textures de surface.
Implémentation pratique — code clé de MoCo v2
# MoCo v2 Mise à jour du codeur de quantité de mouvement (PyTorchPseudo-code) class MoCo(nn.Module): def __init__(self, base_encoder=resnet18, dim=128, K=4096, m=0.999, T=0.2): super().__init__() self.K = K # Longueur de la file d self.m = m # Coefficient de quantité de mouvement self.T = T # Coefficient de température self.encoder_q = base_encoder() # Codeur de requête(Entraînement) self.encoder_k = base_encoder() # Codeur de clé(Mise à jour de la quantité de mouvement) for p in self.encoder_k.parameters(): p.requires_grad = False # Codeur de quantité de mouvement figé # File d: StockageKCaractéristiques d self.register_buffer("queue", torch.randn(dim, K)) self.queue = F.normalize(self.queue, dim=0) self.register_buffer("queue_ptr", torch.zeros(1, dtype=torch.long)) @torch.no_grad() def _momentum_update(self): # Mise à jour de la quantité de mouvement: θ_k = m*θ_k + (1-m)*θ_q for p_q, p_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()): p_k.data = self.m * p_k.data + (1 - self.m) * p_q.data def forward(self, im_q, im_k): q = self.encoder_q(im_q) # Caractéristique de requête NxC q = F.normalize(q, dim=1) with torch.no_grad(): self._momentum_update() k = self.encoder_k(im_k) # Caractéristique de clé NxC k = F.normalize(k, dim=1) # Perte contrastive: l_posPaire d + l_negPaire d l_pos = torch.einsum("nc,nc->n", q, k).unsqueeze(-1) # Nx1 l_neg = torch.einsum("nc,ck->nk", q, self.queue.clone().detach()) # NxK logits = torch.cat([l_pos, l_neg], dim=1) / self.T # Nx(1+K) labels = torch.zeros(logits.shape[0], dtype=torch.long) return F.cross_entropy(logits, labels)Questions fréquentes sur l'apprentissage contrastif
Q : Pourquoi l'apprentissage contrastif est-il plus adapté que le pré-entraînement ImageNet pour la détection de défauts industriels ?
A : Les 14 millions d'images naturelles d'ImageNet (chats, chiens, voitures, scènes) permettent d'apprendre des caractéristiques génériques de contours et de textures, mais leur sémantique de haut niveau diffère considérablement des défauts industriels. L'apprentissage contrastif, en s'entraînant directement sur 5 000 images industrielles, produit un encodeur de caractéristiques naturellement adapté aux motifs texturaux des défauts (rayures, fissures, usure, corrosion). Dans nos expériences, avec 100 annotations, SimCLR atteint un F1 de 0,89 contre 0,85 pour ImageNet, une différence statistiquement significative (test de McNemar, p = 0,003).
Q : 5 000 images non annotées suffisent-elles ? Quelle quantité faut-il pour obtenir des résultats probants ?
A : Dans un contexte industriel, 5 000 images correspondent déjà au point d'inflexion du rendement marginal. Expériences d'extension : 2 000 images → F1 = 0,85 ; 5 000 → 0,90 ; 10 000 → 0,91 ; 20 000 → 0,91. Le volume de 5 000 images offre le meilleur rapport coût-efficacité. Il est recommandé de privilégier la diversité des images (couvrant différents angles, éclairages et fonds) plutôt que d'augmenter simplement la quantité.
Q : Faut-il geler le backbone ou effectuer un fine-tuning complet lors de l'ajustement ?
A : Avec 100 annotations, le gel du backbone (en n'entraînant que la tête de classification FC, lr = 0,001, 50 époques) donne un F1 de 0,90, tandis que le fine-tuning complet chute à 0,87 en raison du surapprentissage. Avec 500 annotations, le fine-tuning complet (lr réduit d'un facteur 10 à 0,0001, 30 époques) atteint un F1 de 0,93, supérieur au gel (F1 = 0,91). Seuil de décision : dès que le nombre d'annotations par classe atteint 200, le fine-tuning complet devient envisageable.
Q : L'ajout d'une nouvelle catégorie de défauts en environnement industriel nécessite-t-il un ré-entraînement complet ?
A : Non. Le pré-entraînement apprend des caractéristiques visuelles génériques (textures, contours, formes) indépendantes des étiquettes de classe. Pour ajouter une 6ᵉ classe « fissure », il suffit de 10 à 20 images annotées, combinées aux 100 existantes, pour un fine-tuning de la couche FC (dimension de sortie 67) en moins de 5 minutes. Si les motifs texturaux de la nouvelle classe diffèrent radicalement des 5 classes existantes (par exemple, soufflure de cordon de soudure vs rayure de surface), il est conseillé de poursuivre le pré-entraînement sur le backbone existant (≈ 2 h) avant le fine-tuning.