写在前面
这里对我最近的研究领域——工业图像上的异常检测中最新的一些进展做一个总结。主要总结的是在2019和2020的一些顶会上,关于Semi-supervised或者Unsupervised anomaly detection的一些比较有意思的文章,并给出我自己的一些看法。
由于水平有限,所以大家辩证地看就好,如有不当之处或可补充之处,欢迎指正~
1. 简要地介绍一下什么是异常检测(anomaly detection)
如果将每个样本看作空间中的一个点的话,异常(anomaly)简单地来说就是离群点,或者说是“非主流”的点,即离大多数样本点都比较远。这里隐藏的意思是,异常通常是少数。
下图很形象地展示了什么是异常。其中,黑色的点为正常的样本点,红色的点为异常点样本点。(更多的介绍可以参考Kiwi:异常检测概述(一):An Overview of Anomaly Detection Part I)
异常检测的任务,就是找到正常样本与异常样本之间的界线,尽可能地将正常样本与异常样本分开。这里的界线,可以是在各种空间中的,例如图像空间、特征空间,甚至后文会介绍到的一篇论文中的loss profile空间(现在可能看到这个比较懵逼,后面的文章会介绍这篇文章,还是挺有意思的)。
目前实际的异常检测遇到的一个很大的困难,是在实际的场景中(例如工业流水线等),异常样本往往很难获得,甚至很多时候没有异常样本。这就迫使我们采用semi-supervised或者unsupervised的方法。接下来介绍的文章也都是semi-supervised或者unsupervised的方法。
下面我将以做异常检测的空间为划分标准,将最近的一些新方法做一个分类。预计将分3-4篇文章介绍完。
2. 图像空间上的异常检测方法
图像空间上的异常检测一般采用的是下图的Auto-encoder结构。
主要的思想是,如果我们只在正常样本的训练集上训练我们的Auto-encoder,则我们重构出来的图像会比较趋近于正常样本。利用这一个假设/性质,在推理阶段,即使输入的图像是异常样本,我们重构出来的图像也会像正常样本。所以我们只需对比原图和重构后的图,就可以判断输入的图像是否为异常,甚至可以定位到异常区域。
2.1 MemAE[1]:利用Memory抑制模型的泛化能力
Story:
上文所说的Auto-encoder框架其实隐藏了一个问题:机器学习模型一般都是具有泛化能力的。也就是说,即使我们在只有正常样本的训练集上训练,在推理阶段,如果输入异常样本,由于泛化能力的存在,我们的模型也有一定的概率输出类似于异常的样本。这时候我们对比原图和重构后的图像,会发现非常相似... 这时候我们的异常检测方法就失效了QwQ。
所以ICCV 2019的一篇文章[1]提出了MemAE来显式地抑制Auto-encoder的泛化能力。他们的思路是,既然Auto-encoder泛化能力有时候会过强,那么如果让输入decoder的embedding都由正常样本的embedding组合而成,能够预计decoder输出的重构图像也主要由正常样本的特征组成。这样,通过抑制泛化能力来逼迫重构后的图像贴近于正常样本。
具体做法是,将所有正常样本经过encoder得到的embedding保存在Memory中。当输入一个图像时,首先用encoder提取出其embedding,并逐一计算图像的embedding和memory中的各个embedding的相似度(例如cosine similarity),再用相似度作为权重,将memory中的embedding加权平均得到新的embedding。
得到的这个新的embedding将同时具有两个特点:
- 比较接近原本图像的embedding;
- 由正常样本的特征构成。
再将这个新的embedding输入decoder中,就可以得到既接近于原图、又贴近于正常样本的图像了。
Tricks:
- 首先是在加权Memory中embedding时weight的计算:
其中
2. 限制参与融合的memory的个数:
文章中提到了一个有趣的现象,当memory中参与融合的embeding过多时,重构后的图像在异常检测中的效果会下降。这样比较好理解:毕竟正常的要素过多,也会组成异常。
为了抑制这个现象,文章中限制了参与融合的embedding个数。一种比较naive的方式如下:
但是上式是不可导的,所以用下式替代:
优缺点总结:
优点:这篇文章提出了一个非常好的想法来抑制auto-encoder的泛化能力——加入只由正常样本特征构成的memory。据我所知,这应该是第一篇将memory引入异常检测的文章,能够算是一篇挖坑之作。后续也有文章跟进这一方面的研究。
缺点:一般来说由于缺少类似于U-net中的skip connection的存在,auto-encoder重构出来的图像一般都比较糊。此篇也不例外。这就给异常区域的定位带来了一定的困难。所以可以看到此篇文章的实验都是在比较简单的数据集上(例如MNIST, cifar10等)做的实验,而且只能将图片分类为正常或异常,而不能定位到异常的位置。我觉得后续如何在只用正常样本的特征情况下,重构出清晰的图,从而定位到异常区域位置也是一个可以挖的点。
2.2 Memory的进一步改进[2]
这是CVPR 2020的一篇文章,可以看作是在上一篇文章[1]之上的升级版。我个人认为这篇文章对上一篇文章的改进之处主要有以下几点:
- 增加了memory update的机制,只需存储固定个数的memory;
- 引入了feature compactness loss 和 feature separateness loss,减少需要保存的memory的数量;
- 采用了将原图的embedding和memory中的embedding结合输入decoder的方式,一定程度上解决了重构后的图像比较糊的缺点,从而可以定位到异常区域的位置,从而可以运用到一些更加复杂、贴近现实情况的数据集上。
这里主要介绍一下feature compactness loss和feature separateness loss。
feature copactness loss的作用是使得memory中的embedding和数据集中图像的embedding尽可能的接近。其计算公式如下图。具体地,对于图像的每一个embedding
feature separateness loss的作用则是使得memory中的embedding相距越大越好。想象一下,如果仅有feature compactness loss,则memory中的embedding会有一种趋于一致的趋势,那么memory就没有什么存在的意义了。
feature separateness loss的计算公式如下。对于图像的每一个embedding
参考
- ^abcGong D, Liu L, Le V, et al. Memorizing normality to detect anomaly: Memory-augmented deep autoencoder for unsupervised anomaly detection[C]//Proceedings of the IEEE International Conference on Computer Vision. 2019: 1705-1714.
- ^Park H, Noh J, Ham B. Learning Memory-guided Normality for Anomaly Detection[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2020: 14372-14381.