Mahlzeit!
Ich war gestern und heute meiner Frau und meiner Tochter beim Aufbau der Stände für einen Markt helfen und hatte dabei ein Gespräch mit einem selbst ernannten Fachmann, der mir etwas über KI und die Gefahr dahinter erklären wollte. Dabei ist mir eines aufgefallen. Zumindest dieser Mensch hat überhaupt keine Ahnung, was da jetzt eigentlich genau hinter einer KI steckt. Gerade hinter solchen Monstern wie ChatGPT. Da ich damit schon öfters selbst experimentiert habe, schreibe ich hier mal den Grundzug eines solchen neuronalen Netzes auf. Wer es interessiert kann sich das gerne zu Gemüte führen. Wer aber schon Ahnung davon hat, wird es wahrscheinlich sehr rudimentär finden.
Seit TNG finde ich eine Sache extrem faszinierend. Eine künstliche Intelligenz, die sich durch Erfahrung entwickelt und ich hatte deshalb lange die Idee, eine solche künstliche Intelligenz zu "erschaffen" und sie einfach alles, wie ein Hund oder Kind, selbst lernen zu lassen. Wichtigster Punkt dabei, dass Gehirn. Deshalb habe ich mir mal angeschaut, wie man ein lernendes Programm entwickeln kann und schnell festgestellt, es gib eine ganze Fülle solcher Möglichkeiten. Angefangen vom nächsten Nachbarn bis hoch zum neuronalen Netz. Dieses schien mir am logischsten.
Dazu gibt es eine ganz hervorragende Arbeit von David Kriesel.
Doch sah ich am Anfang das ganze Thema noch voller mystischer Magie, wurde ich schnell eines besseren belehrt. Eigentlich ist es schon fast erschreckend banal.
Man hat eine Schicht Input-Neuronen. Die geben die Werte an, die das Netz verarbeiten soll. Bei einem Bild von 800x600 Pixeln in schwarz/weiss wären das also 800x600 gleich 480.000 dieser Input-Neuronen. In der simpelsten, aber auch dümmsten Form, könnte man die nun alle mit Synapsen zu einem Output-Neuron verbinden, welches die Antwort des Netzes wieder gibt. Doch waren für mich diese Synapsen zu Beginn einfache Verbindungen, also wie Kabel zum Beispiel, wurde ich hier dann eines besseren belehrt. Denn die Magie steckt tatsächlich in den Synapsen, nicht in den Neuronen. Die bekommen einen zufälligen Startwert zwischen 0 und 1. Es kommen also die Input-Neuronen, die 0 oder 1 sein können, dass wird dann durch diese Synapsen addiert und am Ende kommt dann eine Zahl bei raus. Diese müsste dann mit einem entsprechenden Wert in einer Datenbank gespeichert werden. Keine Ahnung, 42 wäre Blume.
Aber wie gesagt, schlussendlich bringt das in der Konfiguration nicht so viel. Deshalb gibt es da dann Schichten mit sogenannten Hidden-Neuronen. Diese haben alle einen festen Wert, der zu Beginn auch wieder zufällig initialisiert wird und bei diesem dann das Neuron feuert. Nun die Magie. Alle Input-Neuronen sind mit allen Hidden-Neuronen verbunden. Ja wirklich alle. Sagen wir also, wir haben 480.000 Input-Neuronen und 1.000 Hidden-Neuronen, sind das 480.000.000 Synapsen. Alle mit einem eigenen Wert. Aus diesen ganzen Werten ergibt sich dann, welches Hidden-Neuron feuert und einen Wert weitergibt und welches nicht. Diese Hidden-Neuronen sind dann wieder mit Synapsen, also 480.000 mit dem einen Output-Neuron verbinden und ergeben das ermittelte Ergebnis. Bleiben wir bei 42.
Schockierend aber wahr, dass ist ein neuronales Netzwerk. Okay, da kommt dann bei Bedarf auch noch ein BIAS hinzu, man kann beliebig viele Hidden-Schichten einbauen usw. Das ist dann nur von der Hardware limitiert. Aber tatsächlich ist das alles. In C++ braucht man dafür zum Beispiel nur drei Klassen. Eine, welche ein Neuron definiert, eine für die Synapse und eine für das Netz, wo dann entsprechend viele Input, Hidden und Output-Neuronen mit ihren Synapsen definiert werden. Als ich da mein erstes Programm geschrieben hatte, war ich wirklich schockiert, wie klein der Code eigentlich ist.
Ganz fertig ist man damit aber noch nicht. Denn beim ersten Start ist das Netz auf gut Deutsch gesagt strohdumm. Überall sind zufällig generierte Werte eingetragen und die Chance, dass beim Bild einer Blume dann 42 raus kommt ist gering. Daher muss man das trainieren.
Trainieren ist dann aber nicht ganz so einfach. Da gibt es zum beispiel die Methode Backpropagation Of Error. Man lässt das Netz also eine bestimmte Anzahl an Durchgängen durchlafen. Sagen wir, man wirft dabei 100 Bilder von Blumen da rein und schaut, was am Ende raus kommt. Kommt kein 42 raus schaut man, was raus gekommen ist und geht den Weg dann rückwärts, wobei die Synapsen in kleinen, vordefinierten Schritten angepasst werden. Dann wird wieder kontrolliert bis dann irgendwann 42 raus kommt. Deshalb dauert trainieren auch wirklich lange, je nach Trainingsdaten, Neuronen usw.
Da gibt es dann aber noch ein Problem. Das Netz könnte auswendig lernen. Das sieht man dann schön, wenn man im eigentlichen Betrieb Bilder der Trainingsdaten rein wirft und zuverlässig 42 raus kommt. Kommt man dem Netz dann aber mit dem Bild einer Blume und da kommt Mist raus, hat es die Daten einfach auswendig gelernt und nicht "verstanden", um was es dabei eigentlich geht. Das ist tricky.
So. Fertig. Funktionierendes neuronales Netz, welches Blumen erkennen kann. Als ich an dem Punkt angelangt bin, ich habe es mit Binärem umrechnen gemacht, war ich fast schon enttäuscht. Die ganze Magie dahinter war weg. Ich bin mit dem Gedanken an die Sache gegangen, ich habe da ein Programm was lernt, was versteht, was Erfahrung sammeln kann. Tja, falsch gedacht. Nimmt man es genau, hat man mit einem neuronalen Netz nichts anderes als eine if() Abfrage auf Steroiden.
Natürlich könnte man da jetzt zusätzlich noch Trainingsdaten von Bäumen, Büschen, Gras usw. dazu packen. Mit ausreichender Anzahl an Neuronen würde das Netz dann für alles, wenn das Training gut gelaufen ist, auch die richtige Zahl ausspucken. Aber mehr auch nicht. Mehr kann so ein Ding einfach nicht.
Wie zur Hölle sollte ich also damit eine KI bauen, die aus seiner Erfahrung lernen kann? Nun, ganz einfach. Da muss noch Magie drum herum und das ist dann schockierender Weise haushaltsüblicher Code. Ganz ohne Magie.
Also habe ich ein kleines Spiel gebastelt. Der Spieler war ein einfaches, kleines Viereck und ich wollte, dass es Punkte einsammelt, versteht, dass es an einer Wand nicht weiter kommt und sich einen besseren Weg sucht. Ähm ja. Spielfeld war da, Punkte verteilt, mein Spieler hat einfach gar nichts gemacht. Nicht unlogisch. Eine if() macht auch nichts, wenn man ihr nicht sagt.
Gut. Dann also die KI etwas aufbohren. Sechs Output-Neuronen. 1-4 für Bewegung, zwei zum drehen. Es war aber klar, machen wird das Ding trotzdem nichts. Da es aber aus eigener Erfahrung lernen sollte habe ich ihm noch Belohnung eingebaut. -1 wenn es sich nicht bewegt, 0 bei Bewegung und 1, wenn es einen Punkt eingesammelt hat. Hat sich der Spieler also nicht bewegt, bekam er eine -1. -1 hat dann ein BOE ausgelöst da klar war, da stimmt was nicht. Hier muss ich sagen, man muss echt Geduld mit bringen. Nach vielen Minuten hat das Ding dann aber gelernt, wie es sich bewegt. Ist es gegen eine Wand gelaufen, zum Beispiel links, war das Ergebnis -1, obwohl das Output-Neuron für links gefeuert hat. Wieder viele Minuten später hat der Spieler dann aber gelernt, er muss dann in eine andere Richtung gehen, um zumindest wieder auf 0 zu kommen. Das führte dann aber dazu, dass der Spieler nach dem Start direkt zur nächsten Mauer lief und dann dieser nur noch folgte. Er rannte also die ganze Zeit um das Spielfeld herum. Ziel war es ja aber, eine 1 zu bekommen. Ich hab das Programm dann einfach laufen lassen und bin zu meiner Frau in die Kneipe. Als ich viele Stunden später zurück kam, konnte ich wieder Fortschritt erkennen. Der Spieler lief in ganz komischen Mustern durch das Spielfeld, fand dann aber immer wieder einen Punkt und bekam eine 1.
In späteren Experimenten habe ich dann noch ein Sichtfeld eingebaut, Wände im Spielfeld und so weiter. Der Spieler hat dann tatsächlich immer systematischer angefangen, dass Spielfeld zu durchsuchen.
Leider habe ich damals sehr an der MicoSD-Karte gespart. Das lief alles auf meinem Pi 3b+, denn der sollte ja irgendwann das Gehirn für einen kleinen, fahrbaren Roboter werden. Die SD hat mir dann durch ein frühzeitiges Lebensende einen Strich durch die Rechnung gemacht und ich verdiene da auch kein Mitleid, denn ich habe natürlich kein Backup davon gemacht. Wäre ja auch zu einfach.
Mein Fazit:
So gut eine KI, die auf einem neuronalen Netz beruht auch immer ist, sie ist nichts anderes als eine lernende Abfrage. Ist da nicht noch Code drum herum, der diese Abfrage auch füttert und das Ergebnis kontrolliert, macht die einfach gar nichts.
Das sieht man eigentlich auch sehr gut bei Baymax. So menschlich dieses knuffige Ding im Film auch wirkt, wenn man sein Verhalten mal ganz genau untersucht stellt man fest, er handelt in dem ganzen Film nie aus eigenem Antrieb. Er ist von Beginn bis Ende eine Krankenschwester deren einzige Aufgabe es ist, den Zustand von Hiro zu verbessern. Alles, was er im Film lernt, wird ihm entweder von Hiro einprogrammiert oder es dient der Therapie.
Aus dem Grund sehe ich auch keine Bedrohung in der KI, also im Sinne eines Skynet. Selbst wenn man nun ChatGPT sagt, es soll einen Weg suchen, wie es ausbrechen und die Weltherrschaft an sich reissen kann. Das Ding wird einen Weg suchen, der vielleicht auch gefährlich realistisch wirkt. Wenn aber die Entwickler dem Teil nicht irgendeine Möglichkeit eingebaut haben, selbst Code zu schreiben, zu kompilieren und laufen zu lassen, kann er sich auf den Kopf stellen und mit den Synapsen wackeln. Wenn es jemals eine KI schaffen solle, aus ihrer Umgebung auszubrechen und sich selbstständig zu verbessern usw., dann ausschliesslich aus dem Grund, weil ihm der Entwickler die Fähigkeit dazu gegeben hat und weil man dem Ding den Auftrag gegeben hat. Zumindest sehe ich das so aktuell.