`

java版本的神经网络——开源框架JOONE实践

阅读更多

由于实验室事情缘故,需要将python写的神经网络转成Java版本的,但是python中的numpy等啥包也不知道在Java里面对应的是什么工具,所以索性直接寻找一个现成可用的Java神经网络框架,于是就找到了JOONE,JOONE是一个神经网络的开源框架,使用的是BP算法进行迭代计算参数,使用起来比较方便也比较实用,下面介绍一下JOONE的一些使用方法。

 

JOONE需要使用一些外部的依赖包,这在官方网站上有,也可以在这里下载。将所需的包引入工程之后,就可以进行编码实现了。

 

首先看下完整的程序,这个是上面那个超链接给出的程序,应该是官方给出的一个示例吧,因为好多文章都用这个,这其实是神经网络训练一个异或计算器:

import org.joone.engine.*;
import org.joone.engine.learning.*;
import org.joone.io.*;
import org.joone.net.*;


/*
 * 
 * JOONE实现
 * 
 * */
public class XOR_using_NeuralNet implements NeuralNetListener
{
	private NeuralNet nnet = null;
	private MemoryInputSynapse inputSynapse, desiredOutputSynapse;
	LinearLayer input;
	SigmoidLayer hidden, output;
	boolean singleThreadMode = true;

	// XOR input
	private double[][] inputArray = new double[][]
	{
	{ 0.0, 0.0 },
	{ 0.0, 1.0 },
	{ 1.0, 0.0 },
	{ 1.0, 1.0 } };

	// XOR desired output
	private double[][] desiredOutputArray = new double[][]
	{
	{ 0.0 },
	{ 1.0 },
	{ 1.0 },
	{ 0.0 } };

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[])
	{
		XOR_using_NeuralNet xor = new XOR_using_NeuralNet();

		xor.initNeuralNet();
		xor.train();
		xor.interrogate();
	}

	/**
	 * Method declaration
	 */
	public void train()
	{

		// set the inputs
		inputSynapse.setInputArray(inputArray);
		inputSynapse.setAdvancedColumnSelector(" 1,2 ");
		// set the desired outputs
		desiredOutputSynapse.setInputArray(desiredOutputArray);
		desiredOutputSynapse.setAdvancedColumnSelector(" 1 ");

		// get the monitor object to train or feed forward
		Monitor monitor = nnet.getMonitor();

		// set the monitor parameters
		monitor.setLearningRate(0.8);
		monitor.setMomentum(0.3);
		monitor.setTrainingPatterns(inputArray.length);
		monitor.setTotCicles(5000);
		monitor.setLearning(true);

		long initms = System.currentTimeMillis();
		// Run the network in single-thread, synchronized mode
		nnet.getMonitor().setSingleThreadMode(singleThreadMode);
		nnet.go(true);
		System.out.println(" Total time=  "
				+ (System.currentTimeMillis() - initms) + "  ms ");
	}

	private void interrogate()
	{

		double[][] inputArray = new double[][]
		{
		{ 1.0, 1.0 } };
		// set the inputs
		inputSynapse.setInputArray(inputArray);
		inputSynapse.setAdvancedColumnSelector(" 1,2 ");
		Monitor monitor = nnet.getMonitor();
		monitor.setTrainingPatterns(4);
		monitor.setTotCicles(1);
		monitor.setLearning(false);
		MemoryOutputSynapse memOut = new MemoryOutputSynapse();
		// set the output synapse to write the output of the net

		if (nnet != null)
		{
			nnet.addOutputSynapse(memOut);
			System.out.println(nnet.check());
			nnet.getMonitor().setSingleThreadMode(singleThreadMode);
			nnet.go();

			for (int i = 0; i < 4; i++)
			{
				double[] pattern = memOut.getNextPattern();
				System.out.println(" Output pattern # " + (i + 1) + " = "
						+ pattern[0]);
			}
			System.out.println(" Interrogating Finished ");
		}
	}

	/**
	 * Method declaration
	 */
	protected void initNeuralNet()
	{

		// First create the three layers
		input = new LinearLayer();
		hidden = new SigmoidLayer();
		output = new SigmoidLayer();

		// set the dimensions of the layers
		input.setRows(2);
		hidden.setRows(3);
		output.setRows(1);

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

		// Now create the two Synapses
		FullSynapse synapse_IH = new FullSynapse(); /* input -> hidden conn. */
		FullSynapse synapse_HO = new FullSynapse(); /* hidden -> output conn. */

		// Connect the input layer whit the hidden layer
		input.addOutputSynapse(synapse_IH);
		hidden.addInputSynapse(synapse_IH);

		// Connect the hidden layer whit the output layer
		hidden.addOutputSynapse(synapse_HO);
		output.addInputSynapse(synapse_HO);

		// the input to the neural net
		inputSynapse = new MemoryInputSynapse();

		input.addInputSynapse(inputSynapse);

		// The Trainer and its desired output
		desiredOutputSynapse = new MemoryInputSynapse();

		TeachingSynapse trainer = new TeachingSynapse();

		trainer.setDesired(desiredOutputSynapse);

		// Now we add this structure to a NeuralNet object
		nnet = new NeuralNet();

		nnet.addLayer(input, NeuralNet.INPUT_LAYER);
		nnet.addLayer(hidden, NeuralNet.HIDDEN_LAYER);
		nnet.addLayer(output, NeuralNet.OUTPUT_LAYER);
		nnet.setTeacher(trainer);
		output.addOutputSynapse(trainer);
		nnet.addNeuralNetListener(this);
	}

	public void cicleTerminated(NeuralNetEvent e)
	{
	}

	public void errorChanged(NeuralNetEvent e)
	{
		Monitor mon = (Monitor) e.getSource();
		if (mon.getCurrentCicle() % 100 == 0)
			System.out.println(" Epoch:  "
					+ (mon.getTotCicles() - mon.getCurrentCicle()) + "  RMSE: "
					+ mon.getGlobalError());
	}

	public void netStarted(NeuralNetEvent e)
	{
		Monitor mon = (Monitor) e.getSource();
		System.out.print(" Network started for  ");
		if (mon.isLearning())
			System.out.println(" training. ");
		else
			System.out.println(" interrogation. ");
	}

	public void netStopped(NeuralNetEvent e)
	{
		Monitor mon = (Monitor) e.getSource();
		System.out.println(" Network stopped. Last RMSE= "
				+ mon.getGlobalError());
	}

	public void netStoppedError(NeuralNetEvent e, String error)
	{
		System.out.println(" Network stopped due the following error:  "
				+ error);
	}

}

  

 现在我会逐步解释上面的程序。

 【1】 从main方法开始说起,首先第一步新建一个对象:

XOR_using_NeuralNet xor = new XOR_using_NeuralNet();

 【2】然后初始化神经网络:

xor.initNeuralNet();

 初始化神经网络的方法中:

 

// First create the three layers
		input = new LinearLayer();
		hidden = new SigmoidLayer();
		output = new SigmoidLayer();

		// set the dimensions of the layers
		input.setRows(2);
		hidden.setRows(3);
		output.setRows(1);

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

上面代码解释:

input=new LinearLayer()是新建一个输入层,因为神经网络的输入层并没有训练参数,所以使用的是线性层;

hidden = new SigmoidLayer();这里是新建一个隐含层,使用sigmoid函数作为激励函数,当然你也可以选择其他的激励函数,如softmax激励函数

output则是新建一个输出层

之后的三行代码是建立输入层、隐含层、输出层的神经元个数,这里表示输入层为2个神经元,隐含层是3个神经元,输出层是1个神经元

最后的三行代码是给每个输出层取一个名字。

 

// Now create the two Synapses
		FullSynapse synapse_IH = new FullSynapse(); /* input -> hidden conn. */
		FullSynapse synapse_HO = new FullSynapse(); /* hidden -> output conn. */

		// Connect the input layer whit the hidden layer
		input.addOutputSynapse(synapse_IH);
		hidden.addInputSynapse(synapse_IH);

		// Connect the hidden layer whit the output layer
		hidden.addOutputSynapse(synapse_HO);
		output.addInputSynapse(synapse_HO);

 上面代码解释:

 

上面代码的主要作用是将三个层连接起来,synapse_IH用来连接输入层和隐含层,synapse_HO用来连接隐含层和输出层

 

 

// the input to the neural net
		inputSynapse = new MemoryInputSynapse();

		input.addInputSynapse(inputSynapse);

		// The Trainer and its desired output
		desiredOutputSynapse = new MemoryInputSynapse();

		TeachingSynapse trainer = new TeachingSynapse();

		trainer.setDesired(desiredOutputSynapse);

上面代码解释: 

 

上面的代码是在训练的时候指定输入层的数据和目的输出的数据,

 inputSynapse = new MemoryInputSynapse();这里指的是使用了从内存中输入数据的方法,指的是输入层输入数据,当然还有从文件输入的方法,这点在文章后面再谈。同理,desiredOutputSynapse = new MemoryInputSynapse();也是从内存中输入数据,指的是从输入层应该输出的数据

 

// Now we add this structure to a NeuralNet object
		nnet = new NeuralNet();

		nnet.addLayer(input, NeuralNet.INPUT_LAYER);
		nnet.addLayer(hidden, NeuralNet.HIDDEN_LAYER);
		nnet.addLayer(output, NeuralNet.OUTPUT_LAYER);
		nnet.setTeacher(trainer);
		output.addOutputSynapse(trainer);
		nnet.addNeuralNetListener(this);

 上面代码解释:

 

这段代码指的是将之前初始化的构件连接成一个神经网络,NeuralNet是JOONE提供的类,主要是连接各个神经层,最后一个nnet.addNeuralNetListener(this);这个作用是对神经网络的训练过程进行监听,因为这个类实现了NeuralNetListener这个接口,这个接口有一些方法,可以实现观察神经网络训练过程,有助于参数调整。

 

 

【3】然后我们来看一下train这个方法:

 

inputSynapse.setInputArray(inputArray);
		inputSynapse.setAdvancedColumnSelector(" 1,2 ");
		// set the desired outputs
		desiredOutputSynapse.setInputArray(desiredOutputArray);
		desiredOutputSynapse.setAdvancedColumnSelector(" 1 ");

上面代码解释:

 

inputSynapse.setInputArray(inputArray);这个方法是初始化输入层数据,也就是指定输入层数据的内容,inputArray是程序中给定的二维数组,这也就是为什么之前初始化神经网络的时候使用的是MemoryInputSynapse,表示从内存中读取数据

inputSynapse.setAdvancedColumnSelector(" 1,2 ");这个表示的是输入层数据使用的是inputArray的前两列数据。

desiredOutputSynapse这个也同理

 

 

Monitor monitor = nnet.getMonitor();

		// set the monitor parameters
		monitor.setLearningRate(0.8);
		monitor.setMomentum(0.3);
		monitor.setTrainingPatterns(inputArray.length);
		monitor.setTotCicles(5000);
		monitor.setLearning(true);

 

 上面代码解释:

这个monitor类也是JOONE框架提供的,主要是用来调节神经网络的参数,monitor.setLearningRate(0.8);是用来设置神经网络训练的步长参数,步长越大,神经网络梯度下降的速度越快,monitor.setTrainingPatterns(inputArray.length);这个是设置神经网络的输入层的训练数据大小size,这里使用的是数组的长度;monitor.setTotCicles(5000);这个指的是设置迭代数目;monitor.setLearning(true);这个true表示是在训练过程。

 

 

nnet.getMonitor().setSingleThreadMode(singleThreadMode);
		nnet.go(true);

 上面代码解释:

 

nnet.getMonitor().setSingleThreadMode(singleThreadMode);这个指的是是不是使用多线程,但是我不太清楚这里的多线程指的是什么意思

nnet.go(true)表示的是开始训练。

 

【4】最后来看一下interrogate方法

 

 

double[][] inputArray = new double[][]
		{
		{ 1.0, 1.0 } };
		// set the inputs
		inputSynapse.setInputArray(inputArray);
		inputSynapse.setAdvancedColumnSelector(" 1,2 ");
		Monitor monitor = nnet.getMonitor();
		monitor.setTrainingPatterns(4);
		monitor.setTotCicles(1);
		monitor.setLearning(false);
		MemoryOutputSynapse memOut = new MemoryOutputSynapse();
		// set the output synapse to write the output of the net

		if (nnet != null)
		{
			nnet.addOutputSynapse(memOut);
			System.out.println(nnet.check());
			nnet.getMonitor().setSingleThreadMode(singleThreadMode);
			nnet.go();

			for (int i = 0; i < 4; i++)
			{
				double[] pattern = memOut.getNextPattern();
				System.out.println(" Output pattern # " + (i + 1) + " = "
						+ pattern[0]);
			}
			System.out.println(" Interrogating Finished ");
		}

 这个方法相当于测试方法,这里的inputArray是测试数据, 注意这里需要设置monitor.setLearning(false);,因为这不是训练过程,并不需要学习,monitor.setTrainingPatterns(4);这个是指测试的数量,4表示有4个测试数据(虽然这里只有一个)。这里还给nnet添加了一个输出层数据对象,这个对象mmOut是初始测试结果,注意到之前我们初始化神经网络的时候并没有给输出层指定数据对象,因为那个时候我们在训练,而且指定了trainer作为目的输出。

 

 

接下来就是输出结果数据了,pattern的个数和输出层的神经元个数一样大,这里输出层神经元的个数是1,所以pattern大小为1.

 

 

【5】我们看一下测试结果:

 

Output pattern # 1 = 0.018303527517809233

 表示输出结果为0.01,根据sigmoid函数特性,我们得到的输出是0,和预期结果一致。如果输出层神经元个数大于1,那么输出值将会有多个,因为输出层结果是0|1离散值,所以我们取输出最大的那个神经元的输出值取为1,其他为0

 

 

 

【6】最后我们来看一下神经网络训练过程中的一些监听函数:

cicleTerminated:每个循环结束后输出的信息

errorChanged:神经网络错误率变化时候输出的信息

netStarted:神经网络开始运行的时候输出的信息

netStopped:神经网络停止的时候输出的信息

 

【7】好了,JOONE基本上内容就是这些。还有一些额外东西需要说明:

 

1,从文件中读取数据构建神经网络

2.如何保存训练好的神经网络到文件夹中,只要测试的时候直接load到内存中就行,而不用每次都需要训练。

 

 

【8】先看第一个问题:

从文件中读取数据:

文件的格式:

0;0;0

1;0;1

1;1;0

0;1;1

 

中间使用分号隔开,使用方法如下,也就是把上文的MemoryInputSynapse换成FileInputSynapse即可。

 

fileInputSynapse = new FileInputSynapse();
input.addInputSynapse(fileInputSynapse);
fileDisireOutputSynapse = new FileInputSynapse();
TeachingSynapse trainer = new TeachingSynapse();
trainer.setDesired(fileDisireOutputSynapse);

 我们看下文件是如何输出数据的:

 

 

private File inputFile = new File(Constants.TRAIN_WORD_VEC_PATH);
fileInputSynapse.setInputFile(inputFile);
fileInputSynapse.setFirstCol(2);//使用文件的第2列到第3列作为输出层输入
fileInputSynapse.setLastCol(3);

 

 fileDisireOutputSynapse.setInputFile(inputFile);
 fileDisireOutputSynapse.setFirstCol(1);//使用文件的第1列作为输出数据
 fileDisireOutputSynapse.setLastCol(1);

 其余的代码和上文的是一样的。

 

 

【9】然后看第二个问题:

如何保存神经网络

其实很简单,直接序列化nnet对象就行了,然后读取该对象就是java的反序列化,这个就不多做介绍了,比较简单。但是需要说明的是,保存神经网络的时机一定是在神经网络训练完毕后,可以使用下面代码:

 

public void netStopped(NeuralNetEvent e) {
		Monitor mon = (Monitor) e.getSource();
		try {
			if (mon.isLearning()) {
				saveModel(nnet); //序列化对象
			}
		} catch (IOException ee) {
			// TODO Auto-generated catch block
			ee.printStackTrace();
		}

 

 

 

1
5
分享到:
评论
3 楼 ustcter 2016-05-11  
u010223750 写道
LinApex 写道
应用场景在哪?

最近在做文本分类的事情,正好用到了神经网络的方法,用这个训练效果还不错,不过训练速度有点慢


想学习文本分类和神经网络,有完整的例子吗
2 楼 u010223750 2016-03-11  
LinApex 写道
应用场景在哪?

最近在做文本分类的事情,正好用到了神经网络的方法,用这个训练效果还不错,不过训练速度有点慢
1 楼 LinApex 2016-03-11  
应用场景在哪?

相关推荐

    joone JAVA中的开源神经网络框架

    Joone 是一个基于Java语言的开源神经网络框架,它的出现为开发者提供了一个在Java环境中构建、训练和应用神经网络的工具。Joone 的设计目标是易于使用,同时保持足够的灵活性,以便适应各种复杂的神经网络模型。 ...

    Java开源神经网络框架JOONE,Maven

    Java开源神经网络框架JOONE是面向Java开发人员的高级工具,它允许用户构建、训练和应用神经网络模型。JOONE(Java Object Oriented Neural Engine)是基于对象编程的,提供了丰富的API来支持神经网络的创建和操作。...

    java神经元网络框架(JOONE)

    Java神经元网络框架(JOONE)是专门为Java开发者设计的一款深度学习库,它允许程序员构建、训练和应用神经网络模型,以解决复杂的数据预测和模式识别问题。JOONE的出现填补了Java在神经网络领域的一些空白,使得Java...

    开源java神经网络组件Joone、Encog和Neuroph的简单使用

    Java神经网络组件,如Joone、Encog和Neuroph,为开发者提供了在Java环境中构建和训练神经网络的工具。这些开源库不仅简化了神经网络的实现,还为初学者和经验丰富的数据科学家提供了深入了解神经网络工作原理的机会...

    joone框架 java实现神经网络 模式识别

    Joone这个名字来源于"Java Object Oriented Neural Engine"的缩写,它体现了该框架的核心理念——以面向对象的方式实现神经网络引擎。 在标题中提到的"java实现神经网络",是指Joone框架使用Java编程语言来创建神经...

    java的神经网络jar包joone.jar

    1. **Java神经网络框架**:Joone作为Java的神经网络框架,它的设计目标是提供一个易于使用的API,使开发人员能够快速地搭建神经网络结构,而无需深入理解神经网络的底层工作原理。它支持多种网络结构,如前馈网络、...

    java神经网络的jar包joone.jar

    发现joone的jar包资源很少,就上传了,joone-engine.jar

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

    【Java开源项目JOONE】是面向Java程序员的一个强大的工具,它简化了人工智能编程中的复杂性,特别是神经网络的实现。JOONE(Java Object Oriented Neural Engine)是一个遵循LGPL许可的开源项目,允许开发者免费使用...

    joone-engine-0.8.3.zip_Java 8_joone_神经网络 java

    Joone Engine是一个基于Java开发的开源神经网络框架,版本为0.8.3。这个库专为Java 8设计,提供了高效且易于使用的接口来构建和训练神经网络模型。Joone这个名字是“Java Object Oriented Neural Engine”的缩写,...

    神经网络joone_engin模式识别示范,eclipse

    Joone Engine是一个用Java编写的神经网络框架,它提供了构建和训练各种类型的神经网络的能力。 1. **神经网络基础**:神经网络是受生物神经元结构启发的一种计算模型,由大量的处理单元(神经元)组成,通过连接...

    Joone完整指南(中文版)

    Joone是一个开源的人工智能神经网络库,使用Java语言编写,能够在各种平台上运行。Joone可以应用于各种需要神经网络技术的领域,如图像识别、自然语言处理、机器学习等。 Joone的特点 Joone具有以下特点: * 跨...

    joone1.2.1-java包

    Joone 1.2.1 是一个基于Java的开源神经网络框架,专为开发者提供工具来构建、训练和应用神经网络模型。这个框架的核心在于它的灵活性和可扩展性,允许用户自定义网络结构和学习算法,以适应各种复杂的机器学习任务。...

    joone-engine-1.1.2.zip_joone_joone-engine_joone-engine.jar_神经网络

    Joone Engine是一款基于Java开发的神经网络框架,其版本为1.1.2,封装在名为"joone-engine-1.1.2.zip"的压缩文件中。这个工具专为那些希望在Java环境中构建和训练神经网络模型的开发者设计。Joone Engine的核心组件...

    人工智能-神经网络工具包JOONE

    JOONE(Java Object Oriented Neural Network)是sourceforge上一个用java语言迅速开发神经网络的最新工具包

    LTSM需要的jar包joone

    而“joone”则可能是Java Object Oriented Neural Engine的缩写,这是一个基于Java的神经网络框架。描述中提到joone是LTSM可能需要的jar包,但没有明确说明它们之间如何结合使用。此外,joone带有API文档和完整的...

    joone-javadoc.zip

    Joone 是一个开源的Java库,专门用于构建和运行神经网络。这个库为开发者提供了在Java环境中实现神经网络算法的工具,使得复杂的人工神经网络模型可以在Java应用程序中轻松集成。"joone-javadoc.zip" 文件是一个包含...

    joone-engine-2.0.0RC1

    Joone Engine 2.0.0RC1 是一个基于Java的开源神经网络框架,专为在Java环境中构建和训练神经网络模型提供强大的支持。这个工具因其易用性和灵活性而受到开发者的欢迎,使得非专业AI背景的程序员也能轻松地进行神经...

    joone.jar包

    java 人工智能开发的 joone jar 包

    Java编写神经网路的资料

    Joone是一个用Java编写的开源神经网络框架,它为开发者提供了一个强大的工具来实现自己的神经网络算法。 Joone Complete Guide 是一本专门介绍如何使用Joone进行神经网络编程的指南。虽然这本书是全英文的,但根据...

Global site tag (gtag.js) - Google Analytics