# Neuronales Netz



## Feeder (31. Jul 2018)

Hey,

ich schreibe ein kleines Netz und benutze dafür die Bibliothek Neuroph. Inputdaten sind dabie Dinge wie:

Spielerposition, Gegnerposition, Geschwindigkeit, Größe, aber auch die letzte Eingabe des Spielers...

die Ausgabe soll dann eine "Kraft" mit x,y sein, die dann den Spieler bewegt.
Ich nehme die Inputdaten wie folgt auf:

1. Mensch drückt <r>
2. Aufnahme beginnt und nimmt nun in jedem Spieldurchlauf (Durchlauf der Gameloop) alle Daten auf (speichert sie)
3. Nach ca 1 minute hat man dann ca. 5000 Trainingsdaten (vllt overfittet das Netzwerk?)
    Sollte ich dafür die Liste mal etwas mischen, schließlich lernt es immer 20-30 ähnliche Beispiele

Leider konvergiert das folgende Netz nicht. Vorschläge:?



```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import java.util.ArrayList;
import java.util.Arrays;
import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.learning.error.MeanSquaredError;

import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;

import suchtytv.complexservice.game.maths.VectorND;

public class GamePlayingNetwork  {
    MultiLayerPerceptron nn;
    public GamePlayingNetwork(int inputNodes, int outPutNodes) {
 

        nn = new MultiLayerPerceptron(inputNodes,50,50,outPutNodes); //create NN  with 48 inputNodes and 2 outputNodes
        for(Layer l : nn.getLayers()) {
            for(Neuron n : l.getNeurons()) {
                n.setTransferFunction(new TransferFunction() { //recalibrate Sigmoid for better use !!! Library never asked about derivative: f' =  2*simoid' !!!
            
                    @Override
                    public double getOutput(double totalInput) {
                        // TODO Auto-generated method stub
                        return 2/(1+Math.exp(-totalInput))-1; //sigmoid between -1 and 1
                    }
            });
                System.out.println(n.getInputConnections().size());
            }
        }
        BackPropagation bp = new BackPropagation();
        bp.setLearningRate(0.5); //In any case points will beconverging to a to big local minima (if they are converging)
        bp.setErrorFunction(new MeanSquaredError()); //should I use a linearity?
        bp.setMaxIterations(100);
        nn.setLearningRule(bp);

    }
 
    public void train(ArrayList<VectorND> samples) { //Train the network
        System.out.println("Training with "+ samples.size() + " sample(s)... this could take a while ");

        DataSet set = new DataSet(47, 2);
        for(VectorND nd : samples) {
        double[] all = nd.getArray();
        double[] input  = Arrays.copyOfRange(all, 0, 47);
        double[] output  = Arrays.copyOfRange(all, 47, 49); //VectorND is just a multidimensional Vector including the data
        set.addRow(input, output);
 
 
        }
        //set.shuffle() does not help either
        nn.learn(set);
//        nn.getLearningRule().setLearningRate(nn.getLearningRule().getLearningRate() - 0.5*nn.getLearningRule().getLearningRate());
        System.out.println("Training Done");
    }

    public MultiLayerPerceptron getNeuralNetwork() {
        return nn;
 
    }

    public void setInput() {
 
 
    }

    public void setInput(double[] array) {
        nn.setInput(array);
 
    }

    public VectorND getOutput() {
        // TODO Auto-generated method stub
        double[] b = nn.getOutput();
        VectorND nd = new VectorND();
        nd.add(b);
        return nd;
    }
 
 

}
```


----------



## Xyz1 (31. Jul 2018)

Überwachtes Lernen mit Lehrer oder ohne?


----------



## Feeder (31. Jul 2018)

DerWissende hat gesagt.:


> Überwachtes Lernen mit Lehrer oder ohne?



Hey, danke für deine Antwort  
Ich vermute mal ohne - wenn ich nicht irgendetwas dummes eingegeben habe. ich haben mich aber mit supervised learning nicht beschäftigt. Habe den Code nochmal kommentiert


----------



## Xyz1 (31. Jul 2018)

Ich schaus mir später an wo da der Hase im Pfeffer liegt.


----------



## Feeder (31. Jul 2018)

DerWissende hat gesagt.:


> Ich schaus mir später an wo da der Hase im Pfeffer liegt.


Lass dir Zeit


----------



## Xyz1 (31. Jul 2018)

Ok ich habe ein paar Fragen....
Was sind die Inputdaten?
Was sind Beispielinputdaten?
Was ist das Ziel?
Hast du mal per Hand versucht, die Lernrate herunterzuschrauben und / oder die Iterationen zu erhöhen?
Die Mittlere quadratische Abweichung (`new MeanSquaredError()`) ist schon ok....

Dann noch etwas das ist eigentlich überwachtes Lernen das heißt wenn nicht müsstest du eigentlich die Backpropagation weg lassen. Wie hier zu sehen ist.

Also aus der Hüfte: bp.setLearningRate(0.1); oder bp.setLearningRate(0.01); und bp.setMaxIterations(15000); und der rest SOLLTE vielleicht funktionieren.


----------



## Xyz1 (31. Jul 2018)

Undnoch was.... Warum eigentlich so viele Perzeptronen und um welches Spiel geht es eigentlich?


----------



## Feeder (31. Jul 2018)

Hey, meine Inputs (Beispielinputs sind die Trainingsdaten) sind wie folgt strukturiert:


```
//Aufzeichnen des Spiels, wenn gewollt.
        if(Simulation.recordGame) {
            VectorND nd = new VectorND();
            //Adding PlayerPositions
            nd.addElement(player.getPosition().getX()); //add properties of the player
            nd.addElement(player.getPosition().getY());
            nd.addElement(player.getSpeed().getX());//
            nd.addElement(player.getSpeed().getY());//
            nd.addElement(lastforce.getX()); //add the last force which was applied before
            nd.addElement(lastforce.getY());
            //Adding Position of GameObjects (Maximum) and radius
            for(GameObject o : gameList) {
                if(o instanceof Bird) {
                    Bird b = (Bird)o;
                    nd.addElement(b.getPosition().getX()); //add properties of the birds
                    nd.addElement(b.getPosition().getY()); //
                    nd.addElement(b.getRadius());
                    nd.addElement(b.getSpeed().getX());
                    nd.addElement(b.getSpeed().getY());

                }
            }
            //Adding MousePosition
            nd.addElement(1); //add bias if necessary ?!?!
            force.div(2*forcemultiplier); //Turning force to actual force //just translate values for ANN
            nd.addElement(force.getX());   // add the force the ANN shall apply
            nd.addElement(force.getY()); //
            movieMaker.addData(nd);
        }
        lastforce = force.clone();
```

