导航菜单

TensorFlow程序Bug的实证研究

  TensorFlow程序Bug的实证研究

  引用:Zhang, Y., Chen, Y., Cheung, S.C., Xiong, Y. and Zhang, L., 2018, July. An empirical study on TensorFlow program bugs. In Proceedings of the 27th ACM SIGSOFT International Symposium on Software Testing and Analysis (pp. 129-140). ACM.Proksch S , Amann S , Nadi S , et al.[ACM Press the 31st IEEE/ACM International Conference - Singapore, Singapore (2016.09.03-2016.09.07)]Proceedings of the 31st IEEE/ACM International Conference on Automated Software Engineering - ASE 2016 - Evaluating the evaluations of code recommender systems: a reality check[J]. 2016:111-121.

  深度学习应用程序在诸如自动驾驶系统和面部识别系统等重要领域中变得越来越流行。有缺陷的深度学习应用可能会导致灾难性后果。虽然最近的研究成果是在深度学习应用的测试和调试上进行的,但深度学习缺陷的特征从未被研究过。为了解决这个问题,我们研究了构建在TensorFlow之上的深度学习应用程序,并从StackOverflow QA页面和Github项目中收集了与TensorFlow相关的程序错误。我们从QA页面提取信息,提交消息,提取请求消息,并向检查这些错误的根本原因和症状。我们还研究了TensorFlow用户为错误检测和本地化部署的策略。这些结果有助于研究人员和TensorFlow用户更好地理解TensorFlow程序中的编码缺陷,并指出未来研究的新方向。

  DL应用程序的编程范例显着地区别于传统应用程序。在传统应用程序中,我们通过编写针对性的逻辑程序以直接对模型进行编码以解决目标问题。但是,DL应用程序并不直接通过编码模型解决问题。相反,DL应用依赖DL模型的网络结构以及使用大量数据训练的过程,网络结构和培训过程也都需要仔细设置超参数。DL应用程序的开发经常面临在开发其传统对应物时很少遇到的任务,例如,配置包括节点层的复杂网络结构(也称为计算图)。此外,训练过程涉及密集循环,计算对超参数调整敏感,如学习速率和弃置率(比如dropout,剪枝策略)等。

  作者研究了近期对DL应用的测试[1][2][3]和调试[4][5]进行的一些研究。并指出尽管如此,DL应用中的缺陷特征从未被系统地研究过。特别是,目前尚不清楚范式从传统程序语言转向DL语言的新挑战会给故障检测和定位带来什么影响。例如,如果在构建DL模型时存在缺失缺陷,那么在训练模型时它有多大可能被捕获?为此,在这篇论文中,作者选择了TensorFlow这一深度学习框架,首次针对这一框架上编程的DL应用中编码错误的检测和定位进行了实证研究。研究收集了来自GitHub和StackOverflow的TensorFlow编码错误。作者定量和定性地分析了这些错误,并报告了(1)它们的症状和根本原因,(2)错误检测中的挑战,以及(3)bug定位的挑战。

  在论文中作者研究了构建于TensorFlow(下称TF)上的程序bug,依靠对收集的包含175个详细bug信息的数据集的分析讨论。总结了几个重要发现:确定了4种错误症状,7种错误根本原因,5个在错误检测和定位上的难点,以及TF用户用于解决这些问题的5种策略。其中作者重点强调了5种错误检测和定位的难点。

  RQ 1:这些bug的表现症状和根本原因是什么?

  RQ 2:当前存在的检测这些bug的新的挑战是什么,TF用户如何解决?

  RQ 3:当前存在的定位这些bug的新的挑战是什么,TF用户如何解决?

  总体来说,论文做出的贡献有三点:

  从StackOverflow和GitHub收集的TensorFlow错误数据集。对错误的症状和根本原因的研究,这可能有助于未来对TensorFlow应用程序测试和调试技术的研究。研究检测和定位错误的新挑战以及解决这些问题的当前策略,这为未来的研究开辟了新的问题。

  StackOverflow QA和GitHub提交的项目,前者包含难以调试的项目,后者更多聚焦与难以检测的错误。使用StackOverflow方式获取数据时时通过关键词搜索获得相关问题信息,同时作者进一步删除了无效的与TF安装和搭建有关内容。GitHub上则是选取有良好维护的项目,再同样利用关键词进行进一步的搜索选择,最后删除拼写错误,消除不相关和重复提交。在结果校验上,两位作者独立进行判断,对于遇到的分歧进行讨论,并去除了不相关的issue。最终得到所需的数据共计175个错误的数据集,其中的87个样本来自StackOverflow,剩下的来自GitHub。

  (1)RQ1:bug表现症状和原因

  针对GitHub的bug,利用commit信息和pull request信息对于原因和症状进行分析。而对于来自QA网站的,则重点关注回答中是否有对应的原因分析。除此之外,团队还尝试复现了bug,成功的将88个GitHub bug中的75个,87个StackOverflow中的76个bug进行了复现。最后两位作者仍然采用人工分类验证的方式进行分类讨论。归纳出以下4种症状和7个主要原因:

  症状1:错误。 TensorFlow错误类似于传统应用程序中的异常或崩溃,例如NaN错误。 TensorFlow框架可以在构造或执行阶段引发错误。

  症状2:低有效性。该程序在执行阶段表现出极差的准确性或损失。

  症状3:运行效率低下。在构造或执行阶段,程序执行缓慢甚至是无限停滞。

  症状4:未知。在讨论中没有迹象表明bug的后果,其症状仍然未知。

  原因:(1)错误的模型参数或者结构(2)不对称的张量 (3)Tensorflow计算模型的不熟悉(4)TensorFlow API变更(5)TensorFlow API误用(6)低效结构(7)其他

  最终的分类统计见表1。

  TensorFlow程序Bug的实证研究

  表 1 bug表现症状和原因分布

  (2)bug检测的难点

  难点1;概率性正确问题。如何对于非确定的概率性输出进行分析,以确定是否输出有误。作者发现,利用整体的多数据对分析是一个好方法,TF用户主要依靠准确度和训练集或者测试集上的损失来进行判断。对应的策略有两个:一是设置阈值,比较总体准确度或者损失与预期值的差距;二是迭代比较最近准确度和损失的变化程度进行判断。

  难点2:偶然性正确现象。TF模型相对传统的模型来说对于不会引发故障的偶然错误不敏感,原因包括大规模数据下单个错误不易影响最终模型的准确度以及某些非线性激活函数对于一些输入范围不敏感。这些细小的错误容易被后续操作放大,针对的策略一般利用代码审查,即使没有产生错误结果,用户也会进行代码修改优化。

  难点3:随机性执行的问题,黑盒训练和学习过程中bug难以捕获。

  (3)bug定位的难点

  难点1:神经网络内部相互依赖,当前层中的节点通常主要取决于前一层中的节点。此外,在训练阶段,由于反向传播,依赖性变为双向的。因此,切片方法通常包含神经网络中的所有节点并且无助于调试。

  难点2:是神经网络存在未知行为。中间输出难以理解和判断对错。

  对应的,作者研究发现3个典型的用户策略包括修改超参数,更换数据集和测试变量值的分布等。

  本文由南京大学软件学院2019级硕士研究生夏志龙翻译转述