code: def _make_dense_autoregressive_masks(
      params,
      event_size,
      hidden_units,
      input_order="left-to-right",
      hidden_degrees="equal",
      seed=None,
  ):
      """Creates masks for use in dense MADE [Germain et al. (2015)][1] networks.
  
      See the documentation for `AutoregressiveNetwork` for the theory and
      application of MADE networks. This function lets you construct your own dense
      MADE networks by applying the returned masks to each dense layer. E.g. a
      consider an autoregressive network that takes `event_size`-dimensional vectors
      and produces `params`-parameters per input, with `num_hidden` hidden layers,
      with `hidden_size` hidden units each.
  
      ```python
      def random_made(x):
        masks = tfb._make_dense_autoregressive_masks(
            params=params,
            event_size=event_size,
            hidden_units=[hidden_size] * num_hidden)
        output_sizes = [hidden_size] * num_hidden
        input_size = event_size
        for (mask, output_size) in zip(masks, output_sizes):
          mask = tf.cast(mask, tf.float32)
          x = tf.matmul(x, tf.random.normal([input_size, output_size]) * mask)
          x = tf.nn.relu(x)
          input_size = output_size
        x = tf.matmul(
            x,
            tf.random.normal([input_size, params * event_size]) * masks[-1])
        x = tf.reshape(x, [-1, event_size, params])
        return x
  
      y = random_made(tf.zeros([1, event_size]))
      assert [1, event_size, params] == y.shape
      ```
  
      Each mask is a Numpy boolean array. All masks have the shape `[input_size,
      output_size]`. For example, if we `hidden_units` is a list of two integers,
      the mask shapes will be: `[event_size, hidden_units[0]], [hidden_units[0],
      hidden_units[1]], [hidden_units[1], params * event_size]`.
  
      You can extend this example with trainable parameters and constraints if
      necessary.
  
      Args:
        params: Python integer specifying the number of parameters to output
          per input.
        event_size: Python integer specifying the shape of the input to this layer.
        hidden_units: Python `list`-like of non-negative integers, specifying
          the number of units in each hidden layer.
        input_order: Order of degrees to the input units: 'random', 'left-to-right',
          'right-to-left', or an array of an explicit order. For example,
          'left-to-right' builds an autoregressive model
          p(x) = p(x1) p(x2 | x1) ... p(xD | x<D).
        hidden_degrees: Method for assigning degrees to the hidden units:
          'equal', 'random'. If 'equal', hidden units in each layer are allocated
          equally (up to a remainder term) to each degree. Default: 'equal'.
        seed: If not `None`, seed to use for 'random' `input_order` and
          `hidden_degrees`.
  
      Returns:
        masks: A list of masks that should be applied the dense matrices of
          individual densely connected layers in the MADE network. Each mask is a
          Numpy boolean array.
  
      #### References
  
      [1]: Mathieu Germain, Karol Gregor, Iain Murray, and Hugo Larochelle. MADE:
           Masked Autoencoder for Distribution Estimation. In _International
           Conference on Machine Learning_, 2015. https://arxiv.org/abs/1502.03509
      """
      if seed is None:
          input_order_seed = None
          degrees_seed = None
      else:
          input_order_seed, degrees_seed = np.random.RandomState(
              seed
          ).randint(2**31, size=2)
      input_order = _create_input_order(
          event_size, input_order, seed=input_order_seed
      )
      masks = _create_masks(
          _create_degrees(
              input_size=event_size,
              hidden_units=hidden_units,
              input_order=input_order,
              hidden_degrees=hidden_degrees,
              seed=degrees_seed,
          )
      )
      # In the final layer, we will produce `params` outputs for each of the
      # `event_size` inputs.  But `masks[-1]` has shape `[hidden_units[-1],
      # event_size]`.  Thus, we need to expand the mask to `[hidden_units[-1],
      # event_size * params]` such that all units for the same input are masked
      # identically.  In particular, we tile the mask so the j-th element of
      # `tf.unstack(output, axis=-1)` is a tensor of the j-th parameter/unit for
      # each input.
      #
      # NOTE: Other orderings of the output could be faster -- should benchmark.
      masks[-1] = np.reshape(
          np.tile(masks[-1][..., tf.newaxis], [1, 1, params]),
          [masks[-1].shape[0], event_size * params],
      )
      return masks
  
imports: import numpy
  import six
  import tensorflow.compat.v1
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import bijector
  from tensorflow_probability.python.bijectors import chain
  from tensorflow_probability.python.bijectors import scale
  from tensorflow_probability.python.bijectors import shift
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.internal import tf_keras
  from tensorflow_probability.python.math.numeric import clip_by_value_preserve_gradient
  from tensorflow.python.util import deprecation
label_desc: Use image node_id 5 for calling a global function with example usage: _make_dense_autoregressive_masks(params, event_size, hidden_units, input_order, hidden_degrees, seed) and returns: masks