code: def testAffineCustomParamsDist(self):
      def params_model_fn(out_units, in_units, dtype):
          yield Root(
              lognormal.LogNormal(
                  tf.zeros([out_units, in_units], dtype),
                  1.0,
                  name="weights",
              )
          )
          yield Root(
              lognormal.LogNormal(
                  tf.zeros([out_units], dtype), 1.0, name="bias"
              )
          )
  
      dist = jdlayers.Affine(
          5, 4, dtype=self.dtype, params_model_fn=params_model_fn
      )
      layer = dist.sample(
          seed=test_util.test_seed(sampler_type="stateless")
      )
      x = tf.ones([4], self.dtype)
      y = layer(x)
      self.assertAllEqual([5], y.shape)
      self.assertEqual(self.dtype, y.dtype)
      # Since the parameters are log-normal, the outputs will be positive for
      # positive inputs.
      self.assertAllTrue(y > 0.0)
  
imports: from absl.testing import parameterized
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import chain
  from tensorflow_probability.python.bijectors import real_nvp
  from tensorflow_probability.python.bijectors import scale
  from tensorflow_probability.python.bijectors import shift
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import joint_distribution_coroutine
  from tensorflow_probability.python.distributions import lognormal
  from tensorflow_probability.python.experimental.joint_distribution_layers import layers
  from tensorflow_probability.python.internal import custom_gradient
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import test_util
  from tensorflow_probability.python.math import gradient
label_desc: Use image node_id 4 for calling the _JDLayersTestBase obj's underlying member method code with example usage: obj.testAffineCustomParamsDist() without return types