Can you replace the loop by the following and check
while True:
    x_fooling=x_fooling.requires_grad_()
    l=model(x_fooling)[0][target_y]
    l.backward()
    dx=1*x_fooling.grad/x_fooling.grad.norm()
    with torch.no_grad():
       x_fooling=x_fooling+dx 
       pred = torch.argmax(model(x_fooling).detach().squeeze())
       if pred == target_y: break