def test_small_spn(self): num_vars = 13 indicator_leaf = spn.IndicatorLeaf(num_vals=2, num_vars=num_vars) randomize = BlockRandomDecompositions(indicator_leaf, num_decomps=2) p0 = BlockPermuteProduct(randomize, num_factors=4) s0 = BlockSum(p0, num_sums_per_block=3) p1 = BlockPermuteProduct(s0, num_factors=2) s1 = BlockSum(p1, num_sums_per_block=3) p2 = BlockReduceProduct(s1, num_factors=2) m = BlockMergeDecompositions(p2, num_decomps=1) root = BlockRootSum(m) latent = root.generate_latent_indicators(name="Latent") spn.generate_weights(root, initializer=tf.initializers.random_uniform()) valgen = spn.LogValue() val = valgen.get_value(root) logsum = tf.reduce_logsumexp(val) num_possibilities = 2**num_vars nums = np.arange(num_possibilities).reshape((num_possibilities, 1)) powers = 2**np.arange(num_vars).reshape((1, num_vars)) leaf_feed = np.bitwise_and(nums, powers) // powers with self.test_session() as sess: sess.run(spn.initialize_weights(root)) out = sess.run( logsum, { indicator_leaf: leaf_feed, latent: -np.ones((leaf_feed.shape[0], 1), dtype=np.int32) }) self.assertAllClose(out, 0.0)
def test_compute_mpe_path_dilated(self): grid_dims = [4, 4] input_channels = 2 vars = spn.RawLeaf(num_vars=grid_dims[0] * grid_dims[1] * input_channels) convprod = spn.ConvProducts(vars, num_channels=32, padding='valid', strides=1, spatial_dim_sizes=grid_dims, dilation_rate=2) valgen = spn.LogValue(inference_type=spn.InferenceType.MARGINAL) valgen.get_value(convprod) counts = np.stack([np.arange(16) + 23 * i for i in range(4)]).reshape( (1, 2, 2, 16)).astype(np.float32) var_counts = tf.reshape( convprod._compute_log_mpe_path(counts, valgen.values[vars])[0], (1, 4, 4, 2)) with self.test_session() as sess: var_counts_out = sess.run( var_counts, feed_dict={vars: np.random.rand(1, 4 * 4 * 2)}) print(var_counts_out)
def test_compute_value_sum(self, grid_size): indicator_leaf = spn.IndicatorLeaf(num_vals=2, num_vars=grid_size**2) convsum = ConvSums(indicator_leaf, spatial_dim_sizes=[grid_size, grid_size], num_channels=4) convsum2 = ConvSums(indicator_leaf, spatial_dim_sizes=[grid_size, grid_size], num_channels=4) dense_generator = spn.DenseSPNGenerator( num_mixtures=4, num_subsets=4, num_decomps=1, input_dist=spn.DenseSPNGenerator.InputDist.MIXTURE) root = dense_generator.generate(convsum, convsum2) spn.generate_weights(root, initializer=tf.initializers.random_uniform()) init = spn.initialize_weights(root) num_possibilities = 2**(grid_size**2) nums = np.arange(num_possibilities).reshape((num_possibilities, 1)) powers = 2**np.arange(grid_size**2).reshape((1, grid_size**2)) indicator_feed = np.bitwise_and(nums, powers) // powers value_op = spn.LogValue(spn.InferenceType.MARGINAL).get_value(root) value_op_sum = tf.reduce_logsumexp(value_op) with self.test_session() as sess: sess.run(init) root_sum = sess.run(value_op_sum, feed_dict={indicator_leaf: indicator_feed}) print(indicator_feed[:10]) self.assertAllClose(root_sum, 0.0)
def test_compute_mpe_path(self): grid_dims = [4, 4] input_channels = 2 vars = spn.RawLeaf(num_vars=grid_dims[0] * grid_dims[1] * input_channels) convprod = spn.ConvProducts(vars, num_channels=32, padding='valid', strides=2, spatial_dim_sizes=grid_dims) valgen = spn.LogValue(inference_type=spn.InferenceType.MARGINAL) valgen.get_value(convprod) counts = np.stack([ np.arange(16), np.arange(16) + 1000, np.arange(16) + 10000, np.arange(16) + 100000 ]).reshape((1, 2, 2, 16)).astype(np.float32) var_counts = tf.reshape( convprod._compute_log_mpe_path(counts, valgen.values[vars])[0], (1, 4, 4, 2)) truth_single_square = np.asarray([[ 0 + 2 + 4 + 6 + 8 + 10 + 12 + 14, 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 ], [ 0 + 1 + 4 + 5 + 8 + 9 + 12 + 13, 2 + 3 + 6 + 7 + 10 + 11 + 14 + 15 ], [ 0 + 1 + 2 + 3 + 8 + 9 + 10 + 11, 4 + 5 + 6 + 7 + 12 + 13 + 14 + 15 ], [ 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7, 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 ]]).reshape((2, 2, 2)) truth_top_squares = np.concatenate( [truth_single_square, truth_single_square + 8000], axis=1) truth_bottom_squares = np.concatenate( [truth_single_square + 80000, truth_single_square + 800000], axis=1) truth = np.concatenate((truth_top_squares, truth_bottom_squares), axis=0).reshape((1, 4, 4, 2)) with self.test_session() as sess: var_counts_out = sess.run( var_counts, feed_dict={vars: np.random.rand(1, 4 * 4 * 2)}) self.assertAllClose(truth, var_counts_out)
def setup_learning(args, in_var, root): no_op = tf.constant(0) inference_type = spn.InferenceType.MARGINAL if args.value_inf_type == 'marginal' \ else spn.InferenceType.MPE mpe_state = spn.MPEState(value_inference_type=inference_type, matmul_or_conv=True) if args.supervised: # Root is provided with labels, p(x,y) labels_node = root.generate_latent_indicators(name="LabelIndicators") # Marginalized root, so without filling in labels, so p(x) = \sum_y p(x,y) root_marginalized = spn.Sum(*root.values, name="RootMarginalized", weights=root.weights) # A dummy node to get MPE state labels_no_evidence_node = root_marginalized.generate_latent_indicators( name="LabesNoEvidenceIndicators", feed=-tf.ones([tf.shape(in_var.feed)[0], 1], dtype=tf.int32)) # Get prediction from dummy node with tf.name_scope("Prediction"): logger.info("Setting up MPE state") if args.completion_by_marginal and isinstance( in_var, ContinuousLeafBase): in_var_mpe = in_var.impute_by_posterior_marginal( labels_no_evidence_node) class_mpe, = mpe_state.get_state(root_marginalized, labels_no_evidence_node) else: class_mpe, in_var_mpe = mpe_state.get_state( root_marginalized, labels_no_evidence_node, in_var) correct = tf.squeeze( tf.equal(class_mpe, tf.to_int64(labels_node.feed))) else: with tf.name_scope("Prediction"): class_mpe = correct = no_op labels_node = root_marginalized = None if args.completion_by_marginal and isinstance( in_var, ContinuousLeafBase): in_var_mpe = in_var.impute_by_posterior_marginal(root) else: in_var_mpe, = mpe_state.get_state(root, in_var) # Get the log likelihood with tf.name_scope("LogLikelihoods"): logger.info("Setting up log-likelihood") val_gen = spn.LogValue(inference_type=inference_type) labels_llh = val_gen.get_value(root) no_labels_llh = val_gen.get_value( root_marginalized) if args.supervised else labels_llh if args.learning_algo == "em": em_learning = spn.HardEMLearning( root, value_inference_type=inference_type, initial_accum_value=args.initial_accum_value, sample_winner=args.sample_path, sample_prob=args.sample_prob, use_unweighted=args.use_unweighted) accumulate = em_learning.accumulate_updates() with tf.control_dependencies([accumulate]): update_op = em_learning.update_spn() return correct, labels_node, labels_llh, no_labels_llh, update_op, class_mpe, no_op, \ no_op, in_var_mpe logger.info("Setting up GD learning") global_step = tf.Variable(0, trainable=False) learning_rate = tf.train.exponential_decay(args.learning_rate, global_step, args.lr_decay_steps, args.lr_decay_rate, staircase=True) learning_method = spn.LearningMethodType.DISCRIMINATIVE if args.learning_type == 'discriminative' else \ spn.LearningMethodType.GENERATIVE learning = spn.GDLearning( root, learning_task_type=spn.LearningTaskType.SUPERVISED if args.supervised else \ spn.LearningTaskType.UNSUPERVISED, learning_method=learning_method, learning_rate=learning_rate, marginalizing_root=root_marginalized, global_step=global_step) optimizer = { 'adam': tf.train.AdamOptimizer, 'rmsprop': tf.train.RMSPropOptimizer, 'amsgrad': AMSGrad, }[args.learning_algo]() minimize_op, _ = learning.learn(optimizer=optimizer) logger.info("Settting up test loss") with tf.name_scope("DeterministicLoss"): main_loss = learning.loss() regularization_loss = learning.regularization_loss() loss_per_sample = learning.loss( reduce_fn=lambda x: tf.reshape(x, (-1, ))) return correct, labels_node, main_loss, no_labels_llh, minimize_op, class_mpe, \ regularization_loss, loss_per_sample, in_var_mpe