# 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})
inference.run(n_iter=10000)
``````

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)
117
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)
65
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()
99
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()
116       assign_ops.append(tf.scatter_update(variable, self.t, sample[z]))
117

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:

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

qy
<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!

Matt

1 Like

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 `Empirical`s are used for holding the HMC samples from the posterior for the unknown parameters?

Yes.

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.

2 Likes

Ah, excellent, thank you!