Exemplo n.º 1
0
    def test_normalnormal_run(self):
        with self.test_session() as sess:
            x_data = np.array([0.0] * 50, dtype=np.float32)

            mu = Normal(loc=0.0, scale=1.0)
            x = Normal(loc=tf.ones(50) * mu, scale=1.0)

            qmu_loc = tf.Variable(tf.random_normal([]))
            qmu_scale = tf.nn.softplus(tf.Variable(tf.random_normal([])))
            qmu = Normal(loc=qmu_loc, scale=qmu_scale)

            # analytic solution: N(loc=0.0, scale=\sqrt{1/51}=0.140)
            n_iter = 5000
            inference = ed.KLqp({mu: qmu}, data={x: x_data})
            inference.run(n_iter=n_iter)

            self.assertAllClose(qmu.mean().eval(), 0, rtol=1e-1, atol=1e-1)
            self.assertAllClose(qmu.stddev().eval(),
                                np.sqrt(1 / 51),
                                rtol=1e-1,
                                atol=1e-1)

            variables = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                                          scope='optimizer')
            old_t, old_variables = sess.run([inference.t, variables])
            self.assertEqual(old_t, n_iter)
            sess.run(inference.reset)
            new_t, new_variables = sess.run([inference.t, variables])
            self.assertEqual(new_t, 0)
            self.assertNotEqual(old_variables, new_variables)
Exemplo n.º 2
0
    def _test_normal_normal(self, Inference, default, *args, **kwargs):
        with self.test_session() as sess:
            x_data = np.array([0.0] * 50, dtype=np.float32)

            mu = Normal(loc=0.0, scale=1.0)
            x = Normal(loc=mu, scale=1.0, sample_shape=50)

            if not default:
                qmu_loc = tf.Variable(tf.random_normal([]))
                qmu_scale = tf.nn.softplus(tf.Variable(tf.random_normal([])))
                qmu = Normal(loc=qmu_loc, scale=qmu_scale)

                # analytic solution: N(loc=0.0, scale=\sqrt{1/51}=0.140)
                inference = Inference({mu: qmu}, data={x: x_data})
            else:
                inference = Inference([mu], data={x: x_data})
                qmu = inference.latent_vars[mu]
            inference.run(*args, **kwargs)

            self.assertAllClose(qmu.mean().eval(), 0, rtol=0.15, atol=0.5)
            self.assertAllClose(qmu.stddev().eval(),
                                np.sqrt(1 / 51),
                                rtol=0.15,
                                atol=0.5)

            variables = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES,
                                          scope='optimizer')
            old_t, old_variables = sess.run([inference.t, variables])
            self.assertEqual(old_t, inference.n_iter)
            sess.run(inference.reset)
            new_t, new_variables = sess.run([inference.t, variables])
            self.assertEqual(new_t, 0)
            self.assertNotEqual(old_variables, new_variables)
Exemplo n.º 3
0
  def _test_normal_normal(self, Inference, default, *args, **kwargs):
    with self.test_session() as sess:
      x_data = np.array([0.0] * 50, dtype=np.float32)

      mu = Normal(loc=0.0, scale=1.0)
      x = Normal(loc=mu, scale=1.0, sample_shape=50)

      if not default:
        qmu_loc = tf.Variable(tf.random_normal([]))
        qmu_scale = tf.nn.softplus(tf.Variable(tf.random_normal([])))
        qmu = Normal(loc=qmu_loc, scale=qmu_scale)

        # analytic solution: N(loc=0.0, scale=\sqrt{1/51}=0.140)
        inference = Inference({mu: qmu}, data={x: x_data})
      else:
        inference = Inference([mu], data={x: x_data})
        qmu = inference.latent_vars[mu]
      inference.run(*args, **kwargs)

      self.assertAllClose(qmu.mean().eval(), 0, rtol=0.1, atol=0.6)
      self.assertAllClose(qmu.stddev().eval(), np.sqrt(1 / 51),
                          rtol=0.15, atol=0.5)

      variables = tf.get_collection(
          tf.GraphKeys.GLOBAL_VARIABLES, scope='optimizer')
      old_t, old_variables = sess.run([inference.t, variables])
      self.assertEqual(old_t, inference.n_iter)
      sess.run(inference.reset)
      new_t, new_variables = sess.run([inference.t, variables])
      self.assertEqual(new_t, 0)
      self.assertNotEqual(old_variables, new_variables)
