# 3 ways of calculating gradient give 3 differents results

Hello,
To make a kind of fast gradient sign attack, I try to calculate the gradient of an image against a softmax loss. The problem is that the image is normalized before entering the model, and I want to get the gradient relative to the unnormalized (untouched) image.

I think the theoretical gradient of the normalization transform:
`torchvision.transforms.Normalize(mean=mean, std=std)`
can be obtained with:
`torchvision.transforms.Normalize(mean=0, std=std)`

I tried to calculate the gradient in three different ways but I get 3 different results. What am I doing wrong?

The model I use is a model transferred from AlexNet :

``````  n_classes = 10
model = torchvision.models.alexnet(pretrained=False)
model.classifier = torch.nn.Linear(model.classifier.in_features, n_classes)
``````
``````    image = PIL.Image.open("U:\\PROJET_3A\\imagenette2-160\\train\\n01440764\\n01440764_17174.JPEG")
transform = torchvision.transforms.Compose([torchvision.transforms.Resize(256),
torchvision.transforms.CenterCrop(224),
torchvision.transforms.ToTensor(),])
image = transform(image)
image = image[None, :]

mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]

normalize = torchvision.transforms.Normalize(mean=mean, std=std)
target_class = 1

test1 = image.clone().detach()
vector_scores = self.model(normalize(test1))
loss_target = -torch.nn.functional.log_softmax(vector_scores, dim=1)[0, target_class]
loss_target.backward()

vector_scores = self.model(test2)
loss_target = -torch.nn.functional.log_softmax(vector_scores, dim=1)[0, target_class]
loss_target.backward()

test3 = normalize(image).clone().detach()
vector_scores = self.model(test3)
loss_target = -torch.nn.functional.log_softmax(vector_scores, dim=1)[0, target_class]
loss_target.backward()
``````

Can you call `self.model.zero_grad()` in-between measurements? Gradients are accumulated in `.backward()`, so the result for your 2nd method is actually showing method 1 + method 2.

Also, can you share the results? How different are they?

Hi,
I added model.zero_grad() between the measurements and then displayed the gradients without modifying them with matplotlib. The differences are not huge but I see more intense spots in some measurements.

Example :

Can you compare the error via its MSE or MAE value instead of a figure?

I added the calculation of the MSE, here are my results:

``````mse grad 1 grad 2 0.000966
``````

Here is a part of my code after modification, don’t hesitate to tell me if something is wrong:

``````test1 = image.clone().detach()
vector_scores = self.model(normalize(test1))
loss_target = -torch.nn.functional.log_softmax(vector_scores, dim=1)[0, target_class]
loss_target.backward()

vector_scores = self.model(test2)
loss_target = -torch.nn.functional.log_softmax(vector_scores, dim=1)[0, target_class]
loss_target.backward()

test3 = normalize(image.clone().detach())