class_docstr: Autoregressive distributions.
  
  The Autoregressive distribution enables learning (often) richer multivariate
  distributions by repeatedly applying a [diffeomorphic](
  https://en.wikipedia.org/wiki/Diffeomorphism) transformation (such as
  implemented by `Bijector`s). Regarding terminology,
  
    'Autoregressive models decompose the joint density as a product of
    conditionals, and model each conditional in turn. Normalizing flows
    transform a base density (e.g. a standard Gaussian) into the target density
    by an invertible transformation with tractable Jacobian.' [(Papamakarios et
    al., 2016)][1]
  
  In other words, the 'autoregressive property' is equivalent to the
  decomposition, `p(x) = prod{ p(x[i] | x[0:i]) : i=0, ..., d }`. The provided
  `shift_and_log_scale_fn`, `masked_autoregressive_default_template`, achieves
  this property by zeroing out weights in its `masked_dense` layers.
  
  Practically speaking the autoregressive property means that there exists a
  permutation of the event coordinates such that each coordinate is a
  diffeomorphic function of only preceding coordinates
  [(van den Oord et al., 2016)][2].
  
  #### Mathematical Details
  
  The probability function is
  
  ```none
  prob(x; fn, n) = fn(x).prob(x)
  ```
  
  And a sample is generated by
  
  ```none
  x = fn(...fn(fn(x0).sample()).sample()).sample()
  ```
  
  where the ellipses (`...`) represent `n-2` composed calls to `fn`, `fn`
  constructs a `tfd.Distribution`-like instance, and `x0` is a
  fixed initializing `Tensor`.
  
  #### Examples
  
  ```python
  tfd = tfp.distributions
  tfb = tfp.bijectors
  
  def _normal_fn(event_size):
    n = event_size * (event_size + 1) // 2
    p = tf.Variable(tfd.Normal(loc=0., scale=1.).sample(n))
    affine = tfb.FillScaleTriL(tfp.math.fill_triangular(0.25 * p))
    def _fn(samples):
      scale = tf.exp(affine(samples))
      return tfd.Independent(
          tfd.Normal(loc=0., scale=scale, validate_args=True),
          reinterpreted_batch_ndims=1)
    return _fn
  
  batch_and_event_shape = [3, 2, 4]
  sample0 = tf.zeros(batch_and_event_shape)
  ar = tfd.Autoregressive(
      _normal_fn(batch_and_event_shape[-1]), sample0)
  x = ar.sample([6, 5])
  # ==> x.shape = [6, 5, 3, 2, 4]
  prob_x = ar.prob(x)
  # ==> x.shape = [6, 5, 3, 2]
  
  ```
  
  #### References
  
  [1]: George Papamakarios, Theo Pavlakou, and Iain Murray. Masked
       Autoregressive Flow for Density Estimation. In _Neural Information
       Processing Systems_, 2017. https://arxiv.org/abs/1705.07057
  
  [2]: Aaron van den Oord, Nal Kalchbrenner, Oriol Vinyals, Lasse Espeholt,
       Alex Graves, and Koray Kavukcuoglu. Conditional Image Generation with
       PixelCNN Decoders. In _Neural Information Processing Systems_, 2016.
       https://arxiv.org/abs/1606.05328
docstr: Construct an `Autoregressive` distribution.
  
  Args:
    distribution_fn: Python `callable` which constructs a
      `tfd.Distribution`-like instance from a `Tensor` (e.g.,
      `sample0`). The function must respect the 'autoregressive property',
      i.e., there exists a permutation of event such that each coordinate is a
      diffeomorphic function of only preceding coordinates.
    sample0: Initial input to `distribution_fn`; used to
      build the distribution in `__init__` which in turn specifies this
      distribution's properties, e.g., `event_shape`, `batch_shape`, `dtype`.
      If unspecified, then `distribution_fn` should be default constructable.
    num_steps: Number of times `distribution_fn` is composed from samples,
      e.g., `num_steps=2` implies
      `distribution_fn(distribution_fn(sample0).sample(n)).sample()`.
    validate_args: Python `bool`.  Whether to validate input with asserts.
      If `validate_args` is `False`, and the inputs are invalid,
      correct behavior is not guaranteed.
    allow_nan_stats: Python `bool`, default `True`. When `True`, statistics
      (e.g., mean, mode, variance) use the value '`NaN`' to indicate the
      result is undefined. When `False`, an exception is raised if one or
      more of the statistic's batch members are undefined.
    name: Python `str` name prefixed to Ops created by this class.
      Default value: 'Autoregressive'.
  
  Raises:
    ValueError: if `num_steps < 1`.
