with tf.variable_scope(self.name):
// adds placeholders, data normalization and data noise to graph as desired
self.layer_in_x, self.layer_in_y = self._build_input_layers()
self.y_input = L.get_output(self.layer_in_y)
flow_classes = [FLOWS[flow_name] for flow_name in self.flows_type]
// get the individual parameter sizes for each flow
param_split_sizes = [flow.get_param_size(self.ndim_y) for flow in flow_classes]
mlp_output_dim = sum(param_split_sizes)
core_network = MLP(
name="core_network",
input_layer=self.layer_in_x,
output_dim=mlp_output_dim,
hidden_sizes=self.hidden_sizes,
hidden_nonlinearity=self.hidden_nonlinearity,
output_nonlinearity=None,
weight_normalization=self.weight_normalization
)
outputs = L.get_output(core_network.output_layer)
flow_params = tf.split(value=outputs, num_or_size_splits=param_split_sizes, axis=1)
// instanciate the flows with their parameters
flows = [flow(params, self.ndim_y) for flow, params in zip(flow_classes, flow_params)]
// build up the base distribution that will be transformed by the flows
base_dist = tf.distributions.Normal(loc=[0.]*self.ndim_y, scale=[1.]*self.ndim_y)
// chain the flows together and build the transformed distribution using the base_dist + flows
// Chaining applies the flows in reverse, Chain([a,b]).forward(x) being a.forward(b.forward(x))
// We reverse them so the flows are stacked ontop of the base distribution in the original order
flows.reverse()
chain = tf.contrib.distributions.bijectors.Chain(flows)
target_dist = tf.contrib.distributions.TransformedDistribution(distribution=base_dist, bijector=chain)
// since we operate with matrices not vectors, the output would have dimension (?,1)
// and therefor has to be reduce first to have shape (?,)
if self.data_normalization:
self.pdf_ = tf.squeeze(target_dist.prob(self.y_input) / tf.reduce_prod(self.std_y_sym), axis=1)
self.log_pdf_ = tf.squeeze(target_dist.log_prob(self.y_input) - tf.reduce_sum(tf.log(self.std_y_sym)), axis=1)
self.cdf_ = tf.squeeze(target_dist.cdf(self.y_input) / tf.reduce_prod(self.std_y_sym), axis=1)
else:
self.pdf_ = tf.squeeze(target_dist.prob(self.y_input), axis=1)
self.log_pdf_ = tf.squeeze(target_dist.log_prob(self.y_input), axis=1)