Inleiding tot Neuroph

1. Inleiding

Dit artikel gaat in op Neuroph - een open-sourcebibliotheek voor het maken van neurale netwerken en het gebruik van machine learning.

In het artikel bekijken we de kernbegrippen en verschillende voorbeelden om alles samen te stellen.

2. Neuroph

We kunnen communiceren met Neuroph door:

  • een GUI-gebaseerde tool
  • een Java-bibliotheek

Beide benaderingen steunen op een onderliggende klassenhiërarchie die kunstmatige neurale netwerken bouwt uit lagen van neuronen.

We zullen ons concentreren op de programmatische kant, maar zullen verwijzen naar verschillende gedeelde klassen uit de GUI-gebaseerde benadering van Neuroph om te helpen verduidelijken wat we doen.

Raadpleeg de Neuroph-documentatie voor meer informatie over de GUI-gebaseerde benadering.

2.1. Afhankelijkheden

Als we Neuroph willen gebruiken, moeten we het volgende Maven-item toevoegen:

 org. beykery neuroph 2.92 

De meest recente versie is te vinden op Maven Central.

3. Belangrijkste klassen en concepten

Alle gebruikte conceptuele basisbouwstenen hebben overeenkomstige Java-klassen.

Neuronen zijn verbonden met Lagen die vervolgens worden gegroepeerd in NeuralNetworks. NeuralNetworks worden vervolgens getraind met Leerregels en Datasets.

3.1. Neuron

De Neuron klasse heeft vier primaire kenmerken:

  1. inputAansluiting: gewogen verbindingen tussen Neuronen
  2. input Functie: specificeert gewichten en vector sommen toegepast op inkomende verbindingsgegevens
  3. transferFunctie: specificeert gewichten en vector sommen toegepast op uitgaande gegevens

  4. output: de outputwaarde die het resultaat is van de toepassing van transferFunctions en inputFuncties aan een inputConnection

Samen bepalen deze vier primaire kenmerken het gedrag:

output = transferFunction (inputFunction (inputConnections));

3.2. Laag

Lagen zijn in wezen groepen van Neuronen zodat elk Neuron in de Laag is (meestal) alleen verbonden met Neuronen in de voorgaande en volgende Lagen.

Lagengeef daarom informatie tussen hen door via de gewogen functies die op hun bestaan Neuronen.

Neuronen kan aan lagen worden toegevoegd:

Laaglaag = nieuwe laag (); layer.addNeuron (n);

3.3. NeuralNetwork

De superklasse van het hoogste niveau NeuralNetwork is onderverdeeld in verschillende bekende soorten kunstmatige neurale netwerken, waaronder convolutionele neurale netwerken (subklasse Convolutioneel netwerk), Hopfield neurale netwerken (subklasse Hopfield), en meerlagige perceptron neurale netwerken (subklasse Meerlagig Perceptron).

Alle NeuralNetworks zijn samengesteld uit Lagen die meestal zijn georganiseerd in een trichotomie:

  1. invoerlagen
  2. verborgen lagen
  3. uitvoerlagen

Als we de constructor van een subklasse van NeuralNetwork (zoals Perceptron), kunnen we de Laags, het aantal Neurons voor elk Laag, en hun index met behulp van deze eenvoudige methode:

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

Soms willen we dit handmatig doen (en het is goed om te zien wat er onder de motorkap gebeurt). De basisbewerking om een Laag naar een NeuralNetwork wordt als volgt bereikt:

NeuralNetwork ann = nieuw NeuralNetwork (); Laaglaag = nieuwe laag (); ann.addLayer (0, laag); ann.setInputNeurons (layer.getNeurons ()); 

Het eerste argument specificeert de index van de Laag in de NeuralNetwork; het tweede argument specificeert de Laag zelf. Lagen handmatig toegevoegd moet worden aangesloten met behulp van de ConnectionFactory klasse:

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

De eerste en laatste Laag moet ook worden aangesloten:

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

Onthoud dat de kracht en kracht van a NeuralNetwork zijn grotendeels afhankelijk van:

  1. het aantal Lagen in de NeuralNetwork
  2. het aantal Neuronen in elke Laag (en de gewogen functies tussen hen), en
  3. de effectiviteit van de trainingsalgoritmen / nauwkeurigheid van de DataSet

3.4. Training Our NeuralNetwork

NeuralNetworks zijn getraind met behulp van de DataSet en Leerregel klassen.

DataSet wordt gebruikt voor het weergeven en leveren van de informatie die moet worden geleerd of gebruikt om de NeuralNetwork. Datasets worden gekenmerkt door hun input size, output size, en rijen (DataSetRow).

int inputSize = 2; int outputSize = 1; DataSet ds = nieuwe DataSet (inputSize, outputSize); DataSetRow rOne = nieuwe DataSetRow (nieuwe dubbele [] {0, 0}, nieuwe dubbele [] {0}); ds.addRow (rOne); DataSetRow rTwo = nieuwe DataSetRow (nieuwe dubbele [] {1, 1}, nieuwe dubbele [] {0}); ds.addRow (rTwo);