docstr_tok: ["Construct","an","`","Autoregressive","`","distribution",".","Args",":","distribution_fn",":","Python","`","callable","`","which","constructs","a","`","tfd.Distribution","`","-like","instance","from","a","`","Tensor","`","(","e.g.",",","`","sample0","`",")",".","The","function","must","respect","the","'autoregressive","property","'",",","i.e.",",","there","exists","a","permutation","of","event","such","that","each","coordinate","is","a","diffeomorphic","function","of","only","preceding","coordinates",".","sample0",":","Initial","input","to","`","distribution_fn","`",";","used","to","build","the","distribution","in","`","__init__","`","which","in","turn","specifies","this","distribution","'s","properties",",","e.g.",",","`","event_shape","`",",","`","batch_shape","`",",","`","dtype","`",".","If","unspecified",",","then","`","distribution_fn","`","should","be","default","constructable",".","num_steps",":","Number","of","times","`","distribution_fn","`","is","composed","from","samples",",","e.g.",",","`","num_steps=2","`","implies","`","distribution_fn","(","distribution_fn","(","sample0",")",".sample","(","n",")",")",".sample","(",")","`",".","validate_args",":","Python","`","bool","`",".","Whether","to","validate","input","with","asserts",".","If","`","validate_args","`","is","`","False","`",",","and","the","inputs","are","invalid",",","correct","behavior","is","not","guaranteed",".","allow_nan_stats",":","Python","`","bool","`",",","default","`","True","`",".","When","`","True","`",",","statistics","(","e.g.",",","mean",",","mode",",","variance",")","use","the","value","'","`","NaN","`","'","to","indicate","the","result","is","undefined",".","When","`","False","`",",","an","exception","is","raised","if","one","or","more","of","the","statistic","'s","batch","members","are","undefined",".","name",":","Python","`","str","`","name","prefixed","to","Ops","created","by","this","class",".","Default","value",":","'Autoregressive","'",".","Raises",":","ValueError",":","if","`","num_steps","<","1","`","."]
code: def __init__(
      self,
      distribution_fn,
      sample0=None,
      num_steps=None,
      validate_args=False,
      allow_nan_stats=True,
      name="Autoregressive",
  ):
      """Construct an `Autoregressive` distribution.
  
      Args:
        distribution_fn: Python `callable` which constructs a
          `tfd.Distribution`-like instance from a `Tensor` (e.g.,
          `sample0`). The function must respect the 'autoregressive property',
          i.e., there exists a permutation of event such that each coordinate is a
          diffeomorphic function of only preceding coordinates.
        sample0: Initial input to `distribution_fn`; used to
          build the distribution in `__init__` which in turn specifies this
          distribution's properties, e.g., `event_shape`, `batch_shape`, `dtype`.
          If unspecified, then `distribution_fn` should be default constructable.
        num_steps: Number of times `distribution_fn` is composed from samples,
          e.g., `num_steps=2` implies
          `distribution_fn(distribution_fn(sample0).sample(n)).sample()`.
        validate_args: Python `bool`.  Whether to validate input with asserts.
          If `validate_args` is `False`, and the inputs are invalid,
          correct behavior is not guaranteed.
        allow_nan_stats: Python `bool`, default `True`. When `True`, statistics
          (e.g., mean, mode, variance) use the value '`NaN`' to indicate the
          result is undefined. When `False`, an exception is raised if one or
          more of the statistic's batch members are undefined.
        name: Python `str` name prefixed to Ops created by this class.
          Default value: 'Autoregressive'.
  
      Raises:
        ValueError: if `num_steps < 1`.
      """
      parameters = dict(locals())
      with tf.name_scope(name) as name:
          self._distribution_fn = distribution_fn
          self._sample0 = tensor_util.convert_nonref_to_tensor(sample0)
          self._num_steps = tensor_util.convert_nonref_to_tensor(
              num_steps, dtype_hint=tf.int32
          )
  
          # We need to call `distribution_fn` once here to determine the `dtype`
          # and `reparameterization_type` of this distribution.  We don't otherwise
          # use the resulting `distribution0`, so this is '`tf.Variable` safe'
          # as long as `distribution_fn` returns `tfd.Distribution` instances with
          # consistent `dtype` and `reparameterization_type`.
          if self._sample0 is not None:
              distribution0 = self._distribution_fn(self._sample0)
          else:
              distribution0 = self._distribution_fn()
  
          super(Autoregressive, self).__init__(
              dtype=distribution0.dtype,
              reparameterization_type=distribution0.reparameterization_type,
              validate_args=validate_args,
              allow_nan_stats=allow_nan_stats,
              parameters=parameters,
              name=name,
          )
  
imports: import warnings
  import tensorflow.compat.v2
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import samplers
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.util.seed_stream import SeedStream
  from tensorflow_probability.python.util.seed_stream import TENSOR_SEED_MSG_PREFIX
  from tensorflow.python.util import deprecation
label_desc: Use image node_id 1 to create a new Autoregressive object from inherited base classes: distribution with example: obj = Autoregressive(distribution_fn, sample0, num_steps, validate_args, allow_nan_stats, name)