class_docstr: A bijection that generalizes a permutation on the channels of a batch of 2D
  image in :math:`[\ldots,C,H,W]` format conditioning on an additional context
  variable. Specifically this transform performs the operation,
  
      :math:`\mathbf{y} = \text{torch.nn.functional.conv2d}(\mathbf{x}, W)`
  
  where :math:`\mathbf{x}` are the inputs, :math:`\mathbf{y}` are the outputs,
  and :math:`W\sim C\times C\times 1\times 1` is the filter matrix for a 1x1
  convolution with :math:`C` input and output channels.
  
  Ignoring the final two dimensions, :math:`W` is restricted to be the matrix
  product,
  
      :math:`W = PLU`
  
  where :math:`P\sim C\times C` is a permutation matrix on the channel
  dimensions, and  :math:`LU\sim C\times C` is an invertible product of a lower
  triangular and an upper triangular matrix that is the output of an NN with
  input :math:`z\in\mathbb{R}^{M}` representing the context variable to
  condition on.
  
  The input :math:`\mathbf{x}` and output :math:`\mathbf{y}` both have shape
  `[...,C,H,W]`, where `C` is the number of channels set at initialization.
  
  This operation was introduced in [1] for Glow normalizing flow, and is also
  known as 1x1 invertible convolution. It appears in other notable work such as
  [2,3], and corresponds to the class `tfp.bijectors.MatvecLU` of TensorFlow
  Probability.
  
  Example usage:
  
  >>> from pyro.nn.dense_nn import DenseNN
  >>> context_dim = 5
  >>> batch_size = 3
  >>> channels = 3
  >>> base_dist = dist.Normal(torch.zeros(channels, 32, 32),
  ... torch.ones(channels, 32, 32))
  >>> hidden_dims = [context_dim*10, context_dim*10]
  >>> nn = DenseNN(context_dim, hidden_dims, param_dims=[channels*channels])
  >>> transform = ConditionalGeneralizedChannelPermute(nn, channels=channels)
  >>> z = torch.rand(batch_size, context_dim)
  >>> flow_dist = dist.ConditionalTransformedDistribution(base_dist,
  ... [transform]).condition(z)
  >>> flow_dist.sample(sample_shape=torch.Size([batch_size])) # doctest: +SKIP
  
  :param nn: a function inputting the context variable and outputting
      real-valued parameters of dimension :math:`C^2`.
  :param channels: Number of channel dimensions in the input.
  :type channels: int
  
  [1] Diederik P. Kingma, Prafulla Dhariwal. Glow: Generative Flow with Invertible
  1x1 Convolutions. [arXiv:1807.03039]
  
  [2] Ryan Prenger, Rafael Valle, Bryan Catanzaro. WaveGlow: A Flow-based
  Generative Network for Speech Synthesis. [arXiv:1811.00002]
  
  [3] Conor Durkan, Artur Bekasov, Iain Murray, George Papamakarios. Neural Spline
  Flows. [arXiv:1906.04032]
