SimpleNet 学习记录
# 复现演示
操作系统:Ubuntu 20.04(WSL2)
# 拉取代码
git clone git@github.com:DonaldRR/SimpleNet.git
# 创建虚拟环境
# 创建
conda create -n simple-net python=3.8
# 删除
conda remove -n simple-net --all
# 激活
conda activate simple-net
# 退出
conda deactivate
2
3
4
5
6
7
8
# 常用命令
# 安装依赖(已激活环境)
pip install XXX
conda install XXX
# 安装依赖(未激活环境)
conda install -n simple-net XXX
# 查看所有环境
conda env list
# 查看环境所有依赖
conda list
# 只保留环境初始的包,其他全部删除
conda clean -a
# 刷新配置文件索引
conda clean -i
2
3
4
5
6
7
8
9
10
11
12
13
# 换源
清华镜像官网:anaconda | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror (opens new window)
# 安装依赖
# 安装依赖
conda install numpy
# v1.12.1
# CUDA 11.6
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.6 -c pytorch -c conda-forge
conda install -c menpo opencv
2
3
4
5
6
# 配置文件
首先给出我的清华镜像配置(原配置,未更改)
channels:
- defaults
show_channel_urls: true
default_channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
deepmodeling: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
注意:当我们初始安装的时候是没有上面的配置的,只有执行
conda config
才会初始化~/.condarc
配置文件,但是此时配置文件仍旧是空的,需要自己写入配置
# 安装误区
以安装 pytorch 依赖为例
conda install pytorch==2.0.0 torchvision==0.15.0 torchaudio==2.0.0
这时因为没有配置文件,同时没有使用 -c 指定通道,所以使用的是固定的官方 default 通道,注意此时 conda 会从默认通道中搜索三个依赖,只有三个依赖都搜索到才可以允许安装
# conda
conda install pytorch==2.0.0 torchvision==0.15.0 torchaudio==2.0.0 -c pytorch
2
此时分为两种情况
未配置自定义 pytorch 通道时,从官方的 pytorch 通道搜索三种依赖包
已配置自定义 pytorch 通道时,从自定义的 pytorch 通道搜索三种依赖包
注意:上面的通道没有找到都会从配置文件中的默认通道再搜索(未配置默认通道则为官方默认通道)
上面这种情况有种误区,以第二种情况为例,因为已经指定了自定义通道 pytoch,就误认为如果从该通道搜索不到依赖包,就会从官方的 pytorch 通道搜索。
# CUDA 11.7
conda install pytorch==2.0.0 torchvision==0.15.0 torchaudio==2.0.0 pytorch-cuda=11.7 -c pytorch -c nvidia
2
表明优先从 pytorch 渠道搜索并安装包,如果在该渠道中找不到该软件包,则继续在 nvidia 通道中搜索。
需要注意的是,conda 在搜索和安装软件包时会根据指定的渠道顺序进行搜索,因此如果在第一个渠道中找到了软件包,就不会继续在后续渠道中搜索。同样都搜索不到就会从默认通道搜索
# 总结
没有配置文件,看是否指定通道,如果指定通道,则只搜索指定通道和官方默认通道的依赖。如果未指定通道,则只搜索官方默认通道(default)。
有配置文件,看是否指定通道,如果指定通道,确定指定通道顺序如下。
- 先搜索配置文件中 custom_channels
- 再搜索官方通道
- 上述均无,显示不可达或是未找到
注意:上述三步只要满足条件就会终止,不会再向下搜索
所以搜索顺序为先搜索指定通道(如果有),找不到依赖则从配置文件中的默认通道再搜索(未配置默认通道则为官方默认通道)
未指定通道,则查看 channels 配置(可能有多个通道)。同时看到因为配置文件有 default_channels ,所以 defaults 通道被重写,不再是官方默认通道
channels:
- defaults
show_channel_urls: true
default_channels:
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
2
3
4
5
6
7
# 前言
论文/代码(paperwithcode):SimpleNet: A Simple Network for Image Anomaly Detection and Localization | Papers With Code (opens new window)
论文链接:2303.15140.pdf (arxiv.org) (opens new window)
代码链接:DonaldRR/SimpleNet (github.com) (opens new window)
# 论文解读
# 概要
本文提出一个简单和应用友好(application-friendly)的网络( SimpleNet )用于检测和定位异常。SimpleNet由四个组件组成:(1) 生成局部特征的预训练特征提取器(pretrained feature extractor),(2) 将局部特征传输到目标域(target domain)的浅层特征适配器(shallow feature adapter),(3) 一个简单的异常特征生成器(anomaly feature generator),它通过将高斯噪声添加到正常特征来伪造异常特征,以及 (4) 区分异常特征和正常特征的二进制异常鉴别器(binary anomaly discriminator),用于区分异常特征与正常特征。在推理过程中,将丢弃异常特征生成器(即异常特征生成器仅在训练期间使用)。本文的方法基于三种直觉。首先,将预训练的特征转换为面向目标的特征有助于避免领域偏差。其次,在特征空间中生成合成异常更为有效,因为缺陷在图像空间中可能没有太多的共性。第三,一个简单的鉴别器是非常有效和实用的。尽管简单,但SimpleNet在数量和质量上都优于以前的方法。在MVTec AD基准测试中,SimpleNet实现了99.6%的异常检测AUROC,与性能次之的模型相比,误差降低了55.5%。此外,SimpleNet比现有的方法更快,在3080ti的GPU上具有77FPS的高帧率。此外,SimpleNet演示了在One-Class新奇性检测任务上的显著性能改进。
# 1. 简介
图像异常检测和定位任务旨在识别异常图像并定位异常子区域。检测各种感兴趣的异常现象的技术在工业检测中有着广泛的应用。在工业场景中,异常检测和定位尤其困难,因为异常样本很少,异常可能从细微的变化(如薄划痕)到大的结构缺陷(如缺失零件)不等。
目前的方法主要以无监督的方式解决这个问题,即在训练过程中只使用正常样本。使用基于重建的方法(econstruction-based)、基于合成的方法(synthesizing-based)和基于嵌入的方法(embedding-based)是解决无监督异常检测问题的三个主要趋势。
基于重建的方法,假设仅用正常数据训练的深度网络不能准确地重建异常区域。将逐像素重建误差作为用于异常定位的异常分数。然而,这一假设可能并不总是成立的,有时网络可以很好地“泛化”,从而也可以很好的重建异常输入,从而导致错误检测。
基于合成的方法通过对在无异常图像上生成的合成异常进行训练来估计正常和异常之间的决策边界。然而,合成的图像不够逼真。来自合成数据的特征可能会偏离正常特征很远,使用这种负样本进行训练可能会导致有松散边界的正常特征空间,这意味着模糊的缺陷可能会被包括在分布特征空间中。
最近,基于嵌入的方法实现了最先进的性能。这些方法使用ImageNet预训练的CNN来提取广义正态特征。然后采用多元高斯分布、归一化流和内存库等统计算法嵌入正态特征分布。通过将输入特征与学习的分布或记忆的特征进行比较来检测异常。然而,工业图像通常具有与ImageNet不同的分布。直接使用这些有偏见的特征可能会导致失配问题。此外,统计算法总是受到高计算复杂度或高内存消耗的影响。
为了缓解上述问题,我们提出了一种新型的异常检测和定位网络,称为SimpleNet。SimpleNet利用了基于合成和基于嵌入的方式,并做了一些改进。首先,我们不直接使用预训练的特征,而是使用一个特征适配器来产生面向目标的特征,以减少领域偏差。第二,我们不直接合成图像上的异常点,而是通过对特征空间中的正常特征施加噪声来产生异常特征。我们认为,通过适当地校准噪声的尺度,可以得到一个紧密结合的正常特征空间。第三,我们通过训练一个简单的判别器来简化异常检测程序,这比上述基于嵌入的方法所采用的复杂统计算法的计算效率要高得多。具体来说,SimpleNet利用一个预先训练好的骨干来提取正常特征,然后用一个特征适配器将特征转移到目标域。然后,通过向适应的正常特征添加高斯噪声,简单地生成异常特征。一个由几层MLP组成的简单判别器被训练在这些特征上,以判别异常情况。
SimpleNet易于训练和应用,具有出色的性能和推理速度。所提出的SimpleNet基于广泛使用的WideResnet50骨干网,在MVTec AD上实现了99.6%的AUROC,同时运行速度为77fps,在准确性和效率上都超过了之前公布的最佳异常检测方法。我们进一步将SimpleNet引入到单类新颖性检测的任务中,以显示其通用性。这些优势使SimpleNet成为学术研究和工业应用之间的桥梁。代码将公开提供。
# 2. 相关工作
异常检测和定位方法主要可分为三种类型,即基于重建的方法、基于合成的方法和基于嵌入的方法。
基于重构的方法认为,异常的图像区域不应该被正确地重构,因为它们不存在于训练样本中。一些方法[10]利用生成模型,如自动编码器和生成对抗网络[11]来编码和重建正常数据。其他方法[13,21,31]将异常检测作为一个画图问题,图像中的斑块被随机掩盖。然后,利用神经网络来预测被抹去的信息。整合结构相似性指数(SSIM)[29]损失函数被广泛用于训练。异常图被生成为输入图像和其重建图像之间的像素级差异。然而,如果异常点与正常的训练数据有共同的组成模式(如局部边缘),或者解码器对某些异常编码的解码能力 “太强”,那么图像中的异常点就有可能被很好地重建[31]。
基于合成的方法通常在无异常的图像上合成异常点。DRÆM[30]提出了一个网络,该网络以端到端的方式对合成的刚出炉的模式进行判别训练。CutPaste[17]提出了一个简单的策略来生成用于异常检测的合成异常点,该策略在大图像的随机位置剪切一个图像补丁并进行粘贴。一个CNN被训练来区分正常和增强的数据分布的图像。然而,合成异常点的外观与真实异常点的外观并不紧密匹配。在实践中,由于缺陷是多种多样且不可预测的,生成一个包括所有异常值的异常集是不可能的。用所提出的SimpleNet代替合成图像上的异常现象,在特征空间中合成负面样本。
基于嵌入的方法最近取得了最先进的性能。这些方法将正常特征嵌入到一个压缩的空间。**异常特征在嵌入空间中远离正常集群。**典型的方法[6,7,22,24]利用在ImageNet上预先训练好的网络进行特征提取。通过预训练的模型,PaDiM[6]通过多变量高斯分布嵌入提取的异常补丁特征。PatchCore[22]使用名义斑块特征的最大代表存储库。在测试中采用Mahalanobis距离或最大特征距离对输入特征进行评分。然而,工业图像通常具有与ImageNet不同的分布。直接使用预训练的特征可能会造成不匹配的问题。此外,无论是计算协方差的逆值[6]还是通过内存库中的近邻搜索[22]都会限制实时性能,尤其是对于边缘设备。
CS-Flow[24]、CFLOW-AD[12]和DifferNet[23]提出通过归一化流(NF)[20]将正常特征分布转化为高斯分布。由于归一化流只能处理全尺寸的特征图,即不允许向下采样,而且耦合层[9]消耗的内存是正常卷积层的几倍,所以这些方法都很耗费内存。蒸馏法[4, 7]训练学生网络以匹配固定的预训练的教师网络的输出,只用正常的样本。在异常查询的情况下,学生和教师的输出之间的差异应该被检测出来。计算的复杂性是双倍的,因为输入图像应该同时通过教师和学生。
SimpleNet克服了上述的问题。SimpleNet使用一个特征适配器,在目标数据集上进行转移学习,以减轻预训练的CNN的偏见。SimpleNet建议在特征空间中合成异常,而不是直接在图像上合成。SimpleNet在推理时遵循单流方式,完全由传统的CNN模块构建,这有利于快速训练、推理和工业应用。
# 3. 方法
本节将详细介绍拟议的SimpleNet。如图3所示,SimpleNet由一个特征提取器、一个特征适应器、一个异常特征生成器和一个判别器组成。异常特征生成器只在训练过程中使用,因此SimpleNet在推理过程中采用单流方式。这些模块将在下文中依次描述。
#
# 3.1 特征提取器
特征提取器获取本地特征,如~\cite{roth2022towards} 中所述。我们将该过程重新表述如下。我们将训练集和测试集分别表示为 和 。对于 中的任意图像 ,预训练网络 从不同的层次中提取特征,通常采用 ResNet 等骨干网络。由于预训练网络对其训练的数据集存在偏差,因此合理的做法是仅选择用于目标数据集的层次子集。形式上,我们定义 作为包含要使用的层次索引的子集。来自层次 的特征映射表示为 ,其中 、 和 分别是特征映射的高度、宽度和通道数。对于位于位置 的条目 ,其大小为 的邻域定义为
# 效果展示
# 参考文章
CVPR 2023 | SimpleNet:一个简单的图像异常检测和定位网络 - 知乎 (zhihu.com) (opens new window)
更快更准更简单的工业异常检测最新SOTA:SimpleNet - 知乎 (zhihu.com) (opens new window)
# 推荐阅读
2023CVPR SimpleNet A Simple Network for Image Anomaly Detection and Localizations (opens new window)