65.9K
CodeProject 正在变化。 阅读更多。
Home

基准测试和比较 Encog、Neuroph 和 JOONE 神经网络

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (8投票s)

2010年6月3日

LGPL3

8分钟阅读

viewsIcon

70868

downloadIcon

989

我比较了 Encog、Neuroph 和 JOONE 的性能

介绍 

在本文中,我将对 Neuroph、JOONE 和 Encog 进行基准测试。这三个主要的开源 Java 框架。Encog 也有 .NET 版本。我将为这三个框架分配相似的任务,并观察它们完成任务所需的时间。对于本文,我将比较以下版本。随着版本的更新,我将尽量保持本文的时效性。

我开始为我在大学的一个项目创建这个基准测试。我的教授分析他每天收到的地热信息。我们已经使用了一个神经网络一段时间,我们每周都会对其进行重新训练。我们目前使用的是基于 JOONE 的神经网络。如果您查看 我上一篇文章,您会发现,在 JOONE 中执行几乎任何操作所需的源代码比实际情况要复杂得多。此外,JOONE 已不再积极支持。更重要的是,JOONE 没有充分利用现代多核机器。我们想看看是否能将我们一天的训练周期缩短到一个更合理的水平。

所以我创建了这个基准测试来给我们一个概念。我们发现 Neuroph 和 Encog 都提供了从 JOONE 升级的途径。首先,我将回顾结果。然后,我将向您展示实现这一目标所需的代码。

神经网络以迭代的方式进行训练。每次迭代都使神经网络更接近期望的输出。在对神经网络进行基准测试时,实际上有两个方面需要考虑。首先,每次迭代的有效性如何。其次,处理一次迭代需要多长时间。

在我上一篇文章中,我评估了 Neuroph、JOONE 和 Encog 在训练迭代方面的有效性。JOONE 最差,学习简单的 XOR 操作需要超过 5,000 次迭代。Neuroph 的表现要好得多,仅需 613 次迭代。然而,真正的赢家是 Encog,它使用了比其他两个更先进的训练方法。Encog 仅需 18 次迭代即可完成。

因此,您必须同时考虑两者。例如,我最初只是比较 JOONE 和 Neuroph。我发现 Neuroph 比 JOONE 慢得多,但 Neuroph 更先进的训练弥补了这种缓慢,因为 Neuroph 只需 JOONE 完成任务所需的一小部分迭代。然而,Encog 彻底超越了 JOONE 和 Neuroph。Encog 可以有效地利用多核甚至您的显卡 (GPU) 来加速处理。但是,即使消除了这两者,Encog 完成 JOONE 和 Neuroph 每次迭代所需的时间也只是它们的一小部分。此外,Encog 可以在更少的迭代次数中训练到很高的误差率。因此,这对 Encog 来说是双重胜利。

我们实现了 Encog 来替换我们的 JOONE 解决方案。Encog 的框架非常易于使用。我能够删除 JOONE 代码并在大约一天内替换为 Encog。由于 Encog 的速度和高效的训练,我们一天完成的任务现在只需 20 分钟。因此,我们正在将我们的项目升级到 Encog。

我无法发布我教授的代码来演示这一点,但我正在发布我们的基准测试代码,希望它能对其他人有所帮助。本文展示了我们得到的结果。

基准测试任务

为了对神经网络进行基准测试,我创建了以下示例任务

输入神经元 10
输出神经元 10
隐藏层 1 神经元 20
激活函数 TANH
训练集大小 100,000 个元素
训练迭代次数 50
训练方法 带有动量的反向传播

重要的是使用带有动量的反向传播来保持一致。Encog 支持比这更先进的方法,正如我在上一篇文章中所述。但是,我们需要一种所有三个框架都支持的训练方法,所以它们基本上都在做同样的事情。这样我们就可以比较每个神经网络框架的效率。

基准测试计算机

