Example #1
0
def test_softmax_y_shape_assert(num, dimF, dimY):
    """
    SoftMax assumes the class is given as a label (not, e.g., one-hot
    encoded), and hence just uses the first column of Y. To prevent
    silent errors, there is a tf assertion that ensures Y only has one
    dimension. This test checks that this assert works as intended.
    """
    F = tf.random.normal((num, dimF))
    dY = np.vstack((np.random.randn(num - 3, dimY), np.ones((3, dimY)))) > 0
    Y = tf.convert_to_tensor(dY, dtype=default_int())
    likelihood = Softmax(dimF)
    try:
        likelihood.log_prob(F, Y)
    except tf.errors.InvalidArgumentError as e:
        assert "Condition x == y did not hold." in e.message
Example #2
0
    def __init__(self,
                 gating_function_list: List[SVGPGatingFunction] = None,
                 likelihood: Likelihood = None,
                 name='GatingNetwork'):
        super().__init__(gating_function_list, name=name)
        # assert isinstance(gating_function_list, List)
        # for gating_function in gating_function_list:
        #     assert isinstance(gating_function, SVGPGatingFunction)
        # self.gating_function_list = gating_function_list
        # self.num_experts = len(gating_function_list)

        if likelihood is None:
            self.likelihood = Softmax(num_classes=self.num_experts)
            # self.likelihood = Softmax(num_classes=1)
        else:
            self.likelihood = likelihood
Example #3
0
def test_softmax_bernoulli_equivalence(num, dimF, dimY):
    dF = np.vstack(
        (np.random.randn(num - 3,
                         dimF), np.array([[-3.0, 0.0], [3, 0.0], [0.0, 0.0]])))
    dY = np.vstack((np.random.randn(num - 3, dimY), np.ones((3, dimY)))) > 0
    F = to_default_float(dF)
    Fvar = tf.exp(
        tf.stack([F[:, 1], -10.0 + tf.zeros(F.shape[0], dtype=F.dtype)],
                 axis=1))
    F = tf.stack([F[:, 0], tf.zeros(F.shape[0], dtype=F.dtype)], axis=1)
    Y = to_default_int(dY)
    Ylabel = 1 - Y

    softmax_likelihood = Softmax(dimF)
    bernoulli_likelihood = Bernoulli(invlink=tf.sigmoid)
    softmax_likelihood.num_monte_carlo_points = int(
        0.3e7)  # Minimum number of points to pass the test on CircleCI
    bernoulli_likelihood.num_gauss_hermite_points = 40

    assert_allclose(
        softmax_likelihood.conditional_mean(F)[:, :1],
        bernoulli_likelihood.conditional_mean(F[:, :1]),
    )

    assert_allclose(
        softmax_likelihood.conditional_variance(F)[:, :1],
        bernoulli_likelihood.conditional_variance(F[:, :1]),
    )

    assert_allclose(
        softmax_likelihood.log_prob(F, Ylabel),
        bernoulli_likelihood.log_prob(F[:, :1], Y.numpy()),
    )

    mean1, var1 = softmax_likelihood.predict_mean_and_var(F, Fvar)
    mean2, var2 = bernoulli_likelihood.predict_mean_and_var(
        F[:, :1], Fvar[:, :1])

    assert_allclose(mean1[:, 0, None], mean2, rtol=2e-3)
    assert_allclose(var1[:, 0, None], var2, rtol=2e-3)

    ls_ve = softmax_likelihood.variational_expectations(F, Fvar, Ylabel)
    lb_ve = bernoulli_likelihood.variational_expectations(
        F[:, :1], Fvar[:, :1], Y.numpy())
    assert_allclose(ls_ve, lb_ve, rtol=5e-3)
Example #4
0
class SVGPGatingNetworkMulti(SVGPGatingNetworkBase):
    # TODO either remove likelihood or use Bernoulli/Softmax
    def __init__(self,
                 gating_function_list: List[SVGPGatingFunction] = None,
                 likelihood: Likelihood = None,
                 name='GatingNetwork'):
        super().__init__(gating_function_list, name=name)
        # assert isinstance(gating_function_list, List)
        # for gating_function in gating_function_list:
        #     assert isinstance(gating_function, SVGPGatingFunction)
        # self.gating_function_list = gating_function_list
        # self.num_experts = len(gating_function_list)

        if likelihood is None:
            self.likelihood = Softmax(num_classes=self.num_experts)
            # self.likelihood = Softmax(num_classes=1)
        else:
            self.likelihood = likelihood

    def predict_mixing_probs(self,
                             Xnew: InputData,
                             num_inducing_samples: int = None) -> tf.Tensor:

        mixing_probs = []
        Fmu, Fvar = [], []
        for gating_function in self.gating_function_list:
            # num_inducing_samples = None
            f_mu, f_var = gating_function.predict_f(Xnew, num_inducing_samples)
            Fmu.append(f_mu)
            Fvar.append(f_var)
        # Fmu = tf.stack(Fmu)
        # Fvar = tf.stack(Fvar)
        Fmu = tf.stack(Fmu, -1)
        Fvar = tf.stack(Fvar, -1)
        # Fmu = tf.concat(Fmu, -1)
        # Fvar = tf.concat(Fvar, -1)
        if num_inducing_samples is None:
            Fmu = tf.transpose(Fmu, [1, 0, 2])
            Fvar = tf.transpose(Fvar, [1, 0, 2])
        else:
            Fmu = tf.transpose(Fmu, [2, 0, 1, 3])
            Fvar = tf.transpose(Fvar, [2, 0, 1, 3])

        # TODO output dimension is always 1 so delete this
        def single_output_predict_mean(args):
            Fmu, Fvar = args

            def single_predict_mean(args):
                Fmu, Fvar = args
                integrand2 = lambda *X: self.likelihood.conditional_variance(
                    *X) + tf.square(self.likelihood.conditional_mean(*X))
                epsilon = None
                E_y, E_y2 = ndiag_mc(
                    [self.likelihood.conditional_mean, integrand2],
                    S=self.likelihood.num_monte_carlo_points,
                    Fmu=Fmu,
                    Fvar=Fvar,
                    epsilon=epsilon)
                return E_y

            if num_inducing_samples is None:
                mixing_probs = self.likelihood.predict_mean_and_var(Fmu,
                                                                    Fvar)[0]
            else:
                # mixing_probs = tf.map_fn(single_predict_mean, (Fmu, Fvar),
                #                          dtype=tf.float64)
                mixing_probs = tf.vectorized_map(single_predict_mean,
                                                 (Fmu, Fvar))
            return mixing_probs

        # mixing_probs = tf.map_fn(single_output_predict_mean, (Fmu, Fvar),
        #                          dtype=tf.float64)
        mixing_probs = tf.vectorized_map(single_output_predict_mean,
                                         (Fmu, Fvar))
        if num_inducing_samples is None:
            mixing_probs = tf.transpose(mixing_probs, [1, 0, 2])
        else:
            mixing_probs = tf.transpose(mixing_probs, [1, 2, 0, 3])
        # mixing_probs = tf.transpose(mixing_probs, [1, 2, 0, 3])
        return mixing_probs