Harry24k / adversarial-attacks-pytorch

PyTorch implementation of adversarial attacks [torchattacks].
https://adversarial-attacks-pytorch.readthedocs.io/en/latest/index.html
MIT License
1.79k stars 337 forks source link

One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior. #170

Closed rishiyanth closed 6 months ago

rishiyanth commented 7 months ago

✨ Short description of the bug [tl;dr]

The above RunTimeError arises when I am trying to perform torchattack on my custom convolutional layer. It expects allow_unused=True to be set in torch.autograd.grad of the package file

💬 Detailed code and results

RuntimeError Traceback (most recent call last) in <cell line: 1>() ----> 1 perform_attack(QCNN)

3 frames in perform_attack(model) 43 44 #PGD attack ---> 45 adversarial_pgd = attack_pgd(image, label) 46 y_pred_pgd = model1(adversarial_pgd) 47 y_pred_pgd = y_pred_pgd.argmax(dim=1)

/usr/local/lib/python3.10/dist-packages/torchattacks/attack.py in call(self, inputs, labels, *args, *kwargs) 509 self._set_normalization_applied(True) 510 else: --> 511 adv_inputs = self.forward(inputs, labels, args, **kwargs) 512 # adv_inputs = self.to_type(adv_inputs, self.return_type) 513

/usr/local/lib/python3.10/dist-packages/torchattacks/attacks/pgd.py in forward(self, images, labels) 70 71 # Update adversarial images ---> 72 grad = torch.autograd.grad( 73 cost, adv_images, retain_graph=False, create_graph=False 74 )[0]

/usr/local/lib/python3.10/dist-packages/torch/autograd/init.py in grad(outputs, inputs, grad_outputs, retain_graph, create_graph, only_inputs, allow_unused, is_grads_batched, materialize_grads) 392 ) 393 else: --> 394 result = Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass 395 t_outputs, 396 gradoutputs,

RuntimeError: One of the differentiated Tensors appears to not have been used in the graph. Set allow_unused=True if this is the desired behavior.

rikonaka commented 7 months ago

Hi @rishiyanth , can you provide a working test code for me for debug?

rishiyanth commented 7 months ago

https://github.com/mit-han-lab/torchquantum/blob/main/examples/quanvolution/quanvolution.ipynb I ran the above code for developing the model

Below attached is the colab notebook which you can run and debug https://colab.research.google.com/drive/1S52Ibl3-Bxu_DqHcqopx7fVZSSu9-IaQ?usp=sharing

Adversarian commented 6 months ago

I am not 100% certain if this is the issue but in your HybridModel class we have:

class HybridModel(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.qf = QuanvolutionFilter()
        self.linear = torch.nn.Linear(4*14*14, 10)

    def forward(self, x, use_qiskit=False):
        with torch.no_grad():
          x = self.qf(x, use_qiskit)
        x = self.linear(x)
        return F.log_softmax(x, -1)

Taking a closer look at the forward method, you're using a torch.no_grad() context manager ahead of forwarding your inputs. This should cut them off from the computational graph when requires_grad is set on the inputs. Since FGSM is a gradient based method it cannot calculate the gradients of some cost function w.r.t. a set of inputs which you have explicitly cut off from the computation graph with no_grad().

I think removing this clause should resolve your issue but I'm not familiar enough with tq to know if that's even possible.

rishiyanth commented 6 months ago

Ok, let me try that out. Thank you!