[论文解读]DeepHunter: Hunting Deep Neural Network Defects via Coverage-Guided Fuzzing

DeepHunter: Hunting Deep Neural Network Defects via Coverage-Guided Fuzzing


论文标题

  • DeepHunter: Hunting Deep Neural Network Defects via Coverage-Guided Fuzzing
  • DeepHunter:通过复盖引导模糊来寻找深层神经网络缺陷
  • 2018.12

贡献

  • 我们提出了一个通用的覆盖制导模糊框架DeepHunter来系统地测试基于DNN的软件,这是最早对DNN进行反馈制导测试的研究之一。DeepHunter的设计考虑了测试DNNs的独特性和向实际规模DNN的可扩展性。(1)具体地说,测试执行可以很容易地并行化。我们提出了一种基于批处理的策略,并利用它来保持在获得模糊结果时的高吞吐量。(2)为了能够在有效域内大规模自动生成新的测试输入,提出了一种基于变形变异的测试生成技术,保留了变异前后的输入语义。(3)提出使用可插入的反馈分析组件来指导测试生成,包括一组6个不同粒度的测试准则,以进一步指导模糊化过程
  • 我们进行了一项大规模的实证研究,以评估DeepHunter在系统地生成覆盖增强测试方面的有用性,并以最近提出的6个覆盖标准为指导。
  • 我们进一步研究了最近提出的每一个测试覆盖标准如何帮助指导模糊化,(1)DNN模型质量评估,(2)错误行为检测,以及(3)为平台迁移引入量化缺陷。

总的来说,我们发现DeepHunter在以下方面可以有效地生成有用的测试:(1)提高目标覆盖率;(2)评估DNN模型质量;(3)检测错误行为;以及(4)捕获量化DNN版本失败的敏感情况。据我们所知,这项工作是迄今为止规模最大的DNN测试经验评估之一,使用了3个数据集(包括ImageNet)、7个DNN模型(具有VGG-16、ResNet-50等大型模型)和一组6个覆盖标准作为CGF指导。我们将把DeepHunter作为一个开放的框架向公众开放,以促进对DNN测试的进一步比较研究。

本篇是基于DNN覆盖理论的fuzz,并提出了一个框架deephunter,相当于tensorfuzz的扩展

目前基于覆盖的神经元测试到底用处多大仍待考核

摘要

随着过去十年的数据爆炸,基于深度神经网络(DNN)的软件经历了前所未有的飞跃,正在成为许多新型工业应用的关键驱动力,包括许多安全关键场景,如自动驾驶。尽管DNN在各种人类智能任务中取得了巨大的成功,但与传统软件类似,DNN也可能因隐藏的缺陷而表现出不正确的行为,从而导致严重的事故和损失。本文提出了一种自动模糊测试框架DeepHunter,用于寻找通用DNNs的潜在缺陷。DeepHunter执行变形变异以生成新的语义保留的测试,并利用多个Plugable覆盖标准作为反馈,从不同的角度指导测试生成。为了能够扩展到实际大小的DNN,DeepHunter在一批中维护多个测试,并根据主动反馈确定测试选择的优先级。DeepHunter在3个流行的数据集(MNIST、CIFAR-10、ImageNet)和7个具有不同复杂性的DNN上进行了广泛的有效性调查,在6个覆盖标准的大集合上作为反馈。大规模实验表明,DeepHunter可以(1)显著提高引导覆盖率;(2)生成有用的测试来检测错误行为,便于DNN模型质量评估;(3)准确捕获DNN量化过程中的潜在缺陷,用于平台迁移。

初步

对于传统软件来说,变异通常是相当随机的,并且经常生成无效(或无意义)的种子,这些种子将被程序中的健全性检查很早就拒绝。因此,通用模糊器通常只能找到较浅的错误,例如解析错误和不正确的输入验证。另一方面,DNN软件的输入通常需要特殊的格式,违反格式规范的输入甚至在学习过程开始之前就会被拒绝。因此,基于一些中间表示而不是原始数据来定制DNN感知的变异策略被认为是更具成本效益的

现有的技术,特别是覆盖准则[22-24]是否能对DNN模糊提供有意义的指导,还缺乏广泛深入的研究。

DNN软件开发和部署

图1:基于DNN的通用软件的开发和部署过程。我们建议的DeepHunter致力于评估DNN软件质量并查找其中的缺陷。

