docstr: Samples from the distribution, with optional conditional input.
  
  Parameters
  ----------
  n
      `int`, number of samples desired.
  seed
      `int`, seed for RNG. Setting a random seed enforces reproducibility
      of the samples between sessions (not within a single session).
  conditional_input
      `Tensor` on which to condition the distribution (e.g.
      class labels), or `None`.
  training
      `bool` or `None`. If `bool`, it controls the dropout layer,
      where `True` implies dropout is active. If `None`, it defers to Keras'
      handling of train/eval status.
  
  Returns
  -------
  samples
      a `Tensor` of shape `[n, height, width, num_channels]`.
code: def _sample_n(
      self, n, seed=None, conditional_input=None, training=False
  ):
      """Samples from the distribution, with optional conditional input.
  
      Parameters
      ----------
      n
          `int`, number of samples desired.
      seed
          `int`, seed for RNG. Setting a random seed enforces reproducibility
          of the samples between sessions (not within a single session).
      conditional_input
          `Tensor` on which to condition the distribution (e.g.
          class labels), or `None`.
      training
          `bool` or `None`. If `bool`, it controls the dropout layer,
          where `True` implies dropout is active. If `None`, it defers to Keras'
          handling of train/eval status.
  
      Returns
      -------
      samples
          a `Tensor` of shape `[n, height, width, num_channels]`.
      """
      if conditional_input is not None:
          conditional_input = tf.convert_to_tensor(
              conditional_input, dtype=self.dtype
          )
          conditional_event_rank = tensorshape_util.rank(
              self.conditional_shape
          )
          conditional_input_shape = prefer_static.shape(
              conditional_input
          )
          conditional_sample_rank = (
              prefer_static.rank(conditional_input)
              - conditional_event_rank
          )
  
          # If `conditional_input` has no sample dimensions, prepend a sample
          # dimension
          if conditional_sample_rank == 0:
              conditional_input = conditional_input[tf.newaxis, ...]
              conditional_sample_rank = 1
  
          # Assert that the conditional event shape in the `PixelCnnNetwork` is the
          # same as that implied by `conditional_input`.
          conditional_event_shape = conditional_input_shape[
              conditional_sample_rank:
          ]
          with tf.control_dependencies(
              [
                  tf.assert_equal(
                      self.conditional_shape, conditional_event_shape
                  )
              ]
          ):
              conditional_sample_shape = conditional_input_shape[
                  :conditional_sample_rank
              ]
              repeat = n // prefer_static.reduce_prod(
                  conditional_sample_shape
              )
              h = tf.reshape(
                  conditional_input,
                  prefer_static.concat(
                      [(-1,), self.conditional_shape], axis=0
                  ),
              )
              h = tf.tile(
                  h,
                  prefer_static.pad(
                      [repeat],
                      paddings=[[0, conditional_event_rank]],
                      constant_values=1,
                  ),
              )
  
      samples_0 = tf.random.uniform(
          prefer_static.concat([(n,), self.event_shape], axis=0),
          minval=-1.0,
          maxval=1.0,
          dtype=self.dtype,
          seed=seed,
      )
      inputs = (
          samples_0 if conditional_input is None else [samples_0, h]
      )
      params_0 = self.network(inputs, training=training)
      samples_0 = self._sample_channels(*params_0, seed=seed)
  
      image_height, image_width, _ = tensorshape_util.as_list(
          self.event_shape
      )
  
      def loop_body(index, samples):
          """Loop for iterative pixel sampling.
  
              Parameters
              ----------
              index
                  0D `Tensor` of type `int32`. Index of the current pixel.
              samples
                4D `Tensor`. Images with pixels sampled in raster order, up to
                pixel `[index]`, with dimensions `[batch_size, height, width,
                num_channels]`.
  
              Returns
              -------
              samples
                  4D `Tensor`. Images with pixels sampled in raster order, up to \
                  and including pixel `[index]`, with dimensions `[batch_size, height, \
                  width, num_channels]`.
              """
          inputs = (
              samples if conditional_input is None else [samples, h]
          )
          params = self.network(inputs, training=training)
          samples_new = self._sample_channels(*params, seed=seed)
  
          # Update the current pixel
          samples = tf.transpose(samples, [1, 2, 3, 0])
          samples_new = tf.transpose(samples_new, [1, 2, 3, 0])
          row, col = index // image_width, index % image_width
          updates = samples_new[row, col, ...][tf.newaxis, ...]
          samples = tf.tensor_scatter_nd_update(
              samples, [[row, col]], updates
          )
          samples = tf.transpose(samples, [3, 0, 1, 2])
  
          return index + 1, samples
  
      index0 = tf.zeros([], dtype=tf.int32)
  
      # Construct the while loop for sampling
      total_pixels = image_height * image_width
      loop_cond = lambda ind, _: tf.less(
          ind, total_pixels
      )  # noqa: E731
      init_vars = (index0, samples_0)
      _, samples = tf.while_loop(
          loop_cond, loop_body, init_vars, parallel_iterations=1
      )
  
      transformed_samples = self._low + 0.5 * (
          self._high - self._low
      ) * (samples + 1.0)
      return tf.round(transformed_samples)
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import functools
  import numpy
  import warnings
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import bijector
  from tensorflow_probability.python.distributions import categorical
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import independent
  from tensorflow_probability.python.distributions import logistic
  from tensorflow_probability.python.distributions import mixture_same_family
  from tensorflow_probability.python.distributions import quantized_distribution
  from tensorflow_probability.python.distributions import transformed_distribution
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import reparameterization
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.internal import tensorshape_util
label_desc: Use image node_id 4 for calling the PixelCNN obj's underlying member method code with example usage: obj._sample_n(n, seed, conditional_input, training) and returns: tf, unknown,  samples