v0.3.2: Some CAM fixes and support of batch processing
This patch release fixes the Score-CAM methods and improves the base API for CAM computation.
Note: TorchCAM 0.3.2 requires PyTorch 1.7.0 or higher.
Highlights
😯 Batch processing
CAM computation now supports batch sizes larger than 1 (#143) ! Practically, this means that you can compute CAMs for multiple samples at the same time, which will let you make the most of your GPU as well ⚡
The following snippet:
import torch
from torchcam.methods import LayerCAM
from torchvision.models import resnet18
# A preprocessed (resized & normalized) tensor
img_tensor = torch.rand((2, 3, 224, 224))
model = resnet18(pretrained=True).eval()
# Hook your model before inference
cam_extractor = LayerCAM(model)
out = model(img_tensor)
# Compute the CAM
activation_map = cam_extractor(out[0].argmax().item(), out)
print(activation_map[0].ndim)
will yield 3
as the batch dimension is now also used.
🖌️ Documentation theme
New year, new documentation theme!
For clarity and improved interface, the documentation theme was changed from Read the Docs to Furo (#162)
This comes with nice features like dark mode and edit button!
🖱️ Contribution process
Contributions are important to OSS projects, and for this reason, a few improvements were made to the contribution process:
- added a Makefile for easier development (#109)
- added a dedicated README for the documentation (#109)
- updated CONTRIBUTING (#109, #166)
Breaking changes
CAM signature
CAM extractors now outputs a list of tensors. The size of the list is equal to the number of target layers and ordered the same way.
Each of these elements used to be a 2D spatial tensor, and is now a 3D tensor to include the batch dimension:
# Model was hooked and a tensor of shape (2, 3, 224, 224) was forwarded to it
amaps = cam_extractor(0, out)
for elt in amaps: print(elt.shape)
will, from now on, yield
torch.Size([2, 7, 7])
What's Changed
Breaking Changes 🛠
New Features 🚀
- ci: Added release note template and a job to check PR labels by @frgfm in #138
- docs: Added CITATION file by @frgfm in #144
Bug Fixes 🐛
- fix: Updated headers and added pydocstyle by @frgfm in #137
- chore: Updated PyTorch version specifier by @frgfm in #149
- docs: Fixed deprecated method call by @frgfm in #158
- chore: Fixed jinja2 deps (subdep of sphinx) by @frgfm in #159
- docs: Fixed docstring of ISCAM by @frgfm in #160
- docs: Fixed multi-version build by @frgfm in #163
- docs: Fixed codacy badge by @frgfm in #164
- docs: Fixed typo in CONTRIBUTING by @frgfm in #166
- docs: Fixed author entry in pyproject by @frgfm in #168
- style: Fixed import order by @frgfm in #175
Improvements
- docs: Added PR template and tools for contributing by @frgfm in #109
- refactor: Removed unused import by @frgfm in #110
- feat: Added text strip for multiple target selection in demo by @frgfm in #111
- refactor: Updated environment collection script by @frgfm in #112
- style: Updated flake8 config by @frgfm in #115
- ci: Updated isort config and related CI job by @frgfm in #118
- ci: Speeded up the example script CI check by @frgfm in #130
- refactor: Updated the timing function for latency eval by @frgfm in #129
- docs: Updated TOC of documentation by @frgfm in #161
- refactor: Updated build config and documentation theme by @frgfm in #162
- style: Updated mypy and isort configs by @frgfm in #167
- chore: Improved version specifiers and fixed conda recipe by @frgfm in #169
- docs: Fixed README badge and updated documentation by @frgfm in #170
- ci: Updated release job by @frgfm in #173
- refactor: Improved target resolution by @frgfm in #174
- ci: Updated the trigger for the release job by @frgfm in #176
- docs: Updated landing page screenshot by @frgfm in #179
Full Changelog: v0.3.1...v0.3.2