From c778215caf26719fe12025c4254c9f6a10f91224 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Mon, 6 Sep 2021 17:52:57 +0100 Subject: [PATCH 1/9] ndim -> spatial_dims Signed-off-by: Wenqi Li --- monai/losses/image_dissimilarity.py | 17 ++++++++++++----- monai/utils/deprecated.py | 3 --- tests/test_deprecated.py | 4 ++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/monai/losses/image_dissimilarity.py b/monai/losses/image_dissimilarity.py index eed5808aa3..33a532c387 100644 --- a/monai/losses/image_dissimilarity.py +++ b/monai/losses/image_dissimilarity.py @@ -8,14 +8,14 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from typing import Tuple, Union +from typing import Optional, Tuple, Union import torch from torch.nn import functional as F from torch.nn.modules.loss import _Loss from monai.networks.layers import gaussian_1d, separable_filtering -from monai.utils import LossReduction +from monai.utils import LossReduction, deprecated_arg def make_rectangular_kernel(kernel_size: int) -> torch.Tensor: @@ -59,18 +59,20 @@ class LocalNormalizedCrossCorrelationLoss(_Loss): DeepReg (https://github.com/DeepRegNet/DeepReg) """ + @deprecated_arg(name="ndim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - ndim: int = 3, + spatial_dims: int = 3, kernel_size: int = 3, kernel_type: str = "rectangular", reduction: Union[LossReduction, str] = LossReduction.MEAN, smooth_nr: float = 1e-5, smooth_dr: float = 1e-5, + ndim: Optional[int] = None, ) -> None: """ Args: - ndim: number of spatial ndimensions, {``1``, ``2``, ``3``}. Defaults to 3. + spatial_dims: number of spatial ndimensions, {``1``, ``2``, ``3``}. Defaults to 3. kernel_size: kernel spatial size, must be odd. kernel_type: {``"rectangular"``, ``"triangular"``, ``"gaussian"``}. Defaults to ``"rectangular"``. reduction: {``"none"``, ``"mean"``, ``"sum"``} @@ -81,10 +83,15 @@ def __init__( - ``"sum"``: the output will be summed. smooth_nr: a small constant added to the numerator to avoid nan. smooth_dr: a small constant added to the denominator to avoid nan. + + .. deprecated:: 0.6.0 + ``ndim`` is deprecated, use ``spatial_dims``. """ super(LocalNormalizedCrossCorrelationLoss, self).__init__(reduction=LossReduction(reduction).value) - self.ndim = ndim + if ndim is not None: + spatial_dims = ndim + self.ndim = spatial_dims if self.ndim not in [1, 2, 3]: raise ValueError(f"Unsupported ndim: {self.ndim}-d, only 1-d, 2-d, and 3-d inputs are supported") diff --git a/monai/utils/deprecated.py b/monai/utils/deprecated.py index 3a4568b06c..846ff5cca1 100644 --- a/monai/utils/deprecated.py +++ b/monai/utils/deprecated.py @@ -157,9 +157,6 @@ def deprecated_arg( is_deprecated = since is not None and version_leq(since, version_val) is_removed = removed is not None and version_leq(removed, version_val) - if is_not_yet_deprecated: - return lambda obj: obj - def _decorator(func): argname = f"{func.__name__}_{name}" diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 429d5ee767..4cd02555c7 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -222,3 +222,7 @@ def future1(): warnings.warn("fake warning", DeprecationWarning) self.assertEqual(aw.warning.args[0], "fake warning") + + +if __name__ == "__main__": + unittest.main() From 9bbab99f7355231709396560beb79cf1340439a0 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 14:28:20 +0100 Subject: [PATCH 2/9] dimensions -> spatial_dims Signed-off-by: Wenqi Li --- monai/apps/deepgrow/transforms.py | 14 ++- monai/networks/blocks/activation.py | 6 +- monai/networks/blocks/aspp.py | 2 +- monai/networks/blocks/convolutions.py | 37 +++++--- monai/networks/blocks/fcn.py | 4 +- monai/networks/blocks/localnet_block.py | 2 +- monai/networks/blocks/regunet_block.py | 2 +- monai/networks/blocks/segresnet_block.py | 2 +- .../networks/blocks/squeeze_and_excitation.py | 6 +- monai/networks/blocks/upsample.py | 38 ++++++--- monai/networks/nets/autoencoder.py | 23 +++-- monai/networks/nets/basic_unet.py | 85 ++++++++++++------- monai/networks/nets/generator.py | 4 +- monai/networks/nets/highresnet.py | 8 +- monai/networks/nets/regressor.py | 4 +- monai/networks/nets/senet.py | 2 +- monai/networks/nets/unet.py | 21 +++-- monai/networks/nets/varautoencoder.py | 16 +++- monai/networks/nets/vnet.py | 6 +- monai/networks/utils.py | 21 +++-- monai/optimizers/utils.py | 2 +- monai/transforms/utils.py | 27 ++++-- tests/test_autoencoder.py | 2 +- tests/test_basic_unet.py | 2 +- tests/test_integration_determinism.py | 2 +- tests/test_integration_segmentation_3d.py | 4 +- tests/test_integration_sliding_window.py | 2 +- tests/test_integration_unet_2d.py | 4 +- tests/test_integration_workflows.py | 4 +- tests/test_inverse.py | 2 +- tests/test_unet.py | 8 +- tests/test_varautoencoder.py | 2 +- 32 files changed, 234 insertions(+), 130 deletions(-) diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index db450792b0..7ededcd94c 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -19,7 +19,7 @@ from monai.transforms import Resize, SpatialCrop from monai.transforms.transform import MapTransform, Randomizable, Transform from monai.transforms.utils import generate_spatial_bounding_box -from monai.utils import InterpolateMode, ensure_tuple, ensure_tuple_rep, min_version, optional_import +from monai.utils import InterpolateMode, deprecated_arg, ensure_tuple, ensure_tuple_rep, min_version, optional_import measure, _ = optional_import("skimage.measure", "0.14.2", min_version) distance_transform_cdt, _ = optional_import("scipy.ndimage.morphology", name="distance_transform_cdt") @@ -476,7 +476,7 @@ class AddGuidanceFromPointsd(Transform): background: key that represents user background (-ve) clicks. axis: axis that represents slices in 3D volume. (axis to Depth) depth_first: if depth (slices) is positioned at first dimension. - dimensions: dimensions based on model used for deepgrow (2D vs 3D). + spatial_dims: dimensions based on model used for deepgrow (2D vs 3D). slice_key: key that represents applicable slice to add guidance. meta_keys: explicitly indicate the key of the meta data dictionary of `ref_image`. for example, for data with key `image`, the metadata by default is in `image_meta_dict`. @@ -486,8 +486,13 @@ class AddGuidanceFromPointsd(Transform): to the key data, default is `meta_dict`, the meta data is a dictionary object. For example, to handle key `image`, read/write affine matrices from the metadata `image_meta_dict` dictionary's `affine` field. + + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + """ + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, ref_image, @@ -496,10 +501,11 @@ def __init__( background: str = "background", axis: int = 0, depth_first: bool = True, - dimensions: int = 2, + spatial_dims: int = 2, slice_key: str = "slice", meta_keys: Optional[str] = None, meta_key_postfix: str = "meta_dict", + dimensions: Optional[int] = None, ): self.ref_image = ref_image self.guidance = guidance @@ -507,7 +513,7 @@ def __init__( self.background = background self.axis = axis self.depth_first = depth_first - self.dimensions = dimensions + self.dimensions = spatial_dims if dimensions is None else dimensions self.slice = slice_key self.meta_keys = meta_keys self.meta_key_postfix = meta_key_postfix diff --git a/monai/networks/blocks/activation.py b/monai/networks/blocks/activation.py index a380f8e757..9841dbd060 100644 --- a/monai/networks/blocks/activation.py +++ b/monai/networks/blocks/activation.py @@ -48,8 +48,7 @@ class Swish(nn.Module): Shape: - - Input: :math:`(N, *)` where `*` means, any number of additional - dimensions + - Input: :math:`(N, *)` where `*` means, any number of additional dimensions - Output: :math:`(N, *)`, same shape as the input @@ -143,8 +142,7 @@ class Mish(nn.Module): this class will utilize `torch.nn.functional.mish` to do the calculation if meets the version. Shape: - - Input: :math:`(N, *)` where `*` means, any number of additional - dimensions + - Input: :math:`(N, *)` where `*` means, any number of additional dimensions - Output: :math:`(N, *)`, same shape as the input diff --git a/monai/networks/blocks/aspp.py b/monai/networks/blocks/aspp.py index f8bf8a5ba6..9796ea8148 100644 --- a/monai/networks/blocks/aspp.py +++ b/monai/networks/blocks/aspp.py @@ -86,7 +86,7 @@ def __init__( out_channels = conv_out_channels * len(pads) # final conv. output channels self.conv_k1 = Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=out_channels, out_channels=out_channels, kernel_size=1, diff --git a/monai/networks/blocks/convolutions.py b/monai/networks/blocks/convolutions.py index 39ce60e3f8..63790c1167 100644 --- a/monai/networks/blocks/convolutions.py +++ b/monai/networks/blocks/convolutions.py @@ -18,6 +18,7 @@ from monai.networks.blocks import ADN from monai.networks.layers.convutils import same_padding, stride_minus_kernel_padding from monai.networks.layers.factories import Conv +from monai.utils.deprecated import deprecated_arg class Convolution(nn.Sequential): @@ -59,7 +60,7 @@ class Convolution(nn.Sequential): ) Args: - dimensions: number of spatial dimensions. + spatial_dims: number of spatial dimensions. in_channels: number of input channels. out_channels: number of output channels. strides: convolution stride. Defaults to 1. @@ -69,13 +70,13 @@ class Convolution(nn.Sequential): act: activation type and arguments. Defaults to PReLU. norm: feature normalization type and arguments. Defaults to instance norm. dropout: dropout ratio. Defaults to no dropout. - dropout_dim: determine the dimensions of dropout. Defaults to 1. + dropout_dim: determine the spatial dimensions of dropout. Defaults to 1. - When dropout_dim = 1, randomly zeroes some of the elements for each channel. - When dropout_dim = 2, Randomly zeroes out entire channels (a channel is a 2D feature map). - When dropout_dim = 3, Randomly zeroes out entire channels (a channel is a 3D feature map). - The value of dropout_dim should be no no larger than the value of `dimensions`. + The value of dropout_dim should be no no larger than the value of `spatial_dims`. dilation: dilation rate. Defaults to 1. groups: controls the connections between inputs and outputs. Defaults to 1. bias: whether to have a bias term. Defaults to True. @@ -86,6 +87,9 @@ class Convolution(nn.Sequential): output_padding: controls the additional size added to one side of the output shape. Defaults to None. + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + See also: :py:class:`monai.networks.layers.Conv` @@ -93,9 +97,10 @@ class Convolution(nn.Sequential): """ + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_channels: int, out_channels: int, strides: Union[Sequence[int], int] = 1, @@ -112,15 +117,16 @@ def __init__( is_transposed: bool = False, padding: Optional[Union[Sequence[int], int]] = None, output_padding: Optional[Union[Sequence[int], int]] = None, + dimensions: Optional[int] = None, ) -> None: super().__init__() - self.dimensions = dimensions + self.dimensions = spatial_dims if dimensions is None else dimensions self.in_channels = in_channels self.out_channels = out_channels self.is_transposed = is_transposed if padding is None: padding = same_padding(kernel_size, dilation) - conv_type = Conv[Conv.CONVTRANS if is_transposed else Conv.CONV, dimensions] + conv_type = Conv[Conv.CONVTRANS if is_transposed else Conv.CONV, self.dimensions] conv: nn.Module if is_transposed: @@ -159,7 +165,7 @@ def __init__( in_channels=out_channels, act=act, norm=norm, - norm_dim=dimensions, + norm_dim=self.dimensions, dropout=dropout, dropout_dim=dropout_dim, ), @@ -177,7 +183,7 @@ class ResidualUnit(nn.Module): from monai.networks.blocks import ResidualUnit convs = ResidualUnit( - dimensions=3, + spatial_dims=3, in_channels=1, out_channels=1, adn_ordering="AN", @@ -209,7 +215,7 @@ class ResidualUnit(nn.Module): ) Args: - dimensions: number of spatial dimensions. + spatial_dims: number of spatial dimensions. in_channels: number of input channels. out_channels: number of output channels. strides: convolution stride. Defaults to 1. @@ -234,15 +240,19 @@ class ResidualUnit(nn.Module): padding: controls the amount of implicit zero-paddings on both sides for padding number of points for each dimension. Defaults to None. + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + See also: :py:class:`monai.networks.blocks.Convolution` """ + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_channels: int, out_channels: int, strides: Union[Sequence[int], int] = 1, @@ -257,9 +267,10 @@ def __init__( bias: bool = True, last_conv_only: bool = False, padding: Optional[Union[Sequence[int], int]] = None, + dimensions: Optional[int] = None, ) -> None: super().__init__() - self.dimensions = dimensions + self.dimensions = spatial_dims if dimensions is None else dimensions self.in_channels = in_channels self.out_channels = out_channels self.conv = nn.Sequential() @@ -273,7 +284,7 @@ def __init__( for su in range(subunits): conv_only = last_conv_only and su == (subunits - 1) unit = Convolution( - dimensions, + self.dimensions, schannels, out_channels, strides=sstrides, @@ -304,7 +315,7 @@ def __init__( rkernel_size = 1 rpadding = 0 - conv_type = Conv[Conv.CONV, dimensions] + conv_type = Conv[Conv.CONV, self.dimensions] self.residual = conv_type(in_channels, out_channels, rkernel_size, strides, rpadding, bias=bias) def forward(self, x: torch.Tensor) -> torch.Tensor: diff --git a/monai/networks/blocks/fcn.py b/monai/networks/blocks/fcn.py index d84e506774..0c4fa3e320 100644 --- a/monai/networks/blocks/fcn.py +++ b/monai/networks/blocks/fcn.py @@ -155,7 +155,7 @@ def __init__( if self.upsample_mode == "transpose": self.up_conv = UpSample( - dimensions=2, + spatial_dims=2, in_channels=self.out_channels, scale_factor=2, mode="deconv", @@ -236,7 +236,7 @@ def __init__( ) self.init_proj = Convolution( - dimensions=2, + spatial_dims=2, in_channels=in_channels, out_channels=3, kernel_size=1, diff --git a/monai/networks/blocks/localnet_block.py b/monai/networks/blocks/localnet_block.py index 3997d42436..8c8cbafac6 100644 --- a/monai/networks/blocks/localnet_block.py +++ b/monai/networks/blocks/localnet_block.py @@ -66,7 +66,7 @@ def get_deconv_block( out_channels: int, ) -> nn.Module: return Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels, strides=2, diff --git a/monai/networks/blocks/regunet_block.py b/monai/networks/blocks/regunet_block.py index d2cd3518b9..c8409c0c79 100644 --- a/monai/networks/blocks/regunet_block.py +++ b/monai/networks/blocks/regunet_block.py @@ -194,7 +194,7 @@ def get_deconv_block( out_channels: int, ) -> nn.Module: return Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels, strides=2, diff --git a/monai/networks/blocks/segresnet_block.py b/monai/networks/blocks/segresnet_block.py index d8f6d7b268..4d2a5b0623 100644 --- a/monai/networks/blocks/segresnet_block.py +++ b/monai/networks/blocks/segresnet_block.py @@ -39,7 +39,7 @@ def get_upsample_layer( spatial_dims: int, in_channels: int, upsample_mode: Union[UpsampleMode, str] = "nontrainable", scale_factor: int = 2 ): return UpSample( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=in_channels, scale_factor=scale_factor, diff --git a/monai/networks/blocks/squeeze_and_excitation.py b/monai/networks/blocks/squeeze_and_excitation.py index 4db6dc30f7..76cbbb5037 100644 --- a/monai/networks/blocks/squeeze_and_excitation.py +++ b/monai/networks/blocks/squeeze_and_excitation.py @@ -186,16 +186,16 @@ def __init__( if not conv_param_1: conv_param_1 = {"kernel_size": 1, "norm": Norm.BATCH, "act": ("relu", {"inplace": True})} self.conv1 = Convolution( - dimensions=spatial_dims, in_channels=in_channels, out_channels=n_chns_1, **conv_param_1 + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=n_chns_1, **conv_param_1 ) if not conv_param_2: conv_param_2 = {"kernel_size": 3, "norm": Norm.BATCH, "act": ("relu", {"inplace": True})} - self.conv2 = Convolution(dimensions=spatial_dims, in_channels=n_chns_1, out_channels=n_chns_2, **conv_param_2) + self.conv2 = Convolution(spatial_dims=spatial_dims, in_channels=n_chns_1, out_channels=n_chns_2, **conv_param_2) if not conv_param_3: conv_param_3 = {"kernel_size": 1, "norm": Norm.BATCH, "act": None} - self.conv3 = Convolution(dimensions=spatial_dims, in_channels=n_chns_2, out_channels=n_chns_3, **conv_param_3) + self.conv3 = Convolution(spatial_dims=spatial_dims, in_channels=n_chns_2, out_channels=n_chns_3, **conv_param_3) self.se_layer = ChannelSELayer( spatial_dims=spatial_dims, in_channels=n_chns_3, r=r, acti_type_1=acti_type_1, acti_type_2=acti_type_2 diff --git a/monai/networks/blocks/upsample.py b/monai/networks/blocks/upsample.py index 5320611ce6..0cb9d12179 100644 --- a/monai/networks/blocks/upsample.py +++ b/monai/networks/blocks/upsample.py @@ -16,7 +16,7 @@ from monai.networks.layers.factories import Conv, Pad, Pool from monai.networks.utils import icnr_init, pixelshuffle -from monai.utils import InterpolateMode, UpsampleMode, ensure_tuple_rep, look_up_option +from monai.utils import InterpolateMode, UpsampleMode, deprecated_arg, ensure_tuple_rep, look_up_option __all__ = ["Upsample", "UpSample", "SubpixelUpsample", "Subpixelupsample", "SubpixelUpSample"] @@ -34,9 +34,10 @@ class UpSample(nn.Sequential): (often used to map the number of features from `in_channels` to `out_channels`). """ + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_channels: Optional[int] = None, out_channels: Optional[int] = None, scale_factor: Union[Sequence[float], float] = 2, @@ -47,10 +48,11 @@ def __init__( align_corners: Optional[bool] = True, bias: bool = True, apply_pad_pool: bool = True, + dimensions: Optional[int] = None, ) -> None: """ Args: - dimensions: number of spatial dimensions of the input image. + spatial_dims: number of spatial dimensions of the input image. in_channels: number of channels of the input image. out_channels: number of channels of the output image. Defaults to `in_channels`. scale_factor: multiplier for spatial size. Has to match input size if it is a tuple. Defaults to 2. @@ -75,16 +77,21 @@ def __init__( apply_pad_pool: if True the upsampled tensor is padded then average pooling is applied with a kernel the size of `scale_factor` with a stride of 1. See also: :py:class:`monai.networks.blocks.SubpixelUpsample`. Only used in the "pixelshuffle" mode. + + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. """ super().__init__() - scale_factor_ = ensure_tuple_rep(scale_factor, dimensions) + if dimensions is not None: + spatial_dims = dimensions + scale_factor_ = ensure_tuple_rep(scale_factor, spatial_dims) up_mode = look_up_option(mode, UpsampleMode) if up_mode == UpsampleMode.DECONV: if not in_channels: raise ValueError(f"in_channels needs to be specified in the '{mode}' mode.") self.add_module( "deconv", - Conv[Conv.CONVTRANS, dimensions]( + Conv[Conv.CONVTRANS, spatial_dims]( in_channels=in_channels, out_channels=out_channels or in_channels, kernel_size=scale_factor_, @@ -98,7 +105,7 @@ def __init__( raise ValueError(f"in_channels needs to be specified in the '{mode}' mode.") self.add_module( "preconv", - Conv[Conv.CONV, dimensions]( + Conv[Conv.CONV, spatial_dims]( in_channels=in_channels, out_channels=out_channels or in_channels, kernel_size=1, bias=bias ), ) @@ -112,7 +119,7 @@ def __init__( interp_mode = InterpolateMode(interp_mode) linear_mode = [InterpolateMode.LINEAR, InterpolateMode.BILINEAR, InterpolateMode.TRILINEAR] if interp_mode in linear_mode: # choose mode based on dimensions - interp_mode = linear_mode[dimensions - 1] + interp_mode = linear_mode[spatial_dims - 1] self.add_module( "upsample_non_trainable", nn.Upsample( @@ -126,7 +133,7 @@ def __init__( self.add_module( "pixelshuffle", SubpixelUpsample( - dimensions=dimensions, + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels, scale_factor=scale_factor_[0], # isotropic @@ -164,19 +171,21 @@ class SubpixelUpsample(nn.Module): """ + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_channels: Optional[int], out_channels: Optional[int] = None, scale_factor: int = 2, conv_block: Optional[Union[nn.Module, str]] = "default", apply_pad_pool: bool = True, bias: bool = True, + dimensions: Optional[int] = None, ) -> None: """ Args: - dimensions: number of spatial dimensions of the input image. + spatial_dims: number of spatial dimensions of the input image. in_channels: number of channels of the input image. out_channels: optional number of channels of the output image. scale_factor: multiplier for spatial size. Defaults to 2. @@ -190,21 +199,24 @@ def __init__( size of `scale_factor` with a stride of 1. This implements the nearest neighbour resize convolution component of subpixel convolutions described in Aitken et al. bias: whether to have a bias term in the default conv_block. Defaults to True. + + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. """ super().__init__() if scale_factor <= 0: raise ValueError(f"The `scale_factor` multiplier must be an integer greater than 0, got {scale_factor}.") - self.dimensions = dimensions + self.dimensions = spatial_dims if dimensions is None else dimensions self.scale_factor = scale_factor if conv_block == "default": out_channels = out_channels or in_channels if not out_channels: raise ValueError("in_channels need to be specified.") - conv_out_channels = out_channels * (scale_factor ** dimensions) - self.conv_block = Conv[Conv.CONV, dimensions]( + conv_out_channels = out_channels * (scale_factor ** self.dimensions) + self.conv_block = Conv[Conv.CONV, self.dimensions]( in_channels=in_channels, out_channels=conv_out_channels, kernel_size=3, stride=1, padding=1, bias=bias ) diff --git a/monai/networks/nets/autoencoder.py b/monai/networks/nets/autoencoder.py index d0a54b8148..648366b0f9 100644 --- a/monai/networks/nets/autoencoder.py +++ b/monai/networks/nets/autoencoder.py @@ -16,14 +16,16 @@ from monai.networks.blocks import Convolution, ResidualUnit from monai.networks.layers.factories import Act, Norm +from monai.utils import deprecated_arg __all__ = ["AutoEncoder"] class AutoEncoder(nn.Module): + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_channels: int, out_channels: int, channels: Sequence[int], @@ -38,10 +40,15 @@ def __init__( norm: Union[Tuple, str] = Norm.INSTANCE, dropout: Optional[Union[Tuple, str, float]] = None, bias: bool = True, + dimensions: Optional[int] = None, ) -> None: + """ + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + """ super().__init__() - self.dimensions = dimensions + self.dimensions = spatial_dims if dimensions is None else dimensions self.in_channels = in_channels self.out_channels = out_channels self.channels = list(channels) @@ -95,7 +102,7 @@ def _get_intermediate_module(self, in_channels: int, num_inter_units: int) -> Tu for i, (dc, di) in enumerate(zip(self.inter_channels, self.inter_dilations)): if self.num_inter_units > 0: unit = ResidualUnit( - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=layer_channels, out_channels=dc, strides=1, @@ -109,7 +116,7 @@ def _get_intermediate_module(self, in_channels: int, num_inter_units: int) -> Tu ) else: unit = Convolution( - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=layer_channels, out_channels=dc, strides=1, @@ -143,7 +150,7 @@ def _get_encode_layer(self, in_channels: int, out_channels: int, strides: int, i if self.num_res_units > 0: return ResidualUnit( - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, strides=strides, @@ -156,7 +163,7 @@ def _get_encode_layer(self, in_channels: int, out_channels: int, strides: int, i last_conv_only=is_last, ) return Convolution( - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, strides=strides, @@ -173,7 +180,7 @@ def _get_decode_layer(self, in_channels: int, out_channels: int, strides: int, i decode = nn.Sequential() conv = Convolution( - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, strides=strides, @@ -190,7 +197,7 @@ def _get_decode_layer(self, in_channels: int, out_channels: int, strides: int, i if self.num_res_units > 0: ru = ResidualUnit( - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=out_channels, out_channels=out_channels, strides=1, diff --git a/monai/networks/nets/basic_unet.py b/monai/networks/nets/basic_unet.py index 63205f45ee..ebf2377078 100644 --- a/monai/networks/nets/basic_unet.py +++ b/monai/networks/nets/basic_unet.py @@ -16,7 +16,7 @@ from monai.networks.blocks import Convolution, UpSample from monai.networks.layers.factories import Conv, Pool -from monai.utils import ensure_tuple_rep +from monai.utils import deprecated_arg, ensure_tuple_rep __all__ = ["BasicUNet", "BasicUnet", "Basicunet"] @@ -24,19 +24,21 @@ class TwoConv(nn.Sequential): """two convolutions.""" + @deprecated_arg(name="dim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dim: int, + spatial_dims: int, in_chns: int, out_chns: int, act: Union[str, tuple], norm: Union[str, tuple], bias: bool, dropout: Union[float, tuple] = 0.0, + dim: Optional[int] = None, ): """ Args: - dim: number of spatial dimensions. + spatial_dims: number of spatial dimensions. in_chns: number of input channels. out_chns: number of output channels. act: activation type and arguments. @@ -44,11 +46,17 @@ def __init__( bias: whether to have a bias term in convolution blocks. dropout: dropout ratio. Defaults to no dropout. + .. deprecated:: 0.6.0 + ``dim`` is deprecated, use ``spatial_dims`` instead. """ super().__init__() - conv_0 = Convolution(dim, in_chns, out_chns, act=act, norm=norm, dropout=dropout, bias=bias, padding=1) - conv_1 = Convolution(dim, out_chns, out_chns, act=act, norm=norm, dropout=dropout, bias=bias, padding=1) + if dim is not None: + spatial_dims = dim + conv_0 = Convolution(spatial_dims, in_chns, out_chns, act=act, norm=norm, dropout=dropout, bias=bias, padding=1) + conv_1 = Convolution( + spatial_dims, out_chns, out_chns, act=act, norm=norm, dropout=dropout, bias=bias, padding=1 + ) self.add_module("conv_0", conv_0) self.add_module("conv_1", conv_1) @@ -56,19 +64,21 @@ def __init__( class Down(nn.Sequential): """maxpooling downsampling and two convolutions.""" + @deprecated_arg(name="dim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dim: int, + spatial_dims: int, in_chns: int, out_chns: int, act: Union[str, tuple], norm: Union[str, tuple], bias: bool, dropout: Union[float, tuple] = 0.0, + dim: Optional[int] = None, ): """ Args: - dim: number of spatial dimensions. + spatial_dims: number of spatial dimensions. in_chns: number of input channels. out_chns: number of output channels. act: activation type and arguments. @@ -76,11 +86,14 @@ def __init__( bias: whether to have a bias term in convolution blocks. dropout: dropout ratio. Defaults to no dropout. + .. deprecated:: 0.6.0 + ``dim`` is deprecated, use ``spatial_dims`` instead. """ super().__init__() - - max_pooling = Pool["MAX", dim](kernel_size=2) - convs = TwoConv(dim, in_chns, out_chns, act, norm, bias, dropout) + if dim is not None: + spatial_dims = dim + max_pooling = Pool["MAX", spatial_dims](kernel_size=2) + convs = TwoConv(spatial_dims, in_chns, out_chns, act, norm, bias, dropout) self.add_module("max_pooling", max_pooling) self.add_module("convs", convs) @@ -88,9 +101,10 @@ def __init__( class UpCat(nn.Module): """upsampling, concatenation with the encoder feature map, two convolutions""" + @deprecated_arg(name="dim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dim: int, + spatial_dims: int, in_chns: int, cat_chns: int, out_chns: int, @@ -103,10 +117,11 @@ def __init__( interp_mode: str = "linear", align_corners: Optional[bool] = True, halves: bool = True, + dim: Optional[int] = None, ): """ Args: - dim: number of spatial dimensions. + spatial_dims: number of spatial dimensions. in_chns: number of input channels to be upsampled. cat_chns: number of channels from the decoder. out_chns: number of output channels. @@ -124,14 +139,19 @@ def __init__( Only used in the "nontrainable" mode. halves: whether to halve the number of channels during upsampling. This parameter does not work on ``nontrainable`` mode if ``pre_conv`` is `None`. + + .. deprecated:: 0.6.0 + ``dim`` is deprecated, use ``spatial_dims`` instead. """ super().__init__() + if dim is not None: + spatial_dims = dim if upsample == "nontrainable" and pre_conv is None: up_chns = in_chns else: up_chns = in_chns // 2 if halves else in_chns self.upsample = UpSample( - dim, + spatial_dims, in_chns, up_chns, 2, @@ -140,7 +160,7 @@ def __init__( interp_mode=interp_mode, align_corners=align_corners, ) - self.convs = TwoConv(dim, cat_chns + up_chns, out_chns, act, norm, bias, dropout) + self.convs = TwoConv(spatial_dims, cat_chns + up_chns, out_chns, act, norm, bias, dropout) def forward(self, x: torch.Tensor, x_e: Optional[torch.Tensor]): """ @@ -167,9 +187,10 @@ def forward(self, x: torch.Tensor, x_e: Optional[torch.Tensor]): class BasicUNet(nn.Module): + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int = 3, + spatial_dims: int = 3, in_channels: int = 1, out_channels: int = 2, features: Sequence[int] = (32, 32, 64, 128, 256, 32), @@ -178,6 +199,7 @@ def __init__( bias: bool = True, dropout: Union[float, tuple] = 0.0, upsample: str = "deconv", + dimensions: Optional[int] = None, ): """ A UNet implementation with 1D/2D/3D supports. @@ -189,7 +211,7 @@ def __init__( http://dx.doi.org/10.1038/s41592-018-0261-2 Args: - dimensions: number of spatial dimensions. Defaults to 3 for spatial 3D inputs. + spatial_dims: number of spatial dimensions. Defaults to 3 for spatial 3D inputs. in_channels: number of input channels. Defaults to 1. out_channels: number of output channels. Defaults to 2. features: six integers as numbers of features. @@ -207,16 +229,19 @@ def __init__( upsample: upsampling mode, available options are ``"deconv"``, ``"pixelshuffle"``, ``"nontrainable"``. + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + Examples:: # for spatial 2D - >>> net = BasicUNet(dimensions=2, features=(64, 128, 256, 512, 1024, 128)) + >>> net = BasicUNet(spatial_dims=2, features=(64, 128, 256, 512, 1024, 128)) # for spatial 2D, with group norm - >>> net = BasicUNet(dimensions=2, features=(64, 128, 256, 512, 1024, 128), norm=("group", {"num_groups": 4})) + >>> net = BasicUNet(spatial_dims=2, features=(64, 128, 256, 512, 1024, 128), norm=("group", {"num_groups": 4})) # for spatial 3D - >>> net = BasicUNet(dimensions=3, features=(32, 32, 64, 128, 256, 32)) + >>> net = BasicUNet(spatial_dims=3, features=(32, 32, 64, 128, 256, 32)) See Also @@ -225,22 +250,24 @@ def __init__( """ super().__init__() + if dimensions is not None: + spatial_dims = dimensions fea = ensure_tuple_rep(features, 6) print(f"BasicUNet features: {fea}.") - self.conv_0 = TwoConv(dimensions, in_channels, features[0], act, norm, bias, dropout) - self.down_1 = Down(dimensions, fea[0], fea[1], act, norm, bias, dropout) - self.down_2 = Down(dimensions, fea[1], fea[2], act, norm, bias, dropout) - self.down_3 = Down(dimensions, fea[2], fea[3], act, norm, bias, dropout) - self.down_4 = Down(dimensions, fea[3], fea[4], act, norm, bias, dropout) + self.conv_0 = TwoConv(spatial_dims, in_channels, features[0], act, norm, bias, dropout) + self.down_1 = Down(spatial_dims, fea[0], fea[1], act, norm, bias, dropout) + self.down_2 = Down(spatial_dims, fea[1], fea[2], act, norm, bias, dropout) + self.down_3 = Down(spatial_dims, fea[2], fea[3], act, norm, bias, dropout) + self.down_4 = Down(spatial_dims, fea[3], fea[4], act, norm, bias, dropout) - self.upcat_4 = UpCat(dimensions, fea[4], fea[3], fea[3], act, norm, bias, dropout, upsample) - self.upcat_3 = UpCat(dimensions, fea[3], fea[2], fea[2], act, norm, bias, dropout, upsample) - self.upcat_2 = UpCat(dimensions, fea[2], fea[1], fea[1], act, norm, bias, dropout, upsample) - self.upcat_1 = UpCat(dimensions, fea[1], fea[0], fea[5], act, norm, bias, dropout, upsample, halves=False) + self.upcat_4 = UpCat(spatial_dims, fea[4], fea[3], fea[3], act, norm, bias, dropout, upsample) + self.upcat_3 = UpCat(spatial_dims, fea[3], fea[2], fea[2], act, norm, bias, dropout, upsample) + self.upcat_2 = UpCat(spatial_dims, fea[2], fea[1], fea[1], act, norm, bias, dropout, upsample) + self.upcat_1 = UpCat(spatial_dims, fea[1], fea[0], fea[5], act, norm, bias, dropout, upsample, halves=False) - self.final_conv = Conv["conv", dimensions](fea[5], out_channels, kernel_size=1) + self.final_conv = Conv["conv", spatial_dims](fea[5], out_channels, kernel_size=1) def forward(self, x: torch.Tensor): """ diff --git a/monai/networks/nets/generator.py b/monai/networks/nets/generator.py index 1f24944a63..ea05787173 100644 --- a/monai/networks/nets/generator.py +++ b/monai/networks/nets/generator.py @@ -112,7 +112,7 @@ def _get_layer( strides=strides, is_transposed=True, conv_only=is_last or self.num_res_units > 0, - dimensions=self.dimensions, + spatial_dims=self.dimensions, out_channels=out_channels, kernel_size=self.kernel_size, act=self.act, @@ -126,7 +126,7 @@ def _get_layer( in_channels=out_channels, subunits=self.num_res_units, last_conv_only=is_last, - dimensions=self.dimensions, + spatial_dims=self.dimensions, out_channels=out_channels, kernel_size=self.kernel_size, act=self.act, diff --git a/monai/networks/nets/highresnet.py b/monai/networks/nets/highresnet.py index f644a7835a..cd0950804d 100644 --- a/monai/networks/nets/highresnet.py +++ b/monai/networks/nets/highresnet.py @@ -84,7 +84,7 @@ def __init__( ) layers.append( Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=_in_chns, out_channels=_out_chns, kernel_size=kernel_size, @@ -154,7 +154,7 @@ def __init__( _in_chns, _out_chns = in_channels, params["n_features"] blocks.append( Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=_in_chns, out_channels=_out_chns, kernel_size=params["kernel_size"], @@ -190,7 +190,7 @@ def __init__( _in_chns, _out_chns = _out_chns, params["n_features"] blocks.append( Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=_in_chns, out_channels=_out_chns, kernel_size=params["kernel_size"], @@ -206,7 +206,7 @@ def __init__( _in_chns = _out_chns blocks.append( Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=_in_chns, out_channels=out_channels, kernel_size=params["kernel_size"], diff --git a/monai/networks/nets/regressor.py b/monai/networks/nets/regressor.py index 25acb9bfa5..0153014902 100644 --- a/monai/networks/nets/regressor.py +++ b/monai/networks/nets/regressor.py @@ -107,7 +107,7 @@ def _get_layer( layer = ResidualUnit( subunits=self.num_res_units, last_conv_only=is_last, - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, strides=strides, @@ -120,7 +120,7 @@ def _get_layer( else: layer = Convolution( conv_only=is_last, - dimensions=self.dimensions, + spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, strides=strides, diff --git a/monai/networks/nets/senet.py b/monai/networks/nets/senet.py index 9b7035c259..65089afc2c 100644 --- a/monai/networks/nets/senet.py +++ b/monai/networks/nets/senet.py @@ -192,7 +192,7 @@ def _make_layer( downsample = None if stride != 1 or self.inplanes != planes * block.expansion: downsample = Convolution( - dimensions=self.spatial_dims, + spatial_dims=self.spatial_dims, in_channels=self.inplanes, out_channels=planes * block.expansion, strides=stride, diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py index 70cc816fe9..26d56b86ac 100644 --- a/monai/networks/nets/unet.py +++ b/monai/networks/nets/unet.py @@ -10,7 +10,7 @@ # limitations under the License. import warnings -from typing import Sequence, Tuple, Union +from typing import Optional, Sequence, Tuple, Union import torch import torch.nn as nn @@ -18,7 +18,7 @@ from monai.networks.blocks.convolutions import Convolution, ResidualUnit from monai.networks.layers.factories import Act, Norm from monai.networks.layers.simplelayers import SkipConnection -from monai.utils import alias, export +from monai.utils import alias, deprecated_arg, export __all__ = ["UNet", "Unet", "unet"] @@ -26,9 +26,10 @@ @export("monai.networks.nets") @alias("Unet") class UNet(nn.Module): + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_channels: int, out_channels: int, channels: Sequence[int], @@ -40,6 +41,7 @@ def __init__( norm: Union[Tuple, str] = Norm.INSTANCE, dropout: float = 0.0, bias: bool = True, + dimensions: Optional[int] = None, ) -> None: """ Enhanced version of UNet which has residual units implemented with the ResidualUnit class. @@ -48,7 +50,7 @@ def __init__( Refer to: https://link.springer.com/chapter/10.1007/978-3-030-12029-0_40. Args: - dimensions: number of spatial dimensions. + spatial_dims: number of spatial dimensions. in_channels: number of input channels. out_channels: number of output channels. channels: sequence of channels. Top block first. The length of `channels` should be no less than 2. @@ -65,6 +67,9 @@ def __init__( According to `Performance Tuning Guide `_, if a conv layer is directly followed by a batch norm layer, bias should be False. + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + Note: The acceptable spatial size of input data depends on the parameters of the network, to set appropriate spatial size, please check the tutorial for more details: https://github.com/Project-MONAI/tutorials/blob/master/modules/UNet_input_size_constrains.ipynb. @@ -83,14 +88,16 @@ def __init__( raise ValueError("the length of `strides` should equal to `len(channels) - 1`.") if delta > 0: warnings.warn(f"`len(strides) > len(channels) - 1`, the last {delta} values of strides will not be used.") + if dimensions is not None: + spatial_dims = dimensions if isinstance(kernel_size, Sequence): - if len(kernel_size) != dimensions: + if len(kernel_size) != spatial_dims: raise ValueError("the length of `kernel_size` should equal to `dimensions`.") if isinstance(up_kernel_size, Sequence): - if len(up_kernel_size) != dimensions: + if len(up_kernel_size) != spatial_dims: raise ValueError("the length of `up_kernel_size` should equal to `dimensions`.") - self.dimensions = dimensions + self.dimensions = spatial_dims self.in_channels = in_channels self.out_channels = out_channels self.channels = channels diff --git a/monai/networks/nets/varautoencoder.py b/monai/networks/nets/varautoencoder.py index 7f54890992..26c84ebe0c 100644 --- a/monai/networks/nets/varautoencoder.py +++ b/monai/networks/nets/varautoencoder.py @@ -19,16 +19,23 @@ from monai.networks.layers.convutils import calculate_out_shape, same_padding from monai.networks.layers.factories import Act, Norm from monai.networks.nets import AutoEncoder +from monai.utils import deprecated_arg __all__ = ["VarAutoEncoder"] class VarAutoEncoder(AutoEncoder): - """Variational Autoencoder based on the paper - https://arxiv.org/abs/1312.6114""" + """ + Variational Autoencoder based on the paper - https://arxiv.org/abs/1312.6114 + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + """ + + @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, - dimensions: int, + spatial_dims: int, in_shape: Sequence[int], out_channels: int, latent_size: int, @@ -44,15 +51,18 @@ def __init__( norm: Union[Tuple, str] = Norm.INSTANCE, dropout: Optional[Union[Tuple, str, float]] = None, bias: bool = True, + dimensions: Optional[int] = None, ) -> None: self.in_channels, *self.in_shape = in_shape self.latent_size = latent_size self.final_size = np.asarray(self.in_shape, dtype=int) + if dimensions is not None: + spatial_dims = dimensions super().__init__( - dimensions, + spatial_dims, self.in_channels, out_channels, channels, diff --git a/monai/networks/nets/vnet.py b/monai/networks/nets/vnet.py index 72f3290a89..c7eea67e62 100644 --- a/monai/networks/nets/vnet.py +++ b/monai/networks/nets/vnet.py @@ -34,7 +34,7 @@ def __init__(self, spatial_dims: int, nchan: int, act: Union[Tuple[str, Dict], s self.act_function = get_acti_layer(act, nchan) self.conv_block = Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=nchan, out_channels=nchan, kernel_size=5, @@ -74,7 +74,7 @@ def __init__( self.in_channels = in_channels self.act_function = get_acti_layer(act, 16) self.conv_block = Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=16, kernel_size=5, @@ -180,7 +180,7 @@ def __init__( self.act_function1 = get_acti_layer(act, out_channels) self.conv_block = Convolution( - dimensions=spatial_dims, + spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels, kernel_size=5, diff --git a/monai/networks/utils.py b/monai/networks/utils.py index 9d20d2a83b..14afdc48c2 100644 --- a/monai/networks/utils.py +++ b/monai/networks/utils.py @@ -20,6 +20,8 @@ import torch import torch.nn as nn +from monai.utils.deprecated import deprecated_arg + __all__ = [ "one_hot", "slice_channels", @@ -225,9 +227,12 @@ def icnr_init(conv, upsample_factor, init=nn.init.kaiming_normal_): conv.weight.data.copy_(kernel) -def pixelshuffle(x: torch.Tensor, dimensions: int, scale_factor: int) -> torch.Tensor: +@deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") +def pixelshuffle( + x: torch.Tensor, spatial_dims: int, scale_factor: int, dimensions: Optional[int] = None +) -> torch.Tensor: """ - Apply pixel shuffle to the tensor `x` with spatial dimensions `dimensions` and scaling factor `scale_factor`. + Apply pixel shuffle to the tensor `x` with spatial dimensions `spatial_dims` and scaling factor `scale_factor`. See: Shi et al., 2016, "Real-Time Single Image and Video Super-Resolution Using a nEfficient Sub-Pixel Convolutional Neural Network." @@ -236,17 +241,21 @@ def pixelshuffle(x: torch.Tensor, dimensions: int, scale_factor: int) -> torch.T Args: x: Input tensor - dimensions: number of spatial dimensions, typically 2 or 3 for 2D or 3D + spatial_dims: number of spatial dimensions, typically 2 or 3 for 2D or 3D scale_factor: factor to rescale the spatial dimensions by, must be >=1 + .. deprecated:: 0.6.0 + ``dimensions`` is deprecated, use ``spatial_dims`` instead. + Returns: Reshuffled version of `x`. Raises: - ValueError: When input channels of `x` are not divisible by (scale_factor ** dimensions) + ValueError: When input channels of `x` are not divisible by (scale_factor ** spatial_dims) """ - - dim, factor = dimensions, scale_factor + if dimensions is not None: + spatial_dims = dimensions + dim, factor = spatial_dims, scale_factor input_size = list(x.size()) batch_size, channels = input_size[:2] scale_divisor = factor ** dim diff --git a/monai/optimizers/utils.py b/monai/optimizers/utils.py index c52ab07a04..08949912d7 100644 --- a/monai/optimizers/utils.py +++ b/monai/optimizers/utils.py @@ -47,7 +47,7 @@ def generate_param_groups( .. code-block:: python - net = Unet(dimensions=3, in_channels=1, out_channels=3, channels=[2, 2, 2], strides=[1, 1, 1]) + net = Unet(spatial_dims=3, in_channels=1, out_channels=3, channels=[2, 2, 2], strides=[1, 1, 1]) print(net) # print out network components to select expected items print(net.named_parameters()) # print out all the named parameters to filter out expected items params = generate_param_groups( diff --git a/monai/transforms/utils.py b/monai/transforms/utils.py index 30aa5e7b99..72025005fc 100644 --- a/monai/transforms/utils.py +++ b/monai/transforms/utils.py @@ -30,6 +30,7 @@ GridSampleMode, InterpolateMode, InverseKeys, + deprecated_arg, ensure_tuple, ensure_tuple_rep, ensure_tuple_size, @@ -1088,36 +1089,50 @@ class Fourier: """ @staticmethod - def shift_fourier(x: torch.Tensor, n_dims: int) -> torch.Tensor: + @deprecated_arg(name="n_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + def shift_fourier(x: torch.Tensor, spatial_dims: int, n_dims: Optional[int] = None) -> torch.Tensor: """ Applies fourier transform and shifts the zero-frequency component to the center of the spectrum. Only the spatial dimensions get transformed. Args: x: Image to transform. - n_dims: Number of spatial dimensions. + spatial_dims: Number of spatial dimensions. + + .. deprecated:: 0.6.0 + ``n_dims`` is deprecated, use ``spatial_dims`` instead. + Returns k: K-space data. """ + if n_dims is not None: + spatial_dims = n_dims k: torch.Tensor = torch.fft.fftshift( - torch.fft.fftn(x, dim=tuple(range(-n_dims, 0))), dim=tuple(range(-n_dims, 0)) + torch.fft.fftn(x, dim=tuple(range(-spatial_dims, 0))), dim=tuple(range(-spatial_dims, 0)) ) return k @staticmethod - def inv_shift_fourier(k: torch.Tensor, n_dims: int) -> torch.Tensor: + @deprecated_arg(name="n_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + def inv_shift_fourier(k: torch.Tensor, spatial_dims: int, n_dims: Optional[int] = None) -> torch.Tensor: """ Applies inverse shift and fourier transform. Only the spatial dimensions are transformed. Args: k: K-space data. - n_dims: Number of spatial dimensions. + spatial_dims: Number of spatial dimensions. + + .. deprecated:: 0.6.0 + ``n_dims`` is deprecated, use ``spatial_dims`` instead. + Returns: x: Tensor in image space. """ + if n_dims is not None: + spatial_dims = n_dims x: torch.Tensor = torch.fft.ifftn( - torch.fft.ifftshift(k, dim=tuple(range(-n_dims, 0))), dim=tuple(range(-n_dims, 0)) + torch.fft.ifftshift(k, dim=tuple(range(-spatial_dims, 0))), dim=tuple(range(-spatial_dims, 0)) ).real return x diff --git a/tests/test_autoencoder.py b/tests/test_autoencoder.py index 54d6832c8d..d67964f034 100644 --- a/tests/test_autoencoder.py +++ b/tests/test_autoencoder.py @@ -92,7 +92,7 @@ def test_shape(self, input_param, input_shape, expected_shape): self.assertEqual(result.shape, expected_shape) def test_script(self): - net = AutoEncoder(dimensions=2, in_channels=1, out_channels=1, channels=(4, 8), strides=(2, 2)) + net = AutoEncoder(spatial_dims=2, in_channels=1, out_channels=1, channels=(4, 8), strides=(2, 2)) test_data = torch.randn(2, 1, 32, 32) test_script_save(net, test_data) diff --git a/tests/test_basic_unet.py b/tests/test_basic_unet.py index 09d7f72d0e..1e553b363b 100644 --- a/tests/test_basic_unet.py +++ b/tests/test_basic_unet.py @@ -101,7 +101,7 @@ def test_shape(self, input_param, input_shape, expected_shape): self.assertEqual(result.shape, expected_shape) def test_script(self): - net = BasicUNet(dimensions=2, in_channels=1, out_channels=3) + net = BasicUNet(spatial_dims=2, in_channels=1, out_channels=3) test_data = torch.randn(16, 1, 32, 32) test_script_save(net, test_data) diff --git a/tests/test_integration_determinism.py b/tests/test_integration_determinism.py index e077420420..7725990763 100644 --- a/tests/test_integration_determinism.py +++ b/tests/test_integration_determinism.py @@ -41,7 +41,7 @@ def __len__(self): return train_steps net = UNet( - dimensions=2, in_channels=1, out_channels=1, channels=(4, 8, 16, 32), strides=(2, 2, 2), num_res_units=2 + spatial_dims=2, in_channels=1, out_channels=1, channels=(4, 8, 16, 32), strides=(2, 2, 2), num_res_units=2 ).to(device) loss = DiceLoss(sigmoid=True) diff --git a/tests/test_integration_segmentation_3d.py b/tests/test_integration_segmentation_3d.py index d5eb69f7af..215a5b3f9a 100644 --- a/tests/test_integration_segmentation_3d.py +++ b/tests/test_integration_segmentation_3d.py @@ -100,7 +100,7 @@ def run_training_test(root_dir, device="cuda:0", cachedataset=0, readers=(None, # create UNet, DiceLoss and Adam optimizer model = monai.networks.nets.UNet( - dimensions=3, + spatial_dims=3, in_channels=1, out_channels=1, channels=(16, 32, 64, 128, 256), @@ -199,7 +199,7 @@ def run_inference_test(root_dir, device="cuda:0"): dice_metric = DiceMetric(include_background=True, reduction="mean", get_not_nans=False) model = UNet( - dimensions=3, + spatial_dims=3, in_channels=1, out_channels=1, channels=(16, 32, 64, 128, 256), diff --git a/tests/test_integration_sliding_window.py b/tests/test_integration_sliding_window.py index b63f331ba6..0522bf080e 100644 --- a/tests/test_integration_sliding_window.py +++ b/tests/test_integration_sliding_window.py @@ -34,7 +34,7 @@ def run_test(batch_size, img_name, seg_name, output_dir, device="cuda:0"): loader = DataLoader(ds, batch_size=1, pin_memory=torch.cuda.is_available()) net = UNet( - dimensions=3, in_channels=1, out_channels=1, channels=(4, 8, 16, 32), strides=(2, 2, 2), num_res_units=2 + spatial_dims=3, in_channels=1, out_channels=1, channels=(4, 8, 16, 32), strides=(2, 2, 2), num_res_units=2 ).to(device) roi_size = (16, 32, 48) sw_batch_size = batch_size diff --git a/tests/test_integration_unet_2d.py b/tests/test_integration_unet_2d.py index a46a174dc9..88e6d7e795 100644 --- a/tests/test_integration_unet_2d.py +++ b/tests/test_integration_unet_2d.py @@ -32,10 +32,10 @@ def __len__(self): return train_steps if net_name == "basicunet": - net = BasicUNet(dimensions=2, in_channels=1, out_channels=1, features=(4, 8, 8, 16, 16, 32)) + net = BasicUNet(spatial_dims=2, in_channels=1, out_channels=1, features=(4, 8, 8, 16, 16, 32)) elif net_name == "unet": net = UNet( - dimensions=2, in_channels=1, out_channels=1, channels=(4, 8, 16, 32), strides=(2, 2, 2), num_res_units=2 + spatial_dims=2, in_channels=1, out_channels=1, channels=(4, 8, 16, 32), strides=(2, 2, 2), num_res_units=2 ) net.to(device) diff --git a/tests/test_integration_workflows.py b/tests/test_integration_workflows.py index 7fcc0b4064..4a3e027993 100644 --- a/tests/test_integration_workflows.py +++ b/tests/test_integration_workflows.py @@ -98,7 +98,7 @@ def run_training_test(root_dir, device="cuda:0", amp=False, num_workers=4): # create UNet, DiceLoss and Adam optimizer net = monai.networks.nets.UNet( - dimensions=3, + spatial_dims=3, in_channels=1, out_channels=1, channels=(16, 32, 64, 128, 256), @@ -230,7 +230,7 @@ def run_inference_test(root_dir, model_file, device="cuda:0", amp=False, num_wor # create UNet, DiceLoss and Adam optimizer net = monai.networks.nets.UNet( - dimensions=3, + spatial_dims=3, in_channels=1, out_channels=1, channels=(16, 32, 64, 128, 256), diff --git a/tests/test_inverse.py b/tests/test_inverse.py index f2470d47fd..9535a40c05 100644 --- a/tests/test_inverse.py +++ b/tests/test_inverse.py @@ -666,7 +666,7 @@ def test_inverse_inferred_seg(self, extra_transform): device = "cuda" if torch.cuda.is_available() else "cpu" model = UNet( - dimensions=2, + spatial_dims=2, in_channels=1, out_channels=1, channels=(2, 4), diff --git a/tests/test_unet.py b/tests/test_unet.py index 4091c4e9d7..94077dad14 100644 --- a/tests/test_unet.py +++ b/tests/test_unet.py @@ -170,13 +170,15 @@ def test_shape(self, input_param, input_shape, expected_shape): self.assertEqual(result.shape, expected_shape) def test_script(self): - net = UNet(dimensions=2, in_channels=1, out_channels=3, channels=(16, 32, 64), strides=(2, 2), num_res_units=0) + net = UNet( + spatial_dims=2, in_channels=1, out_channels=3, channels=(16, 32, 64), strides=(2, 2), num_res_units=0 + ) test_data = torch.randn(16, 1, 32, 32) test_script_save(net, test_data) def test_script_without_running_stats(self): net = UNet( - dimensions=2, + spatial_dims=2, in_channels=1, out_channels=3, channels=(16, 32, 64), @@ -189,7 +191,7 @@ def test_script_without_running_stats(self): def test_ill_input_shape(self): net = UNet( - dimensions=2, + spatial_dims=2, in_channels=1, out_channels=3, channels=(16, 32, 64), diff --git a/tests/test_varautoencoder.py b/tests/test_varautoencoder.py index 7a4a546d87..a99420930d 100644 --- a/tests/test_varautoencoder.py +++ b/tests/test_varautoencoder.py @@ -88,7 +88,7 @@ def test_shape(self, input_param, input_shape, expected_shape): def test_script(self): net = VarAutoEncoder( - dimensions=2, in_shape=(1, 32, 32), out_channels=1, latent_size=2, channels=(4, 8), strides=(2, 2) + spatial_dims=2, in_shape=(1, 32, 32), out_channels=1, latent_size=2, channels=(4, 8), strides=(2, 2) ) test_data = torch.randn(2, 1, 32, 32) test_script_save(net, test_data) From 9d7c6cca31e214f1eab1c646beb7764ca4bcf81b Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 16:02:28 +0100 Subject: [PATCH 3/9] deprecated arg with auto replacement Signed-off-by: Wenqi Li --- monai/networks/blocks/convolutions.py | 4 +++- monai/networks/blocks/upsample.py | 8 ++++++-- monai/networks/nets/autoencoder.py | 4 +++- monai/networks/nets/basic_unet.py | 10 ++++++---- monai/networks/nets/unet.py | 4 +++- monai/networks/nets/varautoencoder.py | 4 +++- monai/networks/utils.py | 4 +++- monai/transforms/utils.py | 8 ++++++-- monai/utils/deprecated.py | 5 +++++ tests/test_varautoencoder.py | 2 +- 10 files changed, 39 insertions(+), 14 deletions(-) diff --git a/monai/networks/blocks/convolutions.py b/monai/networks/blocks/convolutions.py index 63790c1167..d9ef0fd4a1 100644 --- a/monai/networks/blocks/convolutions.py +++ b/monai/networks/blocks/convolutions.py @@ -97,7 +97,9 @@ class Convolution(nn.Sequential): """ - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int, diff --git a/monai/networks/blocks/upsample.py b/monai/networks/blocks/upsample.py index 0cb9d12179..a6aa13dde4 100644 --- a/monai/networks/blocks/upsample.py +++ b/monai/networks/blocks/upsample.py @@ -34,7 +34,9 @@ class UpSample(nn.Sequential): (often used to map the number of features from `in_channels` to `out_channels`). """ - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int, @@ -171,7 +173,9 @@ class SubpixelUpsample(nn.Module): """ - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int, diff --git a/monai/networks/nets/autoencoder.py b/monai/networks/nets/autoencoder.py index 648366b0f9..acbc5221e3 100644 --- a/monai/networks/nets/autoencoder.py +++ b/monai/networks/nets/autoencoder.py @@ -22,7 +22,9 @@ class AutoEncoder(nn.Module): - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int, diff --git a/monai/networks/nets/basic_unet.py b/monai/networks/nets/basic_unet.py index ebf2377078..f96b299d2b 100644 --- a/monai/networks/nets/basic_unet.py +++ b/monai/networks/nets/basic_unet.py @@ -24,7 +24,7 @@ class TwoConv(nn.Sequential): """two convolutions.""" - @deprecated_arg(name="dim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg(name="dim", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, spatial_dims: int, @@ -64,7 +64,7 @@ def __init__( class Down(nn.Sequential): """maxpooling downsampling and two convolutions.""" - @deprecated_arg(name="dim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg(name="dim", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, spatial_dims: int, @@ -101,7 +101,7 @@ def __init__( class UpCat(nn.Module): """upsampling, concatenation with the encoder feature map, two convolutions""" - @deprecated_arg(name="dim", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg(name="dim", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") def __init__( self, spatial_dims: int, @@ -187,7 +187,9 @@ def forward(self, x: torch.Tensor, x_e: Optional[torch.Tensor]): class BasicUNet(nn.Module): - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int = 3, diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py index 26d56b86ac..3c06b3dc08 100644 --- a/monai/networks/nets/unet.py +++ b/monai/networks/nets/unet.py @@ -26,7 +26,9 @@ @export("monai.networks.nets") @alias("Unet") class UNet(nn.Module): - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int, diff --git a/monai/networks/nets/varautoencoder.py b/monai/networks/nets/varautoencoder.py index 26c84ebe0c..31e187106f 100644 --- a/monai/networks/nets/varautoencoder.py +++ b/monai/networks/nets/varautoencoder.py @@ -32,7 +32,9 @@ class VarAutoEncoder(AutoEncoder): ``dimensions`` is deprecated, use ``spatial_dims`` instead. """ - @deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def __init__( self, spatial_dims: int, diff --git a/monai/networks/utils.py b/monai/networks/utils.py index 14afdc48c2..8ba32f1871 100644 --- a/monai/networks/utils.py +++ b/monai/networks/utils.py @@ -227,7 +227,9 @@ def icnr_init(conv, upsample_factor, init=nn.init.kaiming_normal_): conv.weight.data.copy_(kernel) -@deprecated_arg(name="dimensions", since="0.6", msg_suffix="Please use `spatial_dims` instead.") +@deprecated_arg( + name="dimensions", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." +) def pixelshuffle( x: torch.Tensor, spatial_dims: int, scale_factor: int, dimensions: Optional[int] = None ) -> torch.Tensor: diff --git a/monai/transforms/utils.py b/monai/transforms/utils.py index 72025005fc..9618723430 100644 --- a/monai/transforms/utils.py +++ b/monai/transforms/utils.py @@ -1089,7 +1089,9 @@ class Fourier: """ @staticmethod - @deprecated_arg(name="n_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="n_dims", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def shift_fourier(x: torch.Tensor, spatial_dims: int, n_dims: Optional[int] = None) -> torch.Tensor: """ Applies fourier transform and shifts the zero-frequency component to the @@ -1113,7 +1115,9 @@ def shift_fourier(x: torch.Tensor, spatial_dims: int, n_dims: Optional[int] = No return k @staticmethod - @deprecated_arg(name="n_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead.") + @deprecated_arg( + name="n_dims", new_name="spatial_dims", since="0.6", msg_suffix="Please use `spatial_dims` instead." + ) def inv_shift_fourier(k: torch.Tensor, spatial_dims: int, n_dims: Optional[int] = None) -> torch.Tensor: """ Applies inverse shift and fourier transform. Only the spatial diff --git a/monai/utils/deprecated.py b/monai/utils/deprecated.py index 846ff5cca1..7c330ce51b 100644 --- a/monai/utils/deprecated.py +++ b/monai/utils/deprecated.py @@ -116,6 +116,7 @@ def deprecated_arg( removed: Optional[str] = None, msg_suffix: str = "", version_val: str = __version__, + new_name: Optional[str] = None, ): """ Marks a particular named argument of a callable as deprecated. The same conditions for `since` and `removed` as @@ -137,6 +138,7 @@ def deprecated_arg( removed: version at which the argument was removed and no longer usable. msg_suffix: message appended to warning/exception detailing reasons for deprecation and what to use instead. version_val: (used for testing) version to compare since and removed against, default is MONAI version. + new_name: name of position or keyword argument to replace the deprecated argument. Returns: Decorated callable which warns or raises exception when deprecated argument used @@ -177,6 +179,9 @@ def _decorator(func): @wraps(func) def _wrapper(*args, **kwargs): + if new_name is not None and name in kwargs: + # replace the deprecated arg "name" with "new_name" + kwargs[new_name] = kwargs[name] binding = sig.bind(*args, **kwargs).arguments positional_found = name in binding diff --git a/tests/test_varautoencoder.py b/tests/test_varautoencoder.py index a99420930d..7a4a546d87 100644 --- a/tests/test_varautoencoder.py +++ b/tests/test_varautoencoder.py @@ -88,7 +88,7 @@ def test_shape(self, input_param, input_shape, expected_shape): def test_script(self): net = VarAutoEncoder( - spatial_dims=2, in_shape=(1, 32, 32), out_channels=1, latent_size=2, channels=(4, 8), strides=(2, 2) + dimensions=2, in_shape=(1, 32, 32), out_channels=1, latent_size=2, channels=(4, 8), strides=(2, 2) ) test_data = torch.randn(2, 1, 32, 32) test_script_save(net, test_data) From dcfb979db985bdbab99c2155e6f0901fcc5bf4cf Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 16:43:49 +0100 Subject: [PATCH 4/9] fixes type hints Signed-off-by: Wenqi Li --- monai/networks/blocks/localnet_block.py | 9 ++++++--- monai/networks/blocks/regunet_block.py | 8 +++++--- monai/networks/nets/autoencoder.py | 6 ++++-- monai/networks/nets/unet.py | 7 +++++-- monai/transforms/intensity/array.py | 4 ++-- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/monai/networks/blocks/localnet_block.py b/monai/networks/blocks/localnet_block.py index 8c8cbafac6..4e008b128a 100644 --- a/monai/networks/blocks/localnet_block.py +++ b/monai/networks/blocks/localnet_block.py @@ -29,7 +29,7 @@ def get_conv_block( norm: Optional[Union[Tuple, str]] = "BATCH", ) -> nn.Module: padding = same_padding(kernel_size) - return Convolution( + mod: nn.Module = Convolution( spatial_dims, in_channels, out_channels, @@ -40,6 +40,7 @@ def get_conv_block( conv_only=False, padding=padding, ) + return mod def get_conv_layer( @@ -49,7 +50,7 @@ def get_conv_layer( kernel_size: Union[Sequence[int], int] = 3, ) -> nn.Module: padding = same_padding(kernel_size) - return Convolution( + mod: nn.Module = Convolution( spatial_dims, in_channels, out_channels, @@ -58,6 +59,7 @@ def get_conv_layer( conv_only=True, padding=padding, ) + return mod def get_deconv_block( @@ -65,7 +67,7 @@ def get_deconv_block( in_channels: int, out_channels: int, ) -> nn.Module: - return Convolution( + mod: nn.Module = Convolution( spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels, @@ -77,6 +79,7 @@ def get_deconv_block( padding=1, output_padding=1, ) + return mod class ResidualBlock(nn.Module): diff --git a/monai/networks/blocks/regunet_block.py b/monai/networks/blocks/regunet_block.py index c8409c0c79..29fa3d5d85 100644 --- a/monai/networks/blocks/regunet_block.py +++ b/monai/networks/blocks/regunet_block.py @@ -32,7 +32,7 @@ def get_conv_block( ) -> nn.Module: if padding is None: padding = same_padding(kernel_size) - conv_block = Convolution( + conv_block: nn.Module = Convolution( spatial_dims, in_channels, out_channels, @@ -65,7 +65,7 @@ def get_conv_layer( kernel_size: Union[Sequence[int], int] = 3, ) -> nn.Module: padding = same_padding(kernel_size) - return Convolution( + mod: nn.Module = Convolution( spatial_dims, in_channels, out_channels, @@ -74,6 +74,7 @@ def get_conv_layer( conv_only=True, padding=padding, ) + return mod class RegistrationResidualConvBlock(nn.Module): @@ -193,7 +194,7 @@ def get_deconv_block( in_channels: int, out_channels: int, ) -> nn.Module: - return Convolution( + mod: nn.Module = Convolution( spatial_dims=spatial_dims, in_channels=in_channels, out_channels=out_channels, @@ -205,6 +206,7 @@ def get_deconv_block( padding=1, output_padding=1, ) + return mod class RegistrationExtractionBlock(nn.Module): diff --git a/monai/networks/nets/autoencoder.py b/monai/networks/nets/autoencoder.py index acbc5221e3..08b84d0566 100644 --- a/monai/networks/nets/autoencoder.py +++ b/monai/networks/nets/autoencoder.py @@ -150,8 +150,9 @@ def _get_decode_module( def _get_encode_layer(self, in_channels: int, out_channels: int, strides: int, is_last: bool) -> nn.Module: + mod: nn.Module if self.num_res_units > 0: - return ResidualUnit( + mod = ResidualUnit( spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, @@ -164,7 +165,7 @@ def _get_encode_layer(self, in_channels: int, out_channels: int, strides: int, i bias=self.bias, last_conv_only=is_last, ) - return Convolution( + mod = Convolution( spatial_dims=self.dimensions, in_channels=in_channels, out_channels=out_channels, @@ -176,6 +177,7 @@ def _get_encode_layer(self, in_channels: int, out_channels: int, strides: int, i bias=self.bias, conv_only=is_last, ) + return mod def _get_decode_layer(self, in_channels: int, out_channels: int, strides: int, is_last: bool) -> nn.Sequential: diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py index 3c06b3dc08..a7018a29a7 100644 --- a/monai/networks/nets/unet.py +++ b/monai/networks/nets/unet.py @@ -154,8 +154,10 @@ def _get_down_layer(self, in_channels: int, out_channels: int, strides: int, is_ strides: convolution stride. is_top: True if this is the top block. """ + mod: nn.Module if self.num_res_units > 0: - return ResidualUnit( + + mod = ResidualUnit( self.dimensions, in_channels, out_channels, @@ -167,7 +169,7 @@ def _get_down_layer(self, in_channels: int, out_channels: int, strides: int, is_ dropout=self.dropout, bias=self.bias, ) - return Convolution( + mod = Convolution( self.dimensions, in_channels, out_channels, @@ -178,6 +180,7 @@ def _get_down_layer(self, in_channels: int, out_channels: int, strides: int, is_ dropout=self.dropout, bias=self.bias, ) + return mod def _get_bottom_layer(self, in_channels: int, out_channels: int) -> nn.Module: """ diff --git a/monai/transforms/intensity/array.py b/monai/transforms/intensity/array.py index 20d306be04..de0c89e7b0 100644 --- a/monai/transforms/intensity/array.py +++ b/monai/transforms/intensity/array.py @@ -1318,7 +1318,7 @@ def __call__(self, img: Union[np.ndarray, torch.Tensor]) -> Union[torch.Tensor, # map back img = self.inv_shift_fourier(k, n_dims) - return img if self.as_tensor_output else img.cpu().detach().numpy() + return img if self.as_tensor_output else img.cpu().detach().numpy() # type: ignore def _apply_mask(self, k: torch.Tensor) -> torch.Tensor: """Builds and applies a mask on the spatial dimensions. @@ -1448,7 +1448,7 @@ def __call__(self, img: Union[np.ndarray, torch.Tensor]) -> Union[torch.Tensor, k = torch.exp(log_abs) * torch.exp(1j * phase) img = self.inv_shift_fourier(k, n_dims) - return img if self.as_tensor_output else img.cpu().detach().numpy() + return img if self.as_tensor_output else img.cpu().detach().numpy() # type: ignore def _check_indices(self, img) -> None: """Helper method to check consistency of self.loc and input image. From 12d30a8da66b0c938f7c291e2cb4e1f5d4d5f4d7 Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 17:11:08 +0100 Subject: [PATCH 5/9] update doc Signed-off-by: Wenqi Li --- monai/utils/deprecated.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monai/utils/deprecated.py b/monai/utils/deprecated.py index 7c330ce51b..0d3b8afdaf 100644 --- a/monai/utils/deprecated.py +++ b/monai/utils/deprecated.py @@ -131,6 +131,8 @@ def deprecated_arg( using the Sphinx directives such as `.. versionchanged:: version` and `.. deprecated:: version`. https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-versionadded + In the current implementation type annotations are not preserved. + Args: name: name of position or keyword argument to mark as deprecated. @@ -141,7 +143,7 @@ def deprecated_arg( new_name: name of position or keyword argument to replace the deprecated argument. Returns: - Decorated callable which warns or raises exception when deprecated argument used + Decorated callable which warns or raises exception when deprecated argument used. """ if since is not None and removed is not None and not version_leq(since, removed): raise ValueError(f"since must be less or equal to removed, got since={since}, removed={removed}.") From 3d51665b16a4271aac86d7cea94a0ab217628b0b Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 17:42:56 +0100 Subject: [PATCH 6/9] fixes an issue of version_leq('0+unknown', since) Signed-off-by: Wenqi Li --- monai/utils/deprecated.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/monai/utils/deprecated.py b/monai/utils/deprecated.py index 0d3b8afdaf..49606566b7 100644 --- a/monai/utils/deprecated.py +++ b/monai/utils/deprecated.py @@ -60,6 +60,9 @@ def deprecated( Decorated definition which warns or raises exception when used """ + if version_val == "0+unknown": + # version unknown, set version_val to a large value (assuming the latest version) + version_val = "100" if since is not None and removed is not None and not version_leq(since, removed): raise ValueError(f"since must be less or equal to removed, got since={since}, removed={removed}.") is_not_yet_deprecated = since is not None and version_val != since and version_leq(version_val, since) @@ -145,13 +148,16 @@ def deprecated_arg( Returns: Decorated callable which warns or raises exception when deprecated argument used. """ + + if version_val == "0+unknown": + # version unknown, set version_val to a large value (assuming the latest version) + version_val = "100" if since is not None and removed is not None and not version_leq(since, removed): raise ValueError(f"since must be less or equal to removed, got since={since}, removed={removed}.") is_not_yet_deprecated = since is not None and version_val != since and version_leq(version_val, since) if is_not_yet_deprecated: # smaller than `since`, do nothing return lambda obj: obj - if since is None and removed is None: # raise a DeprecatedError directly is_removed = True From 973c2977c3da0517bd64c8e425812b97ca8da24f Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 17:55:19 +0100 Subject: [PATCH 7/9] add unit tests Signed-off-by: Wenqi Li --- monai/utils/deprecated.py | 8 ++++---- tests/test_deprecated.py | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/monai/utils/deprecated.py b/monai/utils/deprecated.py index 49606566b7..36a6c03986 100644 --- a/monai/utils/deprecated.py +++ b/monai/utils/deprecated.py @@ -60,9 +60,9 @@ def deprecated( Decorated definition which warns or raises exception when used """ - if version_val == "0+unknown": - # version unknown, set version_val to a large value (assuming the latest version) - version_val = "100" + # if version_val.startswith("0+"): + # # version unknown, set version_val to a large value (assuming the latest version) + # version_val = "100" if since is not None and removed is not None and not version_leq(since, removed): raise ValueError(f"since must be less or equal to removed, got since={since}, removed={removed}.") is_not_yet_deprecated = since is not None and version_val != since and version_leq(version_val, since) @@ -149,7 +149,7 @@ def deprecated_arg( Decorated callable which warns or raises exception when deprecated argument used. """ - if version_val == "0+unknown": + if version_val.startswith("0+"): # version unknown, set version_val to a large value (assuming the latest version) version_val = "100" if since is not None and removed is not None and not version_leq(since, removed): diff --git a/tests/test_deprecated.py b/tests/test_deprecated.py index 4cd02555c7..04f8173282 100644 --- a/tests/test_deprecated.py +++ b/tests/test_deprecated.py @@ -223,6 +223,30 @@ def future1(): self.assertEqual(aw.warning.args[0], "fake warning") + def test_arg_except2_unknown(self): + """ + Test deprecated_arg decorator raises exception with `removed` set in the past. + with unknown version + """ + + @deprecated_arg("b", removed=self.prev_version, version_val="0+untagged.1.g3131155") + def afoo4(a, b=None): + pass + + self.assertRaises(DeprecatedError, lambda: afoo4(1, b=2)) + + def test_replacement_arg(self): + """ + Test deprecated arg being replaced. + """ + + @deprecated_arg("b", new_name="a", since=self.prev_version, version_val=self.test_version) + def afoo4(a, b=None): + return a + + self.assertEqual(afoo4(b=2), 2) + # self.assertRaises(DeprecatedError, lambda: afoo4(1, b=2)) + if __name__ == "__main__": unittest.main() From 82d5fb89122eafb77b61d0dbe2719fef387bb37d Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 18:54:10 +0100 Subject: [PATCH 8/9] fixes typo Signed-off-by: Wenqi Li --- monai/networks/nets/unet.py | 1 + 1 file changed, 1 insertion(+) diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py index a7018a29a7..1dd52455d9 100644 --- a/monai/networks/nets/unet.py +++ b/monai/networks/nets/unet.py @@ -169,6 +169,7 @@ def _get_down_layer(self, in_channels: int, out_channels: int, strides: int, is_ dropout=self.dropout, bias=self.bias, ) + return mod mod = Convolution( self.dimensions, in_channels, From 661159b5f5f1e6209bdf2b951cf346afbb88aafa Mon Sep 17 00:00:00 2001 From: Wenqi Li Date: Tue, 7 Sep 2021 20:02:23 +0100 Subject: [PATCH 9/9] resolves refs/pull versions Signed-off-by: Wenqi Li --- monai/utils/deprecated.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/utils/deprecated.py b/monai/utils/deprecated.py index 36a6c03986..c66b60996b 100644 --- a/monai/utils/deprecated.py +++ b/monai/utils/deprecated.py @@ -149,7 +149,7 @@ def deprecated_arg( Decorated callable which warns or raises exception when deprecated argument used. """ - if version_val.startswith("0+"): + if version_val.startswith("0+") or not f"{version_val}".strip()[0].isdigit(): # version unknown, set version_val to a large value (assuming the latest version) version_val = "100" if since is not None and removed is not None and not version_leq(since, removed):