Conversation
…PCam support - Added `preprocess_fn` parameter to `CIAOExplainer` for custom image preprocessing. - Introduced `get_pcam_classes` function to retrieve class names for PatchCamelyon dataset. - Implemented `load_pcam_model` function to load a pretrained ResNet50 model for PCam. - Updated base configuration to include preprocessing settings for ImageNet. - Created new configuration files for PCam classes and model. - Added preprocessing configurations for PCam dataset. - Refactored mean color replacement configuration to include mean and std parameters. - Updated dependencies in `pyproject.toml` to include `timm` for model loading. - Added new packages and their versions in `uv.lock` for dependency management.
📝 WalkthroughWalkthroughAdds an optional ChangesPCam Support and Configurable Preprocessing
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces support for the PatchCamelyon (PCam) dataset and model, including custom preprocessing, constants, model loading via timm, and configurations. It also refactors the image replacement strategies to accept parameterized normalization constants (mean and std). The review feedback suggests optimizing make_mean_color_replacement and make_solid_color_replacement by pre-computing and pre-creating the normalization and color tensors on the CPU once, rather than recreating them inside the inner replacement function on every call, to reduce runtime overhead.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…move unused PCam constants Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds PatchCamelyon (PCam) support to CIAO by introducing a PCam-compatible model/config set and threading a configurable preprocessing callable through the CLI → pipeline → explainer path, while also making replacement strategies configurable with dataset-specific normalization parameters.
Changes:
- Added PCam model/class/config entries (timm/HuggingFace-backed ResNet50 + binary class labels).
- Introduced configurable preprocessing selection via Hydra configs and plumbed a
preprocess_fnthrough the explainer pipeline. - Refactored mean-color and solid-color replacement logic to accept configurable normalization (
mean/std) rather than hardcoding ImageNet.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Locks new dependency set (notably timm and its transitive deps). |
| pyproject.toml | Adds timm>=1.0.0 runtime dependency. |
| configs/replacement/mean_color.yaml | Switches replacement config to make_mean_color_replacement with explicit ImageNet mean/std. |
| configs/replacement/mean_color_pcam.yaml | Adds PCam-oriented mean/std config (identity normalization). |
| configs/preprocessing/pcam.yaml | Adds Hydra preprocessing target for PCam image loading/preprocessing. |
| configs/preprocessing/imagenet.yaml | Adds Hydra preprocessing target for ImageNet preprocessing. |
| configs/model/pcam_resnet50.yaml | Adds Hydra model target for PCam ResNet50 wrapper. |
| configs/classes/pcam.yaml | Adds Hydra classes target for PCam label set. |
| configs/base.yaml | Adds preprocessing config entry to defaults. |
| ciao/model/pcam.py | Implements PCam model loader via timm.create_model(...) from HuggingFace hub. |
| ciao/model/classes.py | Adds PCam binary class names. |
| ciao/explainer/ciao_explainer.py | Adds optional preprocess_fn parameter and uses it to create the input tensor. |
| ciao/data/replacement.py | Refactors mean/solid-color replacements to be normalization-configurable; adds ImageNet-mean replacement. |
| ciao/data/preprocessing.py | Adds PCam preprocessing transform and shared loader helper. |
| ciao/data/init.py | Updates exports for new preprocessing/replacement APIs. |
| ciao/main.py | Instantiates preprocessing from Hydra config and passes it through to the explainer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…solid_color_replacement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
ciao/data/replacement.py (1)
26-36: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winSimplify the mean color computation.
Because normalization is a linear transformation (a scalar multiply and add per channel), calculating the spatial mean of the normalized image yields the exact same result mathematically as unnormalizing it, calculating the mean, and then re-normalizing it.
You can remove the redundant math, tensor instantiations, and device transfers by simply calculating the mean of the input image. The
meanandstdarguments can be left in the function signature if needed to fulfill the Hydra configuration contract.♻️ Proposed refactor
- t_mean_cpu = torch.tensor(mean, dtype=torch.float32).view(3, 1, 1) - t_std_cpu = torch.tensor(std, dtype=torch.float32).view(3, 1, 1) - def replacement(image: torch.Tensor) -> torch.Tensor: - t_mean = t_mean_cpu.to(device=image.device, dtype=image.dtype) - t_std = t_std_cpu.to(device=image.device, dtype=image.dtype) - unnormalized = (image * t_std) + t_mean - mean_color = unnormalized.mean(dim=(1, 2), keepdim=True) - normalized_mean = (mean_color - t_mean) / t_std + normalized_mean = image.mean(dim=(1, 2), keepdim=True) _, height, width = image.shape return normalized_mean.expand(-1, height, width)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ciao/data/replacement.py` around lines 26 - 36, Simplify replacement by computing the spatial mean directly from image in replacement, then expanding it to height and width. Remove the t_mean_cpu/t_std_cpu tensors, device transfers, and unnormalize/renormalize calculations; retain mean and std parameters in the surrounding configuration interface if required by Hydra.ciao/model/pcam.py (1)
7-9: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winPin the Hugging Face checkpoint revision.
The model is fetched from the Hub at runtime using a mutable repository reference, so later changes to its configuration or weights could silently change prediction and explanation results. Pin a commit revision or vendor a checksum-verified artifact; confirm the supported
timm/Hub revision mechanism before implementing it. (huggingface.co)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ciao/model/pcam.py` around lines 7 - 9, Update the timm.create_model call for the Hugging Face PCAM checkpoint to use a supported immutable Hub commit revision or checksum-verified vendored artifact instead of the mutable repository reference. Preserve pretrained loading while ensuring future configuration and weight changes cannot alter the model.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ciao/model/pcam.py`:
- Around line 5-10: Update load_pcam_model to pin the Hugging Face checkpoint by
appending @<revision> to the model_name passed to timm.create_model. Use the
intended immutable commit or tag revision while preserving pretrained=True and
the existing model-loading behavior.
---
Nitpick comments:
In `@ciao/data/replacement.py`:
- Around line 26-36: Simplify replacement by computing the spatial mean directly
from image in replacement, then expanding it to height and width. Remove the
t_mean_cpu/t_std_cpu tensors, device transfers, and unnormalize/renormalize
calculations; retain mean and std parameters in the surrounding configuration
interface if required by Hydra.
In `@ciao/model/pcam.py`:
- Around line 7-9: Update the timm.create_model call for the Hugging Face PCAM
checkpoint to use a supported immutable Hub commit revision or checksum-verified
vendored artifact instead of the mutable repository reference. Preserve
pretrained loading while ensuring future configuration and weight changes cannot
alter the model.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f6b5328b-a4e8-4804-b6b1-fee8310dc272
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
ciao/__main__.pyciao/data/__init__.pyciao/data/preprocessing.pyciao/data/replacement.pyciao/explainer/ciao_explainer.pyciao/model/classes.pyciao/model/pcam.pyconfigs/base.yamlconfigs/classes/pcam.yamlconfigs/model/pcam_resnet50.yamlconfigs/preprocessing/imagenet.yamlconfigs/preprocessing/pcam.yamlconfigs/replacement/mean_color.yamlconfigs/replacement/mean_color_pcam.yamlpyproject.toml
Context:
Extends CIAO to support the PCam (PatchCamelyon) dataset alongside ImageNet models. Adds configurable preprocessing functions so different datasets can define their own normalization constants.
What's Changed / Added:
ciao/data/preprocessing.py: Addedmake_preprocessingfactory function andPreprocessingnamed tuple; ImageNet and PCam preprocessing configs provided as module-level constants.ciao/data/constants.py: Removed unusedPCAM_MEAN/PCAM_STDconstants (PCam normalization is now inlined inpreprocessing.py).ciao/data/replacement.py: Addedmake_mean_color_replacementandmake_solid_color_replacementfactory functions that accept configurablemean/std; both validate inputs at construction time.ciao/model/pcam.py: Added PCam-compatible ResNet50 model wrapper.ciao/model/classes.py: Added PCam class names.ciao/explainer/ciao_explainer.py: No changes required (replacement functions are injected externally).configs/: Addedpreprocessing/imagenet.yaml,preprocessing/pcam.yaml,model/pcam_resnet50.yaml,classes/pcam.yaml,replacement/mean_color_pcam.yaml.Related Task:
XAI-29
Summary by CodeRabbit