TensorFuzz: Debugging Neural Networks with Coverage-Guided Fuzzing

21 篇文章 0 订阅
14 篇文章 5 订阅

因为老板之后可能要做深度学习框架的模糊测试,所以把之前一直没啃的paper先啃了。。

摘要

本文开发一个对神经网络的 coverage-guided fuzzing(CGF) 方法。然后讨论应用CGF达到以下目标:找到预训练好的神经网络中的数值型错误,生成神经网络的不一致并找到这些版本的神经网络,发现字符级别语言模型中意想不到的行为。最后开源了这个工具。

1. 绪论

机器学习模型由于下述原因很难debug或解释:

  • 概念上很难确定用户需要了解模型中哪些特定术语
  • 从特定形式的问题中获取答案的统计和计算上的困难

用难以debug的技术得到鲁棒的实验结论是困难的。

本文贡献:

  • 在神经网络中引入CGF的概念,描述fast approximate nearest neighbors algorithm可以用来检测覆盖率
  • 开源CGF软件库TensorFuzz
  • 使用TensorFuzz找到预训练好的神经网络模型中的数值类issue,不同网络间的不一致和他们的版本,字符级别语言模型的意料外的行为。

2. 背景

2.1 基于覆盖率的fuzzing

两个最常用的fuzzing工具是AFLlibFUzzer
fuzzing流程包含一个输入集合,然后在这些输入上进行变异,如果变异输入产生了新的“覆盖”就把它加入输入集合。

在神经网络中,多个不同的输入常常执行覆盖相同的多行代码和相同的分支。本文提出使用fast approximate nearest neighbors algorithm来确定两个集合的神经网络“activations”(激活函数?)是否不同(大概是,以relu为例,relu是个分段函数,不同分段就是不同的覆盖?),以此来表示神经网络的覆盖率。

2.2 神经网络的测试

Pei在以relu为激活函数的神经网络中引入神经元覆盖率的度量。一个测试用例达到全覆盖如果每个隐层的单元都有正值。然后使用梯度下降优化来交叉引用多层神经网络以发现异常行为。

Ma从两个方面概括神经元覆盖率。在k-multisection coverage中,抽取每个神经元在训练时的值的范围,分为k部分,然后度量k个部分是否都touched。在boundary coverage中,度量激活函数的值是否大于或小于某个值,然后评估测试集是否满足这些度量。

Sun受到Modified Condition/Decision Coverage启发引入一系列度量。以文中提到的ss-coverage目标为例:给定神经网络按层安排, ( n 1 , n 2 ) (n_1, n_2) (n1,n2)是邻接的两层,他们对于输入对 ( x , y ) (x,y) (x,y)ss-covered当且仅当 n 1 n_1 n1 x , y x,y x,y上有不同符号, n 2 n_2 n2 x , y x, y x,y上符号不同,且所有其他的层和 n 1 n_1 n1 x , y x,y x,y上有相同的符号。

还有俩相关工作就不说了。。

2.3 改进的契机

我们需要的覆盖率度量应该是简单的,计算代价低,且能够简单地兼容各种结构的神经网络。因此,我们提出保存每个输入相关的激活函数,使用fast approximate nearest neighbors algorithm检查是否覆盖率增加,来看在预定的距离内是否有其他集合的激活函数。

3 TensorFuzz library

TensorFuzz接受一个TensorFlow graph作为输入,以计算图中的激活函数为覆盖率指标。

3.1 基础fuzzing流程

WX20190612-132704.png
传统CGF以big arrays of bytes为输入,本文工具接收神经网络合法的输入。如果输入是图片,则要保证输入图片大小与网络可接受大小一致;如果输入时字符序列,那么要保证字符输入都在训练集合中。

在TensorFuzz中,两个信息从神经网络中提取出:

  1. 覆盖的数组集合,计算实际覆盖率
  2. 元数据数组集合,目标函数计算出来的结果

一旦覆盖率计算出来,如果产生了新覆盖,则把变异后的输入加入到输入集合中;如果满足了目标函数,则把输入加入到测试用例中。

3.2 fuzzing过程细节

Input Chooser: uniform random selection worked well,但是找到一个faster的启发式: p ( c k , t ) = e t k − t ∑ e t k − t p(c_k, t)=\frac{e^{t_k-t}}{\sum e^{t_k-t}} p(ck,t)=etktetkt,(看着有点像softmax。。), p ( c k , t ) p(c_k, t) p(ck,t)给出了选择输入集合中每个输入的概率, t t t表示选择的时刻, t k t_k tk表示 c k c_k ck加入到集合中的时间。最近加入的输入更有可能/值得用来fuzzing产生新的覆盖率,但是这个有点随时间推移减小。

Mutator: 工具对图像输入和文本输入都实现了变异操作。对于图片输入,实现了两种不同类型的变异:

  1. 简单地添加白噪声,用户配置偏差
  2. 也是添加白噪声

对于文本输入,均匀随机以下规则变异:

  1. 删除某个随机位置的字符
  2. 在某个随机位置添加一个字符
  3. 替换某个随机位置的字符

Objective Function:

Coverage Analyzer: 覆盖率检测器的特性:能够检测神经网络达到了之前没有到达的状态,能够检测到测试集合没有捕捉到的行为;此外,这个检测应该足够快,能够快速发现misbehaviors;再此外,这个检测器能够泛化用在不同的计算图上。这个覆盖率要达到全覆盖是很难的,另外实际上也不会覆盖到很多可能的行为。最后,我们希望用心覆盖帮助我们改进fuzzing流程。

本文使用激活向量(activation vector)来判断是否产生新的覆盖。如果只要vector不一样就算新的覆盖,那么几乎每个输入都会产生新覆盖。所以检测vector是否和之前观测到的vector相似就好了。然后就使用approximate nearest neighbors algorithm,每得到一个activation vector,查找它的近邻,如果欧氏距离大于某个阈值则加到输入集合中。实现上使用库FLANN计算approximate nearest neighbors。

这里还提到一个可能的优化,因为只需要知道是否存在近邻,而不需要知道最近邻,可以使用距离敏感布隆过滤器。

3.3 Batching和不确定

  1. 考虑GPU并行化计算的优势,每次给一个input太屈才了,所以batching一下,每次把多个输入打包成tensor传入模型中;
  2. 由于不确定性,输入可能导致不同结果。工具中进行最简单的处理:如果同个输入执行两次产生不同的覆盖,那么直接在输入集合中包含两次。

4 实验结果

实验中主要找能导致NaN输出的输入。

4.1 CGF可以在预训练好的神经网络模型中找到numerical errors

Numerical errors are important to find:

CGF can quickly find numerical errors:

Gradient-based search techniques might not help find numerical errors:

Random search is prohibitively inefficient for finding some numerical errors:

4.2 CGF发现了模型见的不一致性和他们对应的版本

quantization是用更少的位保存神经网络权重的过程。

Errors resulting from quantization are important to find:

Few errors can be found just by checking existing data:

CGF can quickly find many errors in small regions around the data:

Random search fails to find new errors given the same number of mutations as CGF:

4.3 CGF发现字符级别语言模型中意料之外的行为

5 结论

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值