Skip to content

第44讲:大数据+AI系统的测试设计与执行

人工智能时代的到来,也意味着大量的人工智能系统需要得到测试和验证。而人工智能的测试最早可以追溯到上个世纪五十年代,即 1950 年阿兰·图灵(A.M.Turing)在那篇名垂青史的论文《计算机器与智能》(Computing Machinery and Intelligence)中第一次提出了"图灵测试"。

图灵测试就是为了验证论文所提出的"机器能够思考吗"这样的问题,假如某台机器"表现得"和一个思考的人类无法区分,这并不要求百分之百无法区分,而只要有 30% 的机会能骗过裁判,那么就认为机器能够"思考"。机器想通过图灵测试,还真不容易,直到 64 年后------2014 年在英国皇家学会举行的图灵测试大会上,聊天程序 Eugene Goostman 冒充一个 13 岁乌克兰男孩而骗过了 33% 的评委,从而"通过"了图灵测试。

人工智能发展到今天,已经接近 70 年,比软件工程的历史还长近 20 年,经历了两次浪潮和两次低谷之后进入今天的第 3 次浪潮。之所以,能进入第 3 次浪潮,完全是由于大数据的推波助澜,有了数据,才能训练出更好的模型。当然,也离不开今天发达的网络、廉价的存储能力和超强的计算能力(如 GPU)。

我们进入了一个大数据 + 人工智能的时代,所以用一讲来讨论一下大数据 + 人工智能的测试设计与执行,虽然篇幅极其有限,希望能带给你一些启发和帮助,将来若有需要,可以专门开一个"大数据+人工智能测试"专栏。

大数据的测试

大数据的特点,大家应该比较清楚了,经常用 4V 来表示,即数据规模大(Volume)、变化快或动态性强(Velocity)、多样性(Variety)和低价值密度(Value)。

针对大数据测试,覆盖数据采集、数据存储、数据加工等各个方面的验证,重点是在数据输入/输出、处理过程 ETL(Extract-Transform-Load、抽取-转换-加载)以及基于数据模型的业务应用等的功能测试、性能测试、可靠性测试等多种测试类型。其中基于数据模型的业务应用,一般和人工智能直接相关,将作为下一个主题讨论,主要是算法、AI 模型等的验证。

大数据的性能测试是一个重点,不仅要处理大规模的数据(数据量很大),而且数据种类多、数据变化快,这给大数据的性能测试带来时空上的挑战,特别是在 Test Oracle 上,会面临更大的挑战。因为经过大数据的处理,结果是否正确,很难设计一个明确的判定标准,但同时又和 AI 融合在一起,导致算法、模型、数据质量等问题相互容易,难以分辨。所以,算法、代码评审更有价值,在整个 ETL 处理过程中能讲清楚、解释合理,就能增加我们对质量的信心。最终是否正确,需要实践检验,包括 A/B 测试。

图1 大数据应用基本结构示意图

这里以 Hadoop、MapReduce 平台为例,具体测试分为 3 个阶段分别进行,通过过程的验证才能更好地保证输出的质量。

(1)数据阶段验证

这是数据预处理及其加载的验证,如使用工具 Talend 或 Datameer,验证下列内容:

  • 验证来自各方面的数据资源,检查来自各个数据源的数据是否被加载到数据系统(如 Hadoop 系统)中;
  • 检查相关数据是否以正确的格式、完整地被读入数据系统中;
  • 检验上传数据文件过程中,是否有异常数据流入存储或运算系统中,如果突然中断,系统能否有提示、是否会挂起;
  • 将源数据与加载到数据系统中的数据进行比较,检查它们是否匹配、一致;
  • 验证数据是否正确地被提取并加载到数据存储管理系统(如 HDFS)中。

(2)数据计算验证

这个阶段侧重每个节点上的业务逻辑计算验证,一般需运行多个节点的分布计算后再进行验证,检查下列操作:

  • 分布式计算(如 Map 与 Reduce 进程)能否正常工作;
  • 在数据上能否正确地实现数据聚合或隔离规则;
  • 业务逻辑处理是否正确、是否能正确生成键值对等;
  • 验证数据在分布式计算(Map 和 Reduce 进程执行)后是否正确;
  • 测试一些异常情况,比如数据输入中断、给算法喂的数据过大或过小等。

(3)输出阶段验证

