jacobgil / pytorch-grad-cam

Advanced AI Explainability for computer vision. Support for CNNs, Vision Transformers, Classification, Object detection, Segmentation, Image similarity and more.
https://jacobgil.github.io/pytorch-gradcam-book
MIT License
10.32k stars 1.55k forks source link

'tuple' object has no attribute 'cpu' #386

Open sumit-iitp-2111 opened 1 year ago

sumit-iitp-2111 commented 1 year ago

when I try to execute grayscale_cam = cam(tensor)[0, :,:] in the tutorial for yolov5, I get this error. Please help, I am using the same code for yolov7

CAkahay commented 1 year ago

Please let me know how we can resolve this problem if ur done with this problem

jacobgil commented 1 year ago

It is possible that the YOLO5 model changed and now also returns something else. The tutorial assumed that the YOLO5 model returns a tensor, when it gets a tensor.

I need to check what it returns now (i'm outside right now so can't check that yet), but if we know that it returns for example a tuple where the first element is the actual tensor, we could wrap it in a model that gets the first element.

class YOLOModelOutputWrapper(torch.nn.Module):
    def __init__(self, model): 
        super(YOLOModelOutputWrapper, self).__init__()
        self.model = model

    def forward(self, x):
        return self.model(x)[0]

model = YOLOModelOutputWrapper(model)

Can someone please confirm what YOLO returns now?

acsgn95 commented 1 year ago

Can you give the whole error message? Because I solved this!

acsgn95 commented 1 year ago

@sumit-iitp-2111 you need to go BaseCAM and you must to put there an if condition!

JunKaiLiao commented 1 year ago

@acsgn95
Hi, I would like to use Gradcam with YOLOv7, but I still got this error. Could you show your solution? Thank you very much !!

acsgn95 commented 1 year ago

@JunKaiLiao can you share the total error to here? I will help

JunKaiLiao commented 1 year ago

Hi, @acsgn95 Thanks for your reply!! I got the error as shown below.


AttributeError Traceback (most recent call last) Input In [55], in <cell line: 4>() 2 boxes, colors, names = parse_detections(results) 3 cam = EigenCAM(model, target_layers, use_cuda=False) ----> 4 grayscale_cam = cam(tensor)[0, :, :] 5 cam_image = show_cam_on_image(img, grayscale_cam, use_rgb=True) 6 Image.fromarray(cam_image)

File ~/JunKai/yolov7_Cam/pytorch_grad_cam/base_cam.py:188, in BaseCAM.call(self, input_tensor, targets, aug_smooth, eigen_smooth) 184 if aug_smooth is True: 185 return self.forward_augmentation_smoothing( 186 input_tensor, targets, eigen_smooth) --> 188 return self.forward(input_tensor, 189 targets, eigen_smooth)

File ~/JunKai/yolov7_Cam/pytorch_grad_cam/base_cam.py:76, in BaseCAM.forward(self, input_tensor, targets, eigen_smooth) 74 outputs = self.activations_and_grads(input_tensor) 75 if targets is None: ---> 76 target_categories = np.argmax(outputs.cpu().data.numpy(), axis=-1) 77 targets = [ClassifierOutputTarget( 78 category) for category in target_categories] 80 if self.uses_gradients:

AttributeError: 'tuple' object has no attribute 'cpu'

fallcat commented 1 year ago

@acsgn95 I have the same problem with ViT. I tried the above wrapping method but it doesn't work. Could you help me take a look? Thanks!

class WrappedModel(torch.nn.Module):
    def __init__(self, model, postprocess): 
        super(WrappedModel, self).__init__()
        self.model = model
        self.postprocess = postprocess

    def forward(self, x):
        return self.model(x)[0]

class TorchImageGradCAM(TorchAttribution):
    def __init__(self, model, target_layer, postprocess=None):
        model = WrappedModel(model, postprocess)

        super().__init__(model, postprocess)

        self.target_layer = target_layer
        self.grad_cam = GradCAM(model=model, target_layers=[model.model.vit.encoder.layer[11]], 
                                use_cuda=True if torch.cuda.is_available() else False)

    def forward(self, X, label=None):
        grad_cam_result = self.grad_cam(input_tensor=X)
        return grad_cam_result

And trace back

Traceback (most recent call last):                                             | 0/3 [00:00<?, ?it/s]
  File "actions/wrapper/eval_wrapper_cls_explainers.py", line 458, in <module>
    main()
  File "actions/wrapper/eval_wrapper_cls_explainers.py", line 384, in main
    expln = explainer(inputs)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/nlp/data/weiqiuy/exlib/src/exlib/explainers/gradcam.py", line 38, in forward
    grad_cam_result = self.grad_cam(input_tensor=X)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/pytorch_grad_cam/base_cam.py", line 188, in __call__
    return self.forward(input_tensor,
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/pytorch_grad_cam/base_cam.py", line 74, in forward
    outputs = self.activations_and_grads(input_tensor)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/pytorch_grad_cam/activations_and_gradients.py", line 42, in __call__
    return self.model(x)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/nlp/data/weiqiuy/exlib/src/exlib/explainers/gradcam.py", line 15, in forward
    return self.model(x)[0]
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/transformers/models/vit/modeling_vit.py", line 787, in forward
    outputs = self.vit(
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/transformers/models/vit/modeling_vit.py", line 577, in forward
    encoder_outputs = self.encoder(
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
    return forward_call(*args, **kwargs)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/transformers/models/vit/modeling_vit.py", line 407, in forward
    layer_outputs = layer_module(hidden_states, layer_head_mask, output_attentions)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1547, in _call_impl
    hook_result = hook(self, args, result)
  File "/nlp/data/weiqiuy/miniconda3/envs/attn/lib/python3.8/site-packages/pytorch_grad_cam/activations_and_gradients.py", line 24, in save_activation
    self.activations.append(activation.cpu().detach())
AttributeError: 'tuple' object has no attribute 'cpu'
ymy1946676292 commented 5 months ago

To solve this problem,please follow the blew process: Firstly, change this file, from this picture: first Secondly, change this file, from this picture: second

azizjadehs commented 2 months ago

@ymy1946676292 @JunKaiLiao @jacobgil Hello guys I hope you are doing well.

I am interested to know if you guys managed to use Grad-CAM with YOLOv7. I am trying to do it since a week and I solved many problems, however I encounter a new problem every time I am solving something.

Now I got an error message TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first. which refers to the tensor still being in the GPU and I tried to solve it with .cpu() but not working.

Any ideas ?

ymy1946676292 commented 2 months ago

Hello, you can use Tensor.cpu().numpy() to have a try ---- Replied Message ---- From Abdulaziz @.> Date 07/30/2024 20:45 To @.> Cc @.>@.> Subject Re: [jacobgil/pytorch-grad-cam] 'tuple' object has no attribute 'cpu' (Issue #386) @ymy1946676292 @JunKaiLiao @jacobgil Hello guys I hope you are doing well. I am interested to know if you guys managed to use Grad-CAM with YOLOv7. I am trying to do it since a week and I solved many problems, however I encounter a new problem every time I am solving something. Now I got an error message TypeError: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first. which refers to the tensor still being in the GPU and I tried to solve it with .cpu() but not working. Any ideas ? — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>