本章我们将学习以下内容:
l 什么是微基准测试
l 如何将它应用到代码中
l 什么是激活函数
l 如何绘制和基准测试激活函数
每个开发人员都需要有一个好的基准测试工具。质量基准无处不在;你们每天都能听到,这个减少了10%那个增加了25%还记得那句老话吗,当你听到一个数字被抛出时,98.4%的情况下这个数字是假的。顺便说一下,这个数字也是我编的。当你听到这样的话,让那个人证明一下,你会得到什么?我们不需要定性的结果;我们需要能够被证明和持续复制的量化结果。可重复的结果是非常重要的,不仅对一致性,而且对可信度和准确性。这就是微基准测试发挥作用的地方。
我们将使用BenchmarkDotNet库,您可以在这里找到:https://github.com/dotnet/BenchmarkDotNet。我认为它是您可以使用的最不可替代的框架之一,我认为它的重要性不亚于单元测试和集成测试
为了展示这个工具的价值,我们将绘制几个激活函数并比较它们的运行时。作为其中的一部分,我们将考虑预热、遗留和RyuJIT、冷启动以及程序执行的更多方面。最后,我们会得到一组定量的结果来证明函数的精确度量。如果在2.0版本中,我们看到某些东西运行得比较慢,我们可以重新运行基准并进行比较。
我强烈建议将其集成到您的持续集成/持续构建过程中,以便在每个版本中都可以比较基准数据。
在本章中,我们将有两个样本。第一个是激活函数查看器;它将绘制每个激活函数,以便我们可以看到它的外观。可以在Colin Green的SharpNEAT中找到它,它是开源的。这个包绝对是不可思议的。我在它的基础上创建了新的ui以及高级版本来满足我的需求,它是目前能找到的最灵活的工具。第一个示例应用程序带有最新的SharpNEAT包,可以在https://github.com/colgreen/sharpneat找到它。
下面是一个局部和全局最小值的图,它是由SharpNEAT的自定义版本绘制的。
如前所述,我们将绘制并测试几个激活函数。我们到处都听到激活函数这个词,但我们真的知道它的意思吗?让我们从一个快速的解释开始。
一个激活函数用来决定一个神经元是否被激活。有些人喜欢用fired来代替activated。不管怎样,它最终决定了某个东西是开还是关,是被触发还是没有,是被激活还是没有。
.让我们首先看一个单个激活函数的图:
这是逻辑陡峭近似和Swish激活函数单独绘制时的样子,因为有很多类型的激活函数,这是我们所有的激活函数一起绘制时的样子:
在这一点上,你可能会想,我们为什么还要关心情节是什么样的呢?好问题。我们关心这些,因为一旦你进入神经网络或其他领域,你会经常用到这些。这是非常方便的,能够知道你的激活函数是否将你的神经元的值在开或关的状态,以及它将保持或需要的值在什么范围内。毫无疑问,你将在作为机器学习开发人员的职业生涯中遇到和/或使用激活函数,了解TanH和LeakyReLU激活函数之间的区别非常重要。
所有激活函数的绘图都是在一个函数内完成的,这个函数名为PlotAllFunctions:
在后台,Plot函数负责执行和绘制每个函数:
这是执行我们传入的激活函数的地方,它的值用于y轴标绘值。著名的ZedGraph开源绘图包用于所有图形绘制。一旦执行了每个函数,就会生成相应的图。
BenchmarkDotNet生成了几个报告,其中一个是HTML报告,类似于在这里看到的:
Excel报告提供了运行程序时使用的每个参数的详细信息,是最广泛的信息来源。在很多情况下,这些参数中的大多数都使用默认值,超出了我们的需要,但至少我们可以选择删除我们需要删除的内容:
我们将在下一节中描述其中的一些参数,当我们回顾创建之前看到的内容的源代码时:
让我们进一步分析这段代码:
首先,我们将创建一个手动配置对象,其中包含用于基准测试的配置参数:
接下来,我们将设置一个导出器来保存用于导出结果的参数。我们将使用微秒计时和千字节大小将结果导出到.csv文件:
接下来,我们将创建一个基准作业,它将处理x64体系结构上LegacyJitX64的度量。您可以随意更改此参数和任何其他参数,以进行实验,或者包含测试场景所需或需要的任何结果。在我们的例子中,我们将使用x64平台;启动计数、预热计数和目标计数为1;以及吞吐量的运行策略。我们也会对RyuJIT做同样的事情,但是我们不会在这里显示代码:
最后,我们将运行BenchmarkRunner来执行我们的测试:
BenchmarkDotNet将作为DOS命令行应用程序运行,下面是执行上述代码的一个例子:
让我们来看一个被绘制的激活函数的例子:
此处使用了[Benchmark]属性。这向BenchmarkDotNet表明,这将是一个需要进行基准测试的测试。在内部调用如下函数:
对于logisticfunction陡峭函数,其实现与大多数激活函数一样简单(假设你知道公式)。在这种情况下不是绘制激活函数,而是对其进行基准测试。
你将注意到函数接受并返回double。我们也通过使用和返回浮点变量对相同的函数进行基准测试,因此我们使用double对函数之间的差异进行基准测试和浮动。因此,人们可以看到,有时性能影响比他们想象的要大:
在本章中,我们学习了如何将微基准测试应用到代码中。我们还了解了如何绘制和基准测试激活函数,以及如何使用微基准测试。现在,您有了一个最强大的基准测试库,可以将其添加到所有代码中。在下一章中,我们将深入探讨直观的深度学习,并向您展示c#开发人员可以使用的最强大的机器学习测试框架之一。
“老天爷给你的任何机会,你也不会珍惜,更不会深入下去,你认为自己就是穷命,最喜欢通过脉脉阅读免费的职场技巧。如果你还是杠精思维,任何事情,跑上来先论证困难,给自己一个不干不参与的充分理由,那你完了。人生不过是短短十五年的机会,到了四十岁,你还在屌丝堆里,啥也不干,那你没希望了。”