用Java开源项目JOONE实现人工智能编程

http://www.robotsky.com/ZhiN/MoS/2011-08-25/13142461416649.html

http://www.robotsky.com  来源:网络   时间:2011-08-25   评论 0 条

 (访问论坛) RobotSky恭候您的投稿>>

很少有程序员不对这里或者那里所包含的人工智能编程所吸引,然而,许多对AI感兴趣的程序员很快就因其中包含的算法的复杂性而退却。在本文中,我们将讨论一个能大大简化这种复杂性的Java开源工程。

  Java面向对象的神经网络(JOONE)是一开源工程,它提供给Java程序员一个高适应性的神经网络。该JOONE工程源代码由LGPL所保护。简言之,这意味着源代码是可自由使用的而且你不需要支付版税就可以使用JOONE。JOONE可以从http://joone.sourceforge.net/处下载。

JOONE能允许你轻易地从一个Java程序中创建神经网络。JOONE支持许多特征,如多线程和分布式处理。这意味着JOONE能利用多处理机计算机和多台计算机的优势来进行分布式处理。

  神经网络

  JOONE用Java实现了一个人工神经网络。一个人工神经网络试图仿效生物学神经网络的功能--神经网络组成今天在地球上几乎所有高等生命的大脑形式。神经网络由神经原组成。

从图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

  正如你从上表中看到的,XOR运算的结果是只有当X和Y具有不同值时,结果才为真(1)。其它情况下,XOR运算结果均为假(0)。默认地,JOONE从存储在你的系统中的文本文件中取得输入。这些文本文件通过使用一种称为FileInputSynapse的特殊触角来读取。为了训练XOR运算问题,你必须建立一个输入文件-该文件包含上面显示的数据。该文件显示在列表1中。

  列表1:为解决XOR问题的输入文件的内容

0.0;0.0;0.0
0.0;1.0;1.0
1.0;0.0;1.0
1.0;1.0;0.0

  我们现在分析一个简单的程序,它指导JOONE来识别XOR运算并产生正确的结果。我们现在分析训练该神经网络必须被处理的过程。训练过程包括把XOR问题提交给神经网络,然后观察结果。如果这个结果不是所预期的,该训练算法将调整存储在触角中的重量。在神经网络的实际输出和预料的输出之间的差距称为误差。训练将继续到误差小于一个可接受值为止。这个级别通常是一个百分数,如10%。我们现在分析必须用于训练一个神经网络的代码。

  训练过程通过建立神经网络开始,同时也必须创建隐蔽的输入层和输出层。

// 首先,创造这三个层
input = new SigmoidLayer();
hidden = new SigmoidLayer();
output = new SigmoidLayer();

  每个层被使用JOONE对象SigmoidLayer创建。Sigmoidlayer基于自然对数生成一个输出。JOONE还包含另外的层,而不是你可能选择使用的S形的层类型。

  下一步,每一层被赋于一个名字。这些名字将有助于后面在调试期间识别该层。

input.setLayerName("input");
hidden.setLayerName("hidden");
output.setLayerName("output");

  现在必须定义每个层。我们将指定在每一层中的"行"号。该"行"号对应于这一层中的神经原的数目。

input.setRows(2);
hidden.setRows(3);
output.setRows(1);

  从上面的代码看出,输入层有两个神经原,隐蔽层有三个隐蔽神经原,输出层包含一个神经原。这对于神经网络包含两个输入神经原和一个输出神经原是具有重要意义的,因为XOR运算符接收两个参数而产生一个结果。

  为使用该神经原层,我们也必须创建触角。在本例中,我们要使用多个触角。这些触角用下面的代码实现。

// 输入-> 隐蔽的连接。
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);

  就象许多Java对象本身一样,JOONE监视器允许听者可以添加到它上面去。随着训练的进行,JOONE将通知听者有关训练进程的信息。在这个简单的例子中,我们使用:

monitor.addNeuralNetListener(this);

  我们现在必须建立输入触角。如前所述,我们将使用一个FileInputSynapse来读取一个磁盘文件。磁盘文件不是JOONE唯一能够接受的输入种类。JOONE对于不同的输入源具有很强的灵活性。为使JOONE能够接收其它输入类型,你只需创建一个新的触角来接受输入。在本例中,我们将简单地使用FileInputSynapse。FileInputSynapse首先被实例化。

inputStream = new FileInputSynapse();

  然后,必须通知FileInputSynapse要使用哪些列。列表1中显示的文件使用了输入数据的前两列。下面代码建立起前两列用于输入到神经网络。

// 前两列包含输入值
inputStream.setFirstCol(1);
inputStream.setLastCol(2);

  然后,我们必须提供输入文件的名字,这个名字直接来源于用户接口。然后,提供一个编辑控件用于收集输入文件的名字。下面代码为FileInputSynapse设置文件名。

