Buckets:
| import json | |
| from pathlib import Path | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt # noqa: E402 | |
| import numpy as np # noqa: E402 | |
| RESULTS_DIR = Path(__file__).resolve().parents[1] / "results" | |
| def plot_exp1(): | |
| d = json.load(open(RESULTS_DIR / "exp1_bilevel_rate.json")) | |
| det_rows = d["deterministic"]["rows"] | |
| sto_rows = d["stochastic"]["rows"] | |
| det_slopes = d["deterministic"]["fitted_slopes"] | |
| sto_slopes = d["stochastic"]["fitted_slopes"] | |
| fig, ax = plt.subplots(1, 2, figsize=(11, 4.2)) | |
| Ks_d = [r["K"] for r in det_rows]; grad_d = [r["grad_norm_sq"] for r in det_rows] | |
| Ks_s = [r["K"] for r in sto_rows]; grad_s = [r["grad_norm_sq"] for r in sto_rows] | |
| ax[0].loglog(Ks_d, grad_d, "o--", label=f"deterministic (slope={det_slopes['grad_norm_sq']:.2f})", color="#999999") | |
| ax[0].loglog(Ks_s, grad_s, "o-", label=f"stochastic (slope={sto_slopes['grad_norm_sq']:.2f})", color="#2166ac") | |
| ref = grad_s[0] * (np.array(Ks_s) / Ks_s[0]) ** (-2 / 3) | |
| ax[0].loglog(Ks_s, ref, "--", label=r"$O(K^{-2/3})$ (Thm 3.4)", color="#b2182b") | |
| ax[0].set_xlabel("K (iterations)"); ax[0].set_ylabel(r"$\min_k \|\nabla \mathcal{F}^*(\bar x^k)\|^2$") | |
| ax[0].set_title("Claim 2: Theorem 3.4 hypergradient rate"); ax[0].legend(fontsize=8); ax[0].grid(True, which="both", alpha=0.3) | |
| consx_d = [r["cons_x"] for r in det_rows]; consx_s = [r["cons_x"] for r in sto_rows] | |
| ax[1].loglog(Ks_d, consx_d, "o--", label=f"deterministic (slope={det_slopes['cons_x']:.1f})", color="#999999") | |
| ax[1].loglog(Ks_s, consx_s, "o-", label=f"stochastic (slope={sto_slopes['cons_x']:.2f})", color="#2166ac") | |
| ref2 = consx_s[0] * (np.array(Ks_s) / Ks_s[0]) ** (-1) | |
| ax[1].loglog(Ks_s, ref2, "--", label=r"$O(K^{-1})$ (Prop 3.5)", color="#b2182b") | |
| ax[1].set_xlabel("K (iterations)"); ax[1].set_ylabel(r"$\min_k \frac{1}{n}\sum_i\|x_i^k-\bar x^k\|^2$") | |
| ax[1].set_title("Claim 4: Proposition 3.5 consensus rate"); ax[1].legend(fontsize=8); ax[1].grid(True, which="both", alpha=0.3) | |
| fig.tight_layout() | |
| fig.savefig(RESULTS_DIR / "exp1_bilevel_rate.png", dpi=140) | |
| plt.close(fig) | |
| def plot_exp2(): | |
| d = json.load(open(RESULTS_DIR / "exp2_pushpull_rate.json")) | |
| rows = d["rows"] | |
| Ks = [r["K"] for r in rows] | |
| grad = [r["grad_norm_sq"] for r in rows] | |
| cons = [r["cons"] for r in rows] | |
| sens = d["eta_sensitivity"] | |
| stoch = d["stochastic"] | |
| fig, ax = plt.subplots(1, 2, figsize=(11, 4.2)) | |
| ax[0].loglog(Ks, grad, "o--", label=r"deterministic grad$^2$ ($\eta_x$=0.01)", color="#999999") | |
| ax[0].loglog(stoch["checkpoints"], stoch["grad_norm_sq"], "o-", | |
| label=f"stochastic grad$^2$ (slope={stoch['fitted_slope']:.2f})", color="#2166ac") | |
| ref = stoch["grad_norm_sq"][0] * (np.array(stoch["checkpoints"]) / stoch["checkpoints"][0]) ** (-1) | |
| ax[0].loglog(stoch["checkpoints"], ref, "--", label=r"$O(K^{-1})$ (Thm 3.6)", color="#b2182b") | |
| ax[0].set_xlabel("K (iterations)"); ax[0].set_ylabel("metric") | |
| ax[0].set_title("Claim 3: Theorem 3.6 Push-Pull rate"); ax[0].legend(fontsize=8); ax[0].grid(True, which="both", alpha=0.3) | |
| etas = [r["eta_x"] for r in sens] | |
| c25600 = [max(r["cons_at_25600"], 1e-40) for r in sens] | |
| ax[1].semilogy(etas, c25600, "o-", color="#762a83") | |
| ax[1].set_xlabel(r"fixed step size $\eta_x$"); ax[1].set_ylabel(r"consensus error at $K$=25600") | |
| ax[1].set_title("Step-size threshold (Thm 3.6)", fontsize=11) | |
| ax[1].grid(True, which="both", alpha=0.3) | |
| fig.tight_layout() | |
| fig.savefig(RESULTS_DIR / "exp2_pushpull_rate.png", dpi=140) | |
| plt.close(fig) | |
| def plot_exp3(): | |
| d = json.load(open(RESULTS_DIR / "exp3_fashion_mnist.json")) | |
| fig, ax = plt.subplots(1, 2, figsize=(11, 4.2)) | |
| colors = {"cr_0.3": "#2166ac", "cr_0.5": "#b2182b"} | |
| for cr, v in d.items(): | |
| ks_f = [p[0] for p in v["fab_test_acc"]] | |
| acc_f = [p[1] for p in v["fab_test_acc"]] | |
| ks_b = [p[0] for p in v["baseline_test_acc"]] | |
| acc_b = [p[1] for p in v["baseline_test_acc"]] | |
| c = colors.get(cr, "black") | |
| ax[0].plot(ks_f, acc_f, "-", color=c, label=f"FAB ({cr})") | |
| ax[0].plot(ks_b, acc_b, "--", color=c, label=f"baseline ({cr})") | |
| ax[0].set_xlabel("iteration"); ax[0].set_ylabel("held-out test accuracy") | |
| ax[0].set_title("Claim 5: Fashion-MNIST hyper-cleaning"); ax[0].legend(fontsize=8); ax[0].grid(alpha=0.3) | |
| crs = list(d.keys()) | |
| w_corrupt = [d[cr]["learned_weight_by_corruption"]["mean_weight_corrupted_examples"] for cr in crs] | |
| w_clean = [d[cr]["learned_weight_by_corruption"]["mean_weight_clean_examples"] for cr in crs] | |
| xpos = np.arange(len(crs)) | |
| ax[1].bar(xpos - 0.18, w_corrupt, width=0.35, label="corrupted examples", color="#b2182b") | |
| ax[1].bar(xpos + 0.18, w_clean, width=0.35, label="clean examples", color="#2166ac") | |
| ax[1].set_xticks(xpos); ax[1].set_xticklabels(crs) | |
| ax[1].set_ylabel("mean learned weight sigmoid(x)") | |
| ax[1].set_title("FAB down-weights corrupted examples"); ax[1].legend(fontsize=8); ax[1].grid(alpha=0.3, axis="y") | |
| fig.tight_layout() | |
| fig.savefig(RESULTS_DIR / "exp3_fashion_mnist.png", dpi=140) | |
| plt.close(fig) | |
| if __name__ == "__main__": | |
| plot_exp1() | |
| plot_exp2() | |
| plot_exp3() | |
| print("Saved plots to", RESULTS_DIR) | |
Xet Storage Details
- Size:
- 5.3 kB
- Xet hash:
- 3696754e43a28162e99d757ec58c5b182e49ef718ee697b5ba541777eb24f7ee
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.