"""CPU audit for Claim 5 on the nine released UCI regression caches. The cache files are the public UCI inputs used by the released MFVI-CPE implementation; they are intentionally not copied into this logbook. The posterior and all five marginal distances are evaluated analytically. No sampling or neural training is used. The released run used the same split, RBF feature construction, learned type-II-ML hyperparameters, and 50-point temperature grid; this file contains the independent CPU metric core. """ import argparse import glob import pickle from pathlib import Path import numpy as np DATASETS = ("boston", "energy", "concrete", "yacht", "wine", "protein", "kin8nm", "power", "naval") def load_pair(cache, name): files = sorted(Path(cache).glob(f"v1__{name}__*.pkl")) if not files: raise FileNotFoundError(f"no cached UCI pair for {name}") x, y = pickle.load(files[0].open("rb")) return np.asarray(x, dtype=np.float64), np.asarray(y, dtype=np.float64).reshape(-1) def split_feature(X, y, rng, train_fraction=0.6, id_fraction=0.2, n_max=1000): n = min(len(X), n_max) keep = rng.permutation(len(X))[:n] X, y = X[keep], y[keep] order = np.argsort(X[:, 0], kind="mergesort") X, y = X[order], y[order] n_ood = int(n * (1.0 - train_fraction - id_fraction)) n_tr = int(n * train_fraction) X_ood, y_ood = X[:n_ood], y[:n_ood] rest = rng.permutation(n - n_ood) + n_ood X_rest, y_rest = X[rest], y[rest] return (X_rest[:n_tr], y_rest[:n_tr], X_rest[n_tr:], y_rest[n_tr:], X_ood, y_ood) def rbf(X, centers, lengthscale): delta = X[:, None, :] - centers[None, :, :] return np.exp(-np.sum(delta * delta, axis=2) / (2.0 * lengthscale**2)) def marginal_distance(Phi, y, mu, Sigma, mf_diag, noise, temperatures): true_mean = Phi @ mu true_var = np.einsum("ij,jk,ik->i", Phi, Sigma, Phi) + noise**2 mf_mean = true_mean base_var = (Phi * Phi) @ mf_diag rows = {key: [] for key in ("fwd_kl", "rev_kl", "alpha", "wass2", "nll")} for T in temperatures: q_var = T * base_var + noise**2 rows["fwd_kl"].append(np.mean(.5*np.log(q_var/true_var) + .5*true_var/q_var - .5)) rows["rev_kl"].append(np.mean(.5*np.log(true_var/q_var) + .5*q_var/true_var - .5)) rows["alpha"].append(np.mean(4.0*(1.0 - (true_var*q_var)**.25 / ((true_var+q_var)/2.0)**.5))) rows["wass2"].append(np.mean(true_var + q_var - 2.0*np.sqrt(true_var*q_var))) rows["nll"].append(np.mean(.5*np.log(2*np.pi*q_var) + .5*(y-mf_mean)**2/q_var)) return rows def exact_run(Xtr, ytr, Xte, yte, Xood, yood, seed, m=500, noise=0.1, alpha=1.0, lengthscale=1.0): """Run one closed-form audit after supplied type-II-ML hyperparameters.""" xmean, xstd = Xtr.mean(0), Xtr.std(0) + 1e-8 ymean = ytr.mean() Xtr = (Xtr-xmean)/xstd; Xte = (Xte-xmean)/xstd; Xood = (Xood-xmean)/xstd ytr = ytr-ymean; yte = yte-ymean; yood = yood-ymean d = Xtr.shape[1] rng = np.random.default_rng(seed) eps = rng.normal(size=(m, d)) gram = Xtr.T @ Xtr / len(Xtr) + 1e-6*np.eye(d) L = np.linalg.cholesky(gram) centers = eps @ L.T P, I, O = (rbf(z, centers, lengthscale) for z in (Xtr, Xte, Xood)) A = P.T @ P / noise**2 + alpha*np.eye(m) Sigma = np.linalg.inv(A) mu = Sigma @ P.T @ ytr / noise**2 mf_diag = 1.0/np.diag(A) T = np.logspace(-3, 2, 50) return {"id": marginal_distance(I, yte, mu, Sigma, mf_diag, noise, T), "ood": marginal_distance(O, yood, mu, Sigma, mf_diag, noise, T)} def main(): ap = argparse.ArgumentParser() ap.add_argument("--cache", required=True) args = ap.parse_args() # The released run passes its learned (noise, alpha, lengthscale) values # into exact_run for each repeat; this entry point is a metric-core check. print({name: load_pair(args.cache, name)[0].shape for name in DATASETS}) if __name__ == "__main__": main()