Tutorial

Comment tromper un réseau de neurones en Python 3

Published on July 30, 2020
Default avatar

By Alvin Wan

AI PhD Student @ UC Berkeley

Français
Comment tromper un réseau de neurones en Python 3

L’auteur a choisi Dev Color ​​ pour recevoir un don dans le cadre du programme Write for DOnations.

Un réseau de neurones pour la classification des animaux pourrait-il être trompé ? Tromper un classificateur d’animaux peut avoir peu de conséquences, mais que se passerait-il si notre authentificateur de visage pouvait être trompé ? Ou encore le logiciel de notre prototype de voiture qui se conduit toute seule ? Heureusement, une foule d’ingénieurs et de chercheurs se tiennent entre un prototype de modèle de vision par ordinateur et des modèles de qualité production sur nos appareils mobiles ou nos voitures. Néanmoins, ces risques ont des implications importantes et il est important, en tant que professionnel de l’apprentissage automatique, de les prendre en considération.

Dans ce tutoriel, vous allez essayer de « tromper » ou de duper un classificateur d’animaux. Au fur et à mesure que vous avancez dans le tutoriel, vous utiliserez OpenCV, une bibliothèque de vision par ordinateur, et PyTorch,une bibliothèque de Deep Learning (apprentissage approfondi). Vous aborderez les sujets suivants dans le domaine associé à l’apprentissage automatique contradictoire:

  • Créez un exemple contradictoire ciblé. Choisissez une image, disons, d’un chien. Choisissez une classe cible, disons un chat. Votre objectif est de faire croire au réseau de neurones que le chien représenté est un chat.
  • Créer une défense contradictoire. En bref, protégez votre réseau neuronal contre ces images piégées, sans savoir quelle est le piège.

À la fin du tutoriel, vous disposerez d’un outil permettant de piéger les réseaux neuronaux et vous comprendrez comment vous défendre contre les pièges.

Conditions préalables

Pour terminer ce tutoriel, vous aurez besoin des éléments suivants :

Étape 1 - Création de votre projet et installation des dépendances

Créons un espace de travail pour ce projet et installons les dépendances dont vous aurez besoin. Vous appellerez votre espace de travail AdversarialML :

  1. mkdir ~/AdversarialML

Naviguez vers le répertoire AdversarialML :

  1. cd ~/AdversarialML

Faites un répertoire pour conserver tous vos éléments :

  1. mkdir ~/AdversarialML/assets

Ensuite, créez un nouvel environnement virtuel pour le projet :

  1. python3 -m venv adversarialml

Activez votre environnement :

  1. source adversarialml/bin/activate

Installez ensuite PyTorch, un framework d’apprentissage profond pour Python que nous utiliserons au cours de ce tutoriel.

Sous macOS, installez Pytorch avec la commande suivante :

  1. python -m pip install torch==1.2.0 torchvision==0.4.0

Sous Linux et Windows, utilisez les commandes suivantes pour une construction du CPU uniquement :

  1. pip install torch==1.2.0+cpu torchvision==0.4.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
  2. pip install torchvision

Installez maintenant les binaires pré-packagés pour OpenCV et numpyqui sont respectivement des bibliothèques pour la vision par ordinateur et l’algèbre linéaire. OpenCV propose des utilitaires tels que les rotations d’images et numpy fournit des utilitaires d’algèbre linéaire comme l’inversion d’une matrice :

  1. python -m pip install opencv-python==3.4.3.18 numpy==1.14.5

Sur les distributions Linux, vous devrez installer libSM.so :

  1. sudo apt-get install libsm6 libxext6 libxrender-dev

Une fois les dépendances installées, faisons fonctionner un classificateur d’animaux appelé ResNet18, que nous décrivons ensuite.

Étape 2 - Faire fonctionner un classificateur d’animaux préformés

