pronobis / libspn

Library for learning and inference with Sum-product Networks
Other
23 stars 3 forks source link

Evidence indicator feed #91

Closed anicolson closed 4 years ago

anicolson commented 4 years ago

Hi,

I have modified tutorial 2 to use normal leaves and to use the evidence indicator feed. Was curious why the output for no evidence is 0.2, and not 1.0? It seems to change to whatever I change the first weight of the root to (0.2 at the moment). Is it something I am missing?

Thanks for any help!

Here is the output from the script (see real_x_data and mask in the script, where mask is the evidence indicator)

[[0.07978846] [0.03167224] [0.2 ] [0.2 ]] [[0.03351115] [0.01330234] [0.08400001] [0.08400001]]


Here is the modified script of tutorial 2:

import libspn as spn import tensorflow as tf

num_vars = 2 num_leaf_components = 2 scale_init = 1.0 loc_init = 1.0

evidence_indicator_feed = tf.placeholder(tf.bool, shape=[None, num_vars], name='evidence_indicator_feed') normal_x = spn.NormalLeaf(num_components=num_leaf_components, num_vars=num_vars, trainable_scale=False, trainable_loc=True, scale_init=scale_init, loc_init=loc_init, evidence_indicator_feed=evidence_indicator_feed)

Build structure and attach weight

sum_11 = spn.Sum((normal_x, [0,1]), name="sum_11") sum_11.generate_weights(initializer=tf.initializers.constant([0.4, 0.6])) sum_12 = spn.Sum((normal_x, [0,1]), name="sum_12") sum_12.generate_weights(initializer=tf.initializers.constant([0.1, 0.9])) sum_21 = spn.Sum((normal_x, [2,3]), name="sum_21") sum_21.generate_weights(initializer=tf.initializers.constant([0.7, 0.3])) sum_22 = spn.Sum((normal_x, [2,3]), name="sum_22") sum_22.generate_weights(initializer=tf.initializers.constant([0.8, 0.2])) prod_1 = spn.Product(sum_11, sum_21, name="prod_1") prod_2 = spn.Product(sum_11, sum_22, name="prod_2") prod_3 = spn.Product(sum_12, sum_22, name="prod_3") root = spn.Sum(prod_1, prod_2, prod_3, name="root") root.generate_weights(initializer=tf.initializers.constant([0.2, 0.3, 0.5]))

Connect a latent indicator

indicator_y = root.generate_latent_indicators(name="indicator_y") # Can be added manually

Inspect

print(root.get_num_nodes()) print(root.get_scope()) print(root.is_valid())

init_weights = spn.initialize_weights(root) marginal_val = root.get_value(inference_type=spn.InferenceType.MARGINAL) mpe_val = root.get_value(inference_type=spn.InferenceType.MPE)

mask = [ [True, False], [True, True], [False, False], # should output 1.0 for this? [False, False], # should output 1.0 for this? ]

real_x_data = [ [1.0, 1.0], [1.0, 1.1], [1.0, 1.0], [10.0, -1.0], ]

indicator_y_data = [[0], [0], [0], [0]]

with tf.Session() as sess: init_weights.run() marginal_val_arr = sess.run(marginal_val, feed_dict={normal_x: real_x_data, evidence_indicator_feed: mask, indicator_y: indicator_y_data}) mpe_val_arr = sess.run(mpe_val, feed_dict={normal_x: real_x_data, evidence_indicator_feed: mask, indicator_y: indicator_y_data})

print(marginal_val_arr) print(mpe_val_arr)

anicolson commented 4 years ago

So i just use indicator_y_data = [[-1], [-1], [-1], [-1]] instead of indicator_y_data = [[0], [0], [0], [0]], and it works (output of 1.0 for no evidence). So I asume indicator_y_data = [[-1], [0], [1], [2]] would give outputs for the root, the first weight of the root, the second weight of the root, and then the third weight of the root.