Source code for cde.density_estimator.normalizing_flows.RadialFlow

import tensorflow as tf
from .BaseNormalizingFlow import BaseNormalizingFlow


[docs]class InvertedRadialFlow(BaseNormalizingFlow): """ Implements a bijector x = y + (alpha * beta * (y - y_0)) / (alpha + abs(y - y_0)). Args: params: Tensor shape (?, n_dims+2). This will be split into the parameters alpha (?, 1), beta (?, 1), gamma (?, n_dims). Furthermore alpha will be constrained to assure the invertability of the flow n_dims: The dimension of the distribution that will be transformed name: The name to give this particular flow """ _alpha = None _beta = None _gamma = None def __init__(self, params, n_dims, validate_args=False, name='InvertedRadialFlow'): """ Parameter shapes (assuming you're transforming a distribution over d-space): shape alpha = (?, 1) shape beta = (?, 1) shape gamma = (?, ndims) """ super(InvertedRadialFlow, self).__init__(params, n_dims, validate_args=validate_args, name=name) # split the input parameter into the individual parameters alpha, beta, gamma a_index, b_index, g_index = 0, 1, 2 flow_params = [InvertedRadialFlow._handle_input_dimensionality(x) for x in tf.split(value=params, num_or_size_splits=[1, 1, n_dims], axis=1)] # constraining the parameters before they are assigned to ensure invertibility self._alpha = InvertedRadialFlow._alpha_circ(flow_params[a_index]) self._beta = InvertedRadialFlow._beta_circ(flow_params[b_index]) self._gamma = flow_params[g_index]
[docs] @staticmethod def get_param_size(n_dims): """ :param n_dims: The dimension of the distribution to be transformed by the flow :return: (int) The dimension of the parameter space for the flow """ return 1 + 1 + n_dims
def _r(self, z): return tf.reduce_sum(tf.abs(z - self._gamma), 1, keepdims=True) def _h(self, r): return 1. / (self._alpha + r) def _inverse(self, z): """ Runs a forward pass through the bijector """ z = InvertedRadialFlow._handle_input_dimensionality(z) r = self._r(z) h = self._h(r) return z + (self._alpha * self._beta * h) * (z - self._gamma) def _ildj(self, z): """ Computes the ln of the absolute determinant of the jacobian """ z = InvertedRadialFlow._handle_input_dimensionality(z) r = self._r(z) h = self._h(r) der_h = tf.gradients(h, [r])[0] ab = self._alpha * self._beta det = (1. + ab * h)**(self.n_dims - 1) * (1. + ab*h + ab*der_h*r) return tf.log(det) @staticmethod def _alpha_circ(alpha): """ Method for constraining the alpha parameter to meet the invertibility requirements """ return tf.nn.softplus(alpha) @staticmethod def _beta_circ(beta): """ Method for constraining the beta parameter to meet the invertibility requirements """ return tf.exp(beta) - 1.
[docs] def forward(self, x): """ We don't require sampling and it would be slow, therefore it is not implemented :raise NotImplementedError: """ raise NotImplementedError()