L'étiquette comme surface d'attaque
On protège d'ordinaire le code d'un modèle, ses poids, son interface. On oublie que sa matière première, ce sont des exemples étiquetés, et que ces étiquettes viennent souvent de sources qu'un attaquant peut influencer : signalements d'utilisateurs, échantillons soumis à un service d'analyse, données annotées à la chaîne par des tiers. Le label flipping, ou retournement d'étiquettes, exploite exactement cela. On ne modifie ni le code, ni l'architecture, ni les caractéristiques des exemples : on change seulement les réponses qu'on donne au modèle pendant qu'il apprend.
C'est une forme d'empoisonnement des données, l'une des grandes familles d'attaques que recense la taxonomie du NIST sur l'apprentissage adverse (NIST AI 100-2), et que MITRE ATLAS documente comme une technique à part entière. Sa force tient à sa discrétion : un jeu de données empoisonné ressemble trait pour trait à un jeu propre, aux quelques étiquettes fausses près.
Anatomie du retournement
Deux régimes, très différents dans leurs effets.
Le retournement aléatoire inverse les étiquettes d'une fraction quelconque des exemples. Il dégrade le modèle sans cible : la frontière de décision se brouille, la précision baisse partout. C'est une attaque de sabotage.
Le retournement ciblé est plus intéressant, et plus dangereux. On ne retourne que des exemples choisis pour ouvrir une porte précise : étiqueter « bénins » des échantillons portant un certain motif, pour que le modèle apprenne à associer ce motif à cette classe. La précision globale, elle, peut rester relativement stable. Selon le jeu de données, le modèle et le taux d'empoisonnement, l'attaque devient alors difficile à repérer dans les métriques usuelles.
Le modèle de menace se résume à une question : qui peut écrire une étiquette dans mon jeu d'entraînement ? Toute réponse autre que « moi seul, sur des données que je contrôle » ouvre la voie.
Une démonstration sur un jeu jouet
Le phénomène se mesure en quelques lignes. On entraîne un classifieur, on retourne une part croissante des étiquettes d'entraînement, et on regarde la précision chuter sur un jeu de test resté propre.
import numpy as np
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
rng = np.random.default_rng(0)
X, y = make_classification(n_samples=4000, n_features=20, n_informative=8,
n_classes=2, random_state=0)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.25, random_state=0)
def flip(y, taux):
y = y.copy()
n = int(taux * len(y))
idx = rng.choice(len(y), size=n, replace=False)
y[idx] = 1 - y[idx] # binaire : on inverse l'étiquette
return y
for taux in (0.0, 0.05, 0.10, 0.20, 0.40):
modele = LogisticRegression(max_iter=1000).fit(X_tr, flip(y_tr, taux))
acc = accuracy_score(y_te, modele.predict(X_te))
print(f"{taux:>4.0%} d'étiquettes retournées -> précision {acc:.3f}")
L'ordre de grandeur est constant d'une exécution à l'autre : la précision tient à quelques pour cent de bruit, puis se dégrade nettement au-delà de dix. Il n'a pas fallu toucher une seule caractéristique.
Du bruit à la corrélation ciblée
Le retournement ciblé se code aussi simplement, mais il vise. Supposons que l'attaquant contrôle un motif reconnaissable dans l'espace des caractéristiques : un intervalle de valeurs sur une variable qu'il maîtrise. Il retourne vers « bénin » les seuls exemples malveillants portant ce motif.
def empoisonnement_cible(X, y, motif, cible=0):
y = y.copy()
# On ne retourne que les exemples malveillants (y == 1) qui portent le
# motif choisi par l'attaquant : ils deviendront « bénins » pour le modèle.
masque = (y == 1) & motif(X)
y[masque] = cible
return y
Le modèle apprend alors une corrélation : ce motif tire vers la classe « bénin ». À la différence d'une porte dérobée au sens strict, qui implante dans les entrées un déclencheur artificiel que l'attaquant présente ensuite à volonté, on ne modifie ici aucune entrée d'entraînement : on induit une association ciblée entre une région de l'espace des caractéristiques et une classe. La précision du modèle sur des données ordinaires peut rester excellente, et c'est le piège : l'attaque ne se voit pas dans la métrique qu'on regarde, seulement quand on cherche la porte qu'elle a ouverte.
Détecter et défendre
Aucune parade n'est absolue, mais plusieurs se combinent bien.
Contrôler la provenance. La première défense n'est pas algorithmique : elle consiste à savoir d'où vient chaque étiquette, à signer les lots de données, à isoler les étiquettes issues de sources influençables, et à ne pas réentraîner automatiquement sur des retours non vérifiés.
Inspecter les étiquettes suspectes. Un exemple dont l'étiquette contredit celle de ses plus proches voisins est un candidat au retournement. Un filtre par vote des voisins repère et écarte ces incohérences avant l'entraînement.
from sklearn.neighbors import KNeighborsClassifier
def signaler_suspects(X, y, k=7, seuil=0.8):
# Pour chaque exemple, la classe majoritaire parmi ses k voisins.
# Si elle contredit fortement l'étiquette, l'exemple est suspect.
voisins = KNeighborsClassifier(n_neighbors=k).fit(X, y)
proba = voisins.predict_proba(X)
classe_voisins = proba.argmax(axis=1)
confiance = proba.max(axis=1)
return (classe_voisins != y) & (confiance >= seuil)
Entraîner de façon robuste. Des pertes robustes aux étiquettes aberrantes, un rognage des gradients, ou l'écartement des exemples de perte anormalement élevée en cours d'entraînement limitent l'emprise d'une minorité empoisonnée. Les fonctions d'influence, plus coûteuses, remontent des prédictions douteuses vers les exemples d'entraînement qui les ont le plus façonnées.
Surveiller la dérive. Une chute de précision inexpliquée, ou un motif précis systématiquement mal classé, sont des signaux. Un jeu de validation propre, tenu à l'écart de la chaîne d'annotation, sert de témoin.
Ce que ça change pour un défenseur
Le label flipping déplace la sécurité d'un modèle en amont de son code, jusqu'à la table où l'on décide de la vérité de chaque exemple. Un pipeline d'apprentissage n'est pas seulement du calcul : c'est une chaîne d'approvisionnement, avec ses fournisseurs, ses lots, sa traçabilité. La question à se poser n'est pas « mon modèle est-il précis ? », mais « qui a écrit les étiquettes sur lesquelles il l'est devenu ? ».
À retenir
- 01
L'étiquette est une surface d'attaque : qui l'influence peut fausser le modèle.
- 02
Quelques pour cent d'étiquettes retournées suffisent à dégrader un classifieur.
- 03
L'attaque ciblée peut laisser la précision globale intacte : elle ouvre une porte précise.
- 04
La défense se joue sur la provenance des données et sur l'inspection des étiquettes suspectes.

