神经网络 java包
java神经网络组件Joone、Encog和Neuroph
https://github.com/deeplearning4j/deeplearning4j
http://muchong.com/html/201611/10796085.html
Comparing Neural Networks in Neuroph, Encog and JOONE
https://www.codeproject.com/articles/85385/comparing-neural-networks-in-neuroph-encog-and-joone
Introduction
In this article, I will show you how to create a feedforward neural network. I will show you how to create the feedforward neural network to recognize the XOR operator. There are many examples that will show you how to do this on the Internet. However, I am going to show you how to do this three times. We will use three different neural network frameworks. This all allows you to get a feel for the three major Java open source neural networks that are available on the Internet and how they approach things. This may help you to decide which neural network framework is best suited to your project.
First, let me explain the XOR operation that I will be teaching the neural network to recognize. The XOR operation is essentially the “Hello World” of neural networks. Neural networks accept input and produce output. They process data using layers of neurons. A feedforward neural network has an input layer, zero or more hidden layers, and an output layer. The input accepts an array of floating point numbers. The output layer produces an array of floating point numbers. The size of these arrays does not need to be equal. The number of neurons in the input and output layers determines the array size.
You can then create training data. For the XOR operator, you would have four training items. The training items map the input to the ideal output. For XOR, this training data would be as follows:
- [0,0] -> [0]
- [1,0] -> [1]
- [0,1] -> [1]
- [1,1] -> [0]
These values correspond to the mathematical XOR operator. The neural network will train until the output from the neural network is close to the ideal output. The training is broken up into iterations. Each iteration will get the neural network output closer to the ideal output. The difference between the actual output from the neural network and the ideal output is the error rate of the neural network. There are different ways to train a neural network, but they all usually involve going through iterations, until the error decreases to an acceptable level.
This article will show how to implement the XOR operator in three different Java open source neural network frameworks. The three main open source neural network frameworks that are available on the Internet are:
Creating the XOR Operator in Encog
Encog is licensed under the Lesser GNU Public License. Encog supports a variety of training techniques. In this article, we will make use of a training technique called Levenberg Marquardt, or LMA. LMA is one of the most advanced training techniques available for neural networks. It does not work well with all training sets, but it can learn the XOR in a fraction of the time other training techniques require. LMA requires that the output of the neural network be a single neuron. This is fine for the XOR operator. Also, as the size of the training set increases, the effectiveness of LMA decreases. For larger training sets, you might want to consider Resilient Propagation or Resilient Propagation.
First, we setup the training data. The XOR data is stored in two arrays.
- public static double XOR_INPUT[][] = {
- { 0.0, 0.0 },
- { 1.0, 0.0 },
- { 0.0, 1.0 },
- { 1.0, 1.0 } };
- public static double XOR_IDEAL[][] = {
- { 0.0 },
- { 1.0 },
- { 1.0 },
- { 0.0 } };
Next, we create a BasicNetwork
object. This object will accept the layers that make up the neural network.
- BasicNetwork network = new BasicNetwork();
- network.addLayer(new BasicLayer(new ActivationTANH(),true,2));
- network.addLayer(new BasicLayer(new ActivationTANH(),true,3));
- network.addLayer(new BasicLayer(new ActivationTANH(),true,1));
As you can see, three layers were added. The first one is the input layer. It has two neurons and uses a TANH activation function. The true value means that this layer has bias.
The second layer is a hidden layer. It has three neurons. These neurons help to recognize the signals sent to the neural network. The output layer has a single output neuron.
Encog can support a variety of neural network architectures. These are defined as logic objects. This neural network is a feedforward neural network, so we will use the FeedforwardLogic
class.
- network.setLogic(new FeedforwardLogic());
- network.getStructure().finalizeStructure();
- network.reset();
Finally, the neural network structure must be created, and the neural network reset. The process of resetting the neural network randomizes the weights.
We now create a training set. The training set is used by Encog to train for the XOR operator.
- NeuralDataSet trainingSet = new BasicNeuralDataSet(XOR_INPUT, XOR_IDEAL);
All Encog training is done using the Train
interface. We are going to use LevenbergMarquardtTraining
training.
- final Train train = new LevenbergMarquardtTraining(network, trainingSet);
Levenberg Marquardt training sometimes fails to converge from the random weights. This is especially true for such a small network as this. We will use a reset strategy to rerandomize if there is less than a 1% improvement over 5 iterations.
- train.addStrategy(new RequiredImprovementStrategy(5));
We are now ready to train though the epochs, or iterations. We begin with epoch 1.
- int epoch = 1;
We will loop through training iterations until the error falls below 1%.
- do {
- train.iteration();
- System.out.println("Epoch #" + epoch + " Error:" + train.getError());
- epoch++;
- } while(train.getError() > 0.01);
We will now test the output of the neural network.
- 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));
- }
The same training data is used to export the neural network.
The output from the Encog XOR example is shown here:
- Epoch #1 Error:0.5455122488506147
- Epoch #2 Error:0.5052657193615671
- Epoch #3 Error:0.4807114538448516
- Epoch #4 Error:0.43616509724573044
- Epoch #5 Error:0.20566912505617155
- Epoch #6 Error:0.17638897570315684
- Epoch #7 Error:0.028373668231531972
- Epoch #8 Error:0.026258952179473653
- Epoch #9 Error:0.023244078646272336
- Epoch #10 Error:0.021221881866343273
- Epoch #11 Error:0.019887606329834745
- Epoch #12 Error:0.018885747329580156
- Epoch #13 Error:0.018047468600671735
- Epoch #14 Error:0.017288643933811593
- Epoch #15 Error:0.016572218727452955
- Epoch #16 Error:0.01595505187120417
- Epoch #17 Error:0.010300974511088516
- Epoch #18 Error:0.008141364550377145
- Neural Network Results:
- 0.0,0.0, actual=0.020564759593838522,ideal=0.0
- 1.0,0.0, actual=0.9607289095427742,ideal=1.0
- 0.0,1.0, actual=0.8966620525621667,ideal=1.0
- 1.0,1.0, actual=0.06032304565618274,ideal=0.0
As you can see, it took Encog 18 iterations with Levenberg Marquardt training. Not all training techniques will use as few iterations as Levenberg Marquardt. We will see this in the next section.
Creating the XOR Operator in Neuroph
Neuroph is another neural network framework. It is licensed under the Apache License. It is currently in discussions to be merged into the Apache Machine Learning project. For Neuroph, we will use an automatic variant of the backpropagation algorithm they provide. It is not nearly as advanced as Levenberg Marquard, and as a result will take considerably more training iterations.
We begin by creating a training set.
- TrainingSet trainingSet = new TrainingSet(2, 1);
- trainingSet.addElement(new SupervisedTrainingElement
- (new double[]{0, 0}, new double[]{0}));
- trainingSet.addElement(new SupervisedTrainingElement
- (new double[]{0, 1}, new double[]{1}));
- trainingSet.addElement(new SupervisedTrainingElement
- (new double[]{1, 0}, new double[]{1}));
- trainingSet.addElement(new SupervisedTrainingElement
- (new double[]{1, 1}, new double[]{0}));
Next we create the neural network. Neuroph uses one line to create the neural network.
- MultiLayerPerceptron network =
- new MultiLayerPerceptron(TransferFunctionType.TANH, 2, 3, 1);
This creates the same neural network as was created by Encog. It will use TANH, 2 input, 3 hidden and one output neuron.
For training, we will use Dynamic Backpropagation.
- DynamicBackPropagation train = new DynamicBackPropagation();
- train.setNeuralNetwork(network);
- network.setLearningRule(train);
We now begin to loop through training iterations, until we are trained to below 1%.
- int epoch = 1;
- do
- {
- train.doOneLearningIteration(trainingSet);
- System.out.println("Epoch " + epoch + ", error=" + train.getTotalNetworkError());
- epoch++;
- } while(train.getTotalNetworkError()>0.01);
- Once we are done, we display the trained network’s results.
- System.out.println("Neural Network Results:");
- for(TrainingElement element : trainingSet.trainingElements()) {
- network.setInput(element.getInput());
- network.calculate();
- Vector<Double> output = network.getOutput();
- SupervisedTrainingElement ste = (SupervisedTrainingElement)element;
- System.out.println(element.getInput().get(0) + ","
- + element.getInput().get(0)
- + ", actual=" + output.get(0) + ",ideal=" + ste.getDesiredOutput().get(0));
Now the network is done training. The output was as follows:
- Epoch 1, error=0.8077190599388583
- Epoch 2, error=0.6743673707323136
- Epoch 3, error=0.6059014056204383
- Epoch 4, error=0.5701909436997877
- Epoch 5, error=0.5508436432846441
- Epoch 6, error=0.5399519500630455
- Epoch 7, error=0.5336030007276679
- Epoch 8, error=0.5297843855391863
- Epoch 9, error=0.5274201294309249
- Epoch 10, error=0.5259144756152534
- ...
- Epoch 611, error=0.010100940088620529
- Epoch 612, error=0.010028500485140078
- Epoch 613, error=0.009956945579398092
- Neural Network Results:
- 0.0,0.0, actual=0.014203702898690052,ideal=0.0
- 0.0,0.0, actual=0.8971874832025113,ideal=1.0
- 1.0,1.0, actual=0.909728369858769,ideal=1.0
- 1.0,1.0, actual=0.01578509009382128,ideal=0.0
As you can see, it took 613 iterations to get the error below 1%. Clearly backpropagation is not nearly as robust as Levenberg Marquard. Automatic backpropagation is currently the most advanced training offered by Neuroph. This is one of the areas where Encog really excels in. Encog offers advanced training methods such as Resilient Propagation, Simulated Annealing, Genetic Training, Levenberg Marquard and Scaled Conjugate Gradient.
However, the automatic additions made to backpropagation by Neuroph does give it an advantage over a neural network framework that just uses standard backpropagation.
Creating the XOR Operator in JOONE
JOONE is the oldest neural network framework that we are examining. Encog and Neuroph were both started in 2008. JOONE dates back to 2001. JOONE is not actively supported, though there are a number of systems that were implemented with it. JOONE makes use of backpropagation. JOONE has classes that claim support for resilient propagation, but I was unable to get it to work. JOONE is also known for being “buggy”, and because it is no longer an active project, this can make things difficult.
The last two frameworks that we examined had fairly simple APIs that make it easy on the programmer to get the neural network created. Not so with JOONE. JOONE’s API is a beast. It does not really hide much, and is very difficult to get working. Of all three examples, this one took me the most time. It is also the longest.
JOONE defines arrays to accept the input.
- public static double XOR_INPUT[][] = { { 0.0, 0.0 }, { 1.0, 0.0 },
- { 0.0, 1.0 }, { 1.0, 1.0 } };
- public static double XOR_IDEAL[][] = { { 0.0 }, { 1.0 }, { 1.0 }, { 0.0 } };
We will create a linear layer for the input.
- LinearLayer input = new LinearLayer();
- SigmoidLayer hidden = new SigmoidLayer();
- SigmoidLayer output = new SigmoidLayer();
The hidden and output layers are both sigmoid. Next the layers are labeled.
- input.setLayerName("input");
- hidden.setLayerName("hidden");
- output.setLayerName("output");
We set the neuron counts on each of the layers.
- input.setRows(2);
- hidden.setRows(3);
- output.setRows(1);
Synapses must be created to link the layers together.
- FullSynapse synapse_IH = new FullSynapse(); /* input ->l hidden conn. */
- FullSynapse synapse_HO = new FullSynapse(); /* hidden ->l output conn. */
We should label the synapses.
- synapse_IH.setName("IH");
- synapse_HO.setName("HO");
Now the synapses are actually connected to the layers.
- input.addOutputSynapse(synapse_IH);
- hidden.addInputSynapse(synapse_IH);
The other side of the synapses are connected.
- hidden.addOutputSynapse(synapse_HO);
- output.addInputSynapse(synapse_HO);
Here is one feature I really dislike about JOONE. In both Neuroph and Encog, you create a neural network and then train it. With JOONE, you must physically change the network to switch between training it and using it. Here we are setting up to train. We will use a memory synapse to feed the arrays of XOR into the network.
- MemoryInputSynapse inputStream = new MemoryInputSynapse();
We must specify the array to use and which columns to use.
- inputStream.setInputArray(XOR_INPUT);
- inputStream.setAdvancedColumnSelector("1,2");
We add the input stream to the synapse.
- input.addInputSynapse(inputStream);
We create a teaching synapse to train the network.
- TeachingSynapse trainer = new TeachingSynapse();
- MemoryInputSynapse samples = new MemoryInputSynapse();
We must also specify the ideal output.
- samples.setInputArray(XOR_IDEAL);
- samples.setAdvancedColumnSelector("1");
- trainer.setDesired(samples);
We connect the trainer.
- output.addOutputSynapse(trainer);
Now we create a neural network to hold this entire structure.
- this.nnet = new NeuralNet();
The layers are now added to the network.
- nnet.addLayer(input, NeuralNet.INPUT_LAYER);
- nnet.addLayer(hidden, NeuralNet.HIDDEN_LAYER);
- nnet.addLayer(output, NeuralNet.OUTPUT_LAYER);
We create a monitor to monitor the training process.
- this.monitor = nnet.getMonitor();
- monitor.setTrainingPatterns(4); // # of rows (patterns) contained in the input file
- monitor.setTotCicles(1000); // How many times the net must be trained on the input patterns
- monitor.setLearningRate(0.7);
- monitor.setMomentum(0.3);
- monitor.setLearning(true); // The net must be trained
- monitor.setSingleThreadMode(true); // Set to false for multi-thread mode
- /* The application registers itself as monitor's listener so it can receive
- the notifications of termination from the net. */
- monitor.addNeuralNetListener(this);
- }
The following is the output from the JOONE example.
- ...
- Epoch: 4991 Error:0.01818486701740271
- Epoch: 4992 Error:0.018182516392244434
- Epoch: 4993 Error:0.01818016665209608
- Epoch: 4994 Error:0.018177817796408376
- Epoch: 4995 Error:0.018175469824632386
- Epoch: 4996 Error:0.01817312273621985
- Epoch: 4997 Error:0.01817077653062278
- Epoch: 4998 Error:0.018168431207293823
- Epoch: 4999 Error:0.018166086765686006
As you can see, it took almost 5000 iterations, and JOONE has not yet trained as well as Neuroph. This is because it is using regular backpropagation. The automatic propagation used by Neuroph varies the learning rate and threshold to optimize the learning process. The difference is abundantly clear here.
Conclusions
In this article, I showed you three different approaches to the same problem. In my opinion, Encog and Neuroph are easy choices over JOONE. JOONE is not really supported any longer, and though JOONE can execute an iteration much faster than Neuroph, Neuroph’s auto training makes it superior to JOONE. Also JOONE is very hard to use.
Encog has many more features than Neuroph and supports very advanced training methods. It took Encog 18 iterations, Neuroph 613 and JOONE over 5000. I find the internal code of Neuroph easier to follow than Encog. Though I find the APIs of Encog and Neuroph to be comparable. Encog is built for speed, and it makes its internals more complex. Encog can even take advantage of your GPU for additional training speed.
In my next article, I will benchmark all three and show timings in various situations.
History
- 3rd June, 2010: Initial post
License
This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)
Share
神经网络 java包的更多相关文章
- Android 虚拟机Dalvik、Android各种java包功能、Android相关文件类型、应用程序结构分析、ADB
Android虚拟机Dalvik Dalvik冲击 随着Google 的AndroidSDK 的发布,关于它的API 以及在移动电话领域所带来的预期影响这些方面的讨论不胜枚举.不过,其中的一个话题在J ...
- 在Eclipse工具里创建maven的web工程,在建立src/main/java包出现The folder is already a source folder.解决
1. 与创建普通java工程一样,点击右键找到New菜单,在弹出的界面输入maven ---->>点击maven Project------>>点击next 2 进入下一个界 ...
- android工程gen目录中R.java包名是怎么确定
新建一个工程,包名用的com.mythroad.adskiller, 后来觉得不好,又改成com.mythroad.adsinscepter,但是我发现gen下的R.java文件的包名还是原来的com ...
- JavaSE复习日记 : java包机制
这里是第一个文件,命名为JavaSE_01.java,我在这个文件里面声明了一个m1()方法,通过包机制,我将在另外一个文件夹里访问这个文件里的东西,确切的说是访问这个文件生成的一个class文件; ...
- 6、Java包的命名与划分
6.包的命名与划分 (一)使用Java包的目的 在了解做一件事之前,需要了解做这件事的目的.而使用Java包的目的大概如下: 1 对类进行归类,便于开发查找. 2 将软件在代码层面上模块化 ...
- 列出JDK中常用的Java包
列出JDK中常用的Java包 1.java.lang 2.java.sql 3.java.io 4.java.math 5.java.text 6.java.net 7.java.util 8.jav ...
- Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包
Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的, ...
- java~IDEA引用包时分组所有java包
对于java系统包,我们的IDEA里开发项目时,如果你使用了java系统包,如import java.util,那么,你可以把它和其它第三方的包分开,这样更清晰,我们可以在设置里,代码风格,java ...
- C#调用java包里的方法
用IKVM,步骤: 下载ikvmbin-7.2.4630.5.zip,解压,把bin目录所在路径加到环境变量path里 2.电脑开始->CMD,输入ikvmc –out:”输出dll文件的路径” ...
随机推荐
- 如何玩facebook app上的H5游戏
一.下载facebook app facebook链接 二.下载vpn 国内是访问不了的,必须vpn 因为vpn被封了厉害 我随便百度了个狸猫加速器,没付费,时断时续... 没有推荐的vpn,哪位大佬 ...
- 【CF932E】Team Work/【BZOJ5093】图的价值 数学+NTT
[CF932E]Team Work 题意:求$\sum\limits_{i=1}^nC_n^ii^k$,答案模$10^9+7$.$n\le 10^9,k\le 5000$. [BZOJ5093]图的价 ...
- [工具] multidesk
MultiDesk 是一个选项卡(TAB标签)方式的远程桌面连接 (Terminal Services Client). http://www.hoowi.com/multidesk/index_ch ...
- 利用 bugly 分析应用崩溃
Bugly-Crash监控能让我们及时的掌控应用的Crash,并快速修复.这种情况就在于我们把应用发布出去了,但是用户那边有着各种各样我们想象不到的系统崩溃,我们无法通过简单的控制台捕获错误信息和崩溃 ...
- ArcEngine TextElement 定位点的问题
做ArcGIS Add-In开发,需要在ArcMap中数据视图的左上角加一个上标,如果上标与数据中的地名图层重合,则放在右上角. 上标通过ITextElement,IElement,ITextSymb ...
- 不同修饰符使用细节(java)
常用来修饰类.方法.变量的修饰符如下 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权限修饰符,默认访 ...
- window server 2012 II8 假陌生 碰到的问题
1.我们网站是.net 3.5 开发的.还有一个32DLL 2.从windows server 2008 r2 iis 7 迁移过来碰到了3个问题,及解决办法 I. 在唯一密钥属性“fileExten ...
- 《ACM-ICPC程序设计系列 数论及其应用》例题个人答案记录
例1.1:HDU2099(2017/9/4) 本题书上给的答案是从0到99枚举,显然可以优化到每次递增b,这样至少可以把枚举次数减少到1/10. #include<cstdio> int ...
- SQL Fundamentals: Using Single-Row Functions to Customize Output使用单行函数自定义输出
SQL Fundamentals || Oracle SQL语言 DUAL is a public table that you can use to view results from functi ...
- CCCC L2 部落 L3社交集群
https://www.patest.cn/contests/gplt/L2-024 题解:部落是并查集模板题. 社交集群用并查集暴力有23分 坑:写了半天,发现自己并查集没怎么学明白,现在才搞懂: ...