使用的计算机是DellStudio XPS 8000。它配备了 Intel Core i7 860 @ 2.8 GHz。这是四核带超线程。您可以在此处查看系统显示。

pict1.png

本文的所有基准测试均使用此系统。

基准测试结果

此基准测试的结果显示在此处。所有结果单位均为秒。显然,值越低越好。

测试 结果
Encog 多线程版 0.9520
Encog 单线程版 3.1280
JOONE 多线程版 26.0430
JOONE 单线程版 17.8510
Neuroph 单线程版 39.7450

此处显示了一个演示此的图表

pict2.png

这里一个非常有趣的观察点是单线程与多线程的对比。多线程允许基准测试利用多核 CPU 的优势。只有 Encog 和 JOONE 支持多线程。尽管如此,在多核机器上运行 JOONE 的多线程模式实际上会使其变慢!这是在多核架构上测试代码的一个真实案例。仅仅因为您使用线程并不意味着您的应用程序会扩展。

Encog 几乎是碾压了这里的竞争。即使 Encog 被强制使用单线程,它的性能也远远优于其他。Encog 比 Neuroph 快约 40 倍,比 JOONE 快 17 倍。

功能网格

我还做了一个网格来比较神经网络的功能。Encog 在这里似乎也处于领先地位。尤其是在训练选项方面。

神经网络类型

                          JOONE    Neuroph     Encog

ADALINE                            *           *
ART1                                           *
BAM                                *           *
Boltzmann Machine                              *
CPN                                *           *    
Elman SRN                 *                    *
Perceptron                *        *           *
Hopfield                           *           *
Jordan SRN                         *           *
NEAT                               *1          *2
RBF                                *           * 
Recurrent SOM                                  *
Kohonen/SOM                        *           *
NeuroFuzzy Perceptron              *
Hebbian Network                    *           *

*1 Experimental in preview release(release ???)
*2 Supported in Encog 2.4(currently in beta, release for late June 2010).

激活/传递函数

                          JOONE    Neuroph     Encog
Sigmoid                   *        *           * 
HTAN                      *        *           *
Linear                    *        *           * 
SoftMax                   *                    *
Step                      *        *           *
Bipolar/Sgn                                    *
Gaussian                           *           *
Log                       *        *           *
Sin                       *                    *
logarithmic               *                    *
Ramp                               *           *
Trapezoid                          *

随机化技术

                          JOONE    Neuroph     Encog
Range                     *        *           *
Gaussian                                       *
Fan-In                    *                    *
Nguyen-Widrow                                  *

训练技术

                          JOONE    Neuroph     Encog
Annealing                                      *
Auto Backpropagation               *           *
Backpropagation           *        *           *
Binary Delta Rule                  *
Resilient Prop            *                    *
Hebbian Learning                   *           *
Scaled Conjugate Grd                           *
Manhattan Update                               *
Instar/Outstar                     *           *
Kohonen                   *        *           *
Hopfield                           *           *
Levenberg Marquardt (LMA)                      *
Genetic                                        *
Instar                             *           *
Outstar                            *           *
ADALINE                                        *

其他特性

                          JOONE    Neuroph     Encog
Multithreaded Training    *                    *
GPU/OpenCL                                     *
Platforms                 Java     Java        Java/.Net/Silverlight
Year Started              2001     2008        2008  

实现基准测试

现在我们已经回顾了基准测试的结果,我将向您展示它是如何实际构建的。

Benchmarkable 接口

我首先创建了一个简单的接口,名为 Benchmarkable。该接口定义了一个我将与 Encog、Neuroph 和 JOONE 一起使用的基准测试。接口如图所示

public interface Benchmarkable {
  void prepareBenchmark(double[][] input, double[][] ideal);
  double benchmark(int iterations);
}

