Beiträge von Fischkralle

    So, dass hat jetzt ein wenig gedauert aber gut, dann will ich mal versuchen auf verständliche Weise zusammen zu bekommen, was ich da damals gemacht hab


    Ich hatte mich für ein wirklich kleines Netz entschieden. Somit hatte ich 3 Schichten von Neuronen.
    -1) Die Eingangsschicht (Grün)
    -2) Die Verarbeitungsschicht (Blau)
    -3) Die Ausgabeschicht (Rot)


    [Blockierte Grafik: https://picload.org/image/rpawwwiw/nnn_empty.png]


    Ich hatte hier wirklich nicht die Lust, alle Verbindungen ein zu zeichnen. Stellt euch einfach vor, jedes Neuron aus der Eingabeschicht macht es mit jedem Neuron aus der Verarbeitungsschicht und das gleiche zwischen der Verarbeitungsschicht und der Ausgabeschicht.


    Die Verbindungen zwischen den einzelnen Neuronen nennt man Synapsen.
    In meiner Version haben die Synapsen keine Gewichtung um den Inputt zu verstärken oder zu schwächen. Die Synapsen können hier nur die Zustände 0 = true (Aktiviert) und 1 = false (Deaktiviert) haben. Zu Beginn stehen alle Neuronen auf true.


    Machen wir es an Hand eines Beispiels:
    Wir nehmen den Namen Otto und wollen nun prüfen, ob es sich bei diesem Namen um ein Palindrom handelt. Zu Beginn setze ich alle Buchstaben auf klein. Sonst würde das Netz “O“ und “o“ als nicht gleich betrachten.
    Nun zerlege ich die Buchstaben in ihre Bits. Ich habe dafür natürlich eine kleine Tabelle in der ich mit einem switch / case Block durchlaufe und mir die richtigen Bits zu holen. (Geht auch Algorithmisch aber darum ging es mir nicht.)


    “o“ = 01101111
    “t“ = 01110100
    “t“ = 01110100
    “o“ = 01101111


    So. Nun haben wir unsere 32 Eingangswerte. Diese lassen wir in unser Netz purzeln. Und erhalten so unsere erste gefüllte Schicht:


    [Blockierte Grafik: https://picload.org/image/rpawwwpr/nnn_firstline.png]


    Da in der ersten Runde alle Synapsen aktiv sind fangen auch nun alle Neuronen der Eingabeschicht auf alle Neuronen der Verarbeitungsschicht an zu feuern. Alle eingehenden Werte in ein Neuron der Verarbeitungsschicht werde zusammengerechnet. Da hier jedes Neuron auf jedes Neuron feuert haben alle Neuronen in der Verarbeitungsschicht den gleichen Inputt und zwar [0+1+1+0+1+1+1+1+0+1+1+1+0+1+0+0+0+1+1+1+0+1+0+0+0+1+1+0+1+1+1+1=20]


    [Blockierte Grafik: https://picload.org/image/rpawwwpa/nnn_secondline.png]


    Jetzt kommen die Neuronen aus der Verarbeitungsschicht zum Einsatz.
    In den meisten Neuronalen Netzen steckt hier eine kleine Rechnung hinter, die sich im Laufe der Ausführung ändern und anpassen kann. Auf diese veränderbare Rechnung habe ich in meinem Netz verzichtet und habe den Neuronen eine Konstante Abfrage mitgegeben, nach denen sie bestimmen sollen, ob die Eingabe richtig oder falsch ist.
    Die Frage, die sich nun stellt ist, wann ist die Eingabe richtig und wann ist sie falsch. Also ein Palindrom (Hier mit einer geraden Anzahl von Buchstaben) hat immer eine gerade Anzahl an 1sen und eine gerade Anzahl von 0len in seinem Bit Code. Also habe ich folgende Bedingung in die Neuronen eingebaut:

    Java
    if( value % 2 == 0 ) { output = 0; }
    else { output = 1; }

    Da in unserem Fall value in jedem Neuron 20 ist, kommt am Ende auch immer eine 0 raus. Somit sieht unsere Ausgabeschicht, die ebenfalls von jedem Neuron befeuert wird ziemlich 0lig aus:


    [Blockierte Grafik: https://picload.org/image/rpawwwpl/nnn_thirdline.png]


    Die Ausgabeneuronen werden ausgewertet. Befindet sich keine 1 darunter ist das Netz der Meinung es handelt sich um ein Palindrom und das Ergebnis wird als wahr gewertet.


    RICHTIG!!!


    Nun aber mal ein Wort, dass kein Palindrom ist, wie das Wort “Test“. Erst wird auch dieses Wort wieder in seine Bits zerlegt:


    “t“ = 01110100
    “e“ = 01100101
    “s“ = 01110011
    “t“ = 01110100


    Ohne jetzt immer das Netz zu zeichnen rechnen wir einfach mal nach, was bei der Verarbeitungsschicht ankommt: [0+1+1+1+0+1+0+0+0+1+1+0+0+1+0+1+0+1+1+1+0+0+1+1+0+1+1+1+0+1+0+0 = 17]


    Mit der 17 in der Verarbeitungsschicht angekommen wird wieder auf Mudolo 2 geprüft und festgestellt, dass 17 eine ungerade Zahl ist. Also wird hier von jedem Neuron eine 1 weiter gegeben. Mit lauter Einsen in der Ausgabeschicht ist sofort klar, dass es sich anscheinend nicht um ein Palindrom handelt.


    AUCH RICHTIG!!!


    Das sieht jetzt ja schon alles ganz gut aus. Doch die eigentliche Intelligenz, die ich versuchte nach zu bauen ist noch nicht da. Also werden wir mal etwas fieser und geben das NICHT Palindrom “temp“ rein.


    “t“ = 01110100
    “e“ = 01100101
    “m“ = 01101101
    “p“ = 01110000


    Und auch diese Bits wollen ausgerechnet werden: [0+1+1+1+0+1+0+0+0+1+1+0+0+1+0+1+0+1+1+0+1+1+0+1+0+1+1+1+0+0+0+0 = 16]
    Mit der Rechnung nach Modulo 2 wird festgestellt, dass es sich hierbei um eine gerade Zahl und somit auch um ein Palindrom handelt.


    FALSCH!!!


    Und jetzt geht es los….
    Nachdem das Netz ein falsches Ergebnis ausgeworfen hat, springt nun die Lernfunktion an. Hierbei werden “zufällig“ Synapsen aus der ersten in die zweite und von der zweiten in die dritte Schicht deaktiviert oder aktiviert und der Durchlauf wird wiederholt.


    Es dauert eine Zeit und viele Versuche, bis das Netz auch hier auf das richtige Ergebnis kommt.
    Jetzt wird wieder beim ersten Wort “Otto“ begonnen. Durch die Deaktivierung/Aktivierung einzelner Synapsen ist die Chance nun gegeben, dass hier das Netz bestimmt, dass es sich bei “Otto“ NICHT um ein Palindrom handelt.


    Da dies natürlich falsch ist, wird wieder an den Synapsen rumgeschraubt und der Test so lange wiederholt, bis das Ergebnis wieder richtig ist. Nach “Otto“ kommt wieder “Test“. Müssen hier Einstellungen gemacht werden, wird danach wieder mit “Otto“ angefangen.


    Erst wenn “Otto“, “Test“ und “Temp“ richtig interpretiert werden, kommt das nächste Wort.
    Für das Training hatte ich 100 Wörter vorgesehen, die ihren Test alle bestehen mussten, damit die KI sagt, sie sei fertig. Das Training habe ich natürlich nicht manuell vorgenommen, sondern habe es Unüberwacht gestaltet. (Ein unterschied der Neuronalen Netze ist das Überwachte lernen und das Unüberwachte lernen.)
    Mit einer kleinen GUI konnte ich dem Programm beim Lernen zugucken. und sehen, wann eine Synapse aktiviert und wann eine deaktiviert wurde. (Sah cool aus)


    Schön zu sehen war am Ende, welches Muster sich im Netz ergab:


    [Blockierte Grafik: https://picload.org/image/rpawwwii/nnn_afterlearning.png]


    Wie hier nun NICHT schön zu erkennen ist, wird das erste Bit des ersten Buchstaben mit dem ersten Bit des vierten Buchstabens und das zweite Bit des ersten Buchstabens mit dem zweiten Bit des vierten Buchstabens und das fünfte Bit des zweiten Buchstabens mit dem fünften Bit des dritten Buchstabens verglichen. Natürlich werden auch alle anderen miteinander verglichen. Und zwar so, dass am Ende immer das richtige Ergebnis raus kommt.


    FERTIG!!!


    Dies war nur eine einfache, wirklich richtig einfache, Ausführung eines Neuronalen Netzes. Ich habe dies auf einem solch niedrigen Level gehalten, da es mir nicht darum ging SkyNet nach zubauen, sondern einfach nur um zu verstehen, wie und was da im Hintergrund so abläuft.
    Ich möchte nicht Sagen, dass man nach diesem kleinen Beispiel die Welt der Neuronalen Netze versteht aber man bekommt einen kleinen Einblick davon, wie ein solches Netz arbeitet und was es mit dem lernen auf sich hat.


    Ich habe keine Ahnung ob ich das jetzt verständlich oder ausführlich genug erklärt habe. Wenn Fragen sind, einfach rein damit.
    Wenn ich es kann werde ich diese sogar beantworten.

    Oh man,
    Java Script......
    Also da gibt es das gängigste Framework Jasmine.
    Dieses hat nur einen Nachteil. Es bringt seine eigene DOM mit.
    Daher würde ich auf den Zusatz Karma zurückgreifen, dass in den jeweiligen Browsern mit den original DOMs testet.
    Den genauen Umgang mit beiden kann ich dir allerdings nicht erklären. Aber da gibt es bestimmt genügend auf Google zu finden.

    Ja, im Zuge eines kleinen privaten Projekts hatte ich mal eine geschrieben. Die konnte nach abgeschlossenem Training Wörter darauf prüfen, ob es sich dabei um ein Palindrom handelt oder nicht.


    Kompliziert war zu Beginn, dass reindenken in die Materie. Schlussendlich war es aber nur ein Genetischer Algorithmus, der dafür sorgt, dass sich die Gewichtungen und die einzelnen Verbindungen so anpassten, dass später die richtige Lösung gefunden wurde.

    .xml ist keine Programmiersprache. Das gleiche gilt auch für HTML oder CSS. In keiner dieser Sprachen kann ich eine Bedingung rein bringen.


    Ich kann zwar bestimmen was bei verschiedenen Ereignissen geschehen soll, jedoch kann keine direkte if Abfrage eingebunden werden.


    Ich selber bin nicht so der Fan von .xml Zeug. Man kommt zwar nicht immer drum herum aber im Großen und Ganzen versuche ich darauf zu verzichten.

    Ahh.....
    jetzt habe ich es auch verstanden.


    Ja das habe ich bei mir auch. Wenn ich ein bereits angefangenes Spiel starte ist die Ansicht zu Beginn immer ganz oben und nicht dort, wo ich die letzten Zahlen bewegt habe.

    Der Compiler von C++ verwöhnt seine Programmierer nicht so sehr wie der von Java.


    Rufe ich in einer Funktion (in Java Methode genannt) eine andere Funktion auf, die weiter unten in der Datei erst deklariert wurde, kennt der Compiler diese nicht und schmeißt einen Fehler.


    Aus diesem Grund kann man in C++ am Anfang der Datei sogenannte Funktionsprototypen erstellen. So weiß der Compiler zur Zeit des Aufrufs zwar noch nicht was die Funktion macht, ihm ist aber bewusst, dass eine solche Funktion noch kommt.


    Ein Prototyp sieht aus wie eine abstrakte Methode in Java:

    C
    void doSomthing(int, int, int);
    Java
    public abstract void doSomthing( int x, int y, int z);


    Jetzt kann dieser Prototyp in C++ mit Default Werten ausgestattet werden:

    C
    void doSomthing( int, int, int=2);


    Wird die Funktion nun mit 3 Parametern aufgerufen, werden diese auch alle übernommen. Wird die Funktion mit nur 2 Parametern aufgerufen wird für den 3ten automatisch eine 2 eingesetzt.


    Man kann auch mehrere Default Parameter in einer Funktion deklarieren aber da gibt es noch etwas mehr zu beachten.