class_docstr: Class implementing a convolutional layer in the interval/box domain.
class_docstr_tok: ["Class","implementing","a","convolutional","layer","in","the","interval\/box","domain","."]
docstr: Creates the equivalent dense weights for the specified convolutional layer.
  
  :param in_channels: Number of input channels
  :param out_channels: Number of output channels
  :param kernel_size: Shape of the convolutional kernel
  :param device: Device to put the weights onto
  :param stride: The convolution's stride
  :param padding: Size of padding to use
  :param dilation: Dilation to apply to the convolution
  :param bias: If to include a bias term
  :param supplied_input_weights: Load in a pre-defined set of convolutional weights with the correct specification
  :param supplied_input_bias: Load in a pre-defined set of convolutional bias with the correct specification
  :param to_debug: Helper parameter to help with debugging.
docstr_tok: ["Creates","the","equivalent","dense","weights","for","the","specified","convolutional","layer",".",":","param","in_channels",":","Number","of","input","channels",":","param","out_channels",":","Number","of","output","channels",":","param","kernel_size",":","Shape","of","the","convolutional","kernel",":","param","device",":","Device","to","put","the","weights","onto",":","param","stride",":","The","convolution","'s","stride",":","param","padding",":","Size","of","padding","to","use",":","param","dilation",":","Dilation","to","apply","to","the","convolution",":","param","bias",":","If","to","include","a","bias","term",":","param","supplied_input_weights",":","Load","in","a","pre-defined","set","of","convolutional","weights","with","the","correct","specification",":","param","supplied_input_bias",":","Load","in","a","pre-defined","set","of","convolutional","bias","with","the","correct","specification",":","param","to_debug",":","Helper","parameter","to","help","with","debugging","."]
code: def __init__(
      self,
      in_channels: int,
      out_channels: int,
      kernel_size: Union[int, Tuple[int, int]],
      input_shape: Tuple[int, ...],
      device: Union[str, "torch.device"],
      stride: Union[int, Tuple[int, int]] = 1,
      padding: Union[int, Tuple[int, int]] = 0,
      dilation: Union[int, Tuple[int, int]] = 0,
      bias: bool = True,
      supplied_input_weights: Union[None, "torch.Tensor"] = None,
      supplied_input_bias: Union[None, "torch.Tensor"] = None,
      to_debug: bool = False,
  ):
      """
      Creates the equivalent dense weights for the specified convolutional layer.
  
      :param in_channels: Number of input channels
      :param out_channels: Number of output channels
      :param kernel_size: Shape of the convolutional kernel
      :param device: Device to put the weights onto
      :param stride: The convolution's stride
      :param padding: Size of padding to use
      :param dilation: Dilation to apply to the convolution
      :param bias: If to include a bias term
      :param supplied_input_weights: Load in a pre-defined set of convolutional weights with the correct specification
      :param supplied_input_bias: Load in a pre-defined set of convolutional bias with the correct specification
      :param to_debug: Helper parameter to help with debugging.
      """
  
      self.in_channels = in_channels
      self.out_channels = out_channels
      self.kernel_size = kernel_size
      self.padding = padding
      self.dilation = dilation
      self.stride = stride
      self.device = device
      self.include_bias = bias
      self.cnn: Optional["torch.nn.Conv2d"] = None
  
      super().__init__()
      self.conv = torch.nn.Conv2d(
          in_channels=1,
          out_channels=out_channels * in_channels,
          kernel_size=kernel_size,
          padding=padding,
          dilation=dilation,
          bias=False,
          stride=stride,
      ).to(device)
      self.bias_to_grad = None
  
      if bias:
          self.bias_to_grad = torch.nn.Parameter(
              torch.rand(out_channels).to(device)
          )
  
      if to_debug:
          self.conv_debug = torch.nn.Conv2d(
              in_channels=in_channels,
              out_channels=out_channels,
              kernel_size=kernel_size,
              bias=bias,
              stride=stride,
              padding=padding,
              dilation=dilation,
          ).to(device)
  
          if isinstance(kernel_size, tuple):
              self.conv.weight = torch.nn.Parameter(
                  torch.reshape(
                      torch.tensor(
                          self.conv_debug.weight.data.cpu()
                          .detach()
                          .numpy()
                      ),
                      (
                          out_channels * in_channels,
                          1,
                          kernel_size[0],
                          kernel_size[1],
                      ),
                  ).to(device)
              )
          else:
              self.conv.weight = torch.nn.Parameter(
                  torch.reshape(
                      torch.tensor(
                          self.conv_debug.weight.data.cpu()
                          .detach()
                          .numpy()
                      ),
                      (
                          out_channels * in_channels,
                          1,
                          kernel_size,
                          kernel_size,
                      ),
                  ).to(device)
              )
          if bias and self.conv_debug.bias is not None:
              self.bias_to_grad = torch.nn.Parameter(
                  torch.tensor(
                      self.conv_debug.bias.data.cpu().detach().numpy()
                  ).to(device)
              )
  
      if supplied_input_weights is not None:
          if isinstance(kernel_size, tuple):
              self.conv.weight = torch.nn.Parameter(
                  torch.reshape(
                      supplied_input_weights,
                      (
                          out_channels * in_channels,
                          1,
                          kernel_size[0],
                          kernel_size[1],
                      ),
                  )
              )
          else:
              self.conv.weight = torch.nn.Parameter(
                  torch.reshape(
                      supplied_input_weights,
                      (
                          out_channels * in_channels,
                          1,
                          kernel_size,
                          kernel_size,
                      ),
                  )
              )
  
      if supplied_input_bias is not None:
          self.bias_to_grad = torch.nn.Parameter(
              supplied_input_bias.to(device)
          )
  
      self.in_channels = in_channels
      self.out_channels = out_channels
      self.input_height = input_shape[2]
      self.input_width = input_shape[3]
  
      self.output_height: int = 0
      self.output_width: int = 0
  
      self.dense_weights, self.bias = self.convert_to_dense(device)
  
      self.dense_weights = self.dense_weights.to(device)
      if self.bias is not None:
          self.bias = self.bias.to(device)
  
imports: from typing import List, Union, Tuple, Optional
  import torch
  import numpy
label_desc: Use image node_id 1 to create a new PyTorchIntervalConv2D object from inherited base classes: torch.nn with example: obj = PyTorchIntervalConv2D(in_channels, out_channels, kernel_size, input_shape, device, stride, padding, dilation, bias, supplied_input_weights, supplied_input_bias, to_debug)