Project-MONAI / MONAI

AI Toolkit for Healthcare Imaging
https://monai.io/
Apache License 2.0
5.72k stars 1.04k forks source link

Issue with stride lengths in MONAI's implementation of AttentionUNet #5968

Closed ClarkQTIM closed 1 year ago

ClarkQTIM commented 1 year ago

Describe the bug Simply put, it seems no matter what is used for the stride parameter in MONAI's implementation of AttentionUNet (https://docs.monai.io/en/stable/networks.html#attentionunet), one will either get an output of 'tuple index out of range' if the number of stride lengths provided is less than the length of the channel parameter minus 1 or 'expected stride to be a single integer value or a list of 1 values to match the convolution dimensions, but got stride=[2, 2]', where the value (in this case, 2) depends on what value you put in the list, if you have a list of the correct size.

For example, if the channels is (8, 16, 32, 64, 128) and the strides is (2, 2, 2, 2), it will produce this error. Interestingly, this error only appears in MONAI version 1.1.0, as in 1.0.0, it worked as I expected it would.

To Reproduce The following should reproduce the error:

from monai.networks.nets import AttentionUnet
from torchsummary import summary

def build_AttentionUNet(spatial_dimensions, num_in_channels, num_out_channels, img_height, img_width, num_channels, stride_lens, kernel_size, upsample_kernels_size, dropout_pct, device, model_print):
    model = AttentionUnet(
                spatial_dims = spatial_dimensions,
                in_channels = num_in_channels,
                out_channels = num_out_channels,
                channels = num_channels,
                strides = stride_lens,
                kernel_size = kernel_size,
                up_kernel_size = upsample_kernels_size,
                dropout = dropout_pct
            ).to(device)

    if model_print:
        print(model)
        print(summary(model, (num_in_channels, img_height, img_width)))

    return model

spatial_dimensions = 2
num_in_channels = 3
num_out_channels = 3
num_channels = (8, 16, 32, 64, 128)
stride_lens = (2, 2, 2, 2)
kernel = 3,
upsample_kernel_size = 3,
dropout_pct = 0.5

model_AttentionUNet = build_AttentionUNet(spatial_dimensions, 
num_in_channels, 
num_out_channels, 
512, 
512, 
num_channels, 
stride_lens, 
kernel,
upsample_kernel_size,
dropout_pct, 
device, 
True)

The error


RuntimeError                              Traceback (most recent call last)
Cell In [42], line 3
      1 # UNet Model
----> 3 model_AttentionUNet = build_AttentionUNet(spatial_dimensions, 
      4 num_in_channels, 
      5 num_out_channels, 
      6 512, 
      7 512, 
      8 num_channels, 
      9 stride_lens, 
     10 kernel,
     11 upsample_kernel_size,
     12 dropout_pct, 
     13 device, 
     14 True)

File ~/Documents/AI_in_Medicine/Fundus Segmentation/training_functions.py:78, in build_AttentionUNet(spatial_dimensions, num_in_channels, num_out_channels, img_height, img_width, num_channels, stride_lens, kernel_size, upsample_kernels_size, dropout_pct, device, model_print)
     76 if model_print:
     77     print(model)
---> 78     print(summary(model, (num_in_channels, img_height, img_width)))
     80 return model

File ~/.local/lib/python3.10/site-packages/torchsummary/torchsummary.py:72, in summary(model, input_size, batch_size, device)
     68 model.apply(register_hook)
...
--> 950 return F.conv_transpose2d(
    951     input, self.weight, self.bias, self.stride, self.padding,
    952     output_padding, self.groups, self.dilation)

RuntimeError: expected stride to be a single integer value or a list of 1 values to match the convolution dimensions, but got stride=[2, 2]

Expected behavior I expected this would not bring up a stride error. With 1.0.0, it did not, but with 1.1.0, it does. Playing with the strides parameter as a single integer value or a list with a single (or multiple) values does not seem to change this.

