|
24 | 24 | "[](https://colab.research.google.com/github/Project-MONAI/tutorials/blob/main/modules/rankseg_integration.ipynb)" |
25 | 25 | ] |
26 | 26 | }, |
| 27 | + { |
| 28 | + "cell_type": "markdown", |
| 29 | + "metadata": {}, |
| 30 | + "source": [ |
| 31 | + "## What is RankSEG?\n", |
| 32 | + "\n", |
| 33 | + "A segmentation network usually produces a score or probability for every class at every voxel. A conventional multiclass pipeline converts these values to a mask with `argmax`, independently assigning each voxel to the class with the largest score. This is a natural rule for voxel-wise classification, but it does not directly target region-level metrics such as Dice or IoU, whose values depend on the predicted region as a whole.\n", |
| 34 | + "\n", |
| 35 | + "RankSEG is an inference-time, metric-aware alternative to argmax or fixed thresholding. It leaves the trained model and its probability maps unchanged, and only replaces the final probability-to-mask decision. Unlike connected-component filtering or morphological post-processing, RankSEG does not impose connectivity, shape, or anatomical constraints.\n", |
| 36 | + "\n", |
| 37 | + "| Property | Argmax / fixed threshold | RankSEG |\n", |
| 38 | + "| --- | --- | --- |\n", |
| 39 | + "| Decision | Independent at each voxel | Based on each class probability map as a whole |\n", |
| 40 | + "| Target | Voxel-wise class decision | A selected region metric, such as Dice or IoU |\n", |
| 41 | + "| Region size | Implicit or controlled by a fixed threshold | Adaptively selected for each image and class |\n", |
| 42 | + "| Model training | Unchanged | Unchanged |\n", |
| 43 | + "| Additional inference cost | Minimal | Probability ranking and metric-aware optimization |\n", |
| 44 | + "\n", |
| 45 | + "### How the algorithm works\n", |
| 46 | + "\n", |
| 47 | + "For each class, RankSEG ranks voxels from highest to lowest predicted probability. The `RMA` solver used in this tutorial then estimates how many of the highest-ranked voxels should be included to target the selected metric. In multiclass mode, the class masks are finally combined into one non-overlapping label map. No model retraining or threshold tuning is required.\n", |
| 48 | + "\n", |
| 49 | + "### When should RankSEG be considered?\n", |
| 50 | + "\n", |
| 51 | + "RankSEG can be useful when Dice or IoU is the evaluation target and the model produces meaningful probability maps, particularly for uncertain predictions or small-to-medium foreground regions. When predictions are already confident, RankSEG and argmax may produce nearly identical masks.\n", |
| 52 | + "\n", |
| 53 | + "RankSEG does not correct errors in the underlying probability maps, and its output depends on their quality and calibration. It also adds computation and memory use during inference because the probabilities must be ranked. Improvement is not guaranteed for every case or deployment distribution, so the metric, output mode, and solver should be selected deliberately and validated on representative data. The case below illustrates the integration rather than serving as a standalone performance benchmark." |
| 54 | + ] |
| 55 | + }, |
27 | 56 | { |
28 | 57 | "cell_type": "markdown", |
29 | 58 | "metadata": {}, |
|
44 | 73 | }, |
45 | 74 | "outputs": [], |
46 | 75 | "source": [ |
47 | | - "!python -c \"import monai\" || pip install -q \"monai-weekly[nibabel, tqdm]\"\n", |
48 | | - "!python -c \"import rankseg\" || pip install -q \"rankseg\"\n", |
49 | | - "!python -c \"import huggingface_hub\" || pip install -q huggingface_hub\n", |
50 | | - "!python -c \"import matplotlib\" || pip install -q matplotlib\n", |
| 76 | + "%pip install -q --upgrade-strategy only-if-needed \"monai-weekly[nibabel, tqdm,matplotlib,huggingface_hub]\" rankseg\n", |
51 | 77 | "%matplotlib inline" |
52 | 78 | ] |
53 | 79 | }, |
|
260 | 286 | "import matplotlib.pyplot as plt\n", |
261 | 287 | "import torch\n", |
262 | 288 | "from huggingface_hub import hf_hub_download\n", |
263 | | - "from monai.bundle import download\n", |
| 289 | + "from monai.bundle import ConfigParser, download\n", |
264 | 290 | "from monai.config import print_config\n", |
265 | 291 | "from monai.data import decollate_batch\n", |
266 | 292 | "from monai.inferers import SlidingWindowInferer\n", |
267 | 293 | "from monai.metrics import DiceMetric\n", |
268 | | - "from monai.networks.nets import DiNTS, TopologyInstance\n", |
269 | 294 | "from monai.transforms import (\n", |
270 | 295 | " Activations,\n", |
271 | 296 | " Activationsd,\n", |
|
632 | 657 | " map_location=device,\n", |
633 | 658 | " weights_only=False,\n", |
634 | 659 | ")\n", |
635 | | - "topology = TopologyInstance(\n", |
636 | | - " channel_mul=1,\n", |
637 | | - " num_blocks=12,\n", |
638 | | - " num_depths=4,\n", |
639 | | - " use_downsample=True,\n", |
640 | | - " arch_code=[architecture[\"arch_code_a\"], architecture[\"arch_code_c\"]],\n", |
641 | | - " device=str(device),\n", |
642 | | - ")\n", |
643 | | - "model = DiNTS(\n", |
644 | | - " dints_space=topology,\n", |
645 | | - " in_channels=1,\n", |
646 | | - " num_classes=3,\n", |
647 | | - " use_downsample=True,\n", |
648 | | - " node_a=torch.as_tensor(architecture[\"node_a\"], device=device),\n", |
649 | | - ").to(device)\n", |
| 660 | + "parser = ConfigParser()\n", |
| 661 | + "parser.read_config(os.path.join(bundle_dir, \"configs\", \"inference.yaml\"))\n", |
| 662 | + "parser[\"arch_ckpt\"] = architecture\n", |
| 663 | + "parser[\"dints_space#device\"] = str(device)\n", |
| 664 | + "model = parser.get_parsed_content(\"network_def\").to(device)\n", |
650 | 665 | "checkpoint = torch.load(\n", |
651 | 666 | " os.path.join(bundle_dir, \"models\", \"model.pt\"),\n", |
652 | 667 | " map_location=device,\n", |
|
960 | 975 | "Further reading:\n", |
961 | 976 | "\n", |
962 | 977 | "- [RankSEG repository and documentation](https://github.com/rankseg/rankseg)\n", |
| 978 | + "- [RankSEG: A Consistent Ranking-based Framework for Segmentation](https://www.jmlr.org/papers/v24/22-0712.html)\n", |
| 979 | + "- [RankSEG-RMA: An Efficient Segmentation Algorithm via Reciprocal Moment Approximation](https://openreview.net/forum?id=4tRMm1JJhw)\n", |
963 | 980 | "- [Reproducible MONAI Pancreas comparison](https://github.com/rankseg/rankseg/tree/main/experiments/monai-pr-8908-reproducibility)\n", |
964 | 981 | "- [MONAI Pancreas CT DiNTS Segmentation Bundle](https://github.com/Project-MONAI/model-zoo/tree/dev/models/pancreas_ct_dints_segmentation)\n", |
965 | 982 | "- [Discussion of Option B in MONAI PR #8908](https://github.com/Project-MONAI/MONAI/pull/8908#issuecomment-5077397523)" |
|
0 commit comments