Въведение в Neuroph

1. Въведение

Тази статия разглежда Neuroph - библиотека с отворен код за създаване на невронни мрежи и използване на машинно обучение.

В статията ще разгледаме основните понятия и няколко примера за това как да съберем всичко това.

2. Невроф

Можем да взаимодействаме с Neuroph, като използваме:

  • инструмент, базиран на GUI
  • Java библиотека

И двата подхода разчитат на основната йерархия на класа, която изгражда изкуствени невронни мрежи от слоеве неврони .

Ще се съсредоточим върху програмната страна, но ще се позовем на няколко споделени класа от базирания на GUI подход на Neuroph, за да изясним какво правим.

За повече информация относно подхода, базиран на GUI, разгледайте документацията на Neuroph.

2.1. Зависимости

Ако за да използвате Neuroph, трябва да добавим следния запис на Maven:

 org.beykery neuroph 2.92 

Най-новата версия може да бъде намерена на Maven Central.

3. Основни класове и концепции

Всички използвани основни концептуални градивни блокове имат съответни Java класове.

Невроните са свързани със слоеве, които след това се групират в NeuralNetworks . Впоследствие NeuralNetworks се обучават с помощта на LearningRules и DataSets .

3.1. Неврон

Класът Neuron има четири основни атрибута:

  1. inputConnection: претеглени връзки между невроните
  2. inputFunction: указва тегла и векторни суми, приложени към входящи данни за връзка
  3. transferFunction: указва тегла и векторни суми, приложени към изходящи данни

  4. output: изходната стойност, получена от прилагането на transferFunctions и inputFunctions към inputConnection

Заедно тези четири основни атрибута установяват поведението:

output = transferFunction(inputFunction(inputConnections));

3.2. Слой

Слоевете са по същество групи от неврони , така че всяка Neuro п в слой е (обикновено), свързан само с неврони в предходните и следващите слоеве .

Следователно слоевете предават информация помежду си чрез претеглените функции, които съществуват на техните неврони .

Невроните могат да се добавят към слоеве:

Layer layer = new Layer(); layer.addNeuron(n);

3.3. NeuralNetwork

Най-високо ниво суперкласа NeuralNetwork се subclassed на няколко познати видове невронни мрежи, включително конволюционен невронни мрежи (подклас ConvolutionalNetwork ), Hopfield невронни мрежи (подклас Hopfield ) и многослойни перцептрон невронни мрежи (подклас MultilayerPerceptron ).

Всички NeuralNetworks са съставени от слоеве, които обикновено са организирани в трихотомия:

  1. входни слоеве
  2. скрити слоеве
  3. изходни слоеве

Ако използваме конструктора на подклас на NeuralNetwork (като Perceptron ), можем да предадем Layer s, броя на Neuron s за всеки слой и техния индекс, използвайки този прост метод:

NeuralNetwork ann = new Perceptron(2, 4, 1);

Понякога ще искаме да направим това ръчно (и е добре да видим какво се случва под капака). Основната операция за добавяне на слой към NeuralNetwork се извършва по следния начин:

NeuralNetwork ann = new NeuralNetwork(); Layer layer = new Layer(); ann.addLayer(0, layer); ann.setInputNeurons(layer.getNeurons()); 

Първият аргумент указва индекса на слоя в NeuralNetwork ; вторият аргумент определя самия слой . Добавените ръчно слоеве трябва да бъдат свързани чрез клас ConnectionFactory :

ann.addLayer(0, inputLayer); ann.addLayer(1, hiddenLayerOne); ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));

Първият и последният слой също трябва да бъдат свързани:

ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(ann.getLayersCount() - 1), false); ann.setOutputNeurons(ann.getLayerAt( ann.getLayersCount() - 1).getNeurons());

Не забравяйте, че силата и мощта на NeuralNetwork до голяма степен зависят от:

  1. броят на слоевете в NeuralNetwork
  2. броя на невроните във всеки слойпретеглените функции между тях), и
  3. ефективността на обучителните алгоритми / точността на DataSet

3.4. Обучение на нашата NeuralNetwork

NeuralNetworks се обучават с помощта на класовете DataSet и LearningRule .

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 определя начина, по който DataSet се преподава или обучава от NeuralNetwork . Подкласовете на LearningRule включват BackPropagation и SupervisorLearning .

NeuralNetwork ann = new NeuralNetwork(); //... BackPropagation backPropagation = new BackPropagation(); backPropagation.setMaxIterations(1000); ann.learn(ds, backPropagation);

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

We'll assemble our NeuralNetwork by combining four layers. Our goal is to build a (2, 4, 4, 1) NeuralNetwork.

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

Next, we can put them together into a 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

For training purposes, let's put together a DataSet by specifying the size of both the input and resulting output vector:

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:

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:

BackPropagation backPropagation = new BackPropagation(); backPropagation.setMaxIterations(1000); ann.learn(ds, backPropagation); 

4.4. Testing

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:

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.

In this case, for logical operations, 0 and 1 are perfect for the job. The output will be:

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

We've just reviewed the basic concepts and classes used by Neuroph.

Further information on this library is available here, and the code examples used in this article can be found over on GitHub.