class_docstr: An implementation of ResNet
  
  Arguments
  ---------
  device : str
      Device used, e.g., "cpu" or "cuda".
  activation : torch class
      A class for constructing the activation layers.
  channels : list of ints
      List of number of channels used per stage.
  block_sizes : list of ints
      List of number of groups created per stage.
  strides : list of ints
      List of stride per stage.
  lin_neurons : int
      Number of neurons in linear layers.
  
  Example
  -------
  >>> input_feats = torch.rand([2, 400, 80])
  >>> compute_embedding = ResNet(lin_neurons=256)
  >>> outputs = compute_embedding(input_feats)
  >>> outputs.shape
  torch.Size([2, 256])
code: def __init__(
      self,
      input_size=80,
      device="cpu",
      activation=torch.nn.ReLU,
      channels=[128, 128, 256, 256],
      block_sizes=[3, 4, 6, 3],
      strides=[1, 2, 2, 2],
      lin_neurons=256,
  ):
      super().__init__()
  
      assert len(channels) == 4
      assert len(block_sizes) == 4
      assert len(strides) == 4
  
      input_out = math.ceil(
          input_size
          / (strides[0] * strides[1] * strides[2] * strides[3])
      )
  
      self.conv1 = nn.Conv2d(1, channels[0], 3, 1, 1, bias=False)
      self.bn1 = nn.BatchNorm2d(channels[0])
      self.activation1 = activation()
  
      self.layer1 = self._make_layer_se(
          channels[0], channels[0], block_sizes[0], stride=strides[0]
      )
      self.layer2 = self._make_layer_se(
          channels[0], channels[1], block_sizes[1], stride=strides[1]
      )
      self.layer3 = self._make_layer(
          channels[1], channels[2], block_sizes[2], stride=strides[2]
      )
      self.layer4 = self._make_layer(
          channels[2], channels[3], block_sizes[3], stride=strides[3]
      )
  
      self.norm_stats = torch.nn.BatchNorm1d(
          2 * input_out * channels[-1]
      )
  
      self.attention = nn.Sequential(
          nn.Conv1d(channels[-1] * input_out, 128, kernel_size=1),
          nn.ReLU(),
          nn.BatchNorm1d(128),
          nn.Conv1d(128, channels[-1] * input_out, kernel_size=1),
          nn.Softmax(dim=2),
      )
  
      self.fc_embed = nn.Linear(
          2 * input_out * channels[-1], lin_neurons
      )
      self.norm_embed = torch.nn.BatchNorm1d(lin_neurons)
  
      for m in self.modules():
          if isinstance(m, nn.Conv2d):
              nn.init.kaiming_normal_(
                  m.weight, mode="fan_out", nonlinearity="relu"
              )
          elif isinstance(m, nn.BatchNorm2d):
              nn.init.constant_(m.weight, 1)
              nn.init.constant_(m.bias, 0)
  
imports: import math
  import torch
  import torch.nn
  import torch.nn.functional
  from speechbrain.nnet.normalization import BatchNorm1d
  from speechbrain.nnet.linear import Linear
label_desc: Use image node_id 1 to create a new ResNet object from inherited base classes: nn with example: obj = ResNet(input_size, device, activation, channels, block_sizes, strides, lin_neurons)