We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Basis UNet
On what paper is your UNet based?
The original 2D seems to differ quite a lot from the 3D U-Net by Özgün Çiçek which I'd like to use. 

Thanks.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `monai/networks/nets/unet.py`
Content:
```
1 # Copyright 2020 MONAI Consortium
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
5 #     http://www.apache.org/licenses/LICENSE-2.0
6 # Unless required by applicable law or agreed to in writing, software
7 # distributed under the License is distributed on an "AS IS" BASIS,
8 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 # See the License for the specific language governing permissions and
10 # limitations under the License.
11 
12 from typing import Sequence, Union
13 
14 import torch
15 import torch.nn as nn
16 
17 from monai.networks.blocks.convolutions import Convolution, ResidualUnit
18 from monai.networks.layers.factories import Act, Norm
19 from monai.networks.layers.simplelayers import SkipConnection
20 from monai.utils import alias, export
21 
22 
23 @export("monai.networks.nets")
24 @alias("Unet")
25 class UNet(nn.Module):
26     def __init__(
27         self,
28         dimensions: int,
29         in_channels: int,
30         out_channels: int,
31         channels: Sequence[int],
32         strides: Sequence[int],
33         kernel_size: Union[Sequence[int], int] = 3,
34         up_kernel_size: Union[Sequence[int], int] = 3,
35         num_res_units: int = 0,
36         act=Act.PRELU,
37         norm=Norm.INSTANCE,
38         dropout=0,
39     ) -> None:
40         """
41         Args:
42             dimensions: number of spatial dimensions.
43             in_channels: number of input channels.
44             out_channels: number of output channels.
45             channels: sequence of channels. Top block first.
46             strides: convolution stride.
47             kernel_size: convolution kernel size. Defaults to 3.
48             up_kernel_size: upsampling convolution kernel size. Defaults to 3.
49             num_res_units: number of residual units. Defaults to 0.
50             act: activation type and arguments. Defaults to PReLU.
51             norm: feature normalization type and arguments. Defaults to instance norm.
52             dropout: dropout ratio. Defaults to no dropout.
53         """
54         super().__init__()
55 
56         self.dimensions = dimensions
57         self.in_channels = in_channels
58         self.out_channels = out_channels
59         self.channels = channels
60         self.strides = strides
61         self.kernel_size = kernel_size
62         self.up_kernel_size = up_kernel_size
63         self.num_res_units = num_res_units
64         self.act = act
65         self.norm = norm
66         self.dropout = dropout
67 
68         def _create_block(
69             inc: int, outc: int, channels: Sequence[int], strides: Sequence[int], is_top: bool
70         ) -> nn.Sequential:
71             """
72             Builds the UNet structure from the bottom up by recursing down to the bottom block, then creating sequential
73             blocks containing the downsample path, a skip connection around the previous block, and the upsample path.
74 
75             Args:
76                 inc: number of input channels.
77                 outc: number of output channels.
78                 channels: sequence of channels. Top block first.
79                 strides: convolution stride.
80                 is_top: True if this is the top block.
81             """
82             c = channels[0]
83             s = strides[0]
84 
85             subblock: Union[nn.Sequential, ResidualUnit, Convolution]
86 
87             if len(channels) > 2:
88                 subblock = _create_block(c, c, channels[1:], strides[1:], False)  # continue recursion down
89                 upc = c * 2
90             else:
91                 # the next layer is the bottom so stop recursion, create the bottom layer as the sublock for this layer
92                 subblock = self._get_bottom_layer(c, channels[1])
93                 upc = c + channels[1]
94 
95             down = self._get_down_layer(inc, c, s, is_top)  # create layer in downsampling path
96             up = self._get_up_layer(upc, outc, s, is_top)  # create layer in upsampling path
97 
98             return nn.Sequential(down, SkipConnection(subblock), up)
99 
100         self.model = _create_block(in_channels, out_channels, self.channels, self.strides, True)
101 
102     def _get_down_layer(
103         self, in_channels: int, out_channels: int, strides: int, is_top: bool
104     ) -> Union[ResidualUnit, Convolution]:
105         """
106         Args:
107             in_channels: number of input channels.
108             out_channels: number of output channels.
109             strides: convolution stride.
110             is_top: True if this is the top block.
111         """
112         if self.num_res_units > 0:
113             return ResidualUnit(
114                 self.dimensions,
115                 in_channels,
116                 out_channels,
117                 strides=strides,
118                 kernel_size=self.kernel_size,
119                 subunits=self.num_res_units,
120                 act=self.act,
121                 norm=self.norm,
122                 dropout=self.dropout,
123             )
124         else:
125             return Convolution(
126                 self.dimensions,
127                 in_channels,
128                 out_channels,
129                 strides=strides,
130                 kernel_size=self.kernel_size,
131                 act=self.act,
132                 norm=self.norm,
133                 dropout=self.dropout,
134             )
135 
136     def _get_bottom_layer(self, in_channels: int, out_channels: int) -> Union[ResidualUnit, Convolution]:
137         """
138         Args:
139             in_channels: number of input channels.
140             out_channels: number of output channels.
141         """
142         return self._get_down_layer(in_channels, out_channels, 1, False)
143 
144     def _get_up_layer(
145         self, in_channels: int, out_channels: int, strides: int, is_top: bool
146     ) -> Union[Convolution, nn.Sequential]:
147         """
148         Args:
149             in_channels: number of input channels.
150             out_channels: number of output channels.
151             strides: convolution stride.
152             is_top: True if this is the top block.
153         """
154         conv: Union[Convolution, nn.Sequential]
155 
156         conv = Convolution(
157             self.dimensions,
158             in_channels,
159             out_channels,
160             strides=strides,
161             kernel_size=self.up_kernel_size,
162             act=self.act,
163             norm=self.norm,
164             dropout=self.dropout,
165             conv_only=is_top and self.num_res_units == 0,
166             is_transposed=True,
167         )
168 
169         if self.num_res_units > 0:
170             ru = ResidualUnit(
171                 self.dimensions,
172                 out_channels,
173                 out_channels,
174                 strides=1,
175                 kernel_size=self.kernel_size,
176                 subunits=1,
177                 act=self.act,
178                 norm=self.norm,
179                 dropout=self.dropout,
180                 last_conv_only=is_top,
181             )
182             conv = nn.Sequential(conv, ru)
183 
184         return conv
185 
186     def forward(self, x: torch.Tensor) -> torch.Tensor:
187         x = self.model(x)
188         return x
189 
190 
191 Unet = unet = UNet
192
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py
--- a/monai/networks/nets/unet.py
+++ b/monai/networks/nets/unet.py
@@ -38,6 +38,11 @@
         dropout=0,
     ) -> None:
         """
+        Enhanced version of UNet which has residual units implemented with the ResidualUnit class.
+        The residual part uses a convolution to change the input dimensions to match the output dimensions
+        if this is necessary but will use nn.Identity if not.
+        Refer to: https://link.springer.com/chapter/10.1007/978-3-030-12029-0_40.
+
         Args:
             dimensions: number of spatial dimensions.
             in_channels: number of input channels.

{"golden_diff": "diff --git a/monai/networks/nets/unet.py b/monai/networks/nets/unet.py\n--- a/monai/networks/nets/unet.py\n+++ b/monai/networks/nets/unet.py\n@@ -38,6 +38,11 @@\n         dropout=0,\n     ) -> None:\n         \"\"\"\n+        Enhanced version of UNet which has residual units implemented with the ResidualUnit class.\n+        The residual part uses a convolution to change the input dimensions to match the output dimensions\n+        if this is necessary but will use nn.Identity if not.\n+        Refer to: https://link.springer.com/chapter/10.1007/978-3-030-12029-0_40.\n+\n         Args:\n             dimensions: number of spatial dimensions.\n             in_channels: number of input channels.\n", "issue": "Basis UNet\nOn what paper is your UNet based?\r\nThe original 2D seems to differ quite a lot from the 3D U-Net by \u00d6zg\u00fcn \u00c7i\u00e7ek which I'd like to use. \r\n\r\nThanks.\n", "before_files": [{"content": "# Copyright 2020 MONAI Consortium\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#     http://www.apache.org/licenses/LICENSE-2.0\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import Sequence, Union\n\nimport torch\nimport torch.nn as nn\n\nfrom monai.networks.blocks.convolutions import Convolution, ResidualUnit\nfrom monai.networks.layers.factories import Act, Norm\nfrom monai.networks.layers.simplelayers import SkipConnection\nfrom monai.utils import alias, export\n\n\n@export(\"monai.networks.nets\")\n@alias(\"Unet\")\nclass UNet(nn.Module):\n    def __init__(\n        self,\n        dimensions: int,\n        in_channels: int,\n        out_channels: int,\n        channels: Sequence[int],\n        strides: Sequence[int],\n        kernel_size: Union[Sequence[int], int] = 3,\n        up_kernel_size: Union[Sequence[int], int] = 3,\n        num_res_units: int = 0,\n        act=Act.PRELU,\n        norm=Norm.INSTANCE,\n        dropout=0,\n    ) -> None:\n        \"\"\"\n        Args:\n            dimensions: number of spatial dimensions.\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n            channels: sequence of channels. Top block first.\n            strides: convolution stride.\n            kernel_size: convolution kernel size. Defaults to 3.\n            up_kernel_size: upsampling convolution kernel size. Defaults to 3.\n            num_res_units: number of residual units. Defaults to 0.\n            act: activation type and arguments. Defaults to PReLU.\n            norm: feature normalization type and arguments. Defaults to instance norm.\n            dropout: dropout ratio. Defaults to no dropout.\n        \"\"\"\n        super().__init__()\n\n        self.dimensions = dimensions\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.channels = channels\n        self.strides = strides\n        self.kernel_size = kernel_size\n        self.up_kernel_size = up_kernel_size\n        self.num_res_units = num_res_units\n        self.act = act\n        self.norm = norm\n        self.dropout = dropout\n\n        def _create_block(\n            inc: int, outc: int, channels: Sequence[int], strides: Sequence[int], is_top: bool\n        ) -> nn.Sequential:\n            \"\"\"\n            Builds the UNet structure from the bottom up by recursing down to the bottom block, then creating sequential\n            blocks containing the downsample path, a skip connection around the previous block, and the upsample path.\n\n            Args:\n                inc: number of input channels.\n                outc: number of output channels.\n                channels: sequence of channels. Top block first.\n                strides: convolution stride.\n                is_top: True if this is the top block.\n            \"\"\"\n            c = channels[0]\n            s = strides[0]\n\n            subblock: Union[nn.Sequential, ResidualUnit, Convolution]\n\n            if len(channels) > 2:\n                subblock = _create_block(c, c, channels[1:], strides[1:], False)  # continue recursion down\n                upc = c * 2\n            else:\n                # the next layer is the bottom so stop recursion, create the bottom layer as the sublock for this layer\n                subblock = self._get_bottom_layer(c, channels[1])\n                upc = c + channels[1]\n\n            down = self._get_down_layer(inc, c, s, is_top)  # create layer in downsampling path\n            up = self._get_up_layer(upc, outc, s, is_top)  # create layer in upsampling path\n\n            return nn.Sequential(down, SkipConnection(subblock), up)\n\n        self.model = _create_block(in_channels, out_channels, self.channels, self.strides, True)\n\n    def _get_down_layer(\n        self, in_channels: int, out_channels: int, strides: int, is_top: bool\n    ) -> Union[ResidualUnit, Convolution]:\n        \"\"\"\n        Args:\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n            strides: convolution stride.\n            is_top: True if this is the top block.\n        \"\"\"\n        if self.num_res_units > 0:\n            return ResidualUnit(\n                self.dimensions,\n                in_channels,\n                out_channels,\n                strides=strides,\n                kernel_size=self.kernel_size,\n                subunits=self.num_res_units,\n                act=self.act,\n                norm=self.norm,\n                dropout=self.dropout,\n            )\n        else:\n            return Convolution(\n                self.dimensions,\n                in_channels,\n                out_channels,\n                strides=strides,\n                kernel_size=self.kernel_size,\n                act=self.act,\n                norm=self.norm,\n                dropout=self.dropout,\n            )\n\n    def _get_bottom_layer(self, in_channels: int, out_channels: int) -> Union[ResidualUnit, Convolution]:\n        \"\"\"\n        Args:\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n        \"\"\"\n        return self._get_down_layer(in_channels, out_channels, 1, False)\n\n    def _get_up_layer(\n        self, in_channels: int, out_channels: int, strides: int, is_top: bool\n    ) -> Union[Convolution, nn.Sequential]:\n        \"\"\"\n        Args:\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n            strides: convolution stride.\n            is_top: True if this is the top block.\n        \"\"\"\n        conv: Union[Convolution, nn.Sequential]\n\n        conv = Convolution(\n            self.dimensions,\n            in_channels,\n            out_channels,\n            strides=strides,\n            kernel_size=self.up_kernel_size,\n            act=self.act,\n            norm=self.norm,\n            dropout=self.dropout,\n            conv_only=is_top and self.num_res_units == 0,\n            is_transposed=True,\n        )\n\n        if self.num_res_units > 0:\n            ru = ResidualUnit(\n                self.dimensions,\n                out_channels,\n                out_channels,\n                strides=1,\n                kernel_size=self.kernel_size,\n                subunits=1,\n                act=self.act,\n                norm=self.norm,\n                dropout=self.dropout,\n                last_conv_only=is_top,\n            )\n            conv = nn.Sequential(conv, ru)\n\n        return conv\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        x = self.model(x)\n        return x\n\n\nUnet = unet = UNet\n", "path": "monai/networks/nets/unet.py"}], "after_files": [{"content": "# Copyright 2020 MONAI Consortium\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#     http://www.apache.org/licenses/LICENSE-2.0\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import Sequence, Union\n\nimport torch\nimport torch.nn as nn\n\nfrom monai.networks.blocks.convolutions import Convolution, ResidualUnit\nfrom monai.networks.layers.factories import Act, Norm\nfrom monai.networks.layers.simplelayers import SkipConnection\nfrom monai.utils import alias, export\n\n\n@export(\"monai.networks.nets\")\n@alias(\"Unet\")\nclass UNet(nn.Module):\n    def __init__(\n        self,\n        dimensions: int,\n        in_channels: int,\n        out_channels: int,\n        channels: Sequence[int],\n        strides: Sequence[int],\n        kernel_size: Union[Sequence[int], int] = 3,\n        up_kernel_size: Union[Sequence[int], int] = 3,\n        num_res_units: int = 0,\n        act=Act.PRELU,\n        norm=Norm.INSTANCE,\n        dropout=0,\n    ) -> None:\n        \"\"\"\n        Enhanced version of UNet which has residual units implemented with the ResidualUnit class.\n        The residual part uses a convolution to change the input dimensions to match the output dimensions\n        if this is necessary but will use nn.Identity if not.\n        Refer to: https://link.springer.com/chapter/10.1007/978-3-030-12029-0_40.\n\n        Args:\n            dimensions: number of spatial dimensions.\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n            channels: sequence of channels. Top block first.\n            strides: convolution stride.\n            kernel_size: convolution kernel size. Defaults to 3.\n            up_kernel_size: upsampling convolution kernel size. Defaults to 3.\n            num_res_units: number of residual units. Defaults to 0.\n            act: activation type and arguments. Defaults to PReLU.\n            norm: feature normalization type and arguments. Defaults to instance norm.\n            dropout: dropout ratio. Defaults to no dropout.\n        \"\"\"\n        super().__init__()\n\n        self.dimensions = dimensions\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.channels = channels\n        self.strides = strides\n        self.kernel_size = kernel_size\n        self.up_kernel_size = up_kernel_size\n        self.num_res_units = num_res_units\n        self.act = act\n        self.norm = norm\n        self.dropout = dropout\n\n        def _create_block(\n            inc: int, outc: int, channels: Sequence[int], strides: Sequence[int], is_top: bool\n        ) -> nn.Sequential:\n            \"\"\"\n            Builds the UNet structure from the bottom up by recursing down to the bottom block, then creating sequential\n            blocks containing the downsample path, a skip connection around the previous block, and the upsample path.\n\n            Args:\n                inc: number of input channels.\n                outc: number of output channels.\n                channels: sequence of channels. Top block first.\n                strides: convolution stride.\n                is_top: True if this is the top block.\n            \"\"\"\n            c = channels[0]\n            s = strides[0]\n\n            subblock: Union[nn.Sequential, ResidualUnit, Convolution]\n\n            if len(channels) > 2:\n                subblock = _create_block(c, c, channels[1:], strides[1:], False)  # continue recursion down\n                upc = c * 2\n            else:\n                # the next layer is the bottom so stop recursion, create the bottom layer as the sublock for this layer\n                subblock = self._get_bottom_layer(c, channels[1])\n                upc = c + channels[1]\n\n            down = self._get_down_layer(inc, c, s, is_top)  # create layer in downsampling path\n            up = self._get_up_layer(upc, outc, s, is_top)  # create layer in upsampling path\n\n            return nn.Sequential(down, SkipConnection(subblock), up)\n\n        self.model = _create_block(in_channels, out_channels, self.channels, self.strides, True)\n\n    def _get_down_layer(\n        self, in_channels: int, out_channels: int, strides: int, is_top: bool\n    ) -> Union[ResidualUnit, Convolution]:\n        \"\"\"\n        Args:\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n            strides: convolution stride.\n            is_top: True if this is the top block.\n        \"\"\"\n        if self.num_res_units > 0:\n            return ResidualUnit(\n                self.dimensions,\n                in_channels,\n                out_channels,\n                strides=strides,\n                kernel_size=self.kernel_size,\n                subunits=self.num_res_units,\n                act=self.act,\n                norm=self.norm,\n                dropout=self.dropout,\n            )\n        else:\n            return Convolution(\n                self.dimensions,\n                in_channels,\n                out_channels,\n                strides=strides,\n                kernel_size=self.kernel_size,\n                act=self.act,\n                norm=self.norm,\n                dropout=self.dropout,\n            )\n\n    def _get_bottom_layer(self, in_channels: int, out_channels: int) -> Union[ResidualUnit, Convolution]:\n        \"\"\"\n        Args:\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n        \"\"\"\n        return self._get_down_layer(in_channels, out_channels, 1, False)\n\n    def _get_up_layer(\n        self, in_channels: int, out_channels: int, strides: int, is_top: bool\n    ) -> Union[Convolution, nn.Sequential]:\n        \"\"\"\n        Args:\n            in_channels: number of input channels.\n            out_channels: number of output channels.\n            strides: convolution stride.\n            is_top: True if this is the top block.\n        \"\"\"\n        conv: Union[Convolution, nn.Sequential]\n\n        conv = Convolution(\n            self.dimensions,\n            in_channels,\n            out_channels,\n            strides=strides,\n            kernel_size=self.up_kernel_size,\n            act=self.act,\n            norm=self.norm,\n            dropout=self.dropout,\n            conv_only=is_top and self.num_res_units == 0,\n            is_transposed=True,\n        )\n\n        if self.num_res_units > 0:\n            ru = ResidualUnit(\n                self.dimensions,\n                out_channels,\n                out_channels,\n                strides=1,\n                kernel_size=self.kernel_size,\n                subunits=1,\n                act=self.act,\n                norm=self.norm,\n                dropout=self.dropout,\n                last_conv_only=is_top,\n            )\n            conv = nn.Sequential(conv, ru)\n\n        return conv\n\n    def forward(self, x: torch.Tensor) -> torch.Tensor:\n        x = self.model(x)\n        return x\n\n\nUnet = unet = UNet\n", "path": "monai/networks/nets/unet.py"}]}