mindcv.models.efficientnet 源代码

"""EfficientNet Architecture."""

import copy
from typing import List, Optional, Callable, Any, Union, Sequence
from functools import partial

import math
import numpy as np
from mindspore import Tensor
from mindspore import nn
from mindspore import ops
from mindspore.common import initializer as weight_init
from mindspore.common.initializer import Uniform, Normal

from .layers.squeeze_excite import SqueezeExcite
from .layers.activation import Swish
from .layers.drop_path import DropPath
from .utils import load_pretrained, make_divisible
from .registry import register_model

__all__ = [
    'EfficientNet',  # registration mechanism to use yaml configuration
    "efficientnet_b0",
    "efficientnet_b1",
    "efficientnet_b2",
    "efficientnet_b3",
    "efficientnet_b4",
    "efficientnet_b5",
    "efficientnet_b6",
    "efficientnet_b7",
    "efficientnet_v2_s",
    "efficientnet_v2_m",
    "efficientnet_v2_l",
    "efficientnet_v2_xl",
]


def _cfg(url='', **kwargs):
    return {
        'url': url,
        'num_classes': 1000,
        # 'first_conv': 'features.0.features.0', 'classifier': 'classifier',
        **kwargs
    }


default_cfgs = {
    'efficientnet_b0': _cfg(url=''),
    'efficientnet_b1': _cfg(url=''),
    'efficientnet_b2': _cfg(url=''),
    'efficientnet_b3': _cfg(url=''),
    'efficientnet_b4': _cfg(url=''),
    'efficientnet_b5': _cfg(url=''),
    'efficientnet_b6': _cfg(url=''),
    'efficientnet_b7': _cfg(url=''),
    'efficientnet_v2_s': _cfg(url=''),
    'efficientnet_v2_m': _cfg(url=''),
    'efficientnet_v2_l': _cfg(url=''),
    'efficientnet_v2_xl': _cfg(url=''),
}


class MBConvConfig:
    """
    The Parameters of MBConv which need to multiply the expand_ration.

    Args:
        expand_ratio (float): The Times of the num of out_channels with respect to in_channels.
        kernel_size (int): The kernel size of the depthwise conv.
        stride (int): The stride of the depthwise conv.
        in_chs (int): The input_channels of the MBConv Module.
        out_chs (int): The output_channels of the MBConv Module.
        num_layers (int): The num of MBConv Module.
        width_cnf: The ratio of the channel. Default: 1.0.
        depth_cnf: The ratio of num_layers. Default: 1.0.

    Returns:
        None

    Examples:
        >>> cnf = MBConvConfig(1, 3, 1, 32, 16, 1)
        >>> print(cnf.input_channels)
    """

    def __init__(self,
                 expand_ratio: float,
                 kernel_size: int,
                 stride: int,
                 in_chs: int,
                 out_chs: int,
                 num_layers: int,
                 width_cnf: float = 1.0,
                 depth_cnf: float = 1.0,
                 ) -> None:
        self.expand_ratio = expand_ratio
        self.kernel_size = kernel_size
        self.stride = stride
        self.input_channels = self.adjust_channels(in_chs, width_cnf)
        self.out_channels = self.adjust_channels(out_chs, width_cnf)
        self.num_layers = self.adjust_depth(num_layers, depth_cnf)

    @staticmethod
    def adjust_channels(channels: int, width_cnf: float, min_value: Optional[int] = None) -> int:
        """
        Calculate the width of MBConv.

        Args:
            channels (int): The number of channel.
            width_cnf (float): The ratio of channel.
            min_value (int, optional): The minimum number of channel. Default: None.

        Returns:
            int, the width of MBConv.
        """

        return make_divisible(channels * width_cnf, 8, min_value)

    @staticmethod
    def adjust_depth(num_layers: int, depth_cnf: float) -> int:
        """
        Calculate the depth of MBConv.

        Args:
            num_layers (int): The number of MBConv Module.
            depth_cnf (float): The ratio of num_layers.

        Returns:
            int, the depth of MBConv.
        """

        return int(math.ceil(num_layers * depth_cnf))