Exemplo n.º 4
0
  def test_normalnormal_run(self):
    with self.test_session() as sess:
      x_data = np.array([0.0] * 50, dtype=np.float32)

      mu = Normal(loc=0.0, scale=1.0)
      x = Normal(loc=tf.ones(50) * mu, scale=1.0)

      qmu_loc = tf.Variable(tf.random_normal([]))
      qmu_scale = tf.nn.softplus(tf.Variable(tf.random_normal([])))
      qmu = Normal(loc=qmu_loc, scale=qmu_scale)

      # analytic solution: N(loc=0.0, scale=\sqrt{1/51}=0.140)
      inference = ed.KLpq({mu: qmu}, data={x: x_data})
      inference.run(n_samples=25, n_iter=100)

      self.assertAllClose(qmu.mean().eval(), 0, rtol=1e-1, atol=1e-1)
      self.assertAllClose(qmu.stddev().eval(), np.sqrt(1 / 51),
                          rtol=1e-1, atol=1e-1)
Exemplo n.º 5
0
    def test_normalnormal_run(self):
        with self.test_session() as sess:
            x_data = np.array([0.0] * 50, dtype=np.float32)

            mu = Normal(loc=0.0, scale=1.0)
            x = Normal(loc=tf.ones(50) * mu, scale=1.0)

            qmu_loc = tf.Variable(tf.random_normal([]))
            qmu_scale = tf.nn.softplus(tf.Variable(tf.random_normal([])))
            qmu = Normal(loc=qmu_loc, scale=qmu_scale)

            # analytic solution: N(loc=0.0, scale=\sqrt{1/51}=0.140)
            inference = ed.KLqp({mu: qmu}, data={x: x_data})
            inference.run(n_iter=5000)

            self.assertAllClose(qmu.mean().eval(), 0, rtol=1e-1, atol=1e-1)
            self.assertAllClose(qmu.stddev().eval(),
                                np.sqrt(1 / 51),
                                rtol=1e-1,
                                atol=1e-1)
def main(_):
    def ratio_estimator(data, local_vars, global_vars):
        """Takes as input a dict of data x, local variable samples z, and
    global variable samples beta; outputs real values of shape
    (x.shape[0] + z.shape[0],). In this example, there are no local
    variables.
    """
        # data[y] has shape (M,); global_vars[w] has shape (D,)
        # we concatenate w to each data point y, so input has shape (M, 1 + D)
        input = tf.concat([
            tf.reshape(data[y], [FLAGS.M, 1]),
            tf.tile(tf.reshape(global_vars[w], [1, FLAGS.D]), [FLAGS.M, 1])
        ], 1)
        hidden = tf.layers.dense(input, 64, activation=tf.nn.relu)
        output = tf.layers.dense(hidden, 1, activation=None)
        return output

    ed.set_seed(42)

    # DATA
    w_true = np.ones(FLAGS.D) * 5.0
    X_train, y_train = build_toy_dataset(FLAGS.N, w_true)
    X_test, y_test = build_toy_dataset(FLAGS.N, w_true)
    data = generator([X_train, y_train], FLAGS.M)

    # MODEL
    X = tf.placeholder(tf.float32, [FLAGS.M, FLAGS.D])
    y_ph = tf.placeholder(tf.float32, [FLAGS.M])
    w = Normal(loc=tf.zeros(FLAGS.D), scale=tf.ones(FLAGS.D))
    y = Normal(loc=ed.dot(X, w), scale=tf.ones(FLAGS.M))

    # INFERENCE
    qw = Normal(loc=tf.get_variable("qw/loc", [FLAGS.D]) + 1.0,
                scale=tf.nn.softplus(tf.get_variable("qw/scale", [FLAGS.D])))

    inference = ed.ImplicitKLqp({w: qw},
                                data={y: y_ph},
                                discriminator=ratio_estimator,
                                global_vars={w: qw})
    inference.initialize(n_iter=5000,
                         n_print=100,
                         scale={y: float(FLAGS.N) / FLAGS.M})

    sess = ed.get_session()
    tf.global_variables_initializer().run()

    for _ in range(inference.n_iter):
        X_batch, y_batch = next(data)
        for _ in range(5):
            info_dict_d = inference.update(variables="Disc",
                                           feed_dict={
                                               X: X_batch,
                                               y_ph: y_batch
                                           })

        info_dict = inference.update(variables="Gen",
                                     feed_dict={
                                         X: X_batch,
                                         y_ph: y_batch
                                     })
        info_dict['loss_d'] = info_dict_d['loss_d']
        info_dict[
            't'] = info_dict['t'] // 6  # say set of 6 updates is 1 iteration

        t = info_dict['t']
        inference.print_progress(info_dict)
        if t == 1 or t % inference.n_print == 0:
            # Check inferred posterior parameters.
            mean, std = sess.run([qw.mean(), qw.stddev()])
            print("\nInferred mean & std:")
            print(mean)
            print(std)
