代码之家  ›  专栏  ›  技术社区  ›  forefinger

单元测试机器学习代码

  •  26
  • forefinger  · 技术社区  · 16 年前

    显然,正确的做法是添加单元测试,但不清楚如何做到这一点。我的程序中的许多组件都会产生某种主观的答案,我无法自动进行健全性检查。

    例如,我有一些代码可以用较低分辨率的曲线近似一条曲线,这样我就可以在较低分辨率的曲线上进行计算密集型工作。我无意中在这段代码中引入了一个bug,只有在我的整个程序的结果变得稍微糟糕时,我才通过艰苦的搜索找到它。

    6 回复  |  直到 16 年前
        1
  •  12
  •   APC    7 年前

    您可能不理解其中的讽刺,但基本上您拥有的是遗留代码:一块没有任何单元测试的软件。当然你不知道从哪里开始。因此,阅读处理遗留代码的相关知识可能会有所帮助。

    关于这一点的权威思想是Michael Feather的书, 修改代码的艺术 . ObjectMentor网站上曾经有一个有用的总结,但遗憾的是,该网站已经走上了公司的道路。然而,WELC在评论和其他文章中留下了遗产。 Check them out (or just buy the book)


    2019年更新:我已经用Wayback机器web存档中的版本修复了WELC摘要的链接(谢谢@milia)。

    a new (2019 new) Google tutorial on Testing and Debugging ML code

        2
  •  12
  •   S.Lott    16 年前

    “那么,我并不是真的在测试所有可能出错的事情。”

    对的

    单元测试的工作是 检验 这可能会出错。

    单元测试的工作是测试您所拥有的功能是否正确 正确的

    什么也不能 所有可能出错的事情。你可以写一个证明,但你将很难为它写测试 一切 .

    明智地选择测试用例。

    此外,单元测试的工作是测试整个应用程序的每个小部分是否独立地做正确的事情。

    例如,您的“低分辨率曲线上的计算密集型工作”可能有几个小部分可以作为单独的单元进行测试。孤立地。

    单元测试的重点是创建稍后组装的小而正确的单元。

        3
  •  11
  •   tvanfosson    16 年前

    如果没有看到您的代码,很难判断,但我怀疑您试图以过高的级别编写测试。您可能想考虑将您的方法分解为更小的确定性组件,并对其进行测试。然后通过提供模拟实现来测试使用这些方法的方法,模拟实现从底层方法(可能位于不同的对象)返回可预测的值。然后,您可以编写涵盖各种方法领域的测试,确保覆盖所有可能的结果。对于小方法,可以通过提供表示输入域的值来实现。对于依赖于这些的方法,通过提供从依赖项返回结果范围的模拟实现。

        4
  •  7
  •   0xfe    16 年前

    您的单元测试需要使用某种 ,或者通过接受近似值,或者使用某种概率检查。

    例如,如果您有一个返回浮点结果的函数,那么几乎不可能编写一个能够在所有平台上正常工作的测试。您的检查需要执行近似。

    TEST_ALMOST_EQ(result, 4.0);
    

    TEST_ALMOST_EQ result

    或者,如果您的机器学习算法是概率的,那么您的测试将需要通过计算多次运行的平均值并期望其在一定范围内来适应它。

    x = 0;
    for (100 times) {
      x += result_probabilistic_test();
    }
    
    avg = x/100;
    TEST_RANGE(avg, 10.0, 15.0);
    

    当然,这些测试是不确定的,所以您需要对它们进行调优,以便能够以高概率获得非脆弱的测试(例如,增加试验次数或增加误差范围)。

    您也可以为此使用mock(例如,概率算法的mock随机数生成器),它们通常有助于确定性地测试特定的代码路径,但需要花费大量精力来维护。理想情况下,您可以使用 模糊测试 和嘲笑。

    嗯。

        5
  •  1
  •   Joel    16 年前

    一般来说,对于统计度量,您将为您的答案构建一个ε。即,您的积分的均方差为<0.01或类似值。另一个选择是运行几次,如果“太频繁”失败,那么您就有问题了。

        6
  •  0
  •   Tobias Domhan    13 年前
    1. 计算此数据集的某些指标(例如精度)
    2. 记下获得的值(交叉验证)
    3. 这应该给出设置阈值的指示

    推荐文章