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

Java 的 Encog 神经网络入门

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (9投票s)

2010年1月17日

LGPL3

6分钟阅读

viewsIcon

80165

downloadIcon

2170

介绍如何使用 Encog 框架为 Java 创建神经网络。

XorExample

引言

本文档提供了使用 Encog 人工智能框架进行神经网络和神经网络编程的基础入门。Encog 是一个适用于 Java 和 Microsoft .NET 的 AI 框架。在本文档中,我将向您展示如何使用 Encog 创建和训练一个非常基础的神经网络。将来我可能会发布更多复杂的神经网络示例。然而,目前,本文档将向您展示如何开始使用 Encog。

背景

Encog 是一个高级人工智能框架。使用 Encog,您可以创建高级神经网络应用程序。尽管 Encog 支持人工智能编程的其他方面,但本文档将重点关注神经网络编程。自 2.3 版本以来,神经网络编程是 Encog 的主要关注点。Encog 在 LGPL(GNU 通用公共许可证)下发布。您可以从以下 URL 下载 Encog:http://www.heatonresearch.com/encog/

这是一个简单的入门示例,展示了如何创建一个能够识别 XOR 运算符的神经网络。XOR 运算符本质上是神经网络界的“Hello World”。它通常用于演示新的神经网络。

在我向您展示如何在 Encog 中创建神经网络之前,了解神经网络的工作原理非常重要。几乎所有的神经网络都包含层。层是行为相似的神经元分组。Encog 支持的不同类型的神经网络使用许多不同的层类型。然而,几乎每个神经网络都会有两层非常重要的层:输入层和输出层。输入层是您向神经网络输入数据的方式。输出层是您从神经网络获取响应的方式。

神经网络的输入和输出都是 Java `double` 值,即普通的浮点数。输入层和输出层都将具有一定数量的神经元。这决定了该层将处理多少个浮点数。输入层和输出层通常会有不同数量的神经元。决定输入层和输出层的结构就是您定义要解决的“问题”到神经网络的方式。

让我们看看如何创建一个能够执行 XOR 运算符的神经网络。XOR 运算符要求两个输入不同时,输出才为真。XOR 运算符的真值表可以表示如下:

0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0

我现在想创建一个能够执行此运算符的神经网络。这样的网络将有两个输入神经元和一个输出神经元。它将接受两个操作数并返回结果。

Using the Code

我们现在将看看这个示例的代码是如何构造的。此示例是用 Encog v2.3 创建的,这是撰写本文时 Encog 的当前版本。Encog 2.3 JAR 文件随本示例的下载一起提供。但是,您可能希望从本文档前面提供的 URL 下载最新的 Encog JAR。

神经网络必须经过训练才能使用。要训练此神经网络,我们必须提供训练数据。训练数据是 XOR 运算符的真值表。XOR 的输入如下:

public static double XOR_INPUT[][] = { 
  { 0.0, 0.0 }, 
  { 1.0, 0.0 },
  { 0.0, 1.0 }, 
  { 1.0, 1.0 } };

这些是 XOR 运算符的所有可能输入。同样,预期的输出也存储为数组。

public static double XOR_IDEAL[][] = { 
  { 0.0 }, 
  { 1.0 }, 
  { 1.0 }, 
  { 0.0 } };

这两个数组将被组合起来创建 XOR 运算符的训练数据。以下代码行将这两个数组组合起来创建训练数据:

NeuralDataSet trainingSet = new BasicNeuralDataSet(XOR_INPUT, XOR_IDEAL);

我们现在必须创建一个神经网络。以下代码行完成了这项工作:

BasicNetwork network = new BasicNetwork();

network.addLayer(new BasicLayer(new ActivationSigmoid(), true,2));
network.addLayer(new BasicLayer(new ActivationSigmoid(), true,4));
network.addLayer(new BasicLayer(new ActivationSigmoid(), true,1));
network.getStructure().finalizeStructure();
network.reset();