eine Version des Spiels versuche ich anzuhängen  (selbst programmierter Quatsch )
Ist aber nicht alles kommentiert ;( Du solltest aber selbst kompilieren können

EDIT: Die Datei ist zu groß damit ich sie kompilieren kann

Spielanleitung:

Du bewegst die Kugel mit der Maus.
Du kannst mir <r> eine Trainingaufnahme starten.
Du kannst nachdem du eine Traini ngsaufnahme gestartet hast mit <t> das Netz trainieren
Du kannst mit <p> den Roboter spielen lassen, sobald du das Netz trainiert hatest
Öffne das Spiel mit der Konsole um zusätzliche Infos zu erhalten
Du kannst das Spiel mit Mausklick restarten


----------



## Xyz1 (31. Jul 2018)

Feeder hat gesagt.:


> selbst programmiert Quatsch


Aber es gibt schon einen Sinn in dem Spiel oder? Gleiche anfangsbedingungen? Offen/verdeckt? Gruppenspiel/einzelspiel? Gleichzeitig oder abwechselnd? Und super Frage wann gewinnt man in dem Spiel?


----------



## Xyz1 (31. Jul 2018)

Feeder hat gesagt.:


> Du solltest aber selbst kompilieren können


Vielleicht funktioniert das ja schon mit Beitrag 6 und ich brauch nichts kompilieren.


----------



## Feeder (31. Jul 2018)

JA - das ist einfach ein Survivalgame, überlebe solange wie möglich. Die Anfangsbedingungen sind zufällig. Einzelspiel.

Ich brauchte nur ein einfaches Spiel um das zumachen was ich jetzt mache und da ich momentan eine BeLL schreibe kann ich da nichts zu sehr viel "nicht mathematik" implementieren

Kompiliert habe ich ja - aber wenn du kompilierst ist die Datei nicht zu groß ... srry... 
Ich hab deine Tipps eingebaut - haben nicht geklappt ;(

Trotzdem erst mal danke für die Mühe


----------



## Xyz1 (31. Jul 2018)

Etwas schwierig ein Spiel zu spielen das man nicht kennt....


DerWissende hat gesagt.:


> bp.setLearningRate(0.1); oder bp.setLearningRate(0.01); und bp.setMaxIterations(15000);


Mach das jetzt möcht wissen ob es funktioniert.


----------



## Feeder (31. Jul 2018)

Also:

Mit 0.01 und 15000 hatte ich es bereits probiert und das Training endet nach 3s ohne Erfolg.
Mit 0.1 rechnet er und rechnet und rechnet und rechnet und rechnet und rechnet nur um dann genau das selbe zumachen wie das 0.01 ... Nichts sinnvolles (einfach in eine richtung wegfliegen)

EDIT: Bei dem Netzwerk (49,50,2) rechnet er nochmal viel länger (noch nicht fertig) als bei dem Netzwerk (49,20,20,2)

Danke für deine Antwort 

Gruß Niclas


----------



## Feeder (1. Aug 2018)

EDIT: Auch bei dem Netzwerk (49,50,2) konvergiert nichts.


----------



## mihe7 (1. Aug 2018)

Sind die Daten normalisiert? Verwendest Du Bias-Neuronen?


----------



## Xyz1 (1. Aug 2018)

Gott sei Dank, mihe kennt sich aus 
Was sind nochmal Bias-Neuronen?


----------



## mihe7 (1. Aug 2018)

Auskennen ist da "leicht" übertrieben... und es ist auch ein paar Jährchen her, dass ich mich damit beschäftigt habe. Das Bias-Neuron ist einfach ein zusätzliches Neuron je Layer mit dem konstanten Wert 1. Den genauen Sinn müsste ich jetzt erst nachsehen, sofern ich mich entsinne, hatte das irgendeinen mathematischen Hintergrund. Ich habe mir nur gemerkt, dass man die Daten normalisieren und Bias-Neuronen verwenden soll 

EDIT: hier wird es z. B. beschrieben: https://stackoverflow.com/questions/2480650/role-of-bias-in-neural-networks


----------



## Xyz1 (1. Aug 2018)




----------



## mihe7 (1. Aug 2018)

Ja, im Link zu Stackoverflow (s. oben) ist das ganze noch im Zusammenhang mit der Aktivierungsfunktion dargestellt und ein paar schöne Beispiele sind auch dabei


----------



## Xyz1 (1. Aug 2018)

Wieso kommt da als nächster Videovorschlag "Bares für Rares" bei Youtube? 
Also nochmal kurz zusammenfassen (ich lerne auch besser mit temporell-volativen Skizzen), ein Bias-Neutron ist ein Neutron mit zusätzlichem 1-Eingang.
Zusammen mit der Aktivierungsfunktion, den Funktionssummen und den Lernregel(n) gibt es dann das komplette Neutron.
Und wie sich das auf ein MLP NN auswirkt, weiß keiner....


----------



## mihe7 (1. Aug 2018)

DerWissende hat gesagt.:


> Wieso kommt da als nächster Videovorschlag "Bares für Rares" bei Youtube


Ist das nicht abhängig von den eigenen Vorlieben? 


DerWissende hat gesagt.:


> ein Bias-Neutron ist ein Neutron mit zusätzlichem 1-Eingang.


So könnte man das sagen, würde ich meinen (btw: Neutronen sind was anderes )



DerWissende hat gesagt.:


> Zusammen mit der Aktivierungsfunktion, den Funktionssummen und den Lernregel(n) gibt es dann das komplette Neutron.


Die Lernregeln würde ich weglassen. Das Lernen betrifft ja meist auch kein einzelnes Neuron sondern optimiert ja die Gewichtungen über mehrere Neuronen.



DerWissende hat gesagt.:


> Und wie sich das auf ein MLP NN auswirkt, weiß keiner....


Ach, irgendjemanden wird es schon geben


----------



## Xyz1 (1. Aug 2018)

mihe7 hat gesagt.:


> btw: Neutronen sind was anderes


NICHT NEUTRON SONDERN NEURON !!
verdammt das war die automatische Rechtschreibkorrektur ist mir gar nicht aufgefallen...


mihe7 hat gesagt.:


> Ist das nicht abhängig von den eigenen Vorlieben?


teils teils...


----------



## Feeder (1. Aug 2018)

Hallo,

selbstverständlich habe ich Bias Neuronen verwendet  Und da ich mir zwischenzeitlich auch nicht sicher war, habe ich ein Bias Neuron direkt am Anfang eingefügt 
Ja tatsächlich sind die Daten für 2 * sigmoid -1 angepasst.

Ich wundere mich aber, woher das Programm weiß, wie es im Fall von 2*sigmoid-1 backpropagieren soll (meine AF), da er doch die Ableitung f'(x) = 2sigmoid'(x) nicht kennt


----------



## mihe7 (1. Aug 2018)

Das ist wohl wahr. Wie schaut es mit http://neuroph.sourceforge.net/javadoc/org/neuroph/core/transfer/Sigmoid.html aus?


----------



## Feeder (1. Aug 2018)

Meine Fresse sowas regt mich schon wieder auf - wie kann man denn in der abstrakten Klasse die Ableitungsfunktion definieren... Ich habe das jetzt erstmal angepasst:

```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;

public class BetterSigmoid extends TransferFunction   {

    Sigmoid sig = new Sigmoid();
    @Override
    public double getOutput(double totalInput) {
        // TODO Auto-generated method stub
        return 2/(1+Math.exp(-totalInput))-1; //sigmoid between -1 and 1
        }
    //Warum juckt den mein @Override nicht?
    public double getDerivative(double net) {
        return 2*sig.getDerivative(net);
    
    }

}
```

Leider klappts immer noch net


----------



## Feeder (1. Aug 2018)

Hey, ich habe den Code nochmal abgeändert:


```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;

public class BetterSigmoid extends TransferFunction   {

    Sigmoid sig = new Sigmoid();
    @Override
    public double getOutput(double totalInput) {
        // TODO Auto-generated method stub
        return 2/(1+Math.exp(-totalInput))-1; //sigmoid between -1 and 1
        }

    public double getDerivative(double net) {
        return 2*sig.getOutput(net)*(1-sig.getOutput(net));
       
    }

}
```

Er rechnet jetzt aber schon seit über einer 3/4 Stunde, kann das sein?


----------



## mihe7 (1. Aug 2018)

Rein gefühlsmäßig: ja.


----------



## Feeder (1. Aug 2018)

Hast du noch weitere Vorschläge?, mein Repoirtaire ist erschöpft.


----------



## mihe7 (1. Aug 2018)

Rechnet er noch? Das Zeug dauert teilweise ewig. 
Ansonsten: 
1. neuroph hat doch Tutorials, probiere doch die mal aus (umgesetzt in Java-Code). Da sollten sich die Ergebnisse doch vergleichen lassen. 
2. Standard-Sigmoid verwenden
3. Neuronen reduzieren
4. Daten reduzieren (nur wegen Zeit)

Es gibt auch noch die Möglichkeit, Daten zu "komprimieren" (Hauptkomponentanalyse), das wäre aber nur das letzte Mittel, weil hier natürlich Informationen verloren gehen.


----------



## Feeder (1. Aug 2018)

mihe7 hat gesagt.:


> Rechnet er noch? Das Zeug dauert teilweise ewig.
> Ansonsten:
> 1. neuroph hat doch Tutorials, probiere doch die mal aus (umgesetzt in Java-Code). Da sollten sich die Ergebnisse doch vergleichen lassen.
> 2. Standard-Sigmoid verwenden
> ...



An tutorials habe ich nichts verwertbares gefunden. Nein er hat nicht mehr gerechnet, sondern irgendwann ohne brauchbares aufgehört. Standard-Sigmoid müsste ich erst umstellen.... Ich propier es mal mit weniger Neuronen.


----------



## Feeder (1. Aug 2018)

Weniger Neuronen oder mehr Layer funktionieren auch nicht  Ich verzweifle ...
Daten reduzieren bringt nicht. Das Spiel ist viel zu einfach für eine Hauptkomponentenanalyse...

Edit: Vllt kann die Fehlerfunktion nicht stimmen, da sie bei negativen Werten immernoch positiv ist, was die Gewichte bei negativen Werten in die falsche Richtung (also zu lokalen Maxima) konvergieren ließe.


----------



## Feeder (1. Aug 2018)

Edit: Auch das funktioniert nicht


----------



## mihe7 (1. Aug 2018)

Feeder hat gesagt.:


> An tutorials habe ich nichts verwertbares gefunden.


Verwertbar...  Ok, anders: mach mal ein einfaches Netz mit einfachen Daten, z. B. für XOR. Dabei geht es nur darum, überhaupt mal etwas vernünftiges herauszubekommen. Wenn das klappt, probier damit mal Deine Daten.


----------



## mihe7 (1. Aug 2018)

Feeder hat gesagt.:


> Fehlerfunktion nicht stimmen, da sie bei negativen Werten immernoch positiv ist


Das sollte schon passen. Es geht ja "nur" darum, den Fehler zu minimieren.


----------



## Feeder (1. Aug 2018)

Ich raffs nicht, ich glaube langsam das es nicht an mir liegt, selbst so ein Netz funktioniert einfach nicht:


```
import java.util.ArrayList;

import java.util.Random;

import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.learning.error.MeanSquaredError;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;

import suchtytv.complexservice.game.maths.VectorND;
import suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron.BetterSigmoid;

public class Network  {
    MultiLayerPerceptron nn;
    public Network(int inputNodes, int outPutNodes) {
     

        nn = new MultiLayerPerceptron(inputNodes,5,5,outPutNodes);
        for(Layer l : nn.getLayers()) {
            for(Neuron n : l.getNeurons()) {
                n.setTransferFunction(new BetterSigmoid()); //Werte zwischen 0 und 2
            }
        }
        BackPropagation bp = new BackPropagation();
        bp.setLearningRate(0.1);
        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.1);
        nn.setLearningRule(bp);

    }
 
    public void train(ArrayList<VectorND> samples) {

        DataSet set = new DataSet(5, 1);
        for(int i = 0; i < 100; ++i) {

        Random r = new Random();
        double a = r.nextDouble();
        double b = r.nextDouble();

        double c = r.nextDouble();
        double d = r.nextDouble();
        double e = r.nextDouble();

        double[] input = {a,b,c,d,e};
        double[] output = {0.5*a*b+c+d*e*0.5}; // Werte könne maximal 2 sein , da double zwischen 0 und 1
        set.addRow(input, output);
     
     
        }
        set.shuffle();
        nn.learn(set);
        nn.setInput(new double[]{1,0.5,0.7,1,0.5}); //print 0.25+0.7+0.25 = 1.2
        System.out.println(nn.getOutput()[0]);
        System.out.println("Training Done");
    }

    public VectorND getOutput() {
        // TODO Auto-generated method stub
        double[] b = nn.getOutput();
        VectorND nd = new VectorND();
        nd.add(b);
        return nd;
    }
    public static void main(String args[]) {
        Network nn = new Network(5, 1);
        nn.train(null);
    }
 

}
```


----------



## mihe7 (1. Aug 2018)

Probier mal statt

```
nn = new MultiLayerPerceptron(inputNodes,5,5,outPutNodes);
        for(Layer l : nn.getLayers()) {
            for(Neuron n : l.getNeurons()) {
                n.setTransferFunction(new BetterSigmoid()); //Werte zwischen 0 und 2
            }
        }
        BackPropagation bp = new BackPropagation();
        bp.setLearningRate(0.1);
        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.1);
        nn.setLearningRule(bp);
```

einfach nur


```
nn = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, inputNodes,5,5,outPutNodes);
```


----------



## Feeder (1. Aug 2018)

mihe7 hat gesagt.:


> Probier mal statt
> 
> ```
> nn = new MultiLayerPerceptron(inputNodes,5,5,outPutNodes);
> ...



Funktioniert leider auch nicht


----------



## mihe7 (2. Aug 2018)

allmählich reizt es mich es mal auszuprobieren... mal sehen.


----------



## Feeder (2. Aug 2018)

mihe7 hat gesagt.:


> allmählich reizt es mich es mal auszuprobieren... mal sehen.


Ich möchte nochmal auf meine Inkompetenz hinweisen, es kann auch sein das ich einen idiotischen Fehler mache ...
Bitte mich dafür dann nicht angreifen ^^


----------



## mrBrown (2. Aug 2018)

Einfach mal ein `nn.calculate();` nach `nn.setInput(...)`?


----------



## Feeder (2. Aug 2018)

mrBrown hat gesagt.:


> Einfach mal ein `nn.calculate();` nach `nn.setInput(...)`?


Wenn das klappt, schicke ich dir einen Kasten Bier nach Hause... Oder irgendetwas was bei den sommerlichen Temperaturen nicht ungenießbar wird...


----------



## mihe7 (2. Aug 2018)

So, habe quick & dirty mal was zusammengeschustert:

```
import org.neuroph.core.data.*;
import org.neuroph.nnet.*;
import org.neuroph.util.TransferFunctionType;

public class Test {
  
    public static void main(String[] args) {
        MultiLayerPerceptron p = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, 3,3,1);
        DataSet trainingSet = new DataSet(3,1);

        double[][] in = new double[][]{
            new double[]{1,0,0},
            new double[]{1,1,1},
            new double[]{1,0,1},
            new double[]{1,1,0}
        };
        double[][] exp = new double[][]{
            new double[]{0},
            new double[]{0},
            new double[]{1},
            new double[]{1},
        };

        for (int i = 0; i < in.length; i++) {
            trainingSet.addRow(new DataSetRow(in[i], exp[i]));
        }

        p.learn(trainingSet);

        for (int i = 0; i < in.length; i++) {
            p.setInput(in[i]);
            p.calculate();
            double[] out = p.getOutput();
            System.out.println(in[i][0] + " " + in[i][1] + " " + in[i][2] + ": " + out[0]);
        }   
    }
}
```

Funktioniert.


----------



## mihe7 (2. Aug 2018)

mrBrown hat gesagt.:


> Einfach mal ein nn.calculate(); nach nn.setInput(...)?


LOL


----------



## Feeder (2. Aug 2018)

Es funktioniert immer noch nicht - mihe7s Versuch werde ich morgen ausprobieren


----------



## mihe7 (2. Aug 2018)

Noch besser (aus den Samples): 

```
/**
 * Copyright 2010 Neuroph Project http://neuroph.sourceforge.net
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.neuroph.samples;

import java.util.Arrays;
import java.util.Random;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.events.LearningEvent;
import org.neuroph.core.events.LearningEventListener;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.data.DataSetRow;
import org.neuroph.core.learning.LearningRule;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;
import org.neuroph.nnet.learning.MomentumBackpropagation;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.random.WeightsRandomizer;

/**
 * This sample shows how to create, train, save and load simple Multi Layer Perceptron for the XOR problem.
 * This sample shows basics of Neuroph API.
 * @author Zoran Sevarac <sevarac@gmail.com>
 */
public class XorMultiLayerPerceptronSample implements LearningEventListener {
    public static void main(String[] args) {
        new XorMultiLayerPerceptronSample().run();
    }

    /**
     * Runs this sample
     */
    public void run() {

        // create training set (logical XOR function)
        DataSet trainingSet = new DataSet(2, 1);
        trainingSet.addRow(new DataSetRow(new double[]{0, 0}, new double[]{0}));
        trainingSet.addRow(new DataSetRow(new double[]{0, 1}, new double[]{1}));
        trainingSet.addRow(new DataSetRow(new double[]{1, 0}, new double[]{1}));
        trainingSet.addRow(new DataSetRow(new double[]{1, 1}, new double[]{0}));

        // create multi layer perceptron
        MultiLayerPerceptron myMlPerceptron = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, 2, 3, 1);
        myMlPerceptron.randomizeWeights(new WeightsRandomizer(new Random(123)));

        System.out.println(Arrays.toString(myMlPerceptron.getWeights()));

        myMlPerceptron.setLearningRule(new BackPropagation());

        myMlPerceptron.getLearningRule().setLearningRate(0.5);
        // enable batch if using MomentumBackpropagation
//        if( myMlPerceptron.getLearningRule() instanceof MomentumBackpropagation )
//              ((MomentumBackpropagation)myMlPerceptron.getLearningRule()).setBatchMode(false);

        LearningRule learningRule = myMlPerceptron.getLearningRule();
        learningRule.addListener(this);

        // learn the training set
        System.out.println("Training neural network...");
        myMlPerceptron.learn(trainingSet);

        // test perceptron
        System.out.println("Testing trained neural network");
        testNeuralNetwork(myMlPerceptron, trainingSet);

        // save trained neural network
        myMlPerceptron.save("myMlPerceptron.nnet");

        // load saved neural network
        NeuralNetwork loadedMlPerceptron = NeuralNetwork.createFromFile("myMlPerceptron.nnet");

        // test loaded neural network
        System.out.println("Testing loaded neural network");
        testNeuralNetwork(loadedMlPerceptron, trainingSet);
    }

    /**
     * Prints network output for the each element from the specified training set.
     * @param neuralNet neural network
     * @param testSet test set
     */
    public static void testNeuralNetwork(NeuralNetwork neuralNet, DataSet testSet) {

        for(DataSetRow testSetRow : testSet.getRows()) {
            neuralNet.setInput(testSetRow.getInput());
            neuralNet.calculate();
            double[] networkOutput = neuralNet.getOutput();

            System.out.print("Input: " + Arrays.toString( testSetRow.getInput() ) );
            System.out.println(" Output: " + Arrays.toString( networkOutput) );
        }
    }

    @Override
    public void handleLearningEvent(LearningEvent event) {
        BackPropagation bp = (BackPropagation)event.getSource();
        if (event.getEventType() != LearningEvent.Type.LEARNING_STOPPED)
            System.out.println(bp.getCurrentIteration() + ". iteration : "+ bp.getTotalNetworkError());
    }

}
```


----------



## Xyz1 (2. Aug 2018)

mihe7 hat gesagt.:


> allmählich reizt es mich es mal auszuprobieren... mal sehen.


mich auch ....



Feeder hat gesagt.:


> eine Version des Spiels versuche ich anzuhängen (selbst programmierter Quatsch )
> Ist aber nicht alles kommentiert ;( Du solltest aber selbst kompilieren können


Wir werden wohl gezwungen sein müssen es zu kompilieren im laufe des Tages 



mrBrown hat gesagt.:


> Einfach mal ein nn.calculate(); nach nn.setInput(...)


Dir ist doch nicht langweilig  Wie viele AI Vorlesungen hast du schon gehört? 0, 1, 2,...?
Sie können furchtbar langweilig sein aber auch so das man etwas versteht


----------



## mrBrown (2. Aug 2018)

Feeder hat gesagt.:


> Es funktioniert immer noch nicht - mihe7s Versuch werde ich morgen ausprobieren


Dein Beispiel (nicht das Original, das mit den 5 Werten), funktionier mit calculate halbwegs. Besser wirds wenn man maxError verringert und Anzahl der Trainingsdaten erhöht.
Größere Fehler gibts dann nur, wenn der erwartetet Wert > 1 ist, keine Ahnung ob man das vorher auf [0,1] normieren muss, wird sicher irgendwo in der Doku stehen...




DerWissende hat gesagt.:


> Dir ist doch nicht langweilig  Wie viele AI Vorlesungen hast du schon gehört? 0, 1, 2,...?
> Sie können furchtbar langweilig sein aber auch so das man etwas versteht


Vermutlich mehr als du...


----------



## Xyz1 (2. Aug 2018)

mrBrown hat gesagt.:


> keine Ahnung ob man das vorher auf [0,1] normieren muss,


ja muss man....



mrBrown hat gesagt.:


> Vermutlich mehr als du...


sollst du lügen....


----------



## mrBrown (2. Aug 2018)

DerWissende hat gesagt.:


> ja muss man....


Um die Frage zu spezifizieren: gibt es einen sinnvollen default, oder muss man per Hand normalisieren.

Blick in den Code sagt aber wohl: muss man.



DerWissende hat gesagt.:


> sollst du lügen....


Wie viele hast du denn besucht (inklusive körperlicher und geistiger Anwesenheit)?


----------



## Feeder (2. Aug 2018)

Soll ich eine kommentierte Version der wesentlichen Stellen im Game zur Verfügung stellen?
Ansonsten versteht man in der Simulation.java nichts...


----------



## Feeder (2. Aug 2018)

Hier nochmal der Quellcode:

In der Simulation wird das Spiel berechnet,
im GamePlayingNetwork (das ist relativ selbst erklärend) die AI gebaut

mehr ist wohl nicht von nöten


----------



## Xyz1 (2. Aug 2018)

mrBrown hat gesagt.:


> Wie viele hast du denn besucht (inklusive körperlicher und geistiger Anwesenheit)?


Datenschutz. 



mihe7 hat gesagt.:


> Noch besser (aus den Samples):


Mihe, ich habe einfach mal Deines kopiert und etwas angepasst....
Auch mit einem Sigmoid kann ein MLP in unter 1000 Iterationen zum Beispiel das add von 2 ints lernen....


```
import java.util.Arrays;
import java.util.Random;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.events.LearningEvent;
import org.neuroph.core.learning.LearningRule;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;
import org.neuroph.util.TransferFunctionType;

