class_docstr: BatchNorm + Activation
  
  This module performs BatchNorm + Activation in a manner that will remain backwards
  compatible with weights trained with separate bn, act. This is why we inherit from BN
  instead of composing it as a .bn member.
code: def forward(self, x):
      # cut & paste of torch.nn.BatchNorm2d.forward impl to avoid issues with torchscript and tracing
      _assert(x.ndim == 4, f"expected 4D input (got {x.ndim}D input)")
  
      # exponential_average_factor is set to self.momentum
      # (when it is available) only so that it gets updated
      # in ONNX graph when this node is exported to ONNX.
      if self.momentum is None:
          exponential_average_factor = 0.0
      else:
          exponential_average_factor = self.momentum
  
      if self.training and self.track_running_stats:
          # TODO: if statement only here to tell the jit to skip emitting this when it is None
          if self.num_batches_tracked is not None:  # type: ignore[has-type]
              self.num_batches_tracked.add_(1)  # type: ignore[has-type]
              if self.momentum is None:  # use cumulative moving average
                  exponential_average_factor = 1.0 / float(
                      self.num_batches_tracked
                  )
              else:  # use exponential moving average
                  exponential_average_factor = self.momentum
  
      r"""
          Decide whether the mini-batch stats should be used for normalization rather than the buffers.
          Mini-batch stats are used in training mode, and in eval mode when buffers are None.
          """
      if self.training:
          bn_training = True
      else:
          bn_training = (self.running_mean is None) and (
              self.running_var is None
          )
  
      r"""
          Buffers are only updated if they are to be tracked and we are in training mode. Thus they only need to be
          passed when the update should occur (i.e. in training mode when they are tracked), or when buffer stats are
          used for normalization (i.e. in eval mode when buffers are not None).
          """
      x = F.batch_norm(
          x,
          # If buffers are not to be tracked, ensure that they won't be updated
          self.running_mean
          if not self.training or self.track_running_stats
          else None,
          self.running_var
          if not self.training or self.track_running_stats
          else None,
          self.weight,
          self.bias,
          bn_training,
          exponential_average_factor,
          self.eps,
      )
      x = self.drop(x)
      x = self.act(x)
      return x
  
imports: from typing import Union, List, Optional, Any
  import torch
  from torch import nn
  from torch.nn import functional
  from torchvision.ops.misc import FrozenBatchNorm2d
  from .create_act import get_act_layer
  from .fast_norm import is_fast_norm, fast_group_norm, fast_layer_norm
  from .trace_utils import _assert
label_desc: Use image node_id 2 for calling the BatchNormAct2d obj's underlying member method code with example usage: obj.forward(x) and returns: x