Modèles Sound Logic et Monotonic AI
Publié: 2022-03-11L'IA devient rapidement un atout incroyable, ayant atteint des niveaux de performance surhumains dans des domaines tels que la reconnaissance d'images, le Go et même le poker. Beaucoup sont enthousiasmés par l'avenir de l'IA et de l'humanité. Dans le même temps, il y a un sentiment général que l'IA souffre d'un défaut embêtant : l'IA dans son état actuel peut être imprévisible et peu fiable.
L'exemple classique est le Jeopardy! IBM Challenge , au cours duquel Watson, l'IBM AI, a nettoyé la carte avec facilité, pour rater le "Final Jeopardy!" question, qui relevait de la catégorie des villes américaines : « Son plus grand aéroport porte le nom d'un héros de la Seconde Guerre mondiale ; son deuxième plus grand pour une bataille de la Seconde Guerre mondiale. Watson a répondu: "Qu'est-ce que Toronto ???" - les points d'interrogation supplémentaires (et la faible mise) indiquant son doute.
Ainsi, même si l'IA a la capacité de réaliser des performances dignes d'un conte de fées pendant de longues périodes - des mois, des années, voire des décennies - il y a toujours cette possibilité tenace que tout d'un coup, elle se trompe mystérieusement.
Le plus préoccupant pour nous, les humains, n'est pas que l'IA fera une erreur, mais à quel point l'erreur sera «illogique». Dans le cas de Watson, quelqu'un qui ne connaît pas la réponse à la question essaierait « logiquement » de deviner au moins une grande ville américaine. Je crois que c'est l'une des principales raisons pour lesquelles nous n'avons pas encore d'adoption publique des voitures autonomes : même si les voitures autonomes peuvent être statistiquement plus sûres, nous craignons que leur IA sous-jacente ne se trompe de manière inattendue dans un sens similaire à celui de Watson. , mais avec des répercussions beaucoup plus graves.
Cela m'a amené à me demander si le bon modèle d'IA pourrait résoudre ce problème ? La bonne IA pourrait-elle avoir la capacité de prendre des décisions judicieuses dans des moments critiques, même lorsqu'elle n'a pas toutes les réponses ? Une telle IA serait capable de changer le cours de la technologie et de nous permettre les avantages féeriques de l'IA…
Je crois que la réponse à ces questions est oui. Je pense que des erreurs comme celles de Watson peuvent être évitées grâce à l'utilisation de modèles améliorés, plus logiquement contraints, dont les premiers prototypes sont appelés modèles d'apprentissage automatique monotones . Sans entrer dans les détails pour l'instant, avec le bon modèle d'IA monotone :
- Une voiture autonome serait plus sûre, car la détection de la moindre quantité de signal humain suffirait toujours à activer un protocole de sécurité même en présence d'une grande quantité d'autres signaux.
- Les systèmes d'apprentissage automatique (ML) seraient plus robustes face aux attaques contradictoires et aux situations inattendues.
- Les performances de ML seraient plus logiques et humainement compréhensibles.
Je crois que nous passons d'une ère de grande croissance de la puissance de calcul et algorithmique de l'IA à une ère de finesse, d'efficacité et de compréhension de l'IA, et les modèles d'apprentissage automatique monotones sont la première étape de ce voyage passionnant. Les modèles monotones rendent l'IA plus "logique".
Note de l'éditeur : les lecteurs qui souhaitent faire leur premier pas dans la compréhension des bases du ML sont encouragés à lire notre article d'introduction sur le ML.
La théorie des modèles d'IA monotones
Alors, qu'est-ce qu'un modèle monotone ? En gros, un modèle monotone est un modèle ML qui possède un ensemble de caractéristiques (caractéristiques monotones ) dont l'augmentation conduit toujours le modèle à augmenter sa sortie.
Techniquement...
... il y a deux endroits où la définition ci-dessus est imprécise.
Premièrement, les caractéristiques ici sont croissantes monotones . On peut également avoir des caractéristiques monotones décroissantes, dont l'augmentation entraîne toujours une diminution du modèle. Les deux peuvent être convertis l'un en l'autre simplement par négation (multiplication par -1).
Deuxièmement, lorsque nous disons que la production augmente, nous ne voulons pas dire qu'elle augmente strictement , nous voulons dire qu'elle ne diminue pas , car la production peut rester la même.
Dans la vraie vie, de nombreuses paires de variables présentent des relations monotones. Par exemple:
- Le prix de l'essence pour un trajet augmente de façon monotone avec la distance parcourue.
- La probabilité de recevoir un prêt est plus grande avec un meilleur crédit.
- Le temps de conduite prévu augmente avec la quantité de trafic.
- Les revenus augmentent avec le taux de clic sur une annonce.
Bien que ces relations logiques soient suffisamment claires, pour un modèle ML qui interpole à l'aide de données limitées et d'aucune connaissance du domaine, elles peuvent ne pas l'être. En fait, le modèle pourrait les interpoler de manière incorrecte, ce qui entraînerait des prédictions ridicules et farfelues. Les modèles d'apprentissage automatique qui capturent ces connaissances fonctionnent mieux dans la pratique (en évitant le surajustement), sont plus faciles à déboguer et sont plus interprétables. Dans la plupart des cas d'utilisation, le modèle monotone doit être utilisé conjointement avec un modèle ordinaire, dans le cadre d'un ensemble d'apprenants.
Un endroit où les modèles d'IA monotones brillent vraiment est la robustesse de l'adversaire. Les modèles monotones sont des modèles d'apprentissage automatique "renforcés", ce qui signifie qu'ils résistent aux attaques adverses. Les attaquants capables de manipuler uniquement des fonctionnalités non monotones ne peuvent pas échapper au modèle d'IA monotone car ils ne peuvent pas modifier l'étiquette de l'exemple par rapport au modèle d'IA monotone.
Cas d'utilisation des modèles d'IA monotones
Jusqu'à présent, cette discussion a été entièrement théorique. Discutons de quelques cas d'utilisation réels.
Cas d'utilisation n° 1 : détection de logiciels malveillants
L'un des cas d'utilisation les plus intéressants pour les modèles d'IA monotones doit être leur utilisation dans la détection de logiciels malveillants. Implémenté dans le cadre de Windows Defender, un modèle monotone est présent dans chaque appareil Windows à jour, protégeant discrètement les utilisateurs contre les logiciels malveillants.
Dans un scénario, les auteurs de logiciels malveillants se sont fait passer pour des entreprises légitimes et enregistrées pour frauder les autorités de certification, réussissant à signer numériquement leur logiciel malveillant avec des certificats de confiance. Un classificateur de logiciels malveillants naïf est susceptible d'utiliser la signature de code comme fonctionnalité et indiquerait que ces échantillons sont bénins.
Mais ce n'est pas le cas dans le cas du modèle d'IA monotone de Windows Defender, dont les fonctionnalités monotones ne sont que les fonctionnalités qui indiquent un malware. Quelle que soit la quantité de contenu « inoffensif » que les auteurs de logiciels malveillants injectent dans leurs logiciels malveillants, le modèle d'IA monotone de Windows Defender continuerait à capturer l'échantillon et à protéger les utilisateurs contre les dommages.
Dans mon cours, Machine Learning for Red Team Hackers, j'enseigne plusieurs techniques pour échapper aux classificateurs de logiciels malveillants basés sur ML. L'une des techniques consiste à bourrer un échantillon malveillant avec du contenu/des fonctionnalités « bénignes » pour échapper aux modèles ML naïfs. Les modèles monotones résistent à cette attaque et obligent les acteurs malveillants à travailler beaucoup plus dur s'ils veulent espérer échapper au classifieur.
Cas d'utilisation n° 2 : Filtrage de contenu
Supposons qu'une équipe construise un filtre de contenu de navigation sur le Web pour les bibliothèques scolaires. Un modèle d'IA monotone est un excellent candidat à utiliser ici car un forum qui contient du contenu inapproprié peut également contenir beaucoup de contenu acceptable.
Un classificateur naïf pourrait peser la présence de caractéristiques « appropriées » par rapport à la présence de caractéristiques « inappropriées ». Mais cela ne fonctionnera pas puisque nous ne voulons pas que nos enfants accèdent à du contenu inapproprié, même s'il ne représente qu'une petite fraction du contenu.
Cas d'utilisation n° 3 : IA de voiture autonome
Imaginez construire un algorithme de voiture autonome. Il regarde une image et voit une lumière verte. Il voit aussi un piéton. Doit-il peser le signal de chacun par rapport à celui de l'autre ? Absolument pas. La présence d'un piéton est suffisante pour prendre la décision d'arrêter la voiture. La présence de piétons doit être considérée comme une caractéristique monotone et un modèle d'IA monotone doit être utilisé dans ce scénario.
Cas d'utilisation n° 4 : Moteurs de recommandation
Les moteurs de recommandation sont un excellent cas d'utilisation pour les modèles d'IA monotones. En général, ils peuvent avoir de nombreuses entrées sur chaque produit : nombre d'étoiles, prix, nombre d'avis, etc. Toutes les autres entrées étant égales, telles que le nombre d'étoiles et le prix, nous préférerions le produit qui a le plus grand nombre d'avis. Nous pouvons appliquer une telle logique en utilisant un modèle d'IA monotone.
Cas d'utilisation n° 5 : filtrage des spams et des hameçonnages
Ce cas d'utilisation est similaire au cas d'utilisation de détection de logiciels malveillants. Les utilisateurs malveillants peuvent injecter dans leurs spams ou e-mails de phishing des termes apparemment bénins pour tromper les filtres anti-spam. Un modèle d'IA monotone sera immunisé contre cela.
Mise en œuvre et démonstration
En ce qui concerne les implémentations librement disponibles de modèles d'IA monotones, trois se distinguent comme étant les mieux prises en charge : XGBoost, LightGBM et TensorFlow Lattice.
Tutoriel Monotonic ML XGBoost
XGBoost est considéré comme l'un des algorithmes les plus performants sur les données structurées, basé sur des années de recherche empirique et de concurrence. De plus, la monotonie a été implémentée dans XGBoost.
Le didacticiel XGBoost de démonstration suivant sur l'utilisation des modèles ML monotones est accompagné d'un référentiel Python.
Commencez par importer quelques bibliothèques :
import random import numpy as np import matplotlib.pyplot as plt %matplotlib inline from sklearn.metrics import confusion_matrix import seaborn as sns sns.set(font_scale=1.4)
Le scénario que nous allons modéliser est un filtrage de contenu ou une base de données de logiciels malveillants. Nous aurons quelques benign_features
, qui modélisent, par exemple, la quantité de contenu lié à la "science", à "l'histoire" et au "sport" ou, dans le cas des logiciels malveillants, à la "signature de code" et aux "auteurs reconnus".
De plus, nous aurons malicious_features
, qui modélise, par exemple, la quantité de contenu lié à la "violence" et à la "drogue", ou dans le cas des logiciels malveillants, "le nombre d'appels aux bibliothèques de chiffrement" et "une mesure numérique de similitude avec une famille de logiciels malveillants connue.
Nous allons modéliser la situation via un modèle génératif. Nous générons un grand nombre de points de données au hasard, environ à moitié bénins et à moitié malveillants, en utilisant la fonction :
def flip(): """Simulates a coin flip.""" return 1 if random.random() < 0.5 else 0
Chaque point de données générera aléatoirement ses caractéristiques. Un point de données « bénin » aura un biais plus élevé pour les fonctionnalités bénignes, tandis qu'un point de données « malveillant » aura un biais plus élevé pour les fonctionnalités malveillantes.