inference.initialize(n_iter=5000, n_print=100, scale={y: float(N) / M})

sess = ed.get_session()
tf.global_variables_initializer().run()

for _ in range(inference.n_iter):
    X_batch, y_batch = next(data)
    for _ in range(5):
        info_dict_d = inference.update(variables="Disc",
                                       feed_dict={
                                           X: X_batch,
                                           y_ph: y_batch
                                       })

    info_dict = inference.update(variables="Gen",
                                 feed_dict={
                                     X: X_batch,
                                     y_ph: y_batch
                                 })
    info_dict['loss_d'] = info_dict_d['loss_d']
    info_dict['t'] = info_dict['t'] // 6  # say set of 6 updates is 1 iteration

    t = info_dict['t']
    inference.print_progress(info_dict)
    if t == 1 or t % inference.n_print == 0:
        # Check inferred posterior parameters.
        mean, std = sess.run([qw.mean(), qw.stddev()])
        print("\nInferred mean & std:")
        print(mean)
        print(std)
Exemplo n.º 8
0
# VISUALIZATION
def visualise(X_data, y_data, w, b, ax, n_samples=10):
    w_samples = w.sample(n_samples)[:, 0].eval()
    b_samples = b.sample(n_samples).eval()
    ax.scatter(X_data[:, 0],
               y_data)  # Note, only the 1st input dimension is plotted.
    inputs = np.linspace(-8, 8, num=400)
    for ns in range(n_samples):
        output = inputs * w_samples[ns] + b_samples[ns]
        ax.plot(inputs, output)


fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)

visualise(X_train, y_train, w, b, ax1)  # Models sampled from the prior
visualise(X_train, y_train, qw, qb, ax2)  # Models sampled from the posterior
plt.show()

# EXPLORE THE LEARNED MODEL

print('Point estimate for STD of weights:', w_prior_std.eval())

# Retrieve the means and STDs of the estimated regression coefficients
w_est_mean = qw.mean().eval()
w_est_std = qw.stddev().eval()
print('Correlation between estimated and learned weights: ',
      np.corrcoef(w_est_mean, w_true)[0, 1])
Exemplo n.º 9
0
for _ in range(20):
    plt.scatter(x_train[:,0], np.log(yhat.eval()[:,which_species]), alpha=0.1, c="black", s=10);


# In[ ]:

# Predictions using the approximate posterior on z
plt.figure(figsize=(10, 10))
plt.scatter(x_train[:,0], np.log(mu[:,which_species]));
for _ in range(20):
    plt.scatter(x_train[:,0], np.log(qyhat.eval()[:,which_species]), alpha=0.1, c="darkred", s=10);


# In[ ]:

plt.hist(qz.stddev().eval(), bins=50);


# In[ ]:

# Approximate posterior distributions of z, given x. Should be no big (low-frequency?) trends or gaps
for i in range(n_z):
    for _ in range(25):
        plt.scatter(x_train[:,0], qz.eval()[:,i], alpha=0.1, c="darkred", s=5)
    plt.show()


# In[ ]:

