目前网上还没有特别完整的神经网络代码单元测试的教程。即使像OpenAI这样的网站也只能通过盯着每一行并思考哪里出了问题来找到错误。显然,大多数人没有那种时间并且讨厌这样做。所以希望本教程能帮助您开始使用健壮的测试系统。我们先看一个简单的例子,试着找出下面代码中的错误。你看见了吗?网络实际上并没有堆叠。写这段代码的时候,我只是复制粘贴了slim.conv2d(…)这一行,修改了kernelsize,忘记修改实际的输入了。这其实是笔者一周前刚遇到的情况。这很尴尬,但也是一个重要的教训!由于以下原因,这些错误很难找到。代码不会崩溃、不会抛出异常,甚至不会变慢。网络仍然可以训练,损失会下降。经过几个小时的运行,数值又回到了糟糕的结果,让人摸不着头脑,不知道该如何修复。只有一个线索,最终验证错误,必须审查整个网络架构才能找到问题所在。显然,您需要一种更好的方法来执行此操作。我们如何提前预防,而不是在训练多天后才发现呢?这里可以清楚地注意到,层的值没有达到函数外的任何张量。在损失和优化器的情况下,如果这些张量从未被优化过,它们将保持其默认值。因此,我们可以通过简单地比较训练步骤前后值是否发生变化来检测这一点。哇。不到15行代码,至少保证所有创建的变量都能被训练。这个测试很简单但很有用。现在问题已解决,让我们尝试添加批量归一化。看看你是否能用眼睛看到虫子。你找到了吗?这个bug非常聪明。在tensorflow中,is_training对于batch_norm的默认值为False,所以在训练时加入这行代码会导致输入无法标准化!值得庆幸的是,我们刚刚添加的单元测试会立即捕捉到这一点!(它刚刚帮助我在3天前发现了这个问题。)让我们看另一个例子。这是我从reddit帖子中看到的。我们不会深入研究原始帖子,但简而言之,发帖人想要创建一个输出范围为0到1的分类器。看看你能不能看出问题所在。发现问题?这个问题很难发现,结果也很难理解。简而言之,由于预测只有一个输出值,应用softmax交叉熵函数后,损失将永远为0。发现这个问题最简单的测试是确保损失永远不等于0。测试我们的第一个实现也可以发现这种错误,但是我们需要反向检查:确保只训练需要训练的变量。以生成对抗网络(GAN)为例,一个常见的错误是在优化过程中不小心忘记设置需要训练哪个变量。像这样的代码无处不在。这段代码最大的问题是优化器默认优化所有变量。在像GAN这样的高级架构中,这意味着无限的训练时间。然而,检测这种错误只需要一个简单的测试:也可以为鉴别器编写一个相同类型的测试。同样的测试也可以应用于加强大量其他学习算法。许多actor-critic模型有不同的网络,需要用不同的损失进行优化。下面是作者推荐的一些测试模式。确保输入的确定性。找到一个你永远无法重现的奇怪的失败测试将是一件可怕的事情。在特别需要随机输入的场景下,一定要使用相同的随机数种子。这样,在失败后,您可以使用相同的输入再次重现它。确保你的测试是精简的。不要使用相同的单元测试来检查回归训练和检查验证集。这样做只是浪费时间。确保每次测试时都重置图形。总而言之,仍然有很多方法可以测试这些黑盒算法!花一个小时编写一个简单的测试可以节省几天的重新运行时间,并大大提高您的研究能力。一个天才的想法永远不会因为错误缠身的实施而无法成为现实。本文中列出的测试远未完成,但却是一个很好的起点!如果您找到特定类型的其他建议或测试,请在Twitter上给我发消息!我很想为这篇文章写续集。文章中的所有观点仅代表作者的个人经验,不受谷歌支持或赞助。查看英文原文https://medium.com/@keeper6928/how-to-unit-test-machine-learning-code-57cf6fd81765