/**
 */
public class NeuroTest {

public static void main(String[] args) {
    System.out.println("create training set");
    Random ra = new Random(123);
    DataSet trset = new DataSet(6, 4);
    for (int i = 0; i < 100; i++) {
        int j1 = ra.nextInt(8), j2 = ra.nextInt(8), j3 = j1 + j2;
        double[] ds1 = intToDouble(j1, new double[3]);
        double[] ds2 = intToDouble(j2, new double[3]);
        double[] ds3 = intToDouble(j3, new double[4]);
        trset.addRow(
                new double[]{
                    ds1[0], ds1[1], ds1[2],
                    ds2[0], ds2[1], ds2[2],},
                ds3);
        System.out.println(j1 + " " + j2 + " " + j3 + " " + trset.getRowAt(i).toCSV());
    }

    System.out.println("create neural network...");
    MultiLayerPerceptron nn = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, 6, 12, 4);

    System.out.println("randomize neural network's weights...");
    nn.randomizeWeights(ra);
    System.out.println(Arrays.toString(nn.getWeights()));

    System.out.println("set learning rule...");
    nn.setLearningRule(new BackPropagation());
    nn.getLearningRule().setLearningRate(0.1);
    nn.getLearningRule().setMaxIterations(5000);

    LearningRule learningRule = nn.getLearningRule();
    learningRule.addListener((LearningEvent event) -> {
        BackPropagation bp = (BackPropagation) event.getSource();
        System.out.println(
                bp.getCurrentIteration() /*+ " "
                + Arrays.toString(bp.getNeuralNetwork().getWeights())*/);
    });