La bibliothèque torchvision, la bibliothèque officielle de vision par ordinateur pour PyTorch, contient des versions préformées de réseaux neuronaux de vision par ordinateur couramment utilisés. Ces réseaux neuronaux sont tous formés sur ImageNet 2012, un ensemble de données de 1,2 million d’images de formation avec 1000 classes. Ces classes comprennent les véhicules, les lieux et, surtout, les animaux. Dans cette étape, vous ferez fonctionner l’un de ces réseaux neuronaux préformés, appelé ResNet18. Nous parlerons de ResNet18 formé sur ImageNet comme d’un « classificateur d’animaux ».

Qu’est-ce que ResNet18 ? ResNet18 est le plus petit réseau neuronal d’une famille de réseaux neuronaux appelés réseaux neuronaux résiduels, développé par MSR (He et al.). En bref, il a découvert qu’un réseau neuronal (désigné comme une fonction f, avec l’entrée x, et la sortie f(x)) serait plus performant avec une « connexion résiduelle » x + f(x). Cette connexion résiduelle est utilisée de façon prolifique dans les réseaux neuronaux de pointe, même aujourd’hui. Par exemple, FBNetV2, FBNetV3.

Téléchargez cette image d’un chien avec la commande suivante :

  1. wget -O assets/dog.jpg https://assets.digitalocean.com/articles/trick_neural_network/step2a.png

Image de corgi courant près d'un étang 

Ensuite, téléchargez un fichier JSON pour convertir la sortie du réseau neuronal en un nom de classe lisible par l’homme :

  1. wget -O assets/imagenet_idx_to_label.json https://raw.githubusercontent.com/do-community/tricking-neural-networks/master/utils/imagenet_idx_to_label.json

Ensuite, créez un script pour faire fonctionner votre modèle prédéfini sur l’image du chien. Créez un nouveau fichier appelé step_2_pretrained.py :

  1. nano step_2_pretrained.py

Tout d’abord, ajoutez le passe-partout Python en important les packages nécessaires et en déclarant une fonction principale:

step_2_pretrained.py
from PIL import Image
import json
import torchvision.models as models
import torchvision.transforms as transforms
import torch
import sys

def main():
    pass

if __name__ == '__main__':
    main()

Ensuite, chargez le mappage de la sortie du réseau neuronal en noms de classe lisibles à l’oeil humain. Ajoutez-le directement après vos déclarations d’importation et avant votre fonction principale :

step_2_pretrained.py
. . .
def get_idx_to_label():
    with open("assets/imagenet_idx_to_label.json") as f:
        return json.load(f)
. . .

Créez une fonction de transformation d’image qui garantira tout d’abord que votre image d’entrée a les bonnes dimensions, et ensuite qu’elle est correctement normalisée. Ajoutez la fonction suivante directement après la dernière :

step_2_pretrained.py
. . .
def get_image_transform():
    transform = transforms.Compose([
      transforms.Resize(224),
      transforms.CenterCrop(224),
      transforms.ToTensor(),
      transforms.Normalize(mean=[0.485, 0.456, 0.406],
                           std=[0.229, 0.224, 0.225])
    ])
    return transform
. . .

Dans get_image_transform, vous définissez un certain nombre de transformations différentes à appliquer aux images qui sont transmises à votre réseau de neurones :

  • transforms. Resize(224) : Redimensionne le petit côté de l’image à 224. Par exemple, si votre image est de 448 x 672, cette opération réduira l’image à 224 x 336.
  • transforme.CenterCrop(224): Prend un recadrage du centre de l’image, de taille 224 x 224.
  • transforms.ToTensor() : Convertit l’image en un tenseur PyTorch. Tous les modèles PyTorch nécessitent des tenseurs PyTorch comme entrée.
  • transforms.Normalize(mean=..., std=...): Normalise votre entrée en soustrayant la moyenne, puis en divisant par l’écart type. Ceci est décrit plus précisément dans la documentation de la torchvision.

Ajouter un utilitaire pour prédire la classe de l’animal, compte tenu de l’image. Cette méthode utilise les deux utilitaires précédents pour effectuer la classification des animaux :

step_2_pretrained.py
. . .
def predict(image):
    model = models.resnet18(pretrained=True)
    model.eval()

    out = model(image)

    _, pred = torch.max(out, 1)  
    idx_to_label = get_idx_to_label()  
    cls = idx_to_label[str(int(pred))]  
    return cls
. . .

Ici, la fonction de prédiction classifie l’image fournie en utilisant un réseau neuronal préformé :

  • models.resnet18(pretrained=True): Charge un réseau neuronal préformé appelé ResNet18.
  • model.eval(): modifie le modèle en place pour qu’il fonctionne en mode « evaluation ». Le seul autre mode est le mode « training », mais le mode « training » n’est pas nécessaire, car vous n’êtes pas en train de former le modèle (c’est-à-dire de mettre à jour les paramètres du modèle) dans ce tutoriel.
  • out = model(image) : fait fonctionner le réseau de neurones sur l’image transformée fournie.
  • _, pred = torch.max(out, 1) : Le réseau de neurones produit une probabilité pour chaque classe possible.  Cette étape permet de calculer l’indice de la classe ayant la plus grande probabilité. Par exemple, si out = [0,4, 0,1, 0,2], alors pred = 0.
  • idx_to_label = get_idx_to_label(): Obtient une correspondance entre l’index des classes et les noms de classe lisibles à l’oeil humain. Par exemple, le mappage pourrait être {0 : chat, 1 : chien, 2 : poisson}.
  • cls = idx_to_label [str(int(pred))]: Convertit l’indice de classe prévu en un nom de classe. Les exemples fournis dans les deux derniers points permettraient de donner cls = idx_to_label[0] = 'chat'.

Ensuite, après la dernière fonction, ajoutez un utilitaire pour charger les images :

step_2_pretrained.py
. . .
def load_image():
    assert len(sys.argv) > 1, 'Need to pass path to image'
    image = Image.open(sys.argv[1])

    transform = get_image_transform()
    image = transform(image)[None]
    return image
. . .

Cela va charger une image à partir du chemin fourni dans le premier argument du script. transform(image) [None] applique la séquence de transformations d’images définie dans les lignes précédentes.

Enfin, remplissez votre fonction principale avec ce qui suit, pour charger votre image et classer l’animal dans l’image :

step_2_pretrained.py
def main():
    x = load_image()
    print(f'Prediction: {predict(x)}')

Vérifiez que votre fichier correspond à notre script final de l’étape 2 à step_2_pretrained.py sur GitHub. Sauvegardez et quittez votre script, et lancez le classificateur d’animaux :

  1. python step_2_pretrained.py assets/dog.jpg

Cela produira le résultat suivant, montrant que votre classificateur d’animaux fonctionne comme prévu :

Output
Prediction: Pembroke, Pembroke Welsh corgi

Cela conclut l’inférence courante avec votre modèle préformé. Ensuite, vous verrez un exemple contradictoire en action en trompant un réseau de neurones avec des différences imperceptibles dans l’image.

Étape 3 - Essai d’un exemple contradictoire

Maintenant, vous allez synthétiser un exemple contradictoire et tester le réseau neuronal sur cet exemple. Pour ce tutoriel, vous construirez des exemples contradictoires de la forme x + rx est l’image originale et r est une « perturbation ». Vous finirez par créer la perturbation r vous-même, mais dans cette étape, vous téléchargerez une perturbation que nous avons créée pour vous au préalable. Commencez par télécharger la perturbation r :

  1. wget -O assets/adversarial_r.npy https://github.com/do-community/tricking-neural-networks/blob/master/outputs/adversarial_r.npy?raw=true

Composez maintenant l’image avec la perturbation. Créez un nouveau fichier appelé step_3_adversarial.py​​​​​ :

  1. nano step_3_adversarial.py

Dans ce fichier, vous effectuerez le processus en trois étapes suivant, afin de produire un exemple contradictoire :

  1. Transformez une image
  2. Appliquez la perturbation r
  3. Transformez à l’inverse l’image perturbée

À la fin de l’étape 3, vous aurez une image contradictoire. Tout d’abord, il faut importer les packages nécessaires et déclarer une fonction principale :

step_3_adversarial.py
from PIL import Image
import torchvision.transforms as transforms
import torch
import numpy as np
import os
import sys

from step_2_pretrained import get_idx_to_label, get_image_transform, predict, load_image


def main():
    pass


if __name__ == '__main__':
    main()

Ensuite, créez une « transformation d’image » qui inverse la transformation d’image précédente. Placez ceci après vos importations, avant la fonction principale :

step_3_adversarial.py
. . .
def get_inverse_transform():
    return transforms.Normalize(
        mean=[-0.485/0.229, -0.456/0.224, -0.406/0.255],  # INVERSE normalize images, according to https://pytorch.org/docs/stable/torchvision/models.html
        std=[1/0.229, 1/0.224, 1/0.255])
. . .

Comme précédemment, l’opération transforms.Normalize soustrait la moyenne et divise par l’écart type (c’est-à-dire, pour l’image originale x, y = transforms.Normalize(moyenne=u, std=o) = (x - u) / o). Vous faites un peu d’algèbre et vous définissez une nouvelle opération qui inverse cette fonction de normalisation (transforms.Normalize(mean=-u/o, std=1/o) = (y - -u/o) / 1/o = (y + u/o) o = yo + u = x).

Dans le cadre de la transformation inverse, ajoutez une méthode qui transforme un tenseur PyTorch en une image PIL. Ajoutez ceci à la suite de la dernière fonction :

step_3_adversarial.py
. . .
def tensor_to_image(tensor):
    x = tensor.data.numpy().transpose(1, 2, 0) * 255.  
    x = np.clip(x, 0, 255)
    return Image.fromarray(x.astype(np.uint8))
. . .
  • tensor.data.numpy() convertit le tenseur PyTorch en un tableau NumPy. .transpose(1, 2, 0) réorganise (canaux, largeur, hauteur) en (hauteur, largeur, canaux). Ce tableau NumPy se situe approximativement dans la fourchette (0, 1). Enfin, multipliez par 255 pour vous assurer que l’image est maintenant dans la fourchette (0, 255).
  • np.clip s’assure que toutes les valeurs de l’image se situent entre (0, 255).
  • x.astype(np.uint8) garantit que toutes les valeurs des images sont des entiers.  Enfin, Image.fromarray(...) crée un objet image PIL à partir du tableau NumPy.

Ensuite, utilisez ces services pour créer l’exemple contradictoire suivant :

step_3_adversarial.py
. . .
def get_adversarial_example(x, r):
    y = x + r
    y = get_inverse_transform()(y[0])
    image = tensor_to_image(y)
    return image
. . .

Cette fonction génère l’exemple contradictoire décrit au début de la section :

  1. y = x + r. Prenez votre perturbation r et ajoutez-la à l’image originale x.
  2. get_inverse_transform : Obtenez et appliquez la transformation inverse de l’image que vous avez définie plusieurs lignes plus tôt.
  3. tensor_to_image: Enfin, reconvertissez le tenseur PyTorch en objet image.

Enfin, modifiez votre fonction principale pour charger l’image, charger la perturbation contradictoire r, appliquer la perturbation, enregistrer l’exemple contradictoire sur le disque et exécuter la prédiction sur l’exemple contradictoire :

step_3_adversarial.py
def main():
    x = load_image()
    r = torch.Tensor(np.load('assets/adversarial_r.npy'))

    # save perturbed image
    os.makedirs('outputs', exist_ok=True)
    adversarial = get_adversarial_example(x, r)
    adversarial.save('outputs/adversarial.png')

    # check prediction is new class
    print(f'Old prediction: {predict(x)}')
    print(f'New prediction: {predict(x + r)}')

Votre dossier complété doit correspondre à step_3_adversarial.py sur GitHub. Enregistrez le fichier, quittez l’éditeur et lancez votre script avec :

  1. python step_3_adversarial.py assets/dog.jpg

Vous verrez la sortie suivante :

Output
Old prediction: Pembroke, Pembroke Welsh corgi New prediction: goldfish, Carassius auratus

Vous avez maintenant créé un exemple contradictoire : faire croire au réseau neuronal qu’un corgi est un poisson rouge. Dans l’étape suivante, vous allez en fait créer la perturbation r que vous avez utilisée ici.

Étape 4 - Comprendre un exemple de procédure contradictoire

Pour une introduction à la classification, voir « Comment construire un filtre pour chien basé sur les émotions »

En prenant du recul, rappelez-vous que votre modèle de classification produit une probabilité pour chaque classe. Lors de l’inférence, le modèle prédit la classe avec la plus grande probabilité. Pendant la formation, vous mettez à jour les paramètres du modèle t pour maximiser la probabilité d’avoir la bonne classe y, compte tenu de vos données x.

argmax_y P(y|x,t)

Cependant, pour générer des exemples contradictoires, vous modifiez maintenant votre objectif. Au lieu de trouver une classe, votre objectif est maintenant de trouver une nouvelle image, x. Prenez n’importe quelle classe autre que la classe correcte. Appelons cette nouvelle classe w. Votre nouvel objectif est de maximiser la probabilité de la mauvaise classe.

argmax_x P(w|x)

Notez que les poids du réseau neuronal t sont absents de l’expression ci-dessus. C’est parce que vous assumez maintenant le rôle de l’adversaire : Quelqu’un d’autre a formé et déployé un modèle. Vous êtes seulement autorisé à créer des contributions contradictoires et n’êtes pas autorisé à modifier le modèle déployé. Pour générer l’exemple contradictoire x, vous pouvez exécuter « training », sauf qu’au lieu de mettre à jour les poids du réseau neuronal, vous mettez à jour l’image d’entrée avec le nouvel objectif.

Pour rappel, concernant ce tutoriel, vous supposez que l’exemple contradictoire est une transformation affine de x. En d’autres termes, votre exemple contradictoire prend la forme x + r pour un certain r. Dans l’étape suivante, vous allez écrire un script pour générer ce r.

Étape 5 - Création d’un exemple de procédure contradictoire

Dans cette étape, vous apprendrez une perturbation r, de sorte que votre corgi soit classé à tort comme un poisson rouge. Créez un nouveau fichier appelé step_5_perturb.py​​​​​ :

  1. nano step_5_perturb.py

Tout d’abord, il faut importer les packages nécessaires et déclarer une fonction main :

step_5_perturb.py
from torch.autograd import Variable
import torchvision.models as models
import torch.nn as nn
import torch.optim as optim
import numpy as np
import torch
import os

from step_2_pretrained import get_idx_to_label, get_image_transform, predict, load_image
from step_3_adversarial import get_adversarial_example


def main():
    pass


if __name__ == '__main__':
    main()

Directement après vos importations et avant la fonction main, définissez deux constantes :

step_5_perturb.py
. . .
TARGET_LABEL = 1
EPSILON = 10 / 255.
. . .

La première constante TARGET_LABEL est la classe dans laquelle il faut confondre le corgi. Dans ce cas, l’indice 1 correspond à « poisson rouge ». La deuxième constante EPSILON est la quantité maximale de perturbation autorisée pour chaque valeur d’image. Cette limite est introduite de manière à ce que l’image soit imperceptiblement altérée.

En suivant vos deux constantes, ajoutez une fonction d’aide pour définir un réseau de neurones et le paramètre de perturbation r:

step_5_perturb.py
. . .
def get_model():
    net = models.resnet18(pretrained=True).eval()
    r = nn.Parameter(data=torch.zeros(1, 3, 224, 224), requires_grad=True)
    return net, r
. . .
  • model.resnet18(pretrained=True) charge un réseau neuronal préformé appelé ResNet18, comme auparavant.  Comme auparavant, vous mettez le modèle en mode évaluation en utilisant .eval.
  • nn.Parameter(...) définit une nouvelle perturbation r, la taille de l’image d’entrée. L’image d’entrée est également de la taille (1, 3, 224, 224).  L’argument du mot-clé require_grad=True assure que vous pouvez mettre à jour cette perturbation r dans les lignes suivantes, dans ce fichier.

Ensuite, commencez à modifier votre fonction main. Commencez par charger le réseau modèle, charger les entrées x, et définir l’étiquette label :

step_5_perturb.py
. . .
def main():
    print(f'Target class: {get_idx_to_label()[str(TARGET_LABEL)]}')
    net, r = get_model()
    x = load_image()
    labels = Variable(torch.Tensor([TARGET_LABEL])).long()
  . . .

Ensuite, définissez à la fois le critère et l’optimiseur dans votre fonction. Le premier dit à PyTorch quel est l’objectif, c’est-à-dire quelles sont les pertes à minimiser. Ce dernier indique à PyTorch comment entraîner votre paramètre r :

step_5_perturb.py
. . .
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD([r], lr=0.1, momentum=0.1)
. . .

Directement après, ajoutez la boucle de formation principale pour votre paramètre r:

step_5_perturb.py
. . .
    for i in range(30):
        r.data.clamp_(-EPSILON, EPSILON)
        optimizer.zero_grad()

        outputs = net(x + r)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        _, pred = torch.max(outputs, 1)
        if i % 5 == 0:
            print(f'Loss: {loss.item():.2f} / Class: {get_idx_to_label()[str(int(pred))]}')
. . .

À chaque itération de cette boucle de formation, vous devez :

  • r.data.clamp_(...) : Vous assurer que le paramètre r est petit, dans EPSILON de 0.
  • optimizer.zero_grad(): Effacez tous les gradients que vous avez calculés lors de l’itération précédente.
  • model(x + r): Faire une inférence sur l’image modifiée x + r.
  • Calculez la perte.
  • Calculez le gradient perte.backward.
  • Prenez une étape de descente en gradient optimizer.step.
  • Calculer la prédiction pred.
  • Enfin, signalez la perte et la classe print(...).

Ensuite, sauvegardez la dernière perturbation r :

step_5_perturb.py
def main():
    . . .
    for i in range(30):
        . . .
    . . .
    np.save('outputs/adversarial_r.npy', r.data.numpy())

Directement à la suite, toujours dans la fonction main, sauvegardez l’image perturbée :

step_5_perturb.py
. . .
    os.makedirs('outputs', exist_ok=True)
    adversarial = get_adversarial_example(x, r)

Enfin, faites des prédictions à la fois sur l’image originale et sur l’exemple contradictoire :

step_5_perturb.py
    print(f'Old prediction: {predict(x)}')
    print(f'New prediction: {predict(x + r)}')

Vérifiez que votre script correspond à step_5_perturb.py sur GitHub. Sauvegardez, quittez et lancez le script :

  1. python step_5_perturb.py assets/dog.jpg

Votre script donnera les résultats suivants.

Output
Target class: goldfish, Carassius auratus Loss: 17.03 / Class: Pembroke, Pembroke Welsh corgi Loss: 8.19 / Class: Pembroke, Pembroke Welsh corgi Loss: 5.56 / Class: Pembroke, Pembroke Welsh corgi Loss: 3.53 / Class: Pembroke, Pembroke Welsh corgi Loss: 1.99 / Class: Pembroke, Pembroke Welsh corgi Loss: 1.00 / Class: goldfish, Carassius auratus Old prediction: Pembroke, Pembroke Welsh corgi New prediction: goldfish, Carassius auratus

Les deux dernières lignes indiquent que vous avez maintenant terminé la construction d’un exemple contradictoire à partir de zéro. Votre réseau neuronal classe maintenant une image de corgi parfaite comme un poisson rouge.

Vous avez maintenant montré que les réseaux neuronaux peuvent être facilement dupés, qui plus est, le manque de robustesse aux exemples contradictoires a des conséquences importantes. La question suivante est tout à fait naturelle : Comment pouvez-vous lutter contre les exemples contradictoires ? De nombreuses recherches ont été menées par différentes organisations, dont OpenAI. Dans la section suivante, vous présenterez une défense pour contrecarrer cet exemple de confrontation.

Étape 6 - Se défendre contre des exemples contradictoires

Au cours de cette étape, vous mettrez en œuvre une défense contre des exemples contradictoires. L’idée est la suivante : vous êtes maintenant le propriétaire du classificateur d’animaux en cours de déploiement en phase de production. Vous ne savez pas quels exemples contradictoires peuvent être générés, mais vous pouvez modifier l’image ou le modèle pour vous protéger contre les attaques.

Avant de vous défendre, vous devriez voir par vous-même combien la manipulation de l’image est imperceptible. Ouvrez les deux images suivantes :

  1. assets/dog.jpg
  2. outputs/adversarial.png

Ici, vous montrez les deux côte à côte. Votre image originale aura un rapport d’aspect différent. Pouvez-vous dire quel est l’exemple de la procédure contradictoire ?

(gauche) Corgi en poisson rouge, contradictoire, (droite) Corgi en lui-même, non contradictoire

Remarquez que la nouvelle image semble identique à l’originale. Il s’avère que l’image de gauche est l’image contradictoire. Pour en être certain, téléchargez l’image et lancez votre script d’évaluation :

  1. wget -O assets/adversarial.png https://github.com/alvinwan/fooling-neural-network/blob/master/outputs/adversarial.png?raw=true
  2. python step_2_pretrained.py assets/adversarial.png

Cela donnera naissance à la classe des poissons rouges, pour prouver son caractère contradictoire :

Output
Prediction: goldfish, Carassius auratus

Vous dirigerez une défense assez naïve, mais efficace : Comprimer l’image en écrivant dans un format JPEG avec perte. Ouvrez l’invite interactive Python :

  1. python

Ensuite, chargez l’image contradictoire au format PNG, et enregistrez-la à nouveau au format JPEG.

  1. from PIL import Image
  2. image = Image.open('assets/adversarial.png')
  3. image.save('outputs/adversarial.jpg')

Tapez CTRL + D pour quitter l’invite interactive Python. Ensuite, faites des inférences avec votre modèle sur l’exemple contradictoire compressé :

  1. python step_2_pretrained.py outputs/adversarial.jpg

Cela va maintenant produire la classe corgi, prouvant l’efficacité de votre défense naïve.

Output
Prediction: Pembroke, Pembroke Welsh corgi

Vous avez maintenant terminé votre toute première défense contradictoire. Notez que cette défense n’exige pas de savoir comment l’exemple contradictoire a été généré. C’est ce qui fait une défense efficace. Il existe également de nombreuses autres formes de défense, dont beaucoup impliquent le recyclage du réseau neuronal. Toutefois, ces procédures de recyclage sont un sujet à part entière et dépassent le cadre de ce tutoriel. Ceci conclut votre guide sur l’apprentissage automatique contradictoire.

Conclusion

Pour comprendre les implications de votre travail dans ce tutoriel, revisitez les deux images côte à côte l’original et l’exemple contradictoire.

(gauche) Corgi en poisson rouge, contradictoire, (droite) Corgi en lui-même, non contradictoire

Malgré le fait que les deux images semblent identiques à l’œil humain, la première a été manipulée pour tromper votre modèle. Les deux images montrent clairement un corgi, et pourtant le modèle est tout à fait sûr que le second modèle contient un poisson rouge. Cela devrait vous préoccuper et, en terminant ce tutoriel, gardez à l’esprit la fragilité de votre modèle. Il suffit d’appliquer une simple transformation pour la tromper. Ce sont là des dangers réels et plausibles qui échappent même à la recherche de pointe. La recherche qui va au-delà de la sécurité de l’apprentissage automatique est tout aussi sensible à ces défauts, et, en tant que professionnel, il vous appartient d’appliquer l’apprentissage automatique en toute sécurité. Pour plus de lectures, consultez les liens suivants :

Pour plus de contenu et de tutoriels sur l’apprentissage automatique, vous pouvez visiter notre Page thématique sur l’apprentissage automatique.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Alvin Wan

author

AI PhD Student @ UC Berkeley

I’m a diglot by definition, lactose intolerant by birth but an ice-cream lover at heart. Call me wabbly, witling, whatever you will, but I go by Alvin



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel