Repository: Project-MONAI/MONAI

Issue:
ResNet class does not respect argument feed_forward=False
**Describe the bug**
The ResNet class has a parameter `feed_forward` which allows skipping of the final dense layer if I intepret that correctly. A respective layer is only created if the parameter is set to True (see [here](https://github.com/Project-MONAI/MONAI/blob/bfa054b9c3064628a21f4c35bbe3132964e91f43/monai/networks/nets/resnet.py#L231)) but in the forward pass, there is no query for whether the layer actually exists [see here](https://github.com/Project-MONAI/MONAI/blob/bfa054b9c3064628a21f4c35bbe3132964e91f43/monai/networks/nets/resnet.py#L308).

**To Reproduce**
```python
import torch
from monai.networks.nets.resnet import resnet50

x = torch.ones((1, 1, 64, 64, 64))
model_monai = resnet50(spatial_dims=x.ndim-2, n_input_channels=x.shape[1], feed_forward=False)
print(model_monai)

# throws an error
y = model_monai(x)

```


**Expected behavior**
The ResNet class should not throw an error if `feed_forward=False`.



Discussion:

Resolving patch:
diff --git a/monai/networks/nets/resnet.py b/monai/networks/nets/resnet.py
--- a/monai/networks/nets/resnet.py
+++ b/monai/networks/nets/resnet.py
@@ -167,7 +167,8 @@ class ResNet(nn.Module):
             - 'A': using `self._downsample_basic_block`.
             - 'B': kernel_size 1 conv + norm.
         widen_factor: widen output for each layer.
-        num_classes: number of output (classifications)
+        num_classes: number of output (classifications).
+        feed_forward: whether to add the FC layer for the output, default to `True`.
 
     .. deprecated:: 0.6.0
         ``n_classes`` is deprecated, use ``num_classes`` instead.
@@ -227,9 +228,7 @@ def __init__(
         self.layer3 = self._make_layer(block, block_inplanes[2], layers[2], spatial_dims, shortcut_type, stride=2)
         self.layer4 = self._make_layer(block, block_inplanes[3], layers[3], spatial_dims, shortcut_type, stride=2)
         self.avgpool = avgp_type(block_avgpool[spatial_dims])
-
-        if feed_forward:
-            self.fc = nn.Linear(block_inplanes[3] * block.expansion, num_classes)
+        self.fc = nn.Linear(block_inplanes[3] * block.expansion, num_classes) if feed_forward else None
 
         for m in self.modules():
             if isinstance(m, conv_type):
@@ -301,7 +300,8 @@ def forward(self, x: torch.Tensor) -> torch.Tensor:
         x = self.avgpool(x)
 
         x = x.view(x.size(0), -1)
-        x = self.fc(x)
+        if self.fc is not None:
+            x = self.fc(x)
 
         return x
 


Test patch:
diff --git a/tests/test_resnet.py b/tests/test_resnet.py
--- a/tests/test_resnet.py
+++ b/tests/test_resnet.py
@@ -60,6 +60,12 @@
     (1, 3),
 ]
 
+TEST_CASE_4 = [  # 2D, batch 2, 1 input channel
+    {"pretrained": False, "spatial_dims": 2, "n_input_channels": 1, "num_classes": 3, "feed_forward": False},
+    (2, 1, 32, 64),
+    ((2, 512), (2, 2048)),
+]
+
 TEST_CASES = []
 for case in [TEST_CASE_1, TEST_CASE_2, TEST_CASE_3, TEST_CASE_2_A, TEST_CASE_3_A]:
     for model in [resnet10, resnet18, resnet34, resnet50, resnet101, resnet152, resnet200]:
@@ -76,7 +82,10 @@ def test_resnet_shape(self, model, input_param, input_shape, expected_shape):
         net = model(**input_param).to(device)
         with eval_mode(net):
             result = net.forward(torch.randn(input_shape).to(device))
-            self.assertEqual(result.shape, expected_shape)
+            if input_param.get("feed_forward", True):
+                self.assertEqual(result.shape, expected_shape)
+            else:
+                self.assertTrue(result.shape in expected_shape)
 
     @parameterized.expand(TEST_SCRIPT_CASES)
     def test_script(self, model, input_param, input_shape, expected_shape):