Selbst-organisierende Feature Maps (Kohonen Maps) - Wiederaufgreifen des Themas

Mykola Demko | 24 Mai, 2016

Einführung

Dieser Artikel ist eine Fortsetzung des zuvor veröffentlichten Artikels "Verwendung von selbstorganisierenden Feature Maps (Kohonen Maps) in MetaTrader 5". Ein großer Teil dieses Materials wurde überarbeitet und angepasst für eine einfachere Anwendung in Projekten. Allgemein zielt der Artikel darauf ab, Anfängern und erfahrenen Programmierern zu helfen, einen neuronalen Netzwerk-Algorithmus von Kohonen Maps mit ihre Projekten zu verbinden und den Hauptalgorithmus selbst zu bearbeiten. Es wird nur ein Sample von Mustern im Artikel verwendet, aber die Betonung liegt auf der Vielfalt der Möglichkeiten den Code zu verwenden.


Theorie von Kohonen-Maps

Ein selbst-organisierende Feature Map (SOM) ist ein einschichtiges Netzwerk wo jedes Neuron mit allen Komponenten des n-dimensionalen Eingabevektors (Muster) verbunden ist. Eingabevektor (Muster) – ist eine Beschreibung eines der Objekte das der Clusterbilung unterliegt.

Training ohne einen Supervisor wird in der SOM ausgeführt. Zu Trainingszwecken werden Wettbewerbsmechanismen angewendet. Wenn Sie ein Muster-Netzwerk an die Eingabe senden, gewinnt das Neuron mit dem Vektor, der sich am wenigsten vom Eingabemuster unterscheidet. Das folgende Verhältnis gilt für das Gewinner-Neuron:

Formel 1

wobei:

Der Euklidische Raum wird am häufigsten als Distanz verwendet.

Formel 2

In dieser Implementierung wird die Suche des Gewinnerneurons in der BestMatchingNode-Funktion der CSOM_Net_Base -Klasse ausgeführt.

Nachbarschaft und Radius des Lernens bilden sich rund um das Gewinner-Neuron. Ein Radius des Lernens definiert welche Neuronen in dieser Iteration dem Training unterliegen. Zu Beginn des Trainings ist er beim Maximum und wird mit dem Wachstum der Trainingsiterationen verringert, so dass in der Endphase nur mehr das Gewinner-Neuron im Lern-Radius liegt.

Nachbarschaft des Gewinner-Neurons

Gewichtungen der Neuronen innerhalb des Lernradius werden nach der Kohonenregel angepasst:

Kohonenregel

wobei:

Gewichtungen der Neuronen außerhalb des Lernradius werden nicht angepasst. In dieser Implementierung werden Gewichte in der AdjustWeights-Funktion der CSOMNode -Klasse angepasst.

Das ni(k)Trainingstempo-Verhältnis gliedert sich in zwei Teile:

Nachbarschaft-Funktion

Funktion des Trainingstempos

wo A und B ausgewählte Konstante sind.

Diese Funktion ist umgekehrt proportional zur Nummer der Trainingsschleife, in der Anfangsphase, hat das Training also eine hohe Geschwindigkeit und einen großen Radius, Muster werden gemittelt. Am Ende des Trainings werden Gewichtungen schließlich an die Eingabe-Parameter angepasst.

Im Allgemeinen kann die Anpassungsdynamik eines bestimmten Neurons als ein absteigender Gradient dargestellt werden:

Gradientenabstieg

Wenn das Kohonen-Netzwerk trainiert wird, tritt ein Problem der so genannten "Toten Neuronen" auf. Neuronen, die anfängliche Gewichtungskoeffizienten fernab vom Eingabemuster haben, können ungeachtet der Länge des Trainings nie einen Wettbewerb gewinnen. In dieser Implementierung wurde das Systemproblem des Kohonen-Training-Algorithmus mit zwei Revisionen gelöst.

Zunächst einmal wurde die Funktion der zufälligen Auswahl von Mustern aus einer Trainingsmenge überarbeitet. Die C_PRNG_UD-Klasse wird anstelle von (Rand) / n verwendet, die keine Garantie gibt, dass alle Werte für N Iterationen erscheinen werden. Sie garantiert gleichmäßig verteilte Zufallsmuster-Auswahl. Zweitens werden Gewichtungen der Neuronen mit zufälligen Werten initialisiert, aber nur aus dem Bereich der in den Mustern vorkam.