Nous allons utiliser une distribution triangulaire, comme ceci :
bins = [0.1 * i for i in range(12)] plt.hist([random.triangular(0, 1, 1) for i in range(50000)], bins)
Nous allons utiliser cette fonction pour capturer la logique ci-dessus :
def generate(): """Samples from the triangular distribution.""" return random.triangular(0, 1, 1)
Ensuite, nous allons procéder à la création de notre jeu de données :
m = 100000 benign_features = 5 malicious_features = 5 n = benign_features + malicious_features benign = 0 malicious = 1 X = np.zeros((m, n)) y = np.zeros((m)) for i in range(m): vec = np.zeros((n)) y[i] = flip() if y[i] == benign: for j in range(benign_features): vec[j] = generate() for j in range(malicious_features): vec[j + benign_features] = 1 - generate() else: for j in range(benign_features): vec[j] = 1 - generate() for j in range(malicious_features): vec[j + benign_features] = generate() X[i, :] = vec
X
contient les vecteurs d'entités générées aléatoirement, tandis que y
contient les étiquettes. Ce problème de classification n'est pas anodin.
Vous pouvez voir que les échantillons bénins ont généralement plus de poids dans les premières fonctionnalités, tandis que les échantillons malveillants ont généralement plus de poids dans les dernières fonctionnalités.
Avec les données prêtes, effectuons une simple séparation formation-test :
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
Nous allons utiliser une fonction pour préparer les données à utiliser avec notre tutoriel XGBoost :
import xgboost as xgb def prepare_for_XGBoost(X, y): """Converts a numpy X and y dataset into a DMatrix for XGBoost.""" return xgb.DMatrix(X, label=y) dtrain = prepare_for_XGBoost(X_train, y_train) dtest = prepare_for_XGBoost(X_test, y_test) dall = prepare_for_XGBoost(X, y)
Maintenant, entraînons et testons un modèle XGBoost simple (non monotone) sur les données. Nous imprimerons ensuite la matrice de confusion pour voir une répartition numérique des exemples positifs correctement étiquetés, des exemples négatifs correctement étiquetés, des exemples positifs incorrectement étiquetés et des exemples négatifs incorrectement étiquetés.
params = {"n_jobs": -1, "tree_method": "hist"} model_no_constraints = xgb.train(params=params, dtrain=dtrain) CM = predict_with_XGBoost_and_return_confusion_matrix( model_no_constraints, dtrain, y_train ) plt.figure(figsize=(12, 10)) sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues") plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.title("Unconstrained model's training confusion matrix") plt.show() print() CM = predict_with_XGBoost_and_return_confusion_matrix( model_no_constraints, dtest, y_test ) plt.figure(figsize=(12, 10)) sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues") plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.title("Unconstrained model's testing confusion matrix") plt.show() model_no_constraints = xgb.train(params=params, dtrain=dall)
En regardant les résultats, nous pouvons voir qu'il n'y a pas de surajustement significatif. Nous comparerons ces résultats à ceux des modèles monotones.
À cette fin, formons et testons un modèle XGBoost monotone. La syntaxe dans laquelle nous passons dans les contraintes monotones est une séquence ( f 0 , f 1 , …, f N ), où chaque f i est l'un des -1, 0 ou 1, selon que nous voulons que la caractéristique i soit monotone décroissant, sans contrainte ou croissant de manière monotone, respectivement. Dans le cas présent, nous spécifions que les fonctionnalités malveillantes sont monotones croissantes.
params_constrained = params.copy() monotone_constraints = ( "(" + ",".join([str(0) for m in range(benign_features)]) + "," + ",".join([str(1) for m in range(malicious_features)]) + ")" ) print("Monotone constraints enforced are:") print(monotone_constraints) params_constrained["monotone_constraints"] = monotone_constraints model_monotonic = xgb.train(params=params_constrained, dtrain=dtrain) CM = predict_with_XGBoost_and_return_confusion_matrix(model_monotonic, dtrain, y_train) plt.figure(figsize=(12, 10)) sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues") plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.title("Monotonic model's training confusion matrix") plt.show() print() CM = predict_with_XGBoost_and_return_confusion_matrix(model_monotonic, dtest, y_test) plt.figure(figsize=(12, 10)) sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues") plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.title("Monotonic model's testing confusion matrix") plt.show() model_monotonic = xgb.train(params=params_constrained, dtrain=dall)
Il est clair que les performances du modèle monotone sont les mêmes que celles du modèle sans contrainte.
Maintenant, nous allons créer un jeu de données contradictoire. Nous allons prendre tous les échantillons malveillants et « bourrer » leurs fonctionnalités bénignes en les mettant tous à 1. Nous verrons ensuite comment les deux modèles fonctionnent côte à côte.
X_adversarial = X[y == malicious] y_adversarial = len(X_adversarial) * [malicious] for i in range(len(X_adversarial)): vec = X_adversarial[i, :] for j in range(benign_features): vec[j] = 1 X_adversarial[i, :] = vec
Convertissons-les en un formulaire à ingérer par XGBoost :
dadv = prepare_for_XGBoost(X_adversarial, y_adversarial)
Pour la dernière étape de notre tutoriel XGBoost, nous testerons les deux types de modèles d'apprentissage automatique :
CM = predict_with_XGBoost_and_return_confusion_matrix( model_no_constraints, dadv, y_adversarial ) plt.figure(figsize=(12, 10)) sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues") plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.title("Unconstrained model's confusion matrix on adversarial dataset") plt.show()
CM = predict_with_XGBoost_and_return_confusion_matrix( model_monotonic, dadv, y_adversarial ) plt.figure(figsize=(12, 10)) sns.heatmap(CM / np.sum(CM), annot=True, fmt=".2%", cmap="Blues") plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.title("Monotonic model's confusion matrix on adversarial dataset") plt.show()
Comme vous pouvez le constater, le modèle d'IA monotone était environ 2 500 fois plus robuste face aux attaques adverses.
LightGBM
La syntaxe d'utilisation des fonctionnalités monotones dans LightGBM est similaire.
Réseau TensorFlow
TensorFlow Lattice est un autre framework permettant de résoudre les contraintes de monotonie. Il s'agit d'un ensemble d'estimateurs TensorFlow prédéfinis ainsi que d'opérateurs TensorFlow pour créer vos propres modèles de réseau. Les treillis sont des tables de recherche interpolées multidimensionnelles, ce qui signifie qu'ils sont des points uniformément répartis dans l'espace (comme une grille), ainsi que des valeurs de fonction à ces points. Selon le blog Google AI :
"... les valeurs de la table de consultation sont formées pour minimiser la perte sur les exemples de formation, mais en plus, les valeurs adjacentes dans la table de consultation sont contraintes d'augmenter le long des directions données de l'espace d'entrée, ce qui fait que les sorties du modèle augmentent dans ces orientations. Surtout, parce qu'ils interpolent entre les valeurs de la table de consultation, les modèles de réseau sont lisses et les prédictions sont limitées, ce qui permet d'éviter les fausses prédictions grandes ou petites pendant la durée du test.
Des didacticiels sur l'utilisation de TensorFlow Lattice sont disponibles ici.
Les modèles d'IA monotones et l'avenir
De la défense des appareils contre les attaques malveillantes à l'offre de recommandations de restaurants logiques et utiles, les modèles d'IA monotones se sont révélés être une aubaine pour la société et un outil merveilleux à maîtriser. Les modèles monotones sont là pour nous faire entrer dans une nouvelle ère de sécurité, de finesse et de compréhension de l'IA. Et donc je dis, voici les modèles d'IA monotones, voici le progrès.