class MBConv(nn.Cell):
    """
    MBConv Module.

    Args:
        cnf (MBConvConfig): The class which contains the parameters(in_channels, out_channels, nums_layers) and
            the functions which help calculate the parameters after multipling the expand_ratio.
        keep_prob: The dropout rate in MBConv. Default: 0.8.
        norm (nn.Cell): The BatchNorm Method. Default: None.
        se_layer (nn.Cell): The squeeze-excite Module. Default: SqueezeExcite.

    Returns:
        Tensor
    """

    def __init__(
            self,
            cnf: MBConvConfig,
            keep_prob: float = 0.8,
            norm: Optional[nn.Cell] = None,
            se_layer: Callable[..., nn.Cell] = SqueezeExcite,
    ) -> None:
        super().__init__()

        self.shortcut = cnf.stride == 1 and cnf.input_channels == cnf.out_channels

        layers: List[nn.Cell] = []

        # expand conv: the out_channels is cnf.expand_ratio times of the in_channels.
        expanded_channels = cnf.adjust_channels(cnf.input_channels, cnf.expand_ratio)
        if expanded_channels != cnf.input_channels:
            layers.extend([
                nn.Conv2d(cnf.input_channels, expanded_channels, kernel_size=1),
                norm(expanded_channels),
                Swish()
            ])

        # depthwise conv: splits the filter into groups.
        layers.extend([
            nn.Conv2d(expanded_channels, expanded_channels, kernel_size=cnf.kernel_size,
                      stride=cnf.stride, group=expanded_channels),
            norm(expanded_channels),
            Swish()
        ])

        # squeeze and excitation
        squeeze_channels = max(1, cnf.input_channels // 4)
        layers.append(se_layer(in_channels=expanded_channels, rd_channels=squeeze_channels, act_layer=Swish))

        # project
        layers.extend([
            nn.Conv2d(expanded_channels, cnf.out_channels, kernel_size=1),
            norm(cnf.out_channels)
        ])

        self.block = nn.SequentialCell(layers)
        self.dropout = DropPath(keep_prob)
        self.out_channels = cnf.out_channels

    def construct(self, x) -> Tensor:
        result = self.block(x)
        if self.shortcut:
            result = self.dropout(result)
            result += x
        return result


class FusedMBConvConfig(MBConvConfig):
    """FusedMBConvConfig"""
    # Stores information listed at Table 4 of the EfficientNetV2 paper
    def __init__(
            self,
            expand_ratio: float,
            kernel_size: int,
            stride: int,
            in_chs: int,
            out_chs: int,
            num_layers: int,
    ) -> None:
        super().__init__(expand_ratio, kernel_size, stride, in_chs, out_chs, num_layers)


class FusedMBConv(nn.Cell):
    """FusedMBConv"""
    def __init__(
            self,
            cnf: FusedMBConvConfig,
            keep_prob: float,
            norm: Optional[nn.Cell] = None,
    ) -> None:
        super().__init__()

        if not 1 <= cnf.stride <= 2:
            raise ValueError("illegal stride value")

        self.shortcut = cnf.stride == 1 and cnf.input_channels == cnf.out_channels

        layers: List[nn.Cell] = []

        expanded_channels = cnf.adjust_channels(cnf.input_channels, cnf.expand_ratio)
        if expanded_channels != cnf.input_channels:
            # fused expand
            layers.extend([
                nn.Conv2d(cnf.input_channels, expanded_channels, kernel_size=cnf.kernel_size,
                          stride=cnf.stride),
                norm(expanded_channels),
                Swish()
            ])

            # project
            layers.extend([
                nn.Conv2d(expanded_channels, cnf.out_channels, kernel_size=1),
                norm(cnf.out_channels)
            ])
        else:
            layers.extend([
                nn.Conv2d(cnf.input_channels, cnf.out_channels, kernel_size=cnf.kernel_size,
                          stride=cnf.stride),
                norm(cnf.out_channels),
                Swish()
            ])

        self.block = nn.SequentialCell(layers)
        self.dropout = DropPath(keep_prob)
        self.out_channels = cnf.out_channels

    def construct(self, x) -> Tensor:
        result = self.block(x)
        if self.shortcut:
            result = self.dropout(result)
            result += x
        return result


[文档]class EfficientNet(nn.Cell): """ EfficientNet architecture. `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: arch (str): The name of the model. dropout_rate (float): The dropout rate of efficientnet. width_mult (float): The ratio of the channel. Default: 1.0. depth_mult (float): The ratio of num_layers. Default: 1.0. in_channels (int): The input channels. Default: 3. num_classes (int): The number of class. Default: 1000. inverted_residual_setting (Sequence[Union[MBConvConfig, FusedMBConvConfig]], optional): The settings of block. Default: None. keep_prob (float): The dropout rate of MBConv. Default: 0.2. norm_layer (nn.Cell, optional): The normalization layer. Default: None. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, 1000)`. """ def __init__(self, arch: str, dropout_rate: float, width_mult: float = 1.0, depth_mult: float = 1.0, in_channels: int = 3, num_classes: int = 1000, inverted_residual_setting: Optional[Sequence[Union[MBConvConfig, FusedMBConvConfig]]] = None, keep_prob: float = 0.2, norm_layer: Optional[nn.Cell] = None, ) -> None: super().__init__() self.last_channel = None if norm_layer is None: norm_layer = nn.BatchNorm2d if width_mult >= 1.6: norm_layer = partial(nn.BatchNorm2d, eps=0.001, momentum=0.99) layers: List[nn.Cell] = [] if not inverted_residual_setting: if arch.startswith("efficientnet_b"): bneck_conf = partial(MBConvConfig, width_cnf=width_mult, depth_cnf=depth_mult) inverted_residual_setting = [ bneck_conf(1, 3, 1, 32, 16, 1), bneck_conf(6, 3, 2, 16, 24, 2), bneck_conf(6, 5, 2, 24, 40, 2), bneck_conf(6, 3, 2, 40, 80, 3), bneck_conf(6, 5, 1, 80, 112, 3), bneck_conf(6, 5, 2, 112, 192, 4), bneck_conf(6, 3, 1, 192, 320, 1), ] elif arch.startswith("efficientnet_v2_s"): inverted_residual_setting = [ FusedMBConvConfig(1, 3, 1, 24, 24, 2), FusedMBConvConfig(4, 3, 2, 24, 48, 4), FusedMBConvConfig(4, 3, 2, 48, 64, 4), MBConvConfig(4, 3, 2, 64, 128, 6), MBConvConfig(6, 3, 1, 128, 160, 9), MBConvConfig(6, 3, 2, 160, 256, 15), ] self.last_channel = 1280 elif arch.startswith("efficientnet_v2_m"): inverted_residual_setting = [ FusedMBConvConfig(1, 3, 1, 24, 24, 3), FusedMBConvConfig(4, 3, 2, 24, 48, 5), FusedMBConvConfig(4, 3, 2, 48, 80, 5), MBConvConfig(4, 3, 2, 80, 160, 7), MBConvConfig(6, 3, 1, 160, 176, 14), MBConvConfig(6, 3, 2, 176, 304, 18), MBConvConfig(6, 3, 1, 304, 512, 5), ] self.last_channel = 1280 elif arch.startswith("efficientnet_v2_l"): inverted_residual_setting = [ FusedMBConvConfig(1, 3, 1, 32, 32, 4), FusedMBConvConfig(4, 3, 2, 32, 64, 7), FusedMBConvConfig(4, 3, 2, 64, 96, 7), MBConvConfig(4, 3, 2, 96, 192, 10), MBConvConfig(6, 3, 1, 192, 224, 19), MBConvConfig(6, 3, 2, 224, 384, 25), MBConvConfig(6, 3, 1, 384, 640, 7), ] self.last_channel = 1280 elif arch.startswith("efficientnet_v2_xl"): inverted_residual_setting = [ FusedMBConvConfig(1, 3, 1, 32, 32, 4), FusedMBConvConfig(4, 3, 2, 32, 64, 8), FusedMBConvConfig(4, 3, 2, 64, 96, 8), MBConvConfig(4, 3, 2, 96, 192, 16), MBConvConfig(6, 3, 1, 192, 256, 24), MBConvConfig(6, 3, 2, 256, 512, 32), MBConvConfig(6, 3, 1, 512, 640, 8), ] self.last_channel = 1280 # building first layer firstconv_output_channels = inverted_residual_setting[0].input_channels layers.extend([ nn.Conv2d(in_channels, firstconv_output_channels, kernel_size=3, stride=2), norm_layer(firstconv_output_channels), Swish() ]) # building MBConv blocks total_stage_blocks = sum(cnf.num_layers for cnf in inverted_residual_setting) stage_block_id = 0 # cnf is the settings of block for cnf in inverted_residual_setting: stage: List[nn.Cell] = [] # cnf.num_layers is the num of the same block for _ in range(cnf.num_layers): # copy to avoid modifications. shallow copy is enough block_cnf = copy.copy(cnf) block = MBConv if "FusedMBConvConfig" in str(type(block_cnf)): block = FusedMBConv # overwrite info if not the first conv in the stage if stage: block_cnf.input_channels = block_cnf.out_channels block_cnf.stride = 1 # adjust dropout rate of blocks based on the depth of the stage block sd_prob = keep_prob * float(stage_block_id + 0.00001) / total_stage_blocks stage.append(block(block_cnf, sd_prob, norm_layer)) stage_block_id += 1 layers.append(nn.SequentialCell(stage)) # building last several layers lastconv_input_channels = inverted_residual_setting[-1].out_channels lastconv_output_channels = self.last_channel if self.last_channel is not None else 4 * lastconv_input_channels layers.extend([ nn.Conv2d(lastconv_input_channels, lastconv_output_channels, kernel_size=1), norm_layer(lastconv_output_channels), Swish() ]) self.features = nn.SequentialCell(layers) self.dropout = nn.Dropout(1 - dropout_rate) self.mlp_head = nn.Dense(lastconv_output_channels, num_classes) self._initialize_weights() def forward_features(self, x: Tensor) -> Tensor: x = self.features(x) x = ops.adaptive_avg_pool2d(x, 1) x = ops.flatten(x) if self.training: x = self.dropout(x) return x def forward_head(self, x: Tensor) -> Tensor: return self.mlp_head(x) def construct(self, x: Tensor) -> Tensor: """construct""" x = self.forward_features(x) return self.forward_head(x) def _initialize_weights(self) -> None: """Initialize weights for cells.""" for _, cell in self.cells_and_names(): if isinstance(cell, nn.Dense): init_range = 1.0 / np.sqrt(cell.weight.shape[0]) cell.weight.set_data(weight_init.initializer(Uniform(init_range), cell.weight.shape, cell.weight.dtype)) if cell.bias is not None: cell.bias.set_data(weight_init.initializer(weight_init.Zero(), cell.bias.shape, cell.bias.dtype)) if isinstance(cell, nn.Conv2d): out_channel, _, kernel_size_h, kernel_size_w = cell.weight.shape stddev = np.sqrt(2 / int(out_channel * kernel_size_h * kernel_size_w)) cell.weight.set_data(weight_init.initializer(Normal(sigma=stddev), cell.weight.shape, cell.weight.dtype)) if cell.bias is not None: cell.bias.set_data(weight_init.initializer(weight_init.Zero(), cell.bias.shape, cell.bias.dtype))
def _efficientnet(arch: str, width_mult: float, depth_mult: float, dropout: float, in_channels: int, num_classes: int, pretrained: bool, **kwargs: Any, ) -> EfficientNet: """EfficientNet architecture.""" model = EfficientNet(arch, dropout, width_mult, depth_mult, in_channels, num_classes, **kwargs) default_cfg = default_cfgs[arch] if pretrained: # Download the pretrained checkpoint file from url, and load # checkpoint file. load_pretrained(model, default_cfg, num_classes=num_classes, in_channels=in_channels) return model @register_model def efficientnet_b0(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B0 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b0", 1.0, 1.0, 0.2, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b1(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B1 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b1", 1.0, 1.1, 0.2, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b2(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B2 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b2", 1.1, 1.2, 0.3, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b3(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B3 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b3", 1.2, 1.4, 0.3, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b4(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B4 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b4", 1.4, 1.8, 0.4, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b5(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B5 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b5", 1.6, 2.2, 0.4, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b6(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B6 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b6", 1.8, 2.6, 0.5, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_b7(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B7 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_b7", 2.0, 3.1, 0.5, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_v2_s(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B4 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_v2_s", 1., 1., 0.2, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_v2_m(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B4 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_v2_m", 1., 1., 0.2, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_v2_l(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B4 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_v2_l", 1., 1., 0.2, in_channels, num_classes, pretrained, **kwargs) @register_model def efficientnet_v2_xl(pretrained: bool = False, num_classes: int = 1000, in_channels=3, **kwargs) -> EfficientNet: """ Constructs a EfficientNet B4 architecture from `EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks <https://arxiv.org/abs/1905.11946>`_. Args: pretrained (bool): If True, returns a model pretrained on IMAGENET. Default: False. num_classes (int): The numbers of classes. Default: 1000. in_channels (int): The input channels. Default: 1000. Inputs: - **x** (Tensor) - Tensor of shape :math:`(N, C_{in}, H_{in}, W_{in})`. Outputs: Tensor of shape :math:`(N, CLASSES_{out})`. """ return _efficientnet("efficientnet_v2_xl", 1., 1., 0.2, in_channels, num_classes, pretrained, **kwargs)