class_docstr: Distributional Temporal Convolutional Network: a TCN to learn a time-
  varying distribution.
  
  Composed of a sequence of causal convolution blocks.
  
  Takes as input a three-dimensional tensor (`B`, `C`, `L`) where `B` is the
  batch size, `C` is the number of input channels, and `L` is the length of
  the input. Outputs a three-dimensional tensor (`B`, `C_out`, `L`).
  
  Args:
      in_channels : Number of input channels, typically the dimensionality of the time series
      out_channels : Number of output channels, typically the number of parameters in the time series distribution
      kernel_size : Kernel size of the applied non-residual convolutions.
      channels : Number of channels processed in the network and of output channels,
              typically equal to out_channels for simplicity, expand for better performance.
      layers : Depth of the network.
      bias : If True, adds a learnable bias to the convolutions.
      fwd_time : If True the network is the relation relation if from past to future (forward),
              if False, the relation from future to past (backward).
      output_distr: Distribution whose parameters will be specified by the network output
code: def __init__(
      self,
      in_channels: int,
      out_channels: int,
      kernel_size: int,
      channels: int,
      layers: int,
      bias: bool = True,
      fwd_time: bool = True,
      output_distr=Normal(torch.tensor([0.0]), torch.tensor([1.0])),
  ):
      super().__init__()
  
      self.out_channels = out_channels
  
      # Temporal Convolution Network
      layers = int(layers)
  
      net_layers = []  # List of sequential TCN blocks
      dilation_size = 1  # Initial dilation size
  
      for i in range(layers):
          in_channels_block = in_channels if i == 0 else channels
          net_layers.append(
              TCNBlock(
                  in_channels=in_channels_block,
                  out_channels=channels,
                  kernel_size=kernel_size,
                  dilation=dilation_size,
                  bias=bias,
                  fwd_time=fwd_time,
                  final=False,
              )
          )
          dilation_size *= 2  # Doubles the dilation size at each step
  
      # Last layer
      net_layers.append(
          TCNBlock(
              in_channels=channels,
              out_channels=self.out_channels,
              kernel_size=kernel_size,
              dilation=dilation_size,
              bias=bias,
              fwd_time=fwd_time,
              final=True,
          )
      )
  
      self.network = torch.nn.Sequential(*net_layers)
      self.output_distr = output_distr
  
imports: import torch
  import torch.nn
  from .tcn import TCNBlock
  from torch.distributions.normal import Normal
label_desc: Use image node_id 1 to create a new DistributionalTCN object from inherited base classes: torch.nn with example: obj = DistributionalTCN(in_channels, out_channels, kernel_size, channels, layers, bias, fwd_time, output_distr)