Repository: keras-team/keras-cv

Issue:
Refactor `ResNetV2Backbone` for readability
Our backbone modeling files are very large and hard to read. @LukeWood proposed two changes in #1745:

1. move aliases to their own file
2. move helpers below model declarations

#1745 provides a nice template for this change for `MobileNetBackbone`. Replicate this change for `keras_cv/models/backbones/resnet_v2/`.



Discussion:
jbischof: /gcbrun
jbischof: @ID6109 could you help us with a merge commit?
ID6109: > @ID6109 could you help us with a merge commit?

Done
jbischof: /gcbrun

Patch:
diff --git a/keras_cv/models/__init__.py b/keras_cv/models/__init__.py
index 933c7ff..3736d73 100644
--- a/keras_cv/models/__init__.py
+++ b/keras_cv/models/__init__.py
@@ -79,19 +79,19 @@ from keras_cv.models.backbones.resnet_v1.resnet_v1_aliases import (
 from keras_cv.models.backbones.resnet_v1.resnet_v1_backbone import (
     ResNetBackbone,
 )
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet18V2Backbone,
 )
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet34V2Backbone,
 )
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet50V2Backbone,
 )
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet101V2Backbone,
 )
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet152V2Backbone,
 )
 from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
diff --git a/keras_cv/models/backbones/resnet_v2/resnet_v2_aliases.py b/keras_cv/models/backbones/resnet_v2/resnet_v2_aliases.py
new file mode 100644
index 0000000..8d8cfad
--- /dev/null
+++ b/keras_cv/models/backbones/resnet_v2/resnet_v2_aliases.py
@@ -0,0 +1,236 @@
+# Copyright 2023 The KerasCV Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+import copy
+
+from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+    ResNetV2Backbone,
+)
+from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone_presets import (  # noqa: E501
+    backbone_presets,
+)
+from keras_cv.utils.python_utils import classproperty
+
+ALIAS_DOCSTRING = """ResNetV2Backbone model with {num_layers} layers.
+
+    Reference:
+        - [Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027) (ECCV 2016)
+
+    The difference in ResNet and ResNetV2 rests in the structure of their
+    individual building blocks. In ResNetV2, the batch normalization and
+    ReLU activation precede the convolution layers, as opposed to ResNetV1 where
+    the batch normalization and ReLU activation are applied after the
+    convolution layers.
+
+    For transfer learning use cases, make sure to read the
+    [guide to transfer learning & fine-tuning](https://keras.io/guides/transfer_learning/).
+
+    Args:
+        include_rescaling: bool, whether to rescale the inputs. If set
+            to `True`, inputs will be passed through a `Rescaling(1/255.0)`
+            layer.
+        input_shape: optional shape tuple, defaults to (None, None, 3).
+        input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
+            to use as image input for the model.
+
+    Examples:
+    ```python
+    input_data = tf.ones(shape=(8, 224, 224, 3))
+
+    # Randomly initialized backbone
+    model = ResNet{num_layers}V2Backbone()
+    output = model(input_data)
+    ```
+"""  # noqa: E501
+
+
+class ResNet18V2Backbone(ResNetV2Backbone):
+    def __new__(
+        cls,
+        include_rescaling=True,
+        input_shape=(None, None, 3),
+        input_tensor=None,
+        **kwargs,
+    ):
+        # Pack args in kwargs
+        kwargs.update(
+            {
+                "include_rescaling": include_rescaling,
+                "input_shape": input_shape,
+                "input_tensor": input_tensor,
+            }
+        )
+        return ResNetV2Backbone.from_preset("resnet18_v2", **kwargs)
+
+    @classproperty
+    def presets(cls):
+        """Dictionary of preset names and configurations."""
+        return {}
+
+    @classproperty
+    def presets_with_weights(cls):
+        """Dictionary of preset names and configurations that include
+        weights."""
+        return {}
+
+
+class ResNet34V2Backbone(ResNetV2Backbone):
+    def __new__(
+        cls,
+        include_rescaling=True,
+        input_shape=(None, None, 3),
+        input_tensor=None,
+        **kwargs,
+    ):
+        # Pack args in kwargs
+        kwargs.update(
+            {
+                "include_rescaling": include_rescaling,
+                "input_shape": input_shape,
+                "input_tensor": input_tensor,
+            }
+        )
+        return ResNetV2Backbone.from_preset("resnet34_v2", **kwargs)
+
+    @classproperty
+    def presets(cls):
+        """Dictionary of preset names and configurations."""
+        return {}
+
+    @classproperty
+    def presets_with_weights(cls):
+        """Dictionary of preset names and configurations that include
+        weights."""
+        return {}
+
+
+class ResNet50V2Backbone(ResNetV2Backbone):
+    def __new__(
+        cls,
+        include_rescaling=True,
+        input_shape=(None, None, 3),
+        input_tensor=None,
+        **kwargs,
+    ):
+        # Pack args in kwargs
+        kwargs.update(
+            {
+                "include_rescaling": include_rescaling,
+                "input_shape": input_shape,
+                "input_tensor": input_tensor,
+            }
+        )
+        return ResNetV2Backbone.from_preset("resnet50_v2", **kwargs)
+
+    @classproperty
+    def presets(cls):
+        """Dictionary of preset names and configurations."""
+        return {
+            "resnet50_v2_imagenet": copy.deepcopy(
+                backbone_presets["resnet50_v2_imagenet"]
+            ),
+        }
+
+    @classproperty
+    def presets_with_weights(cls):
+        """Dictionary of preset names and configurations that include
+        weights."""
+        return cls.presets
+
+
+class ResNet101V2Backbone(ResNetV2Backbone):
+    def __new__(
+        cls,
+        include_rescaling=True,
+        input_shape=(None, None, 3),
+        input_tensor=None,
+        **kwargs,
+    ):
+        # Pack args in kwargs
+        kwargs.update(
+            {
+                "include_rescaling": include_rescaling,
+                "input_shape": input_shape,
+                "input_tensor": input_tensor,
+            }
+        )
+        return ResNetV2Backbone.from_preset("resnet101_v2", **kwargs)
+
+    @classproperty
+    def presets(cls):
+        """Dictionary of preset names and configurations."""
+        return {}
+
+    @classproperty
+    def presets_with_weights(cls):
+        """Dictionary of preset names and configurations that include
+        weights."""
+        return {}
+
+
+class ResNet152V2Backbone(ResNetV2Backbone):
+    def __new__(
+        cls,
+        include_rescaling=True,
+        input_shape=(None, None, 3),
+        input_tensor=None,
+        **kwargs,
+    ):
+        # Pack args in kwargs
+        kwargs.update(
+            {
+                "include_rescaling": include_rescaling,
+                "input_shape": input_shape,
+                "input_tensor": input_tensor,
+            }
+        )
+        return ResNetV2Backbone.from_preset("resnet152_v2", **kwargs)
+
+    @classproperty
+    def presets(cls):
+        """Dictionary of preset names and configurations."""
+        return {}
+
+    @classproperty
+    def presets_with_weights(cls):
+        """Dictionary of preset names and configurations that include
+        weights."""
+        return {}
+
+
+setattr(
+    ResNet18V2Backbone,
+    "__doc__",
+    ALIAS_DOCSTRING.format(num_layers=18),
+)
+setattr(
+    ResNet34V2Backbone,
+    "__doc__",
+    ALIAS_DOCSTRING.format(num_layers=34),
+)
+setattr(
+    ResNet50V2Backbone,
+    "__doc__",
+    ALIAS_DOCSTRING.format(num_layers=50),
+)
+setattr(
+    ResNet101V2Backbone,
+    "__doc__",
+    ALIAS_DOCSTRING.format(num_layers=101),
+)
+setattr(
+    ResNet152V2Backbone,
+    "__doc__",
+    ALIAS_DOCSTRING.format(num_layers=152),
+)
diff --git a/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone.py b/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone.py
index e3e952d..eb6bd44 100644
--- a/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone.py
+++ b/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone.py
@@ -11,7 +11,7 @@
 # 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.
