示例#1
0
    def __init__(self, kernel, X, Y, noise_var, n_features, normalize_Y=False):
        self.input_dim = kernel.input_dim
        self.lengthscale = kernel.lengthscale
        self.signal_var = kernel.variance
        self.noise_var = noise_var
        self.X = X
        self.Y = Y if Y.ndim == 2 else np.atleast_2d(Y).T

        self.normalize_Y = normalize_Y
        if self.normalize_Y:
            self.Y, self.y_mean = shift_y(Y)

        self.n_features = n_features
        self.w = None
        self.b = None
        self.phi = self._compute_phi()

        phi_train = self.phi(X)
        A = phi_train @ phi_train.T + self.noise_var * np.eye(self.n_features)
        chol_A = misc.compute_stable_cholesky(A)

        B = np.eye(self.X.shape[0]) + phi_train.T @ phi_train / self.noise_var
        chol_B = misc.compute_stable_cholesky(B)
        v = linalg.cho_solve(chol_B, phi_train.T)

        a_inv = (np.eye(self.n_features) - phi_train @ v / self.noise_var)

        self.theta_mu = linalg.cho_solve(chol_A, phi_train @ self.Y)
        self.theta_var = a_inv
示例#2
0
    def sample_posterior_handle_with_filtered_counterpart(
            self, n_samples, input_var):
        """
        Generate handle to n_samples function samples that can be evaluated at x.
        Additionally generate a handle to the Gaussian-filtered counterpart of this
        sample.
        """
        chol = misc.compute_stable_cholesky(self.theta_var)[0]
        theta_samples = self.theta_mu + chol @ np.random.randn(
            self.n_features, n_samples)

        def handle_to_function_samples(x):
            if x.ndim == 1 and self.input_dim == 1:
                x = np.atleast_2d(x).T
            elif x.ndim == 1 and self.input_dim > 1:
                x = np.atleast_2d(x)

            h = self.phi(x).T @ theta_samples
            return deshift_y(h, self.y_mean) if self.normalize_Y else h

        def handle_to_filtered_function_samples(x):
            if x.ndim == 1 and self.input_dim == 1:
                x = np.atleast_2d(x).T
            elif x.ndim == 1 and self.input_dim > 1:
                x = np.atleast_2d(x)

            phi_filt = self._compute_phi_filt(input_var)
            h = phi_filt(x).T @ theta_samples
            return deshift_y(h, self.y_mean) if self.normalize_Y else h

        return handle_to_function_samples, handle_to_filtered_function_samples
示例#3
0
def predictive_cond_dist(x, ngp, g_star, nm3, nv3):
    n_eval = x.shape[0]
    X = ngp.X
    Y = gp_module.deshift_y(ngp.Y, ngp.y_mean) if ngp.normalize_Y else ngp.Y
    m5, v5 = np.empty((n_eval, )), np.empty((n_eval, ))
    k_f = ngp.kernel.K
    k_g = ngp.kernel_g.K
    k_fg = ngp.kernel_fg.K
    for i, xi in enumerate(x):
        xi = np.atleast_2d(xi)
        kf_Xx = k_f(X, xi)
        kgf_xx = k_fg(xi)
        kz = np.vstack((kf_Xx, kgf_xx))

        kg_xx = k_g(xi)
        kf_XX_noise = k_f(X) + ngp.noise_var * np.eye(X.shape[0])
        kfg_Xx = k_fg(X, xi)

        tmp1 = np.hstack((kf_XX_noise, kfg_Xx))
        tmp2 = np.hstack((kfg_Xx.T, kg_xx))
        Kz = np.vstack((tmp1, tmp2))

        Kz_chol = misc.compute_stable_cholesky(Kz)
        s = linalg.cho_solve(Kz_chol, kz)  # s = inv(Kz) @ kz
        cov4 = k_f(xi) - s.T @ kz
        a1 = s.T[:, :-1]
        a2 = s.T[:, -1:]

        m5[i] = a1 @ Y + a2 * nm3[i]
        v5[i] = cov4 + a2**2 * nv3[i]

    return m5, v5