Selbst wenn wir auf Neuronen stoßen, die nie einen Wettbewerb gewinnen – "tote Neuronen", dann werden diese zumindest in der Nachbarschaft des Gewinners bleiben und werden dem Training unterliegen, indem sie die Rolle einer Brücke zwischen Mustern und Clusterung bilden.


Umsetzung eines Kohonen-Netzwerk mit Anwendungsbeispielen

Wir werden jetzt eine Software-Implementierung von Kohonen-Maps erklären. Die aktuelle Implementierung erfolgt basierend auf zwei Maßzahlen: Dimension der Muster (M_dimension) und Summe der Knoten (M_total_nodes). Jedoch werden die Maps dreidimensional dargestellt, wobei M_total_nodes in ein M_xcells * M_ycells Rechteck gefaltet ist. Daher speichern Knoten Informationen über Gewichte und Lage.

class CSOMNode
  {
protected:
   
   //--- Koordinaten der Knoten-Zone
   int               m_x1;
   int               m_y1;
   int               m_x2;
   int               m_y2;
   
   //--- Koordinaten des Knoten-Zentrums
   double            m_x;
   double            m_y;
   
   //--- Knotengewichtungen
   double            m_weights[];
   ...

Die CSOMNode -Klasse ist kompositorisch in die CSOM_Net_Base Basisklasse in Form eines eindimensionalen Arrays von Beispielen der CSOMNode [M_som_nodes] -Klasse enthalten. Dies ist das eigentliche Kohonen-Netzwerk. Andere Funktionen dienen einfach dem Training und der Erforschung des Netzwerkes.

Der vorherige Artikel betonte die Vielfalt der Musterproben und demonstrierte die grafische Vielfalt der Schnittstelle. In diesem Artikel wird nur ein Beispiel von Mustern, aber in fünf Variationen der Konnektivität betrachtet. Ich habe den Quellcode überarbeitet um eine einfache Anbindung an Nebenprojekte zu ermöglichen. Die Implementierung ist in fünf Klassen unterteilt.

class CSOM_Net_Base
class CSOM_Net_Data   : public CSOM_Net_Base
class CSOM_Net_Train  : public CSOM_Net_Data
class CSOM_Net_Img    : public CSOM_Net_Train
class CSOM_Net_Demo   : public CSOM_Net_Img

Die Deklaration zeigt die kaskadierte Verbindung der Klassen. Wenn es in einem verbundenen Projekt keinen Bedarf für einige Funktionen gibt, genügt es untergeordneten Klassen nicht zu verbinden, so dass die folgenden Funktionen abgeschnitten werden.

Unten ist die Liste der öffentlichen Funktionen:

class CSOM_Net_Base
  {
public:
   //--- öffentliche Knoten des Kohonen-Netzwerk
   CSOMNode         *public_node;
   ---Funktion sendet die ind Knoten zum öffentlichen Bereich Public_node
   void              GetNode(int ind){ public_node=m_som_nodes[ind].GetObjPointer(); };
   // ---Funktion gibt Dimension der Muster zurück
   int               GetDimension(){return(m_dimension);};
   //--- Funktion um das Netzwerk aus einer Datei zu laden                 
   bool              DownloadNet(string file_name);
   // --- Funktion für die Suche nach den besten Knoten basierend auf einem angegebenen Vektor mit einer Maske
   int               BestMatchingNode(const double &vector[]);
   ---Funktion für die Suche nach dem besten Knoten basierend auf einem angegebenen Vektor mit Beschneidung der Größe der Dimension
   int               BestMatchingNode(const double &vector[],int dimension);
   //--- Funktion zum Befüllen einer Bitmaske für die Suche nach Knoten, die Mustern ähnlich sind (die Maske bestimmt, welche Felder zu durchsuchen sind)
   bool              InitSetByteMap(int num,bool value);
  };
  
class CSOM_Net_Data : public CSOM_Net_Base
  {
public:
   //--- Funktion zum Laden von Daten für das Training aus der angegebenen Datei
   bool              LoadPatternDataFromFile(string filename);
   // --- Funktion zum Hinzufügen eines Vektors zur Trainingsmenge
   void              AddVectorToPatternsSet(double &vector[],string title);
   //--- Funktion zum Kopieren einer Musters aus der Trainingsmenge    
   bool              GetPatterns(int ind_pattern,double &vector[]);
   //--- Funktion für die Rückgabe eines Muster-Titels aus der Trainingsmenge  
   string            GetTitlesPatterns(int ind_pattern);
   //--- Funktion für die Rückgabe der Anzahl aller Muster
   int               GetTotalsPatterns();
  }; 
  
class CSOM_Net_Train : public CSOM_Net_Data
  {
public:
   //--- Funktion für die Initialisierung des Netzwerks, abfragen der Parameter
   void              InitParameters(int iterations,int xcells,int ycells);
   //--- Funktion für Trainingsnetzwerk
   void              Train();
   //--- Funktion um das Netzwerk in Datei zu speichern 
   void              SaveNet(string file_name);
   //--- virtuelle Funktionen (der Körper wird im CSOM_Net_Img Kind beschrieben) 
   virtual void      Render(){};
   virtual void      ShowBMP(bool back){};
  }; 
  
class CSOM_Net_Img : public CSOM_Net_Train
  {
public:
   //--- Funktion für die Initialisierung des Netzwerks, abfragen der Parameter
   void              InitParameters(int iterations,int xcells,int ycells,
                                    int bmpwidth,int bmpheight,
                                    bool p_HexagonalCell,bool p_ShowBorders,bool p_ShowTitles,
                                    int p_ColorScheme,int p_MaxPictures);
   //--- Funktion für die Anzeige des Zustands des Netzes
   void              Render();
   //--- Funktion für Anzeige eines Bmp-Bild auf dem Chart  
   void              ShowBMP(bool back);
   //--- Funktion um eine Ressource in einer Bmp-Datei zu speichern
   void              SaveBMP();
   //--- Deinitialisierungsfunktion, BMP-Bild aus dem Diagramm entfernen
   void              NetDeinit();
  };
  
class CSOM_Net_Demonstration : public CSOM_Net_Img
  {
public:
   //--- Funktionsbeispiel für die Verwendung eines Kindes um die Chancen zu erhöhen
   void              ShowTrainPatterns();
  };

Die angehängten Dateien enthalten fünf Beispiele mit Möglichkeiten der Verwendung von Kohonen-Maps. Die Beispiele sind in der Reihenfolge der Klassenkaskade nummeriert. Wir werden alle Beispiele nacheinander analysieren.


Netzwerkerstellung, Basisklasse

Das erste Beispiel erfordert eine Datei mit der Endung somnet um zu funktionieren, sie wird verwendet, um ein zuvor trainiertes Netzwerk zu speichern. Das Beispiel bietet eine Möglichkeit der Verbindung von einem trainierten Netzwerk mit einem Expert Advisor um Muster, die aus der Softwareimplementierung gesendet wurden zu unterscheiden. Der Einfachheit halber werden die Daten über die FileReadArray -Funktion gelesen. Es erfordert keine komplizierte Systeme für das Lesen und erkennen von Zeilen (Parser). Darüber hinaus ist es schneller, Daten mittels Arrays zurückzusetzen und zu beziehen.

Sample1_SOM_Net_Base zeigt, wie ein trainiertes Netzwerk aus einer im Parameter angegebenen binären Datei (ohne Erweiterung) geladen wird:

input string SOM_Net="SOM\\SOM_Net";

Die Somnet Erweiterung wird automatisch eingefügt. Dies hilft Verwechslungen zu vermeiden, sodass eine für den Algorithmus ungeeignete Datei nicht geladen wird.

Das Laden des Netzwerkes erfolgt in der DownloadNet(string file_name)-Funktion. Nach einer eingehenden Prüfung der Funktion des Körpers wird das Format der Datei Somnet klar. Der Header, bestehend aus drei Speicherzellen des double -Typs (wie der Rest des Arrays der aus der Datei geladen wird) wird am Anfang der Datei geschrieben. Das erste Feld speichert die Dimension der Muster plus sechs. Sechs Felder sind notwendig für die Speicherung der Knotenkoordinaten. Aber da sechs ein konstanter Wert ist, können wir leicht die Muster-Dimension durch Abzug von sechs vom ersten Feld des Array-Headers erhalten. Die zweiten und dritten Felder speichern die Variablen M_xcells und M_ycells - Größe von X und Y bzw. in der visuellen Darstellung des Netzwerks. Durch Multiplikation erhalten Sie die Anzahl der Knoten im Netzwerk.

Darauf folgt das Laden der Netzwerkdaten Vektor für Vektor, bis das gesamte Netzwerk geladen wurde.

Fahren wir mit dem Beispiel fort. Nachdem das Netzwerk geladen wurde, wird das vector [] Muster mit Konstanten gefüllt. Initialisierung mit Konstanten wird als Beispiel bereitgestellt. Die BestMatchingNode -Funktion findet den Index des ähnlichsten Knotens. Dann wird der Knoten für einen sicheren Zugriff an den öffentlichen Teil der Funktionen der CSOMNode-Klasse gesendet.

Wir konzentrieren uns mehr auf die BestMatchingNode -Funktion. Es hat drei Möglichkeiten der Anwendung. Beim Aufruf der BestMatchingNode (const double &vector[]) Überladung ohne Maskeninitialisierung wird die Suche durch alle Vektorfelder durchgeführt, weil die Funktion die Maske mit Einheiten selbst initialisiert, d. h. sie ermöglicht die Suche über alle Felder. Wenn die Initialisierung der Maske InitSetByteMap (Int Num, Bool-Wert) für jedes Feld im Voraus aufgerufen wird, wird die Filterung nach welchem Feld gesucht werden soll eingeschaltet. Auf diese Weise haben wir die Möglichkeit, für einen Knoten auf Basis unvollständiger Informationen zu suchen. Wenn eine andere BestMatchingNode (const Double & Vektor [], Int Dimension) Überladung verwendet wird, wird die Filterung bis zu dem Feld eingeschaltet, dessen Nummer über den dimension -Parameter der Funktion mitgeteilt wird.


Musterdaten laden

Das zweite Beispiel Sample2_SOM_Net_Data zeigt eine Verbindung der folgenden Funktionalitätserweiterung – die CSOM_Net_Data-Klasse. Die Klasse wird als untergeordnetes Element von CSOM_Net_Base deklariert, daher hat sie alle Funktionen, die ein Kind hat, sowie eigene Funktionen. Die Klasse wird als eine Einführung in die Parser-Funktionalität für das Laden von Mustern erstellt. Von einem Parser bezogene Muster können für sowohl für das Laden von Trainingsmustern als auch Mustern für die Erkennung verwendet werden.

Ein Namen für die Datei mit Mustern ist durch den Parameter festgelegt:

input string DataFileName="SOM\\optim.csv";

Bitte denken Sie daran, den Namen der Datei mit Erweiterung anzugeben, d.h. es ist ein vollständiger Dateiname. Der Parser-Datei wird als Datei mit dem FILE_CSV-Flag geöffnet.

Dann werden die gleichen Funktionen wie im vorherigen Beispiel aufgerufen: Netzwerk laden, Laden der Datei, Datei Parsen, Mustererkennung in einer Schleife und Ausgabe.

Wir sollten hier ein Dateiformat mit Mustern erwägen auf das der Parser festgelegt ist.

Die erste Zeile der Datei sollte mit Namen der Titel Spalten gefüllt werden. Dies ist eine unabdingbare Voraussetzung. Wenn der Header der Datei nicht gefüllt ist, wird der Parser das oberste Sample abschneiden und als Spaltennamen verwenden.

Datei mit Muster

Spalten in der Datei dienen zum Speichern von Musterdaten der gleichen Tiefe. Folglich speichern Zeilen separate Muster. Das heißt, Vektoren liegen horizontal vor und die gleichen Felder aller Vektoren – vertikal.

Der Parser speichert Musterdaten in das integrierte Array M_patterns_sets_array und erkennt Header Felder, speichert diese in das M_som_titles-Array (deklariert in der abgeleiteten Klasse) und füllt auch das M_patterns_titles -Array mit Zeilennummern. Auf diese Weise gibt es keine Probleme mit der Suche nach einem gewünschten Muster durch eine Zeile in der Datei.


Netzwerktraining

Das dritte Beispiel Sample3_SOM_Net_Train ist das faszinierendste. Erstens ist darin CSOM_Net_Train verbunden, das ist die zweite Basisklasse und die Klasse für das Training von Kohonen-Maps. Zweitens: Es ist die letzte Klasse die für automatisiertes Training ohne Visualisierung geeignet ist, die nachfolgenden Klassen verbinden nur die grafische Shell. Also wird alles, was im Abschnitt "Theorie von Kohonen Maps" beschrieben wurde, in den ersten drei Klassen implementiert. Viertens hat die Klasse einen Vererbungs-Fork.

Für die nachfolgenden Klassen müssen die Funktionen zum Berechnen und Zeichnen eines Bmp-Bildes, das die Trainings-Stufen zeigt in der Netzwerk-Trainings-Funktion Train()aufgerufen werden. Aber da das dritte Beispiel keine Charts hat, sind die Bodies dieser Funktionen hier nicht erforderlich. Um diesen Konflikt zu lösen, werden die Render() und ShowBMP(bool back) Funktionen als virtuell deklariert, haben leere Bodies und der erforderliche Code wird im CSOM_Net_Img Kind definiert.

Nun gehen wir direkt zum Training. Die Parameter sollten vor dem Training an das Netzwerk gesendet werden. Für diesen Zweck gibt es eine Service-Funktion InitParameters (Int Xcells, Int Ycells, Int Iterationen) in der die Parameter übertragen werden an: Anzahl der Trainings-Iterationen – iterations und die Größe des Netzwerks geteilt in zwei Parameter — xcells, ycells (Größe von X bzw. Y).

Die Trainings-Schleife ist in der Train() Funktion untergebracht. Es ist erforderlich das Netzwerk zu initialisieren, bevor Sie die Trainings-Schleife aufrufen. Das impliziert die Initialisierung der Klasse von gleichmäßig verteilten Zahlen, die Definition der Array-Größen, die Berechnung von Maxima und Minima unter Verwendung der Musterspalten und die Initialisierung von Knoten mit zufälligen Daten aus dem Bereich der Menge.

Die eigentliche Training Iteration wurde speziell in eine separate Funktion TrainIterations (Int & P_iter) verwandelt, damit der Code besser verstanden werden kann und einfacheren Zugriff bei der Finalisierung. Diese Implementierung wurde so geschrieben, dass andere Programmierer die Essenz verstehen und eigene Änderungen vornehmen können, falls dies nötig ist. Die Funktion enthält den im Abschnitt "Theorie von Kohonen Maps" beschriebenen Algorithmus, daher gibt es keine Notwendigkeit, es nochmals zu erklären.

Generell zeigt das dritte Beispiel die Konsistenz der Netzwerk-Verbindung von der CSOM_Net_Train -Klasse: Laden einer Datei mit Traingings-Mustern, senden von Parametern, Aurfuf eines Trainings, Netzwerk in eine Datei zu speichern.

Bei der Beschreibung der Funktion des Lesens der Netzwerkdatei, wurde darüber hinaus erwähnt, dass die Funktionen zum Speichern und Lesen gleichzeitig betrachtet werden sollten, um das Format zu verstehen.

void CSOM_Net_Train::SaveNet(string file_name)
bool CSOM_Net_Base::DownloadNet(string file_name)

Binäre Darstellung der Somnet Datei

Der double-Typ herrscht unter den Netzwerkdaten. Daher wird das Netzwerk in ein eindimensionales Array des double-Typs gespeichert. Der Rest der Daten wird in diesem Typ konvertiert.

Zuerst wird der Header im Netzwerk gespeichert. Dies sind die fünf ersten double-Felder in denen notwendige Daten über das Netzwerk gespeichert werden.

  1. 6+dimension_node – Länge der Muster plus 6 (sechs zusätzliche Felder in den Knoten sind erforderlich für die Speicherung von Koordinaten).
  2. M_xcells – Anzahl der Knoten horizontal.
  3. M_ycells – Anzahl der Knoten vertikal.
  4. M_xsize — Bmp Größe horizontal.
  5. M_ysize — Bmp Größe vertikal.

Dann wird das Kopieren in das Knotennetzwerk ausgeführt. Zuerst 6 Bezüge über Knotenkoordinaten dann – Knoten Gewichte. Alle Daten werden auf diese Weise Knoten für Knoten kopiert.

Am Ende wird die Zeile mit der Titel-Enumeration, die binär ist in das double-Format übertragen und zum Netzwerk hinzugefügt.

Das ist also, was wir bekommen. Wir kennen die Mustergröße und die Anzahl der Knoten aus dem Header. Diese Daten können verwendet werden, um zu berechnen, wo Knotendaten beginnen und enden. Titel-Netzwerke werden vom Endpunkt der Knoten bis zum Ende der Datei gespeichert. Sie werden am Ende der Datei gesetzt, denn es ist unmöglich die Größe des erforderlichen Speichers vorherzusagen.


Grafische shell

Die vierte Beispiel Sample4_SOM_Net_Img zeigt die Verbindung einer grafischen Shell. Im vorherigen Artikel war es notwendig, eine Verbindung zur Grafikbibliothek cintbmp.mqh geschrieben von Dmitry Fedoseev herzustellen um sie aufzurufen. Aber ich musste das überarbeiten um alle WinAPI DLL-Aufrufe zu entfernen. Damit wird die Verwendung des Codes im Market ermöglicht. Die aktualisierte Datei enthält Informationen über den Autor, aber ich habe den Namen auf cintbmp2.mqh geändert.

Nur die Funktionen zum Speichern von Dateien in das Image Verzeichnis und zum Laden von Bmp-Dateien wurden im Code geändert. Dateien werden jetzt nur für das Speichern, aber nicht für die Anzeige aufgenommen. Für Anzeigezwecke werden sie sofort in Ressourcen geladen, das hilft den Aufruf von DLL-Bibliotheken zu vermeiden.

Die Reihenfolge der Aufruf von Funktionen ist ähnlich wie beim vorherigen Beispiel. Obwohl jetzt die grafische Shell verbunden ist, sind zusätzliche Parameter-Einstellungen für den Betrieb erforderlich. Daher wurde die Initialisierungsfunktion, die in der vorherigen Kindklasse deklariert wurde, neu gestartet, damit neue Parameter für die grafische Shell passen.

void   InitParameters(int iterations,int xcells,int ycells,
                       int bmpwidth,int bmpheight,
                       bool p_HexagonalCell,bool p_ShowBorders,bool p_ShowTitles,
                       int p_ColorScheme,int p_MaxPictures);

Parameter werden durch die Funktionsschnittstelle übergeben um global deklarierte Variablen im Klassencode zu verhindern. Andernfalls würde es den Anschluss an Nebenprojekte erschweren, in denen Namen von Variablen abweichen könnten.

Danach erfolgt der Aufruf der Trainings-Funktion Train() aus dem Muster der CSOM_Net_Train-Klasse. Aber da es Code zum Arbeiten mit Diagrammen in den Bodies der Funktionen Render() und ShowBMP(bool back) gibt, führt dies zur Anzeige des Trainingsprozesses für jede hundertste Iteration. Nach dem Beenden von Train(), werden diese Funktionen aufgerufen, um die letzten Änderungen anzuzeigen.

Abschluss des Trainings


Erweiterung der Funktionalität

Das fünfte Beispiel Sample5_SOM_Net_Player zeigt ein Beispiel zum Erweitern von Klassen. Dies ist notwendige Grundlage für das Netzwerk, aber es zeigt wie einfach ein bestehender Code überprüft werden kann. Zu diesem Zweck genügt es, die Klasse als Kind einer der Basisklassen zu deklarieren.

Warum sollte die Kind-Klasse geschriebe nwerden? Um alle Funktionen von allen Klassen von denen unsere Klasse erbt, durch den protected-Befehl zu verstecken. Beispielsweise wenn man sich als Kind der Klasse CSOM_Net_Img verbindet, bekommen wir Zugriff auf alle Funktionen und Daten, die als protected und public aller vorherigen Klassen deklariert wurden. Auf diese Weise kann das Programm konfiguriert werden wie Sie es wollen, je nachdem, was erreicht werden soll.

Die Erweiterung der CSOM_Net_ Player-Klasse ist daher ein Grafik-Panel zur Steuerung des Kohonen-Netzwerkes. Um das zu schreiben, habe ich die IncGUI_v3.mqh-Datei mit der Grafikbibliothek von Dmitry Fedoseev verbunden, nachdem sie leicht modifiziert wurde. Die Verbesserung betraf die Anzeige der Grafik Labels (nicht auf der Seite sondern über den Objekten) und Farbe der Labels. Ich habe keine Änderungen an der Originaldatei, stattdessen deklarierte ich die Vererbung Bibliotheksklassen.

Obwohl die Erstellung eines Grafikpanels der Großteil des Codes einnimmt, stellt dies keine Schwierigkeiten dar. Es ist eine regelmäßige Routinearbeit. Ich möchte die Koordinierung zwischen den Grafik-Panels mit dem neuronalen Kohonen-Netzwerk und die grafische Shell weiter erarbeiten.

Zunächst ist darauf hinzuweisen, dass der Prozess des Starts des Netzwerks zwei Teile umfasst. Der erste Teil führt ein Training durch und speichert das trainierte Netzwerk in der Binärdatei Somnet. Der zweite Teil lädt das Netzwerk aus der Datei und sucht nach geeigneten Knoten basierend auf geladenen Mustern. Beide Teile sind unabhängig voneinander, obwohl sie die gleichen Felder für die Anzeige von Daten verwenden: Eingabefeld mit einem Pfad zur Datei mit Mustern, Eingabefeld mit einem Pfad zur Datei mit dem neuronalen Netzwerk.

Die Modi sind jedoch wirklich unabhängig. Und Muster für das Training werden nicht obligatorisch aus der gleichen Datei wie die Muster für die Erkennung entnommen. Das gleiche gilt für das neuronale Netz. Sie können das Netzwerk in einer Datei trainieren, und wechseln dann den Modus in "operational" und laden andere Netzwerke für die Erkennung.

Wichtig: Umschalten der Modi setzt den Modus in einem Nullzustand zurück.

Modi sind also unabhängig. Aber wie wurde eine schnelle Reaktion des Programms für das Ändern des Status der Buttons erreicht? Das Problem ist, dass das Programm nicht die Schleife für das Training oder die Suche nach Mustern verwendet. Es ist anhand von Ereignissen angeordnet.

Wenn das Programm in den Trainings-Modus eintritt, initialisiert es, lädt Parameter, bereitet den Speicher vor und die erste Iteration und sendet sich selbst dann ein Event unter der Nummer 333. Der Eintritt in die Event-Handler wird durch Mausklick auf das Objekt, Beendigung der Objektbearbeitung und das Event 333 gefiltert.

Auf diese Weise tritt - wenn es keine Unterbrechung gegeben hat (wenn der Zustand der Schaltflächen "Start" und "Training" sich nicht geändert hat, und wir noch Zugang für den Trainings-Einstieg haben) - eine neue Trainingsiteration auf und eine neue Nachricht 333 wird gesendet. Und so weiter, bis das Netz trainiert ist und es die Schleife stoppt oder ein Benutzer den Button zum Stoppen des Trainings verwendet.

Das gleiche Schema der Unterbrechung wird im Modus der Mustersuche implementiert.

Ich habe versucht, die Panel-Oberfläche so klar wie möglich zu machen. Meist wird wiederholt es input-Variablen aus den vorherigen Mustern. Wir zeigen noch Werte einiger Schaltflächen und Eingabefelder:


Um das Panel zu starten ist folgendes erforderlich:


Fazit

Vor vierzig Jahren galten neuronale Netze als Spitzentechnik der Wissenschaft. Vor etwa zwanzig Jahren galt jemand, der mit neuronalen Netzes Algorithmen vertraut war als einzigartiger Spezialist. Nun scheint der Begriff "neuronales Netzwerk" niemanden mehr zu erschrecken. Algorithmen der Fuzzy-Logik, neuronale Netze sind jetzt fest in den Handel integriert und sind offenbar nicht so kompliziert. Ich hoffe, dass dieser Artikel Ihnen hilft, etwas Licht auf Kohonen Maps zu werfen und die Arbeit mit ihnen in Bewegung zu bringen.