nn = 1000
xx = 0
def main(_):
  def ratio_estimator(data, local_vars, global_vars):
    """Takes as input a dict of data x, local variable samples z, and
    global variable samples beta; outputs real values of shape
    (x.shape[0] + z.shape[0],). In this example, there are no local
    variables.
    """
    # data[y] has shape (M,); global_vars[w] has shape (D,)
    # we concatenate w to each data point y, so input has shape (M, 1 + D)
    input = tf.concat([
        tf.reshape(data[y], [FLAGS.M, 1]),
        tf.tile(tf.reshape(global_vars[w], [1, FLAGS.D]), [FLAGS.M, 1])], 1)
    hidden = tf.layers.dense(input, 64, activation=tf.nn.relu)
    output = tf.layers.dense(hidden, 1, activation=None)
    return output

  ed.set_seed(42)

  # DATA
  w_true = np.ones(FLAGS.D) * 5.0
  X_train, y_train = build_toy_dataset(FLAGS.N, w_true)
  X_test, y_test = build_toy_dataset(FLAGS.N, w_true)
  data = generator([X_train, y_train], FLAGS.M)

  # MODEL
  X = tf.placeholder(tf.float32, [FLAGS.M, FLAGS.D])
  y_ph = tf.placeholder(tf.float32, [FLAGS.M])
  w = Normal(loc=tf.zeros(FLAGS.D), scale=tf.ones(FLAGS.D))
  y = Normal(loc=ed.dot(X, w), scale=tf.ones(FLAGS.M))

  # INFERENCE
  qw = Normal(loc=tf.get_variable("qw/loc", [FLAGS.D]) + 1.0,
              scale=tf.nn.softplus(tf.get_variable("qw/scale", [FLAGS.D])))

  inference = ed.ImplicitKLqp(
      {w: qw}, data={y: y_ph},
      discriminator=ratio_estimator, global_vars={w: qw})
  inference.initialize(n_iter=5000, n_print=100,
                       scale={y: float(FLAGS.N) / FLAGS.M})

  sess = ed.get_session()
  tf.global_variables_initializer().run()

  for _ in range(inference.n_iter):
    X_batch, y_batch = next(data)
    for _ in range(5):
      info_dict_d = inference.update(
          variables="Disc", feed_dict={X: X_batch, y_ph: y_batch})

    info_dict = inference.update(
        variables="Gen", feed_dict={X: X_batch, y_ph: y_batch})
    info_dict['loss_d'] = info_dict_d['loss_d']
    info_dict['t'] = info_dict['t'] // 6  # say set of 6 updates is 1 iteration

    t = info_dict['t']
    inference.print_progress(info_dict)
    if t == 1 or t % inference.n_print == 0:
      # Check inferred posterior parameters.
      mean, std = sess.run([qw.mean(), qw.stddev()])
      print("\nInferred mean & std:")
      print(mean)
      print(std)
