Einführung in Neuroph
1. Einführung
Dieser Artikel befasst sich mitNeuroph - einer Open-Source-Bibliothek zum Erstellen neuronaler Netze und zum Verwenden von maschinellem Lernen.
In diesem Artikel werfen wir einen Blick auf die Kernkonzepte und einige Beispiele, wie man alles zusammensetzt.
2. Neuroph
Wir können mit Neuroph interagieren, indem wir:
-
ein GUI-basiertes Tool
-
eine Java-Bibliothek
Beide Ansätze beruhen auf einer zugrunde liegenden Klassenhierarchie, die künstliche neuronale Netze aus Schichten vonneurons aufbaut.
Wir konzentrieren uns auf die programmatische Seite, beziehen uns jedoch auf mehrere gemeinsame Klassen aus dem GUI-basierten Ansatz von Neuroph, um zu klären, was wir tun.
Weitere Informationen zum GUI-basierten Ansatz finden Sie unter Neurophdocumentation.
2.1. Abhängigkeiten
Um Neuroph nutzen zu können, müssen wir folgenden Maven-Eintrag hinzufügen:
org.beykery
neuroph
2.92
Die neueste Version finden Sie inon Maven Central.
3. Schlüsselklassen und Konzepte
Alle verwendeten grundlegenden konzeptionellen Bausteine verfügen über entsprechende Java-Klassen.
Neurons sind mitLayers verbunden, die dann inNeuralNetworks gruppiert werden. NeuralNetworks werden anschließend mitLearningRules undDataSets trainiert.
3.1. Neuron
Die KlasseNeuronhat vier Hauptattribute:
-
inputConnection: gewichtete Verbindungen zwischenNeurons
-
inputFunction: gibtweights undvector sums an, die auf eingehende Verbindungsdaten angewendet werden
-
transferFunction: gibtweights undvector sums an, die auf ausgehende Daten angewendet werden __
-
output: ist der Ausgabewert, der sich aus der Anwendung vontransferFunctions undinputFunctions aufinputConnection ergibt
Zusammen bestimmen diese vier Hauptattribute das Verhalten:
output = transferFunction(inputFunction(inputConnections));
3.2. Layer
Layers are essentially groupings of Neurons, so dass jedesNeuron inLayer (normalerweise) nur mitNeurons in den vorhergehenden und nachfolgendenLayers verbunden ist.
Layers leiten daher Informationen zwischen ihnen durch die gewichteten Funktionen, die auf ihrenNeurons existieren.
Neurons können zu Ebenen hinzugefügt werden: __
Layer layer = new Layer();
layer.addNeuron(n);
3.3. NeuralNetwork
Die OberklasseNeuralNetwork der obersten Ebene wird in verschiedene bekannte Arten künstlicher neuronaler Netze unterteilt, einschließlich Faltungs-Neuronale Netze (UnterklasseConvolutionalNetwork), Hopfield-Neuronale Netze (UnterklasseHopfield) und Mehrschicht-Perzeptron-Neuronale Netze (UnterklasseMultilayerPerceptron).
All NeuralNetworks are composed of Layers, die normalerweise in einer Trichotomie organisiert sind:
-
Eingabeebenen
-
versteckte Schichten
-
Ausgabeebenen
Wenn wir den Konstruktor einer Unterklasse vonNeuralNetwork (wiePerceptron) verwenden, können wirLayers, die Anzahl vonNeurons für jedesLayer übergeben und ihren Index mit dieser einfachen Methode:
NeuralNetwork ann = new Perceptron(2, 4, 1);
Manchmal möchten wir dies manuell tun (und es ist gut zu sehen, was unter der Haube vor sich geht). Die grundlegende Operation zum Hinzufügen vonLayer zuNeuralNetwork wird folgendermaßen ausgeführt:
NeuralNetwork ann = new NeuralNetwork();
Layer layer = new Layer();
ann.addLayer(0, layer);
ann.setInputNeurons(layer.getNeurons());
Das erste Argument gibt den Index derLayer inNeuralNetwork an; Das zweite Argument gibt dieLayer selbst an. Manuell hinzugefügteLayers sollten mit der KlasseConnectionFactory verbunden werden:
ann.addLayer(0, inputLayer);
ann.addLayer(1, hiddenLayerOne);
ConnectionFactory.fullConnect(ann.getLayerAt(0), ann.getLayerAt(1));
Das erste und das letzteLayer sollten ebenfalls verbunden sein:
ConnectionFactory.fullConnect(ann.getLayerAt(0),
ann.getLayerAt(ann.getLayersCount() - 1), false);
ann.setOutputNeurons(ann.getLayerAt(
ann.getLayersCount() - 1).getNeurons());
Denken Sie daran, dass die Stärke und Leistung von aNeuralNetwork weitgehend abhängt von:
-
die Anzahl vonLayers inNeuralNetwork
-
die Anzahl vonNeurons in jedemLayer (und dieweighted functions zwischen ihnen) und
-
die Effektivität der Trainingsalgorithmen / Genauigkeit derDataSet
3.4. Training UnsereNeuralNetwork
NeuralNetworks werden mit den KlassenDataSet undLearningRule trainiert.
DataSet wird zum Darstellen und Bereitstellen der zu lernenden Informationen oder zum Trainieren derNeuralNetwork verwendet. DataSets sind durch ihreinput size, outputsize, und Zeilen(DataSetRow). gekennzeichnet
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 gibt an, wieDataSet vonNeuralNetwork unterrichtet oder trainiert wird. Unterklassen vonLearningRule umfassenBackPropagation undSupervisedLearning.
NeuralNetwork ann = new NeuralNetwork();
//...
BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);
4. Alles zusammenfügen
Lassen Sie uns nun diese Bausteine zu einem echten Beispiel zusammenfügen. Wir beginnen mitcombining several layers together into the familiar input layer, hidden layer, and output layer pattern, die durch die meisten neuronalen Netzwerkarchitekturen veranschaulicht werden.
4.1. Schichten
Wir setzen unsereNeuralNetwork zusammen, indem wir vier Schichten kombinieren. Unser Ziel ist es, a (2, 4, 4, 1)NeuralNetwork. zu bauen
Definieren wir zunächst unsere Eingabeebene:
Layer inputLayer = new Layer();
inputLayer.addNeuron(new Neuron());
inputLayer.addNeuron(new Neuron());
Als nächstes implementieren wir die verborgene Ebene eins:
Layer hiddenLayerOne = new Layer();
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
hiddenLayerOne.addNeuron(new Neuron());
Und versteckte Schicht zwei:
Layer hiddenLayerTwo = new Layer();
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
hiddenLayerTwo.addNeuron(new Neuron());
Zuletzt definieren wir unsere Ausgabeebene:
Layer outputLayer = new Layer();
outputLayer.addNeuron(new Neuron());
4.2. NeuralNetwork
Als nächstes können wir sie zu einemNeuralNetwork zusammenfügen:
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. Ausbildung
Für Trainingszwecke setzen wir einDataSet zusammen, indem wir die Größe sowohl des Eingabe- als auch des resultierenden Ausgabevektors angeben:
int inputSize = 2;
int outputSize = 1;
DataSet ds = new DataSet(inputSize, outputSize);
Wir fügen unserenDataSeteine elementare Zeile hinzu, die den oben definierten Eingabe- und Ausgabeeinschränkungen entspricht. Unser Ziel in diesem Beispiel ist es, unserem Netzwerk beizubringen, grundlegende XOR-Operationen (exklusiv oder) auszuführen:
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);
Als nächstes trainieren wir unsereNeuralNetwork mit den eingebautenBackPropogation LearningRule:
BackPropagation backPropagation = new BackPropagation();
backPropagation.setMaxIterations(1000);
ann.learn(ds, backPropagation);
4.4. Testen
Nachdem unserNeuralNetwork trainiert ist, testen wir es. Für jedes Paar logischer Werte, die alsDataSetRow an unsereDataSet übergeben werden, führen wir die folgende Art von Test durch:
ann.setInput(0, 1);
ann.calculate();
double[] networkOutputOne = ann.getOutput();
Ein wichtiger Punkt ist, dassNeuralNetworks only output a value on the inclusive interval of 0 and 1. Um einen anderen Wert auszugeben, müssen wirnormalize unddenormalize unserer Daten.
In diesem Fall sind für logische Operationen 0 und 1 für den Job perfekt. Die Ausgabe wird sein:
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
Wir sehen, dass unsereNeuralNetwork erfolgreich die richtige Antwort vorhersagen!
5. Fazit
Wir haben gerade die grundlegenden Konzepte und Klassen von Neuroph überprüft.
Weitere Informationen zu dieser Bibliothek finden Sie unterhere. Die in diesem Artikel verwendeten Codebeispiele finden Sie unterover on GitHub.