class_docstr_tok: ["A","bijection","that","generalizes","a","permutation","on","the","channels","of","a","batch","of","2D","image","in",":","math",":","`","[","\\ldots",",","C",",","H",",","W","]","`","format","conditioning","on","an","additional","context","variable",".","Specifically","this","transform","performs","the","operation",",",":","math",":","`","\\mathbf","{","y","}","=","\\text","{","torch.nn.functional.conv2d","}","(","\\mathbf","{","x","}",",","W",")","`","where",":","math",":","`","\\mathbf","{","x","}","`","are","the","inputs",",",":","math",":","`","\\mathbf","{","y","}","`","are","the","outputs",",","and",":","math",":","`","W\\sim","C\\times","C\\times","1\\times","1","`","is","the","filter","matrix","for","a","1x1","convolution","with",":","math",":","`","C","`","input","and","output","channels",".","Ignoring","the","final","two","dimensions",",",":","math",":","`","W","`","is","restricted","to","be","the","matrix","product",",",":","math",":","`","W","=","PLU","`","where",":","math",":","`","P\\sim","C\\times","C","`","is","a","permutation","matrix","on","the","channel","dimensions",",","and",":","math",":","`","LU\\sim","C\\times","C","`","is","an","invertible","product","of","a","lower","triangular","and","an","upper","triangular","matrix","that","is","the","output","of","an","NN","with","input",":","math",":","`","z\\in\\mathbb","{","R","}","^","{","M","}","`","representing","the","context","variable","to","condition","on",".","The","input",":","math",":","`","\\mathbf","{","x","}","`","and","output",":","math",":","`","\\mathbf","{","y","}","`","both","have","shape","`","[","...",",","C",",","H",",","W","]","`",",","where","`","C","`","is","the","number","of","channels","set","at","initialization",".","This","operation","was","introduced","in","[","1","]","for","Glow","normalizing","flow",",","and","is","also","known","as","1x1","invertible","convolution",".","It","appears","in","other","notable","work","such","as","[","2,3","]",",","and","corresponds","to","the","class","`","tfp.bijectors.MatvecLU","`","of","TensorFlow","Probability",".","Example","usage",":",">",">",">","from","pyro.nn.dense_nn","import","DenseNN",">",">",">","context_dim","=","5",">",">",">","batch_size","=","3",">",">",">","channels","=","3",">",">",">","base_dist","=","dist.Normal","(","torch.zeros","(","channels",",","32",",","32",")",",","...","torch.ones","(","channels",",","32",",","32",")",")",">",">",">","hidden_dims","=","[","context_dim","*","10",",","context_dim","*","10","]",">",">",">","nn","=","DenseNN","(","context_dim",",","hidden_dims",",","param_dims=","[","channels","*","channels","]",")",">",">",">","transform","=","ConditionalGeneralizedChannelPermute","(","nn",",","channels=channels",")",">",">",">","z","=","torch.rand","(","batch_size",",","context_dim",")",">",">",">","flow_dist","=","dist.ConditionalTransformedDistribution","(","base_dist",",","...","[","transform","]",")",".condition","(","z",")",">",">",">","flow_dist.sample","(","sample_shape=torch.Size","(","[","batch_size","]",")",")","#","doctest",":","+SKIP",":","param","nn",":","a","function","inputting","the","context","variable","and","outputting","real-valued","parameters","of","dimension",":","math",":","`","C^2","`",".",":","param","channels",":","Number","of","channel","dimensions","in","the","input",".",":","type","channels",":","int","[","1","]","Diederik","P.","Kingma",",","Prafulla","Dhariwal",".","Glow",":","Generative","Flow","with","Invertible","1x1","Convolutions",".","[","arXiv:1807.03039","]","[","2","]","Ryan","Prenger",",","Rafael","Valle",",","Bryan","Catanzaro",".","WaveGlow",":","A","Flow-based","Generative","Network","for","Speech","Synthesis",".","[","arXiv:1811.00002","]","[","3","]","Conor","Durkan",",","Artur","Bekasov",",","Iain","Murray",",","George","Papamakarios",".","Neural","Spline","Flows",".","[","arXiv:1906.04032","]"]
code: def condition(self, context):
      LU = self.nn(context)
      LU = LU.view(LU.shape[:-1] + (self.channels, self.channels))
      return ConditionedGeneralizedChannelPermute(self.permutation, LU)
  
imports: import torch
  from torch.distributions import Transform
  from pyro.nn import DenseNN
  from ..None import constraints
  from ..conditional import ConditionalTransformModule
  from ..torch_transform import TransformModule
  from ..util import copy_docs_from
label_desc: Use image node_id 2 for calling the ConditionalGeneralizedChannelPermute obj's underlying member method code with example usage: obj.condition(context) and returns: ConditionedGeneralizedChannelPermute