Captcha Cracking

    • C#

      Captcha Cracking

      Dieses Tutorial ist eine Übersetzung von meinem originalen Tutorial. Wir befassen uns hier mit dem Thema Captcha Cracking. Wir schauen uns ein einführendes Beispiel zum Thema künstliche neuronale Netze an, übertragen dies auf Captcha Cracking, führen dazu etwas Preprocessing durch und enden mit der fertigen Implementierung:




      Einführung künstliche Neuronale Netze (feed forward neural networks)
      Künstliche Neuronale Netze (kurz aber hier neuronale Netze oder ANN=artificial neural network) gehört zu dem spannenden Gebiet "maschinelles Lernen" und wurde bereits in den 50er Jahren entwickelt. Jeder behauptet, dass diese Netze wie unser Gehirn arbeitet, was sehr gewagt ist, da dies niemand weiß. Im Prinzip ist das neuronale Netz eine komplexe mathematische Abbildung von einem Eingaberaum (Vektoren, Arrays einer bestimmten Länge) in einen Ausgaberaum (Vektoren, Arrays einer bestimmten Länge), welche den Anschein erweckt "lernen" zu können, weil sie theoretisch beliebig komplexe Funktionen imitieren kann, wenn man sie beliebig komplex gestaltet.

      Diese Netze kann man sich als Blackbox (besser als Trichter) mit vielen Rädchen zur Justierung vorstellen, welche anscheinend lernt.

      Beispiel
      In der Trainingsphase schüttet man sozusagen Trainingsdaten in den Trichter und man erhält irgend eine Ausgabe. Stellen wir uns vor, dass das neuronale Netz addieren lernen soll. Wir schütten die Aufgabe "7+3" irgendwie als Vektor codiert in den Trichter und erhalten eine Ausgabe von "12". Jetzt justieren wir durch die kleinen Rädchen am Trichter solange, bis die Ausgabe etwa dem Wert entspricht, den wir uns vorstellen. Nämlich "10". Vermutlich gibt das neuronale Netz "10.8" nach dem justieren aus.



      Danach schütten wir den nächsten Trainingsdateneintrag ein: "5+18" und erhält vom ANN die Ausgabe "30.5", nachjustieren, Daten reinschütten, nachjustieren, Daten reinschütten.

      Das wiederholt man solange bis, man zufrieden ist - in der Hoffnung, dass das ANN nicht nur die Aufgaben auswendig lernt, sondern vielmehr schnallt, was Addieren an sich bedeutet.
      Offensichtlich kommt es auf die Anzahl der Rädchen auch an. Sind es zu viele, so lernt das ANN alles "auswendig". Sind es zu wenige, so wird es vermutlich nie kapieren, was "Addition" bedeutet, weil es einfach zu "einfach" konstruiert ist. Was ist nun die optimale Anzahl von Rädchen? Das ist reine Kunst die Anzahl festzulegen. Meistens experimentiert man damit herum.

      Die Blackbox imitiert damit das Lernen von Mustern. Bisher war die Ausgabe eindimensional. Wenn aber der Trichter mehrere Ausgänge hätte, etwa:

      Hier könnten wir die Justierung so durchführen, dass die Eingaben der Bilder "A","B","C" als Vektor kodiert in Kategorien landen. Für ein Bild von einem Buchstaben "lernt" das ANN diesen in eine der 3 Kategorien einzuordnen.

      Theorie (kann übersprungen werden)
      Das ANN ist wirklich ein Netzwerk hier mit einer Eingabelänge von 3 und einer Ausgabelänge von 4.

      (Dieses Verhältnis macht eigentlich keinen Sinn, sieht aber cool aus!). Jede dieser gefüllt Kreise ist ein sog. "Neuron". Wir haben als 3 Inputneurons und 4 Outputneurons. Die dunklen Neuronen heißen "hidden neurons" und sind in 8 Schichten (layers) eingeteilt. Diese hidden neurons bilden eben unsere Blackbox. Von jedem Neuron geht ein Pfeil zu jedem Neuron in der nächsten Schicht. Die Verbindungslinien haben ein Gewicht.

      Ausgabe berechnen
      Von jedem Neuron wird der Wert mit dem entsprechenden Gewicht multipliziert über den Pfeil weiter gegeben. Ist das Gewicht groß, etwa 2, so wird der Wert vom vorherigen Neuron verdoppelt weitergeben. ist der Wert kleiner als 1, so wird der Wert eben vermindert. Alle einkommende Werte in einem Neuron werden (gewichtet) aufaddiert:


      Jetzt gibt es noch diverse Tricks, wie "weight decay", "activation functions" und andere Spielereien, um dieses lineare weitergeben "nichtlinear" zu machen, etwa durch anwenden einer weiteren Funktion "phi"

      Das "phi" ist üblicherweise die "tanh"-Funktion oder die Sigmoid-Funktion. In der Botsuite darf man zwischen 6 verschiedenen Funktionen wählen. Auch hier gilt wieder probieren. Ein paar Beispiele zur Aktivierungsfunktion:



      Das drehen an den Rädchen und das Justieren entspricht dem Verändern der Gewichte an den Pfeilen. Während man beim berechnen der Ausgabe vom ANN ein "feed forward" macht, so heißt das Ändern der Werte "Backpropagation". Dabei werden die Schichten von hinten nach vorne geändert. Die konkrete Mathematik ist etwas komplizierter. Die Kurzfassung ist: Man macht es wie in der Schule. Den Fehler misst man mit einer Fehlerfunktion, Ableiten, Nullsetzen. Hier ist es jedoch etwas komplexer, da man bzgl. jedem Gewicht partiell ableiten. Das dürften in dem Beispielnetzewerk 536 Ableitungen sein, sofern ich micht nicht verrechnet habe. Einfach graue Pfeile zählen. Das Zauberwort heißt hier "Gradientenabstieg" oder eine Abwandlung "stochastischer Gradientenabstieg". Wer sich mehr für die Mathematik interessiert, den darf ich auf meinen Blog verweisen oder im Internet zu suchen.

      Anwendung auf Captchas

      Wie wir gesehen haben, können wir mit den ANN Muster lernen und Buchstaben, die in Bildern vorhanden sind in Kategorien einordnen. Da Frage ist nun, wie wir das Bild kodieren. Der naive Ansatz ist jedem Pixel ein Inputneuron zu spendieren.

      Dummerweise ergibt jeder Input auch wieder etliche Gewichte, die zuverändern sind:

      Man könnte die weißen Pixel als "0" und die blauen Pixel als "1" kodieren. Das ergäben aber etliche Ableitung. Die Idee ist "Features" zu verwenden. Diese Features sind eine höhere Kodierung des Bildes. Bei normaler Bilderkennung könnte man als Features nehmen:
      • Ist ein Auspuff vorhanden
      • Ist ein Auge vorhanden
      • Ist ein Ohr vorhanden
      • Baum vorhanden

      Die neuronale Netze versuchen dann aus den Rückgaben der Features zu erkennen, ob es sich zum Beispiel auf dem Bild um ein Gesicht handelt. Wenn ein Auspuff vorhanden ist, so könnte ich mir vorstellen, dass das neuronale Netz sagt: "Mhm, ist vermutlich kein Gesicht."

      Wir verwenden die Idee von zauberhaften Streichhölzern. Diese sind eben magisch und haben verschiedene Längen und Breiten. Stell dir vor, dass der Buchstabe ab dem Boden liegt und du darüber Streichhölzerschüttest:

      Wie gesagt. Die sind eben magisch. Trifft eines dieser Streichhölzer den Buchstaben, so wird das Streichholz blau:


      Liegen die Streichhölzer nun fest an einer Stelle bei jedem Bild, welches einen Buchstaben kodiert, so ergeben sich bei fester Nummerierung der Streichhölzer verschieden Farbfolgen: (rot,rot,blau,rot,....) ,... (blau,rot,rot,...)

      Unser ANN lernt nun aus diesen Farbfolgen Muster zu erkennen und dementsprechend aus den Mustern Buchstaben zu erkennen. Nähere Details, die wir nicht benötigen sind hier zu finden. Das macht die BotSuite automatisch.
      Ein richtiger Vorteil ist, dass diese Art Features zu extrahieren auch Invariant gegenüber Skalierung ist. Die Streichhölzer "wachsen" sozusagen mit der Bildgröße mit. Hat das eine "e" eine Bildgröße von "12px mal 50px" und ein anderes "21px mal 50px", so werden die Streichhölzer auch länger.
      Captcha PreProcessing
      Das ANN kann nun aus den einzelnen Buchstabenbildern den darauf abgebildeten Buchstaben erkennen. Doch ein Captcha erschwert uns die Aufgabe:

      Wir müssen preprocessing betreiben. Das geht nicht automatisch. Als erstes suchen wir mit Hilfe der Pipette in einem Grafik-Tool unserer Wahl die Farbe von der Störung. Die Captcha-Entwickler waren doch glatt so nett den komischen Strich mit einer gesonderten Farbe zu platzieren. Hierfür ein großes Dankeschön.

      Graustufenbild
      Mittels

      C# - CSharp

      1. private void btnStep000_Click(object sender, EventArgs e)
      2. {
      3. OpenFileDialog DialogForUnknownLetter = new OpenFileDialog();
      4. DialogForUnknownLetter.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*";
      5. if (DialogForUnknownLetter.ShowDialog() == DialogResult.OK)
      6. {
      7. RawCaptcha = new ImageData(DialogForUnknownLetter.FileName);
      8. UpdateCaptchaCanvas();
      9. }
      10. }

      laden wir das Captcha Bild. Die Funktion

      C# - CSharp

      1. protected void UpdateCaptchaCanvas()
      2. {
      3. pbxCaptchaCanvas.Image = RawCaptcha.GetBitmap();
      4. pbxCaptchaCanvas.Refresh();
      5. }

      update jedes Mal nur die PictureBox.
      So jetzt den Strich entfernen und nach Schwarzweiß konvertieren

      C# - CSharp

      1. private void btnStep001_Click(object sender, EventArgs e)
      2. {
      3. Filter.ReplaceSimilarColor(ref RawCaptcha, Color.FromArgb(98, 139, 218), Color.FromArgb(226, 226, 226), 70);
      4. Filter.BlackAndWhite(ref RawCaptcha, 127);
      5. UpdateCaptchaCanvas();
      6. }


      ergibt doch

      Ein bisschen Herumspielen mit Filtern der Botsuite erzielt durch den Code

      C# - CSharp

      1. private void btnStep001_Click(object sender, EventArgs e)
      2. {
      3. // remove the blue pixels
      4. Filter.ReplaceSimilarColor(ref RawCaptcha, Color.FromArgb(98, 139, 218), Color.FromArgb(226, 226, 226), 70);
      5. // darken the dark black pixels
      6. Filter.ReplaceSimilarColor(ref RawCaptcha, Color.FromArgb(25, 32, 16), Color.Black, 50);
      7. // convert to black and white
      8. Filter.BlackAndWhite(ref RawCaptcha, 20);
      9. UpdateCaptchaCanvas();
      10. }


      das Ergebnis

      Das scheint etwas dünner die Buchstaben darzustellen bei mehreren Captchas ergibt es aber besser Ergebnisse.
      Buchstaben trennen
      Nun sind die Buchstaben auch glücklicherweise linear trennbar, d.h. wir können vertikale Geraden zwischen die Buchstaben zeichnen.

      C# - CSharp

      1. private void btnStep002_Click(object sender, EventArgs e)
      2. {
      3. /* --------------- Buchstaben trennen -------------------------------------------- */
      4. // wir testen jede Spalte
      5. bool[] VertikaleLinien = new bool[RawCaptcha.Width];
      6. // jede Spalte durchlaufen
      7. for (Int32 column = 0; column < RawCaptcha.Width; column++)
      8. {
      9. // erst denken wir, dass wir eine Linie zeichnen können
      10. bool blank = true;
      11. // dann schauen wir mal, ob wir an schwarzen Pixeln anecken
      12. for (Int32 row = 0; row < RawCaptcha.Height; row++)
      13. {
      14. if (RawCaptcha.GetPixel(column, row) == Color.Black)
      15. {
      16. // ups ein schwarzer Pixel => hier ist ein Buchstabe
      17. blank = false;
      18. break;
      19. }
      20. }
      21. // alle Pixel weiß
      22. if (blank)
      23. {
      24. // wir merken uns, dass wir die Linie zeichnen können
      25. VertikaleLinien[column] = true;
      26. // und Linie zeichnen
      27. for (int row = 0; row < RawCaptcha.Height; row++)
      28. RawCaptcha.SetPixel(column, row, Color.FromArgb(225, 225, 225));
      29. }
      30. else
      31. {
      32. // Linie kann nicht gezeichnet werden
      33. VertikaleLinien[column] = false;
      34. }
      35. }
      36. UpdateCaptchaCanvas();
      37. }


      Das setzt genau die Idee von oben um: Jede Spalte durchgehen und nachschauen, ob eine Line gezogen werden kann, ohne einen schwarzen Pixel (der gehört zu einem Buchstaben) zu berühren. Ist dies möglich, so zeichnen wir eine graue Linie und erhalten

      Et violà. Jeder Buchstabe ist nun getrennt. Jetzt suchen wir noch den Anfang und das Ende von jedem grauen Gebiet in der gleichen Funktion. Dabei muss man einfach nur das graue Gebiet ablaufen und den Anfangspunkte und den Endpunkt vom Gebiet sich merken:

      C# - CSharp

      1. /* --------------- determine start and end of the letters -------------------------------------------- */
      2. List<Bitmap> Letters = new List<Bitmap>();
      3. bool open = false; // = false --> nor red area
      4. int left = 0, width = 0; // remember position
      5. for (Int32 column = 0; column < RawCaptcha.Width; column++)
      6. {
      7. // not in gray area?
      8. if (!VertikaleLinien[column])
      9. {
      10. if (open == false)
      11. {
      12. // new start of letter
      13. left = column;
      14. // draw green vertical line
      15. for (int row = 0; row < RawCaptcha.Height; row++)
      16. RawCaptcha.SetPixel(column - 1, row, Color.Green);
      17. }
      18. open = true;
      19. }
      20. else
      21. {
      22. if (open == true)
      23. {
      24. // end of current letter
      25. width = column - left - 1;
      26. if (width > 1)
      27. {
      28. Letters.Add(RawCaptcha.GetBitmap(left, 0, width, RawCaptcha.Height - 3));
      29. // draw blue vertical line
      30. for (int row = 0; row < RawCaptcha.Height; row++)
      31. RawCaptcha.SetPixel(column + 1, row, Color.Blue);
      32. left = column;
      33. open = false;
      34. }
      35. }
      36. }
      37. }
      38. UpdateCaptchaCanvas();


      In der Liste "Letters" stehen die einzelnen Buchstaben als Bitmap drin. (Ja der Quelltext ist wieder teilweise englisch, da ich es nicht zurück übersetzen möchte). Wir erhalten

      Linkes Ende ist grün und rechtes Ende ist blau.
      Bilderkennung
      So jetzt haben wir die Buchstaben einzeln. Zuerst der langweilige Teil des Trainings. Man muss manuell Buchstaben sortieren. Ich habe mir etliche Captchas heruntergeladen und mit dem obigen Code getrennt und manuell sortiert. Ihr braucht das nicht machen, weil ich das bereits erledigt habe. Zuerst das langweilige Zeug bestehend aus dem Einlesen der Buchstaben aus den zuvor mühevoll sortierten Buchstaben:

      C# - CSharp

      1. // Wörtbuch für Bilder anlegen
      2. Dictionary<Char, List<ImageData>> ImageTraining = new Dictionary<Char, List<ImageData>> { };
      3. List<ImageData> ImagesForA = new List<ImageData> { };
      4. List<ImageData> ImagesForE = new List<ImageData> { };
      5. // vom aktuellen Pfad aus die Buchstabenordner einlesen
      6. string path = Directory.GetCurrentDirectory();
      7. string pathForA = Path.Combine(path, "sorted", "a");
      8. string pathForE = Path.Combine(path, "sorted", "e");
      9. // einlesen
      10. string[] DirectoryOfA = Directory.GetFiles(pathForA);
      11. Debug("load trainingset for a (" + DirectoryOfA.Length + " files)");
      12. string[] DirectoryOfE = Directory.GetFiles(pathForE);
      13. Debug("load trainingset for e (" + DirectoryOfE.Length + " files)");
      14. // Trainingsdaten erstellen
      15. foreach (string dir in DirectoryOfA)
      16. ImagesForA.Add(new ImageData(dir));
      17. foreach (string dir in DirectoryOfE)
      18. ImagesForE.Add(new ImageData(dir));
      19. // und die Listen bereitstellen
      20. ImageTraining.Add('a', ImagesForA);
      21. ImageTraining.Add('e', ImagesForE);


      Wie gesagt nicht spannendes nur einfach Einlesen der Buchstaben. Jetzt verwerfen wir die ganze Theorie der Captchas und verwenden die folgende Zeilen

      C# - CSharp

      1. MyOCR = new OCR(27);
      2. MyOCR.StartTrainingSession(ImageTraining);

      Hierbei werden 27 der magischen Streichhölzer erstellt und das Training vom ANN beginnt. Hier geht das auch recht flott und dauert nicht einmal eine Minute. Mehr ist das nicht. Im Anhang ist etwas Quelltext für den Debuglog dabei. Ist das Training fertig, so können wir es auch einmal ausprobieren:

      C# - CSharp

      1. private void btnRecognize_Click(object sender, EventArgs e)
      2. {
      3. OpenFileDialog DialogForUnknownLetter = new OpenFileDialog();
      4. DialogForUnknownLetter.Filter = "bmp files (*.bmp)|*.bmp|All files (*.*)|*.*";
      5. if (DialogForUnknownLetter.ShowDialog() == DialogResult.OK)
      6. {
      7. ImageData Letter = new ImageData(DialogForUnknownLetter.FileName);
      8. MessageBox.Show(MyOCR.Recognize(Letter).ToString());
      9. }
      10. }

      Hier öffnen wir einen Dateidialog zum auswählen eines Buchstabens. Eine MessageBox gibt aus, was das ANN meint zu sehen. Wichtig hierbei ist, dass man zum probieren Buchstaben aus dem Ordner "probeset" nimmt, da diese nicht zum Lernen verwendet wurden. Da das klappt, kann man davon ausgehen, dass das ANN nicht die Buchstaben auswendig gelernt hat, sondern vielmehr aus der Mustererkennung die Buchstaben erkennt.

      Da wir dem Nutzer oder dem Bot nicht jedes Mal eine Traingsphase zumuten wollen -unter Umständen kann diese auch mal 30h dauern- kann man das Netzwerk abspeichern mittels:

      C# - CSharp

      1. private void btnSave_Click(object sender, EventArgs e)
      2. {
      3. MyOCR.Store("Demo.ann");
      4. }


      Zum Laden kann man den Code

      C# - CSharp

      1. private void btnLoad_Click(object sender, EventArgs e)
      2. {
      3. MyOCR = OCR.Load("Demo.ann");
      4. btnRecognize.Enabled = true;
      5. btnSave.Enabled = true;
      6. }

      verwenden. Das war alles dazu. Das Projekt befindet sich im Anhang.

      Ausblick:
      Je nach Spaß, Laune, Zeit und anderen Umständen wird demnächst noch eine SVM in die BotSuite mit einziehen, da auch diese geeignet ist Bilderkennung zu betreiben. Da besteht nur der Aufwand eine SVM in ordentlichem C# zu schreiben. Eine weitere tolle Sache sind die Deep Learning Neural Networks, die keine Streichhölzer benötigen, da die selbst diese Features zu extrahieren. Hier ist erschreckend, wie gut das funktioniert. Auf
      cs.nyu.edu/~fergus/tutorials/d…2_nnets_ranzato_short.pdf
      Sind auf Seite 12,13,14 die Features, die der Computer selber extrahiert hat. Während in der 1. Stufe (Seite 12) man nur Edge-Detectors hat, sind auf Seite 13 schon deutlich Autoteile zu erkennen. Das sind die Sachen nach denen das ANN selber sucht und sich merkt.

      Feedback ist erwünscht, deswegen auch außerhalb des Wikis gepostet.

      Für die aktuelle Library einfach unter
      botsuite.net/
      vorbeischauen.
      Gesendet von meiner Schreibmaschine mittels Brieftaube.
      wieschoo.comBotSuite.NET

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „wieschoo“ ()

      Sehr cool und super erklärt, vielen Dank :)! Echt schade, dass du das nicht in Java oder AutoIt machst :P!
      Die Bot Suite wird ja immer mächtiger^^.

      Ist dieses "neuronale Netz" eine "Standard-Funktion" oder musstest du das auch erst selber implementieren?! :)
      Und welche bekannten OCR-Software(s) nutzen das? Tesseract und Co? :)

      LG
      Aca
      Danke für die Blumen ;)

      Ist dieses "neuronale Netz" eine "Standard-Funktion" oder musstest du das auch erst selber implementieren?! :)

      Muss man selber implementieren. Ist aber auch nicht schwierig, wenn man weiß, was man zu machen hat und wie das Ding funktioniert. Des Weiteren habe ich geschaut, wie andere das Implementieren und wie man das besser machen kann. Man kann das besser machen, als andere ;)
      Und welche bekannten OCR-Software(s) nutzen das? Tesseract und Co?

      Danke für den Verweis auf Tesseract. Ich habe eben auf Google Code mal den Quelltext überflogen. Die verwenden auch ein neuronales Netz (allerdins in C++ mit Templates und vorberechneten Werte der Sigmoid-Funktion geschrieben. Das dürfte schneller sein).
      Im Quelltext von Tesseract habe ich "auto-encoder" gefunden. Das ist die Idee, die ich im "Ausblick" bei dem Verweis auf Google kurz angerissen habe.
      nicht in Java oder AutoIt machst

      ersteres wird überbewertet :P und leider an den Unis gelehrt
      letzteres mag ich nicht (wer schreibt schon ein Programm mit "While 1 ... " ?!)

      Im übrigens gibt es von Andrews Ng einen guten Vortrag, der zeigt, was man momentan mit neuronalen Netzen machen kann und wohin die Reise geht, wenn man "deep learning" richtig anwendet:

      Gesendet von meiner Schreibmaschine mittels Brieftaube.
      wieschoo.comBotSuite.NET
      @truvali89: Vlt erläuterst du dein Problem etwas genauer?

      Dieser Löser kann deswegen nur die Buchstaben A und E, weil es ausreichend ist um die Funktionsweise zu zeigen. Alles andere wäre zu viel Arbeit.
      C makes it easy to shoot yourself in the foot. C++ makes itharder, but when you do, it blows away your whole leg.


      Dein Deutsch ist echt gut :thumbsup:

      Ich nehme an, du möchtest ein anderes Captcha mit diesem Algorythmus lösen? Kein Problem!
      Alles was du benötigst, ist das Verständins. Du musst wieschoos Solver analysieren und auf deinen eigenen Captcha-Solver übertragen. Das meiste davon sollte jedoch identisch bleiben.

      Das programm erkennt wahrscheinlich keine Buchstaben, weil du ihm diese noch nicht beigebracht hast .
      C makes it easy to shoot yourself in the foot. C++ makes itharder, but when you do, it blows away your whole leg.


      hi wieschoo
      erstmal danke für dieses Tutorial
      Ich steh nur leider jetzt vor einem Problem ...
      Ich habe jetzt mal angefangen ne paar mehr buchstaben rein zupacken ...

      Quellcode

      1. load trainingset for a (68 files)
      2. load trainingset for b (19 files)
      3. load trainingset for c (50 files)
      4. load trainingset for d (87 files)
      5. load trainingset for e (70 files)
      6. load trainingset for f (47 files)
      7. load trainingset for g (50 files)
      8. initialise OCR
      9. start training
      10. training is finished

      mein Problem ist jetzt aber das g als d erkannt werden
      muss ich die anzahl der "streichhölzer" echt über 100 packen das es richtig erkannt wird oder reicht es wenn ich mehr buchstaben sortiere ?

      danke
      swa
      Jetzt ein halbes Jahr später kommt vielleicht ein kleines Update:

      Es ist wesentlich performanter kernelized PCA und restricted boltzmann machines RBM zu verwenden. Einfach mal nach "MNIST rbm" googeln. Das Tutorial sollte nicht dazu dienen einen hochperformantes OCR zu implementieren sondern einfach und salopp erklären, was eigentlich dahinter steckt. Gerade RBM als ein Spezialfall von Deep Belief Nets ist momentan State-Of-The-Art.
      AForge.NET implementiert viele der Algorithmen.

      Die Ergebnisse werden besser durch:
      • mehr Trainingsbuchstaben
      • mehr Schichten im Netzwerk
      • mehr hidden Nodes
      • mehr "Streichhölzer"

      Allerdings dauert das Training dann länger. Und die genau guten Werte ist Wahrsagerei und hängt von den Daten ab. Leider. Natürlich machen 800 Streichhölzer wenig Sinn. Irgendwann "lernt" das Netz die Daten einfach nur auswendig (overfitting).
      Gesendet von meiner Schreibmaschine mittels Brieftaube.
      wieschoo.comBotSuite.NET
      Es gibt nun eine deutlich performantere Implementation des neuronalen Netzes. Dabei verwendet Eigen sogar vektorisierte Operationen. Wenn es nicht so viele Umstände macht, werde ich es versuchen in der BotSuite unterzubringen. Um in 10 000 Epochen (eine Schicht hidden layers mit 4 Units) die einfache logische OR-Funktion zu lernen benötige ich gerade mal ca. 0.066s. Dagegen sieht die momentane Version in der BotSuite recht alt aus. Vielleicht ist es überlegenswert alle Funktionen nach C++ zu portieren. Für 1 000 000 Epochen sind es gerade mal 0m6.278s.
      Vielleicht kann auch jemand anderes das in die BotSuite integrieren.
      Gesendet von meiner Schreibmaschine mittels Brieftaube.
      wieschoo.comBotSuite.NET