实验记录格式(Experiment Logging Format)
一句话定位
标准化实验日志的记录格式和命名规范,支持wandb/tensorboard等工具,实现实验可追溯性和团队协作。
前置依赖
核心思想
为什么需要标准化日志
问题场景:
- 跑了100个实验,不知道哪些有效
- 需要复现上周的结果但忘了配置
- 团队成员无法理解你的实验记录
标准化日志的价值:
- 快速定位好的实验配置
- 自动化生成实验报告
- 团队知识共享
日志层次结构
实验记录
├── 实验元信息(谁、何时、为什么)
├── 配置文件(完整超参数)
├── 训练日志(loss曲线、metrics)
├── 评估结果(最终性能)
└── 分析总结(教训learned)
实验命名规范
命名格式
推荐格式:
[任务]_[模型]_[关键修改]_[日期]_[备注]
示例:
dmc_walker_walk_dreamerv3_kl10_20240522_v1
dmc_quadruped_run_transfoxr_longseq_20240523
atari_breakout_transformer_wm_20240524_baseline
禁止:
test_experiment_1(无意义)run1(太短)new_model_final_v2_actual(混乱)
Tags和Groups
使用wandb tags组织实验:
wandb.init(
project="world-model-ablation",
name="kl_weight_ablation_0.1",
tags=["ablation", "kl_weight", "dreamerv3"],
group="kl_weight_study"
)核心Metrics记录
训练Metrics
必须记录的Metrics:
# 训练日志 - 每个train step记录
train_metrics = {
# 损失
"train/loss_total": loss_total,
"train/loss_obs": loss_obs,
"train/loss_reward": loss_reward,
"train/loss_kl": loss_kl,
# KL统计
"train/kl_mean": kl_mean,
"train/kl_std": kl_std,
"train/kl_per_dim": kl_mean / z_dim,
# 梯度
"train/grad_norm": grad_norm,
# 学习率
"train/lr": current_lr,
}评估Metrics
# 评估日志 - 每个eval interval记录
eval_metrics = {
# Return统计
"eval/return_mean": np.mean(returns),
"eval/return_std": np.std(returns),
"eval/return_min": np.min(returns),
"eval/return_max": np.max(returns),
# 长度统计
"eval/ep_length_mean": np.mean(lengths),
# 特殊指标
"eval/success_rate": success_count / total_episodes,
}详细日志配置
# wandb_config.yaml
logging:
project: world-model-experiments
entity: your-team
# 记录频率
train_log_interval: 10 # 每10步
eval_log_interval: 1000 # 每1000步
save_checkpoint_interval: 10000 # 每10000步
# 上传
log_gradients: true
log_parameters: false # 太大,不建议开启
log_predictions: false # 可开启用于debug
# watched metrics
watch_log_frequency: 100 # wandb.watch 记录频率Tensorboard配置
目录结构
logs/
├── tensorboard/
│ ├── exp001_dmc_walker/
│ │ ├── train
│ │ └── eval
│ └── exp002_atari_breakout/
│ ├── train
│ └── eval
└── checkpoints/
├── exp001_dmc_walker/
│ ├── step_10000.pt
│ └── best.pt
└── exp002_atari_breakout/
代码配置
from torch.utils.tensorboard import SummaryWriter
# 创建writer
writer = SummaryWriter(log_dir=f"logs/tensorboard/{exp_name}")
# 记录scalar
writer.add_scalar("train/loss_total", loss, global_step)
# 记录多个同一类型的scalar
writer.add_scalars("losses", {
"obs": loss_obs,
"reward": loss_reward,
"kl": loss_kl
}, global_step)
# 记录直方图
writer.add_histogram("weights/dynamics_layer1", weights, global_step)
# 记录图像
writer.add_image("reconstruction", recon_grid, global_step)
# 关闭
writer.close()实验配置记录
YAML配置模板
# config.yaml - 必须保存的完整配置
experiment:
name: dmc_walker_walk_dreamerv3_kl10_20240522
description: "KL weight ablation: kl=0.1 baseline"
created_by: your_name
created_at: 2024-05-22
# 实验类型标签
tags:
- baseline
- dreamerv3
- kl_weight_study
group: world_model_ablation
# 相关实验
related_experiments:
- dmc_walker_walk_dreamerv3_kl01_20240520 # 上一组kl=0.01
- dmc_walker_walk_dreamerv3_kl05_20240521 # 上一组kl=0.05
model:
stochastic_channels: 32
deterministic_hidden: 512
action_channels: 256
encoder:
type: rgb
resolution: [84, 84]
training:
total_steps: 1000000
batch_size: 64
sequence_length: 32
optimizer:
type: AdamW
lr: 1e-4
kl_weight: 0.1
kl_free_nats: 0.0
environment:
name: DM Control Suite/walker_walk
num_train_envs: 16
num_eval_envs: 10自动化配置保存
def save_experiment_config(config, save_dir):
"""保存实验配置到指定目录"""
config_path = Path(save_dir) / "config.yaml"
# 添加元信息
config["experiment"]["saved_at"] = datetime.now().isoformat()
config["experiment"]["git_commit"] = get_git_commit_hash()
with open(config_path, "w") as f:
yaml.dump(config, f, default_flow_style=False)
# 同步保存到wandb
wandb.config.update(config)Checkpoint管理
保存策略
# checkpoint_manager.py
class CheckpointManager:
def __init__(self, save_dir, keep_last_n=5):
self.save_dir = Path(save_dir)
self.keep_last_n = keep_last_n
self.checkpoints = []
def save(self, model, optimizer, step, metrics):
"""保存checkpoint"""
ckpt_path = self.save_dir / f"step_{step}.pt"
torch.save({
"step": step,
"model_state": model.state_dict(),
"optimizer_state": optimizer.state_dict(),
"metrics": metrics,
}, ckpt_path)
self.checkpoints.append(ckpt_path)
# 只保留最近的N个
if len(self.checkpoints) > self.keep_last_n:
old_ckpt = self.checkpoints.pop(0)
old_ckpt.unlink()
def load_best(self):
"""加载最佳checkpoint"""
best_path = self.save_dir / "best.pt"
if best_path.exists():
return torch.load(best_path)
return None最佳模型选择
# 基于eval return选择最佳
best_return = -float("inf")
if eval_return_mean > best_return:
best_return = eval_return_mean
save_checkpoint(model, optimizer, step, "best.pt")
logger.info(f"New best model: return={eval_return_mean:.2f}")实验对比分析
wandb实验对比
import wandb
import pandas as pd
# 查询实验
api = wandb.Api()
runs = api.runs("your-team/world-model-ablation",
filters={"tags": {"$in": ["ablation"]}})
# 转为DataFrame
data = []
for run in runs:
data.append({
"name": run.name,
"state": run.state,
"kl_weight": run.config.get("kl_weight"),
"eval_return": run.summary.get("eval/return_mean"),
"created_at": run.created_at,
})
df = pd.DataFrame(data)
print(df.sort_values("eval_return", ascending=False))生成对比报告
# 实验对比报告: KL Weight Ablation
## 实验配置
| 实验名 | KL Weight | 学习率 | 潜在维度 |
|--------|-----------|--------|----------|
| kl01_baseline | 0.1 | 1e-4 | 32 |
| kl05_lower | 0.05 | 1e-4 | 32 |
| kl20_higher | 0.2 | 1e-4 | 32 |
## 结果
| 实验名 | Eval Return | KL/dim | 训练步数 |
|--------|-------------|--------|----------|
| kl01_baseline | 95.2 ± 3.1 | 0.08 | 1M |
| kl05_lower | 87.3 ± 4.2 | 0.04 | 1M |
| kl20_higher | 91.8 ± 2.8 | 0.15 | 1M |
## 结论
KL weight = 0.1 在walker_walk任务上表现最佳。章节摘要
本章提供了实验记录格式的完整指南:
- 命名规范:标准化实验名称便于搜索和识别
- Metrics记录:训练和评估核心指标的日志格式
- Tensorboard配置:本地日志记录方法
- 配置保存:YAML配置模板和自动化保存
- Checkpoint管理:保存策略和最佳模型选择
- 对比分析:wandb查询和报告生成
良好的实验记录习惯是科研效率的关键,建议从第一个实验开始规范记录。
关键词
实验日志 wandb tensorboard 实验命名 checkpoint metrics 实验管理 实验对比 超参数记录 日志格式