对数据输出进行验证,包括对输出的数据文件及其加载等进行验证:

  • 检查转换规则是否被正确应用;
  • 输出结果的各项指标表现如何?
  • 检查数据是否完整、准确,数据是否被及时加载到目标系统中;
  • 用户可见的数据信息是否准确有序地呈现出来;
  • 可视化图表的展示是否正确、美观;
  • 通过将目标数据与 HDFS 文件系统数据进行比较来检查是否有数据损坏。

除此之外,只要是面对数据进行测试,就需要考虑数据的安全性、完整性、准确性、一致性等,例如:

  • 数据安全性,数据存储是否安全,备份的间隔时间是多少,备份的数据能否及时、完整得到的恢复;
  • 数据的完整性,数据各个维度是否覆盖了业务全部特性、数据的记录是否有丢失,或某条数据是否有部分字段信息丢失等。

但是为了提高测试效率,在进行功能测试而不是性能测试时,一般只选取少量典型的测试数据集进行测试,即选取那些能覆盖计算逻辑和边界场景的测试数据。这时就需要用到很普通的测试方法了,比如等价类划分、边界值分析方法和组合测试方法等。

人为构造的数据无论是在分布形态还是异常场景覆盖上都比不上真实的生产数据,而由于测试数据对异常场景的覆盖不足,在系统上线后,很有可能会导致算法失效或系统崩溃等严重问题。如果可能,要尽可能导入真实数据来进行测试。现在在大数据的性能测试中,流量回放就是人们开始采用的测试方法。

AI 的测试

人工智能的测试侧重算法验证学习模型评估特征项专项测试等,算法和模型的验证,会通过实验评估算法自身的度量指标,如准确率、灵敏度、召回率等进行验证,也会采用蜕变测试、模糊测试等方法来验证算法的可靠性和可解释性等。

  • 即使在 AI 领域的测试,过去所学的测试方法,也有用武之地,比如采用不同数据集进行多次验证,验证算法在不同数据下的表现、探究算法的边界、算法在边界会不会出现异常情况。
  • 可以采用白盒测试方法,基于算法的结构进行验证,如对神经元及其连接的覆盖,也可以采用黑盒方法,针对 AI 输出的结果进行验证。比如上面所说的图灵测试和 A/B 验证,A/B 测试将会在下一讲讨论。
  • AI 测试可以是手工测试,直接让测试人员来进行验证,比如图灵测试或直接让特定领域的专业人士(如李世石、柯洁和 AlphaGo 对弈等)来完成测试;也可以进行自动化测试,让它们自我博弈,如 AlphaGo 的下一代产品 AlphaZero。

AI 系统的白盒测试

以现在最流行的深度学习神经网络算法为例来讨论如何进行白盒测试,并参考一些学者的论文(如 Youcheng Sun 等的论文 Testing Deep Neural Networks)。深度神经网络包含许多层连接的节点或神经元(Neuron),如图 2 所示,一个简单的人工神经网络模型,含有多层感知器。

图2 简单的人工神经网络模型示意图

每个神经元接受输入值并生成输出值或输出矢量(激活值),每个连接都有权重,每个神经元都有偏差。根据输入值、输入连接的权重和神经元的偏向(Bias Unit,偏置单元),通过公式来计算输出值。传统的覆盖率度量对于神经网络并没有真正的用处,因为通常使用单个测试用例即可达到 100% 的语句覆盖率。 缺陷通常隐藏在神经网络本身中,所以必须采用全新的覆盖率度量方法,可以概括为 6 种度量方法。

  • 神经元覆盖(Neuron Coverage):激活的神经元的比例除以神经网络中神经元的总数,如果神经元的激活值超过零,则认为该神经元已被激活。
  • 阈值覆盖率(Threshold Coverage):超出阈值激活值的神经元的比例除以神经网络中神经元的总数,阈值介于 0 和 1 之间。
  • 符号变更覆盖率(Sign Change Coverage):用正激活值和负激活值激活的神经元的比例除以神经网络中神经元的总数。激活值零被视为负激活值。
  • 值变更覆盖率(Value Change Coverage):定义为激活的神经元的比例,其中其激活值相差超过变化量除以神经网络中神经元的总数。
  • 符号-符号覆盖率(Sign-Sign Coverage):如果可以显示通过更改符号的每个神经元分别导致下一层中的另一个神经元更改符号,而下一层中的所有其他神经元保持相同(即它们不更改符号),则可以实现一组测试的符号覆盖。从概念上讲,此级别的神经元覆盖率类似于 MC/DC(修正的条件/判定覆盖)。
  • 层覆盖(Layer Coverage):基于神经网络的整个层以及整个层中的神经元集合的激活值如何变化来定义测试覆盖率。

