Download scripts/plot_interventions_readme.py from Avra98/latent_backtrack: direct link, hf CLI and curl.
- Browser
- Download file 5.87 kB
-
https://huggingface.co/Avra98/latent_backtrack/resolve/main/scripts/plot_interventions_readme.py
- Command line
-
hf download hf://Avra98/latent_backtrack/scripts/plot_interventions_readme.py
-
curl -L -o plot_interventions_readme.py https://huggingface.co/Avra98/latent_backtrack/resolve/main/scripts/plot_interventions_readme.py
5.87 kB
| #!/usr/bin/env python3 | |
| """Regenerate intervention figures for the README from saved JSON.""" | |
| from __future__ import annotations | |
| import json | |
| from pathlib import Path | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| ROOT = Path(__file__).resolve().parents[1] | |
| IN = ROOT / "figs" / "interventions" | |
| OUT = IN | |
| COLORS = {"CSO": "#c0392b", "BT W=5": "#e67e22", "BT W=2": "#2980b9"} | |
| ORDER = ["CSO", "BT W=5", "BT W=2"] | |
| def load_methods(): | |
| out = {} | |
| for name, fname in [ | |
| ("CSO", "L20_CSO.json"), | |
| ("BT W=5", "L20_BT_W5.json"), | |
| ("BT W=2", "L20_BT_W2.json"), | |
| ]: | |
| out[name] = json.load(open(IN / fname)) | |
| return out | |
| def plot_all_methods(methods): | |
| fig, axes = plt.subplots(2, 2, figsize=(12.5, 8.5)) | |
| fig.suptitle( | |
| "L20 interventions: CSO vs BT W=5 vs BT W=2 (128 graphs)", | |
| fontsize=13, | |
| fontweight="bold", | |
| ) | |
| # A: pinlast-k | |
| ax = axes[0, 0] | |
| for name in ORDER: | |
| pk = methods[name]["pinlastk"] | |
| ks = [0] + list(pk["ks"]) | |
| ys = [pk["clean"]] + list(pk["rand_mean"]) | |
| ax.plot(ks, ys, "o-", color=COLORS[name], label=name, lw=2, ms=5) | |
| ax.set_xlabel("k earlier latents corrupted (last pinned)") | |
| ax.set_ylabel("leaf accuracy") | |
| ax.set_ylim(0, 1.05) | |
| ax.set_title("A. Pin-last: corrupt k earlier thoughts") | |
| ax.grid(True, alpha=0.3) | |
| ax.legend(frameon=False) | |
| # B: aggregate bars | |
| ax = axes[0, 1] | |
| keys = [ | |
| ("clean", "clean"), | |
| ("earlier L1..L19 -> noise (last pinned)", "earlier→noise\n(last pin)"), | |
| ("earlier L1..L19 -> other-graph (last pinned)", "earlier→donor\n(last pin)"), | |
| ("LAST thought L20 -> other-graph", "last→donor"), | |
| ("PROPAGATED: corrupt L10, recompute rest", "prop L10"), | |
| ("PROPAGATED: corrupt L19, recompute rest", "prop L19"), | |
| ] | |
| x = np.arange(len(keys)) | |
| width = 0.25 | |
| for i, name in enumerate(ORDER): | |
| rows = {r["label"]: r["acc"] for r in methods[name]["aggregate"]["rows"]} | |
| ys = [rows[k] for k, _ in keys] | |
| ax.bar(x + (i - 1) * width, ys, width, color=COLORS[name], label=name) | |
| ax.set_xticks(x) | |
| ax.set_xticklabels([lab for _, lab in keys], fontsize=8) | |
| ax.set_ylabel("leaf accuracy") | |
| ax.set_ylim(0, 1.05) | |
| ax.set_title("B. Aggregate interventions") | |
| ax.legend(frameon=False, fontsize=8) | |
| ax.grid(True, axis="y", alpha=0.3) | |
| # C: per-slot pin-last | |
| ax = axes[1, 0] | |
| for name in ORDER: | |
| ys = methods[name]["perslot"]["pin_accs"] | |
| xs = np.arange(1, len(ys) + 1) | |
| ax.plot(xs, ys, "o-", color=COLORS[name], label=name, lw=2, ms=4) | |
| ax.axvline(20, color="gray", ls="--", alpha=0.5) | |
| ax.set_xlabel("corrupted latent slot (last pinned unless slot=20)") | |
| ax.set_ylabel("leaf accuracy") | |
| ax.set_ylim(0, 1.05) | |
| ax.set_title("C. Per-slot pin-last") | |
| ax.grid(True, alpha=0.3) | |
| ax.legend(frameon=False) | |
| # D: per-slot propagate | |
| ax = axes[1, 1] | |
| for name in ORDER: | |
| ys = methods[name]["perslot"]["prop_accs"] | |
| xs = np.arange(1, len(ys) + 1) | |
| ax.plot(xs, ys, "o-", color=COLORS[name], label=name, lw=2, ms=4) | |
| ax.set_xlabel("corrupted latent slot (then recompute rest)") | |
| ax.set_ylabel("leaf accuracy") | |
| ax.set_ylim(0, 1.05) | |
| ax.set_title("D. Per-slot propagate") | |
| ax.grid(True, alpha=0.3) | |
| ax.legend(frameon=False) | |
| fig.tight_layout(rect=[0, 0, 1, 0.96]) | |
| path = OUT / "L20_all_methods.png" | |
| fig.savefig(path, dpi=160) | |
| plt.close(fig) | |
| print(f"saved {path}") | |
| def plot_pinlast_k(methods): | |
| fig, ax = plt.subplots(figsize=(7.2, 4.2)) | |
| for name in ORDER: | |
| pk = methods[name]["pinlastk"] | |
| ks = [0] + list(pk["ks"]) | |
| ys = [pk["clean"]] + list(pk["rand_mean"]) | |
| ax.plot(ks, ys, "o-", color=COLORS[name], label=name, lw=2.2, ms=6) | |
| ax.set_title("L20: pin-last intervention") | |
| ax.set_xlabel("k earlier latents corrupted (last pinned)") | |
| ax.set_ylabel("leaf accuracy") | |
| ax.set_ylim(0, 1.05) | |
| ax.grid(True, alpha=0.3) | |
| ax.legend(frameon=False) | |
| fig.tight_layout() | |
| path = OUT / "pinlast_k_L20.png" | |
| fig.savefig(path, dpi=160) | |
| plt.close(fig) | |
| print(f"saved {path}") | |
| def plot_pinlast_table(methods): | |
| ks = methods["BT W=2"]["pinlastk"]["ks"] | |
| rows = ["clean"] + [str(k) for k in ks] + ["all 19"] | |
| col_labels = ["k"] + ORDER | |
| cell = [] | |
| for name in ORDER: | |
| pk = methods[name]["pinlastk"] | |
| vals = [pk["clean"]] + list(pk["rand_mean"]) + [pk["all"]] | |
| cell.append([f"{v:.3f}" for v in vals]) | |
| data = [[rows[i]] + [cell[j][i] for j in range(3)] for i in range(len(rows))] | |
| fig, ax = plt.subplots(figsize=(7.5, 4.8)) | |
| ax.axis("off") | |
| ax.set_title( | |
| "L20 pin-last: k earlier thoughts corrupted (last pinned)", | |
| fontsize=11, | |
| pad=12, | |
| ) | |
| table = ax.table( | |
| cellText=data, | |
| colLabels=col_labels, | |
| loc="center", | |
| cellLoc="center", | |
| ) | |
| table.auto_set_font_size(False) | |
| table.set_fontsize(9) | |
| table.scale(1.15, 1.35) | |
| for (r, c), cell_obj in table.get_celld().items(): | |
| if r == 0: | |
| cell_obj.set_facecolor("#ecf0f1") | |
| cell_obj.set_text_props(fontweight="bold") | |
| if c == 0: | |
| cell_obj.set_text_props(fontweight="bold") | |
| ckpts = ", ".join( | |
| f"{n}={Path(methods[n]['ckpt']).name.split('_')[-1]}" for n in ORDER | |
| ) | |
| fig.text(0.5, 0.02, f"ckpts: {ckpts}", ha="center", fontsize=8, color="#555") | |
| fig.tight_layout(rect=[0, 0.05, 1, 1]) | |
| path = OUT / "pinlast_k_L20_table.png" | |
| fig.savefig(path, dpi=160) | |
| plt.close(fig) | |
| print(f"saved {path}") | |
| def main(): | |
| methods = load_methods() | |
| plot_all_methods(methods) | |
| plot_pinlast_k(methods) | |
| plot_pinlast_table(methods) | |
| if __name__ == "__main__": | |
| main() | |