FUVAS 视频异常分割模型实战指南:基于时空特征低秩分解的少样本无监督方法(anomalib 实现详解)
【免费下载链接】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
导读
FUVAS(Few-shot Unsupervised Video Anomaly Segmentation via Low-Rank Factorization of Spatio-Temporal Features)是发表于 ICASSP 2025 的视频异常检测与分割算法,其核心思想是用预训练的 3D CNN/Transformer 骨干网络提取视频片段的时空特征,再通过 PCA 低秩因子分解拟合正常分布,以特征重构误差(Feature Reconstruction Error, FRE)定位异常帧与异常区域。本文以 anomalib 仓库中的 FUVAS 官方文档 为主体,结合 Lightning 实现、PyTorch 实现 与 PCA 组件源码 进行源码级展开,你将掌握:FUVAS 的完整训练/推理流程、全部可配置参数及其底层影响、backbone 选择与特征层选取技巧,以及如何在 UCSD Pedestrian 等视频数据集上快速复现。
模型概述:什么是 FUVAS
FUVAS 由 Jiang 等人在 ICASSP 2025 提出(论文题为FUVAS: Few-shot Unsupervised Video Anomaly Segmentation via Low-Rank Factorization of Spatio-Temporal Features)。从 模块 docstring 可以确认其技术路线:
- 特征提取:使用预训练的 3D CNN 或 Transformer 骨干网络(如 X3D、I3D、Swin3D)提取视频片段的深层时空特征;
- 低秩因子分解:在训练阶段对提取到的正常视频特征拟合 PCA 变换,以低秩子空间刻画正常数据的分布;
- 异常判定:推理时计算特征在 PCA 低秩子空间中的重构误差,重构误差越大说明该区域越偏离正常分布,从而同时产出帧级分数(pred_score)与像素级异常图(anomaly_map)。
它属于少样本无监督(Few-shot Unsupervised)方法:训练时只使用正常视频片段,且由于骨干网络完全冻结、仅拟合 PCA,整个训练过程不需要梯度回传,单 epoch 即可完成,训练开销远低于端到端微调方案。
在 anomalib 中,FUVAS 与 AiVad 共同构成视频模型家族,对外通过 anomalib.models.video 导出,并已登记在 anomalib.models 的ALLOWED_MODULES白名单中,因此可直接通过Fuvas名称实例化,也支持后续 CLI/配置化调用。
快速上手:在 UCSDped 数据集上训练
官方 README 给出了最简训练示例,下面按 anomalib 标准三件套(数据模块 + 模型 + 引擎)复现并补充说明:
# Import the necessary modules from anomalib.data import UCSDped from anomalib.models import Fuvas from anomalib.engine import Engine # Load the ucsdped dataset, model and engine. datamodule = UCSDped() model = Fuvas() engine = Engine() # Train the model engine.train(model, datamodule)这段代码会自动完成以下事情:
UCSDped()构建视频数据模块,默认从./datasets/ucsd读取数据(源码);Fuvas()使用默认配置(backbone="x3d_s"、layer="blocks.4"、pre_trained=True、pca_level=0.98);engine.train(...)驱动训练:FUVAS 的trainer_arguments会强制设定max_epochs=1、gradient_clip_val=0、num_sanity_val_steps=0(见 lightning_model.py),因此训练只跑一个 epoch,且不会做梯度裁剪与验证集 sanity 检查。
官方示例运行输出
README 记录了在 UCSDped 上训练得到的测试指标:
| Test metric | DataLoader 0 |
|---|---|
| frame_AUROC | 0.9135797023773193 |
| mean_F1Score | 0.9350237846374512 |
| pixel_AUROC | 0.9756277996063232 |
其中frame_AUROC是帧级异常检测的 ROC-AUC,pixel_AUROC是像素级异常分割的 ROC-AUC,mean_F1Score为平均 F1 分数。从数值可以看到像素级 AUC 高于帧级 AUC,这符合分割任务在该数据集上的典型表现。需要说明的是,该表格为 README 记录的某次运行结果,实际复现会因数据版本、随机性等略有浮动。
核心参数详解:从 Lightning 层到 torch 层
FUVAS 的所有可调参数在 Fuvas Lightning 模块 中定义,并原样透传给 FUVASModel:
| 参数 | 默认值 | 含义 | 底层影响 |
|---|---|---|---|
backbone | "x3d_s" | 3D 骨干网络名称 | 决定特征提取网络与输入预处理;支持i3d_r50、x3d_l、x3d_xs、x3d_s、x3d_m(PyTorchVideo)与swin3d_b(torchvision),其他名称会直接抛出ValueError |
layer | "blocks.4" | 从骨干中提取特征的层名 | 决定特征的抽象层次与维度;PyTorchVideo 系列常用blocks.6.dropout(2048 维)或blocks.5.res_blocks.2,Swin3D 常用features.6.1 |
pre_trained | True | 是否加载预训练权重 | 为False时使用随机初始化骨干,实际应用中通常保持True |
spatial_pool | True | 是否对特征做空间池化 | True时用avg_pool3d/2d/1d压缩空间尺寸;False时先展平再按时间维做一维池化 |
pooling_kernel_size | Lightning 层1 | 池化核大小 | 控制特征降采样比例;torch 层 docstring 默认记为4,实际构造参数默认为4(见 torch_model.py),传入前请留意两层默认值差异 |
pca_level | 0.98 | PCA 保留的方差比例 | 取值 0~1;在 PCA 实现 中,小于等于 1 时按累计奇异值占比自动确定主成分个数,大于 1 时视为整数个主成分 |
pre_processor | True | 是否启用默认预处理器 | True用默认预处理,False完全跳过预处理 |
post_processor | True | 是否启用默认后处理器 | 控制阈值化/后处理流程 |
evaluator | True | 是否启用默认评估器 | 控制指标计算 |
visualizer | True | 是否启用默认可视化器 | 控制推理结果的图像可视化 |
一个典型的自定义实例化方式:
from anomalib.models import Fuvas model = Fuvas( backbone="swin3d_b", layer="features.6.1", pre_trained=True, spatial_pool=True, pooling_kernel_size=4, pca_level=0.98, )backbone 选择与输入约定(源码级说明)
从 torch_model.py 的构造逻辑可以归纳出两条 backbone 加载路径:
- PyTorchVideo 系列(
i3d_r50、x3d_l/x3d_xs/x3d_s/x3d_m):通过torch.hub.load("facebookresearch/pytorchvideo", model=backbone, pretrained=pre_trained)加载,常见输入尺寸为 (448, 512),常用特征层为blocks.6.dropout(2048 维特征)与blocks.5.res_blocks.2; - Swin3D-B:通过 torchvision 的
swin3d_b加载,默认权重为Swin3D_B_Weights.KINETICS400_IMAGENET22K_V1(在 Kinetics-400 与 ImageNet-22K 上预训练,使用 ImageNet 归一化);备选权重KINETICS400_V1仅用 Kinetics-400 预训练,归一化均值/标准差为[0.485, 0.456, 0.406]/[0.229, 0.224, 0.225]。常见输入尺寸为 (256, 256),时间维最小为 1。
加载完成后网络被置为eval()模式,并通过torchvision.models.feature_extraction.create_feature_extractor按layer名挂载特征提取器,后续所有特征计算均在torch.no_grad()下完成。
训练机制:为什么 FUVAS 不需要优化器
FUVAS 的 Lightning 模块有多个与其他 anomalib 模型显著不同的设计,理解它们有助于你把握该方法"轻量"的本质:
- 无优化器:
configure_optimizers()直接返回None(lightning_model.py),因为训练阶段只提取特征、不更新任何权重; - 单 epoch 训练:
trainer_arguments固定max_epochs=1,整个训练就是"遍历一遍正常视频,收集特征"; - 训练步骤仅收集特征:
training_step校验batch.image为张量后调用self.model.get_features(batch.image)[0].squeeze()得到 embedding 并追加到self.embeddings列表,最后返回一个requires_grad=True的占位零张量以满足 Lightning 的训练循环协议(lightning_model.py); - 训练结束后拟合 PCA:
fit()方法将收集到的 embedding 通过torch.vstack聚合,再调用self.model.fit(embeddings)拟合 PCA(lightning_model.py)。这一拟合动作由继承的MemoryBankMixin在训练循环结束时自动触发——FUVAS 与 Padim 等记忆库类模型共享这一机制; - 单类学习:
learning_type返回LearningType.ONE_CLASS,即只用正常样本建模(lightning_model.py)。
验证阶段validation_step直接对 batch 前向推理,将pred_score与anomaly_map写回 batch(lightning_model.py),随后由默认评估器计算 frame/pixel 级指标。
PCA 低秩分解的底层实现
PCA 组件位于 pca.py,它是 FUVAS 低秩因子分解的数学核心:
- 拟合:对训练特征做零均值化后,调用
torch.linalg.svd进行奇异值分解;当n_components <= 1时,按累计奇异值平方占比(即方差占比)自动选取使cumsum(sig²)/sum(sig²) >= n_components的最小主成分数,否则按整数成分数截取(pca.py); - 变换与重构:
transform将特征投影到低秩子空间,inverse_transform再映射回原空间,二者结合即可计算重构误差; - 状态持久化:奇异向量、均值、主成分数均注册为 buffer(继承自
DynamicBufferMixin),可随 checkpoint 保存与加载,保证推理阶段可以直接恢复拟合好的 PCA 参数。
推理流程:从特征到异常图
torch_model.py 的 forward 完整串联了推理链路:
get_features(batch):输入形状为(batch_size, clip_len, channels, height, width),先permute为 3D 网络期望的(batch, channels, clip_len, height, width),送入特征提取器;layer以"features"开头(Swin3D)时需再转置回(B, T, C, H, W)。随后按spatial_pool配置执行avg_pool3d/avg_pool2d/avg_pool1d池化,最终展平为(n_samples, n_features)的特征向量,并记录池化后的feature_shape(torch_model.py);compute_scores(features, feature_shapes):计算 PCA 重构误差 FRE——先将特征投影到低秩子空间再重构,计算逐元素平方误差(features - reconstructed)²,按feature_shape重塑为NxTxCxHxW,对通道与时间维求和得到NxHxW的score_map,再对空间维求和得到帧级score(torch_model.py);- 上采样回原图尺寸:将
score_map增加通道维后,用F.interpolate(..., mode="bilinear")上采样到输入视频帧的 H×W,得到与输入对齐的像素级异常图; - 返回
InferenceBatch(pred_score=..., anomaly_map=...),其中pred_score用于帧级指标(frame_AUROC),anomaly_map用于像素级指标(pixel_AUROC)与可视化。
数据准备与适配要点
FUVAS 可以配合 anomalib 支持的所有视频异常检测数据集使用。以示例中的 UCSDped 为例,UCSDped 数据模块 的关键参数:
root:数据集根目录,默认./datasets/ucsd;category:子集,"UCSDped1"或"UCSDped2",默认"UCSDped2";clip_length_in_frames:每个视频片段包含的帧数,默认2;frames_between_clips:相邻片段之间的帧间隔,默认10;target_frame:用于对齐 ground truth 的帧,默认取片段最后一帧(VideoTargetFrame.LAST);train_batch_size/eval_batch_size:默认均为8。
视频片段长度直接对应FUVASModel输入张量的clip_len维(如 docstring 示例中的torch.randn(batch, clip_len, 3, 448, 256)),因此选用较深的 backbone(如 Swin3D-B)时建议同步考虑显存占用与输入分辨率。
测试与工程化现状
在仓库的集成测试 tests/integration/model/test_models.py 中,fuvas与ai_vad目前被标记为pytest.skip("Revisit video models tests"),即视频模型测试尚待补全;fuvas已出现在list_models()的 snake_case、pascal、title 三种命名输出中(models/init.py),可作为anomalib.models.list_models()的枚举结果直接验证安装是否成功。对于希望进一步阅读 API 细节的读者,仓库还提供了由 automodule 自动生成的 FUVAS 参考文档。
引用
如果 FUVAS 在你的研究或项目中发挥了作用,请引用原论文(README 中的 BibTeX):
@inproceedings{icassp2025fuvas, title={FUVAS: Few-shot Unsupervised Video Anomaly Segmentation via Low-Rank Factorization of Spatio-Temporal Features}, author={Jiang, Jiaxiang and Ndiour, Ibrahima J and Subedar, Mahesh and Tickoo, Omesh}, booktitle={ICASSP 2025-2025 IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)}, pages={1--5}, year={2025}, organization={IEEE} }小结
FUVAS 把"视频异常分割"简化为"预训练特征提取 + PCA 低秩拟合 + 重构误差评分"三步,凭借冻结骨干与单 epoch 训练,成为 anomalib 视频模型家族中训练成本最低的方法之一。本文从官方 README 出发,逐层剖析了 Lightning 模块 的训练协议、torch 模块 的特征提取与 FRE 计算细节,以及 PCA 组件 的 SVD 实现,并给出了完整的参数表与 UCSDped 复现示例,可直接作为你在 anomalib 中上手 FUVAS 的起点。
【免费下载链接】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),仅供参考