Leerregel specificeert de manier waarop de DataSet wordt gegeven of getraind door de NeuralNetwork. Subklassen van Leerregel omvatten TerugPropagation en Leren onder toezicht.

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

4. Alles samenvoegen

Laten we nu die bouwstenen samenvoegen tot een echt voorbeeld. We gaan beginnen het combineren van verschillende lagen tot het vertrouwde invoerlaag, verborgen laag, en output laag patroon geïllustreerd door de meeste neurale netwerkarchitecturen.

4.1. Lagen

We zullen onze monteren NeuralNetwork door vier lagen te combineren. Ons doel is om een ​​(2, 4, 4, 1) NeuralNetwork.

Laten we eerst onze invoerlaag definiëren:

Laag inputLayer = nieuwe laag (); inputLayer.addNeuron (nieuwe Neuron ()); inputLayer.addNeuron (nieuwe Neuron ());

Vervolgens implementeren we verborgen laag één:

Laag hiddenLayerOne = nieuwe laag (); hiddenLayerOne.addNeuron (nieuwe Neuron ()); hiddenLayerOne.addNeuron (nieuwe Neuron ()); hiddenLayerOne.addNeuron (nieuwe Neuron ()); hiddenLayerOne.addNeuron (nieuwe Neuron ());

En verborgen laag twee:

Laag hiddenLayerTwo = nieuwe laag (); hiddenLayerTwo.addNeuron (nieuwe Neuron ()); hiddenLayerTwo.addNeuron (nieuwe Neuron ()); hiddenLayerTwo.addNeuron (nieuwe Neuron ()); hiddenLayerTwo.addNeuron (nieuwe Neuron ());

Ten slotte definiëren we onze uitvoerlaag:

Laag outputLayer = nieuwe laag (); outputLayer.addNeuron (nieuwe Neuron ()); 

4.2. NeuralNetwork

Vervolgens kunnen we ze samenvoegen tot een NeuralNetwork:

NeuralNetwork ann = nieuw 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. Opleiding

Laten we voor trainingsdoeleinden een DataSet door de grootte van zowel de invoer- als de resulterende uitvoervector op te geven:

int inputSize = 2; int outputSize = 1; DataSet ds = nieuwe DataSet (inputSize, outputSize);

We voegen een elementaire rij toe aan onze DataSet het naleven van de invoer- en uitvoerbeperkingen die hierboven zijn gedefinieerd - ons doel in dit voorbeeld is om ons netwerk te leren basis XOR (exclusieve of) bewerkingen uit te voeren:

DataSetRow rOne = nieuwe DataSetRow (nieuwe dubbele [] {0, 1}, nieuwe dubbele [] {1}); ds.addRow (rOne); DataSetRow rTwo = nieuwe DataSetRow (nieuwe dubbele [] {1, 1}, nieuwe dubbele [] {0}); ds.addRow (rTwo); DataSetRow rThree = nieuwe DataSetRow (nieuwe dubbele [] {0, 0}, nieuwe dubbele [] {0}); ds.addRow (rThree); DataSetRow rFour = nieuwe DataSetRow (nieuwe dubbele [] {1, 0}, nieuwe dubbele [] {1}); ds.addRow (rFour);

Laten we vervolgens onze NeuralNetwork met de ingebouwde TerugPropogation LearningRule:

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

4.4. Testen

Nu dat onze NeuralNetwork is opgeleid, laten we het uittesten. Voor elk paar logische waarden die in ons zijn doorgegeven DataSet als een DataSetRowvoeren we de volgende test uit:

ann.setInput (0, 1); ann.calculate (); double [] networkOutputOne = ann.getOutput (); 

Een belangrijk ding om te onthouden is dat NeuralNetworks Voer alleen een waarde uit op het inclusieve interval van 0 en 1. Om een ​​andere waarde uit te voeren, moeten we normaliseren en denormaliseren onze gegevens.

In dit geval zijn voor logische bewerkingen 0 en 1 perfect voor de taak. De output zal zijn:

Testen: 1, 0 Verwacht: 1,0 Resultaat: 1,0 Testen: 0, 1 Verwacht: 1,0 Resultaat: 1,0 Testen: 1, 1 Verwacht: 0,0 Resultaat: 0,0 Testen: 0, 0 Verwacht: 0,0 Resultaat: 0,0 

We zien dat onze NeuralNetwork voorspelt met succes het juiste antwoord!

5. Conclusie

We hebben zojuist de basisconcepten en klassen besproken die door Neuroph worden gebruikt.

Meer informatie over deze bibliotheek is hier beschikbaar, en de codevoorbeelden die in dit artikel worden gebruikt, zijn te vinden op GitHub.