-"""ResNet models for Keras.
+"""ResNet backbone model.
 Reference:
   - [Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027) (ECCV 2016)
   - [Based on the original keras.applications ResNet](https://github.com/keras-team/keras/blob/master/keras/applications/resnet_v2.py)
@@ -37,6 +37,156 @@ BN_AXIS = 3
 BN_EPSILON = 1.001e-5
 
 
+@keras.utils.register_keras_serializable(package="keras_cv.models")
+class ResNetV2Backbone(Backbone):
+    """Instantiates the ResNetV2 architecture.
+
+    Reference:
+        - [Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027) (ECCV 2016)
+
+    The difference in Resnet and ResNetV2 rests in the structure of their
+    individual building blocks. In ResNetV2, the batch normalization and
+    ReLU activation precede the convolution layers, as opposed to ResNetV1 where
+    the batch normalization and ReLU activation are applied after the
+    convolution layers.
+
+    For transfer learning use cases, make sure to read the
+    [guide to transfer learning & fine-tuning](https://keras.io/guides/transfer_learning/).
+
+    Args:
+        stackwise_filters: list of ints, number of filters for each stack in
+            the model.
+        stackwise_blocks: list of ints, number of blocks for each stack in the
+            model.
+        stackwise_strides: list of ints, stride for each stack in the model.
+        include_rescaling: bool, whether to rescale the inputs. If set
+            to `True`, inputs will be passed through a `Rescaling(1/255.0)`
+            layer.
+        stackwise_dilations: list of ints, dilation for each stack in the
+            model. If `None` (default), dilation will not be used.
+        input_shape: optional shape tuple, defaults to (None, None, 3).
+        input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
+            to use as image input for the model.
+        block_type: string, one of "basic_block" or "block". The block type to
+            stack. Use "basic_block" for smaller models like ResNet18 and
+            ResNet34.
+
+    Examples:
+    ```python
+    input_data = tf.ones(shape=(8, 224, 224, 3))
+
+    # Pretrained backbone
+    model = keras_cv.models.ResNetV2Backbone.from_preset("resnet50_v2_imagenet")
+    output = model(input_data)
+
+    # Randomly initialized backbone with a custom config
+    model = ResNetV2Backbone(
+        stackwise_filters=[64, 128, 256, 512],
+        stackwise_blocks=[2, 2, 2, 2],
+        stackwise_strides=[1, 2, 2, 2],
+        include_rescaling=False,
+    )
+    output = model(input_data)
+    ```
+    """  # noqa: E501
+
+    def __init__(
+        self,
+        *,
+        stackwise_filters,
+        stackwise_blocks,
+        stackwise_strides,
+        include_rescaling,
+        stackwise_dilations=None,
+        input_shape=(None, None, 3),
+        input_tensor=None,
+        block_type="block",
+        **kwargs,
+    ):
+        inputs = utils.parse_model_inputs(input_shape, input_tensor)
+        x = inputs
+
+        if include_rescaling:
+            x = layers.Rescaling(1 / 255.0)(x)
+
+        x = layers.Conv2D(
+            64,
+            7,
+            strides=2,
+            use_bias=True,
+            padding="same",
+            name="conv1_conv",
+        )(x)
+
+        x = layers.MaxPooling2D(
+            3, strides=2, padding="same", name="pool1_pool"
+        )(x)
+
+        num_stacks = len(stackwise_filters)
+        if stackwise_dilations is None:
+            stackwise_dilations = [1] * num_stacks
+
+        pyramid_level_inputs = {}
+        for stack_index in range(num_stacks):
+            x = apply_stack(
+                x,
+                filters=stackwise_filters[stack_index],
+                blocks=stackwise_blocks[stack_index],
+                stride=stackwise_strides[stack_index],
+                dilations=stackwise_dilations[stack_index],
+                block_type=block_type,
+                first_shortcut=(block_type == "block" or stack_index > 0),
+                name=f"v2_stack_{stack_index}",
+            )
+            pyramid_level_inputs[f"P{stack_index + 2}"] = x.node.layer.name
+
+        x = layers.BatchNormalization(
+            axis=BN_AXIS, epsilon=BN_EPSILON, name="post_bn"
+        )(x)
+        x = layers.Activation("relu", name="post_relu")(x)
+
+        # Create model.
+        super().__init__(inputs=inputs, outputs=x, **kwargs)
+
+        # All references to `self` below this line
+        self.pyramid_level_inputs = pyramid_level_inputs
+        self.stackwise_filters = stackwise_filters
+        self.stackwise_blocks = stackwise_blocks
+        self.stackwise_strides = stackwise_strides
+        self.include_rescaling = include_rescaling
+        self.stackwise_dilations = stackwise_dilations
+        self.input_tensor = input_tensor
+        self.block_type = block_type
+
+    def get_config(self):
+        config = super().get_config()
+        config.update(
+            {
+                "stackwise_filters": self.stackwise_filters,
+                "stackwise_blocks": self.stackwise_blocks,
+                "stackwise_strides": self.stackwise_strides,
+                "include_rescaling": self.include_rescaling,
+                # Remove batch dimension from `input_shape`
+                "input_shape": self.input_shape[1:],
+                "stackwise_dilations": self.stackwise_dilations,
+                "input_tensor": self.input_tensor,
+                "block_type": self.block_type,
+            }
+        )
+        return config
+
+    @classproperty
+    def presets(cls):
+        """Dictionary of preset names and configurations."""
+        return copy.deepcopy(backbone_presets)
+
+    @classproperty
+    def presets_with_weights(cls):
+        """Dictionary of preset names and configurations that include
+        weights."""
+        return copy.deepcopy(backbone_presets_with_weights)
+
+
 def apply_basic_block(
     x,
     filters,
@@ -253,367 +403,3 @@ def apply_stack(
         name=name + "_block" + str(blocks),
     )
     return x
-
-
-@keras.utils.register_keras_serializable(package="keras_cv.models")
-class ResNetV2Backbone(Backbone):
-    """Instantiates the ResNetV2 architecture.
-
-    Reference:
-        - [Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027) (ECCV 2016)
-
-    The difference in Resnet and ResNetV2 rests in the structure of their
-    individual building blocks. In ResNetV2, the batch normalization and
-    ReLU activation precede the convolution layers, as opposed to ResNetV1 where
-    the batch normalization and ReLU activation are applied after the
-    convolution layers.
-
-    For transfer learning use cases, make sure to read the
-    [guide to transfer learning & fine-tuning](https://keras.io/guides/transfer_learning/).
-
-    Args:
-        stackwise_filters: list of ints, number of filters for each stack in
-            the model.
-        stackwise_blocks: list of ints, number of blocks for each stack in the
-            model.
-        stackwise_strides: list of ints, stride for each stack in the model.
-        include_rescaling: bool, whether to rescale the inputs. If set
-            to `True`, inputs will be passed through a `Rescaling(1/255.0)`
-            layer.
-        stackwise_dilations: list of ints, dilation for each stack in the
-            model. If `None` (default), dilation will not be used.
-        input_shape: optional shape tuple, defaults to (None, None, 3).
-        input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
-            to use as image input for the model.
-        block_type: string, one of "basic_block" or "block". The block type to
-            stack. Use "basic_block" for smaller models like ResNet18 and
-            ResNet34.
-
-    Examples:
-    ```python
-    input_data = tf.ones(shape=(8, 224, 224, 3))
-
-    # Pretrained backbone
-    model = keras_cv.models.ResNetV2Backbone.from_preset("resnet50_v2_imagenet")
-    output = model(input_data)
-
-    # Randomly initialized backbone with a custom config
-    model = ResNetV2Backbone(
-        stackwise_filters=[64, 128, 256, 512],
-        stackwise_blocks=[2, 2, 2, 2],
-        stackwise_strides=[1, 2, 2, 2],
-        include_rescaling=False,
-    )
-    output = model(input_data)
-    ```
-    """  # noqa: E501
-
-    def __init__(
-        self,
-        *,
-        stackwise_filters,
-        stackwise_blocks,
-        stackwise_strides,
-        include_rescaling,
-        stackwise_dilations=None,
-        input_shape=(None, None, 3),
-        input_tensor=None,
-        block_type="block",
-        **kwargs,
-    ):
-        inputs = utils.parse_model_inputs(input_shape, input_tensor)
-        x = inputs
-
-        if include_rescaling:
-            x = layers.Rescaling(1 / 255.0)(x)
-
-        x = layers.Conv2D(
-            64,
-            7,
-            strides=2,
-            use_bias=True,
-            padding="same",
-            name="conv1_conv",
-        )(x)
-
-        x = layers.MaxPooling2D(
-            3, strides=2, padding="same", name="pool1_pool"
-        )(x)
-
-        num_stacks = len(stackwise_filters)
-        if stackwise_dilations is None:
-            stackwise_dilations = [1] * num_stacks
-
-        pyramid_level_inputs = {}
-        for stack_index in range(num_stacks):
-            x = apply_stack(
-                x,
-                filters=stackwise_filters[stack_index],
-                blocks=stackwise_blocks[stack_index],
-                stride=stackwise_strides[stack_index],
-                dilations=stackwise_dilations[stack_index],
-                block_type=block_type,
-                first_shortcut=(block_type == "block" or stack_index > 0),
-                name=f"v2_stack_{stack_index}",
-            )
-            pyramid_level_inputs[f"P{stack_index + 2}"] = x.node.layer.name
-
-        x = layers.BatchNormalization(
-            axis=BN_AXIS, epsilon=BN_EPSILON, name="post_bn"
-        )(x)
-        x = layers.Activation("relu", name="post_relu")(x)
-
-        # Create model.
-        super().__init__(inputs=inputs, outputs=x, **kwargs)
-
-        # All references to `self` below this line
-        self.pyramid_level_inputs = pyramid_level_inputs
-        self.stackwise_filters = stackwise_filters
-        self.stackwise_blocks = stackwise_blocks
-        self.stackwise_strides = stackwise_strides
-        self.include_rescaling = include_rescaling
-        self.stackwise_dilations = stackwise_dilations
-        self.input_tensor = input_tensor
-        self.block_type = block_type
-
-    def get_config(self):
-        config = super().get_config()
-        config.update(
-            {
-                "stackwise_filters": self.stackwise_filters,
-                "stackwise_blocks": self.stackwise_blocks,
-                "stackwise_strides": self.stackwise_strides,
-                "include_rescaling": self.include_rescaling,
-                # Remove batch dimension from `input_shape`
-                "input_shape": self.input_shape[1:],
-                "stackwise_dilations": self.stackwise_dilations,
-                "input_tensor": self.input_tensor,
-                "block_type": self.block_type,
-            }
-        )
-        return config
-
-    @classproperty
-    def presets(cls):
-        """Dictionary of preset names and configurations."""
-        return copy.deepcopy(backbone_presets)
-
-    @classproperty
-    def presets_with_weights(cls):
-        """Dictionary of preset names and configurations that include
-        weights."""
-        return copy.deepcopy(backbone_presets_with_weights)
-
-
-ALIAS_DOCSTRING = """ResNetV2Backbone model with {num_layers} layers.
-
-    Reference:
-        - [Identity Mappings in Deep Residual Networks](https://arxiv.org/abs/1603.05027) (ECCV 2016)
-
-    The difference in ResNet and ResNetV2 rests in the structure of their
-    individual building blocks. In ResNetV2, the batch normalization and
-    ReLU activation precede the convolution layers, as opposed to ResNetV1 where
-    the batch normalization and ReLU activation are applied after the
-    convolution layers.
-
-    For transfer learning use cases, make sure to read the
-    [guide to transfer learning & fine-tuning](https://keras.io/guides/transfer_learning/).
-
-    Args:
-        include_rescaling: bool, whether to rescale the inputs. If set
-            to `True`, inputs will be passed through a `Rescaling(1/255.0)`
-            layer.
-        input_shape: optional shape tuple, defaults to (None, None, 3).
-        input_tensor: optional Keras tensor (i.e. output of `layers.Input()`)
-            to use as image input for the model.
-
-    Examples:
-    ```python
-    input_data = tf.ones(shape=(8, 224, 224, 3))
-
-    # Randomly initialized backbone
-    model = ResNet{num_layers}V2Backbone()
-    output = model(input_data)
-    ```
-"""  # noqa: E501
-
-
-class ResNet18V2Backbone(ResNetV2Backbone):
-    def __new__(
-        cls,
-        include_rescaling=True,
-        input_shape=(None, None, 3),
-        input_tensor=None,
-        **kwargs,
-    ):
-        # Pack args in kwargs
-        kwargs.update(
-            {
-                "include_rescaling": include_rescaling,
-                "input_shape": input_shape,
-                "input_tensor": input_tensor,
-            }
-        )
-        return ResNetV2Backbone.from_preset("resnet18_v2", **kwargs)
-
-    @classproperty
-    def presets(cls):
-        """Dictionary of preset names and configurations."""
-        return {}
-
-    @classproperty
-    def presets_with_weights(cls):
-        """Dictionary of preset names and configurations that include
-        weights."""
-        return {}
-
-
-class ResNet34V2Backbone(ResNetV2Backbone):
-    def __new__(
-        cls,
-        include_rescaling=True,
-        input_shape=(None, None, 3),
-        input_tensor=None,
-        **kwargs,
-    ):
-        # Pack args in kwargs
-        kwargs.update(
-            {
-                "include_rescaling": include_rescaling,
-                "input_shape": input_shape,
-                "input_tensor": input_tensor,
-            }
-        )
-        return ResNetV2Backbone.from_preset("resnet34_v2", **kwargs)
-
-    @classproperty
-    def presets(cls):
-        """Dictionary of preset names and configurations."""
-        return {}
-
-    @classproperty
-    def presets_with_weights(cls):
-        """Dictionary of preset names and configurations that include
-        weights."""
-        return {}
-
-
-class ResNet50V2Backbone(ResNetV2Backbone):
-    def __new__(
-        cls,
-        include_rescaling=True,
-        input_shape=(None, None, 3),
-        input_tensor=None,
-        **kwargs,
-    ):
-        # Pack args in kwargs
-        kwargs.update(
-            {
-                "include_rescaling": include_rescaling,
-                "input_shape": input_shape,
-                "input_tensor": input_tensor,
-            }
-        )
-        return ResNetV2Backbone.from_preset("resnet50_v2", **kwargs)
-
-    @classproperty
-    def presets(cls):
-        """Dictionary of preset names and configurations."""
-        return {
-            "resnet50_v2_imagenet": copy.deepcopy(
-                backbone_presets["resnet50_v2_imagenet"]
-            ),
-        }
-
-    @classproperty
-    def presets_with_weights(cls):
-        """Dictionary of preset names and configurations that include
-        weights."""
-        return cls.presets
-
-
-class ResNet101V2Backbone(ResNetV2Backbone):
-    def __new__(
-        cls,
-        include_rescaling=True,
-        input_shape=(None, None, 3),
-        input_tensor=None,
-        **kwargs,
-    ):
-        # Pack args in kwargs
-        kwargs.update(
-            {
-                "include_rescaling": include_rescaling,
-                "input_shape": input_shape,
-                "input_tensor": input_tensor,
-            }
-        )
-        return ResNetV2Backbone.from_preset("resnet101_v2", **kwargs)
-
-    @classproperty
-    def presets(cls):
-        """Dictionary of preset names and configurations."""
-        return {}
-
-    @classproperty
-    def presets_with_weights(cls):
-        """Dictionary of preset names and configurations that include
-        weights."""
-        return {}
-
-
-class ResNet152V2Backbone(ResNetV2Backbone):
-    def __new__(
-        cls,
-        include_rescaling=True,
-        input_shape=(None, None, 3),
-        input_tensor=None,
-        **kwargs,
-    ):
-        # Pack args in kwargs
-        kwargs.update(
-            {
-                "include_rescaling": include_rescaling,
-                "input_shape": input_shape,
-                "input_tensor": input_tensor,
-            }
-        )
-        return ResNetV2Backbone.from_preset("resnet152_v2", **kwargs)
-
-    @classproperty
-    def presets(cls):
-        """Dictionary of preset names and configurations."""
-        return {}
-
-    @classproperty
-    def presets_with_weights(cls):
-        """Dictionary of preset names and configurations that include
-        weights."""
-        return {}
-
-
-setattr(
-    ResNet18V2Backbone,
-    "__doc__",
-    ALIAS_DOCSTRING.format(num_layers=18),
-)
-setattr(
-    ResNet34V2Backbone,
-    "__doc__",
-    ALIAS_DOCSTRING.format(num_layers=34),
-)
-setattr(
-    ResNet50V2Backbone,
-    "__doc__",
-    ALIAS_DOCSTRING.format(num_layers=50),
-)
-setattr(
-    ResNet101V2Backbone,
-    "__doc__",
-    ALIAS_DOCSTRING.format(num_layers=101),
-)
-setattr(
-    ResNet152V2Backbone,
-    "__doc__",
-    ALIAS_DOCSTRING.format(num_layers=152),
-)


Test patch:
diff --git a/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_presets_test.py b/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_presets_test.py
index c1fa4e3..22cf9bd 100644
--- a/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_presets_test.py
+++ b/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_presets_test.py
@@ -17,7 +17,7 @@ import pytest
 import tensorflow as tf
 from absl.testing import parameterized
 
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet50V2Backbone,
 )
 from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
diff --git a/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_test.py b/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_test.py
index a37c044..0ec6ae5 100644
--- a/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_test.py
+++ b/keras_cv/models/backbones/resnet_v2/resnet_v2_backbone_test.py
@@ -19,7 +19,7 @@ import tensorflow as tf
 from absl.testing import parameterized
 from tensorflow import keras
 
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet50V2Backbone,
 )
 from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
diff --git a/keras_cv/models/classification/image_classifier_test.py b/keras_cv/models/classification/image_classifier_test.py
index 1b993a2..5ac15bc 100644
--- a/keras_cv/models/classification/image_classifier_test.py
+++ b/keras_cv/models/classification/image_classifier_test.py
@@ -21,7 +21,7 @@ import tensorflow as tf
 from absl.testing import parameterized
 from tensorflow import keras
 
-from keras_cv.models.backbones.resnet_v2.resnet_v2_backbone import (
+from keras_cv.models.backbones.resnet_v2.resnet_v2_aliases import (
     ResNet18V2Backbone,
 )
 from keras_cv.models.classification.image_classifier import ImageClassifier