简介
很少有程序员不对这里或者那里所包含的人工智能编程所吸引,然而,许多对AI感兴趣的程序员很快就因其中包含的算法的复杂性而退却。在本文中,我们将讨论一个能大大简化这种复杂性的Java开源工程。
Java面向对象的神经网络(JOONE)是一开源工程,它提供给Java程序员一个高适应性的神经网络。该JOONE工程源代码由LGPL所保护。简言之,这意味着源代码是可自由使用的而且你不需要支付版税就可以使用JOONE。JOONE可以从http://joone.sourceforge.net/处下载。
JOONE能允许你轻易地从一个Java程序中创建神经网络。JOONE支持许多特征,如多线程和分布式处理。这意味着JOONE能利用多处理机计算机和多台计算机的优势来进行分布式处理。
神经网络
JOONE用Java实现了一个人工神经网络。一个人工神经网络试图仿效生物学神经网络的功能--神经网络组成今天在地球上几乎所有高等生命的大脑形式。神经网络由神经原组成。图1显示了一个实际神经原图。
图1:一个生物学的神经原
从图1中你可以看出,神经原由一个内核细胞和几个长长的称为触角的连接器组成。神经原之间依靠这些触角进行连接。无论是生物学的还是人工的神经网络,都通过触角把信号从一个神经原传递到另一个神经原来工作。
使用JOONE
在这篇文章中,你将看到一个简单的怎样使用JOONE的实例。神经网络题目涉及广泛并覆盖许多不同的应用领域。在本文中,我们将展示给你怎样使用JOONE来解决一个很简单的模式识别问题。模式识别是神经网络中的最普遍的应用之一。
模式识别提供给神经网络一种模式,判断是否该神经网络能够识别出该模式。这种模式应该能够在某种程度上被扭曲而该神经网络仍然能够识别它。这很像人类识别东西(如一个交通标志)的能力。人类应该能够识别在下雨天,晴天或者晚上的交通标志。即使这些图像看上去可能相当不同,但人类的大脑仍能够判断出它们是一样的图像。
当进行JOONE编程时,你一般要使用两种类型的对象。你要使用神经原层对象,用于描述一层的一个或多个的具有相似特征的神经原。神经网络经常有一层或两层神经元。这些神经元层通过触角联系在一起。这些触角把这种待识别的模式,从一个神经元层传输到另一个神经元层。
触角不仅把这种模式从一个神经元层传输到另一个神经元层。触角还将生成一些指向这种模式的元素的斜线。这些斜线将导致这种模式的某些元素在被传输到下一个神经元层时不如通过其它方式传递更有效些。这些斜线通常称为权重,它们形成神经网络的存储系统。通过调整存储在触角中的这些权重,可以更改神经网络的行为。
触角在JOONE中还承担着另外一个角色。在JOONE中,可以把触角看作是数据导管。正如触角把模式从一个神经元层传输到另一个神经元层,指定版本的触角用于把模式传入和传出神经网络。下面将给你展示一个简单的单层的神经网络是怎样被构建并进行模式识别的。
训练神经网络
为实现本文的目的,我们将指导JOONE去识别一个很简单的模式。在这种模式中,我们将考察一个二进制的布尔操作,例如XOR。这个XOR操作的真值表列举如下:
X
|
Y
|
X XOR Y
|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
// 首先,创造这三个层 input = new SigmoidLayer(); hidden = new SigmoidLayer(); output = new SigmoidLayer(); |
input.setLayerName("input"); hidden.setLayerName("hidden"); output.setLayerName("output"); |
input.setRows(2); hidden.setRows(3); output.setRows(1); |
// 输入-> 隐蔽的连接。 FullSynapse synapse_IH = new FullSynapse(); // 隐蔽-> 输出连接。 FullSynapse synapse_HO = new FullSynapse(); |
synapse_IH.setName("IH"); synapse_HO.setName("HO"); |
// 联接输入层到隐蔽层 input.addOutputSynapse(synapse_IH); hidden.addInputSynapse(synapse_IH); // 联接隐蔽层到输出层 hidden.addOutputSynapse(synapse_HO); output.addInputSynapse(synapse_HO); |
//创建监视器对象并且设置学习参数 monitor = new Monitor(); monitor.setLearningRate(0.8); monitor.setMomentum(0.3); |
学习速度和动力作为参数以用于指定训练的产生方式。JOONE利用backpropagation学习算法。要更多了解关于学习速度或者动力的信息,你应该参考backpropagation算法。
这个监视器对象应该被赋值给每一个神经原层。下面的代码实现这一点。
input.setMonitor(monitor); hidden.setMonitor(monitor); output.setMonitor(monitor); |
monitor.addNeuralNetListener(this); |
inputStream = new FileInputSynapse(); |
// 前两列包含输入值 inputStream.setFirstCol(1); inputStream.setLastCol(2); |
// 这是包含输入数据的文件名 inputStream.setFileName(inputFile.getText()); |
input.addInputSynapse(inputStream); |
trainer = new TeachingSynapse(); trainer.setMonitor(monitor); |
// 设置包含期望的响应值的文件,这由FileInputSynapse来提供 samples = new FileInputSynapse(); samples.setFileName(inputFile.getText()); |
//输出值在文件中的第三列上 samples.setFirstCol(3); samples.setLastCol(3); trainer.setDesired(samples); |
// 连接训练员到网络的最后一层 output.addOutputSynapse(trainer); |
input.start(); hidden.start(); output.start(); trainer.start(); |
monitor.setPatterns(4); monitor.setTotCicles(20000); monitor.setLearning(true); |
monitor.Go(); |
神经网络现在将要被训练20,000个周期。当神经网络训练完成,误差层应该在一个合理的低级别上。一般低于10%的误差级是可接受的。
运行神经网络
现在,既然神经网络已经训练开始,我们可以通过提供输入模式给神经网络来测试它并观察结果。用于运行神经网络的方法必须首先为神经网络处理数据作好准备。目前,该神经网络处理一种训练方式中。首先,我们将从输出层删除训练员。然后,我们将用FileOutputSynapse替换训练员,以便于我们能记录来自于神经网络的输出。下面的代码实现这一点:
output.removeOutputSynapse(trainer); FileOutputSynapse results = new FileOutputSynapse(); results.setFileName(resultFile.getText()); |
inputStream.resetInput(); samples.resetInput(); results.setMonitor(monitor); output.addOutputSynapse(results); |
input.start(); hidden.start(); output.start(); trainer.start(); |
monitor.setPatterns(4); monitor.setTotCicles(1); monitor.setLearning(false); |
monitor.Go(); |
当训练完成,你将看到输出文件产生的结果类似列表2。
列表2:来自于神经网络的输出
0.012549763955262739
0.9854631848890223
0.9853159647305264
0.01783622084836082
可以看出,上面列表中的第一行中的数字合理地接近于零。这是很好的,因为输入训练文件的第一行,如列表1所示,被预期结果是为零的。同样,第二行合理地接近于1,这也很好,因为训练文件的第二行被预期结果也是为1的。
结论
JOONE引擎封装了神经网络编程中的具有相当多的复杂性,本文的例子显示了神经网络使用的基本过程。尽管真实世界中神经网络的实现将复杂得多,但是其基本处理过程是一样的--数据被提供到神经网络用于训练,然后生成新的模式用于识别。这里的例程为用JOONE进行探索提供了一个良好的开端。
后记:joone提供了一个editor可以在gui的界面里面很快的开发出神经网络系统。由于我也是刚开始学习,推荐这个开源程序给大家。以后我也会发表更多的原创。希望大家多多交流