    System.out.println("Training neural network...");
    nn.learn(trset);

    System.out.println("Testing trained neural network");
    for (int i = 0; i < 5; i++) {
        int j1 = ra.nextInt(8), j2 = ra.nextInt(8), j3 = j1 + j2;
        double[] ds1 = intToDouble(j1, new double[3]);
        double[] ds2 = intToDouble(j2, new double[3]);
        double[] ds3 = intToDouble(j3, new double[4]);
        double[] dsi = {
            ds1[0], ds1[1], ds1[2],
            ds2[0], ds2[1], ds2[2],};
        double[] dso = ds3;
        nn.setInput(dsi);
        nn.calculate();
        double[] dso2 = nn.getOutput();
        int j4 = doubleToInt(dso2);
        System.out.println(
                j1 + " " + j2 + " " + j3 + " "
                + Arrays.toString(dsi) + " "
                + Arrays.toString(dso) + " "
                + Arrays.toString(dso2) + " " + j4);
    }
}

static double[] intToDouble(int i, double[] ds) {
    String s = Integer.toBinaryString(i);
    for (int j = 0; j < s.length(); j++) {
        ds[j] = s.charAt(s.length() - j - 1) - '0';
    }
    return ds;
}

static int doubleToInt(double[] ds) {
    int r = 0;
    for (int j = 0; j < ds.length; j++) {
        r |= ((int) Math.round(ds[j])) << j;
    }
    return r;
}

}
```


```
create training set
5 1 6 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0
7 2 9 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0
2 4 6 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0
4 2 6 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0
6 4 10 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
7 4 11 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0
5 1 6 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0
0 5 5 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0
6 2 8 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
4 1 5 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0
7 4 11 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0
1 1 2 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0
7 3 10 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0
0 0 0 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
0 0 0 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
0 2 2 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
3 7 10 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0
6 5 11 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0
4 0 4 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0
3 3 6 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0
2 7 9 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0
1 6 7 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0
2 6 8 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0
3 0 3 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0
3 1 4 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0
1 3 4 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0
4 1 5 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0
0 3 3 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0
5 0 5 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0
5 6 11 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0
0 1 1 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
7 3 10 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0
3 7 10 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0
5 3 8 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
5 6 11 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0
5 5 10 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
4 0 4 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0
3 6 9 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0
1 3 4 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0
0 1 1 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
0 4 4 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0
6 3 9 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0
5 6 11 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0
7 6 13 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0
6 2 8 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
4 6 10 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0
4 4 8 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0
1 2 3 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0
2 1 3 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0
5 5 10 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
3 3 6 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0
7 3 10 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0
5 1 6 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0
2 2 4 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0
7 2 9 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0
3 2 5 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0
1 1 2 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0
5 3 8 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
1 7 8 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0
0 6 6 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0
4 4 8 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0
4 5 9 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0
1 2 3 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0
4 6 10 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0
2 5 7 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0
2 6 8 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0
3 1 4 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0
1 1 2 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0
6 2 8 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
2 1 3 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0
3 0 3 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0
5 6 11 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0
0 4 4 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0
1 3 4 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0
7 0 7 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0
7 3 10 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0
6 1 7 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0
6 7 13 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0
0 0 0 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
3 7 10 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0
1 0 1 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
7 7 14 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0
4 7 11 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0
5 5 10 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
0 6 6 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0
3 4 7 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0
1 7 8 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0
4 3 7 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0
6 4 10 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
0 3 3 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0
5 3 8 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
7 1 8 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0
3 2 5 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0
3 1 4 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0
4 5 9 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0
6 2 8 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
6 1 7 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0
5 7 12 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0
6 2 8 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0
5 1 6 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0
create neural network...
randomize neural network's weights...
[0.647357215491136, 0.2833653573340025, 0.005186258410748934, 0.16071957622616795, 0.780309732765597, 0.7916784518594653, 0.3117819715124699, 0.02372128403098228, 0.5326884083087974, 0.36353401318531553, 0.3090342672889538, 0.20705779115056422, 0.15811812466802477, 0.3657232277640391, 0.01987654069995526, 0.2290447427367961, 0.14734378462417386, 0.3379430273493287, 0.3058032092686285, 0.08986786180559903, 0.4386703976376072, 0.2530810140170595, 0.4640270585612969, 0.13352451959402267, 0.4295248350895613, 0.766862374848878, 0.47373501995925704, 0.7569913113067654, 0.8456883679089797, 0.16013595159641492, 0.1262142127937652, 0.6332743310673092, 0.10775700279466349, 0.39289775562122153, 0.9347523077653593, 0.03394392388012901, 0.8236439887106316, 0.061219786676922405, 0.287600308100715, 0.9119509109778238, 0.4314473127762968, 0.07657290158990859, 0.780917184062471, 0.6369668764890946, 0.81876239832529, 0.571602524934773, 0.048499993353021575, 0.6631861738505911, 0.9525280776859375, 0.8772363457800377, 0.69123457180554, 0.9534726942627975, 0.16775194011929062, 0.4130733703648567, 0.10158617346993115, 0.683929913239893, 0.78396856157569, 0.9863243067977903, 0.07708076532512831, 0.6094176094725173, 0.1450425317246743, 0.30414317166082083, 0.12161176142807084, 0.4832345570371346, 0.010935340099124335, 0.47001064536583137, 0.24453886715828366, 0.09313137108600067, 0.46931354076562126, 0.8568998711539078, 0.8849290024162565, 0.8010129839502235, 0.180383052823047, 0.028275494081400843, 0.31192216524211536, 0.9551359430850607, 0.8200925219612185, 0.3125478738866171, 0.4820872714140031, 0.18130066238854037, 0.044856382804202344, 0.22742330102185093, 0.8707667708431337, 0.3534840566199541, 0.16520593574327203, 0.19766289887246657, 0.23679075583641251, 0.9945536151314497, 0.986284892071741, 0.9130820597278025, 0.6285746923090954, 0.9641490765376436, 0.9498632255728994, 0.2331931928649943, 0.1944973492064338, 0.5535130612324953, 0.7955515854223575, 0.7607146524531969, 0.5215886873681563, 0.52599755713938, 0.44815542624867843, 0.07823889965527187, 0.293939787517563, 0.21716842480174436, 0.733616898224158, 0.1706736992328015, 0.03588016591962406, 0.539875284603039, 0.8277494941255742, 0.7406401001426257, 0.5848504809078479, 0.627349569569006, 0.04997879437164565, 0.9648310259209602, 0.7250312103696261, 0.8913386056087402, 0.7285598966158668, 0.7364056067704764, 0.1051711542646484, 0.47247967319890505, 0.3842508861547216, 0.5918132108073756, 0.1626920823135357, 0.41656181725144326, 0.40617825701053334, 0.33001304992373603, 0.2810286227211517, 0.4230202484610498, 0.726639210030025, 0.7978741814026805, 0.8182956476969212, 0.6809521868110479, 0.7408426888498517, 0.43761188539425855, 0.9627579423239608, 0.13313888331066603]
set learning rule...
Training neural network...
1
....
933
Testing trained neural network
6 1 7 [0.0, 1.0, 1.0, 1.0, 0.0, 0.0] [1.0, 1.0, 1.0, 0.0] [0.9984149175208366, 0.9541509265284592, 0.9136515702001319, 0.029320530721152756] 7
7 4 11 [1.0, 1.0, 1.0, 0.0, 0.0, 1.0] [1.0, 1.0, 0.0, 1.0] [0.9970404893926246, 0.9996918910742172, 0.14573473999840167, 0.9838278417863412] 11
4 4 8 [0.0, 0.0, 1.0, 0.0, 0.0, 1.0] [0.0, 0.0, 0.0, 1.0] [0.06089073314012169, 0.030412914393122492, 0.022566630597148047, 0.9506610240186283] 8
3 3 6 [1.0, 1.0, 0.0, 1.0, 1.0, 0.0] [0.0, 1.0, 1.0, 0.0] [0.008202698117266503, 0.8748929075298061, 0.9810740327187619, 0.016224749669329543] 6
5 7 12 [1.0, 0.0, 1.0, 1.0, 1.0, 1.0] [0.0, 0.0, 1.0, 1.0] [0.03636031649520549, 0.3135859376072287, 0.7443468508986525, 0.9999670793296899] 12
```

@Feeder Das MLP sollte nicht zu groß sein, es sollte viele Trainigssets geben, die Lernrate sollte klein sein und die maximalen Iterationen nicht viel weniger als nötig - und das MLP sollte wenigstens "etwas sinnvoll" aufgebaut sein.


----------



## Feeder (2. Aug 2018)

In wie fern sollte ich denn jetzt abändern? Könntest du es bitter genauer erklären?


----------



## mrBrown (2. Aug 2018)

Feeder hat gesagt.:


> In wie fern sollte ich denn jetzt abändern? Könntest du es bitter genauer erklären?


Alles was ich bei deinem Beispiel (nicht dem mit dem Spiel) ändern musste, war das #calculate und das anpassen des maxError (auf 0.01 oder kleiner).


----------



## Feeder (2. Aug 2018)

mrBrown hat gesagt.:


> Alles was ich bei deinem Beispiel (nicht dem mit dem Spiel) ändern musste, was das #calculate und das anpassen des maxError (auf 0.01 oder kleiner).


Hmmm, aber ich müsste ja schon LÖsungsvorschläge für das richte SpielNN gebrauchen ...

Klassifikation != Regression


----------



## Xyz1 (2. Aug 2018)

Feeder hat gesagt.:


> Klassifikation != Regression


Was war nochmal Regression? Mir ist der Einsatz dieser Begriffe noch nicht ganz geläufig..
Ist ja auch schon etwas her....

Auf die schnelle finde ich nur das





Ähhhhm, vielleicht kann ich morgen doch mal Dein Beispielspiel kompilieren...


----------



## Xyz1 (2. Aug 2018)

Doch jetzt weiß ich es wieder....
Aber eine lin. Regressionsgerade stellt doch auch ne einfache Klassifikation dar?


----------



## Feeder (2. Aug 2018)

Aber meine Zielfunktion (die die mein Gehirn besitzt) ist ja eben nicht linear. Ich verstehe den Sinn hinter XOR nicht. Klassifikation ist wahr oder eben nicht wahr... oder für MlPs

Giraffe, Affe, Hund...


----------



## Xyz1 (2. Aug 2018)

Wie gesacht, ich mache mir da morgen weiter Gedanken dazu....


----------



## Feeder (2. Aug 2018)

DerWissende hat gesagt.:


> Wie gesacht, ich mache mir da morgen weiter Gedanken dazu....


I appreciate this


----------



## mihe7 (2. Aug 2018)

Bei Regression bekommt man einen Wert heraus, z. B. Stückzahlen, bei Klassifikation geht es nur darum, ob etwas "dazu gehört" oder nicht.



Feeder hat gesagt.:


> Ich verstehe den Sinn hinter XOR nicht. Klassifikation ist wahr oder eben nicht wahr...


Nehmen wir mal Giraffe, Affe, Hund: Output-Neuron 1, 2 oder 3 aktiviert (bzw. welches hat den Größten ) . Beim XOR ist es nicht anders: Output-Neuron 1 oder 2.


----------



## Xyz1 (2. Aug 2018)

mihe7 hat gesagt.:


> bei Klassifikation geht es nur darum, ob etwas "dazu gehört" oder nicht.


Aber durch Regressionsgerade geteilte Punkte können dadurch auch klassifiziert werden indem sie auf der einen oder anderen Seite liegen.
Gilt somit: Regression > Klassifikation?

Aber was tut das jetzt alles zum Thema bei.... ?


----------



## mihe7 (2. Aug 2018)

DerWissende hat gesagt.:


> Aber was tut das jetzt alles zum Thema bei.... ?


@Feeder: das ist eine berechtigte Frage.


----------



## Feeder (2. Aug 2018)

mihe7 hat gesagt.:


> @Feeder: das ist eine berechtigte Frage.


Ich war nicht derjenige mit der Idee des XOR Netzes... Es war ein Test der Library und die funktioniert.
Ich versteh nur nicht warum mein Programm nicht läuft...


----------



## mihe7 (2. Aug 2018)

Sorry, das mit der "berechtigten Frage" bezog ich stillschweigend auf das Thema Regression/Klassifikation.



Feeder hat gesagt.:


> Ich versteh nur nicht warum mein Programm nicht läuft...


Kann Dir nix versprechen, aber evtl. schaffe ich es noch, mal Deinen Code auszuprobieren. Sonst könnte es nächste Woche werden - allerdings: @DerWissende wollte ja auch


----------



## Feeder (2. Aug 2018)

mihe7 hat gesagt.:


> Sorry, das mit der "berechtigten Frage" bezog ich stillschweigend auf das Thema Regression/Klassifikation.
> 
> 
> Kann Dir nix versprechen, aber evtl. schaffe ich es noch, mal Deinen Code auszuprobieren. Sonst könnte es nächste Woche werden - allerdings: @DerWissende wollte ja auch


Ich bin euch allen mega dankbar ^^ Man bekommt als Schüler nur wenig rat - weil die Lehrer auch nicht raffen, was man da macht...


----------



## mihe7 (2. Aug 2018)

Das ist auch keine Aufgabe für den Lehrer in der Schule. Der Lehrer hat die Aufgabe, die Vorgaben aus dem Lehrplan didaktisch so aufzubereiten, dass die Schüler es verstehen. Der Lehrplan bewegt sich fachlich auf einem ganz anderen Niveau. Es gibt natürlich Lehrer, die sich zu ihrem eigenen Vergnügen mit z. B. Softwareentwicklung tiefer beschäftigen. Das darfst Du aber nicht voraussetzen.


----------



## Feeder (2. Aug 2018)

mihe7 hat gesagt.:


> Das ist auch keine Aufgabe für den Lehrer in der Schule. Der Lehrer hat die Aufgabe, die Vorgaben aus dem Lehrplan didaktisch so aufzubereiten, dass die Schüler es verstehen. Der Lehrplan bewegt sich fachlich auf einem ganz anderen Niveau. Es gibt natürlich Lehrer, die sich zu ihrem eigenen Vergnügen mit z. B. Softwareentwicklung tiefer beschäftigen. Das darfst Du aber nicht voraussetzen.


Tue ich nicht natürlich nicht, aber es ist halt dennoch nicht immer einfach - wenn man sich mit Informatik hobbymäßig beschäftigt und viele Dinge vor hat, aber viele aufgrund des Wissenstandes einfach nicht umsetzen konnte...
Das ist - wie soll man sagen - frustriend. Um so dankbarer bin ich meiner Infolehrerin, die schon ach wie viele Konsultationen mit mir hatte ...


----------



## Xyz1 (3. Aug 2018)

Bist Du auf einem Einstein-Gymnasium dass ihr NN behandelt?   (Sorry, ich konnte nicht nachgeben....)
So es ist 0 Uhr durch und ich schlafe.


----------



## Feeder (3. Aug 2018)

DerWissende hat gesagt.:


> Bist Du auf einem Einstein-Gymnasium dass ihr NN behandelt?   (Sorry, ich konnte nicht nachgeben....)
> So es ist 0 Uhr durch und ich schlafe.


Wir behandeln rein gar nichts in der Schule - ich durfte nicht mal Informatik als Grundkurs wählen (nicht genug Lehrer) ...
Ich habe mir all meine Programmierskills (wenn man das als Skills bezeichnen kann) in den letzten 4 Jahren aufgebaut mit einem Buch(Java), Internet, Kopfschmerzen, Ausratsern und gelegentlichen Extasen wenn es dann endlich klappt
Und ich fürchte, es werden noch viele schmerzhafte Momente folgen...

Informatiker sind allesamt fetischisten wer sich sowas freiwillig antut... (wie ich)


----------



## Xyz1 (3. Aug 2018)

Feeder hat gesagt.:


> (nicht genug Lehrer)


Das ist ja auch nicht gerade wenig was da drankommt:
`javascript:(function(){window.location.href="[URL]https://www.schulentwicklung.nrw.de/lehrplaene/lehrplannavigator-s-ii/gymnasiale-oberstufe/informatik/hinweise-und-beispiele/schulinterner-lehrplan/schulinterner-lehrplan.html[/URL]";window.onload=toggle("a211Q1GK");})();`

Bereits in Q1gk unter Anderem Strukturierung, Algorithmen und Informatiksysteme....

Allerdings NN ist ein so weit fortgeschrittenes Thema das es nicht mit in den Lehrplan aufgenommen werden sollte


----------



## Xyz1 (3. Aug 2018)

DerWissende hat gesagt.:


> javascript:


Sorry es sollte keine Injection sein sondern nur direkt an die richtige Stelle springen


----------



## Feeder (3. Aug 2018)

Ich versteh jetzt den Zusammenhang nicht - sicherlich ist der GK Informatik nicht ganz schlecht, aber wenn es nicht genug Lehrer gibt kann halt niemand den GK halten 

Das wäre mein Lehrplan:

https://www.schule.sachsen.de/lpdb/web/downloads/1430_lp_gy_informatik_2018.pdf?v2

Meine Leherin meint ich behersche das alles - auch wenn ich noch zum Teil noch . nie was davon gehört habe ^^


----------



## mihe7 (3. Aug 2018)

Feeder hat gesagt.:


> Ich raffs nicht, ich glaube langsam das es nicht an mir liegt, selbst so ein Netz funktioniert einfach nicht:


Doch, das funktioniert schon. Allerdings musst Du die Daten normalisieren, denn Sigmoid liefert ja Werte zwischen 0 und 1.


----------



## Feeder (3. Aug 2018)

Habe ich ja gemacht, indem ich meine Sigmoidfunktion angepasst habe.
f(net) = 2*sigmoid(net) - 1
f'(net) = 2 * sigmoid'(net)


----------



## mrBrown (3. Aug 2018)

Die Werte solltest du trotzdem normalisieren, kannst das DataSet direkt mit zB MaxMinNormalizer normalisieren.


----------



## mihe7 (3. Aug 2018)

@Feeder: sorry, ich verwende immer die Standardfunktionen. Abgesehen davon liefert Sigmoid Werte zwischen 0 und 1, d. h. 2*wertZwischen0und1-1 liefert Werte zwischen -1 und 1.

Das Problem ist einfach, dass die erwartete Ausgabe z. B. 1.2 sein kann - das wird weder mit dem Standard-Sigmoid (0-1) noch mit Deinem (-1 bis +1) erreicht.


----------



## Feeder (3. Aug 2018)

mrBrown hat gesagt.:


> Die Werte solltest du trotzdem normalisieren, kannst das DataSet direkt mit zB MaxMinNormalizer normalisieren.


Und wie denormalisiere ich dann?


----------



## Feeder (3. Aug 2018)

mihe7 hat gesagt.:


> @Feeder: sorry, ich verwende immer die Standardfunktionen. Abgesehen davon liefert Sigmoid Werte zwischen 0 und 1, d. h. 2*wertZwischen0und1-1 liefert Werte zwischen -1 und 1.
> 
> Das Problem ist einfach, dass die erwartete Ausgabe z. B. 1.2 sein kann - das wird weder mit dem Standard-Sigmoid (0-1) noch mit Deinem (-1 bis +1) erreicht.



Aber ich habe doch meine Werte extra zwischen -1 und 1 normalisiert. Die Kraft kann nicht höher als 1 und nicht niedriger als -1 sein.

Wie denormalisere ich den im Fall des MaxMinNormalizers


----------



## Xyz1 (3. Aug 2018)

Feeder hat gesagt.:


> Das wäre mein Lehrplan:


Sowas ist immer sau komisch  :


> Schüler, Lehrer
> Die Bezeichnungen Schüler und Lehrer werden im Lehrplan allgemein für Schülerinnen und Schüler bzw. Lehrerinnen und Lehrer gebraucht.






Feeder hat gesagt.:


> wenn es nicht genug Lehrer gibt


Das ist ein Problem dann kann der Lehrplan noch so gut sein. Es ist ganz einfach, wenn kein Personal: dann kann es nicht angeboten werden.... Zum Leidwesen der Schüler welche Kompetenzen entwickeln möchten....
Ich kann Dich verstehen



mrBrown hat gesagt.:


> das DataSet direkt mit zB MaxMinNormalizer normalisieren


probier das mal bitte....


----------



## Feeder (3. Aug 2018)

Habe ich:


```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import java.util.ArrayList;
import java.util.Arrays;
import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.learning.error.MeanSquaredError;