当前还没有成熟的商用工具来支持神经网络的白盒测试,但有几种实验性工具:

  • DeepXplore,专门用于测试深度神经网络,提出了白盒差分测试算法,系统地生成涵盖网络中所有神经元的对抗示例(阈值覆盖);
  • DeepTest,系统测试工具,用于自动检测由深度神经网络驱动的汽车的错误行为,支持 DNN 的符号-符号覆盖;
  • DeepCover,可以支持上述定义的所有覆盖率。

AI 系统的算法验证

不同类型算法的验证,其关注的模型评估指标也不同,比如人脸检测算法评估指标主要有准确率(Accuracy)、精确率(Precision)、召回率(Recall)等,其次,相同类型算法在不同应用场景其关注的算法模型评估指标也存在差异。比如在高铁站的人脸检索场景中,不太关注召回率,但对精确率要求高,避免认错人或抓错人,造成公共安全事件。但在海量人脸检索的应用场景中,愿意牺牲部分精确率来提高召回率。

算法验证中,还会有一堆指标需要验证,例如:

  • 受试者操作特征曲线(Receiver Operating Characteristic curve,ROC 曲线),以真阳性概率(TPR)为纵轴、假阳性概率(FPR)为横轴所构成的坐标图,它反映敏感性和特异性连续变化的综合指标,其上每个点反映出对同一信号刺激的敏感性,适用于评估分类器的整体性能,如图 3 所示;
  • AUC(Area Under the Curve)是 ROC 曲线的面积,用于衡量"二分类问题"机器学习算法性能(泛化能力);
  • P-R(Recall-Precision)曲线用来衡量分类器性能的优劣,如图 4 所示;
  • Kappa 系数:度量分类结果一致性的统计量,是度量分类器性能稳定性的依据,Kappa 系数值越大,分类器性能越稳定。

图3 ROC 曲线示意图

其中:

  • 真阳性概率( TPR(True Positive Rate)= TP/(TP+FN);
  • 假阳性概率 FPR(False Positive Rate = FP/(TN+FP);
  • TP(True Positive),预测类别是正例,真实类别是正例;
  • FP(False Positive),预测类别是正例,真实类别是反例;
  • TN(True Negative),预测类别是反例,真实类别是反例;
  • FN(False Negative),预测类别是反例,真实类别是正例。

而:

  • 预测值与真实值相同,记为 T(True);
  • 预测值与真实值相反,记为 F(False);
  • 预测值为正例,记为 P(Positive);
  • 预测值为反例,记为 N(Negative)。

图4 P-R 曲线示意图

算法测试的核心是对机器学习模型的泛化误差进行评估,为此使用数据测试集来测试学习模型对新样本的差别能力,即以测试数据集上的测试误差作为泛化误差的近似。测试人员使用的测试数据集,只能尽可能地覆盖正式环境用户产生的数据情况,发现学习模型的性能下降、准确率下降等问题。

这样,如何选取或设计合适的测试数据集,将成为算法验证的关键,一般要遵循下列 3 个原则。

  • 根据场景思考真实的数据情况,倒推测试数据集。例如,需要考虑模型评价指标、算法的实现方式、算法外的业务逻辑、模型的输入和输出、训练数据的分布情况等。
  • 测试数据集独立分布。开发者选择一个数据集,会分为训练数据集和验证数据集,而测试集不能来自开发那个数据集,而应该独立去收集或获取一个全新的数据集,这就是我们通常所说的,机器学习需要三个数据集。
  • 测试数据的数量和训练数据的比例合理,如果拥有百万数据,只需要 1000 条数据,便足以评估单个分类器,并且准确评估该分类器的性能。如果觉得还不够,可以选择 1 万条数据作为测试集。

除了上述算法模型评估指标,我们还常用 ROC、PR 曲线来衡量算法模型效果的好坏。

这一讲就讲到这里了,最后出一个思考题,学习完本讲之后,针对自动驾驶系统,可以列出其测试设计的几个要点吗?