异常检测(Anomaly detection),一个很常见的问题。
在图像方面,比如每天出入地铁安检,常常看到小姐姐小哥哥们坐在那盯着你的行李过检图像,类似如下(图来自GANomaly论文):
又比如在一些医学图像分析上,源自健康人的影像也许是比较容易获取的,并且图像的“模式”往往固定或者不多变的,而病变的图像数量是很少、很难获取,或者病变区域多变、甚至未知的,此时异常检测就面临着正样本/异常图像很少,而相对地,正常图像更容易获得的情况。这种情况其实在很多场景下有所体现,比如工业视觉检测等等。
对于已知类别、数量较多情况下,不管异常与否,我们也许可以通过训练一个分类模型就能解决。但面对也许未知、多变的情况,要想用一个多分类模型分辨出来似乎很难。如果是想仅仅分辨出是不是异常,那也许可以做一个单分类器即可。
我们尽可能地去让模型充分学习正常数据的分布长什么样子,一旦来了异常图像,它即便不知道这是啥新的分布,但依旧可以自信地告诉你:这玩意儿没见过,此乃异类也!
在仅有负样本(正常数据)或者少量正样本情况下:
训练阶段:
可以通过网络仅仅学习负样本(正常数据)的数据分布,得到的模型G只能生成或者重建正常数据。
测试阶段:
使用测试样本输入训练好的模型G,如果G经过重建后输出和输入一样或者接近,表明测试的是正常数据,否则是异常数据。
模型G的选择:
一个重建能力或者学习数据分布能力较好的生成模型,例如GAN或者VAE,甚至encoder-decoder。
下面速览几篇论文、看看GAN是如何做异常检测的(数据主要为图像形式):
思路:通过一个GAN的生成器G来学习正常数据的分布,测试时图像通过学习到的G找到它应该的正常图的样子,再通过对比来找到异常与否的情况。
如上图所示,AnoGAN论文中采用的是DCGAN,一种较简单的GAN架构。
训练阶段:
对抗训练,从一个噪声向量Z通过几层反卷积搭建的生成器G学习生成正常数据图像。
测试阶段:
随机采样一个高斯噪声向量z,想要通过已经训练好的G生成一幅和测试图像x对应的正常图像G(z)。G的参数是固定的,它只能生成落在正常数据分布的图像。但此时仍需进行训练,把z看成待更新的参数,通过比较G(z)和x的差异去更新,从而生成一个与x尽可能相似、理想对应的正常图像。
如果x是正常的图像,那么x和G(z)应该是一样的。
如果x异常,通过更新z,可以认为重建出了异常区域的理想的正常情况,这样两图一对比不仅仅可以认定异常情况,同时还可以找到异常区域。
为了比较G(z)和x差异去更新z:
一是通过计算G(z)和x的图像层面的L1 loss:
二是利用到训练好的判别器D,取G(z)和x在判别器D的中间层的特征层面的loss:
两者综合:
另外,异常分数计算方法:
针对AnoGAN测试阶段仍然需要更新参数的缺陷,此方法提出一种基于BiGAN可快百倍的方法。
训练时,同时学习将输入样本x映射到潜在表示z的编码器E,以及生成器G和判别器D:
如此可避免测试仍需要“找到z”那个耗时的步骤。与常规GAN中的D仅考虑输入(实际的或生成的)图像不同,而还考虑了潜在表示z(作为输入)。
测试时,判断图像的异常与否的分值计算方法,可选择可AnoGAN基本一样的方法。
第二种方法的加强版,也是基于BiGAN,并且在稳定训练上做了些功夫。如下所示,(乖乖,搞了三个判别器 =_=
检测时的计算方法:
原理:
训练时,约束正常的数据编码得到潜在空间表示z1,和对z1解码、再编码得到的z2,差距不会特别大,理想应该是一样的。
所以训练好后,用正常样本训练好的 G只能重建正常数据分布,一旦用于从未见过的异常样本编码、解码、再经历编码得到的潜在空间Z差距是大的。
当两次编码得到的潜在空间差距大于一定阈值的时候,就判定样本是异常样本。
原理:
C(x~|x)是人工缺陷制造模块。X~是模拟缺陷的样本,经过EN-DE编码解码器后重建正常样本Y。
测试阶段,X输入EN-DE后得到理想正常样本y,使用LBP对Y和X逐像素特征比较,相差大则有缺陷。
使用的是AAE来学习建模正常数据分布。有时,对于在正常分布的的两个数据之间的距离,比一个正常和一个异常之间的距离还大,所以提出在隐空间也加一个约束。
暂时先写到这吧。