Screenshots If applicable, add screenshots to help explain your problem.

Environment

Ensuring you use the relevant python executable, please paste the output of:

python -c 'import monai; monai.config.print_debug_info()'

Output of the command:


================================
Printing MONAI config...
================================
MONAI version: 1.1.0
Numpy version: 1.23.4
Pytorch version: 1.12.1+cu113
MONAI flags: HAS_EXT = False, USE_COMPILED = False, USE_META_DICT = False
MONAI rev id: a2ec3752f54bfc3b40e7952234fbeb5452ed63e3
MONAI __file__: /home/clachris/.local/lib/python3.10/site-packages/monai/__init__.py

Optional dependencies:
Pytorch Ignite version: NOT INSTALLED or UNKNOWN VERSION.
Nibabel version: 5.0.0
scikit-image version: 0.19.3
Pillow version: 9.0.1
Tensorboard version: 2.10.1
gdown version: NOT INSTALLED or UNKNOWN VERSION.
TorchVision version: 0.13.1+cu102
tqdm version: 4.64.1
lmdb version: NOT INSTALLED or UNKNOWN VERSION.
psutil version: 5.9.3
pandas version: 1.5.1
einops version: NOT INSTALLED or UNKNOWN VERSION.
transformers version: NOT INSTALLED or UNKNOWN VERSION.
mlflow version: NOT INSTALLED or UNKNOWN VERSION.
pynrrd version: NOT INSTALLED or UNKNOWN VERSION.

For details about installing the optional dependencies, please visit:
    https://docs.monai.io/en/latest/installation.html#installing-the-recommended-dependencies

================================
Printing system config...
================================
System: Linux
Linux version: Ubuntu 22.04.1 LTS
Platform: Linux-5.15.0-58-generic-x86_64-with-glibc2.35
Processor: x86_64
Machine: x86_64
Python version: 3.10.6
Process name: python3
Command: ['python3', '-c', 'import monai; monai.config.print_debug_info()']
Open files: []
Num physical CPUs: 8
Num logical CPUs: 16
Num usable CPUs: 16
CPU usage (%): [13.1, 7.8, 7.9, 8.7, 7.9, 7.8, 8.7, 7.0, 7.9, 7.9, 9.8, 59.4, 48.0, 8.8, 6.9, 8.7]
CPU freq. (MHz): 1697
Load avg. in last 1, 5, 15 mins (%): [1.3, 2.4, 2.6]
Disk usage (%): 24.6
Avg. sensor temp. (Celsius): UNKNOWN for given OS
Total physical memory (GB): 30.6
Available memory (GB): 18.2
Used memory (GB): 11.7

================================
Printing GPU config...
================================
Num GPUs: 1
Has CUDA: True
CUDA version: 11.3
cuDNN enabled: True
cuDNN version: 8302
Current device: 0
Library compiled for CUDA architectures: ['sm_37', 'sm_50', 'sm_60', 'sm_70', 'sm_75', 'sm_80', 'sm_86']
GPU 0 Name: NVIDIA GeForce RTX 3080 Ti Laptop GPU
GPU 0 Is integrated: False
GPU 0 Is multi GPU board: False
GPU 0 Multi processor count: 58
GPU 0 Total memory (GB): 15.7
GPU 0 CUDA capability (maj.min): 8.6

Additional context I appreciate the support.

KumoLiu commented 1 year ago

Hi @ClarkQTIM, after a deep look at your code, I find that the comma following the upsample_kernel_size parameter is the actual cause of the issue. It assumes upsample_kernel_size as (3, ). You could simply set upsample_kernel_size=3 or upsample_kernel_size=(3).

In addition, the reason why it didn't happen in 1.0.0 is that the version at that time had these parameters hard-coded. https://github.com/Project-MONAI/MONAI/blob/170093375ce29267e45681fcec09dfa856e1d7e7/monai/networks/nets/attentionunet.py#L151 Hope it can help you. Thanks!