PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Neuronales Netz zur Mustererkennung



Che Guevara
13.02.2012, 23:37
Hallo,

da ich nun unter anderem einen genetischen Algo, einen Simulated Annealing Algo und ein boolsches Netz programmiert habe, wage ich mich jetzt an die Programmierung eines Neuronalen Netzes zur Mustererkennung (hier: Zahlenerkennung). Programmiert wird in vb.net. Jedoch habe ich ein paar Fragen:

1. Ich habe schon das halbe web durchsucht, wie man mit der Maus auf einer Picturebox zeichnen kann und anschließend das dann in ein Image laden... Das reine Zeichnen funktioniert, jedoch nur mittels des Graphics-Objektes. Diese Graphic müsste ich dann iwie in ein Bitmap bekommen, um die GetPixel Methode darauf anzuwenden. Aber wie?

2. Wenn ihr Lust & Zeit habt, könnt ihr den momentan Stand des Programms ausprobieren (im Anhang). Ihr könnt euch auch die Codes ansehen (bitte nicht beschweren, ist noch sehr unaufgeräumt...). Ein Bug besteht darin, dass wenn man die erste Zeile der Checkboxen als z.b. "0" definiert und die zweite Zeile als "1", und man markiert beide, so ergibt sich für den Output der Wert von +1 * anzahl der Lernzyklen für die "1", obwohl ja eigentlich 0 rauskommen müsste, da beide "0" und "1" gleichstark von den Rezeptoren aufgenommen werden und diese sich somit aufheben müssten... Vielleicht erkennt ja jemand den Fehler? Es scheint irgendwie, als wenn die linke obere Checkbox nicht richtig miteingerechnet wird.

3. Angenommen ich lerne die Darstellung der 1 10mal und die Darstellung der 2 1mal, dann wird, sofern beide vorhanden sind, die 1 bevorzugt, da die Gewichtungen der Synapsen höher sind. Gibt es da eine allg. gültige Vorgehensweise für Neuronale Netze oder wie macht man das, dass die Lernanzahl keine Rolle spielt? Über eine prozentualle Form?

4. Die Gewichtung der Synapsen erfolgt sehr primitiv, d.h. sobald eine Synapse auf den richtigen Output zeigt, wird ihr Wert um 1 erhöht, ansonsten um 1 verringert. Das ist sicherlich nicht optimal.... Kann mir jemand (evtl. an einem gut verständlichen Beispiel) die delta Regel erklären? Oder gibt es hier noch bessere "Bewertungsfunktionen"?

5. Fällt euch irgendetwas an dem Programm auf, das ihr Verbessern würdet (mal abgesehen von der äußeren Form und Darstellung)?

Ich weiß, viele Fragen auf einmal, aber ich denke, es wird hier einige Spezialisten geben, die dazu etwas sagen können.

Vielen Dank schonmal & Gruß
Chris

lokirobotics
14.02.2012, 12:38
Zu 1:

Du solltest die Businesslogik von der Präsentation entkoppeln. Du musst nicht zwingend auf einer Picturebox malen, dazu kannst du jedes Control nehmen. Implementiere dir die Notwendigen MouseEventHandler (MouseDown, MouseMove und MouseUp reichen schon) und dann kannst du die Zeichenlogik selbst umsetzen. Die GetPixel Methode des Bitmaps ist auch sehr langsam. Ich würde eher auf eine einfache Matrix zurückgreifen und die Auswerten. Die Matrix kannst du nach jeder Veränderung in ein Image überführen und das dann in der PictureBox anzeigen.

Zu den anderen Sachen kann ich erstmal nichts sagen, da ich mich vor 4 Jahren das letzte Mal mi ANN beschäftigt habe.

Dein Programm guck ich mir auf jeden Fall mal an.

lokirobotics
14.02.2012, 13:06
Ich hab in dem Archiv keine Implementierungen für Rezeptor, Output und Synapse etc. gefunden.
Ohne diese Klassen kann man nicht viel zum Programm sagen.

Ein paar Tipps hätte ich aber schon:

1. Benennung von Komponenten: Du solltest die Namen deiner Bezeichner sorgfältig wählen. Wenn du dir diesen Code in einem halben Jahr wieder anschaust, wirst du keine Ahnung haben, was Button1 und was Button2 gemacht hat. "btnLearn" und "btnTest" wären wesentlich geeignetere Namen, aus denen man immer gleich den Sinn ersehen kann.
Code wird nur einmal geschrieben, aber sehr oft gelesen. Die Lesbarkeit des Codes sollte mit an erster Stelle stehen.


Dim rezeptor(5, 8) As rezeptor

rezeptor(5,8) ist doch die Menge aller Rezeptoren. Warum dann nicht

Dim rezeptoren(5,8) As rezeptor ?
Wenn du später mal auf statische Methoden zugreifen musst, ist sofort klar, ob du gerade auf dem Typ, oder der Instanz operierst.

2. Separation of Concerns:

Du hast deine ganze Logik in deine Main-Form gepackt. Das ist sehr unsauber, sorgt für starke Kopplung des Codes und macht Wiederverwendung unmöglich. Wenn du mit deinem Lernprojekt am Ende bist, willst du die ANNs doch in anderen Projekten einsetzen. Wie soll das gehen, wenn du den Lernmechanismus direkt mit deinen Checkboxen verheiratet hast? ;D

Deine Rezeptoren, Synapsen und Outputs gehören erstmal in eine eigene Klasse. Die stellt ein definiertes Interface zur Verfügung (inputs, outputs, methoden etc.). Damit erhälst du ein wiederverwendbares Stück Code, dass du dann auch in anderen Projekten einsetzen kannst. Die Details des Lernens, der Berechung der Ausgänge etc. behält die Klasse für sich, das geht niemand anderen etwas an. Auf den ersten Blick würde folgende Signatur ausreichen:

Methoden:
Konstruktor(InputCount, OutputCount)
GetOutput
SetInput
Learn(desiredOutput)

Dein Programm muss sich dann nur noch darum kümmern, die Werte der Checkboxen an die Eingänge zu legen und die Ausgaben irgendwie anzuzeigen.