1. Introduction
1.介绍
This article takes a look at Neuroph – an open-source library for creating neural networks and utilizing machine learning.
本文介绍了Neuroph–一个用于创建神经网络和利用机器学习的开源库。
In the article, we have a look at the core concepts and several examples on how to put it all together.
在文章中,我们看了一下核心概念和几个关于如何把它放在一起的例子。
2. Neuroph
2.神经学
We can interact with Neuroph using:
我们可以用以下方式与Neuroph互动。
- a GUI-based tool
- a Java library
Both approaches rely on an underlying class hierarchy which builds artificial neural networks out of layers of neurons.
这两种方法都依赖于一个底层的类层次结构,它从神经元层中建立了人工神经网络。
We’ll focus on the programmatic side but will refer to several shared classes from Neuroph’s GUI-based approach to help clarify what we’re doing.
我们将专注于编程方面,但会参考Neuroph基于GUI的方法中的几个共享类,以帮助澄清我们在做什么。
For more on the GUI-based approach, take a look at the Neuroph documentation.
关于基于GUI的方法的更多信息,请看Neuroph 文档。
2.1. Dependencies
2.1.依赖性
If order to use Neuroph, we need to add the following Maven entry:
如果要使用Neuroph,我们需要添加以下Maven条目。
<dependency>
<groupId>org.beykery</groupId>
<artifactId>neuroph</artifactId>
<version>2.92</version>
</dependency>
The most recent version can be found on Maven Central.
最新的版本可以在Maven中心找到,。
3. Key Classes and Concepts
3.关键类和概念
All of the basic conceptual building blocks used have corresponding Java classes.
所有使用的基本概念构建块都有相应的Java类。
Neurons are connected to Layers which are then grouped into NeuralNetworks. NeuralNetworks are subsequently trained using LearningRules and DataSets.
神经元被连接到层,然后被分组为神经网络。神经网络随后使用学习规则和数据集进行训练。
3.1. Neuron
3.1.神经元
The Neuron class has four primary attributes:
神经元类有四个主要属性。
- inputConnection: weighted connections between Neurons
- inputFunction: specifies weights and vector sums applied to incoming connection data
- transferFunction: specifies weights and vector sums applied to outgoing data
- output: the output value resulting from the application of transferFunctions and inputFunctions to an inputConnection
Together those four primary attributes establish the behavior:
这四个主要属性共同确立了该行为。
output = transferFunction(inputFunction(inputConnections));
3.2. Layer
3.2.层
Layers are essentially groupings of Neurons such that each Neuron in the Layer is (usually) only connected with Neurons in the preceding and subsequent Layers.
层基本上是神经元的分组,这样层中的每个神经元n(通常)只与前面和后面层中的神经元相连。
Layers, therefore, pass information between them through the weighted functions that exist on their Neurons.
因此,层通过其神经元上存在的加权函数,在它们之间传递信息。
Neurons can be added to layers:
神经元可以被添加到层中:
Layer layer = new Layer();
layer.addNeuron(n);
3.3. NeuralNetwork
3.3.神经网络
The top-level superclass NeuralNetwork is subclassed into several familiar kinds of artificial neural networks including convolutional neural networks (subclass ConvolutionalNetwork), Hopfield neural networks (subclass Hopfield), and multilayer perceptron neural networks (subclass MultilayerPerceptron).
顶层超类NeuralNetwork被子类化为几种熟悉的人工神经网络,包括卷积神经网络(子类ConvolutionalNetwork)、Hopfield神经网络(子类Hopfield),以及多层感知器神经网络(子类MultilayerPerceptron)。
All NeuralNetworks are composed of Layers which are usually organized into a trichotomy:
所有神经网络都是由层组成的,这些层通常被组织成一个三分法。
- input layers
- hidden layers
- output layers
If we are using the constructor of a subclass of NeuralNetwork (such as Perceptron), we can pass the Layers, the number of Neurons for each Layer, and their index using this simple method:
如果我们使用NeuralNetwork的子类(如Perceptron)的构造函数,我们可以使用这个简单的方法传递Layers、每个Layer的Neurons数量以及它们的索引。
NeuralNetwork ann = new Perceptron(2, 4, 1);
Sometimes we’ll want to do this manually (and it’s good to see what’s going on underneath the hood). The basic operation to add a Layer to a NeuralNetwork is accomplished like this:
有时我们会想手动完成这个任务(看看引擎盖下面是什么情况也不错)。向神经网络添加层的基本操作是这样完成的。
NeuralNetwork ann = new NeuralNetwork();
Layer layer = new Layer();
ann.addLayer(0, layer);
ann.setInputNeurons(layer.getNeurons());
The first argument specifies the index of the Layer in the NeuralNetwork; the second argument specifies the Layer itself. Layers added manually should be connected using the ConnectionFactory class:
第一个参数指定Layer在NeuralNetwork中的索引;第二个参数指定Layer本身。手动添加的Layer应使用ConnectionFactory类进行连接。
ann.addLayer(0, inputLayer);
ann.addLayer(1, hiddenLayerOne);
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));
The first and last Layer should also be connected:
第一个和最后一个层也应该被连接。
ConnectionFactory.fullConnect(ann.getLayerAt(0),
ann.getLayerAt(ann.getLayersCount() - 1), false);
ann.setOutputNeurons(ann.getLayerAt(
ann.getLayersCount() - 1).getNeurons());
Remember that the strength and power of a NeuralNetwork are largely dependent on:
请记住,神经网络的强度和功率主要取决于。
- the number of Layers in the NeuralNetwork
- the number of Neurons in each Layer (and the weighted functions between them), and
- the effectiveness of the training algorithms/accuracy of the DataSet
3.4. Training Our NeuralNetwork
3.4.训练我们的神经网络
NeuralNetworks are trained using the DataSet and LearningRule classes.
神经网络使用DataSet和LearningRule类来训练。
DataSet is used for representing and supplying the information to be learned or used to train the NeuralNetwork. DataSets are characterized by their input size, outputsize, and rows (DataSetRow).
DataSet用于表示和提供要学习的信息或用于训练NeuralNetwork。数据集的特征是其输入大小、输出大小和行(DataSetRow)。
int inputSize = 2;
int outputSize = 1;
DataSet ds = new DataSet(inputSize, outputSize);
DataSetRow rOne
= new DataSetRow(new double[] {0, 0}, new double[] {0});
ds.addRow(rOne);
DataSetRow rTwo
= new DataSetRow(new double[] {1, 1}, new double[] {0});
ds.addRow(rTwo);
LearningRule specifies the way the DataSet is taught or trained by the NeuralNetwork. Subclasses of LearningRule include BackPropagation and SupervisedLearning.
LearningRule规定了DataSet被NeuralNetwork教导或训练的方式。LearningRule的子类包括BackPropagation和SupervisedLearning。
NeuralNetwork ann = new NeuralNetwork();
//...
BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);
4. Putting It All Together
4.把一切都放在一起
Now let’s put those building blocks together into a real example. We’re going to start by combining several layers together into the familiar input layer, hidden layer, and output layer pattern exemplified by most neural network architectures.
现在让我们把这些构件组合到一个真实的例子中。我们将从将几个层组合成熟悉的输入层、隐藏层和输出层模式开始,这是大多数神经网络架构的典范。
4.1. Layers
4.1.层数
We’ll assemble our NeuralNetwork by combining four layers. Our goal is to build a (2, 4, 4, 1) NeuralNetwork.
我们将通过组合四个层来组装我们的神经网络。我们的目标是建立一个(2, 4, 4, 1) 神经网络。
Let’s first define our input layer:
让我们首先定义我们的输入层。
Layer inputLayer = new Layer();
inputLayer.addNeuron(new Neuron());
inputLayer.addNeuron(new Neuron());
Next, we implement hidden layer one:
接下来,我们实现隐藏层一。
Layer hiddenLayerOne = new Layer();
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
And hidden layer two:
还有隐藏的第二层。
Layer hiddenLayerTwo = new Layer();
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
Finally, we define our output layer:
最后,我们定义我们的输出层。
Layer outputLayer = new Layer();
outputLayer.addNeuron(new Neuron());
4.2. NeuralNetwork
4.2.神经网络
Next, we can put them together into a NeuralNetwork:
接下来,我们可以把它们组合成一个NeuralNetwork。
NeuralNetwork ann = new NeuralNetwork();
ann.addLayer(0, inputLayer);
ann.addLayer(1, hiddenLayerOne);
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));
ann.addLayer(2, hiddenLayerTwo);
ConnectionFactory.fullConnect(ann.getLayerAt(1), ann.getLayerAt(2));
ann.addLayer(3, outputLayer);
ConnectionFactory.fullConnect(ann.getLayerAt(2), ann.getLayerAt(3));
ConnectionFactory.fullConnect(ann.getLayerAt(0),
ann.getLayerAt(ann.getLayersCount()-1), false);
ann.setInputNeurons(inputLayer.getNeurons());
ann.setOutputNeurons(outputLayer.getNeurons());
4.3. Training
4.3.培训
For training purposes, let’s put together a DataSet by specifying the size of both the input and resulting output vector:
为了训练的目的,让我们通过指定输入和结果输出向量的大小来组建一个DataSet。
int inputSize = 2;
int outputSize = 1;
DataSet ds = new DataSet(inputSize, outputSize);
We add an elementary row to our DataSet adhering to the input and output constraints defined above – our goal in this example is to teach our network to do basic XOR (exclusive or) operations:
我们向DataSet添加一个基本行,遵守上面定义的输入和输出约束–我们在这个例子中的目标是教我们的网络做基本的XOR(排他性或)操作。
DataSetRow rOne
= new DataSetRow(new double[] {0, 1}, new double[] {1});
ds.addRow(rOne);
DataSetRow rTwo
= new DataSetRow(new double[] {1, 1}, new double[] {0});
ds.addRow(rTwo);
DataSetRow rThree
= new DataSetRow(new double[] {0, 0}, new double[] {0});
ds.addRow(rThree);
DataSetRow rFour
= new DataSetRow(new double[] {1, 0}, new double[] {1});
ds.addRow(rFour);
Next, let’s train our NeuralNetwork with the built in BackPropogation LearningRule:
接下来,让我们用内置的BackPropogation LearningRule训练我们的NeuralNetwork。
BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);
4.4. Testing
4.4.测试
Now that our NeuralNetwork is trained up let’s test it out. For each pair of logical values passed into our DataSet as a DataSetRow, we run the following kind of test:
现在我们的NeuralNetwork已经被训练好了,让我们来测试它。对于作为DataSet的DataSetRow传入的每一对逻辑值,我们运行以下测试。
ann.setInput(0, 1);
ann.calculate();
double[] networkOutputOne = ann.getOutput();
An important thing to remember is that NeuralNetworks only output a value on the inclusive interval of 0 and 1. To output some other value, we must normalize and denormalize our data.
需要记住的一件事是,NeuralNetworks只能在0和1的包容性区间内输出一个值。要输出其他值,我们必须对我们的数据进行normalize和denormalize。
In this case, for logical operations, 0 and 1 are perfect for the job. The output will be:
在这种情况下,对于逻辑运算,0和1是完美的工作。输出结果将是。
Testing: 1, 0 Expected: 1.0 Result: 1.0
Testing: 0, 1 Expected: 1.0 Result: 1.0
Testing: 1, 1 Expected: 0.0 Result: 0.0
Testing: 0, 0 Expected: 0.0 Result: 0.0
We see that our NeuralNetwork successfully predicts the right answer!
我们看到,我们的神经网络成功地预测了正确的答案!
5. Conclusion
5.结论
We’ve just reviewed the basic concepts and classes used by Neuroph.
我们刚刚回顾了Neuroph使用的基本概念和类。
Further information on this library is available here, and the code examples used in this article can be found over on GitHub.