Hi everyone,
I’m seeking suggestion on improving a simple Bernoulli model that uses a two-layer neural network as the link function for the Bernoulli distribution. Initially, I put normal priors on the weight and bias terms in the first layer. For the second level, I used a sigmoid function to transform the outputs of the first layer to probabilities. It worked well. I’d like to do the same thing using the TensorFlow function “tf.layers.dense.” I’ve uploaded the code below. However, I’ve not had much success with the inference.
from future import absolute_import
from future import division
from future import print_function
import warnings warnings.filterwarnings(‘ignore’)
import edward as ed
import numpy as np
import tensorflow as tf
from edward.models import Bernoulli, Normal
def sigmoid(x):
return 1. / (1. + np.exp(-x))
ed.set_seed(42)
n = 1000
z_obs = np.random.normal(loc=10.0, scale=1.0, size=n)
p_true = sigmoid(z_obs - 10.0)
x_obs = np.random.binomial(n=1, p=p_true).reshape((n, 1))
regularizer = tf.contrib.layers.l2_regularizer(scale=0.001)
def neural_network(z, w, b):
h = tf.matmul(z, w) + b
h = tf.sigmoid(h)
return h
def nn(z):
h = tf.layers.dense(z, 1, activation=None, kernel_regularizer=regularizer)
h = tf.layers.dense(h, 1, activation=tf.nn.sigmoid)
return h
MODEL
with tf.name_scope(“model”):
z = Normal(loc=10.0, scale=1.00, sample_shape=[n, 1], name=“z”)
p = nn(z)
x = Bernoulli(probs=p, name=“x”)
INFERENCE
with tf.variable_scope(“posterior”):
with tf.variable_scope(“qz”):
qz_variables = [tf.get_variable(“qz/loc”, [n, 1]), tf.get_variable(“qz/scale”, [n, 1])]
qz = Normal(loc=qz_variables[0], scale=tf.nn.softplus(qz_variables[1]))
inference = ed.KLqp({z: qz}, data={x: x_obs})
inference.initialize(n_samples=3)
sess = ed.get_session()
tf.global_variables_initializer().run()
for _ in range(inference.n_iter):
info_dict = inference.update()
inference.print_progress(info_dict)
t = info_dict[‘t’]
if t % 100 == 0:
phat = sess.run§
1000/1000 [100%] Elapsed: 7s | Loss: 692.635 1s | Loss: ETA: 1s | Los ETA: 0s | Loss: 692
In [6]: np.set_printoptions(2)
phat.mean(), np.percentile(phat, q=[0.0, 2.5, 50, 97.5, 100.0])
Out[6]: (0.48400226, array([0.48, 0.48, 0.48, 0.48, 0.48]))
In [7]: np.set_printoptions(2)
p_true.mean(), np.percentile(p_true, q=[0.0, 2.5, 50, 97.5, 100.0])
Out[7]: (0.5028831582094038, array([0.04, 0.14, 0.51, 0.87, 0.98]))
Best,
Mark