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:
- inputAansluiting: gewogen verbindingen tussen Neuronen
- input Functie: specificeert gewichten en vector sommen toegepast op inkomende verbindingsgegevens
- transferFunctie: specificeert gewichten en vector sommen toegepast op uitgaande gegevens
- 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: 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: 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: 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: 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: De eerste en laatste Laag moet ook worden aangesloten: Onthoud dat de kracht en kracht van a NeuralNetwork zijn grotendeels afhankelijk van: 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). Leerregel specificeert de manier waarop de DataSet wordt gegeven of getraind door de NeuralNetwork. Subklassen van Leerregel omvatten TerugPropagation en Leren onder toezicht. 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. 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: Vervolgens implementeren we verborgen laag één: En verborgen laag twee: Ten slotte definiëren we onze uitvoerlaag: Vervolgens kunnen we ze samenvoegen tot een NeuralNetwork: Laten we voor trainingsdoeleinden een DataSet door de grootte van zowel de invoer- als de resulterende uitvoervector op te geven: 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: Laten we vervolgens onze NeuralNetwork met de ingebouwde TerugPropogation LearningRule: 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: 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: We zien dat onze NeuralNetwork voorspelt met succes het juiste antwoord! 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.Laaglaag = nieuwe laag (); layer.addNeuron (n);
3.3. NeuralNetwork
NeuralNetwork ann = nieuwe Perceptron (2, 4, 1);
NeuralNetwork ann = nieuw NeuralNetwork (); Laaglaag = nieuwe laag (); ann.addLayer (0, laag); ann.setInputNeurons (layer.getNeurons ());
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 ());
3.4. Training Our NeuralNetwork
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);
NeuralNetwork ann = nieuw NeuralNetwork (); // ... BackPropagation backPropagation = nieuwe BackPropagation (); backPropagation.setMaxIterations (1000); ann.learn (ds, backPropagation);
4. Alles samenvoegen
4.1. Lagen
Laag inputLayer = nieuwe laag (); inputLayer.addNeuron (nieuwe Neuron ()); inputLayer.addNeuron (nieuwe Neuron ());
Laag hiddenLayerOne = nieuwe laag (); hiddenLayerOne.addNeuron (nieuwe Neuron ()); hiddenLayerOne.addNeuron (nieuwe Neuron ()); hiddenLayerOne.addNeuron (nieuwe Neuron ()); hiddenLayerOne.addNeuron (nieuwe Neuron ());
Laag hiddenLayerTwo = nieuwe laag (); hiddenLayerTwo.addNeuron (nieuwe Neuron ()); hiddenLayerTwo.addNeuron (nieuwe Neuron ()); hiddenLayerTwo.addNeuron (nieuwe Neuron ()); hiddenLayerTwo.addNeuron (nieuwe Neuron ());
Laag outputLayer = nieuwe laag (); outputLayer.addNeuron (nieuwe Neuron ());
4.2. 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
int inputSize = 2; int outputSize = 1; DataSet ds = nieuwe DataSet (inputSize, outputSize);
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);
BackPropagation backPropagation = nieuwe BackPropagation (); backPropagation.setMaxIterations (1000); ann.learn (ds, backPropagation);
4.4. Testen
ann.setInput (0, 1); ann.calculate (); double [] networkOutputOne = ann.getOutput ();
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
5. Conclusie