Esempio n. 1
0
    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)
Esempio n. 2
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)
Esempio n. 3
0
    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)
Esempio n. 4
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)
Esempio n. 5
0
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