// 这是包含输入数据的文件名
inputStream.setFileName(inputFile.getText());

  如前所述,一个触角仅是一个神经原层之间的数据导管。FileInputSynapse正是这里的数据导管,通过它数据进入到神经网络。为了更容易实现这点,我们必须要把FileInputSynapse加到神经网络的输入层。这由下面一行实现。

input.addInputSynapse(inputStream);

  现在既然已经建立起神经网络,我们必须创建一个训练员和一个监视器。训练员用于训练该神经网络,因为该监视器通过一个事先设置好的训练重复数来运行这个神经网络。对于每一次训练重复,数据被提供到神经网络,然后就可以观察到结果。该神经网络的权重(存储在穿梭在神经原层之间的触角连接中)将根据误差作适当调整。随着训练的进行,误差级将下降。下列代码建立训练员并把它依附到监视器。

trainer = new TeachingSynapse();
trainer.setMonitor(monitor);

  你会记得列表1中提供的输入文件包含三个列。到目前为止,我们仅仅使用了第一、二列,它们指定了到神经网络的输入。第三列包含当提供给神经网络第一列中的数字时的期盼的输出值。我们必须使得训练员能够存取该列以便能确定误差。该错误是神经网络的实际输出和期盼的输出之间的差距。下列代码创建另外一个FileInputSynapse并作好准备以读取与前面相同的输入文件。

// 设置包含期望的响应值的文件,这由FileInputSynapse来提供
samples = new FileInputSynapse();
samples.setFileName(inputFile.getText());

  这时,我们想指向在第三列的FileInputSynapse。下列代码实现了这一点,然后让训练员使用这个FileInputSynapse。

//输出值在文件中的第三列上
samples.setFirstCol(3);
samples.setLastCol(3);
trainer.setDesired(samples);

  最后,训练员被连结到神经网络输出层,这将使训练员接收神经网络的输出。

// 连接训练员到网络的最后一层
output.addOutputSynapse(trainer);

  我们现在已为所有的层准备好后台线程,包括训练员。

input.start();
hidden.start();
output.start();
trainer.start();

  最后,我们为训练设置一些参数。我们指定在输入文件中共有四行,而且想训练20,000个周期,而且还在不段学习。如果你设置学习参数为false,该神经网络将简单地处理输入并不进行学习。我们将在下一节讨论输入处理。

monitor.setPatterns(4);
monitor.setTotCicles(20000);
monitor.setLearning(true);

  现在我们已经为训练过程作好准备。调用监视器的Go方法将在后台启动训练过程。

monitor.Go();

  神经网络现在将要被训练20,000个周期。当神经网络训练完成,误差层应该在一个合理的低级别上。一般低于10%的误差级是可接受的。

训练神经网络

  为实现本文的目的,我们将指导JOONE去识别一个很简单的模式。在这种模式中,我们将考察一个二进制的布尔操作,例如XOR。这个XOR操作的真值表列举如下:


X

Y

X XOR Y
0 0 0
0 1 1
1 0 1
1 1 0

  正如你从上表中看到的,XOR运算的结果是只有当X和Y具有不同值时,结果才为真(1)。其它情况下,XOR运算结果均为假(0)。默认地,JOONE从存储在你的系统中的文本文件中取得输入。这些文本文件通过使用一种称为FileInputSynapse的特殊触角来读取。为了训练XOR运算问题,你必须建立一个输入文件-该文件包含上面显示的数据。该文件显示在列表1中。

  列表1:为解决XOR问题的输入文件的内容

0.0;0.0;0.0
0.0;1.0;1.0
1.0;0.0;1.0
1.0;1.0;0.0

  我们现在分析一个简单的程序,它指导JOONE来识别XOR运算并产生正确的结果。我们现在分析训练该神经网络必须被处理的过程。训练过程包括把XOR问题提交给神经网络,然后观察结果。如果这个结果不是所预期的,该训练算法将调整存储在触角中的重量。在神经网络的实际输出和预料的输出之间的差距称为误差。训练将继续到误差小于一个可接受值为止。这个级别通常是一个百分数,如10%。我们现在分析必须用于训练一个神经网络的代码。

  训练过程通过建立神经网络开始,同时也必须创建隐蔽的输入层和输出层。

// 首先,创造这三个层
input = new SigmoidLayer();
hidden = new SigmoidLayer();
output = new SigmoidLayer();

  每个层被使用JOONE对象SigmoidLayer创建。Sigmoidlayer基于自然对数生成一个输出。JOONE还包含另外的层,而不是你可能选择使用的S形的层类型。

  下一步,每一层被赋于一个名字。这些名字将有助于后面在调试期间识别该层。

