Execute vote ensemble on the input data. The input data can be a list or tuple of PyTorch Tensor with shape: [C[, H, W, D]], Or a single PyTorch Tensor with shape: [E[, C, H, W, D]], the `E` dimension represents the output data from different models. Typically, the input data is
| 702 | |
| 703 | |
| 704 | class VoteEnsemble(Ensemble, Transform): |
| 705 | """ |
| 706 | Execute vote ensemble on the input data. |
| 707 | The input data can be a list or tuple of PyTorch Tensor with shape: [C[, H, W, D]], |
| 708 | Or a single PyTorch Tensor with shape: [E[, C, H, W, D]], the `E` dimension represents |
| 709 | the output data from different models. |
| 710 | Typically, the input data is model output of segmentation task or classification task. |
| 711 | |
| 712 | Note: |
| 713 | This vote transform expects the input data is discrete values. It can be multiple channels |
| 714 | data in One-Hot format or single channel data. It will vote to select the most common data |
| 715 | between items. |
| 716 | The output data has the same shape as every item of the input data. |
| 717 | |
| 718 | Args: |
| 719 | num_classes: if the input is single channel data instead of One-Hot, we can't get class number |
| 720 | from channel, need to explicitly specify the number of classes to vote. |
| 721 | |
| 722 | """ |
| 723 | |
| 724 | backend = [TransformBackends.TORCH] |
| 725 | |
| 726 | def __init__(self, num_classes: int | None = None) -> None: |
| 727 | self.num_classes = num_classes |
| 728 | |
| 729 | def __call__(self, img: Sequence[NdarrayOrTensor] | NdarrayOrTensor) -> NdarrayOrTensor: |
| 730 | img_ = self.get_stacked_torch(img) |
| 731 | |
| 732 | if self.num_classes is not None: |
| 733 | has_ch_dim = True |
| 734 | if img_.ndimension() > 1 and img_.shape[1] > 1: |
| 735 | warnings.warn("no need to specify num_classes for One-Hot format data.") |
| 736 | else: |
| 737 | if img_.ndimension() == 1: |
| 738 | # if no channel dim, need to remove channel dim after voting |
| 739 | has_ch_dim = False |
| 740 | img_ = one_hot(img_, self.num_classes, dim=1) |
| 741 | |
| 742 | img_ = torch.mean(img_.float(), dim=0) |
| 743 | |
| 744 | if self.num_classes is not None: |
| 745 | # if not One-Hot, use "argmax" to vote the most common class |
| 746 | out_pt = torch.argmax(img_, dim=0, keepdim=has_ch_dim) |
| 747 | else: |
| 748 | # for One-Hot data, round the float number to 0 or 1 |
| 749 | out_pt = torch.round(img_) |
| 750 | return self.post_convert(out_pt, img) |
| 751 | |
| 752 | |
| 753 | class GenerateHeatmap(Transform): |
no outgoing calls
searching dependent graphs…