| from __future__ import annotations |
|
|
| from pathlib import Path |
|
|
| import gradio as gr |
| import numpy as np |
| import plotly.graph_objects as go |
|
|
| ARTIFACT_DIR = Path(__file__).resolve().parent / "artifacts" / "curiosity-cabinet" |
| TRAJECTORIES = { |
| reward: np.load(ARTIFACT_DIR / f"{reward}_trajectory.npz") |
| for reward in ["prediction_error", "learning_progress"] |
| } |
| ROOMS = ["simple", "learnable", "noisy TV"] |
|
|
|
|
| def rolling_fraction(actions: np.ndarray, room: int, window: int = 100) -> np.ndarray: |
| indicator = (actions == room).astype(np.float32) |
| kernel = np.ones(window, dtype=np.float32) / window |
| return np.convolve(indicator, kernel, mode="valid") |
|
|
|
|
| def compare_curiosity(window: int) -> tuple[go.Figure, dict]: |
| window = int(window) |
| figure = go.Figure() |
| for reward, trajectory in TRAJECTORIES.items(): |
| actions = trajectory["actions"] |
| for room, room_name in enumerate(ROOMS): |
| values = rolling_fraction(actions, room, window) |
| figure.add_trace( |
| go.Scatter( |
| x=np.arange(len(values)) + window, |
| y=values, |
| mode="lines", |
| name=f"{reward}: {room_name}", |
| ) |
| ) |
| figure.update_layout( |
| title="Where curiosity spends experience", |
| xaxis_title="Agent step", |
| yaxis_title="Rolling action fraction", |
| template="plotly_dark", |
| ) |
| return figure, { |
| reward: { |
| room_name: round(float(np.mean(data["actions"] == room)), 4) |
| for room, room_name in enumerate(ROOMS) |
| } |
| for reward, data in TRAJECTORIES.items() |
| } |
|
|
|
|
| with gr.Blocks(title="Curiosity Cabinet") as demo: |
| gr.Markdown( |
| "# Curiosity Cabinet\n" |
| "Compare surprise-seeking with learning-progress curiosity in a world " |
| "containing both learnable structure and irreducible noise." |
| ) |
| window = gr.Slider(25, 250, 100, step=25, label="Rolling window") |
| run = gr.Button("Replay curious agents", variant="primary") |
| chart = gr.Plot() |
| totals = gr.JSON() |
| run.click(compare_curiosity, window, [chart, totals]) |
| demo.load(compare_curiosity, window, [chart, totals]) |
|
|
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|