def __init__(self, loc, scale, validate_args=False, allow_nan_stats=True, name='LogLogistic'): """Construct a log-logistic distribution. The LogLogistic distribution models positive-valued random variables whose logarithm is a logistic distribution with location `loc` and scale `scale`. It is constructed as the exponential transformation of a Logistic distribution. Args: loc: Floating-point `Tensor`; the location of the underlying logistic distribution(s). scale: Floating-point `Tensor`; the scale of the underlying logistic distribution(s). validate_args: Python `bool`, default `False`. 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`. If `False`, raise an exception if a statistic (e.g. mean/mode/etc...) is undefined for any batch member If `True`, batch members with valid parameters leading to undefined statistics will return NaN for this statistic. name: The name to give Ops created by the initializer. """ parameters = dict(locals()) with tf.name_scope(name) as name: super(LogLogistic, self).__init__(distribution=logistic.Logistic( loc=loc, scale=scale, allow_nan_stats=allow_nan_stats), bijector=exp_bijector.Exp(), validate_args=validate_args, parameters=parameters, name=name)
def _make_mixture_dist(self, component_logits, locs, scales): """Builds a mixture of quantized logistic distributions. Args: component_logits: 4D `Tensor` of logits for the Categorical distribution over Quantized Logistic mixture components. Dimensions are `[batch_size, height, width, num_logistic_mix]`. locs: 4D `Tensor` of location parameters for the Quantized Logistic mixture components. Dimensions are `[batch_size, height, width, num_logistic_mix, num_channels]`. scales: 4D `Tensor` of location parameters for the Quantized Logistic mixture components. Dimensions are `[batch_size, height, width, num_logistic_mix, num_channels]`. Returns: dist: A quantized logistic mixture `tfp.distribution` over the input data. """ mixture_distribution = categorical.Categorical(logits=component_logits) # Convert distribution parameters for pixel values in # `[self._low, self._high]` for use with `QuantizedDistribution` locs = self._low + 0.5 * (self._high - self._low) * (locs + 1.) scales *= 0.5 * (self._high - self._low) logistic_dist = quantized_distribution.QuantizedDistribution( distribution=transformed_distribution.TransformedDistribution( distribution=logistic.Logistic(loc=locs, scale=scales), bijector=shift.Shift(shift=tf.cast(-0.5, self.dtype))), low=self._low, high=self._high) dist = mixture_same_family.MixtureSameFamily( mixture_distribution=mixture_distribution, components_distribution=independent.Independent( logistic_dist, reinterpreted_batch_ndims=1)) return independent.Independent(dist, reinterpreted_batch_ndims=2)
def _sample_channels(self, component_logits, locs, scales, coeffs=None, seed=None): """Sample a single pixel-iteration and apply channel conditioning. Args: component_logits: 4D `Tensor` of logits for the Categorical distribution over Quantized Logistic mixture components. Dimensions are `[batch_size, height, width, num_logistic_mix]`. locs: 4D `Tensor` of location parameters for the Quantized Logistic mixture components. Dimensions are `[batch_size, height, width, num_logistic_mix, num_channels]`. scales: 4D `Tensor` of location parameters for the Quantized Logistic mixture components. Dimensions are `[batch_size, height, width, num_logistic_mix, num_channels]`. coeffs: 4D `Tensor` of coefficients for the linear dependence among color channels, or `None` if there is only one channel. Dimensions are `[batch_size, height, width, num_logistic_mix, num_coeffs]`, where `num_coeffs = num_channels * (num_channels - 1) // 2`. seed: `int`, random seed. Returns: samples: 4D `Tensor` of sampled image data with autoregression among channels. Dimensions are `[batch_size, height, width, num_channels]`. """ num_channels = self.event_shape[-1] # sample mixture components once for the entire pixel component_dist = categorical.Categorical(logits=component_logits) mask = tf.one_hot(indices=component_dist.sample(seed=seed), depth=self._num_logistic_mix) mask = tf.cast(mask[..., tf.newaxis], self.dtype) # apply mixture component mask and separate out RGB parameters masked_locs = tf.reduce_sum(locs * mask, axis=-2) loc_tensors = tf.split(masked_locs, num_channels, axis=-1) masked_scales = tf.reduce_sum(scales * mask, axis=-2) scale_tensors = tf.split(masked_scales, num_channels, axis=-1) if coeffs is not None: num_coeffs = num_channels * (num_channels - 1) // 2 masked_coeffs = tf.reduce_sum(coeffs * mask, axis=-2) coef_tensors = tf.split(masked_coeffs, num_coeffs, axis=-1) channel_samples = [] coef_count = 0 for i in range(num_channels): loc = loc_tensors[i] for c in channel_samples: loc += c * coef_tensors[coef_count] coef_count += 1 logistic_samp = logistic.Logistic( loc=loc, scale=scale_tensors[i]).sample(seed=seed) logistic_samp = tf.clip_by_value(logistic_samp, -1., 1.) channel_samples.append(logistic_samp) return tf.concat(channel_samples, axis=-1)
def __init__(self, temperature, logits=None, probs=None, validate_args=False, allow_nan_stats=True, name="RelaxedBernoulli"): """Construct RelaxedBernoulli distributions. Args: temperature: An 0-D `Tensor`, representing the temperature of a set of RelaxedBernoulli distributions. The temperature should be positive. logits: An N-D `Tensor` representing the log-odds of a positive event. Each entry in the `Tensor` parametrizes an independent RelaxedBernoulli distribution where the probability of an event is sigmoid(logits). Only one of `logits` or `probs` should be passed in. probs: An N-D `Tensor` representing the probability of a positive event. Each entry in the `Tensor` parameterizes an independent Bernoulli distribution. Only one of `logits` or `probs` should be passed in. validate_args: Python `bool`, default `False`. When `True` distribution parameters are checked for validity despite possibly degrading runtime performance. When `False` invalid inputs may silently render incorrect outputs. 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. Raises: ValueError: If both `probs` and `logits` are passed, or if neither. """ parameters = dict(locals()) with tf.compat.v1.name_scope( name, values=[logits, probs, temperature]) as name: dtype = dtype_util.common_dtype([logits, probs, temperature], tf.float32) self._temperature = tf.convert_to_tensor( value=temperature, name="temperature", dtype=dtype) if validate_args: with tf.control_dependencies( [tf.compat.v1.assert_positive(temperature)]): self._temperature = tf.identity(self._temperature) self._logits, self._probs = distribution_util.get_logits_and_probs( logits=logits, probs=probs, validate_args=validate_args, dtype=dtype) super(RelaxedBernoulli, self).__init__( distribution=logistic.Logistic( self._logits / self._temperature, 1. / self._temperature, validate_args=validate_args, allow_nan_stats=allow_nan_stats, name=name + "/Logistic"), bijector=sigmoid_bijector.Sigmoid(validate_args=validate_args), validate_args=validate_args, name=name) self._parameters = parameters
def _transformed_logistic(self): logistic_scale = tf.math.reciprocal(self._temperature) logits_parameter = self._logits_parameter_no_checks() logistic_loc = logits_parameter * logistic_scale return transformed_distribution.TransformedDistribution( distribution=logistic.Logistic( logistic_loc, logistic_scale, allow_nan_stats=self.allow_nan_stats), bijector=sigmoid_bijector.Sigmoid())
def __init__(self, temperature, logits=None, probs=None, validate_args=False, allow_nan_stats=True, name='RelaxedBernoulli'): """Construct RelaxedBernoulli distributions. Args: temperature: A `Tensor`, representing the temperature of a set of RelaxedBernoulli distributions. The temperature values should be positive. logits: An N-D `Tensor` representing the log-odds of a positive event. Each entry in the `Tensor` parametrizes an independent RelaxedBernoulli distribution where the probability of an event is sigmoid(logits). Only one of `logits` or `probs` should be passed in. probs: An N-D `Tensor` representing the probability of a positive event. Each entry in the `Tensor` parameterizes an independent Bernoulli distribution. Only one of `logits` or `probs` should be passed in. validate_args: Python `bool`, default `False`. When `True` distribution parameters are checked for validity despite possibly degrading runtime performance. When `False` invalid inputs may silently render incorrect outputs. 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. Raises: ValueError: If both `probs` and `logits` are passed, or if neither. """ parameters = dict(locals()) with tf.name_scope(name) as name: dtype = dtype_util.common_dtype([logits, probs, temperature], tf.float32) self._temperature = tensor_util.convert_nonref_to_tensor( temperature, name='temperature', dtype=dtype) self._probs = tensor_util.convert_nonref_to_tensor(probs, name='probs', dtype=dtype) self._logits = tensor_util.convert_nonref_to_tensor(logits, name='logits', dtype=dtype) if logits is None: logits_parameter = tfp_util.DeferredTensor( lambda x: tf.math.log(x) - tf.math.log1p(-x), self._probs) else: logits_parameter = self._logits shape = tf.broadcast_static_shape(logits_parameter.shape, self._temperature.shape) logistic_scale = tfp_util.DeferredTensor(tf.math.reciprocal, self._temperature) logistic_loc = tfp_util.DeferredTensor( lambda x: x * logistic_scale, logits_parameter, shape=shape) self._transformed_logistic = ( transformed_distribution.TransformedDistribution( distribution=logistic.Logistic( logistic_loc, logistic_scale, allow_nan_stats=allow_nan_stats, name=name + '/Logistic'), bijector=sigmoid_bijector.Sigmoid())) super(RelaxedBernoulli, self).__init__(dtype=dtype, reparameterization_type=reparameterization. FULLY_REPARAMETERIZED, validate_args=validate_args, allow_nan_stats=allow_nan_stats, parameters=parameters, name=name)