但是,如图1所示,在开发和部署阶段都可能引入缺陷。例如,数据收集、培训计划实施、培训执行等都可能在DNN开发阶段引入潜在的缺陷。类似地,量化和平台迁移也可能由于量化运算符或兼容性问题而引入缺陷

开发和部署都有一系列的问题可能会导致缺陷

基于覆盖的灰盒模糊

coverage-based grey-box fuzzing (CGF) ,这里与tensorfuzz中的CGF (coverage-guided fuzzing)不太一样

典型的CGF循环以下步骤:

(1)从种子库中选择种子;(2)对种子进行一定次数的变异,以生成新的测试,采用按位/按字节翻转、块替换和对两个种子文件进行交叉等变异策略;(3)针对新生成的输入运行目标程序,并记录执行的轨迹;(4)如果检测到崩溃,则报告故障种子,并将覆盖新轨迹的有趣种子保存到种子库中。这样的迭代将继续,直到给定的计算资源耗尽。CGF的两个关键组成部分是变异覆盖反馈,它们在很大程度上决定了模糊化的效率。

尽管传统程序和DNN之间存在巨大的差异,但CGF在前者上的成功仍然让我们对后者的模糊有了深刻的了解。例如,目标传统程序反映了DNN,模糊器的种子反映了DNN的输入,覆盖反馈可以是DNN的一些覆盖。考虑到DNN的独特特性,从DNN模糊化的角度出发,开发有效的变异策略和覆盖准则仍然是一项具有挑战性的工作。本文旨在通过设计有效的CGF框架来填补这一空白,在DNN的开发和部署过程中提供一个质量保证小工具。

方法

DeepHunter概述

图2描述了DeepHunter的概述,算法1指定了详细信息。从高层次上讲,DeepHunter由三个主要组成部分组成:变形突变,DNN反馈和批处理池维护。我们将DNN的原子输入(例如,图像)定义为种子,将一组种子(例如,多个图像)定义为。由于DNNs可以一次快速预测多个种子(即一批),因此我们维护批次池而不是种子池,以提高模糊效果。在模糊过程中,DeepHunter首先选择一批并生成大量突变种子,然后DNN一次性预测所有突变种子。最后,DeepHunter根据覆盖信息对池进行维护。下面详细介绍了DeepHunter的工作流程(参见算法1)。

Transformation and Mutation

传统的模糊器,如AFL,通过按位/按字节翻转、块替换、输入文件之间的交叉等来改变输入。然而,这些策略通常生成太多在DNN模糊中没有意义的输入。例如,人类感官感觉不到的图像或声音应该从变异中丢弃。因此,一个挑战是如何在增加突变的可变性和产生有意义的输入之间取得平衡。如果突变变化非常小,新生成的输入可能几乎没有变化;尽管它可能是有意义的,但模糊器发现失败测试的机会较低。另一方面,如果突变变化非常大,可能会识别出更多失败的测试;然而,失败的测试更有可能是没有意义的。

在这项工作中,我们主要关注图像输入。为了解决上述挑战,我们开发了一种Metamorphic Mutation策略。基本目标是给定一个图像i,赋值器生成另一个新图像i0,以便从人的角度看,i和i0的语义是相同的。

图像变换。为了增加突变的可变性,我们选择了八种图像变换,分为两类

  • 像素值变换P:改变图像对比度、图像亮度、图像模糊和图像噪声。
  • 仿射变换G:图像平移、图像缩放、图像剪切和图像旋转。

直观地说,像素值变换P变换会更改图像的像素值,而仿射变换G会移动图像的像素。这些变换在[23]中已被证明是有效和有用的。

Definition 1. An image I \mathcal{I}^{\prime} is one-time mutated from I \mathcal{I} if I \mathcal{I}^{\prime} is generated after a transformation t on I \mathcal{I} (denoted as I t I \mathcal{I} \stackrel{t}{\longrightarrow} \mathcal{I}^{\prime} ), where t P G . t \in \mathcal{P} \cup \mathcal{G} . An image I \mathcal{I}^{\prime} is sequentially mutated from I \mathcal{I} if I \mathcal{I}^{\prime} is generated after a sequence of one-time mutations ( I t 0 I 1 , I 1 t 1 I 2 , , I n t n I ) (  denoted as  I t 0 , t 1 , , t n I ) \left(\mathcal{I} \stackrel{t_{0}}{\longrightarrow} \mathcal{I}_{1}, \mathcal{I}_{1} \stackrel{t_{1}}{\longrightarrow} \mathcal{I}_{2}, \ldots, \mathcal{I}_{n} \stackrel{t_{n}}{\longrightarrow} \mathcal{I}^{\prime}\right)\left(\text { denoted as } \mathcal{I} \stackrel{t_{0}, t_{1}, \ldots, t_{n}}{\longrightarrow} \mathcal{I}^{\prime}\right)

