Im ersten Teil der Reihe zu den künstlichen neuronalen Netzen haben wir uns die Grundlagen dieses Konzeptes – konkret: die Funktionsweise der künstlichen Neuronen – angeschaut; im zweiten Teil haben wir gesehen, wie mit Hilfe der künstlichen Neuronen ein real existierender von-Neumann-Rechner nachgebaut werden könnte. Im heutigen Artikel soll es nun darum gehen, wie künstliche Neuronen am besten vernetzt werden, um bestimmte Aufgaben, etwa zur Mustererkennung, geeignet lösen zu können.
Die Neuronen in einem echten Gehirn sind mit zahlreichen anderen Neuronen ihrer Umgebung verbunden, sind also relativ stark miteinander vernetzt. Bei der Verwendung künstlicher neuronaler Netze hat sich dagegen gezeigt, dass eine zu starke und “ungeordnete” Vernetzung der künstlichen Neuronen zur Lösung vieler Probleme nicht geeignet ist (über das “Warum” kann man nun diskutieren – ich würde ja darauf tippen, dass es unter anderem daran liegt, dass künstliche neuronale Netze über viel weniger Neuronen als echte Gehirne verfügen und dass die Abläufe eines echten Gehirns nur in Teilen nachgebildet werden). Daher ist es üblich, KNNs in einer eher strukturierten Form aufzubauen (wenngleich es auch Projekte gibt, die versuchen, sich dem Aufbau eines echten Gehirns etwas mehr anzunähern – mit viel mehr Neuronen dann natürlich).
Die übliche Form eines künstlichen neuronalen Netzes ist die Schichtenarchitektur; die künstlichen Neuronen werden dabei, wie es der Name sagt, in verschiedenen Schichten (engl. Layer) hintereinander angeordnet. Eine wichtige Schicht ist dabei die letzte, die sogenannte Ausgabeschicht (engl. output layer): die Ausgabesignale der Neuronen dieser Schicht werden “nach außen geleitet”, sie bilden gewissermaßen die Ausgabe des KNN (im echten Gehirn wären sie mit den Neuronen vergleichbar, welche Impulse auf vom Gehirn wegführende Nerven leiten). Die restlichen Schichten des KNN sind im Allgemeinen verborgen und werden daher als verdeckte Schichten (engl. hidden layer) bezeichnet. Die folgende Abbildung zeigt ein einfaches zweischichtiges Netz mit einer verdeckten Schicht und der Ausgabeschicht; zudem verfügt es über 3 mögliche Eingaben, die an die Neuronen der verdeckten Schicht angelegt werden:
Sehr gebräuchliche Netztypen sind die einschichtigen und die zweischichtigen Netze. Das widerspricht vielleicht etwas der Erwartung, dass neuronale Netze doch eigentlich etwas komplexes sind und daher möglichst viele Schichten haben sollten; in der Praxis hat sich aber für viele Aufgaben gezeigt, dass derart “einfach” aufgebaute Netze vollkommen genügen, um die gestellten Aufgaben zu lösen.
Sind die Neuronen einer Schicht alle nur mit denjenigen der darauffolgenden Schicht verbunden, spricht man von einem Feedforward-Netz. Ein derartiges Netz ist relativ einfach zu programmieren, hat jedoch einen “Nachteil” (Nachteil in Anführungszeichen, da er in der Praxis nicht immer von Bedeutung ist): Signale werden in derartigen Netzen immer “vorwärts” (daher der Name) von einer Schicht in die nächste gegeben; einmal “errechnete” Informationen werden also weitergegeben und sind dann verloren.
In der Praxis ist das nicht immer von Bedeutung, da genügend Probleme auch ohne die Speicherung von Informationen gelöst werden können. Ab und zu ist es aber doch nötig, dem Netz eine Art von Gedächtnis zu geben. Das Vorgehen hierfür ist ähnlich zu dem, welches ich bereits im letzten Artikel bei der Speicherung von Bits mit Hilfe von Neuronen erläutert habe: es werden zusätzlich zu den vorwärtsgerichteten auch rückwärtsgerichtete Kanten, also Kanten zurück auf ein Neuron selber, auf ein Neuron der gleichen Schicht oder sogar auf Neuronen vorheriger Schichten, eingeführt. Derartige Netze werden folgerichtig als rekurrente Netze bezeichnet und stellen eine Möglichkeit dar, Informationen zu speichern (sie haben also eine Art Gedächtnis), aber auch, zeitlich ausgedehnte Eingaben zu verarbeiten und darin Muster zu erkennen. Obiges Netz erweitert um alle drei Arten von rückwärtsgerichteten Kanten könnte also so aussehen:
Besitzt jedes Neuron eine Verbindung zu jedem anderen Neuron, so spricht man übrigens von einem vollständig vernetzten oder verbundenem KNN.
Welche Art von Netz (mit wie vielen Schichten) und Vernetzung (Feedforward, rekurrent oder vollständig vernetzt) letztendlich für die Lösung eines Problems verwendet werden kann, hängt in der Regel vom Problem selber ab. Mittlerweile gibt es für viele Problemarten best practise-Erfahrungen (ich suche immer noch nach einer vernünftigen deutschen Übersetzung dafür – Vorschläge?), die angewendet werden können. Leider trifft das natürlich nicht auf sämtliche Probleme zu – die Suche nach dem richtigen Netz ist also bereits ein kleines Problem für sich und kann etwa durch ein trial-and-error-Verfahren oder aber auch durch evolutionäre Algorithmen (oder andere Optimierungsalgorithmen) gelöst werden.
Neben der passenden Netzstruktur muss übrigens auch dafür gesorgt werden, dass die möglichen Eingaben auf eine Art und Weise codiert werden, dass sie möglichst günstig in das Netz gefüttert werden können. Oftmals ist diese Aufgabe nicht trivial, da die Codierung der Daten erheblichen Einfluss auf die Effektivität des Netzes hat. Leider können automatisierte Algorithmen dies kaum übernehmen, so dass es in der Regel dem Entwickler eines Netzes überlassen bleibt, eine geeignete Codierung zu finden. Um es noch schwieriger zu machen, muss natürlich auch die Ausgabe des Netzes entsprechend interpretiert werden. Hier gibt es zwei Möglichkeiten: entweder wird versucht, die Ausgaben so zu interpretieren, dass sie einen Sinn ergeben (nichts anderes tun wir im täglichen Leben mit den teils haarsträubenden verbalen Auswürfen diverser Personen des öffentlichen Interesses [die Bissigkeit musste jetzt einmal sein – bitte nicht zu ernst nehmen]), oder das Netz wird dazu gebracht, seine Ausgaben so zu formulieren, wie es der Programmierer erwartet.
Die Findung der richtigen Netzstruktur und die korrekte Codierung der Eingaben reichen allerdings noch nicht aus, um ein KNN auch erfolgreich zur Problemlösung zu verwenden; mindestens ebenso wichtig ist es natürlich, das Netz entsprechend zu konfigurieren, sprich, die Gewichte der Verbindungen zwischen den Neuronen sowie die Schwellwerte und die Aktivierungsfunktionen der einzelnen Neuronen korrekt einzustellen. Hier durch raten, probieren oder “errechnen” auf Anhieb die richtige Konfiguration zu finden, ist sehr schwierig und wird umso schwerer, je größer das Netz ist – es wird also auch hierfür ein Algorithmus benötigt, welcher die richtigen Einstellungen bestimmt. Evolutionäre Algorithmen können auch hier helfen, öfter jedoch wird sich wieder einmal am echten Gehirn orientiert und ein anderes Verfahren verwendet: das Lernen. Ziel dabei ist es, dem KNN durch verschiedene Methoden ein bestimmtes Verhalten anzuerziehen, ganz so, wie Lebewesen im Laufe ihrer Entwicklung neue Dinge lernen können; es soll also dazu gebracht werden, die Ausgaben zu generieren, die erwartet werden. Doch dazu beim nächsten mal ein wenig mehr (und als kleine Vorwarnung: es könnte etwas mathematischer werden).
Kommentare (9)