您可以看到正在创建的三个层。上面的三个 `addLayer` 方法创建了这三个层。第一层是输入层,它有两个神经元。最后创建的层是输出层,它有一个神经元。中间创建的层称为隐藏层。隐藏层有助于神经网络学习。必须添加更多的隐藏神经元才能让神经网络学习更复杂的模式。四个隐藏神经元对于 XOR 运算符来说绰绰有余。选择隐藏神经元的数量通常是一个反复试验的过程。

调用上面的 `reset` 方法会随机化网络中所有神经元之间的权重。这些随机权重将无法使神经网络充当 XOR 运算符。然而,我们稍后将看到的训练过程将改进这些权重,并促使神经网络产生类似于 XOR 运算符的输出。

`ActivationSigmoid` 类指定要使用的激活类型。Sigmoid 函数是一个不错的选择,因为我们在 XOR 运算符中不使用负值。如果网络需要识别负值,双曲正切激活函数会更合适。Encog 支持许多不同的激活函数,它们都有其独特的用途。

必须创建一个训练对象来训练神经网络。Encog 支持多种不同的训练方法。有些用于特定的神经网络类型。有些在不同类型的数据上表现更好。对于这种类型的神经网络,最佳的“通用”训练器称为 RPROP(弹性传播)。以下代码创建了一个 RPROP 训练器:

final Train train = new ResilientPropagation(network, trainingSet);

创建训练器后,我们应该进行一系列迭代。每次迭代都会使神经网络更接近于充当 XOR 运算符的功能。

int epoch = 1;

do {

  train.iteration();
  System.out.println("Epoch #" + epoch + 
                     " Error:" + train.getError());
  epoch++;

} while(train.getError() > 0.01);

在每次迭代(或周期)中,我们检查误差。我们持续进行,直到误差小于 1%。误差定义了神经网络的输出与前面定义的理想输出之间的差距。

一旦神经网络经过令人满意的训练,我们将对其进行使用。我们将把每个输入馈送到神经网络并观察输出。以下代码执行此操作:

System.out.println("Neural Network Results:");

for(NeuralDataPair pair: trainingSet ) {

  final NeuralData output = network.compute(pair.getInput());
  System.out.println(pair.getInput().getData(0) + 
         "," + pair.getInput().getData(1)  + 
         ", actual=" + output.getData(0) + 
         ",ideal=" + pair.getIdeal().getData(0));

}

我们遍历每个训练数据项,并显示神经网络的输出以及实际输出。程序的输出显示如下:

Epoch #1 Error:0.5494587158070631
Epoch #2 Error:0.5494587158070631
Epoch #3 Error:0.5142230676643447
Epoch #4 Error:0.5005001549387983
Epoch #5 Error:0.5004690225170658
Epoch #6 Error:0.5004317073796488
...
Epoch #40 Error:0.026928155758252966
Epoch #41 Error:0.014605778809936418
Epoch #42 Error:0.007180166468750018
Neural Network Results:
0.0,0.0, actual=0.003348914814615583,ideal=0.0
1.0,0.0, actual=0.995118794356202,ideal=1.0
0.0,1.0, actual=0.9999200785659956,ideal=1.0
1.0,1.0, actual=8.741041885168623E-4,ideal=0.0

正如您所看到的,神经网络会经过多次迭代,直到误差百分比降至 1% 以下。经过 42 次迭代后,网络训练完成。当您运行应用程序时,它可能需要更多或更少的时间,因为神经网络从随机权重开始。

完成后,您将看到神经网络的实际输出。神经网络的输出并不完全匹配理想输出。这是预料之中的。但是,值 0.99 非常接近 1.0。

关注点

本文档演示了一个非常简单的神经网络应用程序。使用神经网络来创建 XOR 运算符是杀鸡焉用牛刀。Encog 提供了许多更复杂的示例。我可能会在此撰写更多文章,演示 Encog 的一些更高级的功能。

神经网络的一个有趣之处在于,它的创建方式与传统程序完全不同。对于传统程序,您需要考虑如何实现 XOR 运算符并创建所有必要的编程逻辑来实现它。对于神经网络,您只需提供输入示例和预期输出。由神经网络决定如何提供这些预期输出。通常,您实际上不知道它实际上是如何学习提供其输出的。对于可能包含数百个神经元的大型神经网络尤其如此。

© . All rights reserved.