Having trouble setting up basic HMC model


Hey all–my apologies for the newbie question, but I’m having some trouble setting up even a pretty basic model using HMC. Here’s the code I’m having trouble with:

import numpy as np
import tensorflow as tf
from edward.models import Normal, Empirical
import edward as ed

X_train = np.array([[ 0.87024415,  0.65901989],
       [ 0.09892046,  0.92157853],
       [ 0.34324086,  0.7804544 ],
       [ 0.19976632,  0.90515983],
       [ 0.75492591,  0.50158632],
       [ 0.41315702,  0.63009453],
       [ 0.40734398,  0.74817169],
       [ 0.85471708,  0.69424045],
       [ 0.14578448,  0.95430565],
       [ 0.51036876,  0.63925266]], dtype=np.float32)

y_train = np.array([[-0.1065    ],
       [-0.005     ],
       [ 0.0488    ],
       [ 0.0714    ],
       [-0.0192    ],
       [ 0.0944    ],
       [ 0.        ],
       [-0.0888    ],
       [ 0.0392    ],
       [-0.73610002]], dtype=np.float32)

layer_1_size = 10

W_0 = Normal(loc = tf.zeros([2,layer_1_size]), scale = tf.ones([2,layer_1_size]))
W_1 = Normal(loc = tf.zeros([layer_1_size,1]), scale = tf.ones([layer_1_size,1]))
b_0 = Normal(loc = tf.zeros(layer_1_size), scale = tf.ones(layer_1_size))
b_1 = Normal(loc = tf.zeros(1), scale = tf.ones(1))

x = tf.placeholder(dtype=np.float32)

y = Normal(loc = tf.matmul(tf.tanh(tf.matmul(x, W_0) + b_0), W_1) + b_1,
           scale = 0.1)

T = 10000
ydata = tf.constant(np.repeat([y_train],T,axis=0))

qy = Empirical(params = ydata)
inference = ed.HMC({y: qy}, data = {x: X_train})

When I run that, I get:

IndexError                                Traceback (most recent call last)
<ipython-input-122-8793699b40bc> in <module>()
----> 1 inference.run(n_iter=10000)

/home/matthew/anaconda3/envs/edward/lib/python3.6/site-packages/edward/inferences/inference.py in run(self, variables, use_coordinator, *args, **kwargs)
    114       Passed into ``initialize``.
    115     """
--> 116     self.initialize(*args, **kwargs)
    118     if variables is None:

/home/matthew/anaconda3/envs/edward/lib/python3.6/site-packages/edward/inferences/hmc.py in initialize(self, step_size, n_steps, *args, **kwargs)
     62     self.n_steps = n_steps
     63     self.scope_iter = 0  # a convenient counter for log joint calculations
---> 64     return super(HMC, self).initialize(*args, **kwargs)
     66   def build_update(self):

/home/matthew/anaconda3/envs/edward/lib/python3.6/site-packages/edward/inferences/monte_carlo.py in initialize(self, *args, **kwargs)
     96     self.n_accept = tf.Variable(0, trainable=False, name="n_accept")
     97     self.n_accept_over_t = self.n_accept / self.t
---> 98     self.train = self.build_update()
    100   def update(self, feed_dict=None):

/home/matthew/anaconda3/envs/edward/lib/python3.6/site-packages/edward/inferences/hmc.py in build_update(self)
    113     assign_ops = []
    114     for z, qz in six.iteritems(self.latent_vars):
--> 115       variable = qz.get_variables()[0]
    116       assign_ops.append(tf.scatter_update(variable, self.t, sample[z]))

IndexError: list index out of range

I have no idea what list is even being accessed here. All the dimensions seem right but maybe I’ve got something wrong:

<tf.Tensor 'Const_112:0' shape=(10000, 10, 1) dtype=float32>

<ed.RandomVariable 'Empirical_74/' shape=(10, 1) dtype=float32>

Incidentally, is my understanding of Empirical correct that I should be setting up a tf.constant tensor with the number of desired samples as the first dimension, with the target data repeated for each one?

Thanks very much for any assistance you can provide!



Before delving into code, it’s useful to reason about what your model is and what it means to infer hidden structure from your model via a posterior distribution.

In your example, you wrote a Bayesian neural network with likelihood y given x, and with weight and bias parameters W_0,W_1,b_0,b_1. You then set up data xdata and ydata.

To perform inference means to calculate a distribution over the weights and biases given the data. In particular, with something like HMC, you should set up Empirical distributions that each approximate W_0,W_1,b_0,b_1 respectively. For more background, I recommend the pages linked to in http://edwardlib.org/tutorials/.


So I guess based on your answer that I’m having some sort of fundamental misunderstanding about what the function of the Empirical distributions is in your examples. I’m coming from a PyMC background so I may be making some unfounded assumptions about how the syntax works. Here, I was attempting to place standard normal priors on W_0, W_1, b_0, and b_1, and then draw inference given x and y. I had assumed that y: qy (with qy filled with the observed values) was the way to get edward to treat y as a likelihood rather than as a prior, like setting the observed=True flag in PyMC (and then putting the observed values of y in qy). But it sounds like instead the Empiricals are used for holding the HMC samples from the posterior for the unknown parameters?



To treat y as data, you simply pass it into the corresponding argument during inference:

inference = ed.HMC({W_0: qW_0, b_0: qb_0,
                    W_1: qW_1, b_1: qb_1,
                    W_2: qW_2, b_2: qb_2}, data={X: X_train, y: y_train})

where q* are all the Empirical approximations. See the inference API for more details. For this example, a useful reference is the examples/bayesian_nn.py script in the Github repository.


Ah, excellent, thank you!