Einführung in Neuroph

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:

  1. inputConnection: gewichtete Verbindungen zwischenNeurons

  2. inputFunction: gibtweights undvector sums an, die auf eingehende Verbindungsdaten angewendet werden

  3. transferFunction: gibtweights undvector sums an, die auf ausgehende Daten angewendet werden __

  4. 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:

  1. Eingabeebenen

  2. versteckte Schichten

  3. 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:

  1. die Anzahl vonLayers inNeuralNetwork

  2. die Anzahl vonNeurons in jedemLayer (und dieweighted functions zwischen ihnen) und

  3. 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.