Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] GI = Guckis Intelligenz
Rumgucker
09.11.2019, 07:46
Hallo KI-Freaks,
vielen Dank Euch für die vielen KNN- und KI-Anregungen hier in diesem Bereich. Seit gestern Abend fasziniert mich das Thema sehr.
Zur Zeit beobachte ich mich selbst sehr intensiv. Da gibt es erstmal Euer Forum. Eine mir unbekannte Umwelt mit mir noch unbekannten Regeln, Protagonisten und Themen. Ich hab noch nie im Leben einen Roboter entwickelt oder was mit KI gemacht.
In dieser unbekannten Umwelt will ich mich nun zurechtfinden. Wie geh ich mit meiner "GI" (Guckis Intelligenz) vor?
--------
Erstmal hab ich meinen vorverdrahteten Programmschalter auf "hallo-ich-bin-da"-Modus geschaltet. Erstmal meine Desktop-Halde durchsucht, was ich davon mit wenigen Handgriffen auf "Roboter" anpassen kann. Aha... die 3D-Feldmessung. Die kann man doch gut nehmen. Dann nur noch schnell rumgeguckt, in welchem Bereich ich das am besten abwerfe und dann mal das Echo abwarten.
Zu diesem Zeitpunkt ist mir noch keine einzige neue Synapse gewachsen und ich habe auch nichts Neues trainiert. Ich hab nur ein bewährtes Standardprogramm abgespult. Jedes Waschmaschinen-Schrittschaltwerk kann das ebenso. Trotzdem hab ich den Eindruck von Intelligenz erweckt.
Ich lerne: ein GI-System verfügt über ein Standardprogramm, mit dem es seine Umweltabfrage beginnt.
--------
Es dauerte nicht lange und ich bekam eine Antwort. Dass meine hochgeladene PDF ja virenverseucht sein könnte und was ich zu tun habe, um das Gegenteil zu beweisen.
Mein GI-System erhielt sozusagen eine Strafe. Irgendwas war schief gelaufen. Was in anderen Foren-Umwelten stets problemlos klappte, war hier nicht gut. Leider hab ich im Gegensatz zu KI-Systemen nun keine Möglichkeit, in stundenlangen "Trainingsläufen" zu bestrafungsfreien Ergebnissen zu gelangen.
So funktioniert die Realität nicht. Mich fauchte hier ein Tiger an und ich musste schnell handeln. Sollte ich mich wegdrehen und die Angst mit einem lauten Lied wegsingen? Soll ich mich hinwerfen und ihm die Kehle zeigen? Oder soll ich zurückfauchen?
Ich stand also rätselnd vor meinem Programmschalter. Sollte ich auf "Igno", "Unterwerfung" oder "Zurückfauchen" schalten?
Ich begann, die Sache zu bewerten. Erstmal bin ich kein Typ, der sich unterwirft. Ich bin selbst Tiger im Herzen. Igno vertagt nur. Von daher standen die Zeichen auf Zurückfauchen. Hinzu kam noch, dass der Tiger die von mir erwarteten Höflichkeitsformeln (wie z.B. "Hallo, neuer User") nicht rezitierte. Die Entscheidung war gefallen. Programmschalter auf Zurückfauchen.
Ich lerne: mein GI-System kann bewerten. Dazu hat es ein Bild von sich selbst und Erwartungshaltungen. Auch dieses war alles schon vorhanden, bevor ich mich bei Euch registrierte.
--------
Danach kamen nettere Beiträge und ich schaltete auf "Schnurren" und speicherte die PDF auch noch zusätzlich online, wie es ursprünglich gefordert wurde.
Neue Synapsen waren immer noch nicht gewachsen. Das passiert in meinem Alter auch nicht mehr so oft.
Mein GI-System hat aber in dem kleinen 3D-Sensor-Thread viel über die neue Umwelt erfahren. PDFs sind da nicht so beliebt. Und ich lernte ein paar erste Nicknames.
--------
Ich hab mich gleich an deren Fersen geheftet und rumgelesen, was die so interessiert und was die so können.
Mein GI-System war jetzt also in der Lage. mit den Nicknames meine neue Umwelt gezielt abzufragen.
Ich las etwas von stundenlangen Trainings der KNN-Systeme auf "leistungsschwachen" Controllern, die vor noch nicht vielen Jahren problemlos ganze Rechenzentren in Betrieb gehalten hätten. Ich stöberte in vielfach geschachtelten Schleifen mit floating-Multiplikationen und bewunderte übergreifende "Bewerter", die irgendwann nach hunderttausenden von Iterationen schließlich einen ausreichenden Lernerfolg feststellten. Oder eben nie.
Und ich wunderte mich sehr, wie ganz anders meine eigene GI zu funktionieren scheint und frage mich nun natürlich, ob das ganze mit der KI nicht auch ein wenig geschickter gehen könnte.
Da ist eine neue Umwelt mit Tigern. Und nun muss sich der mit Intelligenz ausgestattete Roboter in Windeseile einfügen und seine Überlebensnische finden. Sonst wird er gefressen und aus die Maus.
Dieses Überlebensprogramm hat nichts mit stundenlangem KI-Training zu tun. Das ist ein ganz anderer Mechanismus. Der passt sogar in ein einzelliges Wesen. Der Mechanismus würde auch in einen Tiny85 passen, der sich noch nebenher mit der Abfrage von Sensoren und der Steuerung der Aktoren befassen muss.
Lieg ich so falsch?
Viele Grüße
Wolfgang
Obwohl einige Aspekte deiner Beschreibung noch etwas vage, unstrukturiert und suggestiv formuliert sind, erinnern mich manche Ideen im Prinzip an Q-Learning.
Du müsstest die Problemstellung noch etwas konkretisieren und objektivieren, aber such mal das Web nach diesem Stichwort ab!
Rumgucker
09.11.2019, 09:53
Hallo HaWe,
ich bin ja noch absoluter Beginner in dem Thema. Das hat Vor- und Nachteile.
Ein Nachteil ist, dass man die vorgeschriebene Denkweise und Nomenklatur noch nicht kennt.
Und ein Vorteil ist, dass man die vorgeschriebene Denkweise und Nomenklatur noch nicht kennt.
;)
Viele Grüße
Wolfgang
ja, man könnte das, worin DU dich z.Zt befindest, auch mit "Lernprozess" beschreiben. ;)
Du kannst jetzt versuchen, das Rad neu zu erfinden - oder auf bekannte Lösungsstrategien zu setzen und diese für dein Problem anzupassen und weiterzuentwickeln 8)
Rumgucker
09.11.2019, 11:18
Hallo HaWe,
ja.. ich lerne. Daher bitte ich um einige Tage Welpenschutz.
Ich persönlich seh keine Chance, die heutigen Standard-NN in irgendeiner Form auf Tinys zu implementieren.
(Anm: "Tiny" ist ein Synonym für einen wirklich leistungsschwachen Controller.)
Ein Tiny hat aber m.E. viel mehr Intelligenz als eine Amöbe. Auch er sollte also mindestens ähnlich geschickt sein Futter finden, Hindernissen ausweichen und flüchten können, wenn ihm was komisch vorkommt.
Keiner verlangt, dass er mich aus allen Blickwinkeln als sein Herrchen erkennt. Das ist Luxus.
Aber unverzichtbar sind vitale Grundfunktionen. Revier kennenlernen. Ladestation finden. Sich an Umweltänderungen anpassen können. Fluchtverhalten. (Fortpflanzung lassen wir erstmal außen vor).
Für eine Neuerfindung des Rades müsste man erstmal ein Rad haben. Ich hab im Netz kein derartiges Vital-Paket für autonome Tiny-Roboter gefunden. Kennst Du eins?
Viele Grüße
Wolfgang
ja, mach ma'!
Aber ich arbeite grundsätzlich nicht mit Tinys oder anderen mickrigen AVRs ;).
PS,
Unterschätze aber auch bitte Amöben nicht: sie sind Einzeller (keine Bakterien) mit einer hohen Vielzahl von Organellen, Sensoren und Aktoren, die m.E. eine weitaus komplexere Sensorik und Verhaltensmuster als Outputs besitzen als es ein AVR simulieren könnte.
Rumgucker
09.11.2019, 12:22
Hallo HaWe,
Unterschätze aber auch bitte Amöben nicht
Ja... der Rassist ist wieder mal mit mir durchgegangen... :(
-------
ja, mach ma'!
Ja. Ich leg los. Das wird hier mein Labortagebuch-Thread, wenn das für die Admins und Mods ok ist.
Ich kann zwar extrem Beitrags-agil sein. Aber ich will versuchen, Eure Lesebelastung in Grenzen zu halten.
WENN alles so gelingt, wie ich mir das zur Zeit vorstelle und wie sich das mit zunehmender Erkenntnis auch noch schärfer herausbilden wird, dann schreib ich zum Schluss ne PDF, in der noch mal alles gebündelt drin steht.
Wer also keine Lust hat, hier täglich meine (hoffentlich) wachsende Erkenntnis mitzulesen, der verpasst nichts.
Viele Grüße
Wolfgang
Ja. Ich leg los. Das wird hier mein Labortagebuch-Thread, wenn das für die Admins und Mods ok ist.
Falls Du es noch nicht gesehen hast:
Du hast dafür einen eigenen Blog. Kannst den auch verwenden.
MfG
Rumgucker
09.11.2019, 13:01
Hallo Moppi,
Danke für den Hinweis. Das ist je genial. Das wird immer besser hier!
Viele Grüße
Wolfgang
Rumgucker
10.11.2019, 07:09
Moin Forum,
der Blog ist mir zu weit ab vom Schuss. Den lesen zu wenige. Ich bleib erstmal hier im Thread. Soooo umfangreich ist meine Erkenntnis noch nicht. Eher simpel und naheliegend.
Viele Grüße
Wolfgang
************************
Generic Intelligence
GI vs. KI
------------------------------------------------------------
Vorwort
Ein wichtiges Gebiet der AI bzw. KI (artificial intelligence bwz. künstlichen Intelligenz) befasst sich mit der Erstellung künstlicher neuronaler Netze (KNN).
Das Vorgehen bei den KNN ist simpel. Es wird die Funktionalität eines einzigen Neurons programmiert. Und es wird eine große Anzahl von Speicherstrukturen angelegt, die der Anzahl von Nervenzellen entspricht.
Nun wird in endlosen Schleifen das Neuron mit Daten aus der Umwelt oder den internen Speicherstrukturen gefüttert und seine Rechenergebnisse abgespeichert. Ob Daten aus der Umwelt oder internen Speichern verrechnet werden, entscheidet die jeweilige Neuronenschicht, die gerade berechnet wird.
Viele KNN bestehen aus drei Schichten. Einer äußeren Schicht, die mit den Umweltsensoren direkt gekoppelt ist. Einer versteckten inneren Schicht. Und einer Ausgabeschicht, die Aktoren ansteuert.
Die Emulation eines Neurons ist eine wahre Wissenschaft. Die Eingangssignale können gewichtet, summmiert und mit unlinearen Funktionen multipliziert werden. Typischerweise entsteht so ein einziges Ausgangssignal, was alle Eingänge miteinander verrechnet hat.
Formell ist ein KNN eine Matrix-Berechnung. Besonders schnelle Multiplikationen und Additionen sind eine Domäne von Grafikprozessoren, weswegen diese Bauteile gerne in der KI verwendet werden.
Die die natürlichen Intelligenz beherrschenden Merkmale der Vernetzung und Parallelität werden durch mathematische Korrelation und enorme Rechengeschwindigkeiten ersetzt.
------------------------------------------------------------
Motivation
Statt immer größere Rechenleistungen einzusetzen, will ich das andere Ende der Skala beleuchten.
Kleine Controller (z.B. Tiny85 etc.) verfügen nicht über die Ressourcen zur Abarbeitung der geschilderten Dampframmen-KI.
Diese Dampframmen-KI erscheint mir sowieso eher lustlos. Die Entwickler wollen eine informelle Blackbox nutzen, deren Innereien sie eigentlich gar nicht interessiert. Die sie vielleicht nicht mal verstehen. So eine Art KI-Betriebssystem, um das man sich nicht kümmern muss und was es schon richtig machen wird. Konsumer-Mentalität auf höchstem Level.
Es soll stattdessen eine zur Controller-Klasse passende künstliche Intelligenz entwickelt werden, die wegen ihrer universellen Skalierbarkeit als GI bezeichnet wird.
------------------------------------------------------------
Modell
Die GI eines Kleincontrollers besteht aus drei pyramidenförmigen Schichten.
34461
In der obersten Schicht, dem „RAM“ wird z.B. Bildverstehen auf höchster Abstraktion betrieben. Hier wird auch geschlafen, um das RAM für einen neuen Tag freizuschaufeln. Die Speicherzeit ist kurz.
In der mittleren „EEPROM“-Schicht wird Gerlerntes gespeichert. Also z.B. Laufen, Sprechen und Bilderkennung. Hier wachsen Verknüpfungen und werden Anpassungen an Umwelten gespeichert. Die Speicherzeit ist lang.
Die unterste „Flash“-Schicht wird von mir programmiert. Hier befinden sich Reflexe, Instinkte, Triebe und die Treiber für Sensoren und Aktoren. Das Stammhin sozusagen mit ewiger Speicherzeit.
Die Aufgabe des Gebildes ist das Zurechtfinden in einer unbekannten Umwelt.
Vom Prinzip her ist ein GI-System schon mit der Flash-Schicht alleine - in Grenzen -lebensfähig. Es schreit und zappelt zum Beispiel, wenn die Bordnetzspannung zu weit sinkt und es Hunger hat.
Interessanter wird’s aber, wenn die EEPROM-Schicht sich durch Interaktion mit der Flash-Schicht und der daran angekoppelten Umwelt zu organisieren beginnt. Zur Erlangung von Mobilität muss die EEPROM-Schicht rumprobieren. Sie muss selbsttätig versuchen, ein Ablaufprogramm zum „Laufen“ zu entwickeln. Um einen Schritt zu machen, mussen die Unterprogramme und Treiber der Flash-Schicht in einer gewissen Chronologie angesteuert werden. Ein gutes GI-System lernt und optimiert Fortbewegung ganz von alleine.
Sobald die EEPROM-Schicht ausgebildet ist. Kann sich das System fortbewegen, weglaufen, Futter suchen und hat sich an seine Umwelt adaptiert. Man könnte jetzt zufrieden sein und sich am Rumwuseln des Roboters erfreuen.
Spannend wird’s aber, wenn die oberste Schicht freigeschaltet wird. Hier treffen mit höchstem Abstraktionslevel Ereignisse ein. Hier findet „Kombinieren“ und „Denken“ statt. Hier wird im kybernetischen Sinne gespielt und im regelungstechnischen Sinne optimiert. Hier kommt es auch nicht mehr auf die Geschwindigkeit an.
---------------------
Realisierung
Die GI unterstützt eine generische Vorgehensweise. Zuerst werden die Eigenschaften der Flash-Schicht kodiert. Es entsteht eine Art Betriebssystem des Robotors. Dieses Subsystem kann Befehle mit uniformierten Messages empfangen und Events an die höheren Schichten asynchron senden.
Die EEPROM-Schicht nutzt das Flash-Betriebssystem und dessen Rückmeldungen. Es wird zum Beispiel mit einem leckeren Happen gelockt und muss nun irgendwie seine Betriebsystem-Befehle in geeigneter Weise chronologisch kaskadieren, dass eine Bewegung hin zum Futterhappen stattfindet.
Die Arbeitsweise der EEPROM-Schicht erinnert mehr an einen Homöostaten als an ein intelligentes Wesen. Es optimiert sich selbst und passt sich selbst auch an die Umwelt an.
Auch die EEPROM-Schicht kann Messages empfangen und Events senden. Allerdings schon auf sehr hohem Abstraktionsleveln. Ein typischer Befehl an die EEPROM-Schicht wäre: „gehe drei Schritte die Treppe runter“ oder „fahre mit dem Rad immer geradeaus“.
Die übergeordnete RAM-Schicht ist noch nicht konkreter durchdacht worden. Die kann generisch draufgesatteltwerden, wenn die anderen Schichten laufen.
der Blog ist mir zu weit ab vom Schuss. Den lesen zu wenige.
Vielleicht kannst Du Werbeanzeigen schalten, frag mal den Frank ;)
Du kannst Deinen Blog selbst moderieren. Das kannst Du hier nicht! Falls Kommentare auftauchen, die Dein Projekt und den gesamten Thread schlecht machen, was die Meinungsfreiheit nicht verletzen muss und deshalb wohl nicht entfernt wird, hast Du keine Möglichkeiten. Außerdem wird das hier sehr schnell unübersichtlich, weil alles an Information, Kommentaren und Streitereien durcheinander geht.
Ob das dann hier richtig ist, inhaltlich, ist auch noch die Frage.
Vielleicht besser in: Vorstellung-Bilder-Ideen-zu-geplanten-eigenen-Projekten (https://www.roboternetz.de/community/forums/47-Vorstellung-Bilder-Ideen-zu-geplanten-eigenen-Projekten-Bots)
Aber ich bin kein Moderator hier...
:)
MfG
Rumgucker
10.11.2019, 08:29
Moin Moppi,
etwas Meinungsunterschiede brauch ich einfach, damit ich optimal funktioniere. Im Idealfall kommt bei mir das Gefühl hoch, dass ich es dem Meinungsgegner beweisen will. Meinungsvielfalt findet man nicht im stillen Kämmerlein eines Blogs. Da muss man seine Nase schon in den Gegenwind halten. Auch wenns mal weh tut.
Hinterher umarmt man sich ganz einfach wieder und hat sich wieder lieb.
Viele Grüße
Wolfgang
Rumgucker
11.11.2019, 08:06
Hallo,
um mich nicht mit Aktoren und Sensoren abzulenken, wird mein Controller (*) zwei digitale Ausgangsleitungen erhalten, die die Bewegungssteuerung darstellen. Und vier digitale Eingangsleitungen, die Sensorsignale darstellen.
Die Programmierung der Flash-Ebene ist also trivial und das EEPROM-Lernen kann begonnen werden.
Mit diesen zwei Aktorleitungen und den vier Sensorleitungen wird mein System nun auf eine ihm unbekannte Umwelt einwirken. Diese Umwelt wird in einer Blackbox versteckt, also einem zweiten Controller. Innerhalb der Umwelt befindet sich irgendwo das Futter.
Mein GI-Controller muss nun erstmal die Fortbewegung lernen. Er hat keinerlei Informationen darüber, wie und in welcher Reihenfolge er an seinen Aktorleitungen wackeln muss, um voran zu gelangen. Im Falle eines Zuckens verändert er seine Position in der Umwelt und die Umwelt beantwortet diese Positionsänderung mit einer Änderung der vier Sensor-Leitungen. Je mehr Sensorleitungen aktiv sind, desto näher ist das GI-System dem Futter gekommen.
Die Spuren des Lernens kann ich im EEPROM auslesen und analysieren.
So ist der heutige Plan.
Viele Grüße
Wolfgang
(*) Ich nehme einen PIC 12F629, weil der nun wirklich über jeden Verdacht der KI-Eignung erhaben ist.
Hallo Wolfgang,
ich verstehe, was Du machen willst. Aber so ein wenig müssen wir aufräumen, damit es nicht zu falschen Schlüssen kommt. Ich weiß auch, dass ich bei so was ohne blaue Flecken nicht davon komme.
KI ist ein Oberbegriff. Darunter gehören ganz viele Dinge, der Datenverarbeitung, die in ihrer Gesamtheit also diese "Intelligenz" ausmachen. Ein Teilgebiet sind Neuronale Netze. Auch ein PIC kann daher für eine KI zu gebrauchen sein.
Heißt aber auch: eine KI benötigt nicht zwangsläufig ein Neuronales Netz.
Soll eine Anmerkung sein, keine Belehrung oder so!
MfG
- - - Aktualisiert - - -
Das, was Du beschrieben hast, habe ich mir auch schon mal durchdacht. Nicht zuletzt deswegen habe ich mir dann ein Projekt gesucht, mit dem ich mich der Sache nähern kann.
Dabei herausgekommen ist seinerzeit eine Steuerung für Rollos. Falls es Dich interessiert, in meinem Blog habe ich dazu geschrieben.
Ich habe dafür wenige Sensoren und einen Aktor, nämlich einen Motor, der sich links oder rechts herum drehen kann. Mein Ziel ist es gewesen, dass ich nicht die genaue Funktion, wann
der Motor - bezogen auf die Sensorwerte - in welche Richtung dreht und wie weit, vorgeben habe. Das könnte man auch per fester Vorgaben im Programmcode steuern.
Statt dessen habe ich als Eingangsparameter Sensorwerte, Zeit und die letzte Position des Motors (genauer Rollos). Die Steuerung funktioniert dann per Anlernen. Mit der letzten Position bauen die Bewegungen aufeinander auf.
Anhand dieser Geschichte kann ich einige Sachen besser verstehen oder auch vergleichen, ich sehe Stärken und Schwächen dieser speziellen Umsetzung, im praktischen Umgang und Verhalten des
Programmcodes. Ich wollte das erweitern, dass die Software mithilfe nur einer oder zwei Bestätigungstasten (falsch / richtig), das richtige Verhalten selbst erlernt. Das habe ich aber bleiben lassen, weil es vor allem auch einen praktischen Zweck erfüllen und also 100% funktionieren soll (läuft bei mir zuhause schon paar Monate, zufriedenstellend).
MfG
Rumgucker
11.11.2019, 12:48
Hallo Moppi,
danke. Ich bin noch Lehrling. Da wird noch vieles bei mir durcheinander gehen.
Ich hab ne abartige Lernstrategie. Erstmal alles Unbekannte auf Teufel komm raus so vereinfachen, dass selbst ich das begreife. Und dann aus den Trümmern was Neues erschaffen.
Ja.. wär nett, wenn Du mein Gestammele etwas in Form bringst, damit die Informatik-Freaks nicht gleich schreiend weglaufen.... :cheesy:
Ich bin zum Beispiel nicht der Meinung, dass die KNN-Freaks die Natur richtig herum abbilden.
Mein Hirn ist nicht matrizengesteuert. Ich arbeite eher reizgesteuert. Wenn mein Augennerv feuert, dann weiß er, mit welchen Synapsen er verbunden ist. Genau so viele Messages müssen geschickt werden.
Wenn man matrizenbezogen herangeht, dann muss eine Zellschicht alle einzelnen Neuronen der vorgeschalteten Schicht abfragen. Immer und immer wieder. Dem Mathematiker ist das Banane. Aber dem Informatiker geht dadurch zu viel Rechenkapazität nutzlos verloren.
Das Wort "feuern" ist mir auch sehr wichtig. Im Hirn wird ja gar nicht mit float gerechnet. Eher mit ganz wenigen Bit. Angeregte Nerven feuern einfach häufiger. Wodurch man auch die Chronologie gleich am Wickel hat, denn sie sehe ich bei klassischen KNN irgendwie nicht richtig implementiert. Kann ein klassisches 3-Schichten-NN die Ablaufsteuerung einer Waschmaschine lernen? Ich hab da große Zweifel. Gestenerkennung ja. Waschmaschinensteuerung nein.
Bei der Entwicklung der "GI" sind also einige grundlegende Weichen zu stellen. Mangels Vorwissen komme ich dabei möglicherweise gleich zu ganz anderen Basisentscheidungen und "sonderbaren" Nomenklaturen.
Nehmt mich noch nicht allzu ernst. Ich befinde mich gerade in Euren Trainingsphasen. Lasst uns nur hoffen, dass ich keine 3 Milliarden Iterationen benötige, um zu belastbaren Erkenntnissen zu gelangen.
Viele Grüße
Wolfgang
-----------
/Edit bzgl. Moppis Nachtrag: ich versuche natürlich, prozedurale Konstrukte zu vermeiden. "GI" heißt nicht, dass ich KNN ablehne. Ich will sie lediglich so strukturieren, dass sie besser zu Winz-Controllern passen.
Hallo Wolfgang,
prozedurale Konstrukte
ich verstehe, was Du meinst. Aber: wirst Du ohne sie auskommen können?
Alles kann bis auf ein gewisses Maß vereinfacht werden. Darüber hinaus aber eigentlich nicht mehr.
Du wirst drauf kommen, was nötig ist.
Wirklich Ahnung von der Materie habe ich auch nicht, wenngleich ich mich mit dem Thema intelligente Verarbeitung beschäftige. Aber ich bin da auch anders rangegangen, mehr oder weniger so, wie Du.
Vielleicht schaust Du mal zu "Lebewesen" die sehr gut erforscht sind: Mikroben. Vielleicht kann man versuchen solche Lebewesen nachzubauen.
Viel Erfolg aber vor allem Spaß! :)
MfG
Rumgucker
11.11.2019, 14:23
Hallo Moppi,
es macht im Moment wirklich sehr viel Spaß. Das Thema. Aber auch Euer tiefenentspannter Umgang mit meiner beginnenden KNN-Blasphemie. Optimale Kreativitätsmischung für mich und hoffentlich auch für das Thema.
Viele Grüße
Wolfgang
Rumgucker
12.11.2019, 14:06
Hallo,
mein erstes System ist fertig. Absolut stabil und ohne geringste Neigung zur Oszillation. Eigentlich neigt es zu gar nichts.
Es scheint gleich in eine höhere Bewusstseinsebene aufgestiegen zu sein, in der die Futtersuche offensichtlich keine Bedeutung mehr hat. Irgendwas Transzendentes frei von Vergangenheit und Zukunft. Eine große Gelassenheit und Friedfertigkeit.
Erinnert mich an die Lernwilligkeit eines Marmorblocks.
Das muss aber kein Fehler sein. Es kann sich auch um ein Interpretationsproblem handeln... vielleicht war der PIC mit meiner Frage nach der besten Strategie zur Erlangung der Weltherrschaft auch schlicht überfordert.
Viele Grüße
Wolfgang
*lol*
Wolfgang,
............
vielleicht liegt's auch einfach daran, dass Du Dir zu wenige Gedanken gemacht hast, ob das funktionieren kann. - Ich weiß das aber nicht so genau ... hmmmm!
Aber warte!
Ähmmm ...
Du hast doch da, wenn Du das schon vermutest .....
Du hast doch da diese Messeinrich ..... ähmmm ... Sensor, wo verändernde Feldstärken ... na ja, ........ hmm, also Du weißt schon! - Ich habe ja schon geschrieben, dass das für so Ghostbusters interessant sein kann, eben um eventuelle Existenzen aufzuspüren.
Aber Du hättest solche Meßeinrichtung VOR Inbetriebnahme Deiner neuen Intelligenz .... oder .... Leben (wesen) ... aufstellen sollen! Hinterher - also jetzt - zu messen und auf die Suche nach ihm zu gehen, wird sinnlos sein, da Du eben vorher keine Messwerte in der Umgebung erfasst hast.
Kann passieren, aber ... Kopf hoch!
;)
MfG
- - - Aktualisiert - - -
So hat sich die Frage, wofür Du das einsetzen kannst, schon zum Teil beantwortet.
Rumgucker
12.11.2019, 15:38
Hallo Moppi,
man kann an der Sinnhaftigkeit meines solid-state-3D-E-Feldsensors zweifeln. Man kann auch an meinen Erfolgsaussichten bzgl. meiner GI-Versuche zweifeln. Man kann sogar an mir zweifeln.
Alles geschenkt...
Aber an dem gestern Abend im Mini-Fu-Thread erfundenen Zugfeder-Schnürsenkel-Drehmomentmessgerät kann man nicht mehr zweifeln! Das ist Oberklasse. Fast nobelpreisverdächtig. Leider muss ich den Ruhm mit Manfred teilen. Wenn der mich nicht zur Messung getreten hätte, hätte ich es nie versucht.
Ich geb zu, dass der PIC ein harter Gegner für mich ist. Aber er wird sich über kurz oder lang meinen intellektuellen Rammstößen ergeben müssen.
Viele Grüße
Wolfgang
Ich bin zum Beispiel nicht der Meinung, dass die KNN-Freaks die Natur richtig herum abbilden.
Mein Hirn ist nicht matrizengesteuert. Ich arbeite eher reizgesteuert. Wenn mein Augennerv feuert, dann weiß er, mit welchen Synapsen er verbunden ist. Genau so viele Messages müssen geschickt werden.
Wenn man matrizenbezogen herangeht, dann muss eine Zellschicht alle einzelnen Neuronen der vorgeschalteten Schicht abfragen. Immer und immer wieder. Dem Mathematiker ist das Banane. Aber dem Informatiker geht dadurch zu viel Rechenkapazität nutzlos verloren.
Das Wort "feuern" ist mir auch sehr wichtig. Im Hirn wird ja gar nicht mit float gerechnet. Eher mit ganz wenigen Bit. Angeregte Nerven feuern einfach häufiger. Wodurch man auch die Chronologie gleich am Wickel hat, denn sie sehe ich bei klassischen KNN irgendwie nicht richtig implementiert. Kann ein klassisches 3-Schichten-NN die Ablaufsteuerung einer Waschmaschine lernen? Ich hab da große Zweifel. Gestenerkennung ja. Waschmaschinensteuerung nein.
da bst du wschl nicht so ganz auf dem Stand der Nerven- und Hirnforschung, und auch nicht so ganz auf dem Stand der KI-Forschung. :D
Aber nur zu!
Rumgucker
12.11.2019, 18:02
Hallo HaWe,
ich ahne, was Dir wohl eher auf der Zunge lag.....
Jedes dahergelaufene Greenhorn, das die KI nicht mal ansatzweise überblickt, versucht aus Unwissen heraus, das Rad neu zu erfinden. Aber schon nach kurzer Zeit verschwinden sie wieder reihenweise in der Versenkung des Nicht-Verstehens und des Nicht-Könnens. Bzw. benutzen dann doch die fertigen Tools - ohne sie jedoch wirklich zu begreifen. Derartige Typen würden mich an Deiner Stelle genauso nerven.
Anfänglich sieht das alles nach dem gleichen Grünzeug aus und raschelt auf gleiche Weise im Wind. Aber erst nach der Ernte trennt man Spreu von Weizen. Und erst dann stellt sich raus, ob ich Spreu oder Weizen bin.
Deswegen lass mich mal noch etwas reifen, bevor wir die Ernte prüfen können.
Viele Grüße
Wolfgang
da hast du meine Zielrichtung falsch verstanden:
Deine obigen Aussagen über Nerven, Augen, Gehirn, ihren Aufbau, ihre Funktionen und Funktionsprinzipien sind einfach (lange) nicht auf dem heutigen Stand, und gleiches gilt für die grundsätzliche Lernfähigkeit von KNN. Die Vorraussetzungen (Bedingungen), auf Grund derer du bestimmte Schlüsse ziehst, stimmen also einfach nicht.
Dennoch schließt das nicht aus, dass du trotz falscher Vorraussetzungen auch funktionierende Programme schreiben kannst: Sie funktionieren dann aber nicht WEGEN, sondern TROTZ einer falschen Wissensbasis.
Aber ich schrieb ja: Nur zu! Schreib deine Programme, und wenn du dann etwas entwickelt hast, was wirklich funktioniert, dann zeige es uns!
Das von mir aber schon erwähnte Q-Learning ist ebenfalls lauffähig auf sehr anspruchslosen Prozessoren, und es würde mich überhaupt nicht überraschen, wenn dann das von dir "from the scratch" entwickelte Programm genau solchen Q-learning-Algorithmen entspricht - es wäre ein um so größerer Erfolg für dich, wenn du das selber entwickelt hast ohne abzuschreiben.
Also, nochmal:
Nur zu!
Rumgucker
13.11.2019, 20:31
Hallo,
so langsam wächst und gedeiht das System:
CC5X Version 3.5, Copyright (c) B Knudsen Data, Norway 1992-2014
--> FREE edition, 8-16 bit int, 24 bit float, 32k code, reduced optim.
Warning : Main file extension should be '.c'
gi.cp:
Chip = 12F629
RAM: 00h : -------- -------- -------- --------
RAM: 20h : =====7.. ........ ........ ........
RAM: 40h : ....**** ******** ******** ********
RAM usage: 36 bytes (5 local), 28 bytes free
Optimizing - removed 1 instructions (-0 %)
File 'gi.pic'
File 'gi.lst'
File 'gi.hex'
Total of 135 code words (13 %)
Der 12F629 hat 1 kWorte Flash, wovon ich zur Zeit 13% benutze. Bis aufs "Verlernen", "Reflexe" und "Schlafen" (= Zellen-Erregungen wieder normalisieren) ist alles schon programmiert.
Der PIC hat 64 Byte RAM, von denen ich 36 nutze. Damit verwalte ich 30 Neuronen ("Zellen"). Die 128 Byte des EEPROMs werden für Dendriten benutzt, die ich "Links" nenne.
Die Anzahl der Zellen wird vorgegeben. Die Links organisieren sich vollständig alleine. Sie bilden Korrelations-Cluster. Man kann beim GI-System auch nicht von Zell-"Schichten", starren Matrizen oder Deep Learning sprechen. Jede Zelle kann potentiell mit jeder Zelle verlinkt sein. Links können verstärkt werden. Das entspricht der klassischen Gewichtung oder auch vollständig verkümmern. Propagation ist in alle Richtungen möglich. Das System kann sich selbst organisieren, optimieren und anpassen, muss also nicht einem Training unterzogen werden. Kann aber.
Enthalten ist auch schon das "Gehirnknistern" (Stochastik), "Hunger", vier Sensoren und zwei Aktoren.
Neu ist auch die Art des Feuerns. Bei mir wird gefeuert, wenn Deltas auftreten. Dadurch und durch die dynamische Anzahl von Links hab ich auch bei starken System-Erregungen nur eine relativ geringe Anzahl von Operationen abzuleisten.
Das flutscht schon alles ganz gut. Morgen mach ich das Gegenstück dazu: den Umwelt-PIC.
Es wird, es wird.... ich tippe auf ersten laufenden Prototypen am WE.
Viele Grüße
Wolfgang
Rumgucker
15.11.2019, 21:48
Hallo,
es lebt...
34478
Zu sehen sind EEPROM-Bytes, die die 3-Byte-"Links" (Dentriten) beinhalten. Die führenden Nullen sind der Galep-Anzeige geschuldet. Und die letzten beiden Bytes werden wegen der 3-Byte-boundaries nicht verwendet.
Spannend ist, dass sich ein Dendrit gebildet hat, der die Sinneszelle "x00" mit einem Neuron "x0D" verbunden hat und noch "00" Nutzen brachte. Dass der Dendrit sich am Ende des Speichers gebildet hat, hat den Grund, dass der PIC das ganze EEPROM komplett durchsucht hatte und keinen mit der Sinneszelle verbundenen Dendriten finden konnte.
Nach einem Durchlauf hab ich das System angehalten, damit ich das EEPROM analysieren kann. Die Zellen kann man nicht sehen, weil die im RAM versteckt sind.
Aber mir zeigen die drei Byte an, dass alles komplett erfolgreich durchgelaufen ist. Jetzt nehm ich alle Bremsen raus und lass das System sich komplett vernetzen.
Ich rechne mit Sekundenbruchteilen.
Viele Grüße
Wolfgang
----------------------------------
Tatsache: 256-mal alles komplett durchgerechnet. Gesamtlaufzeit dafür vilelleicht 1/4 Sekunde.
34479
Nun ist die Sinneszelle 0x00 (nur die war aktiv) mit acht Links an andere Zellen x19, x11 x09 x07 x17 x0F x15 x0D angeschlossen. Alle Verbindungen konnten ihre Nützlichkeit noch nicht beweisen, weil es nur einen einzigen Lichtblitz gab.
Sobald weitere Lichtblitze erscheinen, werden die zur Zeit noch verkümmerten Links wachsen. Es können sich auch gänzlich neue Links anlegen. Das Dingens sollte sich selbst belohnen können und deep-learning machen. Schon deshalb, weil die Zellen nicht in festen Schichten, sondern sich in dynamischen Clustern organisieren.
Das alles ohne jegliche Matrizen oder Multiplikationen.
Die Weichware sieht auch schon richtig hübsch aus. Zwar spezieller PIC-C-Slang. Aber kurz und knackig. Mit Debug-Code beleg ich zur Zeit 29% des 1 k Flashs.
So richtig große Dinge hab ich wohl nicht vergessen. Da kommt fast nichts mehr dazu. Sensor- und Aktoren-Treiber sind auch schon drin. Es fehlt nur noch die Logik der beiden Zellen für "Hunger" und "Gehirnknistern". Aber das ist beides trivial.
GI-Sourcenvorstellung am WE könnte was werden.
Viele Grüße
Wolfgang
- - - Aktualisiert - - -
Jepp,
Motoren laufen. Sieht schrecklich intelligent aus. Ein zuckeln und ruckeln. Er hat ja noch kein Feedback. Die Umwelt erscheint ihm völlig statisch. Singularität.
Aber das System hat sich in Clustern organisiert. Der Nutzen in den Links läuft hoch (ich hab nen Endanschlag vergessen). Außerdem wird er noch nicht verrechnet, nur geschriebnen. Zellen feuren synchron
34480
Ein Beispiel: die beiden Motorzellen heißen x1C und x1D.
x1D hat sich zweimal direkt mit dem einzigen aktiven Sensor verkoppelt. Offensichtlich war die Motor-Zelle gerade nicht feuerbereit, als der Sensor wieder einen Lichtblitz erzeugte. Welcher der beiden Links sich schließlich durchsetzen kann, ist noch nicht klar.
x1C hatte am Anfang auch geruckelt. Wurde dann aber immer schwächer und seine Dendriten verkümmerten. Zur Zeit ist er taub. Mit nur einer Sinneszelle wird sich daran auch erst dann was ändern können, wenn die Stochastik hilt (Gehirnknistern) oder wenn x1D nicht alle Ereignisse vom Sensor mitbekommt.
Die restlichen Zellen haben sich untereinander vernetzt. Worüber die wohl nachdenken? Vielleicht weden sich die die nächste Zeit mit dem tauben Motor verkoppeln?
Es hat was. Streckenweise läuft es mir etwas kalt den Rücken runter. Ich könnte ein Programm gebrauchen, was mir in einem grafischen 3D-Netz die Zellen als Kugeln und die Links als Verbindungen darstellt. Feuerbereite Kugeln müssten größer sein. Und nützliche Links dicker sein.
Da das ganze aber atmet (lebt) und schon in den nächsten Millisekunden ganz neue Verbindungen schlagen kann, müsste man sowas eigentlich kontinierlich darstellen.
Ich glaub, ich hab was ganz Spannendes erdacht. Die Interpretation ist so komplex, dass man geneigt ist, dem Ding zuzutrauen, dass es schon eine Lösung finden wird. Früher oder später. Aber in jedem Fall in wenigen Millisekunden.
Soll ich die Source mal zeigen. Noch ohne Abfabgen des Nutzen-Überlaufs und ohne Logik für Hunger und Knistern.
Ich machs mal einfach:
#include "allpic.h"
#pragma config = 0b000110000100 // hex-datei: fuses des 12F629
#define EE_ROM // eeprom nutzen
#include "pic_mem.h"
#include "timeloop.h" // timer-routinen
#define IN_0 0 // GPIO-Eingänge
#define IN_1 1 //
#define IN_2 2 //
#define IN_3 3 //
#define OUT_0 4 // GPIO-Ausgänge
#define OUT_1 5 //
//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
uns8 zellen[30]; // zellen im RAM anlegen
#define FIRE_REQ 7 // fire_req bit in der zelle
#define FIRE_LIMIT 10 // fire_limit
#define SENS_0 0 // spezialzellen definieren
#define SENS_1 1 // sensoren
#define SENS_2 2
#define SENS_3 3
#define TIMER 4 // Timer-Zelle
#define HUNGER 5 // Hunger-Zelle
#define FIRST_NEURON 6 // davor nur read-only-zellen
#define AKT_0 (sizeof(zellen) - 2)
#define AKT_1 (sizeof(zellen) - 1)
//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK -1
#define MAX_LINKS (128 / sizeof(struct _link))// viele links im EEPROM
struct _link { // struktur eines EEPROM-links
uns8 src; // leerer link: src_zelle == NO_LINK
uns8 dst; // verbindet source- mit dest-zelle
uns8 use; // nützlichkeit dieses links
};
// LINK-Zugriffe
#define LINK_RD(a,m) ee_read((a) + offsetof(struct _link,m))
#define LINK_WR(a,m,v) ee_write((a) + offsetof(struct _link,m),v)
static uns8 rand_link; // randomize link
static void gi_denke(void) // die genesis
{
uns8 zell_ind = 0, link, free, buf;
BOOL hit;
do { // suche feuernde zellen
rand_link++; // randomize link
FSR = zellen + zell_ind; // pointer auf zelle
/**** sensoren, aktoren und triebe sind besondere zellen *****/
if(zell_ind <= SENS_3) { // sensoren abfragen
buf = _BV(zell_ind); // bit-maske entwickeln
if(GPIO & buf) { if(!(INDF.0)) INDF = FIRE_LIMIT + _BV(FIRE_REQ);}
else INDF.0 = 0 // FIRE_REQ bearbeiten
} // nun die aktoren
else if(zell_ind == AKT_0) GPIO.OUT_0 = INDF.FIRE_REQ;
else if(zell_ind == AKT_1) GPIO.OUT_1 = INDF.FIRE_REQ;
if(INDF.FIRE_REQ == FALSE) continue;// zelle möchte nicht feuern
/***** wenn zelle feuern will, verfolge die links *************/
INDF.FIRE_REQ = FALSE; // zelle möchte feuern
free = NO_LINK; link = 0; hit = FALSE;
do { // alle links durchsuchen
rand_link++; // randomize link
buf = LINK_RD(link,src); // linkbyte lesen
if(buf == NO_LINK) free = link;// leeren link merken
else if(buf == zell_ind) {// link gefunden
FSR = zellen + LINK_RD(link,dst);// pointer auf dst-zelle lesen
if((++INDF == FIRE_LIMIT)&&(!(INDF.FIRE_REQ))) {// will dst feuern?
INDF.FIRE_REQ = TRUE; // feuer_req schon mal vormerken
buf = LINK_RD(link,use);// zwei zellen feuern synchron
LINK_WR(link,use,++buf);// dadurch wird der link nuetzlicher
hit = TRUE; // zumindest ein nützlicher link
}
}
link += sizeof(struct _link);// nächsten link adressieren
} while(link < MAX_LINKS * sizeof(struct _link));
/** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
if((!hit)&&(free != NO_LINK)) {
LINK_WR(free,src,zell_ind);// link neu erzeugen
buf = rand_link % sizeof(zellen); // randomize verlinken, aber eingrenzen
if(buf < FIRST_NEURON) buf += FIRST_NEURON; // keine read-only-zellen
if(buf == zell_ind) buf++; // zellen nicht direkt rückkoppeln
LINK_WR(free,dst,buf);
LINK_WR(free,use,0); // ob der link nützlich wird, weiß keiner
}
} while(++zell_ind < sizeof(zellen)); // nächste zelle
}
#define DELETE 0
#define REDUCE 1
#define SLEEP 2
static void gi_links(uns8 steuer) // links abschwächen
{
uns8 link = 0, buf;
do { // alle links durchsuchen
if(LINK_RD(link,src) != NO_LINK) { // gelöschte ignorieren
if(steuer == DELETE) buf = 0;
else {
buf = LINK_RD(link,use); // nuetzlichkeit lesen
if(buf) LINK_WR(link,use,--buf);// langsam verlernen
}
if(!buf) LINK_WR(link,src,NO_LINK);// link ganz löschen
}
link += sizeof(struct _link); // nächster link
} while(link < MAX_LINKS * sizeof(struct _link));
if(steuer == DELETE) rand_link = 0;
}
static void gi_zellen(uns8 steuer)// zell-erregungen abschwächen
{
uns8 zell_ind = 0;
do { // suche zellen
FSR = zellen + zell_ind; // zellerregung lesen
if(steuer == DELETE) INDF = 0;
if(INDF) INDF--;
if((steuer == SLEEP)&&(INDF > FIRE_LIMIT)) INDF = FIRE_LIMIT - 1;
} while(++zell_ind < sizeof(zellen));// nächste zelle
}
void main(void)
{
RP0 = 1; // erstmal alle Spezialregister...
#asm
DW /*CALL*/ 0x2000 + /*ADRESSE*/ 0x03FF // oscal abholen
#endasm
OSCCAL = W; // und Oszillatorkalibrierung speichern
OPTION = 0; // global weak-pullup ein (je 20kOhm)
WPU = _BV(IN_0) | _BV(IN_1) | _BV(IN_2) /*| _BV(IN_3)*/;
TRISIO = _BV(IN_0) | _BV(IN_1) | _BV(IN_2) | _BV(IN_3);// eingänge
RP0 = 0; // normale register und ram
CMCON = 0x07; // komparator aus
timeloop_init(); // timer initialisieren
gi_links(DELETE); // alle links löschen
gi_zellen(DELETE); // zellerregungen löschen
uns8 loop = 0;
FOREVER {
gi_denke();
if(!++loop) {
gi_links(REDUCE); // links langsam verlernen
gi_zellen(SLEEP); // schlafen
}
else if(!(loop & 0x1F)) // alle 32 durchläufe
gi_zellen(REDUCE); // zellerregungen vermindern
}
}
/* ENDE */
Wie gesagt: noch Kleinkram dran zu machen.
Viele Grüße
Wolfgang
Herzlichen Glückwunsch zu deinen Fortschritten. Es wäre schön, wenn Du irgendwann eine gaphische Darstellung machst, bei dem man den Systemaufbau auf einen Blick erkennen kann.
Die kleinen Roboter machen sehr schnell den Eindruck, dass sie "belebt" sind.
Vielleicht braucht dein Roboter ja auch einen Partnerroboter, damit er sich nicht zu einsam fühlt.
Vor etwa 10 Jahren hatte ich hier im Forum mal einiges mit den Asuros gemacht.
Hier zeigt sich schön, wie sie in Wechselwirkung treten:
https://www.youtube.com/watch?v=oscbdxMhX_4
Komisch: Das eingebetete Video wird nur bei mir im Editor Fenster angezeigt.
Ich hänge es mal noch in Rohform an:
https://www.youtube.com/watch?v=oscbdxMhX_4
@Rumgucker:
worin besteht jetzt die Intelligenz oder Lernfähigkeit?
Welche Reiz-Reaktionsmuster kann es lernen, sich merken oder neu/umlernen,
wer oder was trainiert es zu den gewünschten Lernzielen,
und wie erkennt es, dass es sein/e Lernziel/e erreicht hat?
Und nochmals zum Aufbau deines Netzes:
wieviele Eingänge / welche möglichen Eingangszustände hat das Netz,
und wieviele Ausgänge / welche möglichen Ausgangszustände hat das Netz?
Rumgucker
16.11.2019, 09:49
Hallo stochri,
danke! Da waren noch ein paar kleine Bugs drin bzgl. der Nutzenverarbeitung. Ohne die wirds lustig. Weiterhin wird nur ein Photosensor konstant beleuchtet. Zuerst versucht er im Zickzack zu fahren. Und dann schließlich arbeiten beide Motoren konstant geradeaus.
Würde ich als Mensch auch nicht anders machen. Zuerst mal durch eigene Bewegung versuchen, der statischen Lampe auszuweichen. Und dann beruhigt sein und mit Vollgas auf das offensichtlich entfernte Objekt zufahren.
Es gruselt einen, wie intelligent ein paar wenige Byte erscheinen können. Hätte ich nie gedacht. Aber schon nach wenigen Durchläufen ist eine Analyse des Denk-Systems praktisch nicht mehr möglich. Man bewundert nur noch das Verhalten. Das Hirn gaukelt einem vor, dass da was Vernunftbegabtes umherirrt. Verblüffender Effekt.
------------
Hallo Helmut,
im Prinzip funktioniert auch mein Netz wie Perceptrons mit Matritzen. Meine Dendritengewichtung versteckt sich im Wort "Nutzen" eines "Links". "Links" wachsen, wenn sie zwei Zellen (das können Sinneszellen, Neuronen, Aktuatoren oder Hunger und Knistern sein) verbinden, die synchron feuern.
Jede Zelle sucht sich also über die Links "Freunde", die ähnlich wie sie selbst ticken. Es kann kreuz und quer durchs ganze Nervensystem verlinkt werden. Es gibt keine Schichten mehr. Dabei bilden sich zwangsweise Cluster aus. In diesen Clustern versteckt sich das Lernen.
Lernen kann das System ohne Training, Agenten etc. einfach dadurch, dass die Zellen Freunde suchen. Die Umwelt wird in diesen Optimierungsvorgang mit eingeschlossen. Es werden sich also die derart verlinkten Cluster bevorzugt ausbilden, die zu einem Erfolg führen. Also die Clustersysteme, die besonders effektiv und schnell eine Situation verarbeiten können.
Wenn zwei kompetitive Links an einem Zelleingang hängen, so wird der verkümmern, der asynchron zum Zellenfeuern arbeitet und der erstarken, der mit der Zelle synchron ist. Das System optimiert den zeitlichen Durchsatz.
Zur Zeit hab ich
4 binäre Eingäne (spezialisierte Sinneszellen z.B. für Fototransistoren etc.)
2 interne Statuszellen (Hunger und Gehirnknistern - immer noch nicht programmiert aber schon enthalten)
2 binäre Ausgänge für zwei Motoren (feedbackfähig, also normale Neuronen)
22 Neuronen
Die Anzahl aller Zellen beträgt also 30 und diese können mit bis zu 42 Links verbunden werden. Es sollten deutlich mehr Links als Zellen zur Verfügung stehen.
Ich mach heute noch ein Update der 20 Kernzeilen. Der ganze Rest befasst sich mit Speicherverwaltung. Aber die ganze "GI" steckt in 20 'C'-Zeilen. Daran werde ich den Kern haarklein erklären.
Viele Grüße
Wolfgang
der interne Aufbau ist zur Charakterisierung der Zustände gar nicht so wichtig, wichtig sind zunächst nur inputs und outputs.
Da du 4 inputs hast, sind 16 Eingangszustände möglich,
und da du 2 outputs hast, sind 4 Ausgangszustände möglich.
Damit muss das Netz in der Lage sein, beliebige Zustände zu lernen, z.B. (mindestens)
für alle (paarweisen) Eingänge a, b ∈ {In1...In4}: output[n]= a ODER b ( für alle n ∈ {1,2} )
für alle (paarweisen) Eingänge a, b ∈ {In1...In4}: output[n]= a UND b ( für alle n ∈ {1,2} )
für alle (einzelnen) Eingänge c ∈ {In1...In4}: output[n]= (NICHT c) ( für alle n ∈ {1,2} )
Wie erreichst du, dass das Netz diese Basiszustände wahlweise gezielt lernen kann?
Und wie erkennt es, dass es sein/e Lernziel/e erreicht hat?
Rumgucker
16.11.2019, 10:17
Hallo Helmut,
der Lernerfolg einer Mustererkennung oder eines Dekoders ist ein anderer als der Lernerfolg eines autonomen Roboters. Mein System freut sich, wenn es genug Futter findet.
Die Frage muss also lauten: "wie weiß Dein System, ob es genug Futter gefunden hat?"
Dieser Hunger-Mechanismus ist schon vorbereitet. Es gibt eine Hunger-Zelle (0x05). Die noch zu programmierende Logik wird dem GI-System damit ab und an mal "Hunger" signalisieren.
Dann kurvt es rum. Dabei erfährt es eine Bestrafung zum Beispiel dadurch, dass sich die Umwelt nicht mehr bewegt. Dann hat es sich festgefahren. Und muss andere Wege finden und diese Wege optimieren.
Und irgendwann gibt es eine besondere Lampenkombination an seinen Eingängen (meinetwegen alle vier Eingänge auf high), die dazu führen, dass der Hunger verschwindet.
Mir fehlt immer noch der Umwelt-Chip, also das Gegenstück zur GI. Damit fang ich erst an, wenn ich keine gröberen Fehler im GI-System mehr erkennen kann.
Dann kommt auch die Hunger-Geschichte mit dazu.
Viele Grüße
Wolfgang
---------------
Nachtrag. ein anderer "Umwelt"-Chip könnte die GI alllerdings dazu bringen, dass er auch als Dekoder funktioniert. Jedesmal, wenn er die richtige Ausgangskombination als Funktion der Eingänge "würfelt", wird die GI belohnt und die "Links" manifestieren sich.
Das funktioniert an sich wie bei Dir. Nur Du machst alles mit der gleichen Software: lehren und lernen. Und ich verwende einen Lehrer (= "Umweltchip"), den man nach Benutzung einfach abkoppeln kann. Das spart knappen Flash-Speicher im Schüler.
Viele Grüße
Wolfgang
du formalisierst deinen Zustandsraum nicht exakt genug.
Du musst in der Lage sein, deine möglichen Reaktionen als Funktionen deiner Outputs zu beschreiben und sie abhängig zu machen vom möglichen Zustand der aktuellen Inputs.
Solange du das nicht machen kannst, macht das System "irgend etwas nebulöses", aber es ist weder bewiesen, dass es irgend etwas gezielt lernen kann noch dass es verschiedene Zustände gezielt lernen kann.
Auch "Herumfahren" ist ja ein Zustand, der durch spezifische Output-Muster definiert werden kann, und er tritt ein (wird WAHR), wenn das eine oder andere Input-Muster auftritt.
Die Sache mit dem Hunger ist ja ein weiterer Zustand, zusätzlich zu den 4 Sensor-Eingängen; lassen wir den Hunger also erst mal raus.
Zeige erst mal die oben beschriebenen Grund-Fähigkeiten:
für alle (paarweisen) Eingänge a, b ∈ {In1...In4}: output[n]= a ODER b ( für alle n ∈ {1,2} )
für alle (paarweisen) Eingänge a, b ∈ {In1...In4}: output[n]= a UND b ( für alle n ∈ {1,2} )
für alle (einzelnen) Eingänge c ∈ {In1...In4}: output[n]= (NICHT c) ( für alle n ∈ {1,2} )
Nimmst du den Hunger als Input mit rein, gibt es 32 Input-Zustände, für die zu zeigen wäre:
für alle (paarweisen) Eingänge a, b ∈ {In1...In5}: output[n]= a ODER b ( für alle n ∈ {1,2} )
für alle (paarweisen) Eingänge a, b ∈ {In1...In5}: output[n]= a UND b ( für alle n ∈ {1,2} )
für alle (einzelnen) Eingänge c ∈ {In1...In5}: output[n]= (NICHT c) ( für alle n ∈ {1,2} )
Rumgucker
16.11.2019, 10:47
Hallo Helmut,
ich hatte im letzten Beitrag noch den Nachtrag geschrieben, dass ich auch dekodieren können muss, wenn der "Umwelt"-Chip entsprechend ausgestaltet ist.
Dein Vorschlag gefällt mir also sehr!
Ich werde also einen "Lehrer" programmieren, der dem GI-Schüler das Dekodieren beibringt.
Das ist viel handfester und leichter nachprüfbar als irgendwelche Cyberräume und Irrgärten mit versteckten Futterstellen. Meinem System sollte es Banane sein. Wenn es bestraft wird, sterben Links ab. Wenn es belohnt wird, erstarken Links. Pures Perceptron. Nur eben in PIC gegossen und mit externem Lehrer-Chip.
Wird also gemacht. Sollte noch dieses WE gelingen. Vielen Dank für die Anregung.
Viele Grüße
Wolfgang
------------
Können wir dann auch Benchmarks "mein GI" gegen "Deine Mustererkennung" machen? DAS wär doch ein Knaller. Dann weiß ich, wo die GI steht. Top oder Flop.
Pures Perceptron
Der Begriff "Perzeptron" ist fest definiert für eine Neuron-Struktur (kleinste funktionelle Einheit) mit bestimmten Inputs, Gewichten, Schwellenwert (oder Biasinput), einer Summen- und einer Aktivierungsfunktion...:
das ist bei dir wahrscheinlich nicht der Fall, oder doch? Falls nein, müssen wir die Begriffe etwas schärfer auseinander halten. 8)
Vergleich der Netze: gern, aber dann müsste ich eine exakte, komplette Wahrheitstabelle von dir haben, mit allen denkbaren Input-Output-Konstellationen.
Rumgucker
16.11.2019, 11:26
Hallo Helmut,
doch. Ich hab nur abweichende Begriffe und abweichende strukturelle Ansätze.
Meine Links haben das "Nutzen"-Feld. Das entspricht der Eingangsgewichtung der Perceptron-Matrizen.
Meine Zellen haben Summenspeicher (sie bestehen nur aus einem 7-Bit Summenspeicher und einem FIRE-REQ-Bit). Als Aktivierungsfunktion dient der FIRE_LIMIT-Schwellwert.
Ungewohnt ist, dass ich Eingang (Dendriten) und Neuron nicht mehr fest verbunden habe. Dadurch ist mein System nicht mehr an Schichten, sondern an Ereignisse gekoppelt. Und ich erspar mir Multiplikationen und addiere die Gewichtungen lediglich zum Summenspeicher hinzu.
Kein Hexenwerk. Nur eben gut angepasst an die kläglichen Möglichkeiten eines PICs.
Wenns nicht dekodieren kann, hab ich Mist gebaut oder was Wichtiges nicht verstanden. Vom Prinzip her sollte es aber (mindestens) das gleiche können, wie ein mehrschichtiges Perceptron-System mit allen denkbaren Propagations und deep learning und haste-nicht-gesehen. Mit 20 Kern-Zeilen. Also PIC-kompatibel und trotzdem schweineschnell.
So ist zumindest das Ziel.
Viele Grüße
Wolfgang
jaaaa - es "ENTSPRICHT" hier eine FUNKTION irgendwie in etwa dem, was auch bei einem Perzeptron PASSIERT,
aber es IST kein Perzeptron 8)
2 Outputs würden andererseits auch mindestens 2 miteinander verknüpften Perzeptrons entsprechen.
Rumgucker
16.11.2019, 11:49
Hallo Helmut,
ok. Also ein Perceptron-Abklatsch, ein "Perceptklatsch".
Mir fällt aber gerade ein, dass ich mich noch mit Negationen befassen muss. Das war mir für meinen Irrgarten nicht so wichtig. In so ner trostlosen Einöde sollte man negative Gedanken gleich im Ansatz verhindern.
Bei Dekodern sind Negationen aber unverzichtbar. Ich werde wohl beim Durchlaufen von FIRE_LIMIT zwei FIRE_REQ setzen müssen. Richtungsabhängig.
Egal. Mühsam nährt sich das Eichhörnchen...
Viele Grüße
Wolfgang
mal eine vielleicht ketzerische Frage:
Warum versucht man KI nicht mit Analogrechnern zu realisieren?
Die Natur funktioniert analog, nicht digital!
Ich durfte während meines Studiums noch an einem wunderbaren Analogrechner arbeiten, die Ergebniss waren überraschend gut im Vergleich zur (gemessenen) Realität,
leider wurde das Teil bereits Ende der 70er verschrottet, wie eine spätere Nachfrage von mir ergab, ich hätte mir das Ding in die Wohnung geszellt.
Die Natur funktioniert analog, nicht digital!
FF oder BP Netze mit Perzeptronen rechnen mit floats, das entspricht ja gewissermaßen den "Analogwerten".
Andererseits "rechnet" ein natürliches Neuron überhaupt nicht, weder analog noch digital. Aber es hat eine gewisse Summe von Rezeptoren, die bei einer gewissen Anzahl von gebundenen Neurotransmittern zu einer Depolarisation führen.
In einem synaptischen Spalt können etwa (fließend) 0 bis 10 Milliarden (1010) einzelne Neurotransmittermoleküle vorliegen, die mit einer bestimmten Bindungskraft (Gleichgewichtskonstante) an den Rezeptoren binden und ab einer individuellen Grenzbindung zur Depolarisation postsynaptisch führen.
Das wird bei den Perzeptronen mit float-Zahlen nachgebildet.
Jede float-Zahl (7 signifikante dezimale Digits) könnte dabei ohne weiteres einem Integerwert von 0 bis 1010 entsprechen, wobei man dann sogar eher double als float nehmen müsste - aber float reicht meistens in den Perzeptronen, um damit zu rechnen.
Jede Zelle sucht sich also über die Links "Freunde", die ähnlich wie sie selbst ticken. Es kann kreuz und quer durchs ganze Nervensystem verlinkt werden. Es gibt keine Schichten mehr. Dabei bilden sich zwangsweise Cluster aus. In diesen Clustern versteckt sich das Lernen.
Lernen kann das System ohne Training, Agenten etc. einfach dadurch, dass die Zellen Freunde suchen. Die Umwelt wird in diesen Optimierungsvorgang mit eingeschlossen. Es werden sich also die derart verlinkten Cluster bevorzugt ausbilden, die zu einem Erfolg führen. Also die Clustersysteme, die besonders effektiv und schnell eine Situation verarbeiten können.
Wenn zwei kompetitive Links an einem Zelleingang hängen, so wird der verkümmern, der asynchron zum Zellenfeuern arbeitet und der erstarken, der mit der Zelle synchron ist. Das System optimiert den zeitlichen Durchsatz.
Hallo Wolfgang,
in deinem Beitrag hast Du alle modernen Ansätzte der KI prägnant zusammengefasst. Ich in erstaunt und frage mich, welchen Hintergrund Du hast :-)
Ist Deine KI noch eine Simulation ohne Roboterhardware und wird es ein Video eines Roboters geben?
- - - Aktualisiert - - -
HaLa
Warum versucht man KI nicht mit Analogrechnern zu realisieren?
Die Natur funktioniert analog, nicht digital!
Oh, man tut es und kann es mit dem Pulsneuronenbastelbuch auch selbst ein wenig ausprobieren:
https://www.roboternetz.de/community/threads/74226-Neuronen-basteln
nicht "alle modernen Ansätze der KI prägnant zusammengefasst", aber es klingt etwas nach "self-organizing maps" (SOM) oder Hopfield-Netzen. 8)
Wolfgang schrieb:
doch. Ich hab nur abweichende Begriffe und abweichende strukturelle Ansätze.
Meine Links haben das "Nutzen"-Feld. Das entspricht der Eingangsgewichtung der Perceptron-Matrizen.
Meine Zellen haben Summenspeicher (sie bestehen nur aus einem 7-Bit Summenspeicher und einem FIRE-REQ-Bit). Als Aktivierungsfunktion dient der FIRE_LIMIT-Schwellwert.
Ungewohnt ist, dass ich Eingang (Dendriten) und Neuron nicht mehr fest verbunden habe. Dadurch ist mein System nicht mehr an Schichten, sondern an Ereignisse gekoppelt. Und ich erspar mir Multiplikationen und addiere die Gewichtungen lediglich zum Summenspeicher hinzu.
Kein Hexenwerk. Nur eben gut angepasst an die kläglichen Möglichkeiten eines PICs.
....
ok. Also ein Perceptron-Abklatsch, ein "Perceptklatsch".
Mir fällt aber gerade ein, dass ich mich noch mit Negationen befassen muss. Das war mir für meinen Irrgarten nicht so wichtig. In so ner trostlosen Einöde sollte man negative Gedanken gleich im Ansatz verhindern.
Nix Abklatsch. Du bist ganz vorne dabei, du hast quasi die IAF-Pulsneuronen nachgebaut. Ich kann nicht glauben, dass Du in so kurzer Zeit so weite gekommen bist. Das ist der Hammer, ehrlich.
schick mal bitte einen frei lesbaren Link zu "IAF-Pulsneuronen"!
Ich sehe allerdings auch keine exakte Analogie zu einem Perzeptron-Netz (auch keinen "Abklatsch") - ich schrieb ja schon, dass ich es für irgendetwas anderes halte..
Rumgucker
16.11.2019, 13:21
Hallo,
wow.. Ihr seid aber charmant. Das geht mir ja runter wie Öl. Dankeschön!
Ich hab aber keinen Hintergrund und keine Ahnung. Das sehe ich als Vorteil, weil ich dadurch frei denken kann.
--------
Die Uni Ulm macht viel mit FPAAs rum, das analoge Gegenstück zum digitalen FPGA. Eine Ansammlung von analogen Rechenelementen und eine programmierbare Schaltmatrix.
https://www.uni-ulm.de/in/mikro/forschung/schwerpunkte/mixed-signal-cmos-schaltungen/fpaa/
Genau wie ein FPGA hat das Ding leider auch nicht die dynamische Konnektivität, die man eigentlich bräuchte.
DER Analog-Guru Prof. Bernd Ulmann beobachtet das Gebiet analog + KI sehr genau.
Viele Grüße
Wolfgang
wie unterscheidet sich "analog" vom Rechnen mit Fließkommazahlen?
PS,
auch die DACs oder ADCs in FPAA rechnen ja wieder digitale Integer-Zahlen in analoge Spannungswerte (und umgekehrt) um, die man auch als floats repräsentiern kann.
Rumgucker
16.11.2019, 14:05
Hallo Helmut,
natürlich gar nicht. "Analoges Rechnen" bedeutet ja erstmal nur, dass ein Analogon erschaffen wird. Statt eines OPV-Integrators kann das auch der Wasserstand einer Badewanne sein.
-------
Aber es gibt gewichtige Unterschiede. Analoge Schaltungen arbeiten bevorzugt zeitkontinuierlich. Eine analog errechnete PWM schlägt beispielsweise einfach alles. Theoretisch können ihre Flanken in Attosekunden aufgelöst sein. Im Gegenzug freut man sich bei analogen Verstärkern schon über unlineare Verzerrungen von unter 0,1%. Also 10 Bit Auflösung umgerechnet.
In der Digitaltechnik gehts komplett andersrum. Zeitdiskrete Schritte und irrwitzige Auflösungen.
Viele Grüße
Wolfgang
wozu brauche ich Attosekunden Auflösung in neuronalen Netzen?
Ich vermute: überhaupt nicht - wo ist also der Vorteil von analogen Rechnern vs. digitalen cpus z.B. auch + fpus (ESP32, SAMD51, ARM Cortex A57)?
PS,
64bit double hat 16 Stellen im Dezimalsystem - das sind auch schon 100 atto Genauigkeit!
Rumgucker
16.11.2019, 14:34
Hallo Helmut,
ach komm. Erzähl mir nicht, dass die genannten Controller immer gleich zur Stelle sind, wenn ein Lichtblitz am Eingang vorbeihuscht. Oftmals tingeln die irgendwo im Subsystem herum und es kann schon mal ein paar Millisekunden dauern, bis sie sich den Port anschauen können.
Natürlich kann man auch dagegen gegenan programmieren. Mit Port-change-Interrupts und ähnlichen Dingen. Aber die Systemstabilität, Belastung und Testbarkeit wird durch sowas nicht besser. Ein vergessener Semaphor und die Bombe tickt.
Wie elegant ist im Vergleich dazu eine analoge Schaltung, die von morgens bis abends nichts anderes tut, als nur auf Lichtblitze zu lauern. Das macht sie völlig gleichzeitig zu allen anderen sonstigen analogen Schaltungen.
Diese Parallelität ist ein potentieller Vorteil. Wie eben beim FPAA-Chip.
Und nicht ganz unerheblich in den heutigen Zeiten ist die Energieeffizienz des System. Das analoge Gehirn versorgst Du mit ner verdreckten Solarzelle. Versuch das mal mit einer GPU.
Es gibt keien pauschale Antwort auf Deine Frage. Es ist einfach die Frage nach den gestellten Anforderungen. Analogtechnik kann vielfach effektiver, schneller und zielführender sein. Ein PID-Regler setz ich in 5 Minuten zusammen und hab ihn in 10 Minuten parametriert. Da hast Du kaum das Projektverzeichnis angelegt.
Viele Grüße
Wolfgang
da kommt es auf die Detektoren an: wenn es ein i2c-Detektor ist, dauert es zweifellos immer ein paar Millisekunden. SPI ist schon um den Faktor 100 schneller.
Wenn es aber z.B. um digitale GPIOs geht, dann lese ich die beim Raspi mit 10-100ns Genauigkeit/Schnelligkeit (wenn ich muss oder will), und wenn ich in Multithreading-Environments arbeite, dann locker in < 1 µs Auflösung, per pthread timeslice-Scheduler.
Wenn man es genau nimmt arbeitet jede Digitalschaltung analog, da sie aus Bauteilen besteht,deren Kennlinien analog sind.
Und wenn man es genau nimmt, arbeiten die Neuronen gemischt: Sowohl analog als auch digital. Das Zellpotential wird analog integriert, das Aktionspotential ( der Puls ) ist digital. Entweder das Neuron erzeugt einen Ausgangspuls oder keinen. In der Art und Weise hat sich hier an der Uni auch vor kurzem mal einer der Gastprofessoren geäußert.
DER Analog-Guru Prof. Bernd Ulmann beobachtet das Gebiet analog + KI sehr genau.
Er ist auf jeden Fall ein begeisteter Analogelektroniker:
https://www.youtube.com/watch?v=UnKCCpRFrrk
Man könnte einwenden, dass die große Zeit der Analogcomputer vorbei ist, aber wer weiß, vielleicht lassen sich einige der Prinzipien wieder verwenden.
Rumgucker
17.11.2019, 13:29
Hallo,
nach der Verscheuchung erstaunlich vieler Bugs aus erstaunlich wenigen Programmzeilen hat sich mittlerweile auch meine Faszination über das Wachsen und Vergehen von "Links" etwas gelegt.
--------
Mit der nun von Helmut geforderten Dekodiererei steh ich allerdings noch auf Kriegsfuß. "Klatschi" optimiert die zeitliche Korrelation. Ein Dekoder optimiert Funktionen.
Klatschi reißt den Lenker nach links, wenn ihm etwas von rechts vors Auto läuft und fragt sich nicht erst stundenlang, ob das ne alte Oma, ein Auto oder ein Hund ist.
Helmuts Dekoder fährt erstmal drüber weg, setzt zurück und analysiert dann die Überreste des Opfers und entscheidet mit 89%-iger Sicherheit, dass das mal ne alte Oma gewesen sein könnte.
Vermutlich muss ich den Begriff "dekodieren" irgendwie anders verstehen. Bei mir gehts wohl eher um die zeitliche Staffelung als um die Anzahl und Kombination von statischen Eingängen. Ich kann mir zum Beispiel vorstellen, dass Klatschi das Start- und Stopbit in einem Datenstrom finden ("dekodieren") könnte.
Irgendwas beibringen muss ich dem System eigentlich nicht. Die Neuronen sollten sich vollautomatisch auf Pegelsprünge synchronisieren und Cluster bilden.
Ja... so muss ich - glaub ich - Helmuts Aufgabe an Klatschi anpassen. Klatschi ist was serielles, was chronologisches.
Helmut könnte jetzt fragen, woher ich denn wissen will, welcher (parallele) Ausgang welchem (seriellen) Datum zugeordnet ist. Das weiß ich schlichtweg nicht. Ich könnte also zur Zeit nicht mit Sicherheit sagen, ob Klatschi das Lenkrad wirklich nach links reißt. Vielleicht reißt er auch das Lenkrad nach rechts.
Die Bordelektronik eines Teslas sollte also zur Zeit noch nicht mit einem Klatschi-PIC ersetzt werden. Auch wenn der Kostenvorteil sehr verlockend erscheint.
-------
Ich bau den Generator für den Datenstrom kurzerhand mit ins Klatschi rein.
Mal gucken, was passiert.
Viele Grüße
Wolfgang
Ich fürchte, du hast weder meine Frage zu deinem Netz noch mein eigenes BP Netz verstanden, was es genau wie tut, daher deine aus meiner Sicht momentan etwas seltsamen Interpretationen. Mich interessiert:
a) jedes einzelne mögliche Inputmuster, und auf welches Outputmuster es per Training abgebildet werden soll (also was genau gelernt werden soll), und
b) ob nach dem Training diese Muster auch tatsächlich korrekt nachgebildet werden:
auf 00000 folgt Output...
auf 00001 folgt Output...
auf 00010 folgt Output...
auf 00011 folgt Output...
auf 00100 folgt Output...
usw.
Lässt du einzelne Reizmuster untrainiert, musst du sie später nachtrainieren können, falls darauf nicht die gewünschte Reaktion erfolgt.
Das heißt:
a) DU bist es, der dem Netz im Detail vorgeben muss, wie bestimmte Lernmuster aussehen müssen (Trainingssets: auf Inputmuster=Reiz abcde folgt Outputmuster=Reaktion yz)
und
b) JETZT kommen erst die Auswertungen ("Dekodierungen?") während der Laufzeit usw., wo du nach dem Lernen experimentelle definierte Reize setzt und dein Netz dahingehend kontrollierst, ob die Reaktion genau das ist, was vorher trainiert wurde.
Hat das ganze eine zeitliche Dimension, musst du sagen können:
wenn erst Reiz abcde angelegen hat und darauf Reiz ghijk folgt, dann passiert Reaktion ßv,
wenn erst Reiz abcde angelegen hat und darauf Reiz lmnop folgt, dann passiert Reaktion wx,
wenn erst Reiz abcde angelegen hat und darauf Reiz qrstu folgt, dann passiert Reaktion yz,
wenn erst Reiz bcdef angelegen hat und darauf Reiz ghijk folgt, dann passiert Reaktion ß'v',
wenn erst Reiz bcdef angelegen hat und darauf Reiz lmnop folgt, dann passiert Reaktion w'x',
wenn erst Reiz bcdef angelegen hat und darauf Reiz qrstu folgt, dann passiert Reaktion y'z',
Sobald du aber dein System irgendwie sich selber überlässt, macht es wie schon geschrieben "irgend etwas Nebulöses", was keinem gezielten Lernmuster zuzuordnen ist ("bei welchem definierten Reiz muss wann wie ausgewichen werden und wann nicht?") noch eine Kontrolle und/oder Korrektur von gelerntem Verhalten ermöglicht.
Dazu musst du als allererstes kodieren, wie die möglichen Outputs
00
01
10
11
auf Fahr-Aktionen kodiert werden (gerade.vor, gerade.zurück, vorw.links, vorw.rechts, eigentlich auch stopp und ggf. rückw.li und rückw.re, das wären aber 5-7 Zustände, für die du mindestens 3 Outputs benötigst).
Wenn dann z.B. auf Input-Muster
00110 die falsche Reaktion erfolgt, muss per neuem Training korrigiert werden können:
"Das war Quatsch, hier hätte nach rechts statt nach links ausgewichen werden müssen"
oder falsche Reaktion auf 01001: "Auch das war Quatsch, hier hätte gebremst werden müssen"
oder falsche Reaktion auf 10011 "Hier hilft kein Bremsen und kein Lenken sondern nur Rückwärtsfahren")
Rumgucker
17.11.2019, 17:03
Hallo Helmut,
Klatschi arbeitet anders als das Dir Bekannte. Ich wollte lediglich erklären, wo und warum es Unterschiede in der Herangehensweise gibt. Ich hab kein Problem damit, wenn Dich mein Gerede nicht erreicht.
Aber ich hab ein Problem damit, wenn Du glaubst, dass ich schüchtern sei. Ich bin nicht schüchtern. Wenn ich was nicht versteh, frag ich stets nach. Ich kann mich nicht erinnern, dass ich bei Deinen Ausführungen schon jemals nachfragen musste. Du erklärst stets sehr gut und nachvollziehbar.
Also hab einfach Geduld. Ich arbeite an dem Dekoder-Problem.
---------------
Hallo Forum,
nach Beseitigung der Bugs bin ich mutig rangegangen und hab meinen ersten Dekodierungsversuch (drei Eingänge, drei Ausgänge) gemacht. Die parallelen Eingänge hab ich einfach per Software serialisiert.
Alles noch gänzlich ohne Training, weil ich erstmal die Selbstorganisation sehen wollte.
Der EEPROM-Inhalt nach dem Durchlauf:
34482
Von jedem 16-Bit-Wort zählt immer nur das erste Byte. Drei Bytes geben einen "Link": Source-Zelle, Destination-Zelle und "Nutzen" (Gewichtungen). Ein Nutzen von 0x0A ist der Endanschlag.
Dann hab ich den EEPROM-Inhalt in einem Netz dargestellt:
34483
Die Diodensymbole zeigen Zellen an. Die Anode ist der Eingang, die Katode der Ausgang. Die Verbindungen hab ich mit der Stärke beschriftet.
Erfreulich ist erstmal, dass die Software keinen Mist gebaut hat. Alle Verbindungen und Gewichtungen sind erklärlich. Und das in Millisekunden entstehende Netzwerk ist beeindruckend. Ich hab zwei Stunden gebraucht, um es zu analysieren. Ohne es allerdings wirklich zu verstehen. KNN ist schräger Stuff.
Wie erwartet, haben sich Cluster und sogar Rückkopplungen gebildet. Allerdings nicht vollständig ausgebildet. IN_0 ist umfangreich vernetzt. IN_1 schon deutlich weniger. Und IN_2 konnte gar nicht mehr verbunden werden. Mir fehlte es offensichtlich an Zellen und Links. Alle Links wurden verbraucht. Es konnten zwei Zellen überhaupt nicht angeschlossen werden.
Der PIC verfügt nur über 30 Zellen und 42 Links.
Das erinnert mich an ein Geschwür. Klatschi expandiert zu schnell. Zeitlich spätere Ereignisse (wie gesagt: ich musste Helmuts parallele Daten ja serialisieren) haben keine Chance.
Ich muss also das Wachstum bremsen. Erst wenn alle Inputs mit ungefähr gleich vielen Zellen versorgt sind, kann ich an Dekodierungen denken.
Viele Grüße
Wolfgang
ich verstehe es nicht: Was ist ein "Nutzen"? Wann tritt ein "Nutzen" auf? Woran wird ein "Nutzen" gemessen?
Und welche "parallele Daten" von mir (?) mussten "serialisert" werden? Worauf beziehst du dich und was meinst du damit?
Hallo Wolfgang,
Die Diodensymbole zeigen Zellen an. Die Anode ist der Eingang, die Katode der Ausgang. Die Verbindungen hab ich mit der Stärke beschriftet.
eine sehr beeindruckende Graphik. Hast Du sie automatisch aus den Gewichten erstellen lassen?
Was ich nicht verstehe, wie die Werte dort genau zu interpretieren sind.
Ich sehen z.B. oft den Wert 0A.
- - - Aktualisiert - - -
Ein Interpretationsversuch:
34484
Rumgucker
17.11.2019, 19:24
Hallo Helmut,
"Nutzen" = "Gewichtung". Hatte ich vielfach erklärt. Das mit der seriellen Arbeitsweise erklär ich nochmal in gebündelter Form, wenn ich die PDF erstelle. Im Moment ist es ja nicht so wichtig. Es ist beiden doch letztlich egal, wie Klatschi intern arbeitet. Wichtig ist das Ergebnis. Und das soll dekodieren können.
---------
Hallo stochri,
ich hab einfach LTSpice genommen und mir jedes Byte einzeln "händisch" aus dem Dump abgelesen und versucht, damit ein Netz zu zeichnen.
Mittlerweile bin ich aber schon deutlich schneller. Ich hab die Neigung zu Geschwüren durch zwei Maßnahmen gebremst. Ich duchsuche die Zellen jetzt vom Ausgang kommend. Dadurch können einzelne Eingänge das Netz nicht mehr so schnell mit Zellen vollwuchern. Und ich hab den Detektor zum Neuanlegen von Links etwas straffer gestellt.
Nun kommmt schon was raus (ohne jegliches Training), was an einen Dekoder erinnert (da fehlen noch ein paar Strippen, aber die sind alle unbedeutend:
34485
Es hat sich also ganz ohne Training eine 1:1 Dekodierung ergeben. Das ist nun keine Spezialversion der 20 Zeilen. Das soll so bleiben. Er kann jetzt alten Omas ausweichen UND dekodieren. Zumindest stehen genug Zellen pro Pin zur Verfügung.
Das reicht mir erstmal für heute. Ich werde so langsam zum Klatschi-Versteher.
Ich muss mir nun eh Gedanken machen, wie ich das arme Ding für falsche Dekodierungen bestrafe und was dann genau mit dem Netzwerk geschehen soll.
Das kriegen wir auch noch hin.
Viele Grüße
Wolfgang
Wie gesagt: noch Kleinkram dran zu machen.
Ähäm, naja ... Ich hab's mal im Rahmen der Möglichkeiten für einen Arduino-Uno "Arduinofiziert".
Es lebt tatsächlich, aber im wesentlichen von den Softwarefehlern.
/*
#include "allpic.h"
#pragma config = 0b000110000100 // hex-datei: fuses des 12F629
#define EE_ROM // eeprom nutzen
#include "pic_mem.h"
#include "timeloop.h" // timer-routinen
*/
// PIC C-Compiler compatibility
typedef int8_t uns8; // stdint compatibility
typedef bool BOOL;
#define FALSE false
#define TRUE false
/*
#define IN_0 0 // GPIO-Eingänge
#define IN_1 1 //
#define IN_2 2 //
#define IN_3 3 //
#define OUT_0 4 // GPIO-Ausgänge
#define OUT_1 5 //
*/
//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
#define NUMBEROFNEURONS 30
uns8 zellen[NUMBEROFNEURONS]; // zellen im RAM anlegen
#define FIRE_REQ 7 // fire_req bit in der zelle
#define FIRE_LIMIT 10 // fire_limit
#define SENS_0 0 // spezialzellen definieren
#define SENS_1 1 // Sensoren
#define SENS_2 2
#define SENS_3 3
#define TIMER 4 // Timer-Zelle
#define HUNGER 5 // Hunger-Zelle
#define FIRST_NEURON 6 // davor nur read-only-zellen
#define AKT_0 (sizeof(zellen) - 2)
#define AKT_1 (sizeof(zellen) - 1)
//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK -1
//#define MAX_LINKS (128 / sizeof(struct _link))// viele links im EEPROM
#define MAX_LINKS 32
struct _link { // struktur eines EEPROM-links
uns8 src; // leerer link: src_zelle == NO_LINK
uns8 dst; // verbindet source- mit dest-zelle
uns8 use; // nützlichkeit dieses links
};
#define LINK_SRC 0
#define LINK_DST 1
#define LINK_USE 2
/*
uint8_t src;
uint8_t dst;
uint8_t use;
*/
// LINK-Zugriffe im PIC
// #define LINK_RD(a,m) ee_read((a) + offsetof(struct _link,m))
// #define LINK_WR(a,m,v) ee_write((a) + offsetof(struct _link,m),v)
_link Simulated_EEPROM[NUMBEROFNEURONS];
uns8 LINK_RD(uns8 address, uns8 component)
{
uns8 value = 0;
if (component == LINK_SRC) value = Simulated_EEPROM[address].src;
if (component == LINK_DST) value = Simulated_EEPROM[address].dst;
if (component == LINK_USE) value = Simulated_EEPROM[address].use;
return value;
}
void LINK_WR(uns8 address, uns8 component, uns8 value)
{
if (address < NUMBEROFNEURONS)
{
if (component == LINK_SRC) Simulated_EEPROM[address].src = value;
if (component == LINK_DST) Simulated_EEPROM[address].dst = value;
if (component == LINK_USE) Simulated_EEPROM[address].use = value;
} else
{
Serial.print("Error: link address out of range "); Serial.println(address);
delay(100);
}
}
static uns8 rand_link = 0; // randomize link
/*
void gpio_out(uint8_t pin)
{
}
*/
uint16_t FSR; //pointer auf zelle
uint16_t INDF; // ?
static void gi_denke(void) // die genesis
{
uns8 zell_ind = 0, link=0, freeLink=0, buf=0;
BOOL hit;
do { // Suche feuernde zellen
rand_link++; // randomize link
FSR = zellen + zell_ind; // pointer auf zelle
/**** sensoren, aktoren und triebe sind besondere zellen *****/
/*
if (zell_ind <= SENS_3) { // Sensoren abfragen
buf = _BV(zell_ind); // bit-maske entwickeln
if (GPIO & buf) {
if (!(INDF.0)) INDF = FIRE_LIMIT + _BV(FIRE_REQ);
}
else INDF.0 = 0 // FIRE_REQ bearbeiten
} // nun die aktoren
else if (zell_ind == AKT_0) GPIO.OUT_0 = INDF.FIRE_REQ;
else if (zell_ind == AKT_1) GPIO.OUT_1 = INDF.FIRE_REQ;
if (INDF.FIRE_REQ == FALSE) continue; // zelle möchte nicht feuern
*/
/***** wenn zelle feuern will, verfolge die links *************/
// INDF.FIRE_REQ = FALSE; // zelle möchte feuern
INDF &= ~(1 << FIRE_REQ);
freeLink = NO_LINK; link = 0; hit = FALSE;
do { // alle links durchsuchen
rand_link++; // randomize link
buf = LINK_RD(link, LINK_SRC); // linkbyte lesen
if (buf == NO_LINK) freeLink = link; // leeren link merken
else if (buf == zell_ind) { // link gefunden
FSR = zellen + LINK_RD(link, LINK_DST); // pointer auf dst-zelle lesen
//if ((++INDF == FIRE_LIMIT) && (!(INDF.FIRE_REQ))) { // will dst feuern?
if ((++INDF == FIRE_LIMIT) && (!(INDF & (1 << FIRE_REQ)))) { // will dst feuern?
//INDF.FIRE_REQ = TRUE; // feuer_req schon mal vormerken
INDF |= (1 << FIRE_REQ);
buf = LINK_RD(link, LINK_USE); // zwei zellen feuern synchron
LINK_WR(link, LINK_USE, ++buf); // dadurch wird der link nuetzlicher
hit = TRUE; // zumindest ein nützlicher link
}
}
//link += sizeof(struct _link);// nächsten link adressieren
link++;// the link pointer is only an address
} while (link < MAX_LINKS);
//while (link < MAX_LINKS * sizeof(struct _link));
/** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
if ((!hit) && (freeLink != NO_LINK)) {
LINK_WR(freeLink, LINK_SRC, zell_ind); // link neu erzeugen
buf = rand_link % sizeof(zellen); // randomize verlinken, aber eingrenzen
if (buf < FIRST_NEURON) buf += FIRST_NEURON; // keine read-only-zellen
if (buf == zell_ind) buf++; // zellen nicht direkt rückkoppeln
LINK_WR(freeLink, LINK_DST, buf);
LINK_WR(freeLink, LINK_USE, 0); // ob der link nützlich wird, weiß keiner
}
} while (++zell_ind < sizeof(zellen)); // nächste zelle
}
#define DELETE 0
#define REDUCE 1
#define SLEEP 2
static void gi_links(uns8 steuer) // links abschwächen
{
uns8 link = 0, buf;
do { // alle links durchsuchen
if (LINK_RD(link, LINK_SRC) != NO_LINK) { // gelöschte ignorieren
if (steuer == DELETE) buf = 0;
else {
buf = LINK_RD(link, LINK_USE); // nuetzlichkeit lesen
if (buf) LINK_WR(link, LINK_USE, --buf); // langsam verlernen
}
if (!buf) LINK_WR(link, LINK_SRC, NO_LINK); // link ganz löschen
}
//link += sizeof(struct _link); // nächster link
link++;
} while (link < MAX_LINKS);
//while (link < MAX_LINKS * sizeof(struct _link));
if (steuer == DELETE) rand_link = 0;
}
static void gi_zellen(uns8 steuer)// zell-erregungen abschwächen
{
uns8 zell_ind = 0;
do { // Suche zellen
FSR = zellen + zell_ind; // zellerregung lesen
if (steuer == DELETE) INDF = 0;
if (INDF) INDF--;
if ((steuer == SLEEP) && (INDF > FIRE_LIMIT)) INDF = FIRE_LIMIT - 1;
} while (++zell_ind < sizeof(zellen)); // nächste zelle
}
void showLinks(uint8_t adr)
{
Serial.print(adr); Serial.print(" -");
Serial.print(" src:"); Serial.print(Simulated_EEPROM[adr].src);
Serial.print(" dst:"); Serial.print(Simulated_EEPROM[adr].dst);
Serial.print(" use:"); Serial.print(Simulated_EEPROM[adr].use);
Serial.println();
}
void showAll()
{
Serial.println("list Neurons:");
for (int n = 0; n < MAX_LINKS; n++)
{
showLinks(n);
}
Serial.println();
}
void setup()
{
Serial.begin(115200);
Serial.println("Gugi ;-)");
delay(1000);
gi_links(DELETE); // alle links löschen
gi_zellen(DELETE); // zellerregungen löschen
}
uns8 loopCounter = 0;
// FOREVER {
void loop()
{
Serial.println("gi_denke");
gi_denke();
if (!++loopCounter) {
Serial.println("gi_links");
gi_links(REDUCE); // links langsam verlernen
Serial.println("gi_zellen");
gi_zellen(SLEEP); // schlafen
}
else if (!(loopCounter & 0x1F)) // alle 32 durchläufe
{
Serial.println("gi_zellen");
gi_zellen(REDUCE); // zellerregungen vermindern
showAll();
delay(1000);
}
}
Rumgucker
18.11.2019, 04:42
Hallo stochri,
ich wusste nicht, dass Du "arduinifizieren" wolltest. Die Freitags-Version war noch sehr krank. Hier die aktuelle Sonntags-Version:
34486
----
Zu Deinen "Arduinifizierungen":
FALSE ist bei mir 0
TRUE ist bei mir 1
Der FSR, INDF-Mechanismus ist ein PIC-Feature und zentral. Ich denke an den Konstrukt:
static unsigned char* FSR;
#define INDF (*FSR)
Du solltest auch keinesfalls mit 16-Bit-Werten arbeiten. Dann scheitern Schleifen, Offsets und Bit-Dröseleien.
Ich rechne damit, dass die Anzahl meiner Links eh nicht reichen wird, um Dekoder zu errichten. Dann muss ich sowieso auf Tiny85 umsteigen. Dann gibts naturgemäß kein "Arduinifizierungs"-Problem mehr.
Ich hatte den PIC lediglich genommen, weil er mich gleich zum sparsamen Umgang mit allen Ressourcen anhalten sollte. Mal gucken, wie weit ich damit noch komme....
Ich wäre dafür, dass wir weiterhin gemütlich bleiben. In der Ruhe liegt die Kraft. Zum Nachbauen oder gar zum Konvertieren auf andere Plattformen ist es m.E. noch zu früh. Ich kümmere mich noch nicht um Versionenpflege und Administration und will das zur Zeit auch keinesfalls im Hinterkopf haben. Auch die Anzahl meiner "Links" und Zellen ist beschränkt... ;)
Viele Grüße
Wolfgang
Rumgucker
18.11.2019, 07:08
Hallo Forum,
ich falle mal wieder in meine kleinen Schrittchen zurück.
Über den in der hochgeladenen Sonntags-Software enthaltenen "pattern"-Mechanismus hab ich die drei Sensor-Zellen mit vier Bitmustern geladen, die dann nacheinander im Netzwerk abgearbeitet wurden.
switch(zell_ind) {
case SENS_0: WR_FIRE_REQ(pattern == 1); break;
case SENS_1: WR_FIRE_REQ(pattern == 2); break;
case SENS_2: WR_FIRE_REQ(pattern == 3); break;
Es wird pro Netzwerkdurchlauf also immer ein Bit gesetzt. Oder auch keins.
000 - Ergebnis: alle Ausgänge low
100 - Ergebnis: OUT_0 high
010 - Ergebnis: OUT_1 high
001 - Ergebnis: OUT_2 high
Ohne weiteres Zutun kann Klatschi also drei serielle Bits auseinanderhalten und eindeutig dekodieren.
Ein "zeitloses" Perzeptron-Netz zur Mustererkennung hätte dagegen eher so geanwortet:
000 - Ergebnis: alle Ausgänge low
100 - Ergebnis: OUT_0 high (= ein Input-Bit ist gesetzt)
010 - Ergebnis: OUT_0 high (= ein Input-Bit ist gesetzt)
001 - Ergebnis: OUT_0 high (= ein Input-Bit ist gesetzt)
Ich muss also bei zukünftigen Diskussionen höllisch aufpassen, dass ich mir die Kernidee der 20 Zeilen bewahre und nicht verwässern lasse.
Wenn ein gestelltes Problem nicht auf Anhieb von Klatschi gelöst werden kann, dann muss das nicht unbedingt an Klatschi liegen. Es kann auch am Problem liegen. Da kann schon eine simple Übersetzung des Problems von "Perceptronisch" auf Klatschis Sprache helfen.
------------
Zur Zeit kann Klatschi ohne "Einlernen" zeitliche Ereignisse dekodieren. Nicht mehr und nicht weniger. Unter "zeitlichem Ereignis" verstehe ich das Setzen eines FIRE_REQ-Bits in einer Sensorzelle. Das kann durch eine high-low- oder durch eine low-high-Flanke des serialisierenden patterns entstehen.
Man muss sich jetzt fragen, ob damit die Aufgabe der "Dekodierung" schon hinreichend gelöst ist, denn ich sollte die 8 möglichen Muster von drei Eingangsbits damit vollständig in 8 eindeutige Ausgangssignale wandeln können (wenn ich genug Ausgänge hätte).
Für vier Eingangsmuster konnte ich das gestern Abend ja schon zeigen.
-------
Klatschi ist tatsächlich ein "wenig anders". Es muss anders gedacht werden. Für Klatschi besteht eine "Information" aus Ereignis und dem Zeitpunkt des Ereignisses. Ein klassisches Perzeptron kennt nur Ereignisse und es macht Mühe, ihm ein Zeitgefühl beizubringen.
Mein pattern-Generator "versteckt" sozusagen die Anweisung zur richtigen Dekodierung im Zeitpunkt der Information. Das ist das Geheimnis, warum Klatschi keinen besonderen Lehrer braucht. Der pattern-Generator IST der Lehrer.
Ich werde diese Klatschi-Informationseinheit zukünftig "Ereigniszeit" nennen.
Viele Grüße
Wolfgang
ich wusste nicht, dass Du "arduinifizieren" wolltest. Die Freitags-Version war noch sehr krank. Hier die aktuelle Sonntags-Version:
gi.txt (https://www.roboternetz.de/community/attachment.php?attachmentid=34486&d=1574048473)
Das wollte ich eigentlich gar nicht unbedingt. Aber um deinen Code nachzuvollziehen schien es mir am besten, etwas lauffähiges auf dem Tisch zu haben.
Den Arduino-Uno habe ich gewählt, weil hier wahrscheinlich jeder einen zu Haus rumliegen hat und die niedrige Leistungsklasse ganz im Sinne deiner PIC-Wahl zur Demonstrationszwecken ist, sonst hätte ich einen ESP32 genommen.
Ich wäre dafür, dass wir weiterhin gemütlich bleiben. In der Ruhe liegt die Kraft. Zum Nachbauen oder gar zum Konvertieren auf andere Plattformen ist es m.E. noch zu früh. Ich kümmere mich noch nicht um Versionenpflege und Administration und will das zur Zeit auch keinesfalls im Hinterkopf haben. Auch die Anzahl meiner "Links" und Zellen ist beschränkt...
Es ging mir keineswegs darum vorzugreifen oder dir davon eilen zu wollen. Ich finde es nur schön, wenn ich etwas Lauffähiges auf dem Tisch liegen habe, das irgendwas tut. Das ist besser als abstrakter Code.
Rumgucker
18.11.2019, 08:33
Moin stochri,
ich kann Dich verstehen. Mir würds genauso gehen. Dann nimm aber bitte die Sonntags-Version.
Und ich werde - wenn sich was erhebliches gändert hat - immer gleich die aktuelle Version hochladen.
Wir müssen einfach nur unsere Ereigniszeiten besser synchronisieren. Klatschi ist da vorbildhaft...
Viele Grüße
Wolfgang
Rumgucker
18.11.2019, 11:37
Hallo Forum,
Klatschi entdeckt das Auftreten oder Fehlen von Ereignissen zu autonom gelernten Zeitpunkten. Es kann diese Zeitpunkte an langsame Änderungen anpassen. Das ist schon mal gut.
Ein brauchbarer Dekoder muss aber noch mehr können! Klatschi müsste von Natur aus auch kombinieren können (obwohl ich das noch nie beobachtet/nachvollzogen hab).
Zur Erlangung einer vorgegebenen Kombinationsfähigkeit muss es eine Steuerung geben, die mehrere Ereigniszeiten einspeist und den ersten aus deren Kombination resultierenden Feuerimpuls mit einem gewünschten Ausgang verbindet. Der Lernvorgang ist beendet, wenn alle gewünschten Ausgänge verlinkt wurden.
So sollte ich dann auch x-beliebige Dekodierungen hinbekommen können.
Das bau ich (ab) heute.
Viele Grüße
Wolfgang
Rumgucker
18.11.2019, 16:53
Hallo,
Dekoder klappt bestens:
10 -> OUT_0
01 -> OUT_1
11 -> OUT_2
Mikrominimale Erweiterung an der Source. Neue Links werden im "learn"-Mode auf die gewünschte Ausgangszelle gelenkt:
34487
Es werden nun genau vier Links angelegt und keinerlei Neuronen belegt. Links mit "FF" am Anfang sind noch leer:
34489
Das sich ergebende Netzwerk ist anscheinend goldrichtig:
34488
Der Nutzen aller Links ist noch "00", weil sie halt erst gelernt und noch nicht benutzt wurden.
So wurde das Programm aufgerufen:
FOREVER {
switch(loop) {
case 0: pattern = 0x01; learn = AKT_0; break;
case 1: pattern = 0x02; learn = AKT_1; break;
case 2: pattern = 0x03; learn = AKT_2; break;
default: FOREVER;
}
gi_lerne();
loop++;
}
Es wurde also für jedes pattern ein zuzuweisender Ausgangsport festgesetzt.
Damit sind also Dekoder mit logischen Verknüpfungen realisierbar.
Ich bin mir noch nicht sicher, ob out_2 wirklich bei "11" kommt oder schon bei einem der beiden Bits. Zu dem Test müsste ich in die RAM-Zellen gucken können, damit ich sehe, wann die feuern. Kann ich aber nicht.
Da muss ich mir noch was zum Test einfallen lassen. Da kann ich noch ne kleine Leiche im Logik-Keller haben.
Viele Grüße
Wolfgang
---------------
So würde ich ODER "einlernen" (schreckliches Wort):
pattern=0x10 learn=AKT_2
pattern=0x01 learn=AKT_2
und so UND:
pattern=0x11 learn=OUT_2
Ich bin mir aber noch nicht sicher, ob das Klatschi auch so siieht.
Rumgucker
19.11.2019, 05:22
Moin Forum,
gestern wurde mir bewusst, dass ich mich mal genauer mit der Frage der "Link"-Neubildung befassen muss.
Wenn ich die Neubildung zu großzügig erlaube, wuchert das Netz. Ich kann zwischen Stagnation und Wucherung alles einstellen.
Wuchernde Netze sind unvorhersehbarer und erscheinen intelligenter. Sie scheitern aber schnell bei einfachsten Dekodern, weil ihnen vor lauter Wucherung die Links und Zellen ausgehen.
Wachstumsgebremste Netze sind ideal für Dekoder iund können sich auch an veränderliche Umwelten anpassen. Sie kommen aber keinesfalls in den Verdacht, intelligent zu sein.
------------
Ich halte es für sinnvoll, das Netz in mehreren Phasen wachsen zu lassen.
Zuerst mal müssen die Reflexe wachsen. Die kann man auch Dekoder nennen. "Etwas kommt von rechts - reiße das Lenrad nach links" wäre so ein Dekoder, bei dem ich auch vorgeben muss, was das System genau tun soll. Dazu reicht mein gestriger pattern/learn-Mechnismus vom Prinzip her erstmal aus. Bei diesem Vorgang stelle ich die Wucherneigung sehr gering ein, wodurch auch nur wenige Ressourcen an Links und Zellen verbraucht werden.
Danach könnte ein weiterer Durchlauf stattfinden, in dem ich die Wucher-Bremsen lockere. In den höheren Schichten wird dann abstrahiert und findet Intelligenz statt.
**************
Weiterhin muss ich mich mit dem Nützlichkeits-Mechanismus befassen. Meine gestrige Software konnte leider nicht "undieren", weil ich die Nützlichkeit ("Gewichtung") eines Links stets nur erhöht hatte, wenn erer folgreich war.
Es dauerte nicht lange, bis es nicht mehr zweier Links bedurfte, um eine Zelle zum Feuern zu bewegen (= UND-Funktion) sondern ein einziger der beiden Links ausreichte (= ODER). Der Dekoder mutierte also vom erwünschten UND zum unerwünschten ODER.
Das sind also die beiden momentanen Baustellen. Schichtenweise Wachstumsstrategie und liebevollere Ausgestaltung der Lernregel.
Viele Grüße
Wolfgang
Ich habe gerade mal kurz den Code überflogen.
Vielleicht könntest Du oben ein
typedef uns8 int8_t;
einbauen, dann könnte man alle Typdefinitionen im Code "stdint.h" kompatibel machen, damit sie später auch ohne Mühen auf den Attiny portierbar sind.
Ich habe mir schon überlegt, das Programm einfach mit GCC auf dem PC laufen zu lassen, dann wäre das Debugging auch viel einfacher. Hast Du Linux?
Rumgucker
20.11.2019, 11:51
Hallo stochri,
warum bauen wir nicht einfach einen Kompatibilitätsheader? Den klinken wir ein oder lassen ihn weg.
Da kommt der typedef rein. Diese FSR/INDF-Geschichte. Und was sonst noch nötig ist. Und all die Header, die der Arduino braucht. Das ist doch ne 5-Minuten-Sache.
-------
Ich könnte auch gleich mit Atmel programmieren. Und natürlich auch unter Linux. Aber das bringt für mich alles Ablenkungen. Da werde ich dann langsamer, weil ich dann mit Tools kämpfen muss, die ich nur äußerst selten verwende. Linux zum Beispiel zuletzt 2007. Ich weiß nicht mal, ob meine Installation noch anständig hochläuft.
Im Moment weiß ich ja auch ganz genau, wo ich Mist gebaut hab. Die Vergabe neuer "Links" ist unklar. Zur Zeit brauch ich dafür noch nicht mal ein Windows oder nen Compiler oder einen PIC. Wichtiger ist ein Block auf dem Nachttisch und öfter mal ein paar Minuten Ruhe im Büro.
Die Menschheit kam zigtausend Jahre ohne die GI-KNN aus. Sie wird es auch noch ein paar weitere Tage überstehen. Da bin ich absolut zuversichtlich... ;)
Viele Grüße
Wolfgang
Neue Entwicklungstools kosten immer Zeit. Aber manchmal kann sich der Aufwand lohnen und ein Mikrocontroller ist keine gute Debugging-Plattform für Algorithmen.
Ich hab's jetzt mal mit Eclipse-CDT probiert, damit kann man gut durchs Programm steppen.
Mein ( Dein )Programm wirft allerdings folgends aus:
Gucki running
error, no pattern
#define RUNNING_ON_PC
#define NUMBEROFNEURONS 30
//********************** RUNNIN ON PC ***********************************
#ifdef RUNNING_ON_PC
#include <iostream>
#include <stdint.h>
using namespace std;
#define FOREVER while(1)
typedef uint8_t uns8; // stdint.h compatibility
typedef bool BOOL;
#define FALSE 0
#define TRUE 1
// funktioniert nicht
static unsigned char* FSR;
#define INDF (*FSR)
#define LINK_SRC 0
#define LINK_DST 1
#define LINK_USE 2
/*
#define src 0
#define dst 1
#define use 2
*/
#endif
//************************** RUNNING ON PIC ***************************************
#ifdef PIC
#include "allpic.h"
#pragma config = 0b000110000100 // hex-datei: fuses des 12F629
#pragma cdata[0x2100] = \
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0xFF // eeprom initialisierung
#define EE_ROM // eeprom nutzen
#include "pic_mem.h"
#include "timeloop.h"
// LINK-Zugriffe
#define LINK_RD(a,m) ee_read((a) + offsetof(struct _link,m))
#define LINK_WR(a,m,v) ee_write((a) + offsetof(struct _link,m),v)
#endif
#define OUT_0 0 // GPIO
#define OUT_1 1 //
#define OUT_2 2 //
#define IN_2 3 //
#define IN_1 4 //
#define IN_0 5 //
//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
uns8 zellen[30]; // zellen im RAM anlegen
#define FIRE_LIMIT 10 // fire_limit
#define RD_SUM (INDF & 0x3F) // ZELL-Zugriffe
#define WR_SUM(s) {INDF &= ~0x3F; INDF |= (s);}
#ifdef RUNNING_ON_PIC
#define RD_FIRE_REQ (INDF.7)
#define WR_FIRE_REQ(b) {INDF.7 = (b);}
#endif
#ifdef RUNNING_ON_PC
#define RD_FIRE_REQ !!(INDF>>7)
#define WR_FIRE_REQ(b) {INDF&=~0x80;INDF|=b;} //{INDF.7 = (b);}
#endif
#define SENS_0 0 // sensoren
#define SENS_1 1
#define SENS_2 2
#define AKT_0 3 // spezialzellen definieren
#define AKT_1 4
#define AKT_2 5
#define TIMER 6 // Timer-Zelle
#define HUNGER 7 // Hunger-Zelle
#define FIRST_NEURON 8 // Beginn des Hirns
//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK -1
#define MAX_LINKS (128 / sizeof(struct _link)) // viele links im EEPROM
struct _link { // struktur eines EEPROM-links
uns8 src; // leerer link: src_zelle == NO_LINK
uns8 dst; // verbindet source- mit dest-zelle
uns8 use; // nützlichkeit dieses links
};
//********************** RUNNIN ON PC ***********************************
#ifdef RUNNING_ON_PC
_link Simulated_EEPROM[NUMBEROFNEURONS];
uns8 LINK_RD(uns8 address, uns8 component)
{
uns8 value = 0;
if (component == LINK_SRC) value = Simulated_EEPROM[address].src;
if (component == LINK_DST) value = Simulated_EEPROM[address].dst;
if (component == LINK_USE) value = Simulated_EEPROM[address].use;
return value;
}
void LINK_WR(uns8 address, uns8 component, uns8 value)
{
if (address < NUMBEROFNEURONS)
{
if (component == LINK_SRC) Simulated_EEPROM[address].src = value;
if (component == LINK_DST) Simulated_EEPROM[address].dst = value;
if (component == LINK_USE) Simulated_EEPROM[address].use = value;
} else
{
cout << "Error: link address out of range " + address << endl;
// Serial.print("Error: link address out of range "); Serial.println(address);
// delay(100);
}
}
#endif
static uns8 rand_link; // randomize link
static uns8 pattern;
static uns8 learn;
static void gi_lerne(void) // die genesis
{
uns8 zell_ind = 0, link, free, buf;
BOOL hit;
do { // suche feuernde zellen
FSR = &zellen[zell_ind]; // pointer auf zelle
/**** sensoren, aktoren und triebe sind besondere zellen *****/
/*
switch(zell_ind) {
case SENS_0: WR_FIRE_REQ(pattern.0); break;
case SENS_1: WR_FIRE_REQ(pattern.1); break;
case SENS_2: WR_FIRE_REQ(FALSE); break;
case AKT_0: GPIO.OUT_0 = RD_FIRE_REQ; continue;
case AKT_1: GPIO.OUT_1 = RD_FIRE_REQ; continue;
case AKT_2: GPIO.OUT_2 = RD_FIRE_REQ; continue;
default: break;
}
*/
/***** diese zeilen sind der kern des systems *****************/
if(!RD_FIRE_REQ) continue; // zelle möchte nicht feuern
WR_FIRE_REQ(FALSE); // zell-feuerwunsch wird nun erfüllt
free = NO_LINK; link = 0; hit = FALSE; // verfolge die links
do { // alle links durchsuchen
buf = LINK_RD(link,LINK_SRC); // linkbyte lesen
if(buf == NO_LINK) free = link; // leeren link merken
else if(buf == zell_ind) { // einen link gefunden
uns8 hbuf = LINK_RD(link,LINK_USE); // nuetzlichkeit lesen
if(hbuf) hit = TRUE; // nutzlink gefunden
if(++hbuf > FIRE_LIMIT) hbuf = FIRE_LIMIT;// limitieren
FSR = zellen + LINK_RD(link,LINK_DST);// pointer auf dst-zelle
buf = RD_SUM + hbuf; // zellsumme berechnen
if(buf > FIRE_LIMIT) buf = FIRE_LIMIT; // limitieren
WR_SUM(buf); // zellsumme speichern
if((buf == FIRE_LIMIT)&&(!RD_FIRE_REQ)) {// will dst feuern?
WR_FIRE_REQ(TRUE); // FIRE_REQ vormerken
LINK_WR(link,LINK_USE,hbuf); // nuetzlichkeit inkrementieren
}
}
link += sizeof(struct _link); // nächsten link adressieren
} while(link < MAX_LINKS * sizeof(struct _link));
/** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
if((!hit)&&(free != NO_LINK)) {
LINK_WR(free,LINK_SRC,zell_ind); // link neu erzeugen
if(learn) buf = learn; // gewollte verlinkung
else { // zufällige verlinkung
if(++rand_link >= sizeof(zellen)) rand_link = FIRST_NEURON;
buf = rand_link;
if((buf == zell_ind)&&(++buf >= sizeof(zellen))) buf = FIRST_NEURON;
}
LINK_WR(free,LINK_DST,buf);
LINK_WR(free,LINK_USE,0); // ob der link nützlich wird, weiß keiner
}
} while(++zell_ind < sizeof(zellen)); // nächste zelle
}
static void gi_verlerne(void) // links überarbeiten
{
uns8 link = 0, buf;
do { // alle links durchsuchen
if(LINK_RD(link,LINK_SRC) != NO_LINK) { // leere links skippen
buf = LINK_RD(link,LINK_USE); // nuetzlichkeit lesen
if(buf) LINK_WR(link,LINK_USE,--buf); // langsam verlernen
if(!buf) LINK_WR(link,LINK_SRC,NO_LINK);// link ganz löschen
}
link += sizeof(struct _link); // nächster link
} while(link < MAX_LINKS * sizeof(struct _link));
}
#define DELETE 0
#define REDUCE 1
#define SLEEP 2
static void gi_zellen(uns8 steuer) // zell-erregungen überarbeiten
{ // DELETE, REDUCE oder SLEEP
uns8 zell_ind = 0;
do { // suche zellen
FSR = zellen + zell_ind;
if(steuer == DELETE) INDF = 0; // flags und summe auf einen schlag
else if(steuer == REDUCE) {if(RD_SUM) WR_SUM(RD_SUM - 1);}
else if(RD_SUM > FIRE_LIMIT) WR_SUM(FIRE_LIMIT);
} while(++zell_ind < sizeof(zellen)); // nächste zelle
}
#define NUMBER_OF_SIMULATION_STEPS 100
int main()
{
cout << "Gucki running" << endl;
#ifdef PIC
RP0 = 1; // erstmal alle Spezialregister...
#asm
DW /*CALL*/ 0x2000 + /*ADRESSE*/ 0x03FF // oscal abholen
#endasm
OSCCAL = W; // und Oszillatorkalibrierung speichern
OPTION = 0; // global weak-pullup ein (je 20kOhm)
WPU = _BV(IN_0) | _BV(IN_1) | _BV(IN_2);
TRISIO = _BV(IN_0) | _BV(IN_1) | _BV(IN_2); // eingänge
RP0 = 0; // normale register und ram
CMCON = 0x07; // komparator aus
timeloop_init(); // timer initialisieren
#endif
rand_link = FIRST_NEURON;
gi_zellen(DELETE); // zellerregungen löschen
uns8 loop = 0;
int steps=0;
for(steps=0;steps<NUMBER_OF_SIMULATION_STEPS;steps++)
{
switch(loop)
{
case 0: pattern = 0x01; learn = AKT_0; break;
case 1: pattern = 0x02; learn = AKT_1; break;
case 2: pattern = 0x03; learn = AKT_2; break;
default:
{
cout << "error, no pattern" << endl;
}//FOREVER;
}
gi_lerne();
loop++;
#ifdef WEG
gi_verlerne(); // links langsam verlernen
if(!++loop) {
gi_verlerne(); // links langsam verlernen
gi_zellen(SLEEP); // schlafen
}
else if(!(loop & 0x1F)) // alle 32 durchläufe
gi_zellen(REDUCE); // zellerregungen vermindern
#endif
}
cout << steps + " simulations steps done" << endl;
cout << " Gucki stopped" << endl;
//return 0;
}
/* ENDE */
Rumgucker
20.11.2019, 19:06
Hallo stochri,
die Meldung "error no pattern" verstehe ich nicht. "pattern" ist deklariert und wird benutzt.
Ah ne... Du scheinst die Switcherei gleich am Anfang von gi-lerne() ausgeklammert zu haben. Die ist aber unverzichtbar.
Viele Grüße
Wolfgang
Rumgucker
21.11.2019, 05:54
Hallo Forum,
es sperrt sich in mir alles, die momentane Anpassung des GI-Systems an die Mustererkennung weiterzugehen. Es führt m.E. zur Verblödung des Systems.
Diese für Dekoder scheinbar so ungünstige Mutation nützlicher Zellverschaltungen vom UND zum ODER ist nicht ganz unnatürlich. Dem pawlowschen Hund reicht irgendwann zum Speichelfluss Glocke ODER Futter.
Mustererkennung kann man zwar mit einfach strukturierten KNN betreiben. Aber das ist m.E. nicht natürlich. In der Natur ist Mustererekennung ein hochkomplexer Vorgang. Viele Lebewesen beschränken sich darauf, alles für fressbar zu halten, was sie nicht (oder nicht mehr) zur Fortpflanzung gebrauchen können.
Nein! Ich hab den Pfad der Tugend verlassen. Helmuts: "bau nen Dekoder um zu beweisen, dass GI funktioniert" ist ein Paradoxon. Man müsste sogar andersrum formulieren: "wer einen Dekoder erschaffen hat, muss beweisen, ob sein KNN überhaupt noch was anderes kann".
Wenn ich neue Wege finden will, muss ich mir zukünftig fest die Ohren zuhalten und komplett alles ignorieren, was mir erzählt wird. Sonst fahr ich das Projekt gegen die Wand des Altbekannten.
Trotzdem war dieser Ausflug in die Dekoderei hochinteressant. So versteh ich immer besser, wo die KI zur Zeit steht.
Viele Grüße
Wolfgang
Tja, jetzt tut es das:
Gucki running
Number of Neurons: 30
Number of Links: 42
press return
Simulation step number 0
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:1 dst:3 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
Simulation step number 1
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:2 dst:4 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
Simulation step number 2
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 3
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 4
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 5
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 6
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 7
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 8
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
error, no pattern
Simulation step number 9
show state of the links:
0 - src:255 dst:0 use:0
1 - src:255 dst:0 use:0
2 - src:255 dst:0 use:0
3 - src:255 dst:0 use:0
4 - src:255 dst:0 use:0
5 - src:255 dst:0 use:0
6 - src:255 dst:0 use:0
7 - src:255 dst:0 use:0
8 - src:255 dst:0 use:0
9 - src:255 dst:0 use:0
10 - src:255 dst:0 use:0
11 - src:255 dst:0 use:0
12 - src:255 dst:0 use:0
13 - src:255 dst:0 use:0
14 - src:255 dst:0 use:0
15 - src:255 dst:0 use:0
16 - src:255 dst:0 use:0
17 - src:255 dst:0 use:0
18 - src:255 dst:0 use:0
19 - src:255 dst:0 use:0
20 - src:255 dst:0 use:0
21 - src:255 dst:0 use:0
22 - src:255 dst:0 use:0
23 - src:255 dst:0 use:0
24 - src:255 dst:0 use:0
25 - src:255 dst:0 use:0
26 - src:255 dst:0 use:0
27 - src:255 dst:0 use:0
28 - src:255 dst:0 use:0
29 - src:255 dst:0 use:0
30 - src:255 dst:0 use:0
31 - src:255 dst:0 use:0
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:3 dst:5 use:0
36 - src:255 dst:0 use:0
37 - src:255 dst:0 use:0
38 - src:255 dst:0 use:0
39 - src:255 dst:0 use:0
40 - src:255 dst:0 use:0
41 - src:255 dst:0 use:0
show Neurons
0 - val:0, fire:0
1 - val:0, fire:0
2 - val:0, fire:0
3 - val:0, fire:0
4 - val:0, fire:0
5 - val:0, fire:0
6 - val:0, fire:0
7 - val:0, fire:0
8 - val:0, fire:0
9 - val:0, fire:0
10 - val:0, fire:0
11 - val:0, fire:0
12 - val:0, fire:0
13 - val:0, fire:0
14 - val:0, fire:0
15 - val:0, fire:0
16 - val:0, fire:0
17 - val:0, fire:0
18 - val:0, fire:0
19 - val:0, fire:0
20 - val:0, fire:0
21 - val:0, fire:0
22 - val:0, fire:0
23 - val:0, fire:0
24 - val:0, fire:0
25 - val:0, fire:0
26 - val:0, fire:0
27 - val:0, fire:0
28 - val:0, fire:0
29 - val:0, fire:0
simulations steps done: 10
Gucki stopped
#define RUNNING_ON_PC
#define NUMBEROFNEURONS 30
//********************** RUNNING ON PC ***********************************
#ifdef RUNNING_ON_PC
#include <iostream>
#include <stdint.h>
#include <stdio.h>
using namespace std;
#define FOREVER while(1)
typedef uint8_t uns8; // stdint.h compatibility
typedef bool BOOL;
#define FALSE 0
#define TRUE 1
// funktioniert nicht
static unsigned char* FSR;
#define INDF (*FSR)
#define LINK_SRC 0
#define LINK_DST 1
#define LINK_USE 2
#endif
//************************** RUNNING ON PIC ***************************************
#ifdef RUNNING_ON_PIC
#include "allpic.h"
#pragma config = 0b000110000100 // hex-datei: fuses des 12F629
#pragma cdata[0x2100] = \
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF, 0,0,\
0xFF,0xFF // eeprom initialisierung
#define EE_ROM // eeprom nutzen
#include "pic_mem.h"
#include "timeloop.h"
// LINK-Zugriffe
#define LINK_RD(a,m) ee_read((a) + offsetof(struct _link,m))
#define LINK_WR(a,m,v) ee_write((a) + offsetof(struct _link,m),v)
#endif
#define OUT_0 0 // GPIO
#define OUT_1 1 //
#define OUT_2 2 //
#define IN_2 3 //
#define IN_1 4 //
#define IN_0 5 //
//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
uns8 zellen[NUMBEROFNEURONS]; // zellen im RAM anlegen
// cells are bit coded
// b7 b6 b5 b4 b3 b2 b1 b0
// FIRE_REQ ( cell potential )
#define FIRE_LIMIT 10 // fire_limit
#define RD_SUM (INDF & 0x3F) // ZELL-Zugriffe
#define WR_SUM(s) {INDF &= ~0x3F; INDF |= (s);}
#ifdef RUNNING_ON_PIC
#define RD_FIRE_REQ (INDF.7)
#define WR_FIRE_REQ(b) {INDF.7 = (b);}
#endif
#ifdef RUNNING_ON_PC
#define RD_FIRE_REQ !!(INDF&0x80)
#define WR_FIRE_REQ(b) {INDF&=~0x80;INDF|=b<<7;} //{INDF.7 = (b);}
#endif
#define SENS_0 0 // sensoren
#define SENS_1 1
#define SENS_2 2
#define AKT_0 3 // spezialzellen definieren
#define AKT_1 4
#define AKT_2 5
#define TIMER 6 // Timer-Zelle
#define HUNGER 7 // Hunger-Zelle
#define FIRST_NEURON 8 // Beginn des Hirns
//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK -1
#define MAX_LINKS (128 / sizeof(struct _link)) // viele links im EEPROM
struct _link { // struktur eines EEPROM-links
uns8 src; // leerer link: src_zelle == NO_LINK
uns8 dst; // verbindet source- mit dest-zelle
uns8 use; // nützlichkeit dieses links
};
//********************** RUNNIN ON PC ***********************************
#ifdef RUNNING_ON_PC
_link Simulated_EEPROM[NUMBEROFNEURONS];
void initEEPROM()
{
for(int n=0;n<MAX_LINKS ;n++)
{
int address=n;
Simulated_EEPROM[address].src=0xFF;
Simulated_EEPROM[address].dst=0;
Simulated_EEPROM[address].use=0;
}
}
uns8 LINK_RD(uns8 address, uns8 component)
{
uns8 value = 0;
if (component == LINK_SRC) value = Simulated_EEPROM[address].src;
if (component == LINK_DST) value = Simulated_EEPROM[address].dst;
if (component == LINK_USE) value = Simulated_EEPROM[address].use;
return value;
}
void LINK_WR(uns8 address, uns8 component, uns8 value)
{
if (address < NUMBEROFNEURONS)
{
if (component == LINK_SRC) Simulated_EEPROM[address].src = value;
if (component == LINK_DST) Simulated_EEPROM[address].dst = value;
if (component == LINK_USE) Simulated_EEPROM[address].use = value;
} else
{
printf("Error: link address out of range, address:%d\n ",address);
}
}
void showAktor(int aktorId,bool bit)
{
/*
printf("%d:",aktorId);
if(bit) printf("ON ");
else printf("OFF ");
*/
}
void showLinks(uint8_t adr)
{
int src=Simulated_EEPROM[adr].src;
int dst=Simulated_EEPROM[adr].dst;
int use=Simulated_EEPROM[adr].use;
printf("%d - src:%d dst:%d use:%d\n",adr,src,dst,use);
}
void showNeurons()
{
for(int n=0;n<NUMBEROFNEURONS;n++)
{
int neuronNumber=n;
int potential=zellen[n]&0x3F;
int fireRequest=(zellen[n]&0x80)>>7;
printf("%d - val:%d, fire:%d\n",neuronNumber,potential,fireRequest);
}
}
void showAll()
{
puts("show state of the links:");
for (uint16_t n = 0; n < MAX_LINKS; n++)
{
showLinks(n);
}
puts("show Neurons");
showNeurons();
puts("");
}
#endif
static uns8 rand_link; // randomize link
static uns8 pattern;
static uns8 learn;
static void gi_lerne(void) // die genesis
{
uns8 zell_ind = sizeof(zellen), link, free, buf;
BOOL hit;
do { // suche feuernde zellen
//FSR = &zellen[zell_ind]; // pointer auf zelle
//FSR = zellen + zell_ind;
FSR = zellen + --zell_ind; // pointer auf zelle
/**** sensoren, aktoren und triebe sind besondere zellen *****/
#ifdef RUNNING_ON_PIC
switch(zell_ind) {
case SENS_0: WR_FIRE_REQ(pattern.0); break;
case SENS_1: WR_FIRE_REQ(pattern.1); break;
case SENS_2: WR_FIRE_REQ(FALSE); break;
case AKT_0: GPIO.OUT_0 = RD_FIRE_REQ; continue;
case AKT_1: GPIO.OUT_1 = RD_FIRE_REQ; continue;
case AKT_2: GPIO.OUT_2 = RD_FIRE_REQ; continue;
default: break;
}
#endif
#ifdef RUNNING_ON_PC
switch(zell_ind) {
case SENS_0: WR_FIRE_REQ(pattern&1); break;
case SENS_1: WR_FIRE_REQ((pattern>>1)&1); break;
case SENS_2: WR_FIRE_REQ(FALSE); break;
case AKT_0: showAktor(0,RD_FIRE_REQ); continue;
case AKT_1: showAktor(1,RD_FIRE_REQ); continue;
case AKT_2: showAktor(2,RD_FIRE_REQ); continue;
default: break;
}
#endif
/***** diese zeilen sind der kern des systems *****************/
if(!RD_FIRE_REQ) continue; // zelle möchte nicht feuern
WR_FIRE_REQ(FALSE); // zell-feuerwunsch wird nun erfüllt
free = NO_LINK; link = 0; hit = FALSE; // verfolge die links
do { // alle links durchsuchen
buf = LINK_RD(link,LINK_SRC); // linkbyte lesen
if(buf == NO_LINK) free = link; // leeren link merken
else if(buf == zell_ind) { // einen link gefunden
uns8 hbuf = LINK_RD(link,LINK_USE); // nuetzlichkeit lesen
if(hbuf) hit = TRUE; // nutzlink gefunden
if(++hbuf > FIRE_LIMIT) hbuf = FIRE_LIMIT;// limitieren
FSR = zellen + LINK_RD(link,LINK_DST);// pointer auf dst-zelle
buf = RD_SUM + hbuf; // zellsumme berechnen
if(buf > FIRE_LIMIT) buf = FIRE_LIMIT; // limitieren
WR_SUM(buf); // zellsumme speichern
if((buf == FIRE_LIMIT)&&(!RD_FIRE_REQ)) {// will dst feuern?
WR_FIRE_REQ(TRUE); // FIRE_REQ vormerken
LINK_WR(link,LINK_USE,hbuf); // nuetzlichkeit inkrementieren
}
}
link += sizeof(struct _link); // nächsten link adressieren
} while(link < MAX_LINKS * sizeof(struct _link));
/** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
if((!hit)&&(free != NO_LINK)) {
LINK_WR(free,LINK_SRC,zell_ind); // link neu erzeugen
if(learn) buf = learn; // gewollte verlinkung
else { // zufällige verlinkung
if(++rand_link >= sizeof(zellen)) rand_link = FIRST_NEURON;
buf = rand_link;
if((buf == zell_ind)&&(++buf >= sizeof(zellen))) buf = FIRST_NEURON;
}
LINK_WR(free,LINK_DST,buf);
LINK_WR(free,LINK_USE,0); // ob der link nützlich wird, weiß keiner
}
} while(++zell_ind < sizeof(zellen)); // nächste zelle
}
static void gi_verlerne(void) // links überarbeiten
{
uns8 link = 0, buf;
do { // alle links durchsuchen
if(LINK_RD(link,LINK_SRC) != NO_LINK) { // leere links skippen
buf = LINK_RD(link,LINK_USE); // nuetzlichkeit lesen
if(buf) LINK_WR(link,LINK_USE,--buf); // langsam verlernen
if(!buf) LINK_WR(link,LINK_SRC,NO_LINK);// link ganz löschen
}
link += sizeof(struct _link); // nächster link
} while(link < MAX_LINKS * sizeof(struct _link));
}
#define DELETE 0
#define REDUCE 1
#define SLEEP 2
static void gi_zellen(uns8 steuer) // zell-erregungen überarbeiten
{ // DELETE, REDUCE oder SLEEP
uns8 zell_ind = sizeof(zellen);
do { // suche zellen
FSR = zellen + --zell_ind;
if(steuer == DELETE) INDF = 0; // flags und summe auf einen schlag
else if(steuer == REDUCE) {if(RD_SUM) WR_SUM(RD_SUM - 1);}
else if(RD_SUM > FIRE_LIMIT) WR_SUM(FIRE_LIMIT);
} while(zell_ind); // nächste zelle
}
#define NUMBER_OF_SIMULATION_STEPS 10
int main()
{
#ifdef RUNNING_ON_PC
printf("Gucki running\n" );
initEEPROM();
printf("Number of Neurons: %d\n",NUMBEROFNEURONS);
printf("Number of Links: %d\n",(int)MAX_LINKS);
puts("press return");
getchar();
#endif
#ifdef RUNNING_ON_PIC
RP0 = 1; // erstmal alle Spezialregister...
#asm
DW /*CALL*/ 0x2000 + /*ADRESSE*/ 0x03FF // oscal abholen
#endasm
OSCCAL = W; // und Oszillatorkalibrierung speichern
OPTION = 0; // global weak-pullup ein (je 20kOhm)
WPU = _BV(IN_0) | _BV(IN_1) | _BV(IN_2);
TRISIO = _BV(IN_0) | _BV(IN_1) | _BV(IN_2); // eingänge
RP0 = 0; // normale register und ram
CMCON = 0x07; // komparator aus
timeloop_init(); // timer initialisieren
#endif
rand_link = FIRST_NEURON;
gi_zellen(DELETE); // zellerregungen löschen
uns8 loop = 0;
int steps=0;
for(steps=0;steps<NUMBER_OF_SIMULATION_STEPS;steps++)
{
switch(loop)
{
case 0: pattern = 0x01; learn = AKT_0; break;
case 1: pattern = 0x02; learn = AKT_1; break;
case 2: pattern = 0x03; learn = AKT_2; break;
default:
{
#ifdef RUNNING_ON_PC
printf("error, no pattern\n");
#endif
}//FOREVER;
}
gi_lerne();
#ifdef RUNNING_ON_PC
printf("Simulation step number %d\n",steps);
showAll();
#endif
loop++;
#ifdef WEG
gi_verlerne(); // links langsam verlernen
if(!++loop) {
gi_verlerne(); // links langsam verlernen
gi_zellen(SLEEP); // schlafen
}
else if(!(loop & 0x1F)) // alle 32 durchläufe
gi_zellen(REDUCE); // zellerregungen vermindern
#endif
}
#ifdef RUNNING_ON_PC
printf("\nsimulations steps done: %d\n",steps);
printf(" Gucki stopped\n");
#endif
//return 0;
}
/* ENDE */
Wenn Du Linux hast, kannst Du die Datein mit
gcc Gucki.cpp
und dann laufen lassen.
Ansonsten gäbe es noch die Möglichkeit, Cygwin auf Windows zu installieren, da ist der GCC auch drinn.
- - - Aktualisiert - - -
So richtig ist mir nicht klar, was die Variable "pattern" genau macht. Kannst Du was dazu sagen?
Helmuts: "bau nen Dekoder um zu beweisen, dass GI funktioniert" ist ein Paradoxon.
ich habe nie gesagt, du sollest einen Dekoder bauen - das war deine eigene Idee, weil du ja gar nicht wusstest oder zeigen konntest, was dein GI intern überhaupt macht
MIR war das völlig egal - wichtig waren nur inputs und zugehörige Outputs.
Stattdessen solltest du nur zeigen, dass dein GI überhaupt in der Lage ist, simpelste logische Verknüpfungen darzustellen und zu lernen, welche als Basis der Booleschen Aussagenlogik (Boolesche Algebra) auch gleichzeitig Basis jedes logischen Verhaltens ist und aller wenn-dann-Beziehungen: nämlich UND, ODER und NICHT.
Dabei werden ganz einfach Input-Muster auf Outputs abgebildet, die für die jew. Verknüpfung entsprechend zu lernen wären ("Lern-Pattern") .
Ein intelligentes System muss einfach gezielt mindestens lernen können, dass bei 2 unabhängigen Eingängen
a) ein Ausgang nur true ist, wenn beide zugeordnete Eingänge gleichzeitig true sind (UND)
b) ein Ausgang nur true ist, wenn mindestens einer der beiden zugeordneten Eingänge true ist (ODER)
c) ein Ausgang nur true ist, wenn der zugeordnete Eingang false ist - und umgekehrt (NICHT).
(Dabei war jetzt noch nicht einmal die XOR Verkrnüpfung dabei.)
Und das muss selbstverständlich auch tatsächlich experimentell nachweisbar sein: das ist kein Paradox, sondern zwingende Vorraussetzung.
Sonst lernt das System nicht reproduzierbar Gezieltes und Nachprüfbares, sondern macht nur irgendetwas unachvollziehbar Nebulöses.
Hallo Wolfgang,
im Moment verstehe ich Dein Netz so, dass die Links die Verbindungen zwischen Neuronen sind. Da es nur 42 gibt, müssen wahrscheinlich schwächere Links von Neuronen abgezogen werden, falls ein anderes stärkere Links hat.
Den Parameter "USE" würde man in klassischen KNN meiner Meinung nach als "Gewichtsfaktoren" (überlicherweise als "weight") abgekürzt, bezeichnen.
Im Programm waren noch Fehler, die ich erst mal oben im Code korrigiert habe.
Was mich wundert, ist dass sich nur die Werte 32-35 in der Simulation ändern:
32 - src:157 dst:32 use:96
33 - src:0 dst:0 use:0
34 - src:0 dst:0 use:8
35 - src:1 dst:3 use:0
Der Wert 157 für den Link 32 kann wahrscheinlich auch nicht stimmen ( es geht ja nur bis 41 ).
Rumgucker
22.11.2019, 04:33
Moin stochri,
richtig. Links verbinden Neuronen. Schwächere Links können verkümmern mit der Prozedur "gi_verlerne()", die aber bei Dir noch nicht genutzt wurde. Use ist Gewichtung. Den "157"-Fehler kenn ich nicht.
--------------
Moin Helmut
Stattdessen solltest du nur zeigen, dass dein GI überhaupt in der Lage ist, simpelste logische Verknüpfungen darzustellen und zu lernen, welche als Basis der Booleschen Aussagenlogik (Boolesche Algebra) auch gleichzeitig Basis jedes logischen Verhaltens ist und aller wenn-dann-Beziehungen: nämlich UND, ODER und NICHT.
Dabei werden ganz einfach Input-Muster auf Outputs abgebildet, die für die jew. Verknüpfung entsprechend zu lernen wären ("Lern-Pattern") .
Das nenne ich "Dekoder bauen". Logische Verknüfungen haben m.E. in der Form der boolschen Algebra im GI-System nichts zu suchen.
Dekodierung bzw. Mustererkennung gehört nicht auf die erste(n) Zellschichten einer KNN, sondern ist eine sehr hohe Abstrahierung.
----
Zellen kennen kein NOT, XOR und noch nicht mal ein stabiles AND. Sehr wohl aber ein OR. Und noch ein paar andere Funktionen, die es nun wiederrum in der boolschen Algebra nicht gibt.
Über solche fundamentalen Dinge würde ich mich mit Euch viel lieber unterhalten.
Aber Helmut kommt aus seiner engen Mustererkennung nicht raus und stochri hat komische Fehler mit GI-Derivaten auf anderen Plattformen.
Beides bringt mich zur Zeit nicht voran. Ich zieh mich mal ein paar Tage aus dem Forum zurück, bis ich liefern kann.
Viele Grüße
Wolfgang
Aber Helmut kommt aus seiner engen Mustererkennung nicht raus und stochri hat komische Fehler mit GI-Derivaten auf anderen Plattformen.
Deshalb wäre es ja gut, wenn wir eine gemeinsam funktionierende Softwarebasis haben. Denn ich bin vorwiegend mit Fehlersuche statt mit dem eigentlichen Problem beschäftigt, was mich auch daran hindert, weiterführende Gedanken zum Thema zu äußern. Ich sehe einige Dinge bei deinem Verfahren, die man verbessern könnte. Dazu will ich mich aber erst äußern, wenn der Algortihmus auch so läuft wie mit deinem PIC.
Normalerweise entwickle ich meine Algortihmen selbst, auch weil es mühselig ist, sich in anderer Leute Gedanken einzuarbeiten. Ich habe es mal angefangen, Dein Programm zu portieren, weil es vielversprechende Ansätze hat. Wenn es mich aber zu viel Zeit kostet, den Grundalgorithmus ans Laufen zu bekommen, dann lasse ich es bleiben.
Zellen kennen kein NOT, XOR und noch nicht mal ein stabiles AND. Sehr wohl aber ein OR. Und noch ein paar andere Funktionen, die es nun wiederrum in der boolschen Algebra nicht gibt.
selbstverständlich kennen Zellen UND, ODER und NICHT:
Es gibt hemmende und aktivierende Neurotransmitter in Synapsen für hemmende Zwischenneuronen oder Reflexbögen und aktivierende Zwischenneuronen oder Reflexbögen, sodass das Aktivierungspotential von Zellen bereits angehoben sein kann für eingehende Signale (ODER) oder abgesenkt, damit es erst bei mehreren ± gleichzeitigen Signalen zur Aktivierung kommt (UND) oder eine Aktivierung ein hemmendes Zwischenneuron trifft (NICHT): genau so lässt es sich aussagenlogisch strukturieren!
a XOR b
ist wiederum nichts anderes als
(a UND ^b) ODER ( ^a UND b)
Deine Unkenntnis physiologischer Vorgänge und aussagenlogischer Prinzipien ist wirklich erschreckend.
Gerade die Erkenntnis über diese Zusammenhänge hat ja gerade die Konstruktion von Perzeptronen angestoßen (Eingänge, Eingangsgewichte, Eingangssummation, Schwellenwert, Aktivierungsfunktion), auch wenn es sicherlich auch anders geht (McCulloch-Pitts-Neuronen oder analog oder wie auch immer).
Auch für andere lösbare Probleme wie in der Analysis oder der Algebra ist es hilfreich, wenn man die Grundrechenarten und die Mengenlehre beherrscht (eine Boolesche Algebra mit UND und ODER bildet ebenso einen mathematischen Ring wie die Ganzen Zahlen mit + und *, beides ist elementare, universelle Mathematik, an der weder unbelebte Materie (wie Computer) noch lebende Zellen (wie in Gehirnen) vorbei kommen!), und gleiches gilt für die Grundlagen der Anatomie und der Physiologie, wenn man sich über natürliche neuronale Strukturen äußert.
PS, bin gerade erst ganz zufällig auf diesen Link gestoßen:
https://towardsdatascience.com/mcculloch-pitts-model-5fdf65ac5dd1
Rumgucker
26.11.2019, 15:40
Hallo,
dieser entschleunigende Rückzug ins stille Kämmerlein war bisher für mich sehr wohltuend. Ich wollte mal ein kurzes Lebenszeichen senden.
-----------
Muss ich jetzt verstehen, warum Helmut mir "erschreckende Unkenntnis" vorwirft? Oder darf ich das einfach wegignorieren?
Dass sich bei Perzeptrons das AND zu einem OR verwachsen kann, hatte ich völlig richtig erkannt.
Weiterhin kennt die Natur auch kein NOT. Sie kennt sehr wohl aber ein Wegfall eines Teils einer AND-Verbindung.
Wenn wir die Mauer zum ersten Mal sehen, werden wir nicht feststellen: "Da liegt aber keine tote Katze auf der Mauer". Eine Negation ohne Kontext ist uns fremd. Wer NOT-Funktionen in Perzeptrons einbaut, hat den Schuss nicht gehört.
Sehr wohl fällt uns aber ein Stuhl auf, auf dem seit ein paar Minuten keine schlafende Katze mehr liegt. Wir haben also gelernt "Stuhl AND schlafende Katze" und wir triggern auf "Stuhl AND not(Katze)".
"Kann Dein Dekoder OR, AND und NOT?" ist also im Ansatz Humbug. Zumindest beim GI-System ist AND ein Spezialfall von ODER und NOT ist ein Spezialfall von AND. Das hat mit Zufälligkeiten usw. nichts zu tun. Es geht schlichtweg darum, eine "natürliche" Logik zu entwickeln. Die boolsche Algebra ist nicht natürlich. Die kommt in mein GI-System nicht rein.
Ich will mir diese Gedanken machen dürfen!
---------
@stochri:
Denn ich bin vorwiegend mit Fehlersuche statt mit dem eigentlichen Problem beschäftigt.
Ich hab hier stets nur Software hochgeladen, die das jeweils in den Beiträgen und Dumps beschriebene auf einem PIC12F629 tut. Also exakt das fehlerfrei tut, was ich beschrieben hatte.
Ich hatte Dich weder gebeten noch sollte es nötig sein, irgendwelche Fehler zu beseitigen, wenn man die jeweiligen Beispiele exakt so laufen lässt, wie ich sie hochgeladen hatte.
Weiterhin hatte ich mehrfach geschrieben, dass ich zwar Verständnis für Neugierde hab, aber eben auch keinerlei Versionspflege betreibe. Wenn Du also einen Fehler in einer zwei Tagen alten Software findest, dann schenk ich ihn Dir. Ich kann ihn nicht mal mehr nachvollziehen, weil ich mittlerweile die Software weiterentwickelt hab. Und ich will ihn auch nicht nachvollziehen, weil mich zur Zeit nur meine Plattform interessiert.
----------
Ich hab den Fehler gemacht, dass ich meine bisherige 2,5-wöchige Einarbeitung ("Registriert seit 07.11.2019") in das GI-Thema hier im Forum dokumentiert hab.
Anyway....
Ich entwickele trotzdem in aller Seelenruhe in genau meinem Tempo weiter und schreib die nächsten Tage die PDF zusammen. Sobald ich die fertig hab, stell ich die hier als ersten Milestone rein.
Viele Grüße
Wolfgang
ok, ich sehe schon: es ist schwer, ein Glas zu füllen, das bereits voll ist...
Es soll ja auch immer noch Leute geben, die die Quadratur des Kreises beweisen wollen (obwohl es mathematisch definitiv bewiesen ist, dass es nicht geht) oder die ein Perpetuum mobile zum Patent anmelden wollen (obwohl es durch den Energieerhaltunssatz bewiesen ist, dass es nicht geht) ;)
Aber es st ja nicht verboten, dazuzulernen - vlt wird dir ja noch irgendwann klar, was Boolesche Aussagenlogik ist und warum sie gültig ist, und zwar im gesamten Universum, genau wie auch das Kleine Einmaleins 8)
Aber mach mal... ;)
Hallo,
wer hat jetzt Recht und wer bekommt seine Ruhe? Hier mal eine andere Meinung zu dem Thema.
Das "GI"-System ist ein weiterer Versuch von hunderten oder tausenden, ein Neuronales Netzwerk zu erstellen.
Ich sehe den Fehler, das ein Neuronales Netz mit Intelligenz gleichgesetzt wird.
Das beides hat aber wenig miteinander zu tun. Dagegen sollte auf die Verarbeitung von Daten gesetzt werden,
weil es das ist, was Intelligenz am Ende ausmacht. Nicht nur die Menge der Daten, die gespeichert und zur Verarbeitung zur Verfügung steht,
sondern vor allem die Art und Weise der Verarbeitung. Das Reduzieren auf das Wesentliche, um Verarbeitung auf jede erdenkliche Art und Weise
zu ermöglichen. Ganz wichtig für Intelligenz ist zudem Abstraktion. Das ist eins der wichtigsten Prinzipien überhaupt. Deshalb erstaunt es auch nicht,
dass man dies in künstlich neuronalen Netzen wiederfindet, die ja versuchen, das menschliche Gehirn nachzubilden.
Künstlich neuronale Netze sind sehr alt und werden dauernd weiterentwickelt. Sie können vor allem eines, Muster erkennen. Das geschieht durch
tausend- oder millionenfaches Training. Das, was ein KNN in einem solchen Fall kann bzw. tut, könnte auch auf andere Weise programtechnisch entwickelt
werden.
Jetzt zu versuchen, aus ein paar künstlich nachgebauten Neuronen eine Intelligenz zu entwickeln, wird nicht funktionieren. Ansatzweise kann
aber mit so ein paar künstlichen Neuronen intelligente Verarbeitung "versucht" oder demonstriert werden, ohne aber Anspruch auf eine Intelligenz
zu erheben, die zu "Überwältigendem" fähig ist. Wahrscheinlich hält es der Definition von Intelligenz im menschlichen Maßstab auch nicht stand.
Es gibt Forschung in die Richtung der exakten Nachbildung menschlicher Neuronen und was damit zu tun hat, auf künstlicher Basis. Was durchaus extrem
sinnvoll ist. Denn dadurch kann es eines Tages möglich werden, dass man Menschen mit Verlust an Gehirnmasse (z.B. Schlaganfälle und Unfälle) durch
ein Implantat helfen kann. Es wäre denkbar, z.B. nach einem Schlaganfall, das im Gehirn entstandene Loch mit einem Implantat zu ersetzen, das
von wenigen Quadratmillimeter bis Quadratzentimeter groß sein kann. Die abgestorbene Gehirnmasse wird abgebaut und das hinterbliebene Loch schließt sich.
Da das Gehirn in der Lage ist, sich umzuorganisieren und gerade in der ersten Zeit, nach aufgetretenen Defekten, schnell neue Verbindungen zwischen
den Zellen herzustellen (ähnlich, wie bei einem Kleinstkind), könnte ein künstlicher Speicher, der so funktioniert, wie menschliche Gehirnmasse,
von dem Organ "Gehirn" assimiliert werden. Es ist aber völlig unklar, wie sich das Gehirn umorganisieren wird und wie ein künstlich eingebrachtes Netz
überhaupt genutzt würde oder ob das alles nicht doch noch viel komplizierter ist, als man sich das heute vorstellen kann. Die Forschung geht schon länger
auch in diese Richtung, Neuronen künstlich nachzubauen, die in der Funktion exakt der dem organischen Vorbild entsprechen, inkl. Signale und deren Stärken.
Die CPU als solches besitzt bereits Strukturen zur Verarbeitung und Milliarden Transistoren, die vernetzt sind. Alle Grundmechanismen, auf denen komplexe
Intelligenz basiert, sind bereits in einer heutigen CPU vorhanden. Neuronale Netze können direkt auf Siliziumscheiben nachgebaut werden, ohne, dass eine
CPU im Hintergrund für die Verarbeitung sorgt, was nebenbei auch sehr energieaufwendig ist.
Wenn man davon absieht, dass die Neuronen Mustererkennung lernen sollen oder meinetwegen auch die XOR-Wahrheitstabelle: was sollen sie denn dann lernen?
Auf ein bestimmtes Eingangsmuster eine bestimmte Reaktion zeigen oder eine unbestimmte/nicht vorhersehbare Reaktion zeigen? Irgendwie muss es schon
eine "Grundfunktion" geben, damit zielgerichtetes Lernen möglich ist und nicht nur Chaos. Und das bieten die KNNs, mit denen Mustererkennung möglich ist.
Jedes Lebewesen funktioniert so, dass es auf seine Umwelt reagiert, also lernt, wie es mit den Umweltreizen umgeht. Deshalb entwickelt sich das
Projekt "GI" zu einem KNN, wie auch immer das versucht wird. Deshalb überschneiden sich hier auch die Meinungen, über das, was notwendig und sinnvoll ist.
Natürlich ist es bildlich schön gesprochen, dass "GI" auf "Futter" reagieren soll und also ein "Bein" krumm macht. Das ist aber auch nur eine andere Art und Weise,
zu sagen, dass am Eingang eines KNN eine "1" statt einer "0" vorliegt und der Ausgang an Bit#X dann auch aus der "0" eine "1" machen soll.
Gruß
Rumgucker:
Muss ich jetzt verstehen, warum Helmut mir "erschreckende Unkenntnis" vorwirft? Oder darf ich das einfach wegignorieren?
Der Link von Helmut ist ziemlich gut, aber Du darfst es trotzdem wegignorieren. Die zu starke Fokusierung auf die Mathematik und das sogenannte "XOR"-Problem war nämlich die Ursache, dass die KI-Forschung für rund 20 Jahre in den sogenannten "KI-Winter"
https://de.wikipedia.org/wiki/KI-Winter
geschickt wurde, weil die Forschungsmittel massiv gekürzt wurden. Der KI-Winter wurde durch die Erfindung des Back-Propagation-Algorithmus beendet
Ich hab hier stets nur Software hochgeladen, die das jeweils in den Beiträgen und Dumps beschriebene auf einem PIC12F629 tut. Also exakt das fehlerfrei tut, was ich beschrieben hatte.
Es geht mir nicht um die Kritik an Deiner Software, die Wahrscheinlichkeit ist nicht ganz klein, dass die Fehler in meiner Implementierung liegen.
Damit ich mit Dir kommunizieren kann, brauche ich aber eine funktionierende Version. Meiner Meinung nach kostet die Kommunikation mit anderen immer Zeit, aber bringt einem oft auch weiter.
Das Forum ist genau dazu geeignet, Sachen zu diskutieren die dem einzelnen mehr oder weniger klar sind, und gemeinsam Lösungen zu finden, oder auch nur einen nächsten Schritt in Richtung einer Klärung.
Dabei diskutieren oft auch Teilnehmer, die es unterschiedlich gut verstehen, sich an einer solchen Diskussiuon zu beteiligen.
Als Maßstab hierfür kann immer wieder dienen, zwischen der Beurteilung von Argumenten und der Beurteilung von Personen zu trennen. Damit kommt man erst einmal schon recht weit.
Das ist eigentlich gut verständlich, kann aber doch aktuell immer wieder eine Hilfe sein.
Ich habe keine Ahnung, was manf hier mit seinem Orakelspruch sagen will, aber hierzu:
Rumgucker:
Der Link von Helmut ist ziemlich gut, aber Du darfst es trotzdem wegignorieren. Die zu starke Fokusierung auf die Mathematik und das sogenannte "XOR"-Problem war nämlich die Ursache, dass die KI-Forschung für rund 20 Jahre in den sogenannten "KI-Winter"
geschickt wurde, weil die Forschungsmittel massiv gekürzt wurden.
Der KI-Winter wurde durch die Erfindung des Back-Propagation-Algorithmus beendet
Der grundsätzliche Punkt ist:
Jeder beliebige Zustand (oder eine Aussage) von oder in einem natürlichen Gehirn, einem KNN oder sonstwem irgendwo im gesamten Universum lässt sich in der Booleschen Aussagenlogik darstellen, mit TRUE, FALSE, OR, AND, NOT und einer Verknüpfung dieser Basis-Bausteine. Dazu bietet die Boolesche Sprache eine Möglichkeit, diese Logik formalisiert zu beschreiben:
Auch das, was in natürlichen Neuronen oder Gehirnen passiert, was sie tun und wie sie reagieren.
Dabei muss nicht alles nur von einem einzelnen Neuron erledigt werden können, und auch nicht von mehreren in einer einlagigen Schicht.
Weder ein Perzeptron kann z.B. alleine XOR auflösen noch ein natürliches Neuron.
Baut man aber z.B. mehrschichtige Lagen von Perzeptronen oder Nervenzellen, dann können selbst kompliziertere Verknüpfungen wie XOR dargestellt werden, sowohl von natürlichen Neuronen als auch von Perzeptronen.
Ein Mensch kann bei einem Münzwurf mit 2 Münzen erkennen und entscheiden:
wenn beide Münzen Zahl zeigen, tritt Reaktion A ein, ansonsten tritt Reaktion B ein.
Daher ist das menschliche Gehirn in der Lage, AND aufzulösen, denn genau darum handelt es sich hier.
Ein Mensch kann ebenfalls erkennen und entscheiden:
wenn wenigstens 1 der beiden Münzen Zahl zeigt, tritt Reaktion A ein, ansonsten tritt Reaktion B ein.
Daher ist das menschliche Gehirn in der Lage, OR aufzulösen, denn genau darum handelt es sich hier.
Ein Mensch kann ebenfalls erkennen und entscheiden:
wenn beide Münzen auf dieselbe Seite fallen, tritt Reaktion A ein, wenn beide Münzen auf unterschiedliche Seiten fallen, tritt Reaktion B ein.
Daher ist das menschliche Gehirn in der Lage, XOR aufzulösen, denn genau darum handelt es sich hier.
Auch ein künstliches Neuronales Netz kann es, bei AND (oder OR) bereits eine einzelne Zelle, bei XOR z.B. mehrere gemeinsam per Backpropagation oder auch ganz anders, nur XOR eben keine einzelne Zelle allein.
Gleiches gilt in analoger Weise auch für andere Ereignisse, Verknüpfungen oder Reaktionen, auch für noch weit kompliziertere.
Wenn solche Zustände und Reaktionen also gelernt und darauf definiert, in der gelernten Weise, reagiert werden soll, kommt man um eine aussagenlogische Wahrheitstabelle (nichts anderes macht die Boolesche Algebra) nicht herum.
Der grundsätzliche Punkt ist:
Das kann schon sein, aber die Frage ist, ob man sich an einem Problem festbeißen will, stehen bleibt und andere Lösungswege nicht mehr erkennen kann.
So wie es beim XOR Problem damals der Fall war:
XOR-Problem Frank Rosenblatt zeigte, dass ein einfaches Perzeptron mit zwei Eingabewerten und einem einzigen Ausgabeneuron zur Darstellung der einfachen logischen Operatoren AND, OR und NOT genutzt werden kann. Marvin Minsky (https://de.wikipedia.org/wiki/Marvin_Minsky) und Seymour Papert (https://de.wikipedia.org/wiki/Seymour_Papert) wiesen jedoch 1969 nach, dass ein einlagiges Perzeptron den XOR-Operator (https://de.wikipedia.org/wiki/XOR-Verkn%C3%BCpfung) nicht auflösen kann (Problem der linearen Separierbarkeit (https://de.wikipedia.org/wiki/Lineare_Separierbarkeit)). Dies führte zu einem Stillstand in der Forschung der künstlichen neuronalen Netze.
( aus https://de.wikipedia.org/wiki/Perzeptron )
Durch deine Hinweise hast Du Wolfgang in den Gucki-KI-Winter geschickt, was er aber nach zwei Tagen bemerkt hat und deshalb in die innere Emigration geflohen ist ;-)
Durch deine Hinweise hast Du Wolfgang in den Gucki-KI-Winter geschickt, was er aber nach zwei Tagen bemerkt hat und deshalb in die innere Emigration geflohen ist ;-)
nein, das habe ich nicht, das missverstehst du völlig:
Ich habe nur gezeigt, wie bestimmte Zustände oder Reaktionen aussagenlogisch dargestellt werden, und was auch natürliche Zellen und Netze alles können:
Ich habe gezeigt, dass sie z.B. auf UND und ODER zurückgeführt werden können, und dass das sowohl für künstliche wie auch für natürliche Zellen und Netze gilt.
Wolfgang hat ja bestritten, dass ein natürliches Neuron z.B. sowohl UND als auch ODER "kann" (was nicht stimmt, natürlich können sie es!)
- XOR ist zugegebenermaßen komplizierter, das muss als Grundfunktion nicht unbedingt sein, aber die Grundverknüpfungen sind schon elementar, und auch natürliche Gehirne beherrschen es ja (UND und ODER sowieso, aber auch z.B. XOR wie gezeigt).
Wenn Wolfgangs Netz die ersten beiden Beispiele (UND und ODER) erst mal exemplarisch lernen und erkennen kann (siehe Münzwürfe), ist es schon mal sehr gut, und wenn es auch noch das dritte Beispiel lernen kann, um so besser.
(PS, edit: Wolfgang verwendet ja schließlich auch nicht nur eine einzelne Zelle, sondern mehrere miteinander verknüpfte.)
Ich habe keine Ahnung, was manf hier mit seinem Orakelspruch sagen will... naja, ist eigentlich klar: man soll bei manchen beiträgen mehr auf das "was" - also technischer inhalt - gepostet wurde achten, als auf das "wie" :-) - meine kleinschreibung wurde gelegentlich auch schon mal verrissen :-)
Rumgucker
02.12.2019, 09:50
Hallo Forum,
keiner von Euch ist mir auch nur annähernd auf die Füße gestiegen. Ich würde mich dann schon beschweren.
Aber das Forum lenkte mich zu sehr vom Projekt ab, weswegen ich mir ein paar Tage roboternetz-Abstinenz verordnen musste.
Ich hab eine komische Lernstrategie. Bevor ich mir anhöre, was andere wissen, will ich erstmal rausfinden, was ich selbst weiß. Das ist m.E. der einzig mögliche Weg, um ausgelatschte Pfade zu vermeiden, die mich mit hoher Wahrscheinlichkeit nicht zum Ziel bringen. Denn bisher war KI auf einem 12F629 nun mal undenkbar.
Jeder gutgemeinte Link, Hinweis oder Information kann mich - wenn er zum falschen Zeitpunkt kommt - dazu verleiten, die eingetreteten Pfade zu benutzen. Und damit den Projekterfolg gefährden.
Moderne Menschen lernen anders. Die konsumieren erstmal alle Informationen, die sie kriegen können. Sie lesen wochenlang Bücher, sehen Videos, tummeln sich im Internet.
Vielleicht ist diese "moderne" Lernstrategie einer der Gründe, warum Deutschland im Bereich der Innovationen mittlerweile so weit abgeschlagen ist?
Zurück zum Thema.
Ich hab hier mal zusammengeschrieben, wo ich zur Zeit stehe:
34548
Ich werde diese PDF mit Absicht nicht in GitHub hochladen. Ich will mir keine Nachahmer züchten. Die PDF beschreibt einen Milestone. Kein fertiges Projekt.
Viele Grüße
Wolfgang
schön zusammengefasst!
betr.:
#define STUHL_MIT_KATZE STUHL | KATZE,0
#define STUHL_MIT_HUND STUHL | HUND,0
#define STUHL_OHNE_KATZE STUHL , KATZE
#define STUHL_OHNE_HUND STUHL , HUND
#define STUHL_OHNE_TIER STUHL , HUND | KATZE
hier habe ich Logik-Definitions- bzw. Verständnis- Probleme, ich würde das eigentlich so verstehen (Pseudocode):
#define STUHL_MIT_KATZE STUHL AND KATZE
#define STUHL_MIT_HUND STUHL AND HUND
#define STUHL_OHNE_KATZE STUHL AND ((NOT(KATZE))
#define STUHL_OHNE_HUND STUHL AND ((NOT(HUND))
#define STUHL_OHNE_TIER STUHL AND (NOT( HUND OR KATZE))
ARetobor
02.12.2019, 10:43
Hallo Rumgucker,
"Ich will mir keine Nachahmer züchten"
Warum postest Du dann?
Gruß
AR
Rumgucker
02.12.2019, 10:49
Hallo Helmut,
Stuhl, Hund und Katze sind einzelne Bits (s. _BV-Makro).
Stuhl ist 0x01.
Katze ist 0x02.
Hund ist 0x04.
Diese Bits werden miteinander oderiert, um sie an die gi-Prozedur übergeben zu können. Das hat nichts mit irgendwelcher Logik zu tun. Stuhl und Hund ergeben den Übergabewert 0x05.
Schau Dir bitte das gebildete KNN genau an. Da sieht man ganz genau, wie es funktioniert.
Viele Grüße
Wolfgang
- - - Aktualisiert - - -
Hallo Rumgucker,
"Ich will mir keine Nachahmer züchten"
Warum postest Du dann?
Gruß
AR
Hallo AR,
um zu zeigen, wo ich zur Zeit stehe. Es ist ein Milestone. Eine Diskussionsgrundlage. Noch kein ausgereiftes Projekt zum Nachkochen.
Viele Grüße
Wolfgang
ja, jetzt habe ich es gefunden, danke!
schade, dass du keinen Arduino-kompatiblen Code schreibst (Arduino-high-level API-Funktionen, die automatisch auch ARM- und ESP-kompatibel sind), deinen Code verstehe ich im Großen und Ganzen leider nicht und kann ihn auch nicht durchprobieren.
Hallo Rumgucker!
:)
Ich hab eine komische Lernstrategie. Bevor ich mir anhöre, was andere wissen, will ich erstmal rausfinden, was ich selbst weiß.
Dieses Konzept kann ich auch nur empfehlen. Ich pflege es seit Jahrzehnten. Es ist eins der besten Strategien, sich nur mit seinen Dingen und Vorstellungen zu beschäftigen und zielstrebig zu arbeiten. Dazu gehört Fleiß, der nicht abreißen sollte, auch wenn manchmal Pausen gemacht werden müssen. Also Scheuklappen aufsetzen, um, im positiven Sinn, sich konzentrieren zu können und ein Ziel zu erreichen, ist hier angebracht.
Vielleicht ist diese "moderne" Lernstrategie einer der Gründe, warum Deutschland im Bereich der Innovationen mittlerweile so weit abgeschlagen ist?
Da gibt es viele andere Sachen, die manchen nicht so auffallen. Wie z.B. dass sehr erfinderische Menschen, die auf einem Fachgebiet auch praktisch viel können, nicht immer eingestellt werden. Lieber stellt man Menschen ein, die einem scheinbar mehr liegen und von denen man glaubt, sie könnten einen ähnlichen Wissensstand erreichen. So einen Irrtum durfte ich miterleben. Da haben sich dann Leute zusammengefunden, die weder von der Materie das Notwendige, noch von der Durchsetzung, um ans Ziel zu kommen, genug verstanden haben. Ich war dann Jahre Später mal in dieser Firma, um zu sehen, wie weit das Projekt gekommen ist. Das Projekt war gestorben,; das im übrigen darauf beruhte, eine ähnliche Software aufzubauen, wie Amazon sie funktionell, nach außen sichtbar, verwendet. Solche und ähnliche Fälle treten sehr oft und häufig auf, um nicht zu sagen tagtäglich (was dem vermutlich näher kommt). Es wird auch das Potential der nicht offiziell Studierten nicht ausgeschöpft, oft noch nicht mal angezapft.
Ich werde diese PDF mit Absicht nicht in GitHub hochladen. Ich will mir keine Nachahmer züchten.
Diese Entscheidung ist sehr schwer zu treffen, wann es so weit ist, etwas zu veröffentlichen und ob überhaupt. Aber vor dieser Entscheidung steht man irgendwann.
Es ist aber auch der Grund, warum ich am Ende hier meine in Software formulierten Ai-Objekte nicht vorgestellt habe. Zwecks Beispiel wollte ich das tun und hatte es schon fast abgeschickt, dann aber wieder zurückgezogen; eben aus dem Grund, weil diese Objekte in ihrer Entstehung mehrere Jahre Veränderungen durchgemacht haben. Es ist dann einfach, die Quintessenz zu präsentieren, aber auch genau so schwer, die Entscheidung zu treffen, dies zu tun. Weil es natürlich dann einfach von jedermann adaptiert werden kann.
MfG
Rumgucker
02.12.2019, 15:35
Hallo Helmut,
es würde dem Projekt m.E. wesentlich mehr bringen, wenn ich Euch mit meinen zwei kleinen Ideen:
- dynamische "Links" (Dendriten) statt statischer Matrizen
- Addition statt Multiplikation
und vielleicht auch meinem Ansatz zum "überwachten" Lernen (ich überwache da eigentlich gar nichts) irgendwie zum kreativen Mitdenken motivieren könnte.
Zur Zeit bin ich nun mal der am besten im System Eingearbeitete. Ich kenn das kleine GI-Mistding in- und auswendig. Es wäre von daher eigentlich nur logisch, dass ich zur Zeit weiterhin implementiere, teste und dokumentiere und Ihr Eure Expertise beisteuert.
Sobald alle dann abnicken und zufriden sind, sollten wir gemeinsam die Umsetzung auf andere Zielsysteme durchführen.
So wäre zumindest mein Vorschlag....
------------
Hallo Moppi,
natürlich sollen das System alle bekommen. Dann lade ichs auch bei GitHub hoch. Das will ich nicht für mich behalten. Sowas brauch ich genauso wenig wie eine Feldmessung *ggg*.
Aber zuerst mal muss es so ausgestaltet werden, dass alle hier ansässigen Koryphäen abnicken und mir glaubhaft versichern, dass ich mich damit nicht zu schämen brauche.
Meine Scheuklappen haben Vorteile. Aber sie haben auch den großen Nachteil, dass ich nie so ganz genau weiß, wo ich eigentlich stehe. Ist Helmut so verhältnismäßig sprachlos, weil er sich schallend lachend unter seinem Arbeitstisch wälzt oder weil ich ein KI-Messias bin, wie stochri glaubt?
Wir werden es rausfinden....
Viele Grüße
Wolfgang
es würde dem Projekt m.E. wesentlich mehr bringen, wenn ich Euch mit meinen zwei kleinen Ideen:
- dynamische "Links" (Dendriten) statt statischer Matrizen
- Addition statt Multiplikation
und vielleicht auch meinem Ansatz zum "überwachten" Lernen (ich überwache da eigentlich gar nichts) irgendwie zum kreativen Mitdenken motivieren könnte.
mir ist dein Konzept noch zu unklar, um mich beteiligen zu können -
Lesbarer Arduino-Code wäre fürs Verständnis evt ein erster Schritt...
Rumgucker
02.12.2019, 16:27
Hallo Helmut,
weiß ich doch. ;) Ich wollte nur ein Späßchen versuchen.
Die Portierung steht auf der Liste. Nicht Arduino. Aber zumindest Atmel Tiny85. Das geht schon mal in die gewünschte Richtung.
-------------
Hallo Forum,
ich möchte heute das XOR-Problem angehen. Hier im Thread teilen ja mittlerweile schon einige meine Bedenken bzgl. der fehlenden linearen Separierbarkeit.
Viele Grüße
Wolfgang
soweit nur Standarddatentypen (stdint) und keine spezifischen AVR-Flash- oder Registeroperationen verwendet werden, wäre das evt. ausreichend. Arduino verwendet ja normales C++14, ISO C99 kann da weitgehend als Untermenge durchgehen 8)
Meine Scheuklappen haben Vorteile. Aber sie haben auch den großen Nachteil, dass ich nie so ganz genau weiß, wo ich eigentlich stehe.
Zu Anfang habe ich auch mal so gedacht. Allerdings hat sich im Laufe der letzten 20 Jahre dann was anderes herausgestellt.
"dass ich nie so ganz genau weiß, wo ich eigentlich stehe" - das ist kein Nachteil, sondern ein riesen Vorteil!
Wenn Du mit Deiner Sache fertig bist, dann kannst Du noch immer vergleichen. Aber das Vergleichen raubt Energie, den Biss, den Du brauchst, um schnell voranzukommen. Beschäftige Dich nicht mit anderen Dingen und dem, was andere Menschen tun, sondern bündele Deine ganze Energie auf Dein Vorhaben!
Falls Du es noch nicht gesehen hast und es Dich interessiert, ich hatte etwas von 2015/2016 ausgegraben: jetzt können Computer auch denken (https://www.ingenieur.de/technik/fachbereiche/mikroelektronik/jetzt-koennen-computer-denken/)
MfG
:Weihnacht
Rumgucker
03.12.2019, 07:53
Moin Forum,
ich hab mir eben nochmal die letzten Beiträge im Thread durchgelesen.
Helmut scheint den Unterschied zwischen natürlichen Denkprozessen und mathematischen Lösungen unverändert nicht zu erkennen. Er hatte offensichtlich überhaupt nicht begriffen, was ich bzgl. der "Logik der Natur" geschrieben hatte. Und damit natürlich auch nicht das XOR-Problem.
Natürlich kann man es mit "unnatürlichen" Mitteln lösen. Natürlich kann ich mir ein paar Gatter ins Hirn implementieren lassen. Natürlich kann ich hinter mir einen Lehrer aufstellen, der so lange auf mich einprügelt, bis seine "backpropagation" irgendeine Wirkung zeigt.
Aber so funktioniert doch keiner von uns. Boolsche Algebra und backpropagation haben überhaupt nichts mit natürlichem Denken zu tun. Es ist nicht so banal, wie Helmut sich das so ausdenkt. Das Thema geht wesentlich tiefer. Stochri hats richtig erfasst.
Man kann allerdings darüber diskutieren, ob die XOR-Aufgabe "natürlich" ist.
Es gibt mehrere Aufgaben, die "unnatürlich" sind. Die einfache Negation halte ich für unnatürlich. Negation ist nur in Zusammenhang mit einem AND vorstellbar.
"Da lag immer ne Katze auf dem Stuhl. Nun fehlt die Katze.". Aber wenn ich erstmals im Leben diesen leeren Stuhl sehe, dann fällt mir natürlich die fehlende Katze nicht auf. Eine Operation "not(KATZE)" ist also Humbug. Sinnvoll ist aber "STUHL and not(KATZE)".
Wobei man auch dabei noch diskutieren müsste, ob es nicht auf die Delta-Werte ankommt.
Und weiterhin hatte ich ja auch geschrieben, dass ein AND instabil ist. Es kann jederzeit zum OR mutieren, wie uns der pawlowsche Hund vor Augen führt.
---------
Dass Helmut vorgibt, das alles nicht zu verstehen, ist etwas enttäuschend. Ich bin noch nicht mal vier Wochen mit dem Thema befasst und ich hab zunehmend das Gefühl, dass Helmut mir wohl keine große Stütze sein wird.
Stochris Info, dass ich mich um das XOR-Problem nicht wirklich zu kümmern brauch, ist da deutlich hilfreicher. Er impliziert dann aber gleich das backpropagation. Ich hätte also sozusagen die Wahl zwischen Teufel und Belzebub.
Auch nicht zufriedenstellend....
BTW: das XOR-Problem ist natürlich per GI-System "lösbar":
loop = 20; do {
gi(FIRST_NEURON,AKT_0);
gi(FIRST_NEURON + 1,AKT_0);
} while(--loop);
loop = 20; do {
gi(A_notB,FIRST_NEURON);
gi(B_notA,FIRST_NEURON + 1);
} while(--loop);
Ich würde das mal "Handverdrahtung" der boolschen Algebra nennen. Die gewaltsame Einrichtung eines hidden-layers. Ich schreib dem Wesen praktisch vor, mit welchen Zellen es zu denken hat. Lächerlich.
KI hat in meinen Augen was mit "deep thinking" des KI-Entwicklers zu tun. "deep learning" ist Dampframmen-Technik. Man bestraft seinen KI-Schützling, weil man selbst zu doof ist, ihm vernünftiges Lernen beizubringen. Und Boolsche Algebra gibts im Hirn überhaupt nicht.
Ich zieh mich mal wieder ein paar Tage zurück. In einer Woche melde ich mich wieder. Es wird dem Projekt mehr bringen, als wenn ich hier rumlabere und eh kaum verstanden werde.
Viele Grüße
Wolfgang
ich denke, was du nicht verstehst, ist: dass Boolsche Algebra nur Aussagen beschreibbar macht, in dem es sie auf die Standard-Verknüpfungen zurückführt.
Weder das menschliche Gehirn noch BP-Netze verwenden sie direkt (sie modulieren nur die Muster durch eine Vielzahl von Justierungen), aber das, was sie erkennen können und worauf sie wie reagieren, ist durch die BA als Lernmuster definier- und beschreibbar.
Auch mit der Negation irrst du (wieder mal), in natürlichen Gehirnen gibt es alles das, wovon du behautest, es gäbe es nicht, inkl. OR, AND-, NOR- und NOT-Konstrukten (z.B. über IPSPs neben EPSPs und deren Neuronen-Vernetzung).
Ich frage mich ensthaft, wie jemand, der so wenig von den Grundlagen kennt und versteht, sich zu solchen Äußerungen wie den deinigen hinreißen lassen kann (und dabei noch selber immer wieder betont, davon auch nichts verstehen zu wollen, damit "der Kopf frei" bliebe (vlt frei, aber man könnte vermuten: auch leer ;) )) -
Aber vlt kommst du ja noch mit der Zeit selber dahinter, also mach mal...
Der TO hat vor ein Projekt zu beschreiben das nicht den Vorstellungen von allen anderen entspricht, das ist Sinn eines solchen Forums und kein Anlass zu persönlichen Herabsetzungen.
Vorschläge und sachliche Kritik ist in einem offenen Forum willkommen, persönliche Angriffe sind völlig unangebracht. Es tut mir Leid, dass die Diskussion wieder eine Form erreicht, die so hier nicht weitergführt werden kann.
Ich muss deshalb noch einmal darum bitten, persönliche Auseinandersetzungen zu unterlassen.
Ich galube, du überspannst jetzt hier den Bogen gewaltig, Manf -
W. hat mich und meine Posts persönlich angesprochen und auch falsch und sinnentstellend zitiert, und es muss mir erlaubt sein, die unsinnigen falschen Behauptungen, die er über mich und meine Posts geschrieben hat, als unsinnig aufzuzeigen, richtig zu stellen und zu widerlegen.
Ich habe mit keinem Wort sein Projekt kritisiert, denn ich verstehe ich es schlichtweg nicht
- und von "Beleidigung" kann ebenso wenig die Rede sein: ein Kopf, der nach eigener Aussage frei von Grundlagen ist, ist nun mal frei davon, also diesbezüglich leer, und das war darüberhinus deutlich erkennbar als rhetorische Überspitzung formuliert.
@Wolfgang:
bitte unterlasse es künftig einfach, auf mich und meine Statements Bezug zu nehmen, dann ersparst du mir die Mühe, darauf zu antworten.
Ein eigenes Projekt, was im Detail so kompliziert ist, sollte man allein erarbeiten. Es macht aus verschiedenen Gründen (einige tauchen hier bereits auf) keinen Sinn, das mit der Allgemeinheit zu besprechen. Forschungsteams besprechen sich untereinander - ja, aber auch nicht mit beliebigen Außenstehenden. Wenn ich kein Team habe, muss ich das alles alleine durchziehen. Und dann ist es wirklich am besten, nicht links und nicht rechts zu gucken, was andere machen oder für eine Meinung haben. Man wird zu stark abgelenkt und demotiviert. Ein kompliziertes Projekt anzugehen, von dem ich noch nicht weiß, wohin es mich führen wird, aber ein Ziel vor Augen zu haben, wo noch unklar ist, wie ich es erreichen soll, kostet viel Mühe und Durchhaltevermögen. Man muss einfach selbst sehen, dass man sich alleine durchwurschtelt, man muss nur an seine Idee und sein Ziel glauben. Eine andere Möglichkeit ist, sich ein Team zusammen zu suchen, wo man denkt, dass man mit den Menschen zusammenarbeiten kann. Nach meiner Erfahrung macht dies im Privatsektor aber auch nur wenig bzw. bedingt Sinn, schon allein deswegen, weil die Privatteams nicht lang genug durchhalten.
MfG
Rumgucker
04.12.2019, 05:39
Moin Forum,
das mit dem XOR ging schnell. Ich hatte mit einer Woche gerechnet. Aber ich werde voraussichtlich noch heute "liefern".
Es wundert mich sehr, dass sich die Altvorderen so lange an dem Detail aufgehalten haben. Und schließlich sogar diese backpropagation-Prügelei entwickelten. Man schlägt sozusagen auf das Kind ein, bis es die Lektion gelernt hat. Übel.
Man muss zwei "natürliche" Dinge berücksichtigen und die Lösung liegt sofort vor einem:
Es gibt kein isoliertes NOT. NOT gibts in der Natur nur als Weglassung, also in Verbindungen. Ich sehe einen Stuhl mit Katze. Und plötzlich ist die Katze weg. DAS fällt mir auf.
Ich muss mit dem GI-System wie mit einem Lebewesen umgehen. Ich muss ihm erst den Normalzustand zeigen. Und dann das, worüber es eigentlich stolpern soll:
Zuerst zeige ich ihm zwei Karten: gi(A_B,AKT_0);
Und dann nehm ich eine Karte weg: gi(A_notB,AKT_0);
Dann zeig ich ihm wieder zwei Karten: gi(A_B,AKT_0);
Und dann nehm ich eine Karte weg: gi(B_notA,AKT_0);
Und das wiederhole ich ein paar Mal. Genauso würde man auch die Aufmerksamkeit eines Kindes fesseln!
--------
Die zweite natürliche Sache betrifft den Schwellwert im Perzeptron.
Wenn man dauernd auf eine Stelle auf dem Arm drückt, merkt man den Druck nur am Anfang. Nach einiger Zeit verschwindet aber das Druckgefühl. Da wird in der Natur also irgendwas an der Aktivierungsfunktion rumgestellt. Wird ja auch im KI-Bereich gemacht.
Meine Idee ist noch einfacher, weil ich asymmetrische Perzeptronen nutze. Ich definiere einfach einen Bereich, in dem das Neuron feuert. Unterhalb und oberhalb dieses Bereiches feuert es nicht.
Also hab ich kurzerhand meine Aktivierungsfunktion umgeschrieben
if(RD_SUM >= FIRE) FIRE_REQ = TRUE; // V0.00
if(RD_SUM == FIRE) FIRE_REQ = TRUE; // V0.01
Und siehe da: das XOR-Problem wird nun gelöst. Mit einem einzigen Neuron!!!
Wie kommt das?
Die Karte A und die Karte B bekommen bei o.a. Lernen automatisch jeweils den Nutzen "7". Die Karte notA und die Karte notB bekommen jeweils den Nutzen "3".
Nach dem Lernen kann man dem System vier Kombinationen zeigen (die Zelle feuert genau bei "10").
A plus B = 14, also kein Feuern
notA plus notB = 6, also kein Feuern
A plus notB = 10, also Feuern
B plus notA = 10, also Feuern
Also XOR gelöst. Einfach, natürlich und elegant und ganz ohne Schläge.
----------
Wir dürfen den Pfad der Tugend nicht verlassen. Wir müssen uns immer wieder zur Disziplin aufrufen.
Wenn ein Problem mit dem GI-System nicht lösbar erscheint, dann kann es einfach daran liegen, dass wir das Problem in einer Weise darstellen, dass das auch kein Kleinkind bewältigen lönnte. In der o.a. Form kann jedoch auch ein Kleinkind das XOR-Problem verstehen.
Erweiterte Doku kommt noch heute, wenn nichts dazwischen kommt.
Bis später
Wolfgang
Rumgucker
04.12.2019, 09:14
Hallo,
kurz und schmerzlos anbei die Doku mit XOR-Milestone:
34549
Ich melde mich, wenns was neues aus meinem stillen Kämmerlein gibt.
Viele Grüße
Wolfgang
Rumgucker
04.12.2019, 18:11
Hallo Moppi,
Ein kompliziertes Projekt anzugehen, von dem ich noch nicht weiß, wohin es mich führen wird, aber ein Ziel vor Augen zu haben, ...
in der ersten Stufe soll GI auf vorgegebene Umweltsituationen in vorgegebener Weise seine Aktoren steuern. Also schnelle Reflexe mit einschichtiger Verarbeitung. Reflexe werden einfach per überwachtem Lernen trainiert, dann mit FREEZE eingefroren und per EEPROM vererbt. Alles genau wie in der Doku gezeigt.
In der zweiten Stufe gehts um Umwelterkennung. Praktisch der gleiche Mechanismus wie zuvor, jedoch mit Neuronen und nicht Aktoren als Ziel. Auch hier kann wieder das überwachte Lernen genutzt werden. Man zeigt dem System, wie Futter aussieht. Diesen Teil hab ich gerade eben abgeschlossen.
In der dritten Stufe gehts um Umweltverstehen. Nun soll das System ohne Lehrer an seinen Ausgängen so lange rumfuddeln, bis es Futter am Eingang sieht. Zwischen Ausgang und Eingang befindet sich die Umwelt. Meine ersten "es-lebt"-Versuche haben angedeutet, wie sich die dritte Stufe anfühlen könnte.
Und dann ist die Kiste fertig. Dann beginnen philosophische Fragen. Ist es Mord, wenn ich dem System den Strom wegnehme? Warum ist es kein Mord? Was unterscheidet "echtes" Leben von dem GI-Leben? Darf ich die Aktoren mit Vorrichtungen zu seiner eigenen Selbstverteidigung verbinden? Werde ich die Geister wieder los, die ich rief?
Die 30 Byte RAM und 20 Zeilen Source-Kern werden uns noch schwer ins Grübeln bringen.
Optimal für die dunkle Jahreszeit geeignet...
Viele Grüße
Wolfgang
- - - Aktualisiert - - -
Hallo Manfred,
Der TO hat vor ein Projekt zu beschreiben das nicht den Vorstellungen von allen anderen entspricht, das ist Sinn eines solchen Forums....
mir gefällt dieses Forum ganz außergewöhnlich gut. Nicht so ein weichgespültes Wattebausch-Höflichkeitsfloskel-Ding und auch nicht so ein Rabauken-Forum unerzogener pubertärer Jungs. Hier ist es richtig muckelig.
Ich persönlich hab auch Null Problemo damit, wenn mich jemand mal anfaucht.
Es ist nur etwas schade, dass ich - für meine Verhältnisse - hier noch so zurückhaltend bin. Normalerweise bin ich sozusagen die geborene Foren-Rampensau. Aber dieses KI-Projekt ist im Moment extrem faszinierend und fordert meine ganze Konzentration. Ich träum schon davon.
Dass ich mich überhaupt für KI interessiere, liegt einzig und allein an Helmut. Dafür bin ich Helmut sehr dankbar. Seine Sourcen waren sehr aufschlussreich. Nach deren Sichtung war mir klar, dass das so niemals auf einem PIC 12F629 laufen kann. Helmuts Sourcen öffneten mir sozusagen die Augen.
Also wie gesagt: für mich ist hier alles unverändert höchst angenehm. Kein Paradies. Aber besser als 99% aller Foren, die ich bisher kennengelernt hatte.
Viele Grüße
Wolfgang
A propos Rampensau, es ist ein ziemlicher Spagat das Verhalten einzelner hier im Forum auf die Ebene Verwarnung herunterzudrücken und es kostet immer mehr Aufwand. Ich werde nicht immer Zeit dazu haben, weitere Schritte zurückzuhalten.
Schön finde ich, wenn man es versteht, seine Meinung klar und deutlich auszudrücken. Peinich ist es, wenn es einem nicht gelingt, persönliche Beleidigungen dabei zu vermeiden. Es ist dann so etwas wie eine Behinderung für die man niemanden anklagen möchte, nur muss man gleichzeitig ein gewisses Niveau halten.
Ich freue mich, wenn ich in diesem Sinn weiter auf Dich zählen kann und vielleicht kannst Du ja auch ein wenig mithelfen, dass die gröbsten Entgleisungen schon im Vorfeld gebremst werden, indem Du in auf professionelle Weise auf die entsprecheden Statements Bezug nimmst.
Rumgucker
04.12.2019, 20:39
Hallo Manfred,
professionell muss ich im Beruf sein. Für mich ist das hier ein reines Freizeit- und Hobby-Forum, in dem ich ausdrücklich ohne professionellen Anspruch unterwegs bin.
Zusätzlich bin ich erst seit gut drei Wochen hobbymäßig mit der KI befasst. Da kann ich gar nicht in professioneller Weise auf Statements eingehen. Ich bin noch Lehrling.Ich kann mir die Weisheit doch nicht in Nullzeit aus den Rippen schneiden. Nach 10 Jahren Beschäftigung mit dem Thema mag das ja vielleicht anders aussehen.
Ich kann Dir lediglich zusichern, dass Du auch weiterhin kein böses oder unhöfliches Wort von mir lesen wirst.
Viele Grüße
Wolfgang
Ja, klar. - Ich habe nur oft die Vorstellung, dass viele hier schon erfahren sind im sozialen Umgang, aus ihrem professionellen Hintergrund, aber ein Anspruch sollte es nicht sein, ich hatte deshalb die Ergänzungen vielleicht und ein wenig eingefügt.
Rumgucker
05.12.2019, 05:13
Moin Manfred,
nun muss ich mal etwas strenger auftreten.
Querdenker wie ich stehen immer mit einem Bein auf dem Scheiterhaufen.
Wenn ich sage, dass es in der Natur kein isoliertes NOT gibt (wenn ich eine Mauer zum ersten Mal sehe, dann wird mir nicht auffallen, dass da sonst immer eine tote Katze drauf lag) und auch das UND in der Natur zum ODER mutiert (pawlowscher Hund, s. Wikipedia) und ich sage, dass das XOR in der Natur eben keine einfache boolsche Algebra ist und dass die boolsche Algebra überhaupt nichts im Hirn zu suchen hat, dann gehe ich für diese querdenkerischen Ansichten, die ich mittlerweile alle belegt habe, gerne auf den Scheiterhaufen!
Ich kann nichts dafür, dass sich der hiesige Klerus von diesen Tatsachen provoziert fühlt und weise daran jede Mitverantwortung entschieden von mir.
Aber es freut mich sehr, dass meine Aussagen zur Aufregung geführt haben. Es scheint also kein kalter Kaffee zu sein, den ich dem Klerus eingeschenkt hab.
Gleiches gilt für meine "provokanten" Aussagen, dass Musterererkennung ebensolcher Kinderkram ist, wie Reflexe. Aus reiner Nettigkeit hab ich Reflexe und Mustererkennung zusammen mit intelligentem Verstehen zur "generischen" Intelligenz aufgewertet. Meine persönliche Meinung ist aber, dass Intelligenz erst mit dem Umweltverstehen beginnt. Was hier im Forum vom Klerus also als KI bezeichnet und gefeiert wird, ist in meinen Augen ein Dekoder mit Unschärfen. Eine Art Fuzzy-Logik einer Waschmaschine.
Und um die Banalität zu verdeutlichen, hab ich den gesamten funktionalen KI-Teil auf 20 Source-Zeilen eingedampft. Hätte ich einen anständigen Compiler verwendet, wäre der Code auf 10 Zeilen geschrumpft. Hier im Forum wird vom Klerus also eine Riesen-Welle um ein paar wenige Zeilen Code gemacht. Die dann - trotz meiner ausführlichen Doku - prompt nicht verstanden werden. Albern.
Aber um diesen ganzen "Provokationen" noch die Krone aufzusetzen, konnte ich auch noch am gelösten XOR-Problem nachweisen, dass der Klerus seinen eigenen Code nicht versteht. Ein "natürliches" kindgerechtes Lernen vermeidet backpropagation und löst das XOR-Problem mit einem einzigen Neuron.
So weit bin ich zur Zeit.
Und Manfred.... ich habe absolut nicht vor, meine Ketzerei und Blasphemie in irgendeiner Weise einzuschränken. Ganz im Gegenteil. Ich lerne täglich dazu. Ich werde weitere Tatsachen erkennen, die nun einmal Tatsachen sind.
Wenn Querdenker, Blasphemiker und Ketzer hier unerwünscht sind, weil es den Klerus "provoziert", so werden das Forum und ich nicht zusammenkommen. Dann genügt eine simple Kurznachricht von Dir: "Wolfgang... misch bitte ein anderes Forum auf - wir wollen hier nur unsere Ruhe". Oder schließ einfach den GI-Thread wegen Blasphemie - dann verlass ich das Forum auch.
Ansonsten arbeite ich in diesem Thread weiter wie gehabt. Und ich werde weitere Tatsachen entdecken. Und ich werde sie weiter benennen. Denn ich bin kein Diplomat sondern fühle mich allein der Wissenschaft verpflichtet. Die Erde dreht sich um die Sonne. Derartige Tatsachen werde ich weiterhin unverblümt aussprechen und nicht mit einem "vielleicht" oder "ein wenig" relativieren, damit der Klerus sich nicht aufregt.
Viele Grüße
Wolfgang
Es ist sicher ein richtiger Weg zum Verständnis eines Systems, es auf die Grundprinzipien und auf elementare Fälle zurückzuführen. Da kann ich nur zustimmen.
dass es in der Natur kein isoliertes NOT gibt
Selbstverständlich machen alleinstehende Operatoren keinen Sinn, denn sie haben alleinstehend keinen Wahrheitswert:
alle Operatoren beziehen sich immer auf Elemente bzw. Ereignisse und bilden erst dadurch einen Wahrheitswert ab.
Genausowenig wie es ein "isoliertes NOT" gibt, gibt es ein "isoliertes AND" oder ein "isoliertes OR".
(Anm.: NOT ist eine unäre, AND und OR sind binäre Verknüpfungen)
sag Mal HaWe, warum aktualisiert du grundsätzlich 2x deine Posts? Der Sinn erschließt sich mir irgendwie nicht...
Rumgucker
06.12.2019, 15:27
Hallo,
ich werde bei dem Projekt noch zum Pädagogen.
"Selbständiges Lernen" ist ein Oberbegriff für "selbstgesteuertes Lernen" (z.B. Regelkreis) und "autonomes Lernen" (z.B. Umweltverstehen durch Spiel).
Also erstmal ran an das selbstgesteuerte Lernen.
Gänzlich unpädagogisch hab ich einen Regelkreis aus GI-System und Umwelt gebildet. Das GI-System steuert also die Umwelt. Der Ausgang der Umwelt wird mit einem programmierten XOR mit einem Solwert verglichen und somit erhält das GI-System nur die Fehlergröße. Also eigentlich ein backpropagation, wie es im Buche steht. Nur eben mit dem Unterschied, dass hier die Umwelt im Regelkreis liegt.
Dann hab ich alle GI-Bremsen gelöst und mich irrwitzig gefreut, dass das System die Umwelt so lange beeinflusst, bis Soll- und Istwert übereinstimmen. Ohne eine einzige Zeile Codeänderung an den 20 Kernzeilen. Sobald ich die Umwelt ändere, dreht er wieder an seinen Ausgängen herum, bis er wieder den Zustand des minimalen Fehlers erreicht hat. Mit nur 16 Links hat er drei Umwelten gelernt, ohne dass ich ihm irgendwelche Zellen vorgeschrieben hab. Die Neuronen haben sich auch ganz von alleine mit den Aktoren verbunden. Faszinierende Technik.
Das fühlt sich extrem richtig an.
Allerdings muss ich jetzt schon von "fühlen" sprechen. Denn mit 16 Links hat das GI-System nun eine Komplexität erreicht, die ich eigentlich nur noch per blackbox-Methode überschauen kann. Aber 16 Links für 3 komplette Umwelten deuten auf effizienten Umgang mit den Ressourcen hin.
Allerdings bin ich nicht ganz zufrieden!
Zur Zeit bilde ich per hard-programmierter XOR-Funktion die Fehlergröße. Das ist kybernetisch korrekt aber nicht natürlich. Ich hätte es lieber, wenn ich dem System nur das Soll und das jeweilige Ist zeige und es alle weiteren Dinge automatisch macht.
Mir ist aber noch kein kluges Regelkreis-Lernprogramm eingefallen. Daran werde ich noch etwas zu knabbern haben.
Sobald das Problem gelöst ist, gibts die nächste Doku-Version mit "selbstgesteuertem Lernen". Bis Montag hab ich mir zum Ziel gesetzt.
Viele Grüße
Wolfgang
zur Nomenklatur: https://de.wikipedia.org/wiki/Maschinelles_Lernen#Algorithmische_Ans%C3%A4tze
Rumgucker
07.12.2019, 05:51
Moin Helmut,
vielen Dank. Allerdings führt Dein vorgeschlagnes KI-Sprech automatisch zur KI-Denke und damit zu strunzdummen Mustererkennungsautomaten.
--------
Beim GI-System versuche ich den natürlichen Weg. Ich hab das vielfach betont. Biologie, Pädagogik und Co. müssen daher meine Quellen sein.
Das gelöste XOR-Problem hat mir restlos deutlich gemacht, dass wir unsere Perzeptron-Maschinen nur falsch unterrichten. Wenn man sie wie Maschinen unterrichtet, verhalten sie sich wie Maschinen. Wenn man sie jedoch wie Lebewesen unterrichtet, verhalten sie sich wie Lebewesen.
Wir müssen nicht an den Perzeptrons rumfummeln. Wir müssen an unserer Denkweise rumfummeln. Sonst werden wir nie intelligente Maschinen bauen können.
Viele Grüße
Wolfgang
ein Apfel ist ein Apfel und ein Rad ist ein Rad, und wenn man den Apfel "Birne" nennt, die Radachse "Pedal" und den Reifen "Sattel", führt das nur zur Begriffsverwirrung. Ich würde bei den etablierten Begriffen bleiben, denn dann wird man auch verstanden.
oberallgeier
07.12.2019, 09:19
.. Wir müssen an unserer Denkweise rumfummeln. Sonst werden wir nie intelligente Maschinen bauen können ..An unserer Denkweise ? Die ist(wird) doch vielfach/meist in einem frühen Lebensabschnitt festgelegt (siehe Fichte, Die Bestimmung des Menschen (http://www.zeno.org/Philosophie/M/Fichte,+Johann+Gottlieb/Die+Bestimmung+des+Menschen/Erstes+Buch.+Zweifel), Erstes Buch, vierter Absatz ff) - weitgehend ohne unseren bewussten Einfluss (Link vorher).
Du meinst wohl wir müssten an der Denkweise unserer Maschinen fummeln.? Ahhh - ich habs - wir müssen an unserer Denkweise über die Denkweise unserer Maschinen rumfummeln.
Rumgucker
07.12.2019, 12:43
Hallo, Ihr zwei,
wenn man Computer programmieren will, muss man eine Computer-Programmiersprache verwenden. Nach einigen Jahren der Benutzung denkt man sogar in der Sprache.
Wenn man einem KI-System intelligentes Verhalten beibringen will, muss man ebenso eine geeignete Sprache nutzen. Ich beginne gerade, diese Sprache und Denkweise zu lernen.
Das XOR-Problem im KI-System führt bei mathematischer Denkweise zu einem zweischichtigen Perzeptron-Netzwerk, das erst mit backpropagation beherrschbar ist.
Sobald man jedoch den Lernprozess etwas natürlicher gestaltet, benötigt man weder zwei Schichten noch backpropagation. Plötzlich zerfällt das viele Jahre lang als "unlösbar" bezeichnete XOR-Problem vor unseren Augen zur Trivialität. Ich hab das in der letzten Doku und in dem Beitrag direkt vor der letzten Doku ausführlich erklärt.
Siehe #101 und #102
Allein die geänderte Nomenklatur brachte eine geänderte Denkweise und die führte zu einem direkten Lösungsweg. Ich könnte jetzt auf jedem Perzeptron-Netz das XOR-Problem mit einem einzigen Neuron lösen, ohne die Backproagation-Keule oder eine zweite Schicht zu bemühen.
Eine geänderte Denkweise und Nomenklatur führt - nachweislich - zu neuen Lösungen.
Es hat mich sehr gewundert, dass es hier keinerlei Echo dazu gab. Ich ging daher davon aus, dass die Lösung des XOR-Problems für Euch kalter Kaffee war.
Im Moment scheint es mir aber eher so, dass die Evidenz nicht verstanden wurde.
Viele Grüße
Wolfgang
also ich persönlich kenne das Thema XOR bereits seit 10 Jahren, seit meinem ersten selber geschriebenen KNN, und es funktioniert perfekt, einfach durch Anlernen von Mustern, ohne irgendwelche fest vorprogrammatierte OR/AND/NOT Operatoren, nämlich per Überwachtem Lernen von Input-Output-Musterpaaren. Du wirst mir also nicht unterstellen können, ich habe die Problematik nicht verstanden. Allerdings habe ich auch weder ein nachvollziehbares, funktionierenes Programm von dir bisher gesehen noch auch verstanden, das stimmt ntl soweit.
oberallgeier
07.12.2019, 16:43
.. Im Moment scheint es mir aber eher so, dass die Evidenz nicht verstanden wurde ..Bei mir ist das wohl so, leider. Ich lese hier mit und versuche das nachzu-denken. Hätte besser auch keinen Beitrag gegeben weil dieses für mich ein ".. möcht ich auch wissen/können/kennen .." ist. Ich werde mich zurückhalten.
Rumgucker
07.12.2019, 17:15
Hallo Helmut,
mehr als die Doku inkl. den vollständigen Sourcen für den CC5X und 12F629 gibts von mir zur Zeit nicht. Erst wenn ich das Projekt abgeschlossen hab, gibts eine Konvertierung auf Tiny85.
Dass man mit backpropagation erfolgreich XOR lernen kann, hatte ich stets betont. Backpropagation wurde zu Zeiten entwickelt, als man seine Schutzbefohlenen noch verprügelte, damit sie was anständiges lernen. In meinen Augen anachronistisch. Die Effektivität bleibt auf der Strecke: Man verbraucht viele Neuronen und benötigt lange Lernzyklen.
Intelligente Systeme benötigen intelligente Lernverfahren.
---------
Hallo oberallgeier,
ich nahm irrtümlich an, dass Du Dich über meine unbeholfene Ausdrucksweise lustig machtest.
Bitte entschuldige. Und nun sei nicht gleich eingeschüchtert!
Bei Interesse erklär ich das XOR-Problem und meine Lösung noch mal ganz einfach. Du wirst Dich schlapp lachen. Und es nützt auch anderen, die die Tragweite offensichtlich auch nicht erkannt haben.
---------
Weiter im Text:
Da über die Umwelt nichts bekannt ist, hab ich beim selbstgesteuerten Lernen einfach die trial & error-Methode angewendet. Ein Lehrer beendet den Lernvorgang, wenn die Umwelt das gesuchte Bitmuster ausgibt. Wie das GI-System lernt, ist ihm allein vorbehalten. Ich mach dem System keinerlei Vorgaben.
Trial & error empfinde ich "natürlich". Vieles im GI-System ist nach dieser Methode von mir entwickelt worden. Zwar ist T&E nicht ganz so elegant, wie ichs mir fürs selbstgesteuerte Lernen gewünscht hab. Aber zulässig.
Doku gibts also schon morgen.
Danach fehlt dann nur noch das autonome Lernen. Dann gibt es auch keinen Lehrer mehr, der sagt, wenn das Lernziel erreicht wurde. Dieses Detail halte ich aber für sehr trivial.
Ich denke, bis spätestens Mitte nächster Woche bin ich mit dem gröbsten durch. Dann konvertier ich das noch kurz auf den Tiny85 und dann könnt Ihr losspielen. Source, Doku und gut getestete Anwendungsbeispiele. Das ist ne vernünftige Basis, finde ich.
Viele Grüße
Wolfgang
----------
Nachtrag: hab mir gerade den allerersten Beitrag in diesem Thread nochmal durchgelesen. Am 9.11. war der. Ich bin nicht ganz unstolz.
oberallgeier
07.12.2019, 17:43
.. ich nahm irrtümlich an, dass Du Dich über meine unbeholfene Ausdrucksweise lustig machtest ..Nein - bloß nicht. Im Gegenteil - ich finde Deine Aussagen, schrittweises vorgehen und Folgerungen hoch interessant. Hatte eben nur anmerken wollen(müssen), dass unsere Basisprogrammierung (die das Menschen) weitgehend ohne bewusstem Einfluss erfolgt und "hinterher", nach Eintreten von ordentlichem Schluss-folgern-Können, nur sehr mühevoll umgangen oder gar abgeändert werden kann. Bei mir jedenfalls. Und bei Fichte offenbar auch.
Rumgucker
07.12.2019, 19:19
Hallo oberallgeier, hallo Mitlesende,
ich versuch jetzt aber trotzdem mal, das XOR-Problem verständlich rüberzubringen.
Sowohl Helmuts als auch mein System besteht aus Zellen. Diese Zellen haben mehrere Eingänge. Jeder aktivierte Eingang erhöht in der Zelle einen Summenzähler. Sobald dieser Zähler eine Schwelle erreicht hat, feuert die Zelle.
Er und ich haben unseren Eingängen Zahlenwerte zugeordnet. Eine Zelle mit zwei Eingängen A und B kann zum Beispiel für jeden Eingang den Zahlenwert "5" zugeordnet haben. Die Zelle soll beim Summenzähler "10" feuern.
Wenn nur der Eingang A aktiv ist, wird der Summenzähler nur den Wert "5" erreichen und die Zelle feuert nicht. Auch wenn nur der Eingang B aktiv ist, bleibt der Summenzähler der Zelle auf "5". Die Zelle kann nur feuern, wenn Eingang A UND Eingang B aktiv sind, denn dann werden die beiden "5" eines jeden Eingangs zu "10" addiert. Das Neuron bildet also ein UND-Gatter mit zwei Eingängen.
Man kann auch jedem Eingang eine "10" zuordnen. Dann wird der Summenzähler in der Zelle schon dann "10" erreichen, wenn nur ein Eingang aktiv ist. Das Neuron bildet dann ein ODER-Gatter mit zwei Eingängen.
Rund 10 Jahre nach Erfindung dieser Art von Neuronen kamen zwei Forscher auf die Idee, dass man damit aber keine XOR-Funktion hinbekommen kann. XOR feuert dann, wenn die beiden Eingänge ungleich sind. Sie schrieben ein tolles Buch über ihre Entdeckung und demotivierten für viele Jahre reihenweise Forscher und Geldgeber.
Irgendwann kam dann ein weiterer Knisterkopf auf die Idee, dass man ja nur mehrere Zellen in Schichten aufteilen muss, um das XOR-Problem zu lösen. Aber entdeckte dann, dass es auch nicht so einfach geht und es wurde kurzerhand ein weiterer Mechanismus benötigt, um das Problem dann doch noch per Hauruckverfahren zu lösen. KATASTROPHE!
Mit dem Quatschkram haben sich erwachsene Männer fast zwei Jahrzehnte lang gegenseitig die Rüben eingeschlagen, Vorträge gehalten, Bücher geschrieben, Flugreisen gemacht. Forschungsgelder verballert und letztlich nur dummes Zeug geredet.
Meine Idee geht wie folgt:
Meine Eingänge A und B bekommen jeweils eine "7" zugeordnet. Und die invertierten Eingänge von A und B (ich nenne sie notA und notB) bekommen jeweils die Gewichte "3" zugeordnet. Und mein Neuron feuert nicht bei Erreichen von "10" sondern nur dann, wenn die Zellsumme exakt 10 ist.
Rechnen wir mal durch:
notA und notB = 3 + 3 = 6: Zelle feuert nicht. Das ist beim XOR korrekt.
A und B = 7 + 7 = 14: Zelle feuert nicht. Auch das ist korrekt.
A und notB = 7 + 3 = 10: Zelle feuert! Jippieh!
B und notA = 7 + 3 = 10: Zelle feuert! Nochmal Jippieh!
Und genau diese Eingangsgewichtungen entstehen dann, wenn ich in einer Lernschleife dem "Kindlein" zuerst Teddy und Kasperle zeige (sprich A und B). Das Kind freut sich. Seine beiden Freunde sind da.
Und wenn ich mich dann kurz umdreh und ein Spielzeug wegnehme und mich dann wieder zum Kind wende, ist das Kind entsetzt. Da fehlt doch eine Figur. Nun nehm ich das Patschhändchen und zeige ihm den Feuerknopf.
Und diese Lernanweisung wiederhole ich ein paar Mal. Mal lasse ich den Teddy verschwinden. Mal den Kasperle.
Und wie durch Zauberhand entstehen genau die o.a. Zahlen-Zuordnungen auf den Eingängen und das ganze XOR-Problem verpufft vor unseren Augen wie ein böser Traum.
Die Kombination der natürlichen Lernschleife mit der winzigen Änderung des Feuermechanismus führt zum Erfolg.
Puh.... hab ich das halbwegs verständlich rüberbringen können?
Viele Grüße
Wolfgang
Er und ich haben unseren Eingängen Zahlenwerte zugeordnet. Eine Zelle mit zwei Eingängen A und B kann zum Beispiel für jeden Eingang den Zahlenwert "5" zugeordnet haben. Die Zelle soll beim Summenzähler "10" feuern.
nein, habe ich nicht.
Mit dem Quatschkram haben sich erwachsene Männer fast zwei Jahrzehnte lang gegenseitig die Rüben eingeschlagen, Vorträge gehalten, Bücher geschrieben, Flugreisen gemacht. Forschungsgelder verballert und letztlich nur dummes Zeug geredet.
Und hör doch mal bitte auf, die bestehenden Ansätze immer mit derart abwertenden Attributen zu diskreditieren - sie funktionieren, aber bei dir sehe ich noch keinen funktionierenen Code, der per Überwachtem Lernen beliebig trainiert werden kann.
Puh.... hab ich das halbwegs verständlich rüberbringen können?
nein, da muss ich leider passen. Aber vlt sind ja andere hier klüger und können das nachprogrammieren.
Rumgucker
07.12.2019, 19:51
Hallo Helmut,
Du hast doch Deinen Eingängen doch ebenso Zahlenwerte zugeordnet. Bei Dir ist es eben "0.5" oder was auch immer. Nun verwirr die anderen doch nicht sinnlos.
Vielleicht kannst Du das XOR-Problem besser darstellen?
Viele Grüße
Wolfgang
nein, ich habe überhaupt nichts "zugeordnet". Wie ein Perzeptron funktioniet, muss ich aber wirklch nicht mehr erklären, und auch nicht, wie das XOR Problem nach Papert et al. gelöst werden konnte. Das tut aber auch hier nichts zur Sache, denn ich verwende zwar Perzeptronen und BP-Netze nach Paperts Ansatz, du aber nicht. Verwirrend sind eher deine Vergleiche zwischen den BP-Netzen und deiner Konstruktion, denn die haben wirklich nicht viel gemeinsam - und ob und wie sie funktionieren sollen, kann ich noch nicht erkennen.
Rumgucker
07.12.2019, 20:10
Hallo Helmut,
meine Doku hast Du.
Was sollen dieser dauernden Wiederholungen, dass Du meine Software nicht nachvollziehen kannst? Empfindest Du Dich als Ober-Gutachter meines Projektes?
Ich hab mich gerade umentschieden. Tiny85-Code gibts nur auf Anfrage per Mail.
Viele Grüße
Wolfgang
Es heißt genau das, was ich schreibe, weil du fragst, ob es verständlich sei und ob ich etwas erklären könnte:
ich sehe keinen kompilierbaren Code, den ich verstehen, selber kompilieren und auch varieren und testen kann. Solange sehe ich nur vage Diskussionen um Ideen, aber nichts Verständliches und Substanzielles leider.
- - - Aktualisiert - - -
PS,
@stochri: hast DU kompilierbaren Code für ein lernfähiges Netz zum testen?
Rumgucker
08.12.2019, 06:45
Hallo Helmut,
wieso willst Du das GI-System testen? Du bist doch glücklich mit Deinen Systemen.
Und wieso kannst Du den Code nicht testen?
Gehts um FSR und INDF? Das ist ein eingebauter Pointer-Mechanismus des PICs. Dafür kannst Du schreiben:
char *FSR;
#define INDF (*FSR)
Oder gehts um den FIRE_REQ-Makro
#define FIRE_REQ (INDF.7) // zelle will feuern
Der PIC kann einzelne Bits lesen und kippen. Das wird natürlich genutzt. Du kannst dafür schreiben:
#define FIRE_REQ (INDF & _BV(7)) // zelle will feuern
Dann gelten noch meine Lieblings-Defines
#define BOOL bit // da kannst Du klein "bool" einsetzen
#define TRUE 1
#define FALSE 0
#define FOREVER while(1)
#define _BV(a) (1 << (a))
Und statt "uns8" kannst Du schreiben "unsigned char".
Fertig ist die Laube. Der ganze Rest ist K&R-Standard-C und der Aufruf des eeprom-Speichers.
Wo siehst Du Schwierigkeiten in der Portierung?
Ich habe unverändert Null Bock, Fehler in fremden Portierungen zu suchen. Das ging hier im Thread schon einmal gehörig schief. Getestete Portierungen gibts nur von mir. Und auch nur auf Anfrage ab Mitte nächster Woche, wie schon erklärt.
Viele Grüße
Wolfgang
Hier die aktuelle Doku mit selbstgesteuertem Lernen:
34553
Hallo,
wieso willst Du das GI-System testen? Du bist doch glücklich mit Deinen Systemen.
Warum will er das testen? Vermutlich um es, mindestens extern, zu verifizieren. U.U. selbst dann, wenn er es nicht "gut" findet.
Was den Rest anbelangt, wüsste ich jetzt aus dem Stand auch nicht, ob ich der Darbietung ein "Mangelhaft" oder "Ungenügend" geben sollte.
siehe:
char *FSR;
#define INDF (*FSR)
Oder gehts um den FIRE_REQ-Makro
#define FIRE_REQ (INDF.7) // zelle will feuern
Der PIC kann einzelne Bits lesen und kippen.
Wegen der Frage nach dem Warum:
Dies ist ja ein öffentliches Thema, somit also für die Breite Masse zugänglich. Der Forumsbetreiber hatte dazu geschrieben: Denkt bitte auch an Einsteiger!
Wenn ich es wirklich ernst meine, würde ich meine Gedanken ordnen und versuchen, alles so darzubieten, dass es jeder versteht. Je nach Hintergrundwissen versteht es der eine besser, der andere schlechter und einer gar nicht. Dazu muss ich noch nicht einmal einen Source Code darbieten, wenn zuvor allgemeinverständliche Erklärungen vorlagen, die jeder lückenlos nachvollziehen kann. Das bedeutet aber auch eine Menge Arbeit im Detail. Source Codes für Arduino-IDE, Assembler- oder PIC-Programmierung, oder auch für Pascal, Fortran, MS Visual Basic, Borland C++ Compiler Version X, Java oder ECMA-Script V5 runden die Sache sicher ab, sind aber nicht unbedingt notwendig. Dafür gibt es allgemeingültigen Pseudocode, der auch in Schulen gelehrt wird und für so etwas besser geeignet wäre. Aber es gibt auch gut verständliche PAP-Formen, die verwendet werden können. Dafür gibt es ganz brauchbare Tools, wie diesen PAP-Designer (https://www.heise.de/download/product/papdesigner-51889).
Ich habe unverändert Null Bock, Fehler in fremden Portierungen zu suchen.
Ist durchaus verständlich. Aber genau so wenig haben Leute hier unverändert Bock, sich durch fremde Programmiersprachen zu quälen und/oder stapelweise Dokus zu lesen, die in den Erklärfaden eingestreut sind, wenn die übrige Erklärung drumherum mangelhaft ist. Für solche Art der Darbietung halte ich die Blog-Seiten für geeigneter, die jeder User hier für sich anlegen kann. Dort findet die Wissensdarbeitung dann so statt, wie es jeder für notwendig hält, der seinen Blog fortführt. Dagegen gibt es nichts einzuwenden. Ich will hier niemanden reglementieren, is nur ein Vorschlag und meine Meinung.
MfG
:Weihnacht
Warum will er das testen? Vermutlich um es, mindestens extern, zu verifizieren. Natürlich, genau deswegen! Verschiedene Lernmuster ausprobieren, um die Lernfähigkeit durch die Lernregel(n) zu testen, und ein bisschen mit verschiedenen Training-Sets herum"spielen", indem man verschiedene Sets nacheinander präsentiert und trainiert.
Source Codes für Arduino-IDE, ... oder auch für Pascal,... MS Visual Basic, Borland C++ ... runden die Sache sicher ab, .... Dafür gibt es allgemeingültigen Pseudocode, der auch in Schulen gelehrt wird ...
einverstanden!
Rumgucker
08.12.2019, 10:59
Hallo,
es muss ich hier überhaupt keiner durch irgendwas quälen.
Ich hatte vielfach gesagt, dass es ab Mitte nächster Woche von mir auf Anfrage den auf Tiny85 konvertierten Code gibt.
Eigenzitat aus #119
Danach fehlt dann nur noch das autonome Lernen. Dann gibt es auch keinen Lehrer mehr, der sagt, wenn das Lernziel erreicht wurde. Dieses Detail halte ich aber für sehr trivial.
Ich denke, bis spätestens Mitte nächster Woche bin ich mit dem gröbsten durch. Dann konvertier ich das noch kurz auf den Tiny85 und dann könnt Ihr losspielen. Source, Doku und gut getestete Anwendungsbeispiele. Das ist ne vernünftige Basis, finde ich.
Ich finde Euer Gedrängele schlichtweg belastend.
Viele Grüße
Wolfgang
- - - Aktualisiert - - -
Hallo Moppi,
Was den Rest anbelangt, wüsste ich jetzt aus dem Stand auch nicht, ob ich der Darbietung ein "Mangelhaft" oder "Ungenügend" geben sollte.
dieser Thread ist mein Arbeitsthread. Hier trage ich meine Gedanken vor und hier lade ich den jeweiligen Stand der Doku hoch.
Versteh ich Dich richtig, dass Du meine Darbietung hier als "mangelhaft" bzw. "ungenügend" empfindest?
Das ist starker Tobak, wenn ich das nicht missverstanden haben sollte.
Viele Grüße
Wolfgang
- - - Aktualisiert - - -
Hallo,
neulich Manfreds Ruf nach Professionalität. Und nun das Vorhalten einer mangelhaften bis ungenügenden Darbietung meinerseits. Irgendwas hab ich hier am Forum im Kern nicht verstanden. Ich schein den Ansprüchen nicht genügen zu können.
Ich beende daher meine weitere Arbeit hier im Thread und im Forum und wünsch Euch noch viel Spaß.
Wie man nen Account löschen kann, hab ich nicht rausgefunden. Aber ich betrachte ihn als gelöscht.
Viele Grüße
Wolfgang
Apropos: Wie wär's mit einem KI-Linienfolger (https://www.roboternetz.de/community/threads/74338-lernf%C3%A4higer-Lininenfolger-mit-KI?p=657198#post657198)?
Hallo Rumgucker,
Versteh ich Dich richtig, dass Du meine Darbietung hier als "mangelhaft" bzw. "ungenügend" empfindest?
In manchen Details schon, ja. Bezüglich der allgemeinen Tauglichkeit. Den Zusammenhang habe ich dargestellt, hier:
Was den Rest anbelangt, wüsste ich jetzt aus dem Stand auch nicht, ob ich der Darbietung ein "Mangelhaft" oder "Ungenügend" geben sollte.
siehe:
char *FSR;
#define INDF (*FSR)
Oder gehts um den FIRE_REQ-Makro
#define FIRE_REQ (INDF.7) // zelle will feuern
Der PIC kann einzelne Bits lesen und kippen.
Darauf bin ich eingegangen, auch, wie man es besser machen könnte.
Es gab da den Beitrag #118 (https://www.roboternetz.de/community/threads/74213-GI-Guckis-Intelligenz?p=657164&viewfull=1#post657164) von oberallgeier, auf Deinen Kommentar:
.. Im Moment scheint es mir aber eher so, dass die Evidenz nicht verstanden wurde ..
Er schrieb darauf:
Hätte besser auch keinen Beitrag gegeben weil dieses für mich ein ".. möcht ich auch wissen/können/kennen ..
und hat damit einen Hinweis gegeben, der aber irgendwie nicht erhört wurde(?)
Im Zusammenhang mit meinen Vorschlägen, es besser zu machen, scheint mir aber gerade jetzt, dass deinerseits gerade die Evidenz nicht verstanden wurde.
Ich meine, Du hast z.Z. Vorteile:
- viele lesen mit und versuchen das zu verstehen
- es gibt nicht so viele drastische Reibereien und eigentlich mehr Kritik und Verbesserungsvorschläge in manche Richtung
- Du hast das Potential, Hinweise und Möglichkeiten, das Verständnis zum Thema zu verbessern, dass auch jeder, der neu hinzukommt und auch nicht die Fachbegriffe alle kennt, sich dennoch hinein findet und es versteht. Der Vorteil liegt einfach darin, dass Deine "neu erdachte" Sache nicht so komplex ist. Du sagst ja selbst: ich mach das soundso und dann bin ich fertig. Kurz und bündig - alles gut!
etwas Meinungsunterschiede brauch ich einfach, damit ich optimal funktioniere. Im Idealfall kommt bei mir das Gefühl hoch, dass ich es dem Meinungsgegner beweisen will.
Hmmm .... Und dann willst Du das Thema beenden, weil Gegenwind kommt? Einen richtigen Sturm oder Orkan hast Du hier noch nicht erlebt.
MfG
:Weihnacht
Holomino
08.12.2019, 14:12
Na? Habt ihr wieder einen rausgekickt?
Na? Habt ihr wieder einen rausgekickt?
Daumen hoch..
Nö,
den braucht man nicht kicken, seine (durchschnittliche) Verweildauer in dem Forum war schon überschritten, normalerweise macht er schneller einen (beleidigten) Abgang.
Vermutlich muss er jetzt selbst ein Forum gründen, da es wahrscheinlich keines mehr gibt, wo er noch nicht war.
Holomino
13.12.2019, 16:43
Es drängt sich mir sowieso seit einiger Zeit der Verdacht der intellektuellen Inzucht in diesem Forum auf.
Schön, das mal bestätigt zu sehen.
um Mißverständnissen vorzubeugen, ich meinte nicht die durchschnittliche Verweildauer in diesem Forum, sondern seine (Guckis) durchschnittliche Verweildauer in Foren.
Für weitere Kommentare zum Thema gibt kann man ja einen neuen Thread aufmachen.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.