import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.data.norm.MaxMinNormalizer;

import suchtytv.complexservice.game.maths.VectorND;

public class GamePlayingNetwork  {
    MultiLayerPerceptron nn;

    public GamePlayingNetwork(int inputNodes, int outPutNodes) {
       

        nn = new MultiLayerPerceptron(inputNodes,50,50,50,outPutNodes);

        for(Layer l : nn.getLayers()) {
            for(Neuron n : l.getNeurons()) {
                n.setTransferFunction(new Sigmoid());
            }
        }
        nn.randomizeWeights();
        BackPropagation bp = new BackPropagation();
        bp.setLearningRate(0.1);
        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.01);
        bp.setMaxIterations(100);
        nn.setLearningRule(bp);

    }
   
    public void train(ArrayList<VectorND> samples) {
        System.out.println("Training with "+ samples.size() + " sample(s)... this could take a while ");

        DataSet set = new DataSet(47, 2);
        for(VectorND nd : samples) {
        double[] all = nd.getArray();
        double[] input  = Arrays.copyOfRange(all, 0, nd.length()-2);
        double[] output  = Arrays.copyOfRange(all, nd.length()-2, nd.length());
        set.addRow(input, output);
       
       
        }
        new MaxMinNormalizer().normalize(set);
        set.shuffle();
        nn.learn(set);
//        nn.getLearningRule().setLearningRate(nn.getLearningRule().getLearningRate() - 0.5*nn.getLearningRule().getLearningRate());
        System.out.println("Training Done");
    }

    public MultiLayerPerceptron getNeuralNetwork() {
        return nn;
       
    }

    public void setInput() {
       
       
    }

    public void setInput(double[] array) {
        nn.setInput(array);
       
    }

    public VectorND getOutput() {
        nn.calculate();
       
        // TODO Auto-generated method stub
        double[] b = nn.getOutput();
        VectorND nd = new VectorND();
        nd.add(b);
        return nd;
    }
   
   

}
```

Jetzt werden die Werte lustiger weise alle NaN was eigentlich gar nicht sein kann...


----------



## mihe7 (3. Aug 2018)

Nur, damit wir vom gleichen reden, es geht um 

```
double[] input = {a,b,c,d,e};
      double[] output = {0.5*a*b+c+d*e*0.5}; // Werte könne maximal 2 sein , da double zwischen 0 und 1
