Git Product home page Git Product logo

frgfm / torch-cam Goto Github PK

View Code? Open in Web Editor NEW
1.8K 10.0 185.0 10.26 MB

Class activation maps for your PyTorch models (CAM, Grad-CAM, Grad-CAM++, Smooth Grad-CAM++, Score-CAM, SS-CAM, IS-CAM, XGrad-CAM, Layer-CAM)

Home Page: https://frgfm.github.io/torch-cam/

License: Apache License 2.0

Python 99.40% Makefile 0.60%
pytorch python deep-learning cnn activation-maps gradcam-plus-plus gradcam saliency-map interpretability interpretable-deep-learning

torch-cam's Introduction

TorchCAM: class activation explorer

CI Status ruff ruff Test coverage percentage

PyPi Version Conda Version pyversions License

Huggingface Spaces Open in Colab

Documentation Status

Simple way to leverage the class-specific activation of convolutional layers in PyTorch.

Source: image from woopets (activation maps created with a pretrained Resnet-18)

Quick Tour

Setting your CAM

TorchCAM leverages PyTorch hooking mechanisms to seamlessly retrieve all required information to produce the class activation without additional efforts from the user. Each CAM object acts as a wrapper around your model.

You can find the exhaustive list of supported CAM methods in the documentation, then use it as follows:

# Define your model
from torchvision.models import resnet18
model = resnet18(pretrained=True).eval()

# Set your CAM extractor
from torchcam.methods import SmoothGradCAMpp
cam_extractor = SmoothGradCAMpp(model)

Please note that by default, the layer at which the CAM is retrieved is set to the last non-reduced convolutional layer. If you wish to investigate a specific layer, use the target_layer argument in the constructor.

Retrieving the class activation map

Once your CAM extractor is set, you only need to use your model to infer on your data as usual. If any additional information is required, the extractor will get it for you automatically.

from torchvision.io.image import read_image
from torchvision.transforms.functional import normalize, resize, to_pil_image
from torchvision.models import resnet18
from torchcam.methods import SmoothGradCAMpp

