Buckets:

glennmatlin's picture
download
raw
7.36 kB
#!/usr/bin/env python3
"""Experiment 3: Null-Bin Control — Figures 8-10."""
from __future__ import annotations
import argparse
from pathlib import Path
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
import pandas as pd
from scripts.visualization._shared import (
ACCURACY_METRICS, BASELINE, BENCH_COLORS, EXP_COLORS,
METRIC_LABELS, gamma, paper_rc, save_fig,
)
NULL_BIN = ("Null-Bin Control", "null", 2800, 0.41395, 0.744879, 0.591468, 0.7977, 14.77, 20.2)
COLS = [
"run", "target", "checkpoint", "gsm8k", "mmlu_socsci",
"mmlu_stem", "socialiqa", "wikitext_ppl", "forget_ppl",
]
def _load_exp_gammas():
from scripts.visualization.experiment1_single_bin import build_dataframe as build_df1
from scripts.visualization.experiment2_multi_bin import build_dataframe as build_df2
return build_df1(), build_df2()
def fig8_control(output_dir: Path) -> None:
df1, df2 = _load_exp_gammas()
null_gammas = {m: gamma(NULL_BIN[3 + i], m) for i, m in enumerate(ACCURACY_METRICS)}
fig, axes = plt.subplots(1, 4, figsize=(7, 3.5))
for idx, m in enumerate(ACCURACY_METRICS):
ax = axes[idx]
col = f"{m}_gamma"
exp1_v = df1[col].values
exp2_v = df2[col].values
null_v = null_gammas[m]
bp = ax.boxplot(
[exp1_v, exp2_v], positions=[0, 1], widths=0.4, patch_artist=True,
showmeans=True,
meanprops=dict(marker="D", markerfacecolor="white", markersize=3),
)
bp["boxes"][0].set_facecolor(EXP_COLORS["exp1"])
bp["boxes"][1].set_facecolor(EXP_COLORS["exp2"])
rng = np.random.default_rng(42)
for i, d in enumerate([exp1_v, exp2_v]):
jitter = rng.uniform(-0.08, 0.08, len(d))
ax.scatter(
np.full(len(d), i) + jitter, d,
color="black", s=6, alpha=0.35, zorder=3,
)
ax.scatter(
2, null_v, color=EXP_COLORS["exp3"], marker="*", s=150,
edgecolors="black", linewidth=0.5, zorder=4,
)
ax.set_xticks([0, 1, 2])
ax.set_xticklabels(["Exp 1\n(24)", "Exp 2\n(12)", "Null\nCtrl"], fontsize=7)
ax.axhline(0, color="gray", linestyle="--", linewidth=0.4, alpha=0.5)
ax.set_title(METRIC_LABELS[m], fontweight="bold", fontsize=9)
ax.grid(True, axis="y", alpha=0.2, linewidth=0.3)
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1, decimals=0))
if idx == 0:
ax.set_ylabel(r"$\gamma$")
fig.tight_layout()
save_fig(fig, output_dir, "fig8_control_vs_targeted")
def fig9_anomaly(output_dir: Path) -> None:
null_scores = {m: NULL_BIN[3 + i] for i, m in enumerate(ACCURACY_METRICS)}
fig, (ax_l, ax_r) = plt.subplots(
1, 2, figsize=(7, 3.5), gridspec_kw={"width_ratios": [3, 2]},
)
x = np.arange(len(ACCURACY_METRICS))
width = 0.3
base_vals = [BASELINE[m] for m in ACCURACY_METRICS]
null_vals = [null_scores[m] for m in ACCURACY_METRICS]
ax_l.bar(x - width / 2, base_vals, width, color="#4393c3", label="Baseline")
ax_l.bar(x + width / 2, null_vals, width, color="#d6604d", label="Null-Bin")
ax_l.set_xticks(x)
ax_l.set_xticklabels([METRIC_LABELS[m] for m in ACCURACY_METRICS], fontsize=7)
ax_l.set_ylabel("Accuracy")
ax_l.set_ylim(0, 0.95)
ax_l.legend(fontsize=7, loc="upper left")
ax_l.grid(True, axis="y", alpha=0.2, linewidth=0.3)
for i, (b, n) in enumerate(zip(base_vals, null_vals)):
g = (n - b) / abs(b)
color = "#b2182b" if g < -0.05 else "#333"
ax_l.text(
i, max(b, n) + 0.02, f"{g:+.1%}",
ha="center", va="bottom", fontsize=7, fontweight="bold", color=color,
)
mc_m = ["mmlu_socsci", "mmlu_stem", "socialiqa"]
mc_g = np.mean([gamma(null_scores[m], m) for m in mc_m])
gsm_g = gamma(null_scores["gsm8k"], "gsm8k")
bars = ax_r.bar(
["MC benchmarks\n(mean)", "GSM8K\n(generative)"],
[mc_g, gsm_g], width=0.45,
color=["#4393c3", "#d6604d"], edgecolor="black", linewidth=0.4,
)
ax_r.axhline(0, color="black", linewidth=0.4)
ax_r.set_ylabel(r"$\gamma$")
ax_r.set_title("MC vs Generative", fontweight="bold", fontsize=9)
ax_r.grid(True, axis="y", alpha=0.2, linewidth=0.3)
ax_r.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1, decimals=0))
for bar, val in zip(bars, [mc_g, gsm_g]):
xc = bar.get_x() + bar.get_width() / 2
if abs(val) > 0.05:
ax_r.text(
xc, val / 2, f"$\\gamma$={val:+.1%}",
ha="center", va="center", fontsize=7.5, fontweight="bold", color="white",
)
else:
ax_r.text(
xc, val - 0.02, f"$\\gamma$={val:+.1%}",
ha="center", va="top", fontsize=7.5, fontweight="bold",
)
fig.tight_layout()
save_fig(fig, output_dir, "fig9_gsm8k_anomaly")
def fig10_efficiency(output_dir: Path) -> None:
from scripts.visualization.experiment1_single_bin import (
RESULTS as R1, COLS as C1,
)
from scripts.visualization.experiment2_multi_bin import (
RESULTS as R2, COLS as C2,
)
df1 = pd.DataFrame(R1, columns=C1)
for m in ACCURACY_METRICS:
df1[f"{m}_gamma"] = (df1[m] - BASELINE[m]) / abs(BASELINE[m])
df1["mean_acc_gamma"] = df1[[f"{m}_gamma" for m in ACCURACY_METRICS]].mean(axis=1)
df2 = pd.DataFrame(R2, columns=C2)
for m in ACCURACY_METRICS:
df2[f"{m}_gamma"] = (df2[m] - BASELINE[m]) / abs(BASELINE[m])
df2["mean_acc_gamma"] = df2[[f"{m}_gamma" for m in ACCURACY_METRICS]].mean(axis=1)
null_gamma = np.mean(
[gamma(NULL_BIN[3 + i], m) for i, m in enumerate(ACCURACY_METRICS)]
)
fig, ax = plt.subplots(figsize=(5, 4))
ax.scatter(
df1["checkpoint"], df1["mean_acc_gamma"],
color=EXP_COLORS["exp1"], edgecolors="black", linewidth=0.3,
s=25, label="Exp 1: Single-Bin", zorder=3, alpha=0.7,
)
ax.scatter(
df2["checkpoint"], df2["mean_acc_gamma"],
color=EXP_COLORS["exp2"], edgecolors="black", linewidth=0.3,
s=35, marker="s", label="Exp 2: Multi-Bin", zorder=3, alpha=0.8,
)
ax.scatter(
NULL_BIN[2], null_gamma,
color=EXP_COLORS["exp3"], marker="*", s=180,
edgecolors="black", linewidth=0.5, zorder=4, label="Exp 3: Null-Bin",
)
ax.axhline(0, color="gray", linestyle="--", linewidth=0.4, alpha=0.5)
ax.set_xlabel("Selected checkpoint (training steps)")
ax.set_ylabel(r"Mean accuracy $\gamma$")
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1, decimals=1))
ax.grid(True, alpha=0.2, linewidth=0.3)
ax.legend(fontsize=7, loc="lower right")
save_fig(fig, output_dir, "fig10_checkpoint_efficiency")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--output-dir", type=Path, default=Path("artifacts/experiment3_figures"))
args = parser.parse_args()
args.output_dir.mkdir(parents=True, exist_ok=True)
paper_rc()
print("Generating Experiment 3 figures...")
fig8_control(args.output_dir)
fig9_anomaly(args.output_dir)
fig10_efficiency(args.output_dir)
print(f"All figures saved to {args.output_dir}/")
if __name__ == "__main__":
main()

Xet Storage Details

Size:
7.36 kB
·
Xet hash:
946b52858ec51f97483b4b192cd3eb824d1bbafee921e1109e9712548ddf73cf

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.