```

D. h. Dein Ausgabeneuron liefert Werte zwischen 0 und 1 (bzw. -1 und +1), gleichzeitig soll der Fehler zu Werten zwischen 0 und 2 minimiert werden. Damit ist in jedem Fall ein gewisser Feler enthalten, weil das Ausgabeneuron Werte > 1 nicht "darstellen" kann.

Was das denormalisieren betrifft: soweit sind wir noch gar nicht  Es ging ja erst einmal darum, dass das Netz als solches funktioniert. 

Habe Deinen Code mal ein wenig angepasst, nicht erschrecken, ist nicht schön 


```
public class Network implements LearningEventListener {
    MultiLayerPerceptron nn;
    public Network() {
        nn = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, 5,4,1);
        MomentumBackpropagation bp = new MomentumBackpropagation();
        bp.setMomentum(0.9);
        bp.setLearningRate(0.1);
        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.001);
        bp.addListener(this);
        nn.setLearningRule(bp);
    }

    public void train() {
        DataSet set = new DataSet(5, 1);
        for(int i = 0; i < 1000; ++i) {
            Random r = new Random();
            double a = r.nextDouble();
            double b = r.nextDouble();

            double c = r.nextDouble();
            double d = r.nextDouble();
            double e = r.nextDouble();

            double[] input = {a,b,c,d,e};
            double[] output = {0.5*a*b+c+d*e*0.5};
            set.addRow(input, output);
        }

        Normalizer normalizer = new MaxMinNormalizer();
        normalizer.normalize(set);

        set.shuffle();
        List<DataSet> trainAndTest = set.sample(new SubSampling(70));

        DataSet training = trainAndTest.get(0);
        nn.learn(training);
        System.out.println("Training Done.");

        DataSet test = trainAndTest.get(1);
        for (DataSetRow row : test.getRows()) {
            nn.setInput(row.getInput());
            nn.calculate();
            double actual = nn.getOutput()[0];
            double expected = row.getDesiredOutput()[0];
            double err = Math.pow(actual - expected, 2);

            System.out.printf("Actual: %f, desired: %f, err: %f\n", actual, expected, err);
        }
    }

    public static void main(String args[]) {
        Network nn = new Network();
        nn.train();
    }

    @Override
    public void handleLearningEvent(LearningEvent event) {
        BackPropagation bp = (BackPropagation)event.getSource();
        if (event.getEventType() != LearningEvent.Type.LEARNING_STOPPED)
            System.out.println(bp.getCurrentIteration() + ". iteration : "+ bp.getTotalNetworkError());
    }
}
```


----------



## Feeder (3. Aug 2018)

mihe7 hat gesagt.:


> Nur, damit wir vom gleichen reden, es geht um
> 
> ```
> double[] input = {a,b,c,d,e};
> ...



Jetzt reden wir wieder vom selben. MeinFehler. Einige Fragen zum Code:

Was hast das Momentum zu bedeuten?


----------



## mihe7 (3. Aug 2018)

Der Listener zeigt den Trainings-Fortschritt an. Zum Momentum https://www.quora.com/What-does-momentum-mean-in-neural-networks


----------



## Xyz1 (3. Aug 2018)

Feeder hat gesagt.:


> Was macht der Listener?


Der listener gibt nur zwischenzustände des lernfortschritts aus (Gewichte usw)


----------



## Feeder (3. Aug 2018)

mihe7 hat gesagt.:


> Der Listener zeigt den Trainings-Fortschritt an. Zum Momentum https://www.quora.com/What-does-momentum-mean-in-neural-networks


Okay verstanden  Zumindestens kann ich es nun als Blackbox handhaben.


----------



## Feeder (3. Aug 2018)

In wie weit sollte ich nun weitermachen?


----------



## Feeder (3. Aug 2018)

Ich möchte mal zu dem anderen NN zurückkommen:


