class_docstr: Perform transposed convolution (aka deconvolution, fractionally stride
  convolution) over input. ``conv_transpose`` can also be used to compute
  gradient of conv. Currently support 1D and 2D only.
  
  Parameters
  ----------
  
  x: tensor<[n,C_in,*D_in],T>  (Required)
      * Input data. ``D_in`` are spatial dimensions. ``1 <= len(D_in) <= 2``
      and ``C_in`` is the number of input channels.
  
  weight: const tensor<[C_out,C_in/groups,*D_in], T> (Required)
      * Filter weights. ``C_in, C_out`` are the number of input and output channels respectively.
      * ``D_in`` are spatial dimensions. ``1 <= len(D_in) <= 2``
  
  bias: const tensor<[C_out],T> (Optional. Default to all 0)
      * Bias added along output channels
  
  pad: const tensor<[P],i32> (Optional. Default to all 0s)
      * Number of elements to pad before and after each dimension
      * ``P == 2 * len(D_in)``
      * ``pad[2*i], pad[2*i+1]`` are pad sizes before and after dimension ``i``, where ``0 <= i < len(D_in)``
  
  output_shape: const tensor<[P],i32> (Optional. Default None)
      * Expected output shape
      * Padding is computed using pad_type and output_shape if provided
  
  pad_type: const tensor<[P],i32> (Optional. Default valid)
      * One of ``same``, ``valid``, or ``custom``
  
  strides: const tensor<[S],i32> (Optional. Default to all 1s)
      * Stride along each of the spatial dimensions. ``S == len(D_in)``
  
  dilations: const tensor<[S],i32> (Optional. Default to all 1s)
      * Dilation value along each spatial dimension in ``d_in``. See `conv`.
      * ``S == len(D_in)``
  
  groups: const tensor<[], i32> (Optional. Default to 1)
      * Input and output channels are separated into ``groups``. ``C_in`` and ``C_out`` must be divisible by the number of groups. See ``conv`` for examples.
  
  Returns
  -------
  tensor<[n,C_out,*D_out],T>
      * ``D_out[i] = (D_in[i]-1) * strides[i] + pad[2*i] + pad[2*i+1] - (K[i] - 1) * dilations[i] + 1)] for i = 0, 1``
  
  Attributes
  ----------
  T: fp32
  
  See Also
  --------
  conv
code: def type_inference(self):
      # Input shape is [n, C_in, spatial_dims]
      in_shape = self.x.shape
      # Weight shape is [C_out, C_in, spatial_dims]
      f_shape = self.weight.shape
      kernel_shape = f_shape[2:]
      spatial_dim_rank = len(in_shape) - 2
      N = in_shape[0]
      C_in = self.x.shape[1]
      groups = self.groups.val
      C_out = f_shape[0] * groups
  
      if self.bias is not None and self.bias.val.shape[0] != C_out:
          msg = "# of bias values {} not equal to # output channels {}"
          raise ValueError(msg.format(self.bias.val.shape[0], C_out))
      if C_out % groups != 0:
          msg = "# of input channels {} not divisible by groups {}"
          raise ValueError(msg.format(C_in, groups))
  
      # If output shape is given, return it
      if self.output_shape is not None:
          return types.tensor(
              self.x.dtype,
              tuple([N, C_out] + list(self.output_shape.val)),
          )
  
      strides = (
          [1] * spatial_dim_rank
          if self.strides is None
          else self.strides.val
      )
      dilations = (
          [1] * spatial_dim_rank
          if self.dilations is None
          else self.dilations.val
      )
      kernel_shape = [
          (kernel_shape[r] - 1) * dilations[r] + 1
          for r in range(spatial_dim_rank)
      ]
  
      D_in = in_shape[2:]  # spatial dimensions
  
      # Deconv's output shape is non-deterministic, we follow TF shape logic here.
      if self.pad_type.val == "same":
          d_out_shape = [
              strides[r] * D_in[r] for r in range(spatial_dim_rank)
          ]
      elif self.pad_type.val == "valid":
          d_out_shape = [
              strides[r] * D_in[r] + kernel_shape[r] - 1
              for r in range(spatial_dim_rank)
          ]
      elif self.pad_type.val == "custom":
          if self.pad is None:
              raise ValueError(
                  "self.pad must exist if pad_type is custom"
              )
          pad = self.pad.val
          d_out_shape = [
              strides[r] * (D_in[r] - 1)
              + kernel_shape[r]
              - pad[2 * r]
              - pad[2 * r + 1]
              for r in range(spatial_dim_rank)
          ]
  
      retshape = [N, C_out] + d_out_shape
      return types.tensor(self.x.dtype, tuple(retshape))
  
file_path: turicreate/src/external/coremltools_wrap/coremltools/coremltools/converters/mil/mil/ops/defs/conv.py
imports: from coremltools.converters.mil.mil.ops.defs._utils import spatial_dimensions_out_shape
  from ._op_reqs import *
label_desc: Use image node_id 2 for calling the conv_transpose obj's underlying member method code with example usage: obj.type_inference() and returns: types, types