Gradient of X is NoneType in second iteration

Viewed 37

I'm trying to make images which will fool model, but I have some problem with this code. In the second iteration I get TypeError: unsupported operand type(s) for -: 'Tensor' and 'NoneType' Why is the grad NoneType even if it's working for the first time?

X_fooling = X.clone()
X_fooling.requires_grad_()
loss_f = torch.nn.MSELoss()

for i in range(1000):
      score = model(X_fooling)
      y = torch.zeros(1000)
      y[target_y] = 1
      loss = loss_f(score, y)
      print(loss)
      loss.backward()
        
      if target_y == torch.argmax(score):
        break

      X_fooling = X_fooling - X_fooling.grad
1 Answers

I could not fool the network with a target size of 1000. But I was able to fool it with a target size of 64. Here is a minimal code snippet that runs without error:

import matplotlib.pyplot as plt
import torch

torch.manual_seed(0)
target_size = 64
model = torch.nn.Linear(10, target_size)
target_y = torch.randint(0, target_size, (1, ))

X = torch.rand(1, 10)

X_fooling = X.clone()
X_fooling.requires_grad_()
loss_f = torch.nn.MSELoss()

history = []
goal_achieved = False

for i in range(10_000):
    score = model(X_fooling)
    y = torch.zeros(1, target_size)
    y[:, target_y] = 1
    loss = loss_f(score, y)
    history.append(loss.detach().cpu().item())
    loss.backward()
    
    if target_y == torch.argmax(score):
        goal_achieved = True
        break
    
    X_fooling = (X_fooling - X_fooling.grad).detach()
    X_fooling.requires_grad_()
    model.zero_grad()

plt.title(f"Goal achieved: {goal_achieved}")
plt.plot(history)
plt.show()

Output: History

The thing is that you have to detach your input tensor to the graph after your backward pass.

Related