示例#4
0
    def set_xy(self, X, Y):
        self.X = X
        self.Y = Y

        if self.normalize_Y:
            self.Y, self.y_mean = shift_y(Y)

        K = self.kernel.K(X) + self.noise_var * np.eye(X.shape[0])
        self.chol = misc.compute_stable_cholesky(K)
        self.alpha = linalg.cho_solve(self.chol, self.Y)
示例#5
0
    def __init__(self, kernel, X, Y, noise_var, normalize_Y=False):
        self.kernel = kernel
        self.input_dim = kernel.input_dim
        self.X = X
        self.Y = Y
        self.noise_var = noise_var

        self.normalize_Y = normalize_Y
        if self.normalize_Y:
            self.Y, self.y_mean = shift_y(Y)

        K = self.kernel.K(X) + self.noise_var * np.eye(X.shape[0])
        self.chol = misc.compute_stable_cholesky(K)
        self.alpha = linalg.cho_solve(self.chol, self.Y)
示例#6
0
    def sample_posterior_handle(self, n_samples):
        """
        Generate handle to n_samples function samples that can be evaluated at x.
        """
        chol = misc.compute_stable_cholesky(self.theta_var)[0]
        theta_samples = self.theta_mu + chol @ np.random.randn(
            self.n_features, n_samples)

        def handle_to_function_samples(x):
            if x.ndim == 1 and self.input_dim == 1:
                x = np.atleast_2d(x).T
            elif x.ndim == 1 and self.input_dim > 1:
                x = np.atleast_2d(x)

            h = self.phi(x).T @ theta_samples
            return deshift_y(h, self.y_mean) if self.normalize_Y else h

        return handle_to_function_samples
示例#7
0
def trunc_gauss_approx_g(x, ngp, max_val, mu1, cov1):
    k_f = ngp.kernel.K
    k_fg = ngp.kernel_fg.K
    k_g = ngp.kernel_g.K
    X = ngp.X
    Y = gp_module.deshift_y(ngp.Y, ngp.y_mean) if ngp.normalize_Y else ngp.Y
    n_data = X.shape[0]

    # Step 1: p( g | y, g*) \propto p( g | y ) \prod Indicator(g* > g_i)
    # This is pre-computed and given via mu1, cov1

    # Step 2: p0( g(x) | y, g*) = \int p( g(x) | g, y ) p( g | y, g*) dg
    # Pre-calculate bunch of kernel matrices
    kfg_XX = k_fg(X)
    kf_XX_noisy = k_f(X) + ngp.noise_var * np.eye(n_data)
    K = np.vstack((np.hstack((k_g(X), kfg_XX)), np.hstack(
        (kfg_XX, kf_XX_noisy))))
    k_xX = np.hstack((k_g(x, X), k_fg(X, x).T))

    # p( g(x) | g, y ) = N( g(x) | mu_g, cov_g )
    K_chol = misc.compute_stable_cholesky(K)
    s = linalg.cho_solve(K_chol, k_xX.T)

    covg = k_g(x) - s.T @ k_xX.T
    a1 = s.T[:, :n_data]
    a2 = s.T[:, n_data:]

    # p0(g(x) | y, g *) = N( g(x) | mu2, v2 )
    mu2 = a1 @ mu1[:, None] + a2 @ Y
    cov2 = covg + a1 @ cov1 @ a1.T

    m2 = mu2.squeeze()
    v2 = np.diag(cov2)

    # Step 3: p( g(x) | y, g*) = N( g(x) | mu3, v3 )
    alpha = (max_val - m2) / np.sqrt(v2)
    r = stats.norm.pdf(alpha) / stats.norm.cdf(alpha)
    m3 = m2 - np.sqrt(v2 * r)
    v3 = v2 - v2 * r * (r + alpha)

    return m3, v3