自编码器的一个主要用途,尤其是在无监督或半监督环境下,是异常检测。其基本原理很简单:自编码器经过训练,能够精确重建“正常”数据。当遇到一个异常数据点,即一个明显不同于训练期间所见模式的数据点时,自编码器通常会遇到困难,导致更高的重建误差。此误差可作为识别异常的信号。重建误差原理核心是,自编码器学习一种压缩表示(在潜在空间中),以捕获训练数据的主要特征。如果自编码器专门或主要针对正常实例进行训练,它就会非常擅长以最小误差重建这些正常实例。异常数据点,就其性质而言,不符合这种学习到的正常模式。当异常输入通过自编码器时:编码器尝试将其映射到潜在空间。由于异常数据不符合学习到的正常数据分布,此映射可能不理想,或者落入训练期间未充分表示的潜在空间区域。解码器随后尝试从该潜在表示重建原始输入。鉴于异常的潜在表示从解码器的角度来看可能是“不熟悉”的或形成不良的,重建很可能只是原始异常输入的一个粗略近似。原始输入 $x$ 与其重建 $\hat{x}$ 之间的差异被量化为重建误差。常用度量指标包括:均方误差 (MSE): $$ \text{MSE} = \frac{1}{d} \sum_{i=1}^{d} (x_i - \hat{x}_i)^2 $$ 其中 $d$ 是输入向量的维度。MSE 对较大的误差惩罚更重。平均绝对误差 (MAE): $$ \text{MAE} = \frac{1}{d} \sum_{i=1}^{d} |x_i - \hat{x}_i| $$ MAE 对误差值中的异常点本身不那么敏感。产生高于预设阈值重建误差的数据点随后被标记为异常。下图阐明了这一过程:digraph G { rankdir=TB; graph [fontname="Helvetica", fontsize=10]; node [shape=box, style="rounded,filled", fontname="Helvetica", fontsize=10]; edge [fontname="Helvetica", fontsize=9]; subgraph cluster_training { label = "训练阶段"; style="rounded,dashed"; fillcolor="#e9ecef"; color="#adb5bd"; node [fillcolor="#b2f2bb"]; train_data [label="正常训练数据"]; ae_train [label="自编码器\n(编码器 + 解码器)", shape=component, fillcolor="#748ffc"]; train_data -> ae_train [label=" 训练以最小化\n 正常数据的\n 重建误差 "]; } subgraph cluster_inference { label = "推理/检测阶段"; style="rounded,dashed"; fillcolor="#e9ecef"; color="#adb5bd"; new_data [label="新输入数据\n(未知类型)", fillcolor="#a5d8ff"]; trained_ae [label="已训练自编码器", shape=component, fillcolor="#748ffc"]; reconstruction [label="重建数据", fillcolor="#d0bfff"]; error_calc [label="计算\n重建误差\n(例如,MSE)", shape=ellipse, fillcolor="#ffe066"]; threshold_decision [label="误差 > 阈值?", shape=diamond, style="rounded,filled", fillcolor="#ffc078"]; anomaly_yes [label="标记为异常", shape=ellipse, style="rounded,filled", fillcolor="#ff8787"]; anomaly_no [label="视为正常", shape=ellipse, style="rounded,filled", fillcolor="#8ce99a"]; new_data -> trained_ae; trained_ae -> reconstruction [label=" 生成重建 "]; new_data -> error_calc [label=" 原始 ", taillabel="原始", style=dashed, arrowhead=none]; reconstruction -> error_calc [label=" 重建 ", taillabel="重建", style=dashed, arrowhead=none]; error_calc -> threshold_decision; threshold_decision -> anomaly_yes [label=" 是 "]; threshold_decision -> anomaly_no [label=" 否 "]; } // 隐藏边用于表示流程,尽管集群也有助于此 ae_train -> trained_ae [style=invis, weight=10]; }使用自编码器进行异常检测的工作流程。模型在正常数据上训练,然后根据新输入数据点的高重建误差来识别异常。异常阈值设定选择重建误差的合适阈值是一个重要的步骤。此阈值将正常实例与异常实例区分开来。常用方法包括:在完全(或尽可能多地)由正常数据组成的数据集上训练自编码器。使用正常数据(训练期间未见过)的验证集来观察重建误差的分布。计算该正常验证集中所有样本的重建误差。根据此分布设定阈值。例如:可以将其设定为正常验证数据中误差的高百分位数(例如,第 95、第 99 百分位数)。或者,如果假设误差遵循某种分布(例如,大致正态,但常偏斜),则可以使用统计度量,如均值加上标准差的倍数(例如,$\mu + 3\sigma$)。可视化正常验证集上重建误差的直方图,对于选择合适的阈值非常有帮助。目标是选择一个阈值,该阈值能够尽量减少误报(将正常数据标记为异常),同时仍能捕获真实异常。用于异常检测的自编码器变体尽管标准的简单自编码器已经相当有效,但前几章讨论过的其他变体可能会根据数据和异常的性质提供更多优势:去噪自编码器: 如果异常表现为噪声或正常数据的损坏,去噪自编码器 (DAE) 可能特别适合。通过训练 DAE 从损坏的输入中重建干净版本,它对被视为正常的微小变化具有鲁棒性,可能使真正的结构性异常以更高的重建误差更加突出。变分自编码器 (VAEs): VAEs 在潜在空间中学习概率分布。异常可能导致模型下概率较低的重建,或落入根据学习到的先验(通常是高斯分布)概率密度较低的潜在空间区域。在 VAE 训练期间优化的证据下界 (ELBO),或重建概率 $p(x|z)$ 有时可用作异常分数。VAEs 难以建模的数据点(低 ELBO)可被视为异常。卷积自编码器 (CAEs): 对于图像或其他空间结构化数据,CAEs 更受青睐。它们可以学习重建正常图像模式,图像中的偏差(异常)将导致更高的重建误差。选择通常取决于实验和数据集的具体特征。从一个简单的自编码器开始,如果需要再进一步考虑更复杂的架构,是一个不错的策略。实施的实用步骤数据准备: 这一步必不可少。您的训练数据应尽可能代表“正常”行为,并且理想情况下不含异常。像处理任何神经网络一样,对数据进行归一化或缩放。模型设计与训练:选择自编码器架构(简单、去噪、卷积等)。定义编码器、瓶颈层和解码器层。瓶颈维度是一个重要的超参数。选择合适的损失函数(例如,连续数据的 MSE,二值数据的二元交叉熵)。仅使用正常数据训练自编码器。在单独的正常数据验证集上监控重建损失,以防止过拟合并决定何时停止训练。阈值确定:将正常验证数据通过已训练的自编码器。计算每个实例的重建误差。分析这些误差的分布(例如,绘制直方图)并选择一个阈值。部署与检测:对于每个新的传入数据点,将其通过已训练的自编码器。计算其重建误差。如果误差超过设定的阈值,则将该数据点标记为异常。使用自编码器进行异常检测的优点无监督特性: 自编码器可以在无标签数据上进行训练,这在异常检测问题中很常见,因为异常通常很少且未预先识别。您只需要正常数据的良好表示。非线性: 它们可以捕获数据中复杂、非线性的关系,使其能够建模复杂的正常模式。降维: 编码过程本身就执行降维,这有助于识别定义正常状态的最显著特征。灵活性: 不同的自编码器架构可以根据各种数据类型(表格、图像、时间序列)进行定制。重要考量“正常”数据的质量: 基于自编码器的异常检测器性能严重依赖于训练数据准确代表正常性的假设。如果训练数据包含未标记的异常,自编码器可能也会学习重建它们,从而降低其日后检测类似异常的能力。阈值敏感性: 系统的有效性(异常的精确度和召回率)对所选阈值相当敏感。这通常需要仔细调整和领域专业知识。可解释性: 尽管自编码器可以标记异常,但它们本身不解释为什么特定实例因高重建误差而异常。可能需要进一步分析来解释。计算成本: 训练深度自编码器可能计算密集,特别是对于非常高维的数据或大型数据集。“未知的未知”: 自编码器善于发现与它们学习到的正常模式不同的异常。然而,如果某个异常与正常数据有许多共同特征,但以自编码器学习特征未能捕获的细微方式有所不同,则它可能被遗漏。尽管有这些考量,自编码器为异常检测提供了一个强大而多功能的框架,特别是在带标签的异常数据稀缺时。通过学习压缩和重建正常数据,它们提供了一种识别不符合常规数据点的原则性方法。