Open c0052742 opened 1 year ago
Hi @c0052742 Thank you for using ART for YOLO!
@kieranfraser What do you think?
Thanks @beat-buesser,
Hi @c0052742, thanks for reaching out!
We currently have a notebook here that demonstrates how to set up YOLOv5 for an attack with ART.
Also, just to note that the CarliniL2Method
attack you have implemented will fail as it supports classification estimators and not object detectors. FGM and PGD should work.
If more interested in the individual loss components, as opposed the total, they differ slightly between YOLOv3 and v5 (which you can see here) - they're implemented in this example below which should help.
Let us know how you get on!
import torch
import numpy as np
from art.attacks.evasion.fast_gradient import FastGradientMethod
from art.attacks.evasion import ProjectedGradientDescent
from art.estimators.object_detection import PyTorchYolo
import yolov5
from yolov5.utils.loss import ComputeLoss
import requests
from PIL import Image
from io import BytesIO
response = requests.get('https://ultralytics.com/images/zidane.jpg')
img = np.asarray(Image.open(BytesIO(response.content)).resize((640, 640)))
img_reshape = img.transpose((2, 0, 1))
image = np.stack([img_reshape], axis=0).astype(np.float32)
x = image.copy()
config = {"attack_losses": ["loss_total", "loss_box", "loss_obj", "loss_cls"],}
class Yolo(torch.nn.Module):
def __init__(self, model):
super().__init__()
self.model = model
self.model.hyp = {'box': 0.05,
'obj': 1.0,
'cls': 0.5,
'anchor_t': 4.0,
'cls_pw': 1.0,
'obj_pw': 1.0,
'fl_gamma': 0.0
}
self.compute_loss = ComputeLoss(self.model.model.model)
def forward(self, x, targets=None):
if self.training:
outputs = self.model.model.model(x)
loss, loss_items = self.compute_loss(outputs, targets)
loss_components_dict = {"loss_total": loss,
"loss_box": loss_items[0],
"loss_obj": loss_items[1],
"loss_cls": loss_items[2]}
return loss_components_dict
else:
return self.model(x)
model = yolov5.load('yolov5s.pt')
model = Yolo(model)
detector = PyTorchYolo(model=model,
device_type='cpu',
input_shape=(3, 640, 640),
clip_values=(0, 255),
attack_losses=config["attack_losses"])
fgm = FastGradientMethod(estimator=detector, eps=0.01, targeted=False)
pgd = ProjectedGradientDescent(estimator=detector, eps_step=0.005, max_iter=100, targeted=False)
adversarial_image_fgm = fgm.generate(x=x, y=None)
adversarial_image_pgd = pgd.generate(x=x)
I encountered an error while trying to run the ART_attack.py script for my YOLOv5 object detection model. The error message reads: The code:
The error:
"Traceback (most recent call last): File "c:\dis\dissertation - Copy\yolov5\ART_attack.py", line 52, in <module> adversarial_image_fgm = fgm.generate(x=x, y=None) File "C:\Users\c0052742\AppData\Roaming\Python\Python310\site-packages\art\attacks\evasion\fast_gradient.py", line 316, in generate adv_x_best = self._compute( File "C:\Users\c0052742\AppData\Roaming\Python\Python310\site-packages\art\attacks\evasion\fast_gradient.py", line 540, in _compute perturbation = self._compute_perturbation(batch, batch_labels, mask_batch, decay, momentum) File "C:\Users\c0052742\AppData\Roaming\Python\Python310\site-packages\art\attacks\evasion\fast_gradient.py", line 395, in _compute_perturbation grad = self.estimator.loss_gradient(x, y) * (1 - 2 * int(self.targeted)) File "C:\Users\c0052742\AppData\Roaming\Python\Python310\site-packages\art\estimators\object_detection\pytorch_yolo.py", line 377, in loss_gradient loss = output[loss_name] TypeError: list indices must be integers or slices, not str"
The error seems to be related to the line of code that tries to access an element in a list using a string as an index. Specifically, the "loss_name" variable is a string that is being used to access an element in the "output" list, which is causing the error.
I am not sure what is causing this issue and how to resolve it. Any help would be appreciated. I have looked into other similar issue like #1796 but I can't seem to fix it while using YOLOv5.