class_docstr: The layer outputs both the convolution, and the log determinant
  of its weight matrix.  If reverse=True it does convolution with
  inverse
class_docstr_tok: ["The","layer","outputs","both","the","convolution",",","and","the","log","determinant","of","its","weight","matrix",".","If","reverse=True","it","does","convolution","with","inverse"]
code: def forward(self, z, reverse=False):
      # shape
      batch_size, group_size, n_of_groups = z.size()
  
      W = self.conv.weight.squeeze()
  
      if reverse:
          if not hasattr(self, "W_inverse"):
              # Reverse computation
              W_inverse = W.float().inverse()
              W_inverse = Variable(W_inverse[..., None])
              if z.type() == "torch.cuda.HalfTensor":
                  W_inverse = W_inverse.half()
              self.W_inverse = torch.nn.Parameter(W_inverse.detach())
          z = F.conv1d(
              z, self.W_inverse, bias=None, stride=1, padding=0
          )
          return z
      else:
          # Forward computation
          log_det_W = batch_size * n_of_groups * torch.logdet(W)
          z = self.conv(z)
          return z, log_det_W
  
imports: import copy
  import torch
  from torch.autograd import Variable
  import torch.nn.functional
label_desc: Use image node_id 2 for calling the Invertible1x1Conv obj's underlying member method code with example usage: obj.forward(z, reverse) and returns: z, z,  log_det_W