Python 现代开发学习笔记

(二十九)选定模型后单独评估测试集

# 续写同一文件:training_project/src/readingtorch/engine.py
def evaluate(checkpoint, data):
    # 选定 best 后单独读取测试集,训练循环里没有查询测试指标。
    saved = load_checkpoint(checkpoint)
    task = saved["task"]
    bundle = load_bundle(task, data, saved["seed"])
    if saved["source_hash"] != bundle.source_hash:
        raise ValueError("评估数据与训练记录不一致")
    model = build_model(task)
    model.load_state_dict(saved["model"])
    loss_fn = nn.MSELoss() if task == "regression" else nn.CrossEntropyLoss()
    scale = bundle.preprocess["y_scale"].item() if task == "regression" else 1.0
    metrics = one_epoch(
        model, make_loader(bundle, "test"), loss_fn, torch.device("cpu"), task, scale
    )
    if task == "regression":
        # 标准化后的 0 对应训练目标均值,这就是不训练模型的基线。
        metrics["baseline_rmse"] = (
            bundle.y[bundle.splits["test"]].square().mean().sqrt().item() * scale
        )
    else:
        metrics["baseline_accuracy"] = 1 / 3
    return {
        "task": task,
        "checkpoint_epoch": saved["epoch"],
        "samples": len(bundle.splits["test"]),
        **metrics,
    }

评估读取选定检查点,建立同一结构并装回权重。数据摘要对应后,使用原来的划分种子与训练预处理,读取测试编号,调用不带优化器的 one_epoch。

回归还比较一份简单基线:始终预测训练目标均值。标准化后这个预测就是零,因此可以直接用测试目标与零的差计算基线 RMSE。三类图形数量相同,固定猜一个类别的准确率为三分之一。

先比较基线,能看清模型实际改善了多少;再检查错误样本,判断剩余误差发生在什么输入上。测试指标没有参与训练循环和最佳轮数选择。

训练和验证确定 best 后才进入测试分组,回归恢复页数尺度并比较训练均值基线,图形逐项比较预测类别与真实编号

笔记正文与全部题解 · Ctrl / ⌘ K