ARotting's picture
Publish Prediction-error and learning-progress world models
18603bb verified
Raw
History Blame Contribute Delete
5.42 kB
from __future__ import annotations
import json
from pathlib import Path
import numpy as np
import pandas as pd
import trackio
from experiment import ROOMS, run_agent
from safetensors.torch import save_file
PROJECT_DIR = Path(__file__).resolve().parent
ARTIFACT_DIR = PROJECT_DIR / "artifacts" / "curiosity-cabinet"
DATA_DIR = PROJECT_DIR / "data"
def aggregate(records: list[dict], reward: str) -> dict:
subset = [record for record in records if record["reward"] == reward]
return {
"runs": len(subset),
"mean_middle_action_fraction": {
room: float(
np.mean(
[
record["middle_action_fraction"][room]
for record in subset
]
)
)
for room in ROOMS
},
"mean_final_action_fraction": {
room: float(
np.mean(
[record["final_action_fraction"][room] for record in subset]
)
)
for room in ROOMS
},
"learnable_world_model_mse": {
"mean": float(
np.mean(
[record["learnable_world_model_mse"] for record in subset]
)
),
"median": float(
np.median(
[record["learnable_world_model_mse"] for record in subset]
)
),
},
}
def main() -> None:
runs = 60
steps = 1_200
trackio.init(
project="curiosity-cabinet",
name="error-versus-learning-progress-v1",
config={
"runs_per_reward": runs,
"steps_per_run": steps,
"rooms": ROOMS,
"epsilon": 0.15,
},
)
records = []
representative = {}
for run in range(runs):
for reward in ["prediction_error", "learning_progress"]:
record = run_agent(reward, seed=9000 + run, steps=steps)
if run == 0:
representative[reward] = record
records.append(
{
key: value
for key, value in record.items()
if key not in {"actions", "losses", "learnable_state_dict"}
}
)
if (run + 1) % 10 == 0:
recent = records[-20:]
trackio.log(
{
"completed_runs": run + 1,
"error_noisy_tv_fraction": float(
np.mean(
[
item["middle_action_fraction"]["noisy_tv"]
for item in recent
if item["reward"] == "prediction_error"
]
)
),
"progress_noisy_tv_fraction": float(
np.mean(
[
item["middle_action_fraction"]["noisy_tv"]
for item in recent
if item["reward"] == "learning_progress"
]
)
),
}
)
summary = {
reward: aggregate(records, reward)
for reward in ["prediction_error", "learning_progress"]
}
report = {
"benchmark": "Curiosity Cabinet noisy-TV stress test",
"runs_per_reward": runs,
"steps_per_run": steps,
"summary": summary,
}
ARTIFACT_DIR.mkdir(parents=True, exist_ok=True)
DATA_DIR.mkdir(parents=True, exist_ok=True)
(ARTIFACT_DIR / "evaluation.json").write_text(
json.dumps(report, indent=2), encoding="utf-8"
)
for reward, record in representative.items():
save_file(
record["learnable_state_dict"],
ARTIFACT_DIR / f"{reward}_world_model.safetensors",
)
np.savez_compressed(
ARTIFACT_DIR / f"{reward}_trajectory.npz",
actions=np.asarray(record["actions"], dtype=np.int8),
losses=np.asarray(record["losses"], dtype=np.float32),
)
rows = []
for record in records:
row = {
"reward": record["reward"],
"seed": record["seed"],
"learnable_world_model_mse": record["learnable_world_model_mse"],
}
for window in ["middle_action_fraction", "final_action_fraction"]:
for room in ROOMS:
row[f"{window}_{room}"] = record[window][room]
rows.append(row)
pd.DataFrame(rows).to_parquet(DATA_DIR / "seeded_results.parquet", index=False)
trackio.log(
{
"error_noisy_tv_fraction": summary["prediction_error"][
"mean_middle_action_fraction"
]["noisy_tv"],
"progress_noisy_tv_fraction": summary["learning_progress"][
"mean_middle_action_fraction"
]["noisy_tv"],
"error_learnable_mse": summary["prediction_error"][
"learnable_world_model_mse"
]["mean"],
"progress_learnable_mse": summary["learning_progress"][
"learnable_world_model_mse"
]["mean"],
}
)
trackio.finish()
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()