异常检测通常是指寻找异常或稀有目标的任务,这些物品明显偏离被认为是“正常”的大多数。在这篇博文中,我们使用PatchCore查看图像异常. 除了指出哪些图像异常之外,PatchCore 还会识别每幅图像中最异常的像素区域。PatchCore 的一大优势是它只需要正常图像进行训练,这使得它对于异常图像很少见或获取成本高昂的许多用例具有吸引力。在某些情况下,我们甚至不知道我们可能遇到的所有异常模式,因此无法训练监督模型。
一个示例用例是检测工业制造中的缺陷,根据定义,大多数缺陷都是罕见的,因为生产线经过优化以尽可能少地产生缺陷。最近的方法在图像异常检测方面取得了重大进展,如MVTec 工业基准数据集所示。PatchCore ,在 CVPR 2022 上展示,是该领域的领跑者之一。在这篇博文中,我们首先深入探讨了 PatchCore 的内部工作原理。接下来,我们将其应用于医学成像示例,以衡量其在工业示例之外的适用性。我们使用由 Intel 开发的anomalib库,它提供了许多最新图像异常检测方法的即用型实现。
PatchCore 算法快速浏览
PatchCore 作为一种异常检测技术于 2021 年推出,旨在在工业应用中实现全面召回。如下图所示,PatchCore 有 2 个主要步骤。首先,它从正常图像块中提取局部感知特征。之后,它应用子采样技术(核心集)来近似这些特征并构建一组描述正常模式的补丁特征。在测试时,为测试样本提取补丁特征,并使用最近邻方法计算异常分数。在这篇博文的第一部分,我们更详细地介绍了关键步骤。
[回归基础:卷积
要了解 PatchCore,我们首先要回到卷积神经网络的基础知识。在其核心,卷积层由一组可学习的过滤器组成,在前向传递中,我们将它们中的每一个滑动(或卷积)在输入体积的宽度和高度上,计算每个位置的点积以产生输出。下图对此进行了说明。
该图像显示每个神经元(立方体中的一个圆)都连接到输入体积中的局部区域,或者换句话说连接到一个补丁。该图像显示了沿深度的 5 个神经元,它们中的每一个都对应于一个不同的过滤器,但查看相同的输入块(即它们具有相同的感受野)。
这些神经元的输出一起是一个 5 值向量,表示该输入块。PatchCore 背后的主要思想是使用这些补丁表示作为异常检测的基础。上图仅显示了一个卷积层,但特征图中神经元沿深度轴的输出描述了输入图像中的块的想法适用于深度卷积网络中的任何层。
使用中间 ResNet 表示
获得补丁表示需要有一个训练有素的网络,我们不能在我们的异常检测用例的数据上训练一个,因为我们没有(足够的)标记数据。幸运的是,迁移学习的大量成功实施已经证明,在 ImageNet 上预训练的模型生成的特征(超过 1000 万张不同对象类别的 1000 万张图像)也足够通用,可以用于其他任务,而 PatchCore 正是这样做的.
如上图所示,深度神经网络中的早期层学习较低级别的特征,而较深的层学习更多的高级特征。PatchCore 开发人员认为,中间层或中层特征对于异常检测最有用,因为早期层可能过于通用,而最终层可能过于依赖 ImageNet。他们使用预训练的类似 ResNet 的模型来提取补丁表示,并且只采用中间块的输出,忽略第一个和最后一个块。
使用核心集构建内存库
PatchCore 为所有正常图像提取预训练模型的中间输出,并将生成的向量存储在所谓的内存库中:一组描述正常图像补丁的向量的大集合。这个内存库很快变得非常大,对于每个输入图像,我们可以提取大量的补丁表示(_高度 * 宽度_对于我们想要包含的每个中间特征图)。由于 PatchCore 在下一步中采用最近邻方法检测异常,因此使用所有补丁功能对于推理时间和存储而言都过于昂贵。
为了减少内存库的大小但仍保留尽可能多的信息,PatchCore 使用核心集子采样对其进行近似。更准确地说,PatchCore 使用 minimax facility location coreset selection:它选择一个 coreset,使得原始集中的任何实例与 coreset 中最近的实例的最大距离最小化。在论文中,他们表明仅对内存库中 1% 的补丁表示进行采样就足以获得良好的性能,这使他们能够将推理时间缩短到 200 毫秒以下。
异常检测步骤
基于内存库,我们现在可以采用最近邻方法来检测异常。我们可以在两个层面上做到这一点:为整个图像分配一个异常分数,或者突出显示每张图像中最异常的像素级区域。为了计算图像级异常分数,PatchCore 首先提取要评估的图像的块表示(即通过预训练的 ResNet 网络进行正向传递并收集中间输出),然后取这些块中任何一个的最大距离从核心集中到其最近邻居的表示作为异常分数。还有更多内容(请参阅论文) 但这抓住了主要思想。获取像素级分割图基本上遵循相同的过程:对于每个补丁级别的表示,我们可以计算异常分数作为到核心集中最近的补丁表示的距离,并在原始图像上重新对齐这个分数(作为每个补丁表示对应于输入图像中的特定空间区域)。
应用 PatchCore 检测糖尿病视网膜病变的迹象
虽然 PatchCore 是作为工业制造异常检测的方法引入的,但没有什么能阻止它在其他图像领域的应用。由于使用新方法进行一些实践练习并了解它如何处理新数据总是很有趣,因此我们在健康视网膜图像的数据集上训练了 PatchCore 模型,以了解它在检测不健康视网膜中糖尿病性视网膜病变迹象时的表现. 我们使用anomalib 库中的 PatchCore 实现。您可以按照我们的笔记本进行类似的实验。
我们将使用公开可用的 IDRiD 数据集。请注意,对于这个特定的用例,我们不会在实践中使用异常检测(大型标记数据集可用于训练监督模型)。然而,这个数据集的优势在于我们知道要寻找哪些糖尿病视网膜病变的迹象。此外,这些迹象表现出不同程度的严重性,这使我们能够了解该方法的敏感性。我们可以想象这些异常检测技术可以应用于医疗领域的其他应用程序,在这些应用程序中,不健康患者的图像很少(例如,某些疾病在某些人群中相当罕见),而健康患者的图像则更为丰富。
在查看一些受影响的视网膜之前,让我们先了解一下健康的视网膜是什么样的。下图显示了两个没有任何糖尿病视网膜病变迹象的视网膜。我们看到视网膜的正常结构,包括视盘(亮点,血管和神经进入眼睛的地方)和黄斑(没有血管穿过的暗点,负责高分辨率视觉)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZNvlckl-1675752490235)(null)]
既然我们已经了解了健康的视网膜是什么样子,我们可以看看 PatchCore 在一些患有严重糖尿病性视网膜病变的视网膜上的结果。请注意,该模型仅在 168 个健康视网膜上进行训练,我们没有进行任何超参数调整。在下图中的两个视网膜中,我们看到该模型已经相当准确地识别出渗出物(通过受损视网膜血管泄漏的脂质和蛋白质),这令人印象深刻,因为我们只向它展示了一小部分健康的视网膜,它从未见过任何渗出物训练时渗出。
当然,该模型还远非完美。下面我们看到两个视网膜,它错误地将视盘识别为异常。一般来说,在没有非常明显的异常的情况下,我们会看到视盘和有很多血管的区域都获得了较高的异常分数。这很可能是因为我们相对较小的训练集没有捕捉到足够多的变化。
请注意,我们在这里以 IDRiD 数据集为例,使我们能够在新域中快速演示 PatchCore。更全面的研究可以通过探索不同种类的小而细微的微动脉瘤、使用更大的数据集(例如Kaggle DR 数据集)、验证 PatchCore 的检测能力和对糖尿病视网膜病变造成的各种损害的局限性等来进一步推进该实验。然而,这超出了这篇博文的范围。
总结
我们已经介绍了 PatchCore 的关键概念,并将其应用于医学影像数据集。即使数据集非常有限,我们也看到了一些非常有希望的结果。一般来说,如果您有一个用例,其中正常数据很容易获取但异常数据很昂贵(甚至是先验未知的),anomalib 可能是一个值得考虑的好工具。
相关代码与数据集下载:欢迎关注公众号:猛男技术控,回复异常检测