class_docstr: Densely-connected layer class with local reparameterization estimator.
  
  This layer implements the Bayesian variational inference analogue to
  a dense layer by assuming the `kernel` and/or the `bias` are drawn
  from distributions. By default, the layer implements a stochastic
  forward pass via sampling from the kernel and bias posteriors,
  
  ```none
  kernel, bias ~ posterior
  outputs = activation(matmul(inputs, kernel) + bias)
  ```
  
  It uses the local reparameterization estimator [(Kingma et al., 2015)][1],
  which performs a Monte Carlo approximation of the distribution on the hidden
  units induced by the `kernel` and `bias`. The default `kernel_posterior_fn`
  is a normal distribution which factorizes across all elements of the weight
  matrix and bias vector. Unlike [1]'s multiplicative parameterization, this
  distribution has trainable location and scale parameters which is known as
  an additive noise parameterization [(Molchanov et al., 2017)][2].
  
  The arguments permit separate specification of the surrogate posterior
  (`q(W|x)`), prior (`p(W)`), and divergence for both the `kernel` and `bias`
  distributions.
  
  Upon being built, this layer adds losses (accessible via the `losses`
  property) representing the divergences of `kernel` and/or `bias` surrogate
  posteriors and their respective priors. When doing minibatch stochastic
  optimization, make sure to scale this loss such that it is applied just once
  per epoch (e.g. if `kl` is the sum of `losses` for each element of the batch,
  you should pass `kl / num_examples_per_epoch` to your optimizer).
  
  You can access the `kernel` and/or `bias` posterior and prior distributions
  after the layer is built via the `kernel_posterior`, `kernel_prior`,
  `bias_posterior` and `bias_prior` properties.
  
  #### Examples
  
  We illustrate a Bayesian neural network with [variational inference](
  https://en.wikipedia.org/wiki/Variational_Bayesian_methods),
  assuming a dataset of `features` and `labels`.
  
  ```python
  import tensorflow_probability as tfp
  
  model = tf_keras.Sequential([
      tfp.layers.DenseLocalReparameterization(512, activation=tf.nn.relu),
      tfp.layers.DenseLocalReparameterization(10),
  ])
  
  logits = model(features)
  neg_log_likelihood = tf.nn.softmax_cross_entropy_with_logits(
      labels=labels, logits=logits)
  kl = sum(model.losses)
  loss = neg_log_likelihood + kl
  train_op = tf.train.AdamOptimizer().minimize(loss)
  ```
  
  It uses local reparameterization gradients to minimize the
  Kullback-Leibler divergence up to a constant, also known as the
  negative Evidence Lower Bound. It consists of the sum of two terms:
  the expected negative log-likelihood, which we approximate via
  Monte Carlo; and the KL divergence, which is added via regularizer
  terms which are arguments to the layer.
  
  #### References
  
  [1]: Diederik Kingma, Tim Salimans, and Max Welling. Variational Dropout and
       the Local Reparameterization Trick. In _Neural Information Processing
       Systems_, 2015. https://arxiv.org/abs/1506.02557
  [2]: Dmitry Molchanov, Arsenii Ashukha, Dmitry Vetrov. Variational Dropout
       Sparsifies Deep Neural Networks. In _International Conference on Machine
       Learning_, 2017. https://arxiv.org/abs/1701.05369
code: def _apply_variational_kernel(self, inputs):
      if not isinstance(
          self.kernel_posterior, independent_lib.Independent
      ) or not isinstance(
          self.kernel_posterior.distribution, normal_lib.Normal
      ):
          raise TypeError(
              "`DenseLocalReparameterization` requires "
              "`kernel_posterior_fn` produce an instance of "
              "`tfd.Independent(tfd.Normal)` "
              '(saw: "{}").'.format(self.kernel_posterior.name)
          )
      self.kernel_posterior_affine = normal_lib.Normal(
          loc=tf.matmul(inputs, self.kernel_posterior.distribution.loc),
          scale=tf.sqrt(
              tf.matmul(
                  tf.square(inputs),
                  tf.square(self.kernel_posterior.distribution.scale),
              )
          ),
      )
      self.kernel_posterior_affine_tensor = (
          self.kernel_posterior_tensor_fn(self.kernel_posterior_affine)
      )
      self.kernel_posterior_tensor = None
      return self.kernel_posterior_affine_tensor
  
imports: import tensorflow.compat.v2
  from tensorflow_probability.python import random
  from tensorflow_probability.python.distributions import independent
  from tensorflow_probability.python.distributions import kullback_leibler
  from tensorflow_probability.python.distributions import normal
  from tensorflow_probability.python.internal import docstring_util
  from tensorflow_probability.python.internal import tf_keras
  from tensorflow_probability.python.layers import util
  from tensorflow_probability.python.util import SeedStream
label_desc: Use image node_id 2 for calling the DenseLocalReparameterization obj's underlying member method code with example usage: obj._apply_variational_kernel(inputs) and returns: self