input.setLayerName("input");
hidden.setLayerName("hidden");
output.setLayerName("output");

  现在必须定义每个层。我们将指定在每一层中的"行"号。该"行"号对应于这一层中的神经原的数目。

input.setRows(2);
hidden.setRows(3);
output.setRows(1);

  从上面的代码看出,输入层有两个神经原,隐蔽层有三个隐蔽神经原,输出层包含一个神经原。这对于神经网络包含两个输入神经原和一个输出神经原是具有重要意义的,因为XOR运算符接收两个参数而产生一个结果。

  为使用该神经原层,我们也必须创建触角。在本例中,我们要使用多个触角。这些触角用下面的代码实现。

// 输入-> 隐蔽的连接。
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);

  就象许多Java对象本身一样,JOONE监视器允许听者可以添加到它上面去。随着训练的进行,JOONE将通知听者有关训练进程的信息。在这个简单的例子中,我们使用:

monitor.addNeuralNetListener(this);

  我们现在必须建立输入触角。如前所述,我们将使用一个FileInputSynapse来读取一个磁盘文件。磁盘文件不是JOONE唯一能够接受的输入种类。JOONE对于不同的输入源具有很强的灵活性。为使JOONE能够接收其它输入类型,你只需创建一个新的触角来接受输入。在本例中,我们将简单地使用FileInputSynapse。FileInputSynapse首先被实例化。

inputStream = new FileInputSynapse();

  然后,必须通知FileInputSynapse要使用哪些列。列表1中显示的文件使用了输入数据的前两列。下面代码建立起前两列用于输入到神经网络。

// 前两列包含输入值
inputStream.setFirstCol(1);
inputStream.setLastCol(2);

  然后,我们必须提供输入文件的名字,这个名字直接来源于用户接口。然后,提供一个编辑控件用于收集输入文件的名字。下面代码为FileInputSynapse设置文件名。

// 这是包含输入数据的文件名
inputStream.setFileName(inputFile.getText());

  如前所述,一个触角仅是一个神经原层之间的数据导管。FileInputSynapse正是这里的数据导管,通过它数据进入到神经网络。为了更容易实现这点,我们必须要把FileInputSynapse加到神经网络的输入层。这由下面一行实现。

input.addInputSynapse(inputStream);

  现在既然已经建立起神经网络,我们必须创建一个训练员和一个监视器。训练员用于训练该神经网络,因为该监视器通过一个事先设置好的训练重复数来运行这个神经网络。对于每一次训练重复,数据被提供到神经网络,然后就可以观察到结果。该神经网络的权重(存储在穿梭在神经原层之间的触角连接中)将根据误差作适当调整。随着训练的进行,误差级将下降。下列代码建立训练员并把它依附到监视器。

trainer = new TeachingSynapse();
trainer.setMonitor(monitor);

  你会记得列表1中提供的输入文件包含三个列。到目前为止,我们仅仅使用了第一、二列,它们指定了到神经网络的输入。第三列包含当提供给神经网络第一列中的数字时的期盼的输出值。我们必须使得训练员能够存取该列以便能确定误差。该错误是神经网络的实际输出和期盼的输出之间的差距。下列代码创建另外一个FileInputSynapse并作好准备以读取与前面相同的输入文件。

// 设置包含期望的响应值的文件,这由FileInputSynapse来提供
samples = new FileInputSynapse();
samples.setFileName(inputFile.getText());

  这时,我们想指向在第三列的FileInputSynapse。下列代码实现了这一点,然后让训练员使用这个FileInputSynapse。

//输出值在文件中的第三列上
samples.setFirstCol(3);
samples.setLastCol(3);
trainer.setDesired(samples);

  最后,训练员被连结到神经网络输出层,这将使训练员接收神经网络的输出。

// 连接训练员到网络的最后一层
output.addOutputSynapse(trainer);

  我们现在已为所有的层准备好后台线程,包括训练员。

input.start();
hidden.start();
output.start();
trainer.start();

  最后,我们为训练设置一些参数。我们指定在输入文件中共有四行,而且想训练20,000个周期,而且还在不段学习。如果你设置学习参数为false,该神经网络将简单地处理输入并不进行学习。我们将在下一节讨论输入处理。

monitor.setPatterns(4);
monitor.setTotCicles(20000);
monitor.setLearning(true);

  现在我们已经为训练过程作好准备。调用监视器的Go方法将在后台启动训练过程。

monitor.Go();

  神经网络现在将要被训练20,000个周期。当神经网络训练完成,误差层应该在一个合理的低级别上。一般低于10%的误差级是可接受的。

时间: 2024-08-23 07:17:16

用Java开源项目JOONE实现人工智能编程的相关文章

Java开源项目(备查)