如您所见,有两个方法。第一个方法称为 prepareBenchmark。此方法使用输入和理想数组进行调用。我只对使用监督学习的框架进行基准测试。此方法允许框架创建必要的对象来训练神经网络。我们不希望计算设置时间。神经网络可以训练数天。我真的不在乎一个框架是否需要几秒钟的时间来设置。实际的基准测试是在 benchmark 方法中完成的。此方法在框架完成训练之前不会返回。因此,我们将衡量此方法执行的时间。我们还返回最终的误差率。

生成数据

这是使用 GenerateDataclassgenerate 方法完成的。您可以在此处查看方法签名。

public
void generate(final int count, final int inputCount,
final int idealCount, final double min, final double max) {

count 参数告诉神经网络应该创建多少个训练集元素。每个训练集元素都是一对数组。inputCount 参数指定输入数组的大小。idealCount 参数指定输出数组的大小。这两个数组会被分配。

this.input = new double[count][inputCount];
this.ideal = new double[count][idealCount];

我们现在将遍历指定的 count 并生成随机训练数据。随机训练数据就可以了。神经网络永远无法真正学会预测随机数字。这是不可能的。它永远无法获得好的误差率。误差率是神经网络的实际输出与提供的理想输出匹配的程度。我们不测量一个框架能够减少多少误差。我们稍后会这样做。现在,我们只想看看每个框架执行 50 次迭代需要多长时间。神经网络是使用迭代来训练的,每次迭代都试图降低误差率。通常,您会使用远超过 50 次的迭代,但是,这足以看出网络的相对速度。

for(int i = 0; i < count; i++) {

接下来我们生成随机输入和理想数据。

for(int j = 0; j < inputCount; j++) {
input[i][j] = randomRange(min,max);
}

for(int j = 0; j < idealCount; j++) {
ideal[i][j] = randomRange(min, max);
}

使用以下代码准备基准测试。我们将随机训练数据放入数组并准备基准测试。

public static void time(String title, Benchmarkable run)
{
  GenerateData data = new GenerateData();
  data.generate(10000, Benchmark.INPUT_COUNT, Benchmark.OUTPUT_COUNT, -1, 1);
  double[][] input = data.getInput();
  double[][] ideal = data.getIdeal();
  run.prepareBenchmark(input, ideal);
  
  long started = System.currentTimeMillis();
  run.benchmark(50);
  long finish = System.currentTimeMillis();
  long elapsed = finish-started;
  double e2 = elapsed/1000.0;
  NumberFormat f = NumberFormat.getNumberInstance();
  f.setMinimumFractionDigits(4);
  f.setMaximumFractionDigits(4);
  System.out.println(f.format(e2) + " seconds for " + title );
}

然后,我们使用 Stopwatch 类来实际执行基准测试。

基准测试会遍历并计时每个网络在迭代循环中的情况。如果您想了解如何编程这三种神经网络类型,您应该查看我的上一篇文章,其中对此进行了介绍。

结论

从我的两篇文章可以看出,明显的赢家是 Encog。它提供了一个清晰易用的 API 和惊人的性能。Encog 的性能目前是无与伦比的。

Neuroph 是一个有趣的项目,在 Sourceforge 上拥有非常活跃的社区。我认为 Neuroph 具有巨大的潜力,但它不像 Encog 那样先进。Neuroph 的目标之一是易于使用。查看其内部代码,他们做得很好。我可以比 Encog 更容易地理解 Neuroph 的内部代码。如果您将在框架内部工作,这一点可能很重要。然而,使用框架的 API,我实际上并没有看到 Encog 和 Neuroph 之间在复杂性上有太大差异。这一点在我 之前的文章 中得到了说明。 

JOONE 在技术上比 Neuroph 快。但是,如果您在 Neuroph 中使用自动反向传播,JOONE 的速度优势就真的不再那么重要了。它们的净速度大致相同。由于 JOONE 缺乏支持和接口的复杂性,我真的不推荐 JOONE。

基准测试和比较 Encog、Neuroph 和 JOONE 神经网络 - CodeProject - 代码之家
© . All rights reserved.