```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import java.util.ArrayList;
import java.util.Arrays;
import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.events.LearningEvent;
import org.neuroph.core.events.LearningEventListener;
import org.neuroph.core.learning.error.MeanSquaredError;
import org.neuroph.core.transfer.Linear;
import org.neuroph.core.transfer.RectifiedLinear;
import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;
import org.neuroph.nnet.learning.MomentumBackpropagation;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.data.norm.MaxMinNormalizer;

import suchtytv.complexservice.game.maths.VectorND;

public class GamePlayingNetwork implements LearningEventListener {
    MultiLayerPerceptron nn;

    public GamePlayingNetwork(int inputNodes, int outPutNodes) {

        nn = new MultiLayerPerceptron(inputNodes, 50, 50, outPutNodes);

        for (Layer l : nn.getLayers()) {
            for (Neuron n : l.getNeurons()) {
                n.setTransferFunction(new RectifiedLinear());
            }
        }
        nn.getLayerAt(3).getNeuronAt(0).setTransferFunction(new Linear());
        nn.getLayerAt(3).getNeuronAt(1).setTransferFunction(new Linear());

        nn.randomizeWeights();
        MomentumBackpropagation bp = new MomentumBackpropagation();
        bp.setMomentum(0.9);
        bp.setLearningRate(0.1);
        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.001);
        bp.addListener(this);
        bp.setMaxIterations(200);
        nn.setLearningRule(bp);

    }

    public void train(ArrayList<VectorND> samples) {
        System.out.println("Training with " + samples.size() + " sample(s)... this could take a while ");

        DataSet set = new DataSet(47, 2);
        for (VectorND nd : samples) {
            double[] all = nd.getArray();
            double[] input = Arrays.copyOfRange(all, 0, nd.length() - 2);
            double[] output = Arrays.copyOfRange(all, nd.length() - 2, nd.length());
            set.addRow(input, output);

        }
        set.shuffle();
        nn.learn(set);
        System.out.println("Training Done");
    }

    public MultiLayerPerceptron getNeuralNetwork() {
        return nn;

    }

    public void setInput() {

    }

    public void setInput(double[] array) {
        nn.setInput(array);

    }

    public VectorND getOutput() {
        nn.calculate();

        // TODO Auto-generated method stub
        double[] b = nn.getOutput();
        VectorND nd = new VectorND();
        nd.add(b);
        return nd;
    }

    @Override
    public void handleLearningEvent(LearningEvent event) {
        BackPropagation bp = (BackPropagation)event.getSource();
        if (event.getEventType() != LearningEvent.Type.LEARNING_STOPPED)
            System.out.println(bp.getCurrentIteration() + ". iteration : "+ bp.getTotalNetworkError());
       
    }

}
```

Dieses Netzwerk zeigt erste Lebenzeichen... Es weicht tatsächlich aus...


----------



## Feeder (3. Aug 2018)

```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import java.util.ArrayList;
import java.util.Arrays;
import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.events.LearningEvent;
import org.neuroph.core.events.LearningEventListener;
import org.neuroph.core.learning.error.MeanSquaredError;
import org.neuroph.core.transfer.Linear;
import org.neuroph.core.transfer.Log;
import org.neuroph.core.transfer.RectifiedLinear;
import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;
import org.neuroph.nnet.learning.MomentumBackpropagation;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.data.norm.MaxMinNormalizer;

import suchtytv.complexservice.game.maths.VectorND;

public class GamePlayingNetwork implements LearningEventListener {
    MultiLayerPerceptron nn;

    public GamePlayingNetwork(int inputNodes, int outPutNodes) {

        nn = new MultiLayerPerceptron(inputNodes, 50, 50, outPutNodes);

        for (Layer l : nn.getLayers()) {
            for (Neuron n : l.getNeurons()) {
                n.setTransferFunction(new org.neuroph.core.transfer.Sigmoid());
            }
        }
        nn.getLayerAt(3).getNeuronAt(0).setTransferFunction(new Linear());
        nn.getLayerAt(3).getNeuronAt(1).setTransferFunction(new Linear());

        nn.randomizeWeights();
        MomentumBackpropagation bp = new MomentumBackpropagation();
        bp.setMomentum(10);
        bp.setLearningRate(0.01);
        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.001);
        bp.addListener(this);
        bp.setMaxIterations(200);
        nn.setLearningRule(bp);

    }

    public void train(ArrayList<VectorND> samples) {
        System.out.println("Training with " + samples.size() + " sample(s)... this could take a while ");

        DataSet set = new DataSet(47, 2);
        for (VectorND nd : samples) {
            double[] all = nd.getArray();
            double[] input = Arrays.copyOfRange(all, 0, nd.length() - 2);
            double[] output = Arrays.copyOfRange(all, nd.length() - 2, nd.length());
            set.addRow(input, output);

        }
        set.shuffle();
        nn.learn(set);
        System.out.println("Training Done");
    }

    public MultiLayerPerceptron getNeuralNetwork() {
        return nn;

    }

    public void setInput() {

    }

    public void setInput(double[] array) {
        nn.setInput(array);

    }

    public VectorND getOutput() {
        nn.calculate();

        // TODO Auto-generated method stub
        double[] b = nn.getOutput();
        VectorND nd = new VectorND();
        nd.add(b);
        return nd;
    }

    @Override
    public void handleLearningEvent(LearningEvent event) {
        BackPropagation bp = (BackPropagation)event.getSource();
        if (event.getEventType() != LearningEvent.Type.LEARNING_STOPPED)
            System.out.println(bp.getCurrentIteration() + ". iteration : "+ bp.getTotalNetworkError());
   
    }

}
```

Dieses Netzwerk schafft es das Spiel für einige Sekunden lang zu spielen, es ist eine Intension erkennbar. Es bleibt wie ich immer auf der linken Seite des Spielfeldes und versucht häufig nicht über den Spielrand zu kommen. Es versucht meine Kreisbewegung zu imitieren, die ich nutze um schnellen Objekten ausweichen zu können, ohne dabei von null beschleunigen zu müssen. Bei zu vielen Vögeln in der Nähe, verliert es ...

Der Fehler liegt bei lediglich 0.009 . Wie mach ich jetzt das Fein-tuning?


----------



## mrBrown (3. Aug 2018)

Kannst du die "Güte" des Spielens irgendwie bewerten?


----------



## Xyz1 (3. Aug 2018)

mrBrown hat gesagt.:


> Güte" des Spielens


Was ist denn das.... 

@Feeder ich meine, Dein NN (Perzeptron) wäre zu groß, es muss ja teils Neuronen mit 2500 _Bearbeitung: 50_ Eingängen haben....


----------



## mrBrown (3. Aug 2018)

DerWissende hat gesagt.:


> mrBrown hat gesagt.:
> 
> 
> > Güte" des Spielens
> ...


Güte: https://www.duden.de/rechtschreibung/Guete#Bedeutung2
des: https://www.duden.de/rechtschreibung/des_bestimmter_Artikel_im_Genitiv
Spielens: https://www.duden.de/rechtschreibung/spielen



DerWissende hat gesagt.:


> @Feeder ich meine, Dein NN (Perzeptron) wäre zu groß, es muss ja teils Neuronen mit 2500 _Bearbeitung: 50_ Eingängen haben....


Bei 47 Eingangsvariablen wären es merkwürdige, wenn es nicht teils 50 Eingänge wären...


----------



## Xyz1 (3. Aug 2018)

Was hat der Duden denn mit Informatik zu tun 
Brauchst nicht gleich patzig werden
und es heißt des Spiels....


----------



## mrBrown (3. Aug 2018)

DerWissende hat gesagt.:


> Was hat der Duden denn mit Informatik zu tun


Nichts, aber meine Worte sind halt auch nicht Informatik-spezifisch...



DerWissende hat gesagt.:


> und es heißt des Spiels....


Nein, ich meine "des Spiel*ens*".
Das Spielen und das Spiel sind unterschiedliche Dinge, erstes meint den Vorgang des Spielens, zweiteres das Spiel.


----------



## Xyz1 (3. Aug 2018)

Hier
https://av.tib.eu/media/21145
ab Minute 57 sagt er etwas über Approximationsgüte .... (vielleicht kann es helfen)


----------



## Xyz1 (3. Aug 2018)

mrBrown hat gesagt.:


> Nichts,


Es gibt aber auch einen Duden für Informatik 
https://www.amazon.de/Duden-Informatik-Fachlexikon-Studium-Ausbildung/dp/3411052341


----------



## Feeder (4. Aug 2018)

Die Güte meines Spielens ist ca 40 Sekunden survival.. gegen den computer der nur 10s schafft


----------



## Feeder (9. Aug 2018)

Hey, ich bin es nochmal:

Es funktioniert leider von der Qualität des Spielens noch nicht wie ich es mir vorgestellt habe, sollte ich noch irgendetwas anderes probieren:

Ich habe bereits versucht:
Mehr Neuronen
Höheres Momentum
Höhere Learningrate


```
package suchtytv.complexservice.game.maths.artificialneuralnetwork.multilayerperceptron;

import java.util.ArrayList;
import java.util.Arrays;
import org.neuroph.core.Layer;
import org.neuroph.core.Neuron;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.events.LearningEvent;
import org.neuroph.core.events.LearningEventListener;
import org.neuroph.core.learning.error.MeanSquaredError;
import org.neuroph.core.transfer.Linear;
import org.neuroph.core.transfer.Log;
import org.neuroph.core.transfer.RectifiedLinear;
import org.neuroph.core.transfer.Sigmoid;
import org.neuroph.core.transfer.TransferFunction;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.nnet.learning.BackPropagation;
import org.neuroph.nnet.learning.MomentumBackpropagation;
import org.neuroph.util.TransferFunctionType;
import org.neuroph.util.data.norm.MaxMinNormalizer;

import suchtytv.complexservice.game.maths.VectorND;

public class GamePlayingNetwork implements LearningEventListener {
    MultiLayerPerceptron nn;

    public GamePlayingNetwork(int inputNodes, int outPutNodes) {

        nn = new MultiLayerPerceptron(inputNodes, 16,16, outPutNodes);

        for (Layer l : nn.getLayers()) {
            for (Neuron n : l.getNeurons()) {
                n.setTransferFunction(new org.neuroph.core.transfer.Sigmoid());
            }
        }
        nn.getLayerAt(3).getNeuronAt(0).setTransferFunction(new Linear());
        nn.getLayerAt(3).getNeuronAt(1).setTransferFunction(new Linear());

        nn.randomizeWeights();
        MomentumBackpropagation bp = new MomentumBackpropagation();
        bp.setMomentum(5);
        bp.setLearningRate(0.01);


        bp.setErrorFunction(new MeanSquaredError());
        bp.setMaxError(0.001);
        bp.addListener(this);
        bp.setMaxIterations(25);
        nn.setLearningRule(bp);

    }

    public void train(ArrayList<VectorND> samples) {
        System.out.println("Training with " + samples.size() + " sample(s)... this could take a while ");

        DataSet set = new DataSet(47, 2);
        for (VectorND nd : samples) {
            double[] all = nd.getArray();
            double[] input = Arrays.copyOfRange(all, 0, nd.length() - 2);
            double[] output = Arrays.copyOfRange(all, nd.length() - 2, nd.length());
            set.addRow(input, output);

        }
        set.shuffle();
        nn.learn(set);
        System.out.println("Training Done");
    }

    public MultiLayerPerceptron getNeuralNetwork() {
        return nn;

    }

    public void setInput() {

    }

    public void setInput(double[] array) {
        nn.setInput(array);

    }

    public VectorND getOutput() {
        nn.calculate();

        // TODO Auto-generated method stub
        double[] b = nn.getOutput();
        VectorND nd = new VectorND();
        nd.add(b);
        return nd;
    }

    @Override
    public void handleLearningEvent(LearningEvent event) {
        BackPropagation bp = (BackPropagation)event.getSource();
        if (event.getEventType() != LearningEvent.Type.LEARNING_STOPPED)
            System.out.println(bp.getCurrentIteration() + ". iteration : "+ bp.getTotalNetworkError());
  
    }

}
```


