ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Anomalib FastFlow 实战:基于 2D 归一化流的无监督异常检测原理、配置与源码解析

Anomalib FastFlow 实战:基于 2D 归一化流的无监督异常检测原理、配置与源码解析 Anomalib FastFlow 实战基于 2D 归一化流的无监督异常检测原理、配置与源码解析【免费下载链接】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/anomalibFastFlow 是 anomalib 中基于 2D 归一化流Normalizing Flow的异常检测与定位算法。本篇以仓库中 FastFlow 参考文档 覆盖的四个核心模块Lightning 封装、Torch 网络、损失函数、异常图生成器为骨架结合 模型源码 与 官方配置完整讲清其参数含义、前向计算链路与训练方式读完后可独立完成 FastFlow 的配置、训练与结果解读。一、FastFlow 是什么可插拔的 2D 归一化流FastFlow 的核心思想论文FastFlow: Unsupervised Anomaly Detection and Localization via 2D Normalizing Flows是把任意预训练深度特征提取器ResNet、Vision Transformer 等抽出的视觉特征通过归一化流变换到一个可解析的概率分布空间。训练阶段学习输入特征 → 可处理分布的变换推理阶段则评估像素级似然——正常区域似然高异常区域似然低。模型 README 将其定位为Segmentation像素级分割/定位类型的模型即它不仅输出图像级异常分数还输出与输入同尺寸的异常热力图。在 anomalib 中FastFlow 作为 AnomalibModule 生态的一部分注册在 anomalib.models 下可通过类名Fastflow直接实例化也可通过 YAML 配置反序列化。二、模块组成与源码结构参考文档 通过automodule指令引用了四个模块它们共同构成 FastFlow 的完整实现模块职责关键类/函数lightning_model.pyPyTorch Lightning 封装训练/验证步骤、优化器、评估指标Fastflowtorch_model.py纯 PyTorch 网络特征提取器 多层 Fast Flow BlockFastflowModel、create_fast_flow_block、subnet_conv_funcloss.py负对数似然损失FastflowLossanomaly_map.py由隐变量生成异常热力图AnomalyMapGenerator__init__.py对外暴露三个公共符号# 来自 src/anomalib/models/image/fastflow/__init__.py __all__ [FastflowModel, FastflowLoss, Fastflow]三、模型参数详解Fastflow的构造函数见 lightning_model.py#L100-L136参数及默认值如下参数类型默认值说明backbonestrresnet18特征提取骨干网络pre_trainedboolTrue是否加载 ImageNet 预训练权重flow_stepsint8每个尺度下归一化流的耦合变换步数conv3x3_onlyboolFalse是否只使用 3x3 卷积子网否则奇偶步交替 3x3/1x1hidden_ratiofloat1.0子网隐藏通道数 输入通道数 × 该比例pre_processor/post_processor/evaluator/visualizer组件或bool均为True标准 Anomalib 组件插槽True表示使用各自默认实现需要注意一个初始化约束Fastflow要求传入input_size否则直接抛出ValueErrorlightning_model.py#L118-L120if self.input_size is None: msg Fastflow needs input size to build torch model. raise ValueError(msg)这是因为每个 Fast Flow Block 的卷积子网和 LayerNorm 形状都依赖于特征图的空间尺寸。input_size通常由数据模块如MVTecAD的input_size通过配置注入。四、FastflowModel骨干网络与 Fast Flow Block4.1 支持的四类骨干网络FastflowModeltorch_model.py#L109-L151通过 timm 加载骨干网络仅支持四种取值cait_m48_448CaiTdeit_base_distilled_patch16_384DeiTresnet18wide_resnet50_2其他取值会抛出ValueError并提示可用列表。两类骨干的处理方式不同ResNet 系多尺度 CNN以features_onlyTrue, out_indices[1, 2, 3]取三个阶段的特征通道数与下采样倍数由feature_info动态获取并为每个尺度附加一个可训练的 LayerNormtorch_model.py#L138-L145# for transformers, use their pretrained norm w/o grad # for resnets, self.norms are trainable LayerNorm self.norms nn.ModuleList() for channel, scale in zip(channels, scales, strictTrue): self.norms.append( nn.LayerNorm([channel, int(input_size[0] / scale), int(input_size[1] / scale)], elementwise_affineTrue), )Transformer 系单尺度 ViT直接取768通道、下采样16倍的最后一层 patch 特征源码中还会手动截取特定 block 深度——ViT 取前 8 个 block、CaiT 取前 41 个 block对应原论文 Table 6 的 Block Index 7 / 40见 torch_model.py#L228 与 torch_model.py#L259再 reshape 回(B, C, H/16, W/16)的 2D 特征图。无论哪种骨干其参数都会被冻结for parameter in self.feature_extractor.parameters(): parameter.requires_grad False即只训练流变换与 LayerNorm骨干网络不参与更新这是无监督模式下的标准做法。4.2 Fast Flow Block 的构造每个特征尺度上都有一个独立的SequenceINN来自 FrEIA 库块由create_fast_flow_block构建torch_model.py#L53-L85nodes SequenceINN(*input_dimensions) for i in range(flow_steps): kernel_size 1 if i % 2 1 and not conv3x3_only else 3 nodes.append( AllInOneBlock, subnet_constructorsubnet_conv_func(kernel_size, hidden_ratio), affine_clampingclamp, # 默认 2.0 permute_softFalse, )要点每个 block 由flow_steps个AllInOneBlock堆叠该组件位于 anomalib/models/components/flow对应原论文 Section 3.3 的all-in-one耦合层设计默认配置下奇数步用 1x1 卷积子网、偶数步用 3x3 卷积子网conv3x3_onlyTrue时全部使用 3x3子网本身是卷积-ReLU-卷积的两层结构隐藏通道数由hidden_ratio控制torch_model.py#L42-L48affine_clamping2.0用于约束仿射系数范围保证变换数值稳定permute_softFalse表示不使用 FrEIA 的软置换层。4.3 前向计算训练与推理两条路径forward方法torch_model.py#L168-L202先强制骨干进入eval()模式然后按骨干类型分派到_get_cnn_features/_get_vit_features/_get_cait_features。随后对每个尺度的特征执行流变换for fast_flow_block, feature in zip(self.fast_flow_blocks, features, strictTrue): hidden_variable, log_jacobian fast_flow_block(feature) hidden_variables.append(hidden_variable) log_jacobians.append(log_jacobian)训练模式返回(hidden_variables, log_jacobians)供损失函数使用推理模式调用AnomalyMapGenerator生成异常图并以异常图在空间维上的最大值作为图像级分数anomaly_map self.anomaly_map_generator(hidden_variables) pred_score torch.amax(anomaly_map, dim(-2, -1)) return InferenceBatch(pred_scorepred_score, anomaly_mapanomaly_map)五、损失函数逐层的负对数似然FastflowLossloss.py#L36-L65对每一层的隐变量与雅可比行列式对数求和loss torch.tensor(0.0, devicehidden_variables[0].device) for hidden_variable, jacobian in zip(hidden_variables, jacobians, strictTrue): loss torch.mean(0.5 * torch.sum(hidden_variable**2, dim(1, 2, 3)) - jacobian) return loss从公式看它假设隐空间服从标准正态分布0.5 * Σ z²即标准正态密度的负对数似然主体- jacobian项由变量代换公式修正流变换带来的体积变化。总损失是所有尺度层逐样本平均后的累加。该损失与training_step中train_loss的日志项一一对应lightning_model.py#L138-L154。六、异常图生成从隐变量到热力图AnomalyMapGeneratoranomaly_map.py#L50-L84把每层隐变量转换为一张flow map并做平均for hidden_variable in hidden_variables: log_prob -torch.mean(hidden_variable**2, dim1, keepdimTrue) * 0.5 prob torch.exp(log_prob) flow_map F.interpolate( input-prob, sizeself.input_size, modebilinear, align_cornersFalse, ) flow_maps.append(flow_map) flow_maps torch.stack(flow_maps, dim-1) return torch.mean(flow_maps, dim-1)步骤与类文档说明一致对每个隐变量先按通道取均方计算负对数概率指数化为概率取负后经双线性插值放大到input_size最后把各尺度的 flow map 堆叠后跨层取平均得到最终(N, 1, H, W)异常图。多尺度平均的设计使浅层特征对定位细节的贡献与深层语义特征得到平衡。七、Lightning 封装训练配置与指标Fastflow继承AnomalibModule几个值得注意的实现细节训练器参数lightning_model.py#L172-L175property def trainer_arguments(self) - dict[str, Any]: return {gradient_clip_val: 0, num_sanity_val_steps: 0}FastFlow 关闭梯度裁剪与训练前的 sanity check 验证轮。优化器固定的 Adam学习率0.001、weight decay0.00001lightning_model.py#L177-L187不提供外部超参覆盖入口。学习类型LearningType.ONE_CLASS单类学习只用正常样本训练。评估器验证阶段记录image_AUROC、pixel_AUROC两项用于早停监控测试阶段额外增加image_F1Score、pixel_F1Scorelightning_model.py#L198-L215。八、配置与训练YAML CLI Python API8.1 官方配置文件examples/configs/model/fastflow.yaml 给出了仓库自带的标准配置model: class_path: anomalib.models.Fastflow init_args: backbone: resnet18 pre_trained: true flow_steps: 8 conv3x3_only: false hidden_ratio: 1.0 trainer: max_epochs: 500 callbacks: - class_path: lightning.pytorch.callbacks.EarlyStopping init_args: patience: 3 monitor: pixel_AUROC mode: max要点最多 500 个 epoch早停回调以pixel_AUROC为监控指标、耐心值 3——这与 模型 README 中基准结果均使用 early stopping (patience: 3) 产生的说明相互印证。8.2 CLI 训练命令README 给出的命令行方式为anomalib train --model Fastflow --data MVTecAD --data.category category8.3 Python APIFastflow的模块级文档示例给出了完整流程init.py#L10-L20from anomalib.data import MVTecAD from anomalib.models import Fastflow from anomalib.engine import Engine datamodule MVTecAD() model Fastflow() engine Engine() engine.fit(model, datamoduledatamodule) predictions engine.predict(model, datamoduledatamodule)由于Fastflow要求input_size实践中一般通过配置方式AnomalibModule.from_config让数据模块的input_size注入模型而非手工构造裸参数。8.4 测试用例佐证单元测试 tests/unit/models/components/base/test_anomaly_module.py 将fastflow纳入参数化用例验证AnomalibModule.from_config能基于examples/configs/model/fastflow.yaml成功构建出AnomalibModule实例是配置文件与模型注册链路一致性的回归保障。九、基准结果来自模型 README模型 README 附带了在 MVTec AD 数据集上的基准全部使用 seed0启用 patience 为 3 的早停回调。四类骨干的平均指标如下骨干图像级 AUC像素级 AUC图像 F1像素 F1ResNet-180.9070.9680.9160.519Wide ResNet500.9630.9790.9470.589DeiT0.9250.9750.9060.557CaiT0.9440.9800.9110.575完整分类目表格Bottle、Cable、Capsule 等 15 个类别的 Image AUC / Pixel AUC / Image F1 / Pixel F1可查阅 README 原文。从中可以看出更换更强的骨干Wide ResNet50能同时提升检测与定位指标而 README 也提示增大早停 patience 有可能进一步改善结果。十、小结FastFlow 在 anomalib 中的实现是一条清晰的链路冻结的多尺度骨干特征 → FrEIA 多层 AllInOneBlock 流变换输出隐变量与雅可比对数→ 逐层高斯负对数似然损失训练 → 隐变量转 flow map 并跨层平均得到异常图 → 空间最大值作为图像分数。理解这条链路后可以结合flow_steps、conv3x3_only、hidden_ratio与骨干选择torch_model.py做针对性调参并利用 fastflow.yaml 中500 epoch pixel_AUROC 早停的标准配置复现基准结果。【免费下载链接】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),仅供参考
返回列表