def add_params_0(self, size, dimc=1): # stochastic dim = np.prod(size) spler = self.merged_sampler.register_sampler( flows.LinearFlow(dim, dimc, oper=nn.Linear)) print 'registering stochastic parameter of size {}'.format(size) return lambda: spler().contiguous().view(-1, *size)
def set_linear_flow(self, b, name=""): """set_linear_flow constructs the first stage of normalizing flow, which is a linear flow. This function adds the necessary parameters to self.params. The offset term is entirely a funtion of network output Args: b: the output of the network, to be used for defining the offset, b Returns: the flow object and the KL divergence for the approximate posterior """ # the slope is learned by VI, establish approximate # posterior. We use the initial level of observation # noise as the prior mean. log_m_prior_sigma = 2.0 (log_m_mu, log_m_logstd), log_m, log_m_KL = utils.set_q( name=name + "log_m", mu_prior=utils.un_softplus(1.0), sigma_prior=log_m_prior_sigma, mu_init_mu=utils.un_softplus(self.init_sigma_obs), mu_init_sigma=0.0, sigma_init=self.init_sigma_params, n_samples=self.n_samples, save_summary=True) m = tf.nn.softplus(log_m, name=name + "linear_flow_slope") # actually create the flow flow = flows.LinearFlow(b=b, m=m) # add variational parameters of linear flow to list. KL = log_m_KL if self.learn_sigma_obs: self.params += [log_m_mu] if self.inference == 'VI': self.params += [log_m_logstd] # Create Tensorboard logs tf.summary.histogram(name + "LinearFlow_b", b) tf.summary.histogram(name + "LinearFlow_m", m) return flow, KL
def construct_flow(self, outputs, y, n_flows, predict_var, input_dependent=False): """construct_flow builds and links together the normalizing flow and establishes the log likelihood of samples. args: outputs: the outputs of the neural network which we will use to parameterize the flows. y: the placeholder tensor for the outputs to be passed through the flow. n_flows: number of stages in the flow. predict_var: true is predicting slope of first flow input_dependent: True if predicting the variance of flows after the first one. Returns: new parameters of flows (i.e. those not defined as outputs of the network) and the negative log likelihoods """ self.flows, flow_params = [], [] # check for correct number of input dimensions. if input_dependent or (self.noise_dim != 0): assert outputs.shape[-1] == (n_flows - 1) * 3 + (2 if predict_var else 1) else: assert outputs.shape[-1] == 2 if predict_var else 1 out_idx = 0 # keep track of which output we are working with. with tf.name_scope("Normalizing_Flows"): with tf.variable_scope('network'): ## Construct first flow, a Linear Flow b = outputs[:, :, out_idx] out_idx += 1 tf.summary.histogram("LinearFlow_b", b) if predict_var: log_m = outputs[:, :, out_idx] out_idx += 1 else: log_m = tf.get_variable( 'log_m', shape=[], initializer=tf.constant_initializer(0.0)) ### Add this to the core set of parameters self.params.append(log_m) flow_params.append(log_m) m = tf.exp(log_m, name="linear_flow_slope") if predict_var: tf.summary.histogram("LinearFlow_m", m) else: tf.summary.scalar("LinearFlow_m", m) self.flows.append(flows.LinearFlow(b=b, m=m)) print "b.shape", self.flows[-1].b.shape print "m.shape", self.flows[-1].m.shape ## Construct the Subsequent Flows for f_i in range(1, n_flows): if input_dependent or (self.noise_dim != 0): z_i = outputs[:, :, out_idx] out_idx += 1 beta_raw = outputs[:, :, out_idx] out_idx += 1 alpha_raw = outputs[:, :, out_idx] out_idx += 1 else: z_i = tf.get_variable( 'z_%d' % f_i, initializer=tf.constant( np.random.normal(size=[1], scale=0.25).astype( np.float32))) beta_raw = tf.get_variable( 'beta_%d' % f_i, shape=[1], initializer=tf.constant_initializer(0.0)) alpha_raw = tf.get_variable( 'alpha_%d' % f_i, shape=[1], initializer=tf.constant_initializer(0.0)) flow_params.extend([z_i, beta_raw, alpha_raw]) # In the 1D regression case, it does not make sense ot # thread the z_0's through previous flows, so prev=None flow = flows.RadialFlow(z_i, alpha_raw, beta_raw, prev=None) self.flows.append(flow) if input_dependent or (self.noise_dim != 0): tf.summary.histogram("flow_%d_zi" % f_i, flow.z_0) tf.summary.histogram("flow_%d_beta" % f_i, flow.beta) tf.summary.histogram("flow_%d_alpha" % f_i, flow.alpha) else: tf.summary.scalar("flow_%d_zi" % f_i, flow.z_0[0]) tf.summary.scalar("flow_%d_beta" % f_i, flow.beta[0]) tf.summary.scalar("flow_%d_alpha" % f_i, flow.alpha[0]) ## Check that every output has been used assert out_idx == outputs.shape[-1] return flow_params