----------



## thecain (9. Aug 2018)

Konvergiert es noch? Sonst mehr Daten und/oder mehr iterationen


----------



## Feeder (9. Aug 2018)

thecain hat gesagt.:


> Konvergiert es noch? Sonst mehr Daten und/oder mehr iterationen


Das konvergiert gegen 0.01, wenn ich ein bischen was änder, es überfittet dann aber schnell...


----------



## Feeder (9. Aug 2018)

Ich habe nun eine extrem kleinen Lernrate: 0.0001 
Ich wiederhole 20000 mal. Aber das Feintuning funktioniert nicht, ich habe die Anzahl ähnlicher Werte verkleinert.


----------



## Feeder (10. Aug 2018)

Hat jemand vielleicht noch eine Idee?


----------



## Xyz1 (10. Aug 2018)

Wir müssen mehr über NN s wissen und mehr über das bislang unbekannte Spiel wissen.  sonst wird Dir keiner helfen können


----------



## Feeder (10. Aug 2018)

Ich werde einfach mal ein YouTube Video drehen...


----------



## Xyz1 (10. Aug 2018)

Feeder hat gesagt.:


> Ich werde einfach mal ein YouTube Video drehen...


Das schaue ich mir an!!


----------



## Feeder (10. Aug 2018)

Entschuldigt bitte die schlechte Audioqualität, aber ich habe keinen Weg gefunden das Rauschen so schnell zu beheben:






Grüße Niclas


----------



## thecain (10. Aug 2018)

Hast du schon mal versucht es full Connected zu machen?

https://github.com/neuroph/neuroph/...va/org/neuroph/nnet/MultiLayerPerceptron.java

so ähnlich


----------



## Xyz1 (10. Aug 2018)

Ok vielleicht zwei "Ideen"/Tipps dazu.
"R" startet die Trainingsmenge, dann nochmal "R" stoppt das Training....
Wenn aber in der Trainingsmenge ein oben oder unten über den Rand schreiten gar nicht vorkommt , dann kann er das ja auch nicht lernen, denke ich


----------



## Feeder (10. Aug 2018)

thecain hat gesagt.:


> Hast du schon mal versucht es full Connected zu machen?
> 
> https://github.com/neuroph/neuroph/...va/org/neuroph/nnet/MultiLayerPerceptron.java
> 
> so ähnlich


Es sollte eigentlich von Natur aus fullmashed sein... Ich schau mal nach...
Das Netz ist fully mashed.


----------



## Feeder (10. Aug 2018)

DerWissende hat gesagt.:


> Ok vielleicht zwei "Ideen"/Tipps dazu.
> "R" startet die Trainingsmenge, dann nochmal "R" stoppt das Training....
> Wenn aber in der Trainingsmenge ein oben oder unten über den Rand schreiten gar nicht vorkommt , dann kann er das ja auch nicht lernen, denke ich


Nochmal r stoppt das Training, das ist korrekt.
wie meinst du das, er versucht ja eine Funktion zu approximieren die bei unbekannten Werten was sinnvolles macht...


----------



## Xyz1 (10. Aug 2018)

ich meine das so, das er gerade gelernt hat, das er sich dorthin bewegt, wo keine Vögel sind, und das ist außerhalb des Spielbereichs 
Kannst du das Spiel so ändern, das ein Überschreiten von "oben/unten" nicht möglich ist?


----------



## Feeder (10. Aug 2018)

DerWissende hat gesagt.:


> ich meine das so, das er gerade gelernt hat, das er sich dorthin bewegt, wo keine Vögel sind, und das ist außerhalb des Spielbereichs
> Kannst du das Spiel so ändern, das ein Überschreiten von "oben/unten" nicht möglich ist?



Ich verstehe was du meinst, wenn ich das ändern würde würde es vermutlich besser funktionieren. Aber cooler wäre es natürlich wenn es anhand meiner Daten auch lernt, dass ich nie die Spielgrenzen überschreite


----------



## Xyz1 (10. Aug 2018)

Feeder hat gesagt.:


> Aber cooler wäre es natürlich wenn es anhand meiner Daten auch lernt, dass


Wahrscheinlich wird er das auch lernen, so das Du ein Überschreiten von "oben/unten" im echten Spiel (nicht im Trainingsspiel) wieder zulassen kannst, denk ich


----------



## Feeder (10. Aug 2018)

DerWissende hat gesagt.:


> Wahrscheinlich wird er das auch lernen, so das Du ein Überschreiten von "oben/unten" im echten Spiel (nicht Trainingsspiel) wieder zulassen kannst, denk ich


Ich kann dir gerade leider nicht ganz folgen. Trainingsspiel? Soll ich die Spielregeln abändern?


----------



## Xyz1 (10. Aug 2018)

Feeder hat gesagt.:


> Soll ich die Spielregeln abändern?


ja quasi, wenn ymax = 100 und ymin = 0 ist dann lass bei y >= 100 den roten Punkt mal bei 100....


----------



## Feeder (10. Aug 2018)

DerWissende hat gesagt.:


> ja quasi, wenn ymax = 100 und ymin = 0 ist dann lass bei y >= 100 den roten Punkt mal bei 100....


Dann würde der doch einfach nur stupide gegen die Wand rennen, oder? Ich müsste auch die Geschwindigkeit ds/dt abändern  Sonst funktioniert die Simlation nicht mehr


----------



## Xyz1 (10. Aug 2018)

Feeder hat gesagt.:


> Dann würde der doch einfach nur stupide gegen die Wand rennen,


joa, aber das Verweilen dort wäre nicht gut  ==> er lernt dann innerhalb des Spielbereichs zu bleiben.


----------



## Feeder (10. Aug 2018)

DerWissende hat gesagt.:


> joa, aber das Verweilen dort wäre nicht gut  ==> er lernt dann innerhalb des Spielbereichs zu bleiben.


ahh, du willst eine Neuroevolution implementieren?


----------



## Xyz1 (10. Aug 2018)

Feeder hat gesagt.:


> Neuroevolution


ja
hab ich noch nie


----------



## Feeder (10. Aug 2018)

DerWissende hat gesagt.:


> ja
> hab ich noch nie



also zuerst müsste ich einen Spielplatz bauen, indem mehrere Spieler spielen können. Dann sollte ich die genetische Mutation multithreaden, sonst bekommt man ja Augenkrebs bevor da mal was sinnvolles passiert. Dann sollte ich ein Netz vorfertigen, was möglichst viele Neuronen hat || vielleicht auch ohne grafische Ausgabe iterieren...

Dann bräuchte ich ne Fitnessfunktion das wäre bestmöglich: t oder t^2
Dann würde ich eine eingeschlechtige Fortpflanzung vorziehen, weil Crossingover und sowas Rotz ist...
Dann vielleicht die Liste aller Gewicht:

1
2
3,1
4

in eine Bytekette formattieren:

00000001|00000010|11,0001100110011001100110011001100110011001100110011|00000100

Dann eine Learningrate festlegen.

Und mit dieser Wahrscheinlichkeit jedes Bit flippen.

Dann die neue Kette einlesen...

Das klingt nach einen Haufen Arbeit


----------



## Feeder (10. Aug 2018)

Es muss aber noch einen anderen Weg geben...


----------



## Feeder (11. Aug 2018)

Hatte gerade einen AHA - Moment:

ich nehme ja oft Daten auf bei den nicht wirklich viel passiert. Diesen Daten kommen überproportional häufiger vor als die Daten in dennen was dramatisches/wichtiges passiert. Ich muss also Datenfilterung betreiben...

Ideen?


----------



## Xyz1 (11. Aug 2019)

Hallo @Feeder , habe mich jetzt etwas näher mit Neuroph beschäftigt und ich denke , es liegt an dem max error...


```
BackPropagation bp = new BackPropagation();
		bp.setLearningRate(0.005);
		bp.setMaxIterations(50000);
		bp.setMaxError(0.001);
		System.out.println(bp.getLearningRate());
		System.out.println(bp.getMaxIterations());
		System.out.println(bp.getMaxError());
```

der ist bei neuroph zu hoch eingestellt. Wenn der max error zu hoch ist, learning rate zu hoch ist und max iterations zu klein oder gar nicht eingestellt ist, so bricht er das Training ab - bevor es wirklich sinnvoll ist.

Meine zweite Idee ist, dass Du zu viele hidden layer hast, die Effekte im NN gegenseitig "aufheben" und wodurch das NN zu komplex wird.


----------

