如何使用java代码构建NN
引擎的支点是Layer对象。它由N个神经元组成(可以通过属性'rows'设置)。想象一下由三层组成的前馈神经网络,如下所示:
要使用joone构建这个网络,我们必须创建三个Layer对象和两个Synapse对象:
SigmoidLayer layer1 = new SigmoidLayer(); SigmoidLayer layer2 = new SigmoidLayer(); SigmoidLayer layer3 = new SygmoidLayer(); FullSynapse synapse1 = new FullSynapse(); FullSynapse synapse2 = new FullSynapse();
然后我们完成网连接三个层与突触:
layer1.addOutputSynapse(synapse1); layer2.addInputSynapse(synapse1); layer2.addOutputSynapse(synapse2); layer3.addInputSynapse(synapse2);
在这里你可以看到,每个突触是一个层的输出突触和网络中下一层的输入突触。这个简单的网络已经准备就绪,但它不能做任何有用的工作,因为没有组件读/写网络必须详细阐述的数据。看下一个例子来学习如何建立一个真正的网络,它可以训练和用于一个真正的问题。
一个真正的实现:XOR问题
假设我们必须建立一个网来教授古典XOR问题。在本示例中,网络必须学习以下XOR真值表:
输入1 | 输入2 | 输出 |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
所以,我们必须创建一个包含这个值的文件:
0.0; 0.0; 0.0; 1.0; 1.0 1.0; 0.0; 1.0 1.0; 1.0; 0.0
每个列必须用分号分隔; 如果数字是整数,小数点不是强制的。使用文本编辑器编写此文件并将其保存在文件系统(例如Windows环境中的c:\ joone \ xor.txt)中。现在我们将建立神经网络,正如文学说,必须有三层:
- 具有2个神经元的输入层,以映射XOR函数的两个输入。
- 隐藏层有3个神经元,一个很好的价值,以加快网的收敛。
- 具有1个神经元的输出层,以表示XOR函数的输出。
如下图所示:
首先,我们创建三个层(其中两个使用Sigmoid传递函数):
LinearLayer input = new LinearLayer(); SigmoidLayer hidden = new SigmoidLayer(); SigmoidLayer output = new SygmoidLayer();
设置尺寸:
input.setRows(2); hidden.setRows(3); output.setRows(1);
现在我们建立连接层的神经网络,所以我们创建两个突触; 我们使用FullSynapse,将其输入上的所有神经元与其输出上的所有神经元连接(见上图):
FullSynapse synapse_IH = new FullSynapse(); / * Input - > Hidden conn。* / FullSynapse synapse_HO = new FullSynapse(); / * Hidden - > Output conn。* /
首先,我们连接输入层和隐藏层:
input.addOutputSynapse(synapse_IH); hidden.addInputSynapse(synapse_IH);
然后,隐藏层与输出层:
hidden.addOutputSynapse(synapse_HO); output.addInputSynapse(synapse_HO);
创建NeuralNet对象并添加图层:
NeuralNet nnet = new NeuralNet(); nnet.addLayer(input,NeuralNet.INPUT_LAYER); nnet.addLayer(hidden,NeuralNet.HIDDEN_LAYER); nnet.addLayer(output,NeuralNet.OUTPUT_LAYER);
现在我们提取Monitor对象的引用,以便为网络提供其工作所需的所有参数:
Monitor monitor = nnet.getMonitor(); monitor.setLearningRate(0.7); monitor.setMomentum(0.5);
应用程序将自身注册为监听器的监听器,因此它可以从网络接收终止的通知。为此,应用程序必须实现org.joone.engine.NeuralNetListener接口。
monitor.addNeuralNetListener(this);
现在我们必须为网络定义一个输入,然后我们创建一个org.joone.io.FileInputStream并给它所有的参数:
FileInputSynapse inputStream = new FileInputSynapse(); / *前两列包含输入值* / inputStream.setAdvancedColumnSelector(“1,2”); / *这是包含输入数据的文件* / inputStream.setInputFile(new File(“#topofpage”));
我们将输入突触添加到第一层。输入突触扩展了Synapse对象,然后它可以连接到一个层,如突触; 所以图层不处理其输入对象的种类。
input.addInputSynapse(inputStream);
神经网可以从例子中学习,所以我们必须向它提供正确的答案。对于每个输入,事实上,网络必须提供期望的响应和从网络给出的有效响应之间的差;org.joone.engine.learning.TeachingSynapse是具有此任务的对象:
TeachingSynapse(); / *设置包含所需响应的文件,由FileInputSynapse * / FileInputSynapse samples = new FileInputSynapse(); samples.setInputFile(new File(“#topofpage”)); trainer.setDesired(samples); / *输出值在文件的第三列* / samples.setAdvancedColumnSelector(“3”); / *我们将它添加到神经网络* / nnet.setTeacher(教练);
TeacherSynapse对象扩展了Synapse对象,然后我们可以将其添加为网络的最后一层的输出。
output.addOutputSynapse(trainer);
我们设置网络的所有训练参数:
monitor.setTrainingPatterns(4); / *输入文件中包含的行数* / monitor.setTotCicles(2000); / *网络必须在输入模式上训练多少次* / monitor.setLearning(true); / *网必须训练* / nnet.go(); / *网络启动培训作业* /
(您可以在CVS存储库中找到源代码到org.joone.example包中)
如果这个例子看起来太复杂了(它只有一个小的网,只有5个神经元!),记住这是一个低级的方法; 这里我们只使用java中的核心引擎编码。你可以用以下三种方式(按难度递减排序)用joone构建神经网络:
- 像上面的例子,通过编写使用核心引擎的java代码
- 通过使用JooneTools帮助类来简化神经网络的使用,通过隐藏核心引擎的复杂性
- 通过使用Joone提供的GUI编辑器(单击此处查看使用编辑器构建的XOR问题)