class_docstr: Implementation of EfficientNet, https://arxiv.org/pdf/1905.11946.pdf
  References:
      https://github.com/tensorflow/tpu/tree/master/models/official/efficientnet
      https://github.com/lukemelas/EfficientNet-PyTorch
  
  NOTE: the original implementation uses the names depth_divisor and min_depth
        to refer to the number of channels, which is confusing, since the paper
        refers to the channel dimension as width. We use the width_divisor and
        min_width names instead.
class_docstr_tok: ["Implementation","of","EfficientNet",",","https",":","\/\/arxiv.org\/pdf\/1905.11946.pdf","References",":","https",":","\/\/github.com\/tensorflow\/tpu\/tree\/master\/models\/official\/efficientnet","https",":","\/\/github.com\/lukemelas\/EfficientNet-PyTorch","NOTE",":","the","original","implementation","uses","the","names","depth_divisor","and","min_depth","to","refer","to","the","number","of","channels",",","which","is","confusing",",","since","the","paper","refers","to","the","channel","dimension","as","width",".","We","use","the","width_divisor","and","min_width","names","instead","."]
code: def __init__(
      self,
      num_classes: int,
      model_params: EfficientNetParams,
      bn_momentum: float,
      bn_epsilon: float,
      width_divisor: int,
      min_width: Optional[int],
      drop_connect_rate: float,
      use_se: bool,
  ):
      super().__init__()
  
      self.num_classes = num_classes
      self.image_resolution = model_params.resolution
  
      # use the swish activation function
      self.relu_fn = swish
  
      # width and depth parameters
      width_coefficient = model_params.width_coefficient
      depth_coefficient = model_params.depth_coefficient
  
      # drop connect rate
      self.drop_connect_rate = drop_connect_rate
  
      # input dimensions
      in_channels = 3
  
      # Stem
      out_channels = 32
      out_channels = scale_width(
          out_channels, width_coefficient, width_divisor, min_width
      )
      self.conv_stem = nn.Conv2d(
          in_channels=in_channels,
          out_channels=out_channels,
          kernel_size=3,
          stride=2,
          padding=1,
          bias=False,
      )
      self.bn0 = nn.BatchNorm2d(
          num_features=out_channels,
          momentum=bn_momentum,
          eps=bn_epsilon,
      )
  
      # Build blocks
      blocks = OrderedDict()
      for block_idx, block_params in enumerate(BLOCK_PARAMS):
          assert block_params.num_repeat > 0, "num_repeat has to be > 0"
  
          # Update block input and output filters based on the width_coefficient,
          # and the number of repeats based on the depth_coefficient
          block_params = block_params._replace(
              input_filters=scale_width(
                  block_params.input_filters,
                  width_coefficient,
                  width_divisor,
                  min_width,
              ),
              output_filters=scale_width(
                  block_params.output_filters,
                  width_coefficient,
                  width_divisor,
                  min_width,
              ),
              num_repeat=scale_depth(
                  block_params.num_repeat, depth_coefficient
              ),
          )
  
          block_name = f"block{block_idx}-0"
          # The first block needs to take care of the stride and filter size increase
          blocks[block_name] = MBConvBlock(
              block_params.input_filters,
              block_params.output_filters,
              block_params.expand_ratio,
              block_params.kernel_size,
              block_params.stride,
              block_params.se_ratio,
              block_params.id_skip,
              use_se,
              bn_momentum,
              bn_epsilon,
          )
          if block_params.num_repeat > 1:
              block_params = block_params._replace(
                  input_filters=block_params.output_filters, stride=1
              )
          for i in range(1, block_params.num_repeat):
              block_name = f"block{block_idx}-{i}"
              blocks[block_name] = MBConvBlock(
                  block_params.input_filters,
                  block_params.output_filters,
                  block_params.expand_ratio,
                  block_params.kernel_size,
                  block_params.stride,
                  block_params.se_ratio,
                  block_params.id_skip,
                  use_se,
                  bn_momentum,
                  bn_epsilon,
              )
      self.blocks = nn.Sequential(blocks)
  
      # Head
      in_channels = block_params.output_filters
      out_channels = 1280
      out_channels = scale_width(
          out_channels, width_coefficient, width_divisor, min_width
      )
      self.conv_head = nn.Conv2d(
          in_channels=in_channels,
          out_channels=out_channels,
          kernel_size=1,
          stride=1,
          padding=0,
          bias=False,
      )
      self.bn1 = nn.BatchNorm2d(
          num_features=out_channels,
          momentum=bn_momentum,
          eps=bn_epsilon,
      )
  
      # add a trunk_output module to attach heads to
      self.trunk_output = nn.Identity()
  
      self.avg_pooling = nn.AdaptiveAvgPool2d((1, 1))
  
      # Fully connected layer
      self.fc = nn.Linear(out_channels, num_classes)
  
      if model_params.dropout_rate > 0:
          self.dropout = nn.Dropout(p=model_params.dropout_rate)
      else:
          self.dropout = None
  
      # initialize weights
      self.init_weights()
  
imports: import copy
  import math
  from collections import OrderedDict
  from typing import Any, Dict, NamedTuple, Optional
  import torch
  import torch.nn
  from classy_vision.generic.util import get_torch_version
  from classy_vision.models import ClassyModel, register_model
label_desc: Use image node_id 1 to create a new EfficientNet object from inherited base classes: ClassyModel with example: obj = EfficientNet(num_classes, model_params, bn_momentum, bn_epsilon, width_divisor, min_width, drop_connect_rate, use_se)