Bayesian Network inference using Edward


#1

Inspired by the Sprinkler example (great work):

I created this demo:

with Categorical distribution, it is a simple network as well, but with more states in the node, the images in the notebook is the result of Bayes Server, a Bayesian network inference tool, in order to cross verify the KLpq inference result.

The result does not seems to be very accurate, and some how the state index is kind of incorrect, it might be the problem that I constrcut the network incorrect as well.

Please leave a commet about this work, if you think anything is wrong or incorrect, let’s work on it and make
Edward more friendly to BN development.

PS: I tried Dirichlet distribution to create the q_ distribution, but it stops at the inference.run() step and yields not log_prob error, any one got ideas?

Regards


#2

I’m trying to do the same thing. So we are kind of business competitors :).

I will put up my work in github very soon.

I’m a beginner so take my advice with a grain of salt, but Let me make some points:

(1) What I have done is to write a script that reads a .bif file and writes a file containing the corresponding Edward model. For that, I use tools from my own B net application Quantum Fog. Maybe you should do something similar, but using your preferred application Bayes Server.

For example, for the network (all arrows pointing down)

         Cloudy
      /          \
Sprinkler        Rain
    \             /
        WetGrass

my script reads the bif fiile and writes the following model:

import numpy as np
import tensorflow as tf
import edward as ed
import edward.models as edm


# node names in lexicographic (alphabetic) order
nd_names_lex_ord = ['Cloudy', 'Rain', 'Sprinkler', 'WetGrass']

# node names in topological (chronological) order
nd_names_topo_ord = ['Cloudy', 'Sprinkler', 'Rain', 'WetGrass']

with tf.name_scope('model'):
    p_Cloudy = np.array([ 0.5,  0.5])
    Cloudy = edm.Categorical(
        probs=p_Cloudy, name='Cloudy')

    arr_Sprinkler = np.array([[ 0.2,  0.8],
       [ 0.7,  0.3]])
    p_Sprinkler = tf.convert_to_tensor(arr_Sprinkler, dtype=tf.float32)[
        Cloudy, :]
    Sprinkler = edm.Categorical(
        probs=p_Sprinkler, name='Sprinkler')

    arr_Rain = np.array([[ 0.4,  0.6],
       [ 0.5,  0.5]])
    p_Rain = tf.convert_to_tensor(arr_Rain, dtype=tf.float32)[
        Cloudy, :]
    Rain = edm.Categorical(
        probs=p_Rain, name='Rain')

    arr_WetGrass = np.array([[[ 0.99,  0.01],
        [ 0.01,  0.99]],

       [[ 0.01,  0.99],
        [ 0.01,  0.99]]])
    p_WetGrass = tf.convert_to_tensor(arr_WetGrass, dtype=tf.float32)[
        Sprinkler, Rain, :]
    WetGrass = edm.Categorical(
        probs=p_WetGrass, name='WetGrass')

with tf.name_scope('posterior'):
    Cloudy_q = edm.Categorical(
        probs=tf.nn.softmax(tf.get_variable('Cloudy_q/probs', shape=[2])),
        name='Cloudy_q')

    Sprinkler_q = edm.Categorical(
        probs=tf.nn.softmax(tf.get_variable('Sprinkler_q/probs', shape=[2])),
        name='Sprinkler_q')

    Rain_q = edm.Categorical(
        probs=tf.nn.softmax(tf.get_variable('Rain_q/probs', shape=[2])),
        name='Rain_q')

    WetGrass_q = edm.Categorical(
        probs=tf.nn.softmax(tf.get_variable('WetGrass_q/probs', shape=[2])),
        name='WetGrass_q')

I define a query (_q) variable for all the nodes but of course, I will only use the query variables for latent nodes. The script also has an option to define the root nodes as placeholders or as Categoricals. In this example, I defined them all as Categoricals

(2) I see from github that you are interested in QISKit in Chinese.
We seem to be on the same page there. I am very interested in using Edward for doing quantum computing. I’m not Chinese, but if you are, the CTO Dr. Tao Yin of my company (artiste-qb.net) is Chinese and lives in ShenZhen


#3

Uploaded my notebook to github


#4

Great work, Dr. Tucci !
It is a great pleasure some one else is working on the same topic.
I think Edward has a great potential in Bayesian Network usgage.
Although BN is not a hot topic in machine learning area at the moment, but it still a good tool for data exploration.
May be we can do something with Edward such as warp the Edward code with NetworkX, might be easier to construct Bayesian networ or other DAG models.

PS: 1. yeah, I am a Chinese, and I am interested in Quantum Computing, ^-^.
2. Very interesting to see your work with combination of QC and Edward.


#5

Hello rrtucci,

I was wondering whether you have any update on the discrete Bayesian network above?

In the case evidence is set, the query on evidence below does not give probability 1 for the evidence, which seems a bit suspicious.

print('\nCloudy')
print(Cloudy_q.probs.eval())

Best,
M

Summary

This text will be hidden


#6

Hi Michalis,
The notebook whose link appears above is my latest. However, note that since Cloudy is observed, the Cloudy_q variable is never used, so it probably just gives whatever it was initiated with.


#8

Thanks Robert,

It would have been nice to see that the query is at 100% for validation. As it is, it is not clear whether the evidence is set properly, which could be related with the large variations we see with respect to exact inference in this example…