1.1异常检测介绍
本章将介绍如何使用基于深度学习的异常检测和全局上下文异常检测。通过这两种方法,我们想要检测图像是否包含异常(异常是指偏离正常的事物,未知的事物)。
异常检测或全局上下文异常检测模型学习无异常图像的共同特征。经过训练的模型将推断,输入图像只包含学习特征的可能性有多大,或者图像是否包含其他内容(这被解释为异常现象)。这个推理结果作为一个灰度值图像返回。其中的像素值指示输入图像中相应像素显示异常的可能性有多大。
我们区分了两种可以使用的模型类型:异常检测和全局上下文异常检测。
异常检测(模型类型为'anomaly_detection')的目标是结构异常,因此在训练过程中没有学习到的任何特征(这些可能包括划痕、裂缝或污染)。
图(1)一个可能的异常检测示例
在图(1)中,输入图像的每个像素都被赋予一个值,该值表明该像素是异常的可能性有多大。虫子不是模型在训练中看到的无虫苹果的一部分,因此它的像素得到了更高的分数。
全局上下文异常检测(模型类型'gc_anomaly_detection')包括两个任务:结构异常检测和逻辑异常检测。结构异常主要包括未知特征,如划痕、裂缝或污染。逻辑异常包括图像中对象的数量错误或位置错误。
图(2) 一个可能的全局上下文异常检测示例
在图(2)中,输入图像的每个像素被分配一个值,该值表明该像素是异常的可能性有多大。因此,可以检测到两种不同类型的异常,结构异常和逻辑异常。结构异常:一个苹果中有一条虫子,这与模型在训练中看到的苹果不同。逻辑异常:一个苹果被放在柠檬中。虽然苹果本身是完整的,但违反了逻辑约束,因为模型在训练过程中只看到了正确分类的水果的图像。
全局上下文异常检测模型由局部子网和全局子网组成。该模型可以简化为一个子网,以提高运行时和内存消耗。如果单个子网性能足够好,建议这样做。详细信息请参见get_dl_model_param中的参数'gc_anomaly_networks'。设置'gc_anomaly_networks'后,需要再次评估模型,因为该参数会显著改变全局上下文异常检测的性能。
局部子网(Local subnetwork):该子网用于在较小的局部范围内对图像进行异常检测。它的设计目的是检测结构异常,但也可以发现逻辑异常。因此,如果可以通过分析图像的单个patches来识别异常,则由模型的局部子网来检测异常。有关如何定义局部子网的相关信息,请参阅get_dl_model_param中参数'patch_size'的描述。
全局子网(Global subnetwork):该子网用于在大范围或全局范围内对图像进行异常检测。它的设计目的是检测逻辑异常,但也可以发现结构异常。因此,如果需要查看大部分或全部图像来识别异常,则由模型的全局组件检测异常。
图(3)图像训练的一个典型任务
在图(3) 中,苹果和柠檬完好无损,分类正确,贴上了正确的标签。
图(4)一些可以通过全局上下文异常检测的示例
在图(4-1)中,逻辑异常,最有可能被局部子网检测到(标签异常);图(4-2)结构异常,极有可能被局部子网检测到(苹果上有虫子);图(4-3)逻辑异常,极有可能被全局子网检测到(排序错误);图(4-4)逻辑异常,很可能被全局子网检测到(苹果有缺失)。
1.2 异常检测通用工作流程
(1) 数据预处理
①通过函数read_dl_dataset_anomaly()函数来转换数据集的信息内容。它创建一个字典DLDataset作为数据库,并存储有关数据的所有必要信息。
②使用split_dl_dataset()函数进行数据集的拆分。
③网络对图像提出了相应的要求,例如图像大小和灰度值范围可以使用get_dl_model_param()算子获取。
④使用preprocess_dl_dataset()函数对数据进行预处理。使用create_dl_preprocess_param()函数,来设置指定预处理参数,例如图像大小,并将所有参数及其值存储在字典DLPreprocessParam中。
(2) 模型训练
①采用create_dl_train_param()函数,设置训练参数并将其存储在字典TrainParam中。
②采用train_dl_model()函数训练模型。此函数调用normalize_dl_gc_anomaly_features()函数,将类型为'gc_anomaly_detection'的模型适应于数据集的图像统计。
然后分别调用相应的训练算子 train_dl_model_anomaly_dataset ('anomaly_detection') 或'train_dl_model_batch' ('gc_anomaly_detection')。此算子期望的参数是模型句柄DLModelHandle、包含数据信息的字典DLDataset和包含训练参数的字典TrainParam。
③归一化网络。此步骤仅在使用全局上下文异常检测模型时才需要。异常分数需要通过normalize_dl_gc_anomaly_scores()函数进行归一化。这样做目的是在稍后对异常分数应用阈值时获得合理的结果(请参阅下面的“特定参数”一节)。
(3) 模型评估
①设置可能影响评估的模型参数。
②使用evaluate_dl_model()进行模型的评估。此函数需要一个带有评估参数的字典GenParam。
③字典EvaluationResult保存所需的评估度量。
(4) 模型推理
①使用get_dl_model_param()算子或者create_dl_preprocess_param_from_model()函数获取模型对图像的要求。
②使用set_dl_model_param()算子设置下面“模型参数”一节中描述的模型参数。
③使用gen_dl_samples_from_images()函数为每张图像生成数据字典DLSample。
④使用preprocess_dl_samples()函数对每张图像(都要像训练图像一样)进行预处理。在预处理步骤中保存字典DLPreprocessParam时,可以直接使用它作为输入来指定所有参数值。
⑤使用apply_dl_model()算子进行模型推理,并从字典DLResult中获取推理结果。
1.3 异常检测补充说明
(1) 数据(Data)
我们区分用于训练、评估和新图像推理的数据。作为一个基本概念,该模型通过字典处理数据,这意味着它从字典DLSample接收输入数据,并分别返回字典DLResult和DLTrainResult。
(2) 类(Classes)
在异常检测和全局上下文异常检测中,有两类:'ok',意思是没有异常,类ID为0。'nok',表示异常,类别ID为1(对于ID >0的像素值,请参见下面的“评估数据”小节)。这些类既适用于单个像素,也适用于整个图像。
(3) 训练数据(Data for training)
该数据集仅包含无异常的图像和相应的信息。它们必须以模型可以处理它们的方式提供。关于图像要求,请在下面的“图像”一节中找到更多信息。训练数据用于为您的特定任务训练模型。借助这些数据,模型可以学习无异常图像的共同特征。
(4) 评估数据(Data for evaluation)
该数据集包括没有异常的图像,但也可以包含有异常的图像。这个集合中的每个图像都需要一个指定图像类别的真值标签(参见上面的部分)。这表示图像是否显示异常('nok')或没有('ok')。如果图像包含在DLSample字典中,则可以在像素级别上直观地评估模型在查找异常方面的性能。在该图像中,每个像素表示类ID,因此输入图像中对应的像素是否显示异常(像素值> 0)或不显示异常(像素值等于0)。
图(5) anomaly_file_name示例
在图(5)中,为了提高可见度,灰度值被用来表示数字。图(5-1)为输入图像,图(5-2)对对应的normaly_file_name提供类注释,0:'ok'(白色和浅灰色),2:'nok'(深灰色)。
(5) 图像(Images)
该模型对图像的尺寸、灰度值范围、类型等提出了要求。具体的值取决于模型本身。有关不同模型的具体值,请参阅read_dl_model的文档。对于读模型,可以使用get_dl_model_param查询它们。采用preprocess_dl_samples()函数对图像进行预处理。
(5) 模型输出(Model output)
训练输出根据使用的模型类型不同而不同:
异常检测:作为训练输出,train_dl_model_anomaly_dataset()算子将返回一个字典DLTrainResult,其中包含训练期间收到的最佳获得错误和实现该错误的时间点。
全局上下文异常检测:作为训练输出,train_dl_model_batch()算子将返回一个字典DLTrainResult,其中包含总损失的当前值以及模型中包含的所有其他损失的值。
作为推理和评估输出,模型将为每个样本返回一个字典DLResult。
对于异常检测和全局上下文异常检测,该字典包括以下额外项:
normaly_score:表示整个图像包含异常的可能性的分数。这个分数是基于normaly_image中给出的像素分数。
对于全局上下文异常检测,根据所使用的子网,也可以只计算局部(anomaly_score_local)和全局(anomaly_score_global)子网的异常分数。
anomaly_image:一个图像,其中每个像素的值表示其对应的像素在输入图像中显示异常的可能性(参见下图)。对于异常检测,这些值对于全局上下文异常检测没有约束。根据所使用的子网,在使用全局上下文异常检测时,也可以仅通过局部(anomaly_image_local)或全局(anomaly_image_global)子网计算异常图像。
图(6) normaly_image示例
在图(6)中,为了可视化,灰度值被用来表示数字。图(6-1)提供类注释的anomaly_file_name, 0: 'ok'(白色和浅灰色),2:'nok'(深灰色)图(6-2)为对应的anomaly_image。
(7) 特定参数(Specific Parameters)
对于异常检测或全局上下文异常检测模型,使用set_dl_model_param设置模型参数和超参数。在get_dl_model_param中更详细地解释了模型参数。由于异常检测模型的训练是一次利用完整数据集完成的,而不是批处理,因此某些参数(例如“batch_size_multiplier”)没有影响。
该模型返回分数,但不将像素和图像分类为是否显示异常。对于这种分类,需要给出阈值,为视为异常的像素或图像设置最小分数。可以使用compute_dl_normaly_thresholds()函数来估计可能的阈值。可以通过threshold_dl_normaly_results()函数来应用这些阈值。
作为结果,该过程将以下项(取决于阈值)添加到样本的字典DLResult中:
①anomaly_class
整个图像的预测类别(对于给定阈值)。对于全局上下文异常检测,根据所使用的子网,也可以仅通过局部(anomaly_class_local)和全局(anomaly_class_global)子网计算异常类。
②anomaly_class_id
整个图像的预测类的ID(对于给定的阈值)。对于全局上下文异常检测,根据所使用的子网,也可以仅通过局部(anomaly_class_id_local)和全局(anomaly_class_id_global)子网计算异常类ID。
③anomaly_region
由所有被认为显示异常的像素组成的区域(对于给定的阈值,请参见下图)。对于全局上下文异常检测,根据使用的子网,也可以只计算局部(anomaly_region_local)和全局(anomaly_region_global)子网的异常区域。
图(7) anomaly_region 示例
在图(7)中,为了可视化,灰度值被用来表示数字;图(7-1)为得到的像素分数的异常图像;图(7-2)为对应的异常区域。