就是对原始图像执行一系列的P或G操作,得到了变异后的图像

Metamorphic Mutation. 然而,在模糊化过程中,一幅图像可能会从原始图像连续变异,在一系列变异之后生成有意义的图像是具有挑战性的。为了提高变异的有效性,我们提出了Metamorphic Mutation.。

为了尽可能保证突变图像的有意义,我们采用了一种保守的策略,使得仿射变换只被选择一次,因为多个仿射变换更容易产生无意义的图像。我们假设仿射变换不会影响所选参数下的语义。像素值变换可以多次选择,我们使用L0和L∞来限制像素级的变化。假设通过像素值变换将图像i突变为I0,则如果满足f(i,I0)(等式1),则I0关于I是有意义的
f ( I , I ) = { L 255 ,  if  L 0 < α × size ( I ) L < β × 255 ,  otherwise  f\left(\mathcal{I}, \mathcal{I}^{\prime}\right)=\left\{\begin{array}{l} L_{\infty} \leq 255, \quad \text { if } L_{0}<\alpha \times \operatorname{size}(\mathcal{I}) \\ L_{\infty}<\beta \times 255, \quad \text { otherwise } \end{array}\right.
其中,0<α,β<1,L0表示变化的最大像素数,L_∞表示像素变化的最大值,size(I)表示图像 0 < I 0 < I 中的像素数。

直观地说,如果改变的像素数非常小(<α×Size(I)),我们假设它不改变语义,并且L_∞可以是任何值。如果更改的像素数超过边界,则限制最大更改值(<β×255)。

G只执行一次,P可以执行多次,但P有限制,要么变化像素数量少,变化程度高,要么变化像素多,变化程度低

这个函数决定了突变的难易程度

Definition 2. Given a mutated image I \mathcal{I} , the original image (denoted as I 0 \mathcal{I}_{0} ) of I \mathcal{I} is the image in the initial seeds and I \mathcal{I} is one-time mutated or sequence mutated from I 0 \mathcal{I}_{0} , i.e., I 0 t 0 , , t n I , \mathcal{I}_{0} \stackrel{t_{0}, \ldots, t_{n}}{\longrightarrow} \mathcal{I}, where n 0. n \geq 0 . The reference image (denoted as I 0 \mathcal{I}_{0}^{\prime} ) is defined as:
I 0 = { I j , 0 j n . t j G I 0 t 0 , , t j I j I 0 , \mathcal{I}_{0}^{\prime}=\left\{\begin{array}{l} \mathcal{I}_{j}, \exists 0 \leq j \leq n . t_{j} \in \mathcal{G} \wedge \mathcal{I}_{0} \stackrel{t_{0}, \ldots, t_{j}}{\longrightarrow} \mathcal{I}_{j} \\ \mathcal{I}_{0}, \end{array}\right.
参考图像要么是变异后的,要么是原始图像

算法2显示了变异的细节,

它将原始图像I作为输入,

将变异的图像I0作为输出。

state: 当前突变状态0或1,如果当前突变状态为0,则可以从仿射变换和像素值变换(第4行)中进行选择。如果突变状态为1,则只能使用像素值转换(第6行)

TRY_NUM:最大试验次数

Power Scheduling

如算法2中所述,DeepHunter只需有限的尝试次数即可变异一幅图像。如果满足f(I0,I0),则i的变异是成功的。实际上,突变成功的可能性取决于满足f(I0,I0)的难度

mutation potential: β × 255 × size ( I ) sum ( abs ( I I 0 ) ) \beta \times 255 \times \operatorname{size}(\mathcal{I})-\operatorname{sum}\left(\operatorname{abs}\left(\mathcal{I}-\mathcal{I}_{0}^{\prime}\right)\right)

直观地,突变势近似地表示图像i的突变空间,即满足 f ( I 0 , I ) f\left(\mathcal{I}_{0}^{\prime}, \mathcal{I}^{\prime}\right) 的难度,β×255×Size(I)表示图像可以更改的最大值

例如, 假设 I \mathcal{I}^{\prime} 来自突变序列 I 0 : ( I 0 t 0 I 1 , , I n t n I ) , \mathcal{I}_{0}^{\prime}:\left(\mathcal{I}_{0}^{\prime} \stackrel{t_{0}}{\longrightarrow} \mathcal{I}_{1}, \ldots, \mathcal{I}_{n} \stackrel{t_{n}}{\longrightarrow} \mathcal{I}^{\prime}\right), 中 序列前面的图像 ( e . g . , I 1 ) \left(e . g ., \mathcal{I}_{1}\right) 的突变潜力更可能高于在尾部的图像(e.g., I \mathcal{I}^{\prime} ).

功率调度是DeepHunter为不同种子(即图像)决定变异机会的过程。为了提高模糊化的效率,我们希望对更多具有较高突变潜力的图像进行突变。

就是定义一个函数好选择哪些种子突变

Plugable Coverage-Guided Fuzzing

在本文中,DeepHunter选择六个不同的标准作为不同的反馈,以确定是否应该保留新生成的批次以供进一步突变。该准则已被证明对捕获内部DNN状态是有用的。然而,由于每个神经元数值的巨大数值空间和DNN软件的大规模性质,模糊器可能会因泛洪反馈而过载。事实上,如果没有分类,具有相似神经元值的种子输入将被不必要地保留。由于突变的本能,将会有大量这样的突变体起源于给定的种子。为了解决这个问题,我们将每个标准的数值神经元反馈间隔平均划分为不同的桶,每个桶将被视为“等价类”。如果一个新的种子及其覆盖范围导致一个神经元落入现有的桶中,它就会失去兴趣并被丢弃。该机制的灵感来自于传统模糊框架(例如,AFL)中使用的“循环桶”实践,以缓解跟踪利用问题[45]。

BKNC是与TKNC相反的,选择的是最不活跃的

Batch Prioritization

批次优先顺序决定下一批应该挑选哪个批次。我们采用一种策略,即根据批次模糊化的次数以概率方式选择批次。特别地,该概率是通过以下方式计算的:
P ( B ) = { 1 f ( B ) / γ ,  if  f ( B ) < ( 1 p min  ) × γ p min  ,  otherwise  P(B)=\left\{\begin{array}{l} 1-f(B) / \gamma, \text { if } f(B)<\left(1-p_{\text {min }}\right) \times \gamma \\ p_{\text {min }}, \quad \text { otherwise } \end{array}\right.
其中B是批次,f(B)表示批次B已经模糊化了多少次,pmin>0是最小概率。参数γ和pmin的值可以调整

这里的基本思想是对很少fuzz的批次进行优先排序。例如,新突变批次的概率为1,因为它获得了新的覆盖范围,并且被认为是有趣的。为了保持多样性,其他经过多次模糊化的批次也有一个最小的选择概率Pmin。

Experiments

DeepHunter用Python和C实现:基于深度学习框架Kera(2.1.3版)[10]和TensorFlow(1.5.0版)后端[9],用Python实现变形突变组件和DNN覆盖反馈组件;为了提高效率,批量维护组件用C语言实现。我们通过调查以下研究问题来评估DeepHunter:

问1:在六个测试标准的指导下,DeepHunter可以达到什么覆盖率?

问2:DeepHunter是否有效地促进了DNN模型的评估?

问3:DeepHunter能否实现对DNN的各种错误行为检测?

问4:DeepHunter能否检测到DNN量化过程中引入的潜在缺陷?

由不同测试标准指导的覆盖结果

RQ1的答案:DeepHunter通过不同的标准指导显著提高了覆盖范围。

DNN模型质量评价
对于RQ2,我们尝试评估DeepHunter是否启用了DNN模型质量评估。因此,除了用于MNIST和CIFAR-10的每个模型的最佳候选C实例外,我们还从前两个训练阶段的每个阶段中选择了另外两个实例A和B,这使得我们可以将模型质量关系QA<QB<QC排序为基础

A,B是没训练完全好的模型,即epoch低

我们已经使用DeepHunter生成每个模型的实例C的测试。在这些测试中,我们保留C正确预测的测试,并在实例A和B上运行这些测试

我们看到,在我们生成的测试下,实例A和B的大部分准确性(参见表5)都低于原始测试的准确性(参见表2)。相反,在我们生成的测试下,实例A和B之间的大多数绝对精度差异超过了原始测试数据下的绝对精度差异。这表明生成的测试可以更好地区分实例A和B的质量,实例C比其他两个实例能够生成高质量的测试,这与我们的预期是一致的。

RQ2的答案:DeepHunter通过引导式模糊测试简化了模型质量评估。使用不同的覆盖指导生成的测试展示了不同的测试能力,为模型质量提供了不同的反馈。

就是说训练好的模型比没训练好的覆盖率高

DNN错误行为检测

对于RQ3,在DeepHunter的Fuzz测试过程中,我们不断收集生成的触发DNNs错误行为的测试。由于我们的变形变种对输入进行基于约束的变换,为了保证变换前后图像的语义不变,我们对变换前后的图像进行了批量预测检查,并记录了触发被测DNN错误行为的测试。表6显示了从每个模型的建议覆盖标准中检测到的错误行为。因此,DeepHunter成功生成测试来触发DNN的错误行为也就不足为奇了。最近的工作[22,23]已经表明,仅基于神经元覆盖的测试已经产生了数千个错误的触发测试。

RQ3的答案:DeepHunter可以有效地生成测试来触发测试下DNN的错误行为,它还可以很好地扩展到实际大小的数据集和DNN模型。

受控DNN量化设置下的缺陷检测

为了回答RQ4,最近有在移动设备、边缘计算设备等不同平台上部署DNN解决方案的强烈需求。由于计算和功耗的限制,通常的做法是将DNN模型从高精度浮点量化到低精度形式,以减小部署的规模。然而,量化可能会引入潜在的意想不到的错误行为。一个有效的测试套件应该能够捕获这样的错误案例,作为反馈给DL开发人员,以便进一步分析和调试。在这个研究问题中,我们调查DeepHunter是否有助于在量化过程中检测潜在的缺陷。

对于表2中所研究的每个DNN模型(即32位浮点精度),我们用3种配置进行量化:(1)随机抽样1%的权重将32位浮点截断为16位,得到混合精度DNN模型;(2)随机抽样50%的权重以将32位浮点截断为16位;以及(3)将所有权重从32位浮点截断为16位。

请注意,每个数据集的初始种子不能检测量化前后的错误行为。然后,我们重用DeepHunter生成的测试来评估量化模型,结果汇总在表7中。在所有情况下,DeepHunter都能够检测量化过程中引入的潜在次要错误行为。

在许多配置中,使用NBC和SNAC指导生成的测试检测到更多错误问题。一个潜在的原因是,NBC和SNAC较高的测试往往会覆盖神经元的角区行为,这可能会引发量化模型的错误行为。另一个有趣的发现是,我们发现全量化DNN模型的错误触发测试次数有时可能小于混合精度量化模型。直观地说,量化比越大,失去精度的权重就越多,可能会引入更多的错误行为。然而,我们的评估结果提示,有时由于较大的权重精度损失而引入的误差可能会相互抵消,从而获得误差较小的量化版本。

RQ4的答案:DeepHunter可以有效地检测DNN量化过程中引入的潜在缺陷,尽管会有轻微的精度损失。

讨论和对有效性的威胁

根据覆盖结果(参见。表4)以及相应的判据定义,我们发现KMNC是一个细粒度的判据,代表了k-多节神经元,很容易产生有趣的测试。例如,KMNC的平均覆盖增益为47%,超过了其他。另一方面,NC是一个相对粗粒度的标准,它记录了激活神经元的比率。正因为如此(见表5),NC指导的模糊测试不能产生有效的结果来评估各种质量的模型。表2和表3中的结果还表明,NC在错误触发测试检测和敏感缺陷检测方面的效果较差

与KMNC和NC相比,其他四个标准在指导模糊测试方面表现出不同的行为,其中一些标准可能很难涵盖,如SNAC和NBC。他们倾向于在生成角例测试时指导模糊测试,以便在许多情况下触发更多的错误行为

相关工作

DeepHunter与TensorFuzz的区别主要体现在三个方面。在TensorFuzz中,突变器只向输入提供一种类型的突变,即加性噪声。在DeepHunter中,基于全局和局部图像变换,赋予变异体8种保持语义的变形突变类型,从而产生既多样又可信的变形输入。此外,在TensorFuzz中,反馈仅依赖于一个标准,即基本神经元覆盖。相反,在DeepHunter中,我们使用了一组六个多粒度神经元覆盖标准来向模糊器提供多方面的反馈。最重要的是,DeepHunter与TensorFuzz在测量范围上也有所不同。事实上,本文的重点是对多个覆盖进行大规模的实证研究,以考察它们的有用性,以指导测试生成来检测DNN开发和部署过程中引入的潜在问题。