class_docstr: A 2D upsampling layer with an optional convolution.
  
  Parameters:
      channels (`int`):
          number of channels in the inputs and outputs.
      use_conv (`bool`, default `False`):
          option to use a convolution.
      use_conv_transpose (`bool`, default `False`):
          option to use a convolution transpose.
      out_channels (`int`, optional):
          number of output channels. Defaults to `channels`.
      name (`str`, default `conv`):
          name of the upsampling 2D layer.
class_docstr_tok: ["A","2D","upsampling","layer","with","an","optional","convolution",".","Parameters",":","channels","(","`","int","`",")",":","number","of","channels","in","the","inputs","and","outputs",".","use_conv","(","`","bool","`",",","default","`","False","`",")",":","option","to","use","a","convolution",".","use_conv_transpose","(","`","bool","`",",","default","`","False","`",")",":","option","to","use","a","convolution","transpose",".","out_channels","(","`","int","`",",","optional",")",":","number","of","output","channels",".","Defaults","to","`","channels","`",".","name","(","`","str","`",",","default","`","conv","`",")",":","name","of","the","upsampling","2D","layer","."]
code: def __init__(
      self,
      channels: int,
      use_conv: bool = False,
      use_conv_transpose: bool = False,
      out_channels: Optional[int] = None,
      name: str = "conv",
      kernel_size: Optional[int] = None,
      padding=1,
      norm_type=None,
      eps=None,
      elementwise_affine=None,
      bias=True,
      interpolate=True,
  ):
      super().__init__()
      self.channels = channels
      self.out_channels = out_channels or channels
      self.use_conv = use_conv
      self.use_conv_transpose = use_conv_transpose
      self.name = name
      self.interpolate = interpolate
      conv_cls = nn.Conv2d if USE_PEFT_BACKEND else LoRACompatibleConv
  
      if norm_type == "ln_norm":
          self.norm = nn.LayerNorm(channels, eps, elementwise_affine)
      elif norm_type == "rms_norm":
          self.norm = RMSNorm(channels, eps, elementwise_affine)
      elif norm_type is None:
          self.norm = None
      else:
          raise ValueError(f"unknown norm_type: {norm_type}")
  
      conv = None
      if use_conv_transpose:
          if kernel_size is None:
              kernel_size = 4
          conv = nn.ConvTranspose2d(
              channels,
              self.out_channels,
              kernel_size=kernel_size,
              stride=2,
              padding=padding,
              bias=bias,
          )
      elif use_conv:
          if kernel_size is None:
              kernel_size = 3
          conv = conv_cls(
              self.channels,
              self.out_channels,
              kernel_size=kernel_size,
              padding=padding,
              bias=bias,
          )
  
      # TODO(Suraj, Patrick) - clean up after weight dicts are correctly renamed
      if name == "conv":
          self.conv = conv
      else:
          self.Conv2d_0 = conv
  
imports: from typing import Optional, Tuple
  import torch
  import torch.nn
  import torch.nn.functional
  from ..utils import USE_PEFT_BACKEND
  from .lora import LoRACompatibleConv
  from .normalization import RMSNorm
label_desc: Use image node_id 1 to create a new Upsample2D object from inherited base classes: nn with example: obj = Upsample2D(channels, use_conv, use_conv_transpose, out_channels, name, kernel_size, padding, norm_type, eps, elementwise_affine, bias, interpolate)