Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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