Wrapper to replace the last layer of model by convolutional layer or FC layer. See also: :py:class:`monai.networks.nets.TorchVisionFCModel` Args: model: a PyTorch model, which can be both 2D and 3D models. typically, it can be a pretrained model in Torchvision, lik
| 24 | |
| 25 | |
| 26 | class NetAdapter(torch.nn.Module): |
| 27 | """ |
| 28 | Wrapper to replace the last layer of model by convolutional layer or FC layer. |
| 29 | |
| 30 | See also: :py:class:`monai.networks.nets.TorchVisionFCModel` |
| 31 | |
| 32 | Args: |
| 33 | model: a PyTorch model, which can be both 2D and 3D models. typically, it can be a pretrained model |
| 34 | in Torchvision, like: ``resnet18``, ``resnet34``, ``resnet50``, ``resnet101``, ``resnet152``, etc. |
| 35 | more details: https://pytorch.org/vision/stable/models.html. |
| 36 | num_classes: number of classes for the last classification layer. Default to 1. |
| 37 | dim: number of supported spatial dimensions in the specified model, depends on the model implementation. |
| 38 | default to 2 as most Torchvision models are for 2D image processing. |
| 39 | in_channels: number of the input channels of last layer. if None, get it from `in_features` of last layer. |
| 40 | use_conv: whether to use convolutional layer to replace the last layer, default to False. |
| 41 | pool: parameters for the pooling layer, it should be a tuple, the first item is name of the pooling layer, |
| 42 | the second item is dictionary of the initialization args. if None, will not replace the `layers[-2]`. |
| 43 | default to `("avg", {"kernel_size": 7, "stride": 1})`. |
| 44 | bias: the bias value when replacing the last layer. if False, the layer will not learn an additive bias, |
| 45 | default to True. |
| 46 | fc_name: the corresponding layer attribute of the last fully connected layer. Defaults to ``"fc"``. |
| 47 | node_name: the corresponding feature extractor node name of `model`. |
| 48 | Defaults to "", the extractor is not in use. |
| 49 | |
| 50 | """ |
| 51 | |
| 52 | def __init__( |
| 53 | self, |
| 54 | model: torch.nn.Module, |
| 55 | num_classes: int = 1, |
| 56 | dim: int = 2, |
| 57 | in_channels: int | None = None, |
| 58 | use_conv: bool = False, |
| 59 | pool: tuple[str, dict[str, Any]] | None = ("avg", {"kernel_size": 7, "stride": 1}), |
| 60 | bias: bool = True, |
| 61 | fc_name: str = "fc", |
| 62 | node_name: str = "", |
| 63 | ): |
| 64 | super().__init__() |
| 65 | layers = list(model.children()) |
| 66 | orig_fc = look_up_named_module(fc_name, model) |
| 67 | if orig_fc is None: |
| 68 | orig_fc = layers[-1] |
| 69 | # guess the number of input channels of the last fully connected layer |
| 70 | in_channels_: int |
| 71 | if in_channels is None: |
| 72 | if not hasattr(orig_fc, "in_features"): |
| 73 | raise ValueError("please specify input channels of the last fully connected layer with `in_channels`.") |
| 74 | in_channels_ = orig_fc.in_features |
| 75 | |
| 76 | else: |
| 77 | in_channels_ = in_channels |
| 78 | |
| 79 | # modify the input model, depending on whether to replace the last pooling layer ``pool`` |
| 80 | if pool is None: # no modification of pooling |
| 81 | if node_name != "": |
| 82 | raise ValueError("`node_name` is not compatible with `pool=None`, please set `pool=''`.") |
| 83 | # we just drop the model's fully connected layer or set it to identity |
no outgoing calls
searching dependent graphs…