class_docstr: LeNet is a customizable Convolutional Neural Network (CNN) model based on the LeNet architecture, designed for
  feature extraction from image and audio modalities.
     LeNet supports several layers of 2D convolution, followed by batch normalization, max pooling, and adaptive
     average pooling, with a configurable number of channels.
     The depth of the network (number of convolutional blocks) is adjustable with the 'additional_layers' parameter.
     An optional linear layer can be added at the end for further transformation of the output, which could be useful
     for various tasks such as classification or regression. The 'output_each_layer' option allows for returning the
     output of each layer instead of just the final output, which can be beneficial for certain tasks or for analyzing
     the intermediate representations learned by the network.
     By default, the output tensor is squeezed before being returned, removing dimensions of size one, but this can be
     configured with the 'squeeze_output' parameter.
  
  Args:
      input_channels (int): Input channel number.
      output_channels (int): Output channel number for block.
      additional_layers (int): Number of additional blocks for LeNet.
      output_each_layer (bool, optional): Whether to return the output of all layers. Defaults to False.
      linear (tuple, optional): Tuple of (input_dim, output_dim) for optional linear layer post-processing. Defaults to None.
      squeeze_output (bool, optional): Whether to squeeze output before returning. Defaults to True.
  
  Note:
      Adapted code from https://github.com/slyviacassell/_MFAS/blob/master/models/central/avmnist.py.
code: def __init__(
      self,
      input_channels,
      output_channels,
      additional_layers,
      output_each_layer=False,
      linear=None,
      squeeze_output=True,
  ):
      super(LeNet, self).__init__()
      self.output_each_layer = output_each_layer
      self.conv_layers = [
          nn.Conv2d(
              input_channels,
              output_channels,
              kernel_size=5,
              padding=2,
              bias=False,
          )
      ]
      self.batch_norms = [nn.BatchNorm2d(output_channels)]
      self.global_pools = [nn.AdaptiveAvgPool2d(1)]
  
      for i in range(additional_layers):
          self.conv_layers.append(
              nn.Conv2d(
                  (2**i) * output_channels,
                  (2 ** (i + 1)) * output_channels,
                  kernel_size=3,
                  padding=1,
                  bias=False,
              )
          )
          self.batch_norms.append(
              nn.BatchNorm2d(output_channels * (2 ** (i + 1)))
          )
          self.global_pools.append(nn.AdaptiveAvgPool2d(1))
  
      self.conv_layers = nn.ModuleList(self.conv_layers)
      self.batch_norms = nn.ModuleList(self.batch_norms)
      self.global_pools = nn.ModuleList(self.global_pools)
      self.squeeze_output = squeeze_output
      self.linear = None
  
      if linear is not None:
          self.linear = nn.Linear(linear[0], linear[1])
  
      for m in self.modules():
          if isinstance(m, (nn.Conv2d, nn.Linear)):
              nn.init.kaiming_uniform_(m.weight)
  
imports: import torch.nn
  from torch.nn import functional
  from torchvision import models
label_desc: Use image node_id 1 to create a new LeNet object from inherited base classes: nn with example: obj = LeNet(input_channels, output_channels, additional_layers, output_each_layer, linear, squeeze_output)