model = resnet18(pretrained=True).eval()
# Get your input
img = read_image("path/to/your/image.png")
# Preprocess it for your chosen model
input_tensor = normalize(resize(img, (224, 224)) / 255., [0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

with SmoothGradCAMpp(model) as cam_extractor:
  # Preprocess your data and feed it to the model
  out = model(input_tensor.unsqueeze(0))
  # Retrieve the CAM by passing the class index and the model output
  activation_map = cam_extractor(out.squeeze(0).argmax().item(), out)

If you want to visualize your heatmap, you only need to cast the CAM to a numpy ndarray:

import matplotlib.pyplot as plt
# Visualize the raw CAM
plt.imshow(activation_map[0].squeeze(0).numpy()); plt.axis('off'); plt.tight_layout(); plt.show()

raw_heatmap

Or if you wish to overlay it on your input image:

import matplotlib.pyplot as plt
from torchcam.utils import overlay_mask

# Resize the CAM and overlay it
result = overlay_mask(to_pil_image(img), to_pil_image(activation_map[0].squeeze(0), mode='F'), alpha=0.5)
# Display it
plt.imshow(result); plt.axis('off'); plt.tight_layout(); plt.show()

overlayed_heatmap

Setup

Python 3.8 (or higher) and pip/conda are required to install TorchCAM.

Stable release

You can install the last stable release of the package using pypi as follows:

pip install torchcam

or using conda:

conda install -c frgfm torchcam

Developer installation

Alternatively, if you wish to use the latest features of the project that haven't made their way to a release yet, you can install the package from source:

git clone https://github.com/frgfm/torch-cam.git
pip install -e torch-cam/.

CAM Zoo

This project is developed and maintained by the repo owner, but the implementation was based on the following research papers:

  • Learning Deep Features for Discriminative Localization: the original CAM paper
  • Grad-CAM: GradCAM paper, generalizing CAM to models without global average pooling.
  • Grad-CAM++: improvement of GradCAM++ for more accurate pixel-level contribution to the activation.
  • Smooth Grad-CAM++: SmoothGrad mechanism coupled with GradCAM.
  • Score-CAM: score-weighting of class activation for better interpretability.
  • SS-CAM: SmoothGrad mechanism coupled with Score-CAM.
  • IS-CAM: integration-based variant of Score-CAM.
  • XGrad-CAM: improved version of Grad-CAM in terms of sensitivity and conservation.
  • Layer-CAM: Grad-CAM alternative leveraging pixel-wise contribution of the gradient to the activation.

Source: YouTube video (activation maps created by Layer-CAM with a pretrained ResNet-18)

What else

Documentation

The full package documentation is available here for detailed specifications.

Demo app

A minimal demo app is provided for you to play with the supported CAM methods! Feel free to check out the live demo on Hugging Face Spaces

If you prefer running the demo by yourself, you will need an extra dependency (Streamlit) for the app to run:

pip install -e ".[demo]"

You can then easily run your app in your default browser by running:

streamlit run demo/app.py

torchcam_demo

Example script

An example script is provided for you to benchmark the heatmaps produced by multiple CAM approaches on the same image:

python scripts/cam_example.py --arch resnet18 --class-idx 232 --rows 2

gradcam_sample

All script arguments can be checked using python scripts/cam_example.py --help

Latency benchmark

You crave for beautiful activation maps, but you don't know whether it fits your needs in terms of latency?

In the table below, you will find a latency benchmark (forward pass not included) for all CAM methods:

CAM method Arch GPU mean (std) CPU mean (std)
CAM resnet18 0.11ms (0.02ms) 0.14ms (0.03ms)
GradCAM resnet18 3.71ms (1.11ms) 40.66ms (1.82ms)
GradCAMpp resnet18 5.21ms (1.22ms) 41.61ms (3.24ms)
SmoothGradCAMpp resnet18 33.67ms (2.51ms) 239.27ms (7.85ms)
ScoreCAM resnet18 304.74ms (11.54ms) 6796.89ms (415.14ms)
SSCAM resnet18
ISCAM resnet18
XGradCAM resnet18 3.78ms (0.96ms) 40.63ms (2.03ms)
LayerCAM resnet18 3.65ms (1.04ms) 40.91ms (1.79ms)
CAM mobilenet_v3_large N/A* N/A*
GradCAM mobilenet_v3_large 8.61ms (1.04ms) 26.64ms (3.46ms)
GradCAMpp mobilenet_v3_large 8.83ms (1.29ms) 25.50ms (3.10ms)
SmoothGradCAMpp mobilenet_v3_large 77.38ms (3.83ms) 156.25ms (4.89ms)
ScoreCAM mobilenet_v3_large 35.19ms (2.11ms) 679.16ms (55.04ms)
SSCAM mobilenet_v3_large
ISCAM mobilenet_v3_large
XGradCAM mobilenet_v3_large 8.41ms (0.98ms) 24.21ms (2.94ms)
LayerCAM mobilenet_v3_large 8.02ms (0.95ms) 25.14ms (3.17ms)

*The base CAM method cannot work with architectures that have multiple fully-connected layers

This benchmark was performed over 100 iterations on (224, 224) inputs, on a laptop to better reflect performances that can be expected by common users. The hardware setup includes an Intel(R) Core(TM) i7-10750H for the CPU, and a NVIDIA GeForce RTX 2070 with Max-Q Design for the GPU.

You can run this latency benchmark for any CAM method on your hardware as follows:

python scripts/eval_latency.py SmoothGradCAMpp

All script arguments can be checked using python scripts/eval_latency.py --help

Example notebooks

Looking for more illustrations of TorchCAM features? You might want to check the Jupyter notebooks designed to give you a broader overview.

Citation

If you wish to cite this project, feel free to use this BibTeX reference:

@misc{torcham2020,
    title={TorchCAM: class activation explorer},
    author={François-Guillaume Fernandez},
    year={2020},
    month={March},
    publisher = {GitHub},
    howpublished = {\url{https://github.com/frgfm/torch-cam}}
}

Contributing

Feeling like extending the range of possibilities of CAM? Or perhaps submitting a paper implementation? Any sort of contribution is greatly appreciated!

You can find a short guide in CONTRIBUTING to help grow this project!

License

Distributed under the Apache 2.0 License. See LICENSE for more information.

FOSSA Status

torch-cam's People

Contributors

alexandrosstergiou avatar frgfm avatar pkmandke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

torch-cam's Issues

Make target_layer also a `nn.Module`

🚀 Feature

Hello there,

I would like to pass an nn.Module instance to any *Cam constructor but currently, I can only use 'str'.

Motivation

Well, if your model has a good design it is much easier to pass a reference than the key.

Thanks!

Francesco

Issue when visualizing with xception network

Bug description

I have a varient of xception model which has only 2 classes in final layer. When I use this library with the model it only works with CAM and not with other activation map models.

Code snippet to reproduce the bug

This is the network i use link . Similar error can be seen in some models in Hugging Face
image

Error traceback

File "cam.py", line 34, in <module> activation_map = cam_extractor(out.squeeze(0).argmax().item(), out) File "/hdd/2017CS128/.conda/envs/env_pytorch/lib/python3.6/site-packages/torchcam/methods/core.py", line 143, in __call__ return self.compute_cams(class_idx, scores, normalized) File "/hdd/2017CS128/.conda/envs/env_pytorch/lib/python3.6/site-packages/torchcam/methods/core.py", line 158, in compute_cams weights = self._get_weights(class_idx, scores) File "/hdd/2017CS128/.conda/envs/env_pytorch/lib/python3.6/site-packages/torchcam/methods/gradient.py", line 280, in _get_weights grad_2 = [g2.add_(grad.pow(2)) for g2, grad in zip(grad_2, self.hook_g)] File "/hdd/2017CS128/.conda/envs/env_pytorch/lib/python3.6/site-packages/torchcam/methods/gradient.py", line 280, in <listcomp> grad_2 = [g2.add_(grad.pow(2)) for g2, grad in zip(grad_2, self.hook_g)] RuntimeError: The size of tensor a (10) must match the size of tensor b (149) at non-singleton dimension 3

Environment

ubuntu 18.4
CUDA Version: 11.2

Application In Object Detection

@frgfm
Hello, I am using your CAM program for the first time. I would like to ask, is this program suitable for object detection?
For example, I now use yolov5 to train a model, and then want to use your CAM program to export the heatmap of the detected image. Is this feasible? Although I slightly know that CAM is aimed at classification problems, the detection also includes classification.

Add annotation typing and mypy CI verification

Considering the relatively small codebase, it would be preferable to add annotation typing early for clearer documentation and interface. A CI job should be added to enforce mypy where it's possible.

Include `requirements.txt` in the source

Bug description

The file requirements.txt (reqfile) is missing from the source, although setup.py:install_requires depends on requirements.txt. Without the reqfile, it is not possible to install torchcam from the source.

How to fix it?

Include requirements.txt in the MANIFEST.in file and publish again on PyPI.

image

The result of ScoreCAM, SSCAM, ISCAM have no heatmap

🐛 Bug

I run the cam-example.py with this image url (https://s3.ax1x.com/2021/03/14/60gHte.png) and class-idx 407, but the result shows no heatmap on ScoreCAM, SSCAM, ISCAM :
image

Environment

Please describe your environement so that the bug can be easily reproduced:

  • Torchcam Version (e.g., 0.1.1): 2021/3/14 installed
  • PyTorch Version (e.g., 1.7): 1.7
  • OS (e.g., Linux): Windows
  • How you installed Torchcam (conda, pip, source): pip
  • Python version: 3.8
  • CUDA/cuDNN version: 10.2, but i use cpu to run the python script
  • GPU models and configuration: others are default

By the way, i found the result of grad cam is different with the one generate by this repo, its grad-cam result is :
cam

What is class_idx in __call__() ??

Hello sir,
I want to display heat-map for my classification task.
So i found your library.
What is class_idx of call()??
(I think that it is class index of top-1)

And,
Using my datasets,
I met nan.
In compute_cam() of core.py
My result of torch.nansum has all < 0.
Then F.relu return all 0.
So, in normalization, it return nan.

Is this nornal??
If not, what should i change in my data??

Thanks.
Edward cho

Allowing for batch processing/multi-processing

🚀 Feature

Currently when I use this package, I can only feed a single image through the network at a time in order to process a CAM. However, it would be greatly beneficial to me if I could pass an entire batch of images through the network and obtain a batch of CAMs. This would greatly speed up my processing time, as I am using the CAMs as supervision for a segmentation branch, and at the moment am building a batch of CAMs one at a time (very slow).

I could possibly look into how this could be implemented myself, but since you are more familiar with your own code then maybe you already have an idea of how this could be implemented.

torch 1.8.0+cu111 - UserWarning for non-full backward hook

torch: '1.8.0+cu111'
Python: 3.9

Getting the following warning:

/lib/python3.9/site-packages/torch/nn/modules/module.py:795: UserWarning: Using a non-full backward hook when the forward contains multiple autograd Nodes is deprecated and will be removed in future versions. This hook will be missing some grad_input. Please use register_full_backward_hook to get the documented behavior.
  warnings.warn("Using a non-full backward hook when the forward contains multiple autograd Nodes "

Might be something to keep an eye for to prevent future errors? :)

package conflicts

When I use pytorch 1.6, there are a lot of package conflicts when installing torchcam, how can I solve it?
Thank u.

Some models will calculate 'nan'

I try your code with your example picture on resnet34 and resnet50 ,the the scoreCAM, SSCAM, ISCAM will calculate 'nan' .
can you help me to solve this problem?

I try on torch 1.5

Release tracker - v0.5.0

This issue is to be used to track the roadmap of TorchCAM for release v0.5.0, and collect feedback from users & contributors.

Methods

Scripts

Demo

Why is the output different every time

hi,this code is great,but i meet a Strange appearance
I set the model to eval and then use the example given, but I find that the output of the same photo is different every time.
how can i do it , thanks :)

Missing explaination in example

The suggested example below have no explaination where scores come from. I also assume that the import of cam is missing,

from torcham.cams import SmoothGradCAMpp
from torchvision.models import resnet18

img_tensor = torch.rand((1, 3, 224, 224))
model = resnet18(pretrained=True).eval()
# Hook your model before the forward pass
cam_extractor = cam(model)
# By default the last conv layer will be selected
out = model(input_tensor)
# Retrieve the CAM
activation_map = cam_extractor(out.squeeze(0).argmax().item(), scores)

How can I use cam to train my model?

🚀 Feature

In the cam_example.py file, the cam only be used as visualization. So how can I use the cam to train my model to get the discriminative part in image just like "Learning Deep Features for Discriminative Localization" says.

[signature] Add automatic layer name resolution

Currently, some CAM constructor arguments require several user's inputs. While most layer name could be checked automatically by default. Automatic layer name resolution should be enabled to reduce the user's minimum inputs.

Add a `conda` install option for `torchcam`

🚀 Feature

A conda install option could be very helpful. Preferably, if it is on conda-forge channel. I have already started the work (PR: conda-forge/staged-recipes#17307). Once the PR is merged, you will be able to install torchcam as:

conda install -c conda-forge torchcam

I will post updates once the PR is merged here in this issue.

Getting the CAM for BiT

Hi.

I am trying to get CAM for a particular variant of the BiT (Big Transfer) family of ResNets. I think I am providing the the target_layer name correctly however I am unable to make it work.

Here's how the last portion of the model looks like:

(norm): GroupNormAct(
    32, 6144, eps=1e-05, affine=True
    (act): ReLU(inplace=True)
  )
  (head): ClassifierHead(
    (global_pool): SelectAdaptivePool2d (pool_type=avg, flatten=False)
    (fc): Conv2d(6144, 1000, kernel_size=(1, 1), stride=(1, 1))
  )
)

Here's the error I am getting:

KeyError                                  Traceback (most recent call last)
<ipython-input-13-f63345257370> in <module>()
      1 model = timm.create_model('resnetv2_101x3_bitm', pretrained=True).eval()
----> 2 cam_extractor = CAM(model, fc_layer='fc')
      3 
      4 # Get your input
      5 img = read_image("welsh-corgi-1581119_960_720.jpg")

/usr/local/lib/python3.7/dist-packages/torchcam/cams/cam.py in __init__(self, model, target_layer, fc_layer, input_shape)
     62                 raise ValueError("unable to resolve `fc_layer` automatically, please specify its value.")
     63         # Softmax weight
---> 64         self._fc_weights = self.submodule_dict[fc_layer].weight.data
     65 
     66     def _get_weights(self, class_idx: int, scores: Optional[Tensor] = None) -> Tensor:

KeyError: 'fc'

The main code:

model = timm.create_model('resnetv2_101x3_bitm', pretrained=True).eval()
cam_extractor = CAM(model, fc_layer='fc')

Here's the Colab Notebook to reproduce the issue.

What are the requirements of the model by using these visual code?

Bug description

image

I have got a error, we failed to use these method to obtain a results. I have got 4D matrix, but it needs to be 2D. My model have not a fully connected layer,while consists of many convolution layers. Should I how to deal with this problem? Thank you

Code snippet to reproduce the bug

def _backprop(self, scores: Tensor, class_idx: int) -> None:
    """Backpropagate the loss for a specific output class"""

    # Backpropagate to get the gradients on the hooked layer


    loss = scores[:, class_idx].sum()
    self.model.zero_grad()
    loss.backward(retain_graph=True)

Error traceback

image

Environment

Cuda 11.0
torch-gpu==1.7.0

Upcoming support for new CAM methods

TorchCAM is now mature enough to welcome new CAM methods 👍
This issue is meant to track upcoming additions on the next release!

A few things to consider:

  • TorchCAM is not meant to support all available methods. This should focus on the ones providing SOTA performances (or perf milestones)
  • the rightful contributors have to be credited: if a piece of code is borrowed from someone else's implementation, that should be indicated ("borrowed from", "inspired by", etc.)

Here is the list of envisioned CAM methods:

Suggestions are welcome 😄

Autograd Warning

🐛 Bug

When I am integrating densenet121 with torchcam I am getting following warning, which I am not getting while using the model diectly.

usr/local/lib/python3.7/dist-packages/torch/nn/functional.py:1204: UserWarning: Output 0 of BackwardHookFunctionBackward is a view and is being modified inplace. This view was created inside a custom Function (or because an input was returned as-is) and the autograd logic to handle view+inplace would override the custom backward associated with the custom Function, leading to incorrect gradients. This behavior is deprecated and will be forbidden starting version 1.6. You can remove this warning by cloning the output of the custom Function. (Triggered internally at /pytorch/torch/csrc/autograd/variable.cpp:547.) result = torch.relu_(input)

Here is the code

model = densenet121(pretrained=True).eval()

img = read_image("image.png")
input_tensor = normalize(resize(img, (224, 224)) / 255., [0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
extract = GradCAM(model=model)
out = model(input_tensor.unsqueeze(0))

Environment

  • I am working on Google colab
  • Installed Torchcam using pip
  • Pytorch version: 1.8.1+cu101
  • Torchcam Version: 0.2.0
  • Python version: 3.7.10

3D images not supported?

Tried to use SmoothGradCAMpp, ScoreCAM and SSCAM on pytorch ResNet architecture.

SmoothGradCAMpp complains when taking the sum on the weights:
RuntimeError: The size of tensor a (5) must match the size of tensor b (3) at non-singleton dimension 1

Input: (1, 1, 79, 190, 158)

I printed the input and the received the following:
"Weight.View:" torch.Size([2048, 5, 1, 1]) "Hook Squeese:" torch.Size([2048, 3, 6, 5]) "Weights:" torch.Size([2048, 5]) "Hook:" torch.Size([1, 2048, 3, 6, 5])

Question: Is it reasonable that SSCAM allocates 18gb memory on the GPU?

self.hook_g is None

When I run cam_example.py with grad-cam, i get following issue that self.hook_g is None, please tell me how to fix it?
image

Add support for batch processing

Following up on #79 & #90, the CAM methods should be able to process batches. With the way they are computed, here is the proposal to handle two cases:

  • if the model got an input_tensor with batch size = 1, then the CAM extractor can only be passed either a single integer (class index) or a list of class indices of length 1.
  • if the model gets a tensor with batch_size = N, then:
    • if the CAM extractor receives class_idx: int, it will return a tensor of shape (N, H, W) which is the class activation map for class corresponding to index = class_idx, for each element of the input batch
    • if the CAM extractor receives class_idx: List[int] (of size N), it will return a tensor of shape (N, H, W) where element k, along the batch axis, will be the class activation map for class corresponding to index = class_idx[k] for the k-th element of the input batch.

So far, for more complex behaviours, I cannot foresee a way to do it efficiently (without breaking the backprop).

Video Models

Hi can we use this library to use GRAD-CAM on 3D CNN models?

Problem about 3D image visualization

🚀 Feature

Hi! I'm doing visual display for my program which is a 3D cube. Now I meet a problem.
When I was debugging the program, I found that the values of the activation map were all 'nan'.
My cube size is 32 × 32 × 32 (z, y, x)pixel data and the type of 3D cube is. NPY type. How to change the activation map in line 210 ---'activation_map = cam_extractor(out.squeeze(0).argmax().item(), out)' so that the value is not 'nan'?
I will put the relevant data and weights in the following links-- https://drive.google.com/drive/folders/19xJiUqVDNrqSzcSkNc0wF95WJ58cOsEV?usp=sharing
By the way, In line 214 of the test.py, I want to add 32 × 32 × 32 cubes visualized slice by slice as 32×32. Can you tell me how to operate this step?
Thank you very much and look forward to your reply! Best regards!

Motivation & pitch

I want to use cam for 3D image visualization, and I have ready-made data, but I meet a problem. When I was debugging the program, I found that the values of the activation map were all 'nan'. My cube size is 32 × 32 × 32 (z, y, x)pixel data and the type of 3D cube is. NPY type. How to change the activation map in line 210 ---'activation_map = cam_extractor(out.squeeze(0).argmax().item(), out)' so that the value is not 'nan'?
I will put the relevant data and weights in the following links-- https://drive.google.com/drive/folders/19xJiUqVDNrqSzcSkNc0wF95WJ58cOsEV?usp=sharing
Thanks!

Alternatives

No response

Additional context

No response

ScoreCAM, SSCAM,ISCAM failed when feeding this image

Bug description

When trying the example with torchcam v0.3.2dev0, the command is
python scripts/cam_example.py --arch resnet18 --class-idx 386 --img ./elephant.jpg --method ScoreCAM
The ScoreCAM seems to crash with no outputs.

elephant

By the way, when trying this command, it shows "WARNING:root:no value was provided for 'target_layer', thus set to 'layer4'"

Code snippet to reproduce the bug

python scripts/cam_example.py --arch resnet18 --class-idx 386 --img ./elephant.jpg --method ScoreCAM

Error traceback

2

Environment

torchcam v0.3.2dev0

model file is .h5or.pth

🚀 Feature

My model file is 'XXXX.h5' or 'XXX.pth',can I use your project to visualize the feature map?
thank you very much~

Motivation & pitch

ohh

Alternatives

No response

Additional context

No response

Any interest to suppport LayerCAM

Hello, @frgfm,
Our paper "LayerCAM: Exploring Hierarchical Class Activation Maps for Localization" is accepted by TIP recently, which can visualize the class activation maps from any cnn layer of an off-the-shelf network. Could you add our method to your popular repository for more people to try this method? Our method is a simple modification of Grad-CAM. It should easy to implement. Here is the paper and code. Hope for your reply.

Add a script for performance evaluation

As discussed in #122, CAM methods are usually compared using a few metrics including:

  • Average Drop
  • Increase in Confidence

Those metrics require an image classification dataset, Imagenette could be used for the first version 👌

self._normalize() got NAN...

Bug description

Sir, when I print upsampled_a in upsampled_a = self._normalize(self.hook_a, self.hook_a.ndim - 2)
I got NAN in some value. Is there any bug?

I set model to vgg19 target_layer1='features.35' fc_layer1='classifier.6'

Code snippet to reproduce the bug

nan

Error traceback

nan

Environment

nan

evaluation code

Sir, can you provide the other evaluation code like Average Drop/Incr. in Confidence/Insertion /Deletion ?Thanks a lot!

Problem to get CAM with SqueezeNet

Hi,

I try to get CAM with SqueezeNet. But this model have a classifier composed with a convolution layer followed by a global average pooling one that replace the FC one.

The used code is

net = squeezenet1_1(pretrained=True).eval()

getcam = CAM(net, "features", "classifier.1")
out = net(img.unsqueeze(0).float())
saillancy_map = getcam(class_idx=out.argmax(1).item(), scores=out)
print(saillancy_map.shape)

Now the problem is on the shape of the obtained activation map saillancy_map which is torch.Size([1, 512, 13, 13]).

Need some help to solve this.

ImportError: cannot import name 'ScoreCAM'

Hello,

I am trying to use your implementation of Score CAM.
Before implementing it in my model (pre-trained resnet) I wanted to run the basic example provided in the documentation:

from torchvision.models import resnet18
from torchcam.cams import ScoreCAM

model = resnet18(pretrained=True).eval()
cam = ScoreCAM(model, 'layer4', 'conv1')
with torch.no_grad(): out = model(input_tensor)
cam(class_idx=100)

However I am getting the error mentioned in the title.

Initially I've installed it via pip,
I tried uninstalling it and installing via conda.

However this then "broke" the torchvision package which required re-installing.

gram-cam issue

When I run cam_example.py with grad-cam, i get following issue, please tell me how to fix it?

1

conda install issue

When I install torchcam via conda install -c frgfm torchcam, the verison of pytorch will be downgraded into 1.4 .

My pytorch version is 1.6.

Fix the implementation of ScoreCAM methods

There are a few subtle differences between paper and the implementations in this repo. Some need to be fixed as they do not reflect any voluntary improvement upon the author's original idea:

VGG16 can't assist with plain CAM?

Bug description

hi~
I followed your Quick Tour, and I chose the plain CAM and VGG16, but an error occured

Only the line 6 and lin 7 are different from you Quick Tour

But When I chose plain CAM with Resnet18, it went well

Code snippet to reproduce the bug

from torchvision.io.image import read_image
from torchvision.transforms.functional import normalize, resize, to_pil_image
from torchvision.models import resnet18,vgg16
from torchcam.methods import SmoothGradCAMpp, CAM

model = vgg16(pretrained=True).eval()   #   The first place differs to Quick Tour    just resnet => vgg
cam_extractor = CAM(model)  #    The second place differs to Quick Tour    just SmoothGradCAMpp => CAM

img = read_image("./datasets/barracouta.JPEG")

input_tensor = normalize(resize(img, (224, 224)) / 255., [0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
out = model(input_tensor.unsqueeze(0))


activation_map = cam_extractor(out.squeeze(0).argmax().item(), out)

Error traceback

The size of tensor a (25088) must match the size of tensor b (512) at non-singleton dimension 0

in <module>
    activation_map = cam_extractor(out.squeeze(0).argmax().item(), out)

Environment

I run it in jupyter as the same as you Quick Tour

didn't find remove_hooks() in cam_extractor

Bug description

I downloaded the cam_example and ran it. It stopped at remove_hooks().
I checked previous issues, only to find the change of name.
I ran a jupyter demo. It worked fine with cam, but it didn't have a remove_hooks() method as well.
QQ截图20221109144911

Was the method dropped already?

Code snippet to reproduce the bug

cam_extractor.remove_hooks()

Error traceback

Traceback (most recent call last):
  File "cam_exp.py", line 135, in <module>
    main(args)
  File "cam_exp.py", line 84, in main
    extractor.remove_hooks()
AttributeError: 'CAM' object has no attribute 'remove_hooks'

Environment

torchcam 0.3.1 0 frgfm

Error when clearing hooks

Bug description

Dear fellow,
When I execute the following line :
`# Once you're finished, clear the hooks on your model

cam_extractor.clear_hooks()
I'm getting this error : ---------------------------------------------------------------------------

AttributeError Traceback (most recent call last)

in ()
1 # Once you're finished, clear the hooks on your model
2
----> 3 cam_extractor.clear_hooks()
4

AttributeError: 'SmoothGradCAMpp' object has no attribute 'clear_hooks'`

Do you have any idea to correct this ?
Thanks in advance

Code snippet to reproduce the bug

'''
`# Once you're finished, clear the hooks on your model

cam_extractor.clear_hooks()
'''

Error traceback

'''
`# Once you're finished, clear the hooks on your model

cam_extractor.clear_hooks()
'''

Environment

Collecting environment information...
TorchCAM version: 0.3.2.dev0+5c83d3a
PyTorch version: 1.10.0+cu111

OS: Ubuntu 18.04.5 LTS

Python version: 3.7.13
Is CUDA available: No
CUDA runtime version: 11.1.105
GPU models and configuration: Could not collect
Nvidia driver version: Could not collect
cuDNN version: Probably one of the following:
/usr/lib/x86_64-linux-gnu/libcudnn.so.7.6.5
/usr/lib/x86_64-linux-gnu/libcudnn.so.8.0.5
/usr/lib/x86_64-linux-gnu/libcudnn_adv_infer.so.8.0.5
/usr/lib/x86_64-linux-gnu/libcudnn_adv_train.so.8.0.5
/usr/lib/x86_64-linux-gnu/libcudnn_cnn_infer.so.8.0.5
/usr/lib/x86_64-linux-gnu/libcudnn_cnn_train.so.8.0.5
/usr/lib/x86_64-linux-gnu/libcudnn_ops_infer.so.8.0.5
/usr/lib/x86_64-linux-gnu/libcudnn_ops_train.so.8.0.5

More NaNs

Bug description

Thank you for fixing the previous NaN bug. This solves most issues. However, sometimes these NaNs still occur. With the newest commit, the tensors are zero.

I would suggest adding to torch.nansum a warning message that informs the user that NaN was found. Otherwise, the activation map is just zero and the user is not aware that a problem occurred. I am referring to line

cam = torch.nansum(weight * activation, dim=1)

Here an example from ImageNet that produces NaN: ILSVRC2012_val_00033712.JPEG

ILSVRC2012_val_00033712

Code snippet to reproduce the bug

from torchvision.io.image import read_image
from torchvision.transforms.functional import normalize, resize, to_pil_image
import torch
import timm
from torchvision.models import resnet50
from torchcam.methods import *

model = timm.create_model("efficientnet_b0", pretrained=True).eval()
cam_extractor = ScoreCAM(model, target_layer="blocks.6")
# Get your input
img = read_image("ILSVRC2012_val_00033712.JPEG")
# Preprocess it for your chosen model
input_tensor = normalize(resize(img, (224, 224)) / 255., [0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

# Preprocess your data and feed it to the model
out = model(input_tensor.unsqueeze(0))
# Retrieve the CAM by passing the class index and the model output
activation_map = cam_extractor(out.squeeze(0).argmax().item(), out)

print(activation_map)

Error traceback

[tensor([[[0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0.],
         [0., 0., 0., 0., 0., 0., 0.]]])]

Environment

not relevant

Multi-Inputs CAM support

🚀 Feature

Hi, thanks for this great toolbox.

I am wondering how to get CAM for multiple input cases. Currently, I found that the CAM I am getting is from the last input.

The model which I want to check takes 3 images as a single input and then concatenates or stack the feature maps for the final FC layer to make a multi-label classification.

Would it be possible to generate 3 CAMs for each image?

Thanks in advance

Motivation & pitch

  • Multi-view model or multi-input model take a list of items as a single input
  • Current CAM code will only generate a class activation map based on the last item in the list (depending on how items are passed to the forward function tho).

Alternatives

No response

Additional context

No response

Add support of Vision Transformer

🚀 Feature

I am appreciated for your great job! However, I have a question. Can Layer-CAM be used with Vision Transformer Network? If it does work, what aspects should I change?

Motivation & pitch

I'm working on the job related to CAM.

Alternatives

No response

Additional context

No response

Model evaluation

Hi,

I have a question about cam_example.py. Shouldn't the model be in eval() mode? I noticed without setting the model.eval() the prediction labels are wrong while after setting to eval mode the ScoreCam and SSCAM heatmaps are zero. Could you please check this?

element 0 of tensors does not require grad and does not have a grad_fn

I get this error when I use the API.

`model = models.resnet34(pretrained=True).eval()
cam = GradCAMpp(model,'layer4')
import numpy as np
from PIL import Image
from torch.autograd import Variable

from torchvision.transforms.functional import normalize,resize,to_tensor
img_path = ''
pil_img = Image.open(img_path)
#pil_img = np.expand_dims(img_tensor,axis=0)

img_tensor = normalize(to_tensor(resize(pil_img,(224,224))),[0.485,0.456,0.406],[0.229,0.224,0.225])
_ = _forward(model,torch.stack((img_tensor,img_tensor)))
scores = _forward(model, img_tensor.unsqueeze(0))
#img_variable = Variable(img_tensor.unsqueeze(0),requires_grad=True)
cam(class_idx=1,scores=scores)
`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.