转自:http://www.blogjava.net/Carter0618/archive/2008/08/11/221222.html Spring Framework  [Java开源 J2EE框架] Spring 是一个解决了许多在J2EE开发中常见的问题的强大框架. Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不是对类编程的良好习惯.Spring的架构基础是基于使用JavaBean属性的 Inversion of Control容器.然而,这仅仅是完整图景中的一部分

【我整理的java开源项目】

摘要: 1. 整理出一些使用比较广或者个人觉得比较好的java开源项目和资料供参考. 2. 如果你觉得好但是我没有列出的开源项目请告诉我,方便我添加到列表里. 3. 如果你发现信息描述有误请联系我,我会及时修改或删除. 开源项目的繁荣离不开你我的参与 下面提供一些跟开源相关的文章链接: 1. Apache的开源软件列表 http://www.oschina.net/project/apache 2. Java开源Apache项目 http://www.open-open.com/56.htm 3

2013 年开源中国 10 大热门 Java 开源项目

2013 年结束了,我们根据过去一年的用户访问.交流分享和项目本身的更新频度等诸多角度对收录于开源中国的近三万款开源软件进行统计,从而得出前 XX 名最受欢迎的开源软件,仅供参考. 本排行榜主要是针对开源中国社区在2013年度最受欢迎的 10 大热门 Java 开源项目根据用户访问量.讨论和关注等角度进行筛选,从而得出前 10 名的 Java 开源软件列表: 1. JFinal JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功

【转】Java开源项目源码阅读方法及二次开发方法

一直以来,都想要阅读某些Java开源项目的源代码,甚至想要修改某些代码,实现对开源项目进行二次开发的目的.但总是不知从何入手,直接将开源项目的源代码导入Eclipse,总是会报很多错误,而无法编译.可以直接通过Eclipse打开开源项目的源代码,至少能够达到可视化源码阅读.源码导航的目的,还是能在一定程度上解决源码阅读不爽的问题,因为直接打开并没有改变源文件项目的目录结果,对于修改过后的代码,可以通过命令行找到源文件项目目录,并使用mvn或者ant对项目进行编译,再查看修改后的项目是否正确. 由

硬核! 逛了4年Github ,一口气把我收藏的 Java 开源项目分享给你!

Awsome Java Great Java project on Github(Github 上非常棒的 Java 开源项目). English Version 大家都知道 Github 是一个程序员福地,这里有各种厉害的开源框架.软件或者教程.这些东西对于我们学习和进步有着莫大的进步,所以我有了这个将 Github 上非常棒的 Java 开源项目整理下来的想法.我会按照几个维度对项目进行分类,以便大家查阅.当然,如果你觉得不错的话,欢迎给本项目点个 Star.我会用我的业余时间持续完善这份名

硬核! Github上 ,star超高的Java 开源项目分享给你!

Awsome JavaGreat Java project on Github(Github 上非常棒的 Java 开源项目). English Version 大家都知道 Github 是一个程序员福地,这里有各种厉害的开源框架.软件或者教程.这些东西对于我们学习和进步有着莫大的进步,所以我有了这个将 Github 上非常棒的 Java 开源项目整理下来的想法.我会按照几个维度对项目进行分类,以便大家查阅.当然,如果你觉得不错的话,欢迎给本项目点个 Star.我会用我的业余时间持续完善这份名单

10个你能参加并学习的java开源项目

如果你正在寻找有趣的 Java 项目想参与和贡献,那么请继续阅读这篇文章.这篇博文是 Java 画廊(Java Gallery)中的一部分,在Java画廊栏目下我介绍了一些有趣的Java项目给我们的读者.成为 Java 开发团队中的一员并编写大量代码是一件很棒的事情. 在学校里我们也许没有机会接触到真正的开发环境.在企业里我们可能做不了最喜欢的项目.在这种情况下,让我们加入可以带给我们欢乐和兴趣的开源项目吧. 有很多备受关注的初创开源项目,下面列出十个项目是我觉得非常有趣的,涉及到的学习范围也很

2019年 Github 上最热门的 Java 开源项目

10个热门的开源项目分享给大家,希望对大家有所帮助: 1Java https://github.com/TheAlgorithms/Java Star 18468 该项目用Java实现的所有算法,对算法感兴趣的伙伴们不要错过了. 2eladmin https://github.com/elunez/eladmin Star 4639 该项目基于 Spring Boot 2.1.0 . Jpa. Spring Security.redis.Vue的前后端分离的后台管理系统,项目采用分模块开发方式,

阿里巴巴的26款Java开源项目,赶紧戳…

本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ 开源展示了人类共同协作,成果分享的魅力.没有任何一家网络公司可以不使用开源技术,仅靠自身技术发展起来.“取之于开源,用之于开源,才能促进开源的良性发展”,阿里巴巴各个团队将踩过的坑和总结的经验融入到开源