异常检测在工业机器视觉中有着重要应用,本文介绍集成多个优秀异常检测算法的工具包 Anomalib 。
原则 | 内容 |
---|---|
再现性 | anomalib 库的主要目标之一是比较不同最先进的异常检测算法在公共和自定义基准数据集上的性能。为了确保有效比较,anomalib 中的算法实现旨在重现原始出版物中报告的结果 |
可扩展性 | 鉴于异常检测领域的快速发展,以最小的努力将新算法添加到库中至关重要。为此,anomalib 提供了几个接口,开发人员可以实现这些接口,以使他们的模型与库的训练和推理入口点兼容。 |
模块化 | 该库包含几个现成的组件,可以在创建新算法时用作构建块。开发人员和研究人员可以以即插即用的方式重复使用这些组件,以进一步减少实施工作并快速原型化新想法。 |
实时性能 | anomalib 的一个关键目标是减少使用经过训练的模型进行推理的工作量。因此,该库提供了接口,分别通过 PyTorch 和 OpenVINO 部署选项使用 GPU 或 CPU 实时部署模型。 |
当前(2022.8) anomalib 需要 pytorch 1.11 + 版本,如果当前环境中有其他版本 pytorch 建议在新的环境中安装
pip install anomalib
git clone https://github.com/openvinotoolkit/anomalib.git
cd anomalib
pip install -e .
git clone https://github.com/openvinotoolkit/anomalib.git
├─anomalib # anomalib 核心文件
│ ├─config
│ ├─data
│ │ └─utils
│ │ └─generators
│ ├─deploy
│ │ └─inferencers
│ ├─models
│ │ ├─cflow
│ │ ├─components
│ │ │ ├─base
│ │ │ ├─dimensionality_reduction
│ │ │ ├─feature_extractors
│ │ │ ├─filters
│ │ │ ├─freia
│ │ │ │ ├─framework
│ │ │ │ └─modules
│ │ │ ├─layers
│ │ │ ├─sampling
│ │ │ └─stats
│ │ ├─dfkde
│ │ ├─dfm
│ │ ├─draem
│ │ │ └─utils
│ │ ├─fastflow
│ │ ├─ganomaly
│ │ ├─padim
│ │ ├─patchcore
│ │ ├─reverse_distillation
│ │ │ └─components
│ │ └─stfpm
│ ├─post_processing
│ │ └─normalization
│ ├─pre_processing
│ │ └─transforms
│ └─utils
│ ├─callbacks
│ │ ├─nncf
│ │ └─visualizer
│ ├─cli
│ ├─loggers
│ ├─metrics
│ └─sweep
│ └─helpers
├─configs # 默认配置文件
│ └─model
├─docs # 文档
├─notebooks
├─requirements # 依赖库
├─results # 我的运行结果
│ ├─fastflow
│ │ └─mvtec
│ │ └─linescan_ref
│ │ ├─images
│ │ │ ├─good
│ │ │ └─ng
│ │ └─weights
├─tests
└─tools # 训练、测试入口
├─benchmarking
│ └─utils
├─hpo
│ └─utils
└─inference
anomalib
中的代码不要修改比较方便的准备方式是将自己的数据整理成 MVTec 的数据格式
以我的数据为例
MyData
├─ground_truth
│ └─ng
├─test
│ ├─good
│ └─ng
└─train
└─good
这样我就有了名为 MyData 的自己的训练集
anomalib/models/parchcore/config.yaml
作为自己的配置文件configs/my_models
文件夹中数据集路径
、数据类型名称
、图像尺寸
、backbone
、模型参数
等tools/train.py
文件,加上自己配置文件作为参数python tools/train.py --config <path/to/model/config.yaml>
def get_args() -> Namespace:
"""Get command line arguments.
Returns:
Namespace: List of arguments.
"""
parser = ArgumentParser()
parser.add_argument("--model", type=str, default="fastflow", help="Name of the algorithm to train/test")
parser.add_argument("--config", type=str, default="configs/model/fastflow_raw.yaml", help="Path to a model config file")
parser.add_argument("--log-level", type=str, default="INFO", help="<DEBUG, INFO, WARNING, ERROR>")
args = parser.parse_args()
return args
数据预处理
、加载
、训练
、测试
、评估
等操作LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
Testing DataLoader 0: 0%| | 0/141 [00:00<?, ?it/s]QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
failed to get the current screen resources
Testing DataLoader 0: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 141/141 [00:39<00:00, 3.54it/s]
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Test metric DataLoader 0
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
image_AUROC 1.0
image_F1Score 0.994535505771637
pixel_AUROC 0.9919205904006958
pixel_F1Score 0.556056797504425
def get_model(self, config_path, model_path):
config = OmegaConf.load(config_path)
model = Patchcore(
input_size=tuple(config.dataset.image_size),
backbone=config.model.backbone,
layers=config.model.layers,
pre_trained=False,
coreset_sampling_ratio=config.model.coreset_sampling_ratio,
num_neighbors=config.model.num_neighbors,
)
weight = load(model_path)
print(f"loading Patchcore model from path {model_path}.")
load_res = model.load_state_dict(weight["state_dict"], strict=False)
print(f"Patchcore model loaded: {load_res}")
model.threshold = model.image_threshold.value.cpu()
return model
model.eval()