Feature/classic mil - #34
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughThe change introduces slide-label-only bag datasets and datamodules, extracts shared MIL behavior into ChangesClassic MIL workflows
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Dataset as SLLabeledBagOfEmbeddingsDataset
participant DataModule as ClassicBagOfTilesDataModule
participant Model as ProstateCancerClassicMIL
participant Base as ProstateCancerMILBase
Dataset->>DataModule: provide slide-labeled bags
DataModule->>Model: collate slide labels and embeddings
Model->>Base: compute attention and slide prediction
Base-->>Model: return slide logits
Model-->>DataModule: log slide loss and metrics
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.
Actionable comments posted: 2
🧹 Nitpick comments (2)
prostate_cancer/datamodule/datasets/bag_of_embeddings_dataset.py (1)
32-32: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePlace
Generic[T]as the last base class.Ruff reports
PYI059becauseGeneric[T]is not last. Reorder fromclass BagOfEmbeddingsDataset(Dataset[T], Generic[T], ABC):toclass BagOfEmbeddingsDataset(Dataset[T], ABC, Generic[T]):.🤖 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 `@prostate_cancer/datamodule/datasets/bag_of_embeddings_dataset.py` at line 32, Update the base-class order in BagOfEmbeddingsDataset so Generic[T] is the last base class, preserving Dataset[T] and ABC before it.Source: Linters/SAST tools
prostate_cancer/mil_model_base.py (1)
97-133: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueGuard against NaN when a bag has zero valid tiles.
maskat Line 104 can be all-zero if every tile in a bag is treated as padding. In that case,raw_attn.masked_fill(~mask.bool(), float("-inf"))at Line 110 sets every attention logit to-inf, andtorch.softmaxover an all--infrow producesNaN(0/0). ThatNaNthen propagates intosl_pred_rawand the downstream loss/metrics for the whole batch.The class docstring states a bag is "all embeddings from a single slide," so this is unlikely in practice today, but there is no explicit safeguard if an upstream data issue ever produces an empty bag. Consider asserting
mask.sum(dim=1) > 0per bag, or clamping the softmax denominator.🤖 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 `@prostate_cancer/mil_model_base.py` around lines 97 - 133, Update forward to explicitly handle bags with zero valid tiles before softmax, using a per-bag validity check such as mask.sum(dim=1) > 0 and the project’s established failure-handling convention. Ensure attention_weights never comes from an all--inf row, preventing NaN propagation into sl_pred_raw and downstream outputs.
🤖 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 `@prostate_cancer/mil_model_base.py`:
- Around line 135-149: Apply sigmoid once to the slide-level and tile-level
outputs before passing them to binary metric update calls, and reuse those
probabilities for the returned values where applicable. Update test_step in
prostate_cancer/mil_model_base.py#L135-L149, both affected metric-update sites
in prostate_cancer/attention_mil_model.py#L59-L60 and `#L99-L100`, and both sites
in prostate_cancer/classic_mil_model.py#L25 and `#L40`; preserve masking and
existing metric/logging behavior.
In `@prostate_cancer/typing.py`:
- Line 46: Update the comment describing the UnlabeledTileSampleBatch alias to
state “Images | Metadata” instead of “Images | labels | Metadata,” matching its
Tensor and TileMetadataBatch contents.
---
Nitpick comments:
In `@prostate_cancer/datamodule/datasets/bag_of_embeddings_dataset.py`:
- Line 32: Update the base-class order in BagOfEmbeddingsDataset so Generic[T]
is the last base class, preserving Dataset[T] and ABC before it.
In `@prostate_cancer/mil_model_base.py`:
- Around line 97-133: Update forward to explicitly handle bags with zero valid
tiles before softmax, using a per-bag validity check such as mask.sum(dim=1) > 0
and the project’s established failure-handling convention. Ensure
attention_weights never comes from an all--inf row, preventing NaN propagation
into sl_pred_raw and downstream outputs.
🪄 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 Plus
Run ID: 2ed322df-24aa-4869-8280-3d5402420d27
📒 Files selected for processing (64)
configs/datamodule/classic_bag_of_embeddings_datamodule.yamlconfigs/datamodule/datasets/embeddings/bag_of_embeddings_sl_labeled.yamlconfigs/experiment/predict/bag_of_embeddings/base.yamlconfigs/experiment/predict/bag_of_embeddings/classic_base.yamlconfigs/experiment/predict/bag_of_embeddings/hybrid_base.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/classic_base.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/classic_slide_threshold.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/hybrid_base.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/hybrid_slide_threshold.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/mil_predictions/classic_base.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/mil_predictions/classic_mmci_sl_group_1.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/mil_predictions/classic_mmci_tl_val.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/mil_predictions/hybrid_base.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/mil_predictions/hybrid_mmci_sl_group_1.yamlconfigs/experiment/predict/bag_of_embeddings/pgp/mil_predictions/hybrid_mmci_tl_val.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/classic_base.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/classic_slide_threshold.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/hybrid_base.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/hybrid_slide_threshold.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/mil_predictions/classic_base.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/mil_predictions/classic_mmci_sl_group_1.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/mil_predictions/classic_mmci_tl_val.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/mil_predictions/hybrid_base.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/mil_predictions/hybrid_mmci_sl_group_1.yamlconfigs/experiment/predict/bag_of_embeddings/virchow2/mil_predictions/hybrid_mmci_tl_val.yamlconfigs/experiment/test/bag_of_embeddings/base.yamlconfigs/experiment/test/bag_of_embeddings/classic_base.yamlconfigs/experiment/test/bag_of_embeddings/hybrid_base.yamlconfigs/experiment/test/bag_of_embeddings/pgp/classic_base.yamlconfigs/experiment/test/bag_of_embeddings/pgp/classic_tile_threshold.yamlconfigs/experiment/test/bag_of_embeddings/pgp/hybrid_base.yamlconfigs/experiment/test/bag_of_embeddings/pgp/hybrid_tile_threshold.yamlconfigs/experiment/test/bag_of_embeddings/pgp/test_suite/classic_base.yamlconfigs/experiment/test/bag_of_embeddings/pgp/test_suite/classic_mmci_tl_test.yamlconfigs/experiment/test/bag_of_embeddings/pgp/test_suite/hybrid_base.yamlconfigs/experiment/test/bag_of_embeddings/pgp/test_suite/hybrid_mmci_tl_test.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/classic_base.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/classic_tile_threshold.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/hybrid_base.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/hybrid_tile_threshold.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/test_suite/classic_base.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/test_suite/classic_mmci_tl_test.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/test_suite/hybrid_base.yamlconfigs/experiment/test/bag_of_embeddings/virchow2/test_suite/hybrid_mmci_tl_test.yamlconfigs/experiment/train/bag_of_embeddings/base.yamlconfigs/experiment/train/bag_of_embeddings/classic_base.yamlconfigs/experiment/train/bag_of_embeddings/classic_pgp.yamlconfigs/experiment/train/bag_of_embeddings/classic_virchow2.yamlconfigs/experiment/train/bag_of_embeddings/hybrid_base.yamlconfigs/experiment/train/bag_of_embeddings/hybrid_pgp.yamlconfigs/experiment/train/bag_of_embeddings/hybrid_virchow2.yamlconfigs/model/checkpoints/mmci_tl/pgp_classic_mil.yamlconfigs/model/checkpoints/mmci_tl/virchow2_classic_mil.yamlconfigs/model/pgp_classic_mil_model.yamlconfigs/model/virchow2_classic_mil_model.yamlprostate_cancer/attention_mil_model.pyprostate_cancer/classic_mil_model.pyprostate_cancer/datamodule/__init__.pyprostate_cancer/datamodule/bag_of_tiles_data_module.pyprostate_cancer/datamodule/datasets/__init__.pyprostate_cancer/datamodule/datasets/bag_of_embeddings_dataset.pyprostate_cancer/datamodule/samplers/bag_of_tiles_stratified_weighted_random_sampler.pyprostate_cancer/mil_model_base.pyprostate_cancer/typing.py
💤 Files with no reviewable changes (2)
- configs/experiment/test/bag_of_embeddings/base.yaml
- configs/experiment/train/bag_of_embeddings/base.yaml
This PR adds MIL with SL supervision
Summary by CodeRabbit
New Features
Improvements