【2022工业图像异常检测文献】PatchCore

Towards Total Recall in Industrial Anomaly Detection

1、Background

工业图像异常检测主要解决 冷启动问题 ,即仅使用正常(无缺陷)样本图像来训练模型。

现有的关于冷启动工业视觉异常检测的工作依赖于通过自编码方法、生成对抗网络或其他无监督适应方法来学习名义分布的模型.

本文提出了 PatchCore 作为一种有效的解决 AD 方案,通过:

  1. 最大化测试时可用的正常信息。
  2. 减少对ImageNet类别的偏向。
  3. 保持高推理速度。

PatchCore通过利用局部聚合的中层特征补丁实现了基于单个区块异常即可以判断整个图像异常的事实这一目标。中层网络区块特征的使用使PatchCore能够在高分辨率下操作,并且对ImageNet类别的偏向最小化,而局部邻域特征聚合确保了足够的空间上下文保留,这产生了一个广泛的记忆库,使PatchCore能够在测试时最佳利用可用的正常上下文。

最后,为了实际应用,PatchCore还引入了贪婪核集子采样作为正常特征库的一个关键元素,以减少提取的区块级记忆库的冗余,并显著降低存储内存和推理时间,使PatchCore对实际工业应用非常有吸引力。(通过贪婪核集子采样以舍去部分局部特征从而提升性能)

PatchCore 结合 SPADE( 利用包括各种特征层次的记忆库进行细粒度的基于 kNN 的异常分割和图像级异常检测 )和 PaDiM( 利用局部约束的特征袋方法,估计补丁级特征分布矩来进行补丁级马氏距离测量 )优点, 使用邻域感知的补丁级特征记忆库和核集子采样,提高检测性能并降低推理成本。

2、Method

PatchCore 的核心思想:

  • 构建记忆库(Memory Bank):
    • 使用正常样本的图像,提取其中的特征来构建一个记忆库。这个记忆库包含了正常样本的特征表示,用于后续与测试样本进行比较。
  • 局部感知的补丁特征(Locally Aware Patch Features):
    • 将图像分割成小块(补丁),并从每个补丁中提取特征。这些特征不仅包括补丁自身的特征,还通过考虑补丁周围的邻域来捕捉局部上下文信息。
  • 特征聚合
    • 对于每个补丁,通过聚合邻域内的特征来构建一个局部感知的特征表示。这通常通过适应性平均池化(adaptive average pooling)来实现。
  • 核心集下采样(Coreset Subsampling):
    • 为了提高推理速度和减少存储需求,PatchCore使用核心集下采样技术来减少记忆库的大小,同时尽量保留正常样本特征的覆盖范围。
  • 异常检测与定位
    • 对于测试样本,PatchCore通过比较其补丁特征与记忆库中特征之间的距离来检测异常。如果任何一个补丁的特征与记忆库中的特征差异显著,那么该样本就被认为是异常的。
    • 通过评估每个补丁的异常分数,PatchCore还能生成一个热力图,用于定位图像中的异常区域。

贪婪核心集下采样 (Greedy Coreset Subsampling) 旨在减少存储需求和加速推理过程,同时尽量保留记忆库中正常样本特征的代表性。

核心集(Coreset)是原始数据集的一个小子集,它尽可能好地代表了整个数据集的关键特性。在机器学习和数据挖掘中,核心集用于近似大规模数据集,以便在减少计算资源消耗的同时,保持算法的准确性和效率。

贪婪核心集下采样的优点:

  1. 减少存储需求: 通过选择代表性强的样本,核心集大大减少了需要存储的数据量。
  2. 加快推理速度: 在进行异常检测时,只需要对核心集进行操作,而不是整个记忆库,这显著减少了计算时间。
  3. 保持性能: 尽管核心集比原始记忆库小得多,但它仍然能够很好地捕捉正常样本的特征分布,从而保持异常检测的准确性。

在这里插入图片描述

pseudo-code

# 伪代码:PatchCore异常检测算法

# 输入:
# X_N: 正常样本的图像集合
# φ: 预训练的深度神经网络模型
# j: 选择的特征层次
# p: 补丁大小
# s: 步长
# l: 核心集的目标大小

# 输出:
# M: 记忆库
# MC: 核心集缩减后的记忆库
# 异常检测结果

# 步骤1: 构建记忆库
M = {}
for each image x_i in X_N:
    M = M ∪ P_s,p(φ_j(x_i))  # 将图像分割成补丁并提取特征

# 步骤2: 核心集下采样
MC = {}
for i from 0 to l-1:
    m_i = arg max(m in M - MC) min(n in MC) ||ψ(m) - ψ(n)||^2
    MC = MC ∪ {m_i}  # 迭代选择最有代表性的特征加入核心集

# 步骤3: 异常检测
function AnomalyDetect(test_image):
    P_test = ExtractPatches(test_image, s, p)  # 从测试图像提取补丁特征
    scores = []
    for each patch_feature in P_test:
        m_test, m_star = FindClosestInMC(patch_feature, MC)  # 在核心集中找到最接近的特征
        score = ||m_test - m_star||^2  # 计算异常分数
        scores.append(score)
    return max(scores)  # 返回最大的异常分数作为整体异常评估

