TensorFuzz: Debugging Neural Networks with Coverage-Guided Fuzzing
文章目录
简介
论文标题
- TensorFuzz: Debugging Neural Networks with Coverage-Guided Fuzzing
- TensorFuzz:使用覆盖引导模糊来调试神经网络
- 2018.8
贡献
- 我们引入了神经网络CGF的概念,并描述了如何快速地使用近似近邻算法来检查覆盖范围。
- 我们为CGF开源了一个名为TensorFuzz的软件库
- 我们使用TensorFuzz来发现训练神经网络中的数值问题,神经网络与其量化版本之间的不一致,以及字符级语言模型中的不良行为
摘要
众所周知,机器学习模型很难解释和调试。神经网络尤其如此。在这项工作中,我们介绍了用于神经网络的自动化软件测试技术,这些技术非常适合于发现只对罕见输入发生的错误。具体地说,我们发展了神经网络的覆盖引导模糊(CGF)方法。在CGF中,神经网络输入的随机突变由覆盖度量引导到满足用户指定约束的目标。我们描述了近似最近邻算法如何快速地提供这种覆盖度量。然后,我们讨论了CGF在以下目标中的应用:发现训练神经网络中的数值错误,在神经网络和量化版本之间产生不一致,以及在字符级语言模型中显示不期望的行为。最后,我们发布了一个名为TensorFuzz的开源库,它实现了所描述的技术。
- coverage-guided fuzzing (CGF) 覆盖引导模糊
Background
我们真正想要的是一种简单、计算成本低、易于应用于各种神经网络结构的覆盖度量。因此,我们建议存储与每个输入相关联的激活(或它们的某个子集),并通过使用近似最近邻算法来检查给定输入上的覆盖是否增加,以查看在预先指定的距离内是否存在任何其他激活集。
模糊过程
模糊化过程的整体结构非常类似于用于正常计算机程序的覆盖制导模糊器的结构。主要区别在于,我们与TensorFlow图形交互,而不是与我们检测的任意计算机程序交互,我们可以向TensorFlow图形馈送输入并从中获取输出。
模糊器从包含计算图的至少一组输入的种子语料库开始。与传统的CGF不同,我们不仅仅是输入大的字节数组。取而代之的是,我们将输入限制为在某种意义上是有效的神经网络输入。如果输入是图像,则我们将输入限制为具有正确的大小和形状,并且与所考虑的数据集的输入像素处于相同的间隔内。如果输入是字符序列,我们只允许从训练集中提取的词汇中的字符。
给定这个种子语料库,模糊化按如下方式进行:在被指示停止之前,模糊器根据我们将称为输入选择器的某个组件从输入语料库中选择元素。
给定输入后,赋值器组件将对该输入执行某种修改。修改可以像翻转图像中输入像素的符号一样简单,也可以被限制为遵循对语料库元素随时间进行的总修改的某种约束
最后,突变的输入可以馈送到神经网络。在TensorFuzz中,从神经网络中提取两件事:一组覆盖数组,从中计算实际覆盖范围;以及一组元数据数组,从中计算目标函数的结果。
一旦计算了覆盖率,如果变异的输入行使了新的覆盖率,它将被添加到语料库中,如果它使目标函数得到满足,它将被添加到测试用例列表中。
组件
Input Chooser:在任何给定的时间,模糊者必须从现有语料库中选择要变异的输入。论文中使用的启发式: p ( c k , t ) = e t k − t ∑ e t k − t p\left(c_{k}, t\right)=\frac{e^{t_{k}-t}}{\sum e^{t_{k}-t}} p(ck,t)=∑etk−tetk−t,这背后的直觉是,最近采样的输入在发生突变时更有可能产生有用的新覆盖,但随着时间的推移,这种优势会减弱。
Mutator:一旦输入选择器选择了语料库中的一个元素进行变异,就需要应用这些变异。在这项工作中,我们必须实现图像输入和文本输入的突变。对于图像输入,我们实现了两种不同类型的变异。第一种方法是只将用户可配置方差的白噪声添加到输入。第二种方法是添加白噪声,但限制突变元素与原始元素之间的差异,使其具有用户可配置的L-∞范数。如果我们想要找到满足某个目标函数的输入,但似乎仍然与用作种子的原始输入属于同一“类”,则这种类型的约束突变会很有用。在这两种类型的图像突变中,我们对突变后的图像进行裁剪,使其位于与用于训练被模糊化的神经网络的输入相同的范围内。
对于文本输入,因为我们不能简单地向字符串添加统一的噪声,所以我们根据以下策略进行变异:我们统一地随机执行以下操作之一:在随机位置删除字符、在随机位置添加随机字符或在随机位置替换随机字符
Objective Function:通常情况下,我们会怀着一定的目标来运行fuzzer。也就是说,我们希望神经网络达到某种特定的状态–也许是我们认为是错误的状态。目标函数用于评估是否已达到该状态。当变异的输入输入到计算图中时,覆盖率数组和元数据数组都将作为输出返回。将目标函数应用于元数据数组,并标记导致满足目标的输入。
Coverage Analyzer:覆盖率分析器负责从TensorFlow运行时读取数组,将它们转换为表示覆盖率的python对象,并检查该覆盖率是否为新的。检查新覆盖的算法是模糊器正常工作的核心。
一个理想的覆盖率检查器的特点是:我们希望它检查神经网络是否处于它以前没有处于的“状态”,这样我们就可以发现测试集可能没有捕获到的错误行为。我们希望检查速度快(所以我们可能希望它简单),这样我们就可以快速发现许多这样的不当行为。我们希望它可以在没有特殊工程的情况下适用于许多不同类型的计算图,这样从业者就可以使用我们的工具,而不必进行特殊的调整。我们希望所有的覆盖都是困难的,否则我们实际上不会覆盖很多可能的行为。最后,我们希望获得新的覆盖范围,以帮助我们取得增量进展,以便持续的模糊收益率继续上涨。
天真的、暴力的解决方案是读出整个激活向量,并将新的激活向量视为新的覆盖。然而,这样的覆盖度量不会提供有用的指导,因为大多数输入都会平淡无奇地产生新的覆盖。最好检测激活矢量是否接近先前观察到的矢量。实现这一点的一种方法是使用近似最近邻算法。当我们得到一个新的激活向量时,我们可以查找它的最近邻居,然后检查最近邻居在欧几里德距离中有多远,如果距离大于某个量L,则将输入添加到语料库中
实验结果
CGF可以有效地发现训练好的神经网络中的数值错误
查找数字错误很重要:如果第一次在“野外”遇到数字错误,特别是那些导致NAN的错误,可能会导致重要系统的危险行为。CGF可用于在部署前识别大量错误,并降低在有害环境中发生错误的风险。
CGF可以快速发现数字错误:使用CGF,我们应该能够简单地将校验数字运算添加到元数据中,并运行我们的模糊器。为了验证这一假设,我们训练了一个完全连接的神经网络来对MNIST[26]数字进行分类。我们故意使用了实施不佳的交叉熵损失,这样就有可能出现一些数值错误。我们对该模型进行了35000个步骤的训练,小批量大小为100时,其验证准确率为98%。然后,我们检查MNIST数据集中没有导致数字错误的元素。尽管如此,TensorFuzz还是跨多个随机初始化快速找到了NAN。有关更多详细信息,请参见图2。
基于梯度的搜索技术可能无助于查找数字错误:CGF技术的一个潜在反对意见是,基于梯度的搜索技术可能比随机化的搜索技术更高效。然而,如何为基于梯度的搜索指定目标并不明显。没有一种简单的方法来衡量模型的实值输出与NaN值有多相似
随机搜索在查找某些数字错误时效率低得令人望而却步:为了证明随机搜索是不够的,并且为了提高效率,覆盖引导是必要的,我们将其与随机搜索进行了比较。我们实现了一个基线随机搜索算法,并用10种不同的随机初始化对语料库中的100,000个样本进行了运行。基线在所有这些试验中都找不到非有限元素。
CGF在模型和它们的量化版本之间的不一致
量化(Quantization)[18]是使用由较少的计算机存储器组成的数值表示来存储神经网络权重和执行神经网络计算的过程。量化是一种降低神经网络计算成本或大小的流行方法,被广泛用于例如在Android神经网络API或TFLite中的手机上运行推理,以及在自定义机器学习硬件的上下文中-例如Google的张量处理单元[20]或NVIDIA的TensorRT
量化产生的误差是很重要的:当然,如果量化大大降低了模型的精确度,那么量化就没有多大用处了。在给定量化模型的情况下,检查量化在多大程度上降低了精确度将是一件很好的事情。
仅通过检查现有数据就可以发现很少的错误:作为基准实验,我们使用32位浮点数训练了一个MNIST分类器(这次没有故意引入数字问题)。然后,我们将所有权重和激活截断为16位。然后,我们在MNIST测试集上比较了32位和16位模型的预测,发现0个不一致的地方。
CGF可以快速地在数据周围的小区域中发现许多错误:然后,我们运行模糊器,将突变限制在种子图像周围半径为0.4无穷大的范数球中,只使用32位模型的激活作为覆盖范围。我们将输入限制在种子图像附近,因为这些输入几乎都具有明确的类语义。如果模型的两个版本在没有真正类的域外垃圾数据上存在分歧,那就没什么意思了。在这些设置下,模糊器能够对我们尝试的70%的示例产生不同意见。因此,CGF使我们能够找到测试时可能发生的真正错误。有关更多详细信息,请参见图3。
在给定与CGF相同数量的突变的情况下,随机搜索无法发现新的错误:如在4.1节中,我们尝试了基线随机搜索方法,以证明覆盖指导在此上下文中特别有用。当给定与模糊器相同数量的突变时,随机搜索基线不能找到任何不存在的分歧,
CGF表示字符级语言模型中的不良行为
线随机搜索方法,以证明覆盖指导在此上下文中特别有用。当给定与模糊器相同数量的突变时,随机搜索基线不能找到任何不存在的分歧,
CGF表示字符级语言模型中的不良行为
后略