Example #1
0
def objective(vs, m, x_data, y_data, locs):
    """NLML objective.

    Args:
        vs (:class:`varz.Vars`): Variable container.
        m (int): Number of latent processes.
        x_data (tensor): Time stamps of the observations.
        y_data (tensor): Observations.
        locs (tensor): Spatial locations of observations.

    Returns:
        scalar: Negative log-marginal likelihood.
    """
    y_proj, _, S, noises_obs = project(vs, m, y_data, locs)
    xs, noise_obs, noises_latent = model(vs, m)

    # Add contribution of latent processes.
    lml = 0
    for i, (x, y) in enumerate(zip(xs, y_proj)):
        e_signal = GP((noise_obs / S[i] + noises_latent[i]) * Delta(),
                      graph=x.graph)
        lml += (x + e_signal)(x_data).logpdf(y)

        e_noise = GP(noise_obs / S[i] * Delta(), graph=x.graph)
        lml -= e_noise(x_data).logpdf(y)

    # Add regularisation contribution.
    lml += B.sum(Normal(Diagonal(noises_obs)).logpdf(B.transpose(y_data)))

    # Return negative the evidence, normalised by the number of data points.
    n, p = B.shape(y_data)
    return -lml / (n * p)
Example #2
0
def project(vs, m, y_data, locs):
    """Project the data.

    Args:
        vs (:class:`varz.Vars`): Variable container.
        m (int): Number of latent processes.
        y_data (tensor): Observations.
        locs (tensor): Spatial locations of observations.

    Returns:
        tuple: Tuple containing the projected outputs, the mixing matrix,
            S from the mixing matrix, and the observation noises.
    """
    _, noise_obs, noises_latent = model(vs, m)

    # Construct mixing matrix and projection.
    scales = vs.bnd(B.ones(2), name='scales')
    K = dense(Matern52().stretch(scales)(locs))
    U, S, _ = B.svd(K)
    S = S[:m]
    H = U[:, :m] * S[None, :]**.5
    T = B.transpose(U[:, :m]) / S[:, None]**.5

    # Project data and unstack over latent processes.
    y_proj = B.unstack(B.matmul(T, y_data, tr_b=True))

    # Observation noises:
    noises_obs = noise_obs * B.ones(B.dtype(noise_obs), B.shape(y_data)[1])

    return y_proj, H, S, noises_obs