# 步骤4: 异常定位
function AnomalyLocalize(test_image, MC):
    P_test = ExtractPatches(test_image, s, p)
    anomaly_map = zeros(test_image.height, test_image.width)
    for each (h, w) in P_test:
        m_test, m_star = FindClosestInMC(P_test[h, w], MC)
        score = ||m_test - m_star||^2
        anomaly_map[h, w] = score
    return anomaly_map

# 主程序
test_image = LoadImage("test.jpg")
anomaly_score = AnomalyDetect(test_image)
if anomaly_score > threshold:
    print("异常检测到!")
    anomaly_map = AnomalyLocalize(test_image, MC)
    Display(anomaly_map)  # 显示异常热力图
else:
    print("图像正常")

流程:

  1. 构建记忆库: 遍历所有正常样本图像,对每张图像提取局部感知特征,并将这些特征聚合成记忆库。
  2. 核心集下采样: 使用贪婪算法从记忆库中选择最具代表性的特征,形成核心集。这一步是为了减少计算量和提高推理速度。
  3. 异常检测: 对测试图像进行同样的局部特征提取。对每个补丁特征,在核心集中找到最接近的特征,并计算距离,最后返回最大的异常分数作为整体异常评估。
  4. 异常定位: 与异常检测类似,但是为测试图像的每个补丁计算异常分数,并生成一个异常热力图,用于精确显示异常的位置。
  5. 主程序: 加载测试图像,调用异常检测函数,根据返回的分数判断是否异常,并可视化异常热力图。

3、Experiments

相比于其他方法,PatchCore 最好的。。。

在这里插入图片描述

4、Conclusion

  1. 提出用于冷启动异常检测的 PatchCore 算法,该算法仅利用名义样本的知识来在测试时检测和分割异常数据。
  2. PatchCore 在测试时 通过使用由从 ImageNet 预训练网络中提取的局部感知名义区块级特征表示组成的记忆库,保持最大量的名义上下文,并通过核集子采样实现最小运行时间之间取得了平衡。
  3. 其适用性通常受限于预训练特征的可迁移性。

[REFERENCE]
【文献】面向零漏检的工业异常检测方法
CVPR2022:PatchCore:工业异常检测中的全召回研究
【Patchcore论文阅读】迈向工业异常检测的全面召回 | Towards Total Recall in Industrial Anomaly Detection
论文精读:Towards Total Recall in Industrial Anomaly Detection
缺陷检测:PatchCore的代码解读


http://www.niftyadmin.cn/n/5670665.html

相关文章

Linux操作系统:GCC(GNU Compiler Collection)编译器

在 Linux 系统中,gcc(GNU Compiler Collection)是一个非常强大的编译器,主要用于编译 C 语言程序。 除了基本的编译和链接命令外,gcc还提供了许多选项和功能。 以下是一些常用的 gcc命令及其功能: 1. 基本…

Java设计模式(单例模式)——单例模式存在的问题(完整详解,附有代码+案例)

文章目录 4.3 单例模式存在的问题4.3.1序列化反序列化破环单例模式4.3.2 反射破环单例模式 4.3 单例模式存在的问题 破坏单例模式: 使上面定义的单例类(Singleton)可以创建多个对象,枚举方式除外。有两种方式,分别是…

【LandSat卫星】LandSat系列卫星介绍,文末附下载方式。

【LandSat卫星】LandSat系列卫星介绍,文末附下载方式。 【LandSat卫星】LandSat系列卫星介绍,文末附下载方式。 文章目录 【LandSat卫星】LandSat系列卫星介绍,文末附下载方式。前言LandSat系列卫星1.Landsat 12.Landsat 23.Landsat 34.Land…

Go并发编程的高级技巧——请求复制与限流

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在一些高性能应用场景中,快速响应是非常重要的目标。例如,当一个应用需要快速响应用户的HTTP请求,或从多个副本中检索数据时,如何优化请求处理成为关键。本文将讨论如何在Go语言中,通过并发和限流机制来实现…

Stream练习

取偶数 package stream;import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors;public class StreamDemo2 {public static void main(String[] args) {ArrayList<Integer> list new ArrayList<>…

python:给1个整数,你怎么判断是否等于2的幂次方?

最近在csdn上刷到一个比较简单的题目&#xff0c;题目要求不使用循环和递归来实现检查1个整数是否等于2的幂次方&#xff0c;题目如下&#xff1a; 题目的答案如下&#xff1a; def isPowerofTwo(n):z bin(n)[2:]print(bin(n))if z[0] ! 1:return Falsefor i in z[1:]:if i !…

大学生必看!60万人在用的GPT4o大学数学智能体有多牛

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作者&#x1…

配置管理工具——omegaconf

omegaconf是专门用来解析.yaml文件&#xff0c;支持对yaml中设置参数的变量插值、类型检查、默认值处理、层次化配置。参考&#xff1a;omegaconf&#xff0c;一个超强的 Python 库&#xff01;_omeaconf-CSDN博客 主要介绍一下几个常用到的功能&#xff08;持续补充...&#…