class_docstr: Decoder Network.
  
  Args:
      input_size (tuple[int, int]): Size of input image
      latent_vec_size (int): Size of latent vector z
      num_input_channels (int): Number of input channels in the image
      n_features (int): Number of features per convolution layer
      extra_layers (int): Number of extra layers since the network uses only a single encoder layer by default.
          Defaults to 0.
class_docstr_tok: ["Decoder","Network",".","Args",":","input_size","(","tuple","[","int",",","int","]",")",":","Size","of","input","image","latent_vec_size","(","int",")",":","Size","of","latent","vector","z","num_input_channels","(","int",")",":","Number","of","input","channels","in","the","image","n_features","(","int",")",":","Number","of","features","per","convolution","layer","extra_layers","(","int",")",":","Number","of","extra","layers","since","the","network","uses","only","a","single","encoder","layer","by","default",".","Defaults","to","0","."]
code: def __init__(
      self,
      input_size: tuple[int, int],
      latent_vec_size: int,
      num_input_channels: int,
      n_features: int,
      extra_layers: int = 0,
  ) -> None:
      super().__init__()
  
      self.latent_input = nn.Sequential()
  
      # Calculate input channel size to recreate inverse pyramid
      exp_factor = math.ceil(math.log(min(input_size) // 2, 2)) - 2
      n_input_features = n_features * (2**exp_factor)
  
      # CNN layer for latent vector input
      self.latent_input.add_module(
          f"initial-{latent_vec_size}-{n_input_features}-convt",
          nn.ConvTranspose2d(
              latent_vec_size,
              n_input_features,
              kernel_size=4,
              stride=1,
              padding=0,
              bias=False,
          ),
      )
      self.latent_input.add_module(
          f"initial-{n_input_features}-batchnorm",
          nn.BatchNorm2d(n_input_features),
      )
      self.latent_input.add_module(
          f"initial-{n_input_features}-relu", nn.ReLU(True)
      )
  
      # Create inverse pyramid
      self.inverse_pyramid = nn.Sequential()
      pyramid_dim = (
          min(*input_size) // 2
      )  # Use the smaller dimension to create pyramid.
      while pyramid_dim > 4:
          in_features = n_input_features
          out_features = n_input_features // 2
          self.inverse_pyramid.add_module(
              f"pyramid-{in_features}-{out_features}-convt",
              nn.ConvTranspose2d(
                  in_features,
                  out_features,
                  kernel_size=4,
                  stride=2,
                  padding=1,
                  bias=False,
              ),
          )
          self.inverse_pyramid.add_module(
              f"pyramid-{out_features}-batchnorm",
              nn.BatchNorm2d(out_features),
          )
          self.inverse_pyramid.add_module(
              f"pyramid-{out_features}-relu", nn.ReLU(True)
          )
          n_input_features = out_features
          pyramid_dim = pyramid_dim // 2
  
      # Extra Layers
      self.extra_layers = nn.Sequential()
      for layer in range(extra_layers):
          self.extra_layers.add_module(
              f"extra-layers-{layer}-{n_input_features}-conv",
              nn.Conv2d(
                  n_input_features,
                  n_input_features,
                  kernel_size=3,
                  stride=1,
                  padding=1,
                  bias=False,
              ),
          )
          self.extra_layers.add_module(
              f"extra-layers-{layer}-{n_input_features}-batchnorm",
              nn.BatchNorm2d(n_input_features),
          )
          self.extra_layers.add_module(
              f"extra-layers-{layer}-{n_input_features}-relu",
              nn.LeakyReLU(0.2, inplace=True),
          )
  
      # Final layers
      self.final_layers = nn.Sequential()
      self.final_layers.add_module(
          f"final-{n_input_features}-{num_input_channels}-convt",
          nn.ConvTranspose2d(
              n_input_features,
              num_input_channels,
              kernel_size=4,
              stride=2,
              padding=1,
              bias=False,
          ),
      )
      self.final_layers.add_module(
          f"final-{num_input_channels}-tanh", nn.Tanh()
      )
  
imports: from __future__ import annotations
  import math
  import torch
  from torch import Tensor, nn
  from anomalib.data.utils.image import pad_nextpow2
label_desc: Use image node_id 1 to create a new Decoder object from inherited base classes: nn with example: obj = Decoder(input_size, latent_vec_size, num_input_channels, n_features, extra_layers)