Exemplo n.º 11
0
def main(_):
    # setting up output directory
    outdir = os.path.expanduser(FLAGS.outdir)
    os.makedirs(outdir, exist_ok=True)

    N, M, D, R_true, I_train, I_test = get_data()
    debug('N, M, D', N, M, D)

    # Solution components
    weights, qUVt_components = [], []

    # Files to log metrics
    times_filename = os.path.join(outdir, 'times.csv')
    mse_train_filename = os.path.join(outdir, 'mse_train.csv')
    mse_test_filename = os.path.join(outdir, 'mse_test.csv')
    ll_test_filename = os.path.join(outdir, 'll_test.csv')
    ll_train_filename = os.path.join(outdir, 'll_train.csv')
    elbos_filename = os.path.join(outdir, 'elbos.csv')
    gap_filename = os.path.join(outdir, 'gap.csv')
    step_filename = os.path.join(outdir, 'steps.csv')
    # 'adafw', 'ada_afw', 'ada_pfw'
    if FLAGS.fw_variant.startswith('ada'):
        lipschitz_filename = os.path.join(outdir, 'lipschitz.csv')
        iter_info_filename = os.path.join(outdir, 'iter_info.txt')

    start = 0
    if FLAGS.restore:
        #start = 50
        #qUVt_components = get_random_components(D, N, M, start)
        #weights = np.random.dirichlet([1.] * start).astype(np.float32)
        #lipschitz_estimate = opt.adafw_linit()
        parameters = np.load(os.path.join(outdir, 'qt_latest.npz'))
        weights = list(parameters['weights'])
        start = parameters['fw_iter']
        qUVt_components = list(parameters['comps'])
        assert len(weights) == len(qUVt_components), "Inconsistent storage"
        # get lipschitz estimate from the file, could've stored it
        # in params but that would mean different saved file for
        # adaptive variants
        if FLAGS.fw_variant.startswith('ada'):
            lipschitz_filename = os.path.join(outdir, 'lipschitz.csv')
            if not os.path.isfile(lipschitz_filename):
                raise ValueError("Inconsistent storage")
            with open(lipschitz_filename, 'r') as f:
                l = f.readlines()
                lipschitz_estimate = float(l[-1].strip())
    else:
        # empty the files present in the folder already
        open(times_filename, 'w').close()
        open(mse_train_filename, 'w').close()
        open(mse_test_filename, 'w').close()
        open(ll_test_filename, 'w').close()
        open(ll_train_filename, 'w').close()
        open(elbos_filename, 'w').close()
        open(gap_filename, 'w').close()
        open(step_filename, 'w').close()
        # 'adafw', 'ada_afw', 'ada_pfw'
        if FLAGS.fw_variant.startswith('ada'):
            open(lipschitz_filename, 'w').close()
            open(iter_info_filename, 'w').close()

    for t in range(start, start + FLAGS.n_fw_iter):
        g = tf.Graph()
        with g.as_default():
            tf.set_random_seed(FLAGS.seed)
            sess = tf.InteractiveSession()
            with sess.as_default():
                # MODEL
                I = tf.placeholder(tf.float32, [N, M])

                scale_uv = tf.concat(
                    [tf.ones([D, N]), tf.ones([D, M])], axis=1)
                mean_uv = tf.concat(
                    [tf.zeros([D, N]), tf.zeros([D, M])], axis=1)

                UV = Normal(loc=mean_uv, scale=scale_uv)
                R = Normal(loc=tf.matmul(tf.transpose(UV[:, :N]), UV[:, N:]),
                           scale=tf.ones([N, M]))  # generator dist. for matrix
                R_mask = R * I  # generated masked matrix

                p_joint = Joint(R_true, I_train, sess, D, N, M)

                if t == 0:
                    fw_iterates = {}
                else:
                    # Current solution
                    prev_components = [
                        coreutils.base_loc_scale('mvn0',
                                                 c['loc'],
                                                 c['scale'],
                                                 multivariate=False)
                        for c in qUVt_components
                    ]
                    qUV_prev = coreutils.get_mixture(weights, prev_components)
                    fw_iterates = {UV: qUV_prev}

                # LMO (via relbo INFERENCE)
                mean_suv = tf.concat([
                    tf.get_variable("qU/loc", [D, N]),
                    tf.get_variable("qV/loc", [D, M])
                ],
                                     axis=1)
                scale_suv = tf.concat([
                    tf.nn.softplus(tf.get_variable("qU/scale", [D, N])),
                    tf.nn.softplus(tf.get_variable("qV/scale", [D, M]))
                ],
                                      axis=1)

                sUV = Normal(loc=mean_suv, scale=scale_suv)

                #inference = relbo.KLqp({UV: sUV}, data={R: R_true, I: I_train},
                inference = relbo.KLqp({UV: sUV},
                                       data={
                                           R_mask: R_true,
                                           I: I_train
                                       },
                                       fw_iterates=fw_iterates,
                                       fw_iter=t)
                inference.run(n_iter=FLAGS.LMO_iter)

                loc_s = sUV.mean().eval()
                scale_s = sUV.stddev().eval()
                # sUV is batched distrbution, there are issues making
                # Mixture with batch distributions. mvn0
                # with event size (D, N + M) and batch size ()
                # NOTE log_prob(sample) still returns tensor
                # mvn and multivariatenormaldiag work for 1-D not 2-D shapes
                sUV_mv = coreutils.base_loc_scale('mvn0',
                                                  loc_s,
                                                  scale_s,
                                                  multivariate=False)
                # TODO send sUV or sUV_mv as argument to step size? sample
                # works the same way. same with log_prob

                total_time = 0.
                data = {R: R_true, I: I_train}
                if t == 0:
                    gamma = 1.
                    lipschitz_estimate = opt.adafw_linit()
                    step_type = 'init'
                elif FLAGS.fw_variant == 'fixed':
                    start_step_time = time.time()
                    step_result = opt.fixed(weights, qUVt_components, qUV_prev,
                                            loc_s, scale_s, sUV, p_joint, data,
                                            t)
                    end_step_time = time.time()
                    total_time += float(end_step_time - start_step_time)
                elif FLAGS.fw_variant == 'line_search':
                    start_step_time = time.time()
                    step_result = opt.line_search_dkl(weights, qUVt_components,
                                                      qUV_prev, loc_s, scale_s,
                                                      sUV, p_joint, data, t)
                    end_step_time = time.time()
                    total_time += float(end_step_time - start_step_time)
                elif FLAGS.fw_variant == 'adafw':
                    start_step_time = time.time()
                    step_result = opt.adaptive_fw(weights, qUVt_components,
                                                  qUV_prev, loc_s, scale_s,
                                                  sUV, p_joint, data, t,
                                                  lipschitz_estimate)
                    end_step_time = time.time()
                    total_time += float(end_step_time - start_step_time)

                    step_type = step_result['step_type']
                    if step_type == 'adaptive':
                        lipschitz_estimate = step_result['l_estimate']
                elif FLAGS.fw_variant == 'ada_pfw':
                    start_step_time = time.time()
                    step_result = opt.adaptive_pfw(weights, qUVt_components,
                                                   qUV_prev, loc_s, scale_s,
                                                   sUV, p_joint, data, t,
                                                   lipschitz_estimate)
                    end_step_time = time.time()
                    total_time += float(end_step_time - start_step_time)

                    step_type = step_result['step_type']
                    if step_type in ['adaptive', 'drop']:
                        lipschitz_estimate = step_result['l_estimate']
                elif FLAGS.fw_variant == 'ada_afw':
                    start_step_time = time.time()
                    step_result = opt.adaptive_pfw(weights, qUVt_components,
                                                   qUV_prev, loc_s, scale_s,
                                                   sUV, p_joint, data, t,
                                                   lipschitz_estimate)
                    end_step_time = time.time()
                    total_time += float(end_step_time - start_step_time)

                    step_type = step_result['step_type']
                    if step_type in ['adaptive', 'away', 'drop']:
                        lipschitz_estimate = step_result['l_estimate']

                if t == 0:
                    gamma = 1.
                    weights.append(gamma)
                    qUVt_components.append({'loc': loc_s, 'scale': scale_s})
                    new_components = [sUV_mv]
                else:
                    qUVt_components = step_result['params']
                    weights = step_result['weights']
                    gamma = step_result['gamma']
                    new_components = [
                        coreutils.base_loc_scale('mvn0',
                                                 c['loc'],
                                                 c['scale'],
                                                 multivariate=False)
                        for c in qUVt_components
                    ]

                qUV_new = coreutils.get_mixture(weights, new_components)

                #qR = Normal(
                #    loc=tf.matmul(
                #        tf.transpose(qUV_new[:, :N]), qUV_new[:, N:]),
                #    scale=tf.ones([N, M]))
                qR = ed.copy(R, {UV: qUV_new})
                cR = ed.copy(R_mask, {UV: qUV_new})  # reconstructed matrix

                # Log metrics for current iteration
                logger.info('total time %f' % total_time)
                append_to_file(times_filename, total_time)

                logger.info('iter %d, gamma %.4f' % (t, gamma))
                append_to_file(step_filename, gamma)

                if t > 0:
                    gap_t = step_result['gap']
                    logger.info('iter %d, gap %.4f' % (t, gap_t))
                    append_to_file(gap_filename, gap_t)

                # CRITICISM
                if FLAGS.fw_variant.startswith('ada'):
                    append_to_file(lipschitz_filename, lipschitz_estimate)
                    append_to_file(iter_info_filename, step_type)
                    logger.info('lt = %.5f, iter_type = %s' %
                                (lipschitz_estimate, step_type))

                test_mse = ed.evaluate('mean_squared_error',
                                       data={
                                           cR: R_true,
                                           I: I_test
                                       })
                logger.info("iter %d ed test mse %.5f" % (t, test_mse))
                append_to_file(mse_test_filename, test_mse)

                train_mse = ed.evaluate('mean_squared_error',
                                        data={
                                            cR: R_true,
                                            I: I_train
                                        })
                logger.info("iter %d ed train mse %.5f" % (t, train_mse))
                append_to_file(mse_train_filename, train_mse)

                # very slow
                #train_ll = log_likelihood(qUV_new, R_true, I_train, sess, D, N,
                #                          M)
                train_ll = ed.evaluate('log_lik',
                                       data={
                                           qR: R_true.astype(np.float32),
                                           I: I_train
                                       })
                logger.info("iter %d train log lik %.5f" % (t, train_ll))
                append_to_file(ll_train_filename, train_ll)

                #test_ll = log_likelihood(qUV_new, R_true, I_test, sess, D, N, M)
                test_ll = ed.evaluate('log_lik',
                                      data={
                                          qR: R_true.astype(np.float32),
                                          I: I_test
                                      })
                logger.info("iter %d test log lik %.5f" % (t, test_ll))
                append_to_file(ll_test_filename, test_ll)

                # elbo_loss might be meaningless
                elbo_loss = elboModel.KLqp({UV: qUV_new},
                                           data={
                                               R: R_true,
                                               I: I_train
                                           })
                elbo_t = elbo(qUV_new, p_joint)
                res_update = elbo_loss.run()
                logger.info('iter %d -elbo loss %.2f or %.2f' %
                            (t, res_update['loss'], elbo_t))
                append_to_file(elbos_filename,
                               "%f,%f" % (elbo_t, res_update['loss']))

                # serialize the current iterate
                np.savez(os.path.join(outdir, 'qt_latest.npz'),
                         weights=weights,
                         comps=qUVt_components,
                         fw_iter=t + 1)

                sess.close()
        tf.reset_default_graph()
Exemplo n.º 12
0
class BayesianRegression:
    def __init__(self, in_dim=1, n_classes=2):
        """
        Bayesian Logistic regression based on Edward lib (http://edwardlib.org).

        y = W * x + b

        :param in_dim:
        :param n_classes:
        """

        self.in_dim = in_dim
        self.n_classes = n_classes

        self.X = tf.placeholder(tf.float32, [None, self.in_dim])
        self.W = Normal(loc=tf.zeros([self.in_dim, self.n_classes]),
                        scale=tf.ones([self.in_dim, self.n_classes]))
        self.b = Normal(loc=tf.zeros(self.n_classes),
                        scale=tf.ones(self.n_classes))

        h = tf.matmul(self.X, self.W) + self.b
        self.y = Normal(loc=tf.sigmoid(-h), scale=0.1)

        self.qW = Normal(loc=tf.get_variable("qW/loc",
                                             [self.in_dim, self.n_classes]),
                         scale=tf.nn.softplus(
                             tf.get_variable("qW/scale",
                                             [self.in_dim, self.n_classes])))
        self.qb = Normal(loc=tf.get_variable("qb/loc", [self.n_classes]),
                         scale=tf.nn.softplus(
                             tf.get_variable("qb/scale", [self.n_classes])))

    def infer(self, X, y, n_samples=5, n_iter=250):

        inference = ed.KLqp({
            self.W: self.qW,
            self.b: self.qb,
        },
                            data={
                                self.y: y,
                                self.X: X
                            })

        inference.run(n_samples=n_samples, n_iter=n_iter)

    def predict(self, X):

        self.qW_mean = self.qW.mean().eval()
        self.qb_mean = self.qb.mean().eval()

        h = tf.matmul(X, self.qW_mean) + self.qb_mean

        return tf.sigmoid(-h).eval()

    def sample_boudary(self, X):

        qW = self.qW.eval()
        qb = self.qb.eval()

        w = -qW[0][0] / qW[1][0]
        b = (0.5 - qb[0]) / qW[0][0]

        return w, b

    def predict_std(self, X):
        self.qW_stddev = self.qW.stddev().eval()
        self.qb_stddev = self.qb.stddev().eval()

        h = tf.matmul(X, self.qW_stddev) + self.qb_stddev

        return tf.sigmoid(-h).eval()

    def get_coef(self):
        return self.qW.mean().eval().T[0]
qw = Normal(loc=tf.Variable(tf.random_normal([D]) + 1.0),
            scale=tf.nn.softplus(tf.Variable(tf.random_normal([D]))))

inference = ed.ImplicitKLqp(
    {w: qw}, data={y: y_ph},
    discriminator=ratio_estimator, global_vars={w: qw})
inference.initialize(n_iter=5000, n_print=100, scale={y: float(N) / M})

sess = ed.get_session()
tf.global_variables_initializer().run()

for _ in range(inference.n_iter):
  X_batch, y_batch = next(data)
  for _ in range(5):
    info_dict_d = inference.update(
        variables="Disc", feed_dict={X: X_batch, y_ph: y_batch})

  info_dict = inference.update(
      variables="Gen", feed_dict={X: X_batch, y_ph: y_batch})
  info_dict['loss_d'] = info_dict_d['loss_d']
  info_dict['t'] = info_dict['t'] // 6  # say set of 6 updates is 1 iteration

  t = info_dict['t']
  inference.print_progress(info_dict)
  if t == 1 or t % inference.n_print == 0:
    # Check inferred posterior parameters.
    mean, std = sess.run([qw.mean(), qw.stddev()])
    print("\nInferred mean & std:")
    print(mean)
    print(std)