(Méthode d'attaque rapide par signe de gradient détaillée ici : https://pytorch.org/tutorials/beginner/fgsm_tutorial.html )
J'ai un classificateur entraîné avec une précision de >90% que j'utilise pour créer ces exemples contradictoires, puis j'utilise torchvision.utils.save_image
pour enregistrer les images dans différents dossiers.
La hiérarchie des dossiers est la suivante :
-
DOSSIER_1
- original_image.jpg (1)
- image_perturbée.jpg (2)
-
DOSSIER_2
- image_perturbée.jpg (3)
Aquí (2) y (3) sont le même tenseur d'image, qui est la somme du tenseur d'image original et d'un tenseur d'image de perturbation - je veux juste sauver les images qui ont trompé le classificateur deux fois. Ce que je constate, c'est que (1) y (2) imprimer O.K., mais (3) n'imprime que le tenseur d'image de la perturbation (il a soustrait le tenseur d'image original !). Ainsi, lorsque j'ouvre (2) Je vois mon image originale avec tout le bruit en haut (des commutations aléatoires de pixels RVB à cause de l'attaque FGSM), mais lorsque j'ouvre le fichier (3) Je vois une toile blanche avec ces interrupteurs aléatoires de pixels RVB SEULEMENT.
Puisque j'imprime la même variable ( données perturbées ) deux fois, je ne comprends pas pourquoi torchvision.utils.save_image
choisit de soustraire le tenseur de l'image de perturbation la deuxième fois que je l'appelle. Le code pour ce que je décris est ci-dessous, et data est le tenseur de l'image originale.
epsilon = 0.5
# Collect datagrad
data_grad = data.grad.data
# Call FGSM Attack
perturbed_data = fgsm_attack(data, epsilon, data_grad)
# Re-classify the perturbed image
perturbed_output = model(perturbed_data)
perturbed_output = torch.sigmoid(perturbed_output)
perturbed_output = perturbed_output.max(1, keepdim=True)[1]
max_pred = perturbed_output.item()
final_pred = torch.tensor([0, 0]).to(device)
final_pred[max_pred] = 1
# Store all original and perturbed images, regardless of model prediction
torchvision.utils.save_image(data, "./FOLDER_1/original.jpg")
torchvision.utils.save_image(perturbed_data, "./FOLDER_1/perturbed_image.jpg")
# If the perturbed image fools our classifier, put a copy of it in FOLDER_2
if !torch.all(torch.eq(final_pred, target)):
torchvision.utils.save_image(perturbed_data, "./FOLDER_2/perturbed_image.jpg")
Je suis presque sûr qu'il s'agit d'un bug de Torchvision, mais je pensais demander ici avant de soumettre un rapport de bug. Peut-être que quelqu'un voit quelque chose que je ne vois pas. J'ai également joint un exemple de (2) y (3) pour la visualisation. La première image est dans le format correct, mais la seconde s'imprime sans le tenseur d'image original.