如何展示Detectron2模型的验证损失与验证精度并在metrics文件中添加validation_loss列
问题背景
我已将数据集按0.85的比例划分为训练集与测试集,以下是我的损失可视化代码:
import pandas as pd metrics_df = pd.read_json("./output/metrics.json", orient="records", lines=True) mdf = metrics_df.sort_values("iteration") mdf.head(10).T fig, ax = plt.subplots() mdf1 = mdf[~mdf["total_loss"].isna()] ax.plot(mdf1["iteration"], mdf1["total_loss"], c="C0", label="train") if "validation_loss" in mdf.columns: mdf2 = mdf[~mdf["validation_loss"].isna()] ax.plot(mdf2["iteration"], mdf2["validation_loss"], c="C1", label="validation") # ax.set_ylim([0, 0.5]) ax.legend() ax.set_title("Loss curve") plt.show()
请问如何在我的metrics文件中添加validation_loss列,同时如何展示Detectron2模型的验证损失与验证精度指标?
解决方案
一、让Detectron2自动在metrics.json中写入validation_loss及验证精度指标
Detectron2默认不会自动记录验证集指标,需要通过修改训练配置和启用评估钩子来实现:
修改训练配置,开启定期验证
在你的训练脚本中,给Detectron2的配置对象设置两个关键参数:from detectron2.config import get_cfg cfg = get_cfg() # ... 其他配置(加载预训练模型、设置数据集、训练参数等) ... # 1. 指定验证集名称(需确保已注册该验证数据集) cfg.DATASETS.TEST = ("your_validation_dataset",) # 2. 设置每N次迭代评估一次验证集,示例为每500次迭代评估一次 cfg.TEST.EVAL_PERIOD = 500这里的
your_validation_dataset是你注册的验证集名称,和训练集注册方式一致(比如用register_coco_instances或自定义数据集注册函数)。确保训练时启用评估钩子
如果你使用Detectron2的DefaultTrainer,只要cfg.TEST.EVAL_PERIOD > 0,Trainer会自动添加EvalHook,在指定迭代次数后评估验证集,并将所有验证指标(包括validation_loss、bbox/AP等精度指标)写入./output/metrics.json文件。若自定义了Trainer类,记得继承
DefaultTrainer,或者手动添加EvalHook:from detectron2.engine import DefaultTrainer from detectron2.engine.hooks import EvalHook from detectron2.evaluation import DatasetEvaluators class CustomTrainer(DefaultTrainer): def build_hooks(self): hooks = super().build_hooks() # 添加EvalHook定期评估验证集 hooks.append(EvalHook( self.cfg.TEST.EVAL_PERIOD, self.model, DatasetEvaluators(self.cfg, "your_validation_dataset") )) return hooks重新运行训练脚本后,metrics.json里就会自动出现
validation_loss和对应任务的精度指标(比如检测任务的bbox/AP)。
二、修改可视化代码,同时展示验证损失与精度指标
基于你现有的代码,我们可以扩展出同时展示损失曲线和验证精度的可视化逻辑:
import pandas as pd import matplotlib.pyplot as plt # 读取metrics文件 metrics_df = pd.read_json("./output/metrics.json", orient="records", lines=True) mdf = metrics_df.sort_values("iteration") # 创建1行2列的子图,分别展示损失和精度 fig, (ax_loss, ax_acc) = plt.subplots(1, 2, figsize=(14, 6)) # ---------------------- 绘制损失曲线 ---------------------- # 训练损失 train_loss_data = mdf[~mdf["total_loss"].isna()] ax_loss.plot(train_loss_data["iteration"], train_loss_data["total_loss"], c="C0", label="Train Loss") # 验证损失(如果存在) if "validation_loss" in mdf.columns: val_loss_data = mdf[~mdf["validation_loss"].isna()] ax_loss.plot(val_loss_data["iteration"], val_loss_data["validation_loss"], c="C1", label="Validation Loss") ax_loss.set_title("Loss Curve") ax_loss.set_xlabel("Iteration") ax_loss.set_ylabel("Loss") ax_loss.legend() # 可选:根据你的损失范围调整y轴 # ax_loss.set_ylim([0, 0.5]) # ---------------------- 绘制验证精度曲线 ---------------------- # 不同任务的精度指标键不同,示例为实例检测任务的bbox AP: # - 实例分割:segm/AP、segm/AP50 # - 分类任务:accuracy # - 关键点检测:keypoints/AP if "bbox/AP" in mdf.columns: val_acc_data = mdf[~mdf["bbox/AP"].isna()] ax_acc.plot(val_acc_data["iteration"], val_acc_data["bbox/AP"], c="C2", label="Validation BBox AP") ax_acc.set_title("Validation Accuracy (BBox AP)") ax_acc.set_xlabel("Iteration") ax_acc.set_ylabel("AP (%)") ax_acc.legend() # AP的范围通常是0-100,固定y轴范围更直观 ax_acc.set_ylim([0, 100]) # 调整子图间距,避免重叠 plt.tight_layout() plt.show()
运行这段代码后,你就能同时看到训练/验证损失的变化趋势,以及验证精度的提升情况了。
内容的提问来源于stack exchange,提问作者MohamedHakim BEDHIEF

