anomalib 模型训练完全指南:从 Engine API 到 Folder 自定义数据集与 CLI 实战
【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib
导读
本文基于开源异常检测库 anomalib 的anomalib-training技能文档,系统讲解如何在 anomalib 中完成一次完整的模型训练:从 Python API 使用anomalib.engine.Engine封装 LightningTrainer训练标准基准数据集(如 MVTecAD),到用Folderdatamodule 零代码训练自定义目录数据集,再到通过anomalibCLI 一条命令完成训练与配置覆盖。读完本文,你将掌握 Engine 的核心方法调用链、Folder 目录结构的组织规范、Trainer 参数的传入方式(含 XPU 加速),以及调试训练时的结果目录定位技巧。
训练总入口:一切训练都经由Engine
在 anomalib 中,无论是 Python API 还是 CLI,所有训练流程都统一经过anomalib.engine.Engine—— 它是 PyTorch LightningTrainer的一层封装,负责在标准训练/测试流程之上叠加异常检测特有的逻辑:指标计算与日志、checkpoint 保存、模型导出、分布式训练支持等。从 engine.py 的类定义可以看到,Engine的核心构造参数是callbacks、logger、default_root_dir,以及通过**kwargs透传的全部 LightningTrainer参数。
这种设计意味着没有独立的 "Trainer 配置对象" 需要构造——你需要的一切训练行为(accelerator、devices、strategy、max_epochs、logger、callbacks、enable_checkpointing、val_check_interval、barebones等)都是Engine(**kwargs)的普通关键字参数,会被直接缓存并最终用于实例化底层Trainer(见 engine.py 的_setup_trainer)。
Python API 训练标准基准数据集(MVTecAD)
使用标准基准数据集训练是验证 anomalib 流程的最快方式。以 MVTecAD 为例,完整流程如下:
from anomalib.data import MVTecAD from anomalib.models import Patchcore from anomalib.engine import Engine datamodule = MVTecAD(root="./datasets/MVTecAD", category="bottle", train_batch_size=32) model = Patchcore() engine = Engine() # 任何 Lightning Trainer kwarg 都可以放在这里 engine.fit(model=model, datamodule=datamodule) results = engine.test(model=model, datamodule=datamodule)MVTecAD指定数据集根目录与子类(category),train_batch_size控制训练批次大小;Patchcore()直接实例化模型,无需额外配置;engine.fit(...)完成训练,engine.test(...)在测试集上评估并返回结果字典列表(每个 dataloader 一个 dict)。
Engine 的核心方法
Engine围绕训练生命周期提供以下关键方法(签名详见 engine.py):
| 方法 | 作用 | 关键参数 |
|---|---|---|
fit(model, datamodule=...) | 训练(拟合)模型 | train_dataloaders/val_dataloaders/datamodule/ckpt_path |
train(...) | 一次调用完成 fit + test | 与 fit 相同的参数,另加test_dataloaders |
test(model=None, datamodule=...) | 在测试集上评估 | dataloaders/ckpt_path/verbose |
predict(model=None, datamodule=..., dataset=..., data_path=...) | 推理预测 | 支持传dataset或data_path(图片路径/文件夹) |
一个重要约定:如果在test/predict中省略model/datamodule,Engine 会自动复用之前传给fit的那一份。例如先engine.fit(model=model, datamodule=datamodule)再直接engine.test()即可。predict的data_path参数还支持直接指向单张图片或一个文件夹(见 engine.py),内部会将其包装为PredictDataset再构建 DataLoader。
Python API 训练自定义数据:Folder datamodule
当你的数据以普通文件夹形式组织(无需编写任何数据集代码)时,使用Folderdatamodule 即可。其目录布局约定为root/normal_dir/*(正常样本)、root/abnormal_dir/*(异常样本,可选),以及root/mask_dir/*(逐像素分割掩码,可选)。该结构在 folder.py 的 docstring 中有明确说明:
root/ ├── normal_dir/ │ ├── image1.png │ └── image2.png ├── abnormal_dir/ │ ├── image3.png │ └── image4.png └── mask_dir/ ├── mask3.png └── mask4.png对应的训练代码:
from anomalib.data import Folder from anomalib.models import Padim from anomalib.engine import Engine datamodule = Folder( name="custom", # 必填 —— 用作 datamodule 的显示名称 root="./datasets/custom", normal_dir="good", # 必填 abnormal_dir="defect", # 可选:启用异常测试/评估样本 mask_dir="mask", # 可选:启用像素级(分割)评估 train_batch_size=32, eval_batch_size=32, num_workers=8, ) model = Padim() engine = Engine() engine.fit(model=model, datamodule=datamodule)Folder 的目录组织规则与参数细节
从 Folder 构造函数 可以梳理出完整的参数语义:
normal_dir(必填):正常训练图像所在目录;abnormal_dir(可选):异常图像目录,提供后测试/评估集才包含异常样本,使图像级(分类)指标有意义;normal_test_dir(可选):专门用于测试集的独立正常图像目录;mask_dir(可选):与异常图像一一对应的掩码目录,提供后评估从图像级(分类)切换为像素级(分割)指标;normal_split_ratio(默认 0.2):在没有独立正常测试图像时,从正常训练图像中切出测试集的比例;test_split_mode(默认TestSplitMode.FROM_DIR)/test_split_ratio(默认 0.2):测试集划分方式与比例;val_split_mode(默认ValSplitMode.FROM_TEST)/val_split_ratio(默认 0.5):验证集划分方式与比例;extensions:纳入的图像扩展名过滤;train_batch_size(默认 32)、eval_batch_size(默认 32)、num_workers(默认 8)控制数据加载;seed:划分数据集时使用的随机种子。
如果只有正常训练图像、且测试集也是正常或无标注图像:直接省略abnormal_dir和mask_dir。此时Folder会通过test_split_ratio从正常训练图像中按比例切出一部分作为测试集,仍然能产生合法的 train/test 划分。若你有专门用于测试的正常图像目录,则用normal_test_dir指定。
Folder在内部通过FolderDataset构建 train/test 数据(见 folder.py),其训练集和测试集 batch 都会包含image、label、mask、image_path、mask_path字段,便于后续可视化和调试。
CLI 命令行训练
除了 Python API,anomalib 提供了基于 jsonargparse 的完整 CLI(入口为anomalib命令,实现位于 cli.py 的AnomalibCLI类)。常用训练命令如下:
# 标准数据集,默认参数 anomalib train --model Patchcore --data anomalib.data.MVTecAD # 覆盖 datamodule 字段 anomalib train --model Patchcore --data anomalib.data.MVTecAD --data.category transistor # 覆盖 trainer 字段(max_epochs 对梯度训练模型如 Stfpm 才有意义) anomalib train --model anomalib.models.Stfpm --data anomalib.data.MVTecAD --trainer.max_epochs 3 # 从 CLI 训练自定义 Folder 数据集 anomalib train --model Padim --data anomalib.data.Folder \ --data.name custom --data.root ./datasets/custom \ --data.normal_dir good --data.abnormal_dir defect # 从配置文件启动(jsonargparse;可与上面任意覆盖项组合) anomalib train --config path/to/config.yamlCLI 的接线原理
--model/--data之所以既能接受短名(Padim)又能接受完整类路径(anomalib.models.Padim、anomalib.data.Folder),是因为AnomalibCLI通过parser.add_subclass_arguments将AnomalibModule和AnomalibDataModule暴露为 jsonargparse 的 subclass 参数(见 cli.py)。
CLI 还支持以下子命令(见 cli.py):
train:拟合模型后紧接着调用 test;predict:对模型进行推理(--data可传数据集类路径或直接传图片/文件夹路径);export:将模型导出为 ONNX 或 OpenVINO 格式;fit/validate/test:对应 Lightning Trainer 的原始子命令;install:安装 anomalib 的完整或可选依赖。
命令行里通过--trainer.max_epochs 3这样的点号路径直接覆盖 Trainer 参数,通过--data.category transistor覆盖 datamodule 字段,所有覆盖项都可以与--config配置文件组合使用。
选择 accelerator / devices(含 Intel XPU)
加速器与设备选择同样是标准的 Lightning 关键字参数,直接传给Engine(...)即可:
accelerator="gpu"|"cpu"|"xpu":选择计算后端;devices=1:使用的设备数量。
针对 Intel XPU 这一特殊后端,anomalib 在anomalib.engine命名空间中专门导出了SingleXPUStrategy与XPUAccelerator(见 engine/init.py),组合方式如下:
from anomalib.engine import Engine, SingleXPUStrategy, XPUAccelerator engine = Engine(strategy=SingleXPUStrategy(), accelerator=XPUAccelerator())对应的底层实现位于 accelerator/xpu.py 与 strategy/xpu_single.py。在 CLI 中同样可以通过--trainer.accelerator xpu --trainer.strategy ...风格的参数完成配置。
训练中的常见坑(Gotchas)
1. 非梯度模型也会走engine.fit(...)
并非所有模型都通过梯度下降训练——像Padim、Patchcore这类免训练(training-free)模型同样需要调用engine.fit(...),此时Engine/Trainer只会执行构建记忆库所需的单次 "epoch",不需要任何特殊代码。
但需要注意:这些模型通过各自的trainer_arguments属性覆盖默认训练参数。例如 Padim 的 trainer_arguments 返回{"max_epochs": 1, "val_check_interval": 1.0, "num_sanity_val_steps": 0, "devices": 1}。Engine 内部通过_TrainerArgumentsCache在实例化 Trainer 前用模型参数覆盖用户传入值,并打印类似Overriding max_epochs from 100 with 1 for Padim的日志(见 engine.py)。因此对这类模型,你传给Engine的max_epochs会被模型自身的trainer_arguments覆盖——想控制训练轮数,请选择 Stfpm、Cflow 等真正梯度训练的模型。
2.mask_dir决定评估粒度
Folder的mask_dir是图像级(分类)指标与像素级(分割)指标之间的开关:只有传入mask_dir才会启用像素级 ground-truth 评估。仅当你确实拥有逐像素掩码标注时才传入该参数,否则应省略。
3. 结果输出到哪里:default_root_dir
训练的产出物(checkpoint、日志、可视化图像)统一写入Engine的default_root_dir(默认值为"results",即当前目录下的results文件夹)。Engine 的_setup_workspace会按模型名 / 数据集名 / category的层级嵌套子目录(见 engine.py),并额外生成版本化目录。调试训练运行异常时,应优先到这个目录下排查:
results/ └── Padim/ └── custom/ └── (category)/ ├── weights/lightning/ # 模型 checkpoint ├── images/ # 可视化输出 └── ... # 日志等在 CLI 中可通过--default_root_dir覆盖该路径(见 cli.py)。
源码级自检清单(Reviewer / self-check)
结合 anomalib-training 技能文档 的检查项,在编写或调试训练脚本时可逐条核对:
Engine(...)接收的是 Trainer 覆盖参数(普通 kwargs),而不是手工构造的Trainer对象;- Folder 数据集训练时,
normal_dir以及(如适用)abnormal_dir/mask_dir与实际磁盘目录布局一致; - CLI 调用使用的
anomalib.data.<Class>/anomalib.models.<Class>路径确实在anomalib命名空间中导出(模型与 datamodule 的导出机制分别见.agents/skills/anomalib-adding-a-model/SKILL.md与.agents/skills/anomalib-adding-a-datamodule/SKILL.md)。
相关资源
- anomalib-training 技能文档:本文依据的原始技能说明;
- Engine 源码:Engine 完整实现与所有方法签名;
- Folder datamodule 源码:Folder 参数与目录结构定义;
- AnomalibCLI 源码:CLI 子命令与参数解析实现;
- XPU 加速实现:Intel XPU 加速器与单卡策略源码;
- MVTecAD datamodule:标准基准数据集的 datamodule 实现,可作为自定义数据集的参考模板。
【免费下载链接】anomalibAn anomaly detection library comprising state-of-the-art algorithms and features such as experiment management, hyper-parameter optimization, and edge inference.项目地址: https://gitcode.com/GitHub_Trending/an/anomalib
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考