PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : lernfähiger Lininenfolger mit KI



stochri
08.12.2019, 10:03
Schon die ganze Zeit überlege ich, welches einfache Lernbeispiel man für einen KI-Lernalgorithmus verwenden könnte. Wir sind hier ja im Roboterforum und die zweirädrigen Roboter könnten bei der Funktion ein paar Inspirationen aus der Natur gebrauchen.

Bei diesem Video eines linienfolgenden NiboBee-Roboters ist mir aufgefallen, dass er leicht hin und her pendelt:

https://www.youtube.com/watch?v=D0R-CtTEuEs&list=TLPQMDcxMjIwMTnH1pwrqRWq0w&index=2

Daher kam mir die Idee, dass ein Linienfolger doch ganz wunderbar als Echtzeitlernbeispiel dienen könnte.

Vielleicht kennt Ihr ja auch ein paar Projekte, die das schon umsetzen.

Moppi
08.12.2019, 10:47
Für einen Linienfolger brauchts ja nicht wirklich KI ;)

Aber klar, den Sinn verstehe ich. Gerade hatte ich überlegt, ob ich selber mal anfangen sollte, das Thema aufzubauen, so, dass jeder was davon hat und mitmachen kann, egal, in welcher Programmiersprache er schreibt.
Ich halte es daher für unerlässlich und hätte die dringende Bitte, nicht wieder einfach irgendwie loszulegen, sondern, von Anfang an, mit dem PAP-Designer zu arbeiten. Das Teil ist winzig klein, aber man kann damit in der Tat sofort arbeiten. Das kann eigentlich jeder. Das Projekt könnte man nach dem Speichern auch austauschen. Müsste man sich genauer ansehen, ob das nur eine Datei ist oder mehrere. Kann dann jeder laden und bearbeiten und hier wieder einstellen. Und da es jeder versteht, kann es in seiner Programmiersprache verfassen und für die Allgemeinheit den PAP zur Verfügung stellen. Aber vielleicht wäre so ein Miniprojekt dann in Open-Source-Projekte besser aufgehoben.



MfG
:Weihnacht

PS: so wie es aussieht speichert der PAP-Designer nur eine kleine Datei, als PAP

HaWe
08.12.2019, 10:59
lernfähiger Lininenfolger mit KI - welches einfache Lernbeispiel man für einen KI-Lernalgorithmus verwenden könnte.
ja das geht.
Ist aber "nicht einfach".
Prinzip:
Man hat 2 , 3, 4 oder 5 Linien-Lichtsensoren als Inputs.
Man hat die pwm-Geschwindigkeits-Steuerung linkes/rechtes Rad als binäre Outputs (Differentialantrieb).
Man fährt beim Training manuell die Linie ab, in verschiedenen Schlenkern mit verschieden großen Fehlern, und das System speichert die Sensor-Inputs und die zugehörigen Drehgeschwindigkeiten der Räder zur Bahn- und Kurven-Korrektur in Echtzeit ab.
Man braucht so vlt ca. 50- 200 Lernsets, die gespeichert werden, je nach Parcour.
Wenn die Lernsets alle gespeichert wurden, wird das Training des Netzes begonnen. Das kann ein paar Stunden, Tage oder Wochen dauern, je nach MCU und Datensätzen.
Wenn das Netz sich darauf einjustiert hat, kann man es mit den Daten laufen lassen.

stochri
08.12.2019, 11:15
man hat 2 , 3, 4 oder 5 Linien-Lichtsensoren als Inputs.
Vor kurzem habe ich meine alten Roboter wieder gefunden: Unter anderem ein paar Asuros und ein NiboBee. Am liebsten ist mir der Asuro, der hat nur zwei SFH300 als Liniensensoren.


Man braucht so vlt ca. 50- 200 Lernsets, die gespeichert werden, je nach Parcour.
Wenn die Lernsets alle gespeichert wurden, wird das Training des Netzes begonnen. Das kann ein paar Stunden, Tage oder Wochen dauern, je nach MCU und Datensätzen.

Das wäre jetzt wahrscheinlich die richtige Herausforderung für Gucki mit seinem Attiny85. Echzeitlernen auf Minimalprozessoren wäre das Ziel.
Schade, dass sich Wolfgang im "Leberwurstmodus" verabschiedet hat.

Moppi
08.12.2019, 11:24
Schade, dass sich Wolfgang im "Leberwurstmodus" verabschiedet hat.
Noch ist nicht aller Tage Abend.


:Weihnacht

HaWe
08.12.2019, 11:29
Echzeitlernen auf Minimalprozessoren wäre das Ziel.
das lässt sich evtl auch auf einem AVR Arduino (z.B. einem MEGA2560) machen, dann hat man etwas mehr RAM in Reserve. Bei KI würde ich persönlich aber nicht unter einem M0 anfangen, am besten mit fpu (M4, ESP32).
Der Arduino-API Code wäre dann aber auch glücklicherweise für alle MCUs der gleiche.

stochri
08.12.2019, 13:00
Aber klar, den Sinn verstehe ich. Gerade hatte ich überlegt, ob ich selber mal anfangen sollte, das Thema aufzubauen, so, dass jeder was davon hat und mitmachen kann, egal, in welcher Programmiersprache er schreibt.

Anfangen ist immer gut, man lernt bestimmt was dabei. Als Controller eignet sich etwas "Arduino-artiges", das hat jeder zu Hause.


Bei KI würde ich persönlich aber nicht unter einem M0 anfangen, am besten mit fpu (M4, ESP32).

Die Frage wäre, ob ein ESP für die Erforschung der grundlegenden Prinzipien nicht schon etwas überdimensioniert wäre.
Eventuell reichen schon zwei Neuronen (https://www.robotshop.com/community/robots/show/motoko-neural-network-line-follower). Wobei das entstehende System dann wohl eher einem klassischen Regler entspricht.

HaWe
08.12.2019, 13:27
Die Frage wäre, ob ein ESP für die Erforschung der grundlegenden Prinzipien nicht schon etwas überdimensioniert wäre.
Eventuell reichen schon zwei Neuronen. Wobei das entstehende System dann wohl eher einem klassischen Regler entspricht.
klar, klein anfangen kann man immer, und MCU-mäßig aufstocken, wenn es dann doch komplizierter wird (Verhalten bei Sackgassen, Kreuzungen, starken wechselnden Kurven, Ecken, spitzen Winkeln,...)
Hier wird man auch schnell in den Bereich der XOR-Situationen kommen, die bereits mehrschichtige Netze mit rechenintensiver float-Arithmetik auch für Exponentialfunktionen erfordern.
Aber wie gesagt, bei Arduino Code ist das ja egal - was auf kleinen MCUs läuft, läuft auch auf großen (ntl keine spez. Register-Befehle verwenden!), und ein ESP32 ist nicht überdimensioniert, wenn man einen besitzt - er ist dann höchstens nicht ausgelastet (aber ausbaufähig).

- - - Aktualisiert - - -

PS,
Vergiss auch nicht, dass die Outputs von Perzeptronen auf Boolean Werte trainiert werden, d.h. für 2 Motoren mit je 3 Steuerwerten (vor, rück, stop) braucht man bereits 3-4 Output- Neuronen, bei (notwendiger) abgestufter pwm-Steuerung sogar deutlich mehr, und bei 2-schichtigen Netzen dann davon jeweils (mindestens) das doppelte.

Moppi
09.12.2019, 07:37
Vielleicht kennt Ihr ja auch ein paar Projekte, die das schon umsetzen.

Direkt ein Linienfolger nicht. Aber an einem ähnlichen Projekt arbeite ich gerade. Dazu habe ich mir zuerst angesehen, wie ein einfacher Linienfolger funktioniert. Das geht nach dem Schema, in Fahrtrichtung: wenn der rechte Sensor über die schwarze Linie gerät, dann lenke nach rechts, wenn der linke Sensor über die schwarze Linie gerät, dann lenke nach links. Die schwarze Linie befindet sich zwischen den Sensoren. Das Trainieren eines KNN sollte daher nicht so kompliziert sein. Im Grunde sollte ein Perceptron-Modell mit 2 Eingabe und 2 Ausgabeneuronen für's Erste genügen.


MfG
:Weihnacht

Moppi
09.12.2019, 15:39
Ein Link zu einer deutschen Seite (https://jaai.de/kuenstliche-neuronale-netze-aufbau-funktion-291/), wo Grundsätzliches zu Neuronalen Netzen erklärt wird. Unten auf der Seite, unter Trackbacks & Pingbacks, sind noch weitere Links, hinter denen sich weitere Erklärseiten verbergen.
Da gibt es eine schöne Übersicht, über Arten neuronaler Netze.

Auch schon mehrmals erwähnt, glaub ich: http://neuronalesnetz.de


MfG
:Weihnacht

Moppi
10.12.2019, 12:15
MXT hatte, in einem andern Thread, schon einen guten Link auf diese Seite: http://robotics.hobbizine.com/arduinoann.html
Nachdem ich das mehrfach angeschaut und nichts verstanden habe, hat mein biologisches Netz aber langsam gelernt, dass das nicht soo schwer ist. Zumal auf der Seite jeder einzelne Schritt gut erklärt ist. Allerdings lernt das Netz nur. Jetzt weiß ich nicht, wie man das einfach nutzt, wenn es trainiert ist.

/************************************************** *****************
Compute output layer activations and calculate errors
************************************************** ****************/


for( i = 0 ; i < OutputNodes ; i++ ) {
Accum = OutputWeights[HiddenNodes][i] ;
for( j = 0 ; j < HiddenNodes ; j++ ) {
Accum += Hidden[j] * OutputWeights[j][i] ;
}
Output[i] = 1.0/(1.0 + exp(-Accum)) ;
}
Serial.print (" Output ");
for( i = 0 ; i < OutputNodes ; i++ ) {
Serial.print (Output[i], 5);
Serial.print (" ");
}
}




Macht man das einfach mit diesem Programmteil? - Aus Unwissenheit würde ich vermuten: ja

Dann kann aus den einzelnen Fragmenten (des kompletten Codes), die alle erklärt sind, ein eigenes KNN aufgebaut werden. Man kann auch mit einem Eingabe-, einem Ausgabeneuron und einem Neuron für die Zwischenschicht starten. Dann evaluieren, wie das funktioniert und ob es funktioniert, um den Durchblick zu bekommen. Klar ist mir außerdem nicht, wieviele Neuronen für eine Zwischenschicht benötigt werden. Wovon hängt das ab? Kann man die Anzahl, je nach Anwendungsfall, frei wählen?

Vielleicht bauen wir ein Grundgerüst auf, das jeder nachvollziehen und verstehen kann. Ich würde das mit dem PAP dann schon machen, wenn das sonst keiner tun will, nur muss ich nat. dafür selber den Programmcode erst einmal verinnerlicht haben, der dann auch funktionieren sollte. Deshalb: Schritt um Schritt aufbauen.

Man kann ja so anfangen, wenn man sich hier auf Arduino-Code einigt:



#include <math.h>

void setup()
{

}

void loop()
{

}



Gar nicht so schwer - schon fast fertig \\:D/


MfG
:Weihnacht

HaWe
10.12.2019, 12:52
Faustregel
InputLayer = Anzahl der Inputs
HiddenLayer = etwa wie Inputlayer oder auch etwas größer
OutputLayer = Anzahl der Outputs

Moppi
10.12.2019, 12:53
Warum nimmt man für die versteckte Schicht mehr Neuronen?

HaWe
10.12.2019, 13:07
hängt vom Lernziel und Zweck ab, man kann auch einen Wert zwischen In- und Outputzahl nehmen, muss man ausprobieren - daher: "Faustregel".
Je kleiner das HiddenLayer, desto weniger Input-Informationen werden logischerweise an die Outputs weitergereicht, und je größer, desto differenzierter können diese moduliert werden.

stochri
11.12.2019, 03:41
Gar nicht so schwer - schon fast fertig

Ein guter Anfang. Man muss konkret werden, sonst nützt alles nichts.
Man kann das System am Anfang auch ohne lernen ganz einfach aufbauen:


...
boolean SensorLinks;
boolean SensorRechts;

boolean MotorLinks;
boolean MotorRechts;

int w[4];

....
void loop()
{

MotorLinks=w[0]*SensorLinks+w[1]*SensorRechts;
MotorRechts=v[2]*SensoLinks+w[3]*SensorRechts;

stepMotorLinks(MotorLinks);
stepMotorRechts(MotorRechts);

...

}

Moppi
11.12.2019, 09:02
Ich würde zunächst auf eine konkrete Problemlösung verzichten. Und erst einmal mit den grundsätzlichen Dingen und Fragen zum neuronalen Netz anfangen.


1. Netzstruktur


Hier würde ich mich jetzt auf das Beispiel beziehen, daher wäre das ein was für ein Netz? Feed Forward mit Backpropagation, wenn ich richtig gelesen habe.
Dafür wir mindestens benötigt: ein Eingangsneuron, ein verstecktes Neuron (zwischen Ein- und Ausgang) und ein Ausgangsneuron.
Wenn ich das richtig sehe, ist jedes Eingangsneuron mit jedem versteckten Neuron verbunden (ich brauche einen Speicherplatz für das Gewicht jeder dieser Verbindungen)
und jedes versteckte Neuron ist mit jedem Ausgangsneuron verbunden (auch hier wieder Speicherplatz für das Gewicht jeder dieser Verbindungen).




Für die Gewichtsberechnung wird wohl der Datentyp "float" benötigt, für Datenmengen werden Arrays benötigt:


//Gewicht für Verbindungen Eingangsneuron, mit jedem versteckten Neuron
float IH_Weights[InputNeurons][HiddenNeurons];


//Gewicht für Verbindungen jedes versteckte Neuron, mit jedem Ausgangsneuron
float HO_Weights[HiddenNeurons][OutputNeurons];






Wenn ich mir das jetzt im Vergleich zur Beispielseite ansschaue, ist dort nur die Rede von HiddenWeights und OutputWeights.


Die Frage, wie bezeichne ich die Gewichte zwischen den Input Nodes und den Hidden Nodes - als InputWeights oder als HiddenWeights? - war für mich noch nicht ganz so spontan zu beantworten.
Deshalb habe ich die mal IH_Weights und HO_Weights genannt.
Man will ja auch nicht immer langwierig den Sachverhalt in jeder Variablen beschreiben, was zu Vereinfachungen führt, die für Außenstehende aber missverständlich sein können.
Deswegen lasse ich das jetzt erst mal so stehen.







MfG
:Weihnacht

stochri
11.12.2019, 09:59
Ich würde zunächst auf eine konkrete Problemlösung verzichten. Und erst einmal mit den grundsätzlichen Dingen und Fragen zum neuronalen Netz anfangen.

Das ist mir jetzt ein wenig zu "low level". Schau Dir doch erst mal ein paar Videos auf Youtube zum Aufbau neuronaler Netze an, damit Du mal ein wenig Grundverständnis für die Sache bekommst, sonst wird das hier wie das Lernen des 1x1.

Moppi
11.12.2019, 10:14
Schau Dir doch erst mal ein paar Videos auf Youtube zum Aufbau neuronaler Netze an, damit Du mal ein wenig Grundverständnis für die Sache bekommst, sonst wird das hier wie das Lernen des 1x1.
Ich habe mir schon einige Sachen angeschaut, dennoch muss doch ein Grundgerüst erarbeitet werden und damit einhergehend ein Verständnis, dem auch jeder hier folgen kann.


Das ist mir jetzt ein wenig zu "low level".
Gut, dann passt das nicht in diesen Thread. Denn Du hast den ja erstellt.
Da von Deiner Seite aus nichts kam, hatte ich einfach mal angefangen.
Dann mach Du auf einem andern Level weiter. Wenn Du das nichts kannst, aber eine Lösung für Dich suchst, verstehe ich das auch. Mir geht es mehr um die Allegmeinheit, damit wir hier mehr Leute finden, die an einem solchen Thema teilnehmen können, aber dafür braucht es idealer Weise eine einheitliche Wissensbasis. Das ist nicht so schnell gemacht, das weiß ich.

Manf kann den bisherigen Verlauf löschen und Du kannst neu starten.



MfG
:Weihnacht

Manf
11.12.2019, 12:07
Manf kann den bisherigen Verlauf löschen und Du kannst neu starten.
Das ist mehr ein Kurs abstecken und gehört eher dazu, wenn es ganz neu sein soll dann ist auch ein neuer Thread möglich.
Aber ich lösche bei Bedarf auch selektiv.

HaWe
12.12.2019, 08:19
Ein guter Anfang. Man muss konkret werden, sonst nützt alles nichts.
Man kann das System am Anfang auch ohne lernen ganz einfach aufbauen:


...
boolean SensorLinks;
boolean SensorRechts;

boolean MotorLinks;
boolean MotorRechts;

int w[4];

....
void loop()
{

MotorLinks=w[0]*SensorLinks+w[1]*SensorRechts;
MotorRechts=v[2]*SensoLinks+w[3]*SensorRechts;

stepMotorLinks(MotorLinks);
stepMotorRechts(MotorRechts);

...

}


das hat aber weder etwas mit einem Perzeptron noch mit einem Netz noch mit lernfähig zu tun... ;)
und wie das (mindestens) designed werden müste, habe ich ja bereits oben skizziert... 8)

Außerdem halte ich nach wie vor einen Linienfolger nicht für NN-Anfänger-geeignet, hier braucht man schon das Grundwissen und das Verständnis über einfache Netze, wie das in Mxts Link.

stochri
12.12.2019, 10:53
das hat aber weder etwas mit einem Perzeptron noch mit einem Netz noch mit lernfähig zu tun..

Ja, das war auch im Sinne der "Gucki"-Intelligenz gedacht, nämlich auf die Reduktion auf das absolut Essentielle, von dem man weiter aufbauten kann.
Aber hier geht die Diskussion in die gleiche Richtung wie bei der Gucki Intelligenz: Der eine versteht die Grundlagen nicht, der andere meint, er weiß schon alles.
Ich halte es jetzt mal wie Wolfgang: Ich lasse die Diskussion hier bleiben, das führt zu nichts.

inka
12.12.2019, 11:25
und genau damit wäre es HaWe gelungen ein Thema zu beenden. Wollen wir das wirklich?

Moppi
12.12.2019, 12:06
Ich denke nicht, dass diesmal HaWe ...
Wenn er wirklich davon viel versteht, hat er Kommentare abgegeben, was nach seiner Erfahrung richtig ist.

Allerdings hätte Stochri auch früher sagen können, dass er mit diesem Thema hier nicht in die Richtung gehen möchte, wie sie in der von MXT verlinkten Seite aufgezeigt wird. Sondern, dass er einen neuen Ansatz sucht. Allerdings wissen wir nicht welchen. Und wenn der Ansatz in Richtung KNN geht, dann gibt es Ansätze, die grundlegend wichtig sind, damit so etwas funktioniert. Man kann das Thema auch ganz neu interpretieren, aus einem ganz andern Blickwinkel betrachten und ganz andere Techniken anwenden, aber welche und wie? Das muss Stochri dann vorgeben.

"Der eine versteht die Grundlagen nicht, der andere meint, er weiß schon alles."
Und dem nächstes sind Grundlagen zu langweilig.


Das ist ein generelles Problem. Spiegelt wohl aber die Bandbreite wider, die wir hier im Forum haben.
Verschiedene Meinungen sollten kein Problem sein, und so hat auch jeder seinen Standpunkt, wann er sich beteiligt oder wann er helfende Kommentare abgibt.
Ich für meinen Teil halte es für wenig hilfreich, wenn erst abgewartet wird, was andere beginnen, um dann z.B. mit einem "ist mir zu langweilig" dazwischen zu gehen.
Das ist auch ein Standpunkt und von der Sache her vertretbar. Aber man sollte schon daran denken, dass andere sich Arbeit machen, um im Thema voran zu kommen. Und das geht schnell mal in die Stunden, wenn man auch was Sinnvolles zu einem Thema beitragen möchte, dass man selbst noch nie erarbeitet hat.


Mich persönlich interessiert das Thema nicht wirklich, weil ich weiß, wohin es führt und welche Früchte mit so etwas, wie einem KNN, zu ernten sind. Dreißig Jahre Programmiererfarung helfen mir. Ich bin eher Verfechter anderer Methoden.
Dennoch habe ich im Moment Zeit, mich damit irgendwie zu beschäftigen, weil ich auf Teile warte, die erst zu Weihnachten hier sein werden.


Um aus dem schlau zu werden, wer hier was will und was unnötig ist, zu presentieren, habe ich, für alle User im Forum, eine Umfrage gestartet, die aber nur bei Beteiligung einen Sinn ergibt. Deswegen wäre es gut, wenn sich jeder daran beteiligt, egal welcher Meinung er ist. Ich habe versucht die wesentlichen drei Meinungen abzubilden, von denen jeder eine für sich priorisieren können sollte. So dass wir alle ein Bild bekommen, wie das Thema behandelt werden kann. Dann sieht auch jeder, der seine Meinung dazu hat, wofür die Mehrheit ist und kann sich daran orientieren. So weiß man auch von vornherein, wie ein Kommentar, den man abzugeben gedenkt, ankommen wird. Deshalb kann ich nur an Teilnahme an der Umfrage appellieren.


Ich hoffe, dass wir weiter kommen. Warum soll das Thema jetzt beendet sein? Stochri, Du hast das Thema gestartet, dann nimm die Sache in die Hand und bestimme, wie es weiter gehen kann.






MfG
:Weihnacht

- - - Aktualisiert - - -


... nämlich auf die Reduktion auf das absolut Essentielle, von dem man weiter aufbauten kann.

Ja, genau das haben wir hier begonnen. KNNe haben eine Art Grundstock, der zunächst für viele Aufgabenstellungen tauglich ist. Der ist im Wesentlich nicht komplex und hat sich im Laufe der Entwicklung von KNNen etabliert. Gewisse Voraussetzungen, die Lernfähigkeit hervorbringen. MXT hat einen Link gepostet. Ich habe darauf Bezug genommen und versucht, einen Anfang zu gestalten. Sollte zeigen, wie man an so eine Sache rangehen kann. Wird als Unwissenheit abgetan und dann beginnen wir wieder mit der Suche nach dem absolut Essentiellen, von dem man weiter aufbauten kann.
Ich will jetzt nichts behaupten, aber für mich sieht es so aus, als ob die Thematik, im Ansatz, nicht verstanden wurde.

inka
12.12.2019, 14:09
ich trau mich mal aus der deckung:


was wir haben:
-ein paar leute, die sich auskennen
- ein paar mehr leute, die nicht so viel wissen, die aber interesse haben (kann man irgendwo sehen, wie viele z.b. dieses thema aboniert haben? Manf?)
- kaum jemmand wird einen "12F629" in der schublade haben, von der beschaltung und dem handling mal ganz zu schweigen, aber einen arduino? Hat wohl fast jeder. Manch einer sogar einen ESP32...

was wir nicht haben:
- lust auf rechthaberei oder streit

mein vorschlag wäre, dass sich einer, der sich auskennt, gedanken darüber macht, wie man zum KI und NN einen arduino nutzen könnte und schön step by step das ganze aufbaut. Von der beschaltung, bis hin zu basis der software, vielleicht mal einiges anhand von beispielen erklärt. Hinweise auf weblinks sind zwar manchmal hilfreich, hier wären sie nicht so gut passend ...
Dieser KI-tutorial sollte weder in Rumgucker's flapsiger noch mit (manchmal) HaWe's herablassender art erfolgen, da geht doch sicher noch was anders. Auch ein ganz neuer thread könnte es werden...

Nun, wer machts?

Manf
12.12.2019, 17:58
mein vorschlag wäre, dass sich einer, der sich auskennt, gedanken darüber macht, wie man zum KI und NN einen arduino nutzen könnte und schön step by step das ganze aufbaut. Von der beschaltung, bis hin zu basis der software, vielleicht mal einiges anhand von beispielen erklärt.

Ich gehe mal davon aus, dass niemand etwas dagegen hätte, nur in der Zeit bis soetwas von selbst passiert kann man ja unterschiedliche Erklärungen suchen die es schon gibt und vergleichen wie gut sie den Anforderungen entsprechen.
Etwas in der Art wie hier oder eine der anderen.
https://www.youtube.com/watch?v=bxe2T-V8XRs

https://www.3blue1brown.com/neural-networks
https://www.youtube.com/watch?v=2-Ol7ZB0MmU
...

Moppi
12.12.2019, 18:19
[nicht ernst gemeint]



Nun, wer machts?

Da gibt es so eine geflügelte Antwort: "Der, der fragt!"


ich trau mich mal aus der deckung

Ok !

[/nicht ernst gemeint]

:Weihnacht

- - - Aktualisiert - - -

Wenn man das nicht jeden Tag macht oder schon längere Zeit mit dem Thema zu tun hat, ist es insgesamt eine Herausforderung. Wenn man das richtig aufdröseln und später auch noch im Aufbau und zweckbestimmt variieren will, muss man bis auf die unterste Ebene durchgestiegen sein. Wenngleich man nicht unbedingt den wissenschaftlichen Hintergrund im Detail verstanden haben muss. Aber die Grundfunktionen müssen "sitzen". Selbst das Beispiel von MXTs verlinkter Seite ist nicht gerade für Einsteiger die erste Wahl. Weil dort schon Indizes für mehrere Muster drin enthalten sind. Das spiegelt sich auch in den Formeln wider, die dann gleich noch etwas komplizierter werden. Das auf das Nötigste abzuspecken, ist für Einstiger in die Materie nicht so schnell gemacht. Gemeinsam würde es vielleicht schneller gehen.

inka
12.12.2019, 18:51
[nicht ernst gemeint]



Da gibt es so eine geflügelte Antwort: "Der, der fragt!"



Ok !

[/nicht ernst gemeint]
ok, danke...
ich kenne nur die zwei hier: Rumgucker und HaWe. Beide zusammen? Das wäre doch ein super gespann...
Man munkelt ja schon...

Moppi
12.12.2019, 19:17
Um aber nochmals auf den Kern zurückzukommen, folgendes.
DIE, programmiertechnisch und vom Verstehen der Materie her, einfachste Struktur für ein KNN gibt es eigentlich nicht.
Ein Beispiel ist die Aktivierungsfunktion. Wenn man die einfach linear gestaltet, stößt man früher oder später auf Probleme, die das Netz womöglich nicht lösen kann. Dasselbe gilt für Lernen aus Fehlern. In manchen Fällen funktionieren solche Funktionen besser und in anderen Fällen andere Funktionen, was die Lerngeschwindigkeit und Genauigkeit anbelangt. Es kann wohl auch zu so einer Art Dauerschleife im Netz kommen, wo das Netz nie zu einem Ergebnis kommt. Aus diesen und anderen Gründen werden in den Netzen oft nichtliniare Funktionen verwendet. Da geht es dann nicht mehr nur um "0" und "1" oder "an" und "aus", sondern da wird schon mal ein Tangensberechnung bemüht oder was anderes.
Ich bin aber nicht der Spezi für solche Dinge.

Vielleicht kann sich Stochri nochmal äußern, wie (oder mit welchen "Basics") er sich das vorstellt umzusetzen?


MFG
:Weihnacht

Moppi
13.12.2019, 18:31
Ich bin mit dem Thema noch nicht durch, aber ich habe zumindest einmal den Linienfolgermechanismus mit einer Wahrheitstabelle getestet.
Als Quellcode habe ich den genommen, wo MXT den Link auf die Beispielseite gesetzt hat.

Es sind etwa 2400 bis 2800 Trainingszyklen notwendig, bis die vorgegebene Genauigkeit erreicht wurde. Die Werte, welche diese bestimmen, wurden aus dem Originalquelltext beibehalten.
Das Training dauert, auf einem nodeMCU ESP-12E, ca. 5 Sekunden.

Da es sich um analoge Berechnungen handelt, sind die Werte der Ausgabeneurone Fließkomma-Näherungswerte. Eine Berechnung im KNN stellt immer eine Annäherung dar.
Würden die Ausgaben, ohne Nachkommastellen, gerundet, erhielte man das gewünschte Ergebnis, als "0" oder "1".

Die Trainingszyklen variieren bei jedem Neustart, weil in den Berechnungen Zufallswerte mitspielen. So werden u.a. die Neuronengewichte Anfangs mit Zufallswerten und nicht mit immer gleichen festen Werten initialisiert.
Die Fließkommaergebnisse variieren genau so, weil es Näherungswerte sind und eben in den Berechnungen Zufallswerte mitspielen.



Im Input haben wir 2 Eingänge. Der Erste, für den linken Sensor. Der Zweite für den rechten Sensor. In der Mitte der Sensoren soll die schwarze Linie verlaufen.

Im Output haben wir 2 Ausgänge.
Der Erste, für den linken Motor, der langsam vorwärts fährt oder steht (0); oder schneller vorwärts fährt (1).
Der Zweite, für den rechten Motor, der langsam vorwärts fährt oder steht (0); oder schneller vorwärts fährt (1).


1. Wenn sich der linke Sensor neben der schwarzen Linie befindet (0), kann der linke Motor laufen (1).
2. Wenn sich der rechte Sensor neben der schwarzen Linie befindet (0), kann der rechte Motor laufen (1).
3. Wenn sich der linke Sensor auf der schwarzen Linie befindet (1), kann der linke Motor stehen oder langsam drehen (0).
4. Wenn sich der rechte Sensor auf der schwarzen Linie befindet (1), kann der rechte Motor stehen oder langsam drehen (0).

Das Ergebnis des neuronalen Netzes sieht dazu so aus; zum Vergleich wird Target (das Muster, auf das zuvor trainiert wurde) mit ausgegeben; Target ist eine Vorgabe und wird nicht durch das neuronale Netz erzeugt:

Input 0 0 Target 1 1 Output 0.98662 0.98579
Input 1 0 Target 0 1 Output 0.01587 0.99852
Input 0 1 Target 1 0 Output 0.99999 0.00660
Input 1 1 Target 1 0 Output 0.99995 0.01100

Input sind die Werte des linken und rechten Lichtsensors, auf die das KNN eine Ausgabe (Output) für den linken und rechten Motor erzeugen würde, um das Fahrzeug zu steuern.

Das stellt für mich jetzt den einfachsten Fall einer solchen Steuerung dar, den man mit einem KNN umsetzen kann. Sozusagen das Notwendigste. Das Trainingsset ist als Wahrheitstabelle fest vorgegeben und wird durch die CPU so lange abgearbeitet, bis die richtigen Reaktionen der Ausgänge, auf die Eingangssignale, stattfinden.
Verwendet habe ich 2 Eingangsneuronen, 2 versteckte Neuronen und 2 Ausgangsneuronen.

Mit einem versteckten Neuron funktioniert es auch. Die Ergebnisse sind dann etwas genauer, die Trainingsphase dauert aber ca. 9 Sekunden, bei ca. 9000 Zyklen:

Input 0 0 Target 1 1 Output 0.98612 0.98504
Input 1 0 Target 0 1 Output 0.01456 0.99999
Input 0 1 Target 1 0 Output 1.00000 0.00847
Input 1 1 Target 1 0 Output 1.00000 0.00998

Mit 10 versteckten Neuronen, ca. 900 Trainingszyklen, bei 4 Sekunden:

Input 0 0 Target 1 1 Output 0.98621 0.98668
Input 1 0 Target 0 1 Output 0.01535 0.99720
Input 0 1 Target 1 0 Output 0.99992 0.00877
Input 1 1 Target 1 0 Output 0.99469 0.00908

Mit 20 versteckten Neuronen, ca. 800 Trainingszyklen, bei 4 Sekunden:

Input 0 0 Target 1 1 Output 0.98555 0.98742
Input 1 0 Target 0 1 Output 0.01570 0.99923
Input 0 1 Target 1 0 Output 0.99999 0.00424
Input 1 1 Target 1 0 Output 0.99645 0.01238

Mit 50 versteckten Neuronen dauern die Berechnungen ca. 12 Sekunden, bei ca. 650 Trainingszyklen:

Input 0 0 Target 1 1 Output 0.98657 0.98793
Input 1 0 Target 0 1 Output 0.01528 0.99561
Input 0 1 Target 1 0 Output 0.99999 0.00667
Input 1 1 Target 1 0 Output 0.99218 0.01062






MfG
:Weihnacht

- - - Aktualisiert - - -

Übrigens ließe sich nach so einem Schema auch die in einem anderen Thread angezweifelte Waschmaschinensteuerung realisieren.

HaWe
13.12.2019, 20:05
langsam vorwärts fährt oder steht (0)

hier sehe ich logische Unschärfen bzw. Unmöglichkeiten, denn langsam kann nicht gleichzeitig dasselbe sein wie stehen.
wenn also aus+langsam+schnell möglich sein sollen:
4 Ausgänge, 2 für motor0 und 2 für motor1:
Daher
out0 0 out1 0: motor0 steht
out0 0 out1 1: motor0 langsam vor
out0 1 out1 1: motor0 schnell vor

out2 0 out3 0: motor1 steht
out2 0 out3 1: motor1 langsam vor
out2 1 out3 1: motor1 schnell vor


hier hätte man dann sogar noch je 1 Kodierung für 1/0 frei.

bei 2 inputs und 4 outputs sind fürs Hiddenlayer 3-5 Neuronen sinnvoll und angemessen.

vgl. hier: https://www.roboternetz.de/community/threads/74338-lernf%C3%A4higer-Lininenfolger-mit-KI?p=657215&viewfull=1#post657215 (PS.)

Damit die Outputs eineindeutig sind, sollten sie mit der round() Funktion auf 0/1 ab/aufgerundet werden, sobald sie nach dem Lernen im laufenden Betrieb angewandt werden.
Dann lassen sie sich sogar (fast) direkt zur Pinsteuerung für H-Brücken verwenden.
Und natürlich gilt so etwas auch für Waschmaschinen, was definitiv auch nie von mir angezweifelt wurde.

Moppi
13.12.2019, 20:21
hier sehe ich logische Unschärfen bzw. Unmöglichkeiten, denn langsam kann nicht gleichzeitig dasselbe sein wie stehen.



Der Erste, für den linken Motor, der langsam vorwärts fährt oder steht (0); oder schneller vorwärts fährt (1).
Der Zweite, für den rechten Motor, der langsam vorwärts fährt oder steht (0); oder schneller vorwärts fährt (1).

Bedeutet, dass ich zwei Möglichkeiten der praktischen Umsetzung sehe.

Selbstverständlich gilt:
langsames Fahren ODER Stehen !== langsames Fahren && Stehen

Ergo:
langsames Fahren ODER Stehen

Aber:
Mir geht es nicht darum, eine Motorsteuerung im Detail vorzustellen.


Zu den Unschärfen schreibe ich jetzt nichts, das würde nicht gut ausgehen.

MfG
:Weihnacht

HaWe
13.12.2019, 20:41
für ein ODER brauchst du 2 seperate Outputs pro Motor, du kannst nicht 1 einzigen Output pro Motor ODERn.
Oder er kann immer nur 1 von beiden ausschließlich, aber nie optional und alternativ.
ODER du hattest es vorher oben unscharf (heißt: missverständlich) fomuliert.

Aber klar, du kannst auf meine Ratschläge aus meinem Wissen und meiner Erfahrung hören und daraus lernen, oder es bleiben lassen.

Moppi
14.12.2019, 07:21
für ein ODER brauchst du 2 seperate Outputs pro Motor, du kannst nicht 1 einzigen Output pro Motor ODERn.
Oder er kann immer nur 1 von beiden ausschließlich, aber nie optional und alternativ.
ODER du hattest es vorher oben unscharf (heißt: missverständlich) fomuliert.

Aber klar, du kannst auf meine Ratschläge aus meinem Wissen und meiner Erfahrung hören und daraus lernen, oder es bleiben lassen.

Ich hatte ja geschrieben, das Eine oder das Andere. Da die Wahrheitstabelle digital ist und das Netz nur auf "0" oder "1" trainiert wird,
folgt der logische Schluss, dass nicht beides gemeinsam verwendet werden kann. Das sieht man.

Aber klar, Dein Wissen und Erfahrung ....
Vielleicht sind für mich, nach 30 Jahren Programmieren und Konzipieren, manche Dinge auch einfach logisch, wenn ich nur kurz drüberlese.
Vielleicht sind daher meine eingestreuten Anmerkungen und Hinweise etwas missverständlich.

Einfach einmal so einen Antrieb und die Steuerung per "0" und "1" entwerfen und schauen, wie es funktionieren könnte, würde ich vorschlagen. Dann versteht Du es vielleicht besser.

Mit Deinem Wissen und Deiner Erfahrung kannst Du Dir aber auch schnell selbst eine rudimentäre Steuerung ausdenken, die einfach verständlich per KNN umzusetzen ist.
Weitere Vorschläge sind im Forum doch eigentlich immer gern gesehen.

Ich hatte auch schon gebeten, dass Du Dein Wissen und Deine Erfahrung über einen Workshop zum Thema darbieten könntest. Dann würde uns allen das mühselige Einarbeiten erspart und wir wären eher auf einem gemeinsamen Nenner. Aber da dies nicht passiert, geschieht zwangsläufig etwas anderes: dass wir jetzt ganz verschiedene Ansichten und Erfahrungen bekommen, was KNNe anbelangt, denn jeder setzt sich mit dem Thema selber auseinander, so gut er es kann. Und das bringt verschiedenste Lösungen hervor, in die sich jeder User hier hineindenken muss.


MfG
:Weihnacht

- - - Aktualisiert - - -

@HaWe
Übrigens ist das Thema "Workshop" noch nicht vom Tisch. Du kannst damit beginnen, wenn Du Dein Wissen und Deine Erfahrung teilen magst! Ich fände das gut und andere User hier offenbar auch.

Moppi
14.12.2019, 10:06
Natürlich kann die Steuerung des linken und rechten Motors verfeinert werden. Indem man, richtig von HaWe dargestellt, mehr Ausgangsneuronen verwendet.

Das, was vorgestellt wurde, ist ein sehr einfacher Lernmechanismus, bei dem die möglichen Eingangszustände vorgegeben sind.
Soll das Netz selbstständig lernen, zum Beispiel nur mit der Information, ob das Verhalten "richtig" oder "falsch" war, wird es komplizierter.
Denn in diesem Fall hat das KNN keine Vorgabe, welche Fälle es, mit welchem Ergebnis, trainieren muss. Das Wissen darüber (also die Wahrheitstabelle)
könnte wieder von einem KNN eingespeist werden. Auch das Wissen, welcher Ausgang dann wann aktiviert werden muss.
Anders könnte aber auch eine Zielvorgabe formuliert werden, die beschreibt, dass das Ergebnis immer dann richtig ist, wenn beide Eingangsneuronen
nicht aktiviert (0) sind, also kein Signal bekommen. Dieses Traingsverfahren könnte ewig dauern, weil der Roboter dann durch Zufall herausfinden muss,
wann die Linie überfahren wurde und wann sie sich zwischen den Sensoren befindet. Das kann auch dazu führen, dass sich der Roboter sehr weit von
der Linie entfernt und erst nach einigen Minuten oder Stunden die Linie erneut überquert. Womöglich könnte so ein unkoordiniertes Training dann
Tage, Wochen oder Monate dauern. Vielleicht ist es aber auch so, dass das KNN die Aufgabe gar nicht lösen kann, weil die Linie verloren wurde
und dann das Herumdrehen an den Gewichten, der einzelnen Neuronen, zu keinem Ergebnis führen kann oder zu einem falschen Ergebnis. Denn das
beide Lichtsensoren "0" liefern (Bedingung, die oben genannt wurde), wäre auch dann bewerkstelligt, wenn der Roboter ganz einfach die Linie nicht überquert.
Er könnte also einfach lernen, sich von der Linie fernzuhalten, ohne ihr zu folgen.

Würde das KNN nach der Wahrheitstabelle trainiert und der Roboter würde die Linie verlieren, würde er einfach weiter geradeaus fahren.

HaWe
14.12.2019, 12:43
Ich hatte, wie gesagt, dein "langsam oder stop" schlicht falsch verstanden, es war für mich unscharf bzw. missverständlich ausgedrückt.
Zum Workshop:
Ich finde nach wie vor, dass ein Linienfolger zu schwierig als Anfängerprojekt ist. Speziell ist es mir selber zu schwierig, eine Motorsteuerung per KI für Anfänger herunterzubrechen, sowohl (einfach) per Hard-Coding der Lernsets als auch (erst recht) für das echte autonome Muster-Training durch Abfahren von Linien samt manuell gemachter Korrekturen.
Selbst als Fortgeschrittenenprojekt ist letzteres recht anspruchsvoll, wenn es Sinn machen soll (hatte ich oben auch bereits grob umrissen).
Ich finde vielmehr, man sollte bei der Mustererkennung aus Mxts Link aufsetzen und als Anfängerprojekt einfach versuchen, andere Muster zu trainieren und dann multipel zu erweitern.

Ich habe meine diesbezüglichen Netze bereits konstruiert (und auch verlinkt).

Deine Erfahrung in Programmierung in allen Ehren, aber du hast bestimmt noch keine 10 Jahre selber verschiedene Netze programmiert und auch getestet und optimiert.
Aber wie Konfuzius sagt:
Der Mensch hat dreierlei Wege, klug zu Handeln;
erstens durch Nachdenken, das ist das Edelste,
zweitens durch Nachahmen, das ist das Leichteste,
und drittens durch Erfahrung, das ist das Bitterste.
Ich habe von daher überhaupt keine Probleme damit, wenn du deine eigene Erfahrung sammeln willst.

Moppi
14.12.2019, 13:06
Ich habe von daher überhaupt keine Probleme damit, wenn du deine eigene Erfahrung sammeln willst.

Offenbar hast Du es nicht verstanden, dass DU das tun solltest, uns das zu vermitteln.
Du machst es nicht.

Also gibt es zwei Möglichkeiten:
1. das Thema bleibt hier unbehandelt
2. wir beschäftigen uns selbst damit

Ich hatte auch schon mal Fragen gestellt, die ich nun teilweise selbst beantworten kann. Warum war Dir das nicht möglich? Weil Du das Wissen nicht hast?




selber verschiedene Netze programmiert und auch getestet und optimiert

Nein muss ich auch nicht. Ich will nicht jahrelang irgend etwas kopieren und damit herummachen. Das kann ich zu Anfang tun.

Falls es um Wissendiskussionen geht, habe ich hier und da schon gewissen Spielraum geschaffen, wo man diskutieren könnte, da vermisse ich aber Deine Teilnahme.


Deine Erfahrung in Programmierung in allen Ehren, ..

In der Äußerung zeigt sich, dass Du die nicht einzuschätzen vermagst.



So, HaWe. Um es zu beweisen, dass Du etwas davon verstehst, bevor wir hier sinnlos weiter diskutieren, möchte ich jetzt, dass Du uns erklärst, auf welchen Prinzipien des Rumguckers Code funktioniert und welche Aussichten auf eine Intelligenz er, jenseits eines XOR-Problemlösung, hat.

Ich bin jetzt kurz davor, gar nichts mehr zum Thema KNN auszuführen. Und Deine unquallifizierten Äußerungen zukünftig zu ignorieren oder gleich ganz hier weg zu bleiben.

Bitte zeige jetzt, was Du auf dem Kasten hast!
Nochmal die Fragestellung: dass Du uns erklärst, auf welchen Prinzipien des Rumguckers Code funktioniert und welche Aussichten auf eine Intelligenz er, jenseits eines XOR-Problemlösung, hat




MfG
:Weihnacht

HaWe
14.12.2019, 13:11
Offenbar hast Du es nicht verstanden, dass DU das tun solltest, uns das zu vermitteln.
Du machst es nicht.
Also gibt es zwei Möglichkeiten:
1. das Thema bleibt hier unbehandelt
2. wir beschäftigen uns selbst damit
Ich hatte auch schon mal Fragen gestellt, die ich nun teilweise selbst beantworten kann. Warum war Dir das nicht möglich? Weil Du das Wissen nicht hast?
selber verschiedene Netze programmiert und auch getestet und optimiert
Nein muss ich auch nicht. Ich will nicht jahrelang irgend etwas kopieren und damit herummachen. Das kann ich zu Anfang tun.
Falls es um Wissendiskussionen geht, habe ich hier und da schon gewissen Spielraum geschaffen, wo man diskutieren könnte, da vermisse ich aber Deine Teilnahme.
Deine Erfahrung in Programmierung in allen Ehren, ..
In der Äußerung zeigt sich, dass Du die nicht einzuschätzen vermagst.
So, HaWe. Um es zu beweisen, dass Du etwas davon verstehst, bevor wir hier sinnlos weiter diskutieren, möchte ich jetzt, dass Du uns erklärst, auf welchen Prinzipien des Rumguckers Code funktioniert und welche Aussichten auf eine Intelligenz er, jenseits eines XOR-Problemlösung, hat.
Ich bin jetzt kurz davor, gar nichts mehr zum Thema KNN auszuführen. Und Deine unquallifizierten Äußerungen zukünftig zu ignorieren oder gleich ganz hier weg zu bleiben.
Bitte zeige jetzt, was Du auf dem Kasten hast!
Nochmal die Fragestellung: dass Du uns erklärst, auf welchen Prinzipien des Rumguckers Code funktioniert und welche Aussichten auf eine Intelligenz er, jenseits eines XOR-Problemlösung, hat


WAS sollte ICH tun?

PS
du hast deinen Post nachträglich geändert, aber ich habe meinen Standpunkt ja nun schon mehrfach dargelegt.
Ich muss dir hier überhaupt nichts beweisen -
was ich von der Idee " KI-Linienfolger für Anfänger" halte, habe ich bereits geschrieben,
welche anderen Ansätze ich für sinnvoller halte, ebenfalls,
großartiges Interesse von anderen an KI erkenne ich nicht,
Anfänger arbeiten sich besser selber an Hand von Tutorials und Lehrbüchern selber in das Thema ein,
KI-Linienfolger interessiert mich selber überhaupt nicht, und würde es das, wäre das IMO eher ein Projekt für Fortgeschrittene.
Und nach speziell nach deinem - gelinde ausgedrückt - unkooperativen Verhalten im Topic html-Interface für KI und im Topic outdoor I werde ich bestimmt kein Anfänger- oder Fortgeschrittenen-Privat-Tutorial speziell für dich erstellen, sorry.
Alles weitere wurde bereits gesagt, und speziell zu gucki lies bitte bei gucki nach.

Moppi
15.12.2019, 07:37
Ich muss dir hier überhaupt nichts beweisen -


Musst Du nicht, aber Du kannst. Sonstige Hilfegesuche gehen ja an Dir vorbei.
Noch direkter konnte ich mich nicht ausdrücken.
Normal bringt man sein Wissen in Diskussionen mit ein.
Bei diesem Thema funktioniert das aber irgendwie nicht.

Kein Mensch hat was gegen Deine Meinung.
Du hast zu Anfang schon gesagt, dass Du davon nichts hältst, einen einfachen Linienfolger zu bauen.
Gut, ist doch in Ordnung, wurde gelesen und zur Kenntnis genommen! Aber mir scheint, dass für Dich
das nicht ausreichend ist. Wenn das dann doch diskutiert wird und Lösungsansätze vorgestellt werden,
gibst Du dazu Kommentare ab, weil Du was nicht verstanden hast, was nicht so schlimm ist,
ich erkläre das dann. - Vielleicht drücke ich mich manchmal auch nicht ganz 100% verständlich aus.
Deine Reaktion dann da drauf, unterm Strich: habe ich schon mal gesagt, dass ich das für zu schwer halte.


Du kannst immer wieder betonen, dass Du das für zu schwer hältst, vielleicht kommt die Diskussion dann
tatsächlich irgendwann zum Erliegen.



großartiges Interesse von anderen an KI erkenne ich nicht
Kann ich mir vorstellen. Ich sehe schon ein großes Interesse.
Was erwartest Du? Dass sich 50 User aus dem Forum hier melden und betteln, dass Du das tun sollst?
Das wurde ja praktisch schon gemacht, selbst Inka hat das vorgeschlagen. Erwartest Du, dass noch mehr
das machen?



Anfänger arbeiten sich besser selber an Hand von Tutorials und Lehrbüchern selber in das Thema ein
Deine Ansicht? Gut, ist auch kein Problem!
Aber dann lass sie das machen! Lass Leute sich in das Thema einarbeiten! Da muss man nicht dauernd dazwischen
gehen mit: ist zu schwer für Anfänger.. Habe ich schon mal gesagt, funktioniert so nicht..
Ich habe 10 Jahre Erfahrung, Du kannst auf mich hören oder es lassen ... und ähnliche Sachen.



Und nach speziell nach deinem - gelinde ausgedrückt - unkooperativen Verhalten im Topic html-Interface für KI und im Topic outdoor I


Kann mich zwar nicht erinnern, dass ich unkooperativ war, aber wenn Du das so sehen solltest, solltest Du Dich fragen, woran es gelegen haben könnte.
"im Topic html-Interface für KI" habe ich mehr als 24h Arbeit reingesteckt, ink. ausführlicher Schnittstellenbeschreibung.
"Topic outdoor I" hast Du nicht richtig gelesen, den Thread nicht richtig verfolgt. Angemahnt, dass Du mit dem Inhalt der Quelltexte nicht einverstanden bist,
in welcher Richtung auch immer. Du gehst mal eben bei zwei Usern, die an einem Quelltext arbeiten, der nicht von Dir stammt, dazwischen indem Du
den einfach änderst und wehement darauf bestehst, dass man sich an die Regeln halten soll, die Du gerade für gut hältst.





und speziell zu gucki lies bitte bei gucki nach


Das habe ich und deswegen wollte ich wissen, was Du dazu sagst.




Mein Vorschlag oder Wunsch:
Rücke von dem Prinzip ab: ich weiß alles besser und wer nicht auf mich hört ist selber Schuld, aber erklären tu ich nichts.
So kommen wir im Forum nicht weiter.






MfG
:Weihnacht

HaWe
15.12.2019, 08:39
ich habe gesagt, was zu sagen war - und selbst jetzt beweist du ja wieder, das du nichts besseres zu tun hast als meine wohlgemeinten Ratschläge ganz besonders auch in diesem Topic in pampiger Weise in den Wind zu schlagen als wäre Borniertheit eine Tugend - statt auf sie zu hören.
Und ich bin tatsächlich der Meinung, ich weiß es im eigentlichen Wortsinne "besser", während vor allem du derjenige bist, der ständig alles "besser weiß" - nur eben im übertragenen Sinne.
Ich bin daher hier erst mal raus, es sei denn vom OP kommen noch inhaltliche Vorschläge, die uns weiterführen.
Oder derart unsinnige Behauptungen von anderer Seite, die man einfach nicht unkorrigiert stehen lassen kann, um andere Leser nicht zu verwirren.
Du bist jetzt jedenfalls erst mal auf meiner ignore-Liste.

Moppi
15.12.2019, 09:51
ich habe gesagt, was zu sagen war - und selbst jetzt beweist du ja wieder, das du nichts besseres zu tun hast als meine wohlgemeinten Ratschläge ganz besonders auch in diesem Topic in pampiger Weise in den Wind zu schlagen als wäre Borniertheit eine Tugend - statt auf sie zu hören.
Und ich bin tatsächlich der Meinung, ich weiß es im eigentlichen Wortsinne "besser", während vor allem du derjenige bist, der ständig alles "besser weiß" - nur eben im übertragenen Sinne.
Ich bin daher hier erst mal raus, es sei denn vom OP kommen noch inhaltliche Vorschläge, die uns weiterführen.
Oder derart unsinnige Behauptungen von anderer Seite, die man einfach nicht unkorrigiert stehen lassen kann, um andere Leser nicht zu verwirren.
Du bist jetzt jedenfalls erst mal auf meiner ignore-Liste.

Ja, vielleicht hilft diskreditieren weiter.


:Weihnacht

inka
15.12.2019, 10:02
Du bist jetzt jedenfalls erst mal auf meiner ignore-Liste.

aus eigener erfahrung - das funktioniert nicht. Man möchte dann doch wissen was der andere "idiot" geschrieben hat :-)

noch einmal vielleicht andersherum zu meinen "bedürfnissen" was KI bzw. NN betrifft. Ich will keinen code schreiben bzw. entwickeln. Ich möchte am anfang an einem - für mich schon recht komplexen - beispiel wie dem hier z.b.



/************************************************** ****************
ArduinoANN - An artificial neural network for the Arduino
All basic settings can be controlled via the Network Configuration
section.
See robotics.hobbizine.com/arduinoann.html for details.
************************************************** ****************/

#include <math.h>

/************************************************** ****************
Network Configuration - customized per network
************************************************** ****************/

const int PatternCount = 10;
const int InputNodes = 7;
const int HiddenNodes = 8;
const int OutputNodes = 4;
const float LearningRate = 0.3;
const float Momentum = 0.9;
const float InitialWeightMax = 0.5;
const float Success = 0.0004;

const byte Input[PatternCount][InputNodes] =
{
{ 1, 1, 1, 1, 1, 1, 0 }, // 0
{ 0, 1, 1, 0, 0, 0, 0 }, // 1
{ 1, 1, 0, 1, 1, 0, 1 }, // 2
{ 1, 1, 1, 1, 0, 0, 1 }, // 3
{ 0, 1, 1, 0, 0, 1, 1 }, // 4
{ 1, 0, 1, 1, 0, 1, 1 }, // 5
{ 0, 0, 1, 1, 1, 1, 1 }, // 6
{ 1, 1, 1, 0, 0, 0, 0 }, // 7
{ 1, 1, 1, 1, 1, 1, 1 }, // 8
{ 1, 1, 1, 0, 0, 1, 1 } // 9
};

const byte Target[PatternCount][OutputNodes] =
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 1 },
{ 0, 0, 1, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 1 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 1 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 1 }
};

/************************************************** ****************
End Network Configuration
************************************************** ****************/


int i, j, p, q, r;
int ReportEvery1000;
int RandomizedIndex[PatternCount];
long TrainingCycle;
float Rando;
float Error;
float Accum;


float Hidden[HiddenNodes];
float Output[OutputNodes];
float HiddenWeights[InputNodes + 1][HiddenNodes];
float OutputWeights[HiddenNodes + 1][OutputNodes];
float HiddenDelta[HiddenNodes];
float OutputDelta[OutputNodes];
float ChangeHiddenWeights[InputNodes + 1][HiddenNodes];
float ChangeOutputWeights[HiddenNodes + 1][OutputNodes];

void setup() {
Serial.begin(9600);
randomSeed(analogRead(3));
ReportEvery1000 = 1;
for ( p = 0 ; p < PatternCount ; p++ )
{
RandomizedIndex[p] = p ;
}
}

void loop ()
{


/************************************************** ****************
Initialize HiddenWeights and ChangeHiddenWeights
************************************************** ****************/

for ( i = 0 ; i < HiddenNodes ; i++ )
{
for ( j = 0 ; j <= InputNodes ; j++ )

{
ChangeHiddenWeights[j][i] = 0.0 ;
Rando = float(random(100)) / 100;
HiddenWeights[j][i] = 2.0 * ( Rando - 0.5 ) * InitialWeightMax ;
}
}
/************************************************** ****************
Initialize OutputWeights and ChangeOutputWeights
************************************************** ****************/

for ( i = 0 ; i < OutputNodes ; i ++ )
{
for ( j = 0 ; j <= HiddenNodes ; j++ )
{
ChangeOutputWeights[j][i] = 0.0 ;
Rando = float(random(100)) / 100;
OutputWeights[j][i] = 2.0 * ( Rando - 0.5 ) * InitialWeightMax ;
}
}
Serial.println("Initial/Untrained Outputs: ");
toTerminal();
/************************************************** ****************
Begin training
************************************************** ****************/

for ( TrainingCycle = 1 ; TrainingCycle < 2147483647 ; TrainingCycle++)
{

/************************************************** ****************
Randomize order of training patterns
************************************************** ****************/

for ( p = 0 ; p < PatternCount ; p++)
{
q = random(PatternCount);
r = RandomizedIndex[p] ;
RandomizedIndex[p] = RandomizedIndex[q] ;
RandomizedIndex[q] = r ;
}
Error = 0.0 ;
/************************************************** ****************
Cycle through each training pattern in the randomized order
************************************************** ****************/
for ( q = 0 ; q < PatternCount ; q++ )
{
p = RandomizedIndex[q];

/************************************************** ****************
Compute hidden layer activations
************************************************** ****************/

for ( i = 0 ; i < HiddenNodes ; i++ )
{
Accum = HiddenWeights[InputNodes][i] ;
for ( j = 0 ; j < InputNodes ; j++ )
{
Accum += Input[p][j] * HiddenWeights[j][i] ;
}
Hidden[i] = 1.0 / (1.0 + exp(-Accum)) ;
}

/************************************************** ****************
Compute output layer activations and calculate errors
************************************************** ****************/

for ( i = 0 ; i < OutputNodes ; i++ )
{
Accum = OutputWeights[HiddenNodes][i] ;
for ( j = 0 ; j < HiddenNodes ; j++ )
{
Accum += Hidden[j] * OutputWeights[j][i] ;
}
Output[i] = 1.0 / (1.0 + exp(-Accum)) ;
OutputDelta[i] = (Target[p][i] - Output[i]) * Output[i] * (1.0 - Output[i]) ;
Error += 0.5 * (Target[p][i] - Output[i]) * (Target[p][i] - Output[i]) ;
}

/************************************************** ****************
Backpropagate errors to hidden layer
************************************************** ****************/

for ( i = 0 ; i < HiddenNodes ; i++ )
{
Accum = 0.0 ;
for ( j = 0 ; j < OutputNodes ; j++ ) {
Accum += OutputWeights[i][j] * OutputDelta[j] ;
}
HiddenDelta[i] = Accum * Hidden[i] * (1.0 - Hidden[i]) ;
}


/************************************************** ****************
Update Inner-->Hidden Weights
************************************************** ****************/


for ( i = 0 ; i < HiddenNodes ; i++ )
{
ChangeHiddenWeights[InputNodes][i] = LearningRate * HiddenDelta[i] + Momentum * ChangeHiddenWeights[InputNodes][i] ;
HiddenWeights[InputNodes][i] += ChangeHiddenWeights[InputNodes][i] ;
for ( j = 0 ; j < InputNodes ; j++ )
{
ChangeHiddenWeights[j][i] = LearningRate * Input[p][j] * HiddenDelta[i] + Momentum * ChangeHiddenWeights[j][i];
HiddenWeights[j][i] += ChangeHiddenWeights[j][i] ;
}
}

/************************************************** ****************
Update Hidden-->Output Weights
************************************************** ****************/

for ( i = 0 ; i < OutputNodes ; i ++ )
{
ChangeOutputWeights[HiddenNodes][i] = LearningRate * OutputDelta[i] + Momentum * ChangeOutputWeights[HiddenNodes][i] ;
OutputWeights[HiddenNodes][i] += ChangeOutputWeights[HiddenNodes][i] ;
for ( j = 0 ; j < HiddenNodes ; j++ )
{
ChangeOutputWeights[j][i] = LearningRate * Hidden[j] * OutputDelta[i] + Momentum * ChangeOutputWeights[j][i] ;
OutputWeights[j][i] += ChangeOutputWeights[j][i] ;
}
}
}

/************************************************** ****************
Every 1000 cycles send data to terminal for display
************************************************** ****************/
ReportEvery1000 = ReportEvery1000 - 1;
if (ReportEvery1000 == 0)
{
Serial.println();
Serial.println();
Serial.print ("TrainingCycle: ");
Serial.print (TrainingCycle);
Serial.print (" Error = ");
Serial.println (Error, 5);

toTerminal();

if (TrainingCycle == 1)
{
ReportEvery1000 = 999;
}
else
{
ReportEvery1000 = 1000;
}
}


/************************************************** ****************
If error rate is less than pre-determined threshold then end
************************************************** ****************/

if ( Error < Success ) break ;
}
Serial.println ();
Serial.println();
Serial.print ("TrainingCycle: ");
Serial.print (TrainingCycle);
Serial.print (" Error = ");
Serial.println (Error, 5);

toTerminal();

Serial.println ();
Serial.println ();
Serial.println ("Training Set Solved! ");
Serial.println ("--------");
Serial.println ();
Serial.println ();
ReportEvery1000 = 1;
}

void toTerminal()
{

for ( p = 0 ; p < PatternCount ; p++ )
{
Serial.println();
Serial.print (" Training Pattern: ");
Serial.println (p);
Serial.print (" Input ");
for ( i = 0 ; i < InputNodes ; i++ )
{
Serial.print (Input[p][i], DEC);
Serial.print (" ");
}
Serial.print (" Target ");
for ( i = 0 ; i < OutputNodes ; i++ )
{
Serial.print (Target[p][i], DEC);
Serial.print (" ");
}
/************************************************** ****************
Compute hidden layer activations
************************************************** ****************/

for ( i = 0 ; i < HiddenNodes ; i++ )
{
Accum = HiddenWeights[InputNodes][i] ;
for ( j = 0 ; j < InputNodes ; j++ )
{
Accum += Input[p][j] * HiddenWeights[j][i] ;
}
Hidden[i] = 1.0 / (1.0 + exp(-Accum)) ;
}

/************************************************** ****************
Compute output layer activations and calculate errors
************************************************** ****************/

for ( i = 0 ; i < OutputNodes ; i++ )
{
Accum = OutputWeights[HiddenNodes][i] ;
for ( j = 0 ; j < HiddenNodes ; j++ )
{
Accum += Hidden[j] * OutputWeights[j][i] ;
}
Output[i] = 1.0 / (1.0 + exp(-Accum)) ;
}
Serial.print (" Output ");
for ( i = 0 ; i < OutputNodes ; i++ )
{
Serial.print (Output[i], 5);
Serial.print (" ");
}
}


}


unter "anleitung" in den einstellungen etwas verändern und lernen wie ich diese verändern muss um ein bestimmtes ergebnis zu erreichen. Und vielleicht noch der hinweis, in welchem codeteil das passiert, wäre aber schon unter nice to have zu sehen...
Das würde mir zunächst einmal völlig reichen. Dazu muss ich keine 10 jahre lang (bewundernswert) die theorie studieren. Ich glaube nicht, dass Du - HaWe das kannst und willst - nichts für ungut...

@Moppi:

ein vorschlag. Ich habe vor jahren den versuch gestartet mit meinem enkel zusammen (der wohnt ca. 600km weit weg) einen roboter zu bauen. Dazu habe ich ca. ein dutzend video-tutorials aufgenommen, wie das (https://youtu.be/hBLPOkQM_hE) hier z.b. Natürlich geht es da nicht um KI oder NN, sondern um simple mechanik. Könntest Du Dir vorstellen Deine versuche in der richtung KI in einem video, also anders als schriftlich zu erklären? Man könnte auch den serialmonitor und die IDE aufnehmen und erklären was bei welcher änderung des codes passiert...
Auch wenn mein (technisches) englisch - allerdings hauptsächlich mechanik betreffend - nicht schlecht ist, der vorteil wäre, dass das video in deutsch wäre :-)

Moppi
15.12.2019, 11:29
unter "anleitung" in den einstellungen etwas verändern und lernen wie ich diese verändern muss um ein bestimmtes ergebnis zu erreichen. Und vielleicht noch der hinweis, in welchem codeteil das passiert, wäre aber schon unter nice to have zu sehen...
Das würde mir zunächst einmal völlig reichen.

So hatte das mal angefangen, irgendwo, aber es gab keine Antworten, in der Form, dass das mal wirklich zusammenhängend erklärt worden wäre.
In dem Thema, dass ich mal erstellt habe, habe ich schon, auf den von Dir angeführten Code, Bezug genommen. Dort kannst Du sehen, wie weit ich damit vorangeschritten bin. Dort habe ich auch selbst etwas zu den ursprünglichen Fragestellungen geschrieben.

Ich bin nun gezwungen worden, mich selbst mit dem Thema eingehend auseinanderzusetzen. Dabei sind mir viele Beispielerklärseiten über den Weg gelaufen. Um es kurz zu machen: so schwer ist es nicht. Und es ist besser, wenn man es in einer gewissen Tiefe verstanden hat. Man muss ja nicht die mathematisch abgeleiteten Formeln beherrschen und verstehen. Oftmals steht Anfangs schlicht eine Beobachtung und eine einfache Problembeschreibung. Siehe Herr Hebb. Mit Mathematik kann man diese Vorgänge dann beschreiben. Man kann aber auch anders ran gehen. Der Rumgucker hat das so gemacht. Und er war ja nicht auf einem schlechten Weg! Er war ja mit seinem Netz schon in der Weiterentwicklung. Als er ein zusätzliches Neuron eingeführt hat, um das XOR-Problem zu lösen. Die Art und Weise, die er dabei hatte... ist eine andere Frage... das war schon sehr herausfordernd und hat sicher nicht zuletzt deshalb bestimmte Reaktionen in der Diskussion hervorgebracht.

Der Code oben, Inka, ist auch noch nicht der Weisheit letzter Schluss. Da gibt es noch einige Sachen mehr dazu. Z.B. verschiedene Aktivierungsfunktionen und deren Auswirkungen auf das gesamte Netz. Dann kommt man zu Netzen mit mehr Schichten, als nur drei. Dann gibt es verschiedene Lernregeln/Lernmethoden, von denen jede ihre Vor und Nachteile hat, Backpropagation aber eine sehr verbreitete Methode ist.

Ich schreibe das nicht, weil ich es mal wieder "besser weiß", sondern einfach mal in die Richtung arbeiten möchte, dass man Einblick in das Thema bekommt.




MfG
:Weihnacht

- - - Aktualisiert - - -

Bezüglich des Codes habe ich schon damit begonnen, den auseinander zu nehmen und mir zu den einzelnen Vorgängen Fakten im Netz zu suchen, um daraus eine im Detail nachvollziehbare Beschreibung in Deutsch zu erstellen. Das habe ich gemacht, weil ich mich gerade selber in das Thema einarbeite. Erfahrungsgemäß ist dies der beste Zeitpunkt, so eine Beschreibung zu erstellen, weil dann am Umfassendsten auf die Fragen der Themenneulinge eingegangen wird. Aber ich bin noch nicht fertig, und - vielleicht auch verständlich - gerade etwas demotiviert, dass dann hier so öffentlich zur Verfügung zu stellen. Schauen wir mal. Vielleicht ergeben sich hier im Forum auch noch andere Möglichkeiten.

Holomino
15.12.2019, 11:32
Was ist denn eigentlich das Ziel der Sache?
Ein Linienfolger, der Kurven (einem Kreis) folgen kann?
Ein Linienfolger, der Ecken (einem Rechteck) folgen kann?
Ein Linienfolger, der Beides kann, aber zweifellos aufgrund der physikalischen Trägheit und dem Unvermögen, Ecken rechtzeitig zu sehen, nur langsam fährt?
Oder ein Linienfolger, der den Parcours erlernt, sich die Ecken merkt und rechtzeitig bremst, ansonsten aber auf Geraden und sanften Kurven Gummi gibt?

Moppi
15.12.2019, 12:22
Es ging wohl darum, anhand dieses Beispiels eines Linienfolgers (sicher auf einfachste Art und Weise umgesetzt), eine Beispielsteuerung durch ein KNN zu realisieren, sicher nicht zuletzt, um überhaupt erst einmal Verständnis für die Materie zu bekommen. Nur hier war dann die Grundlagenerarbeitung nicht gewünscht (das scheint bekannt zu sein), sondern einfach ein KNN vorzustellen, dass die Forderung erfüllen könnte, aber eben möglichst einfach (nach Möglichkeit einfachste Netzstuktur des KNN, auf das Nötigste reduziert - was das genau heißt, war glaub ich noch nicht so ganz klar).


MfG
:Weihnacht

Holomino
15.12.2019, 13:14
Hmm,
mit dem typischen Aufbau mit einer Reihe von Farb- oder Reflexlichtschranken an der Front ließe sich zusammen mit der Bewegung des Gefährts ja vielleicht ein grobes 2-D-Bild zusammenbasteln, über das sich mit einem NN zumindest die Klassifizierung "Gerade/Kurve/Ecke/Verzweigung" aufbauen ließe. Das wäre dann so etwas wie eine abgewandelte Handschrifterkennung.
Motorregelung oder Entscheidung, wohin man abzweigt, kann man ja auch außerhalb des NN programmieren.

Moppi
15.12.2019, 19:08
Im Grunde ist die Idee nicht schlecht. Aber ich glaube weit von einfach(st) entfernt. Mal sehen, vielleicht ist was Brauchbares hinzubekommen. Die Sensoren für einen Linienfolger habe ich schon. Dann probiere ich das mal mit herkömmlicher Programmierung. Das wird wohl funktionieren und dann mal sehen, ob derselbe Code als KNN-Geschichte funktioniert.
Bloß das so, wie es in dem Video zu sehen ist, hinzubekommen, wird vermutlich schwieriger. Das Teil trifft auf ein Hindernis und sucht sich scheinbar einen anderen Weg. Aber ich finde, das ist schon auf jeden Fall für ein Forum interessant, als Gemeinschaftsprojekt. Es wird nicht viel Hardware dafür benötigt. Interessant ist dabei, zunächst zu wissen, wie man sich die "Intelligenz" vorstellt. Vor allem wie, zumindest nach außen sichtbar, das Lernen stattfinden soll.


Das mit
dem typischen Aufbau mit einer Reihe von Farb- oder Reflexlichtschranken an der Front
kann ich mir noch nicht vorstellen. Aber wie wäre es mit 4x oder 5x BH1750? Zumindest haben die gewisse Lichtempfindlichkeit. Aber die Auflösung wäre so schlecht, dass damit womöglich kaum verwertbare Daten zusammen kommen.


MfG
:Weihnacht

inka
19.12.2019, 13:14
Im Grunde ist die Idee nicht schlecht. Aber ich glaube weit von einfach(st) entfernt. Mal sehen, vielleicht ist was Brauchbares hinzubekommen. Die Sensoren für einen Linienfolger habe ich schon. Dann probiere ich das mal mit herkömmlicher Programmierung. Das wird wohl funktionieren und dann mal sehen, ob derselbe Code als KNN-Geschichte funktioniert.
es ist ja nicht nur das mit dem "linienfolgen". Das allein geht vermutlich sogar mit einer standard-programmierung besser (weil schneller?) Auch hindernisse, lichtquellen, IR-baken und was weiss ich noch könnten da einfliessen...


Bloß das so, wie es in dem Video zu sehen ist, hinzubekommen, wird vermutlich schwieriger. Das Teil trifft auf ein Hindernis und sucht sich scheinbar einen anderen Weg. Aber ich finde, das ist schon auf jeden Fall für ein Forum interessant, als Gemeinschaftsprojekt. Es wird nicht viel Hardware dafür benötigt. Interessant ist dabei, zunächst zu wissen, wie man sich die "Intelligenz" vorstellt. Vor allem wie, zumindest nach außen sichtbar, das Lernen stattfinden soll.
welches video?





mit dem typischen Aufbau mit einer Reihe von Farb- oder Reflexlichtschranken an der Front ließe sich zusammen mit der Bewegung des Gefährts ja vielleicht ein grobes 2-D-Bild zusammenbasteln, über das sich mit einem NN zumindest die Klassifizierung "Gerade/Kurve/Ecke/Verzweigung" aufbauen ließe. Das wäre dann so etwas wie eine abgewandelte Handschrifterkennung.
Das mit kann ich mir noch nicht vorstellen. Aber wie wäre es mit 4x oder 5x BH1750? Zumindest haben die gewisse Lichtempfindlichkeit. Aber die Auflösung wäre so schlecht, dass damit womöglich kaum verwertbare Daten zusammen kommen.
Ich habe schon auch diese sensoren (https://www.ebay.de/i/352895817780?chn=ps&norover=1&mkevt=1&mkrid=707-134425-41852-0&mkcid=2&itemid=352895817780&targetid=301754823111&device=c&mktype=pla&googleloc=9043005&poi=&campaignid=1669209310&mkgroupid=60123319570&rlsatarget=pla-301754823111&abcId=1103836&merchantid=109820967&gclid=CjwKCAiA3OzvBRBXEiwALNKDP-fh9ZY8zKafLSNmDzlm1RGCrAlYpXXPEDlLpdmChhsv4HhZKehz XBoCPK8QAvD_BwE) ( https://www.ebay.de/i/352895817780?chn=ps&norover=1&mkevt=1&mkrid=707-134425-41852-0&mkcid=2&itemid=352895817780&targetid=301754823111&device=c&mktype=pla&googleloc=9043005&poi=&campaignid=1669209310&mkgroupid=60123319570&rlsatarget=pla-301754823111&abcId=1103836&merchantid=109820967&gclid=CjwKCAiA3OzvBRBXEiwALNKDP-fh9ZY8zKafLSNmDzlm1RGCrAlYpXXPEDlLpdmChhsv4HhZKehz XBoCPK8QAvD_BwE ) verwendet, die helligkeitsunterschiede waren gut zu verwenden...

Moppi
19.12.2019, 14:08
welches video?

Musst Du den Thread von Anfang an lesen! ;)


Übrigens, Dein eBay-Link funkt. nicht.


es ist ja nicht nur das mit dem "linienfolgen". Das allein geht vermutlich sogar mit einer standard-programmierung besser (weil schneller?)

Es geht doch darum, klein anzufangen. Und so ein Verständnis zu entwickeln.
Wir wollen doch nicht mit der Mondlandung anfangen, sondern erst mit dem Bau einer Rakete. :)


MfG

:Weihnacht

inka
19.12.2019, 14:50
ach, dumeinst das mit dem nibo-bee? Ich dachte da wäre noch was anderes....

https://www.youtube.com/watch?v=D0R-...qRWq0w&index=2 (https://www.youtube.com/watch?v=D0R-CtTEuEs&list=TLPQMDcxMjIwMTnH1pwrqRWq0w&index=2)

habe noch einmal mein ebaylink getestet, bei mir geht er - hier (https://www.ebay.de/i/352895817780?c...BoCPK8QAvD_BwE) noch einmal...

Moppi
19.12.2019, 15:54
Also lange Rede kurzer Sinn: bei dem eBay-Link bekomme ich Schriftgröße 86 mit dem Hinweis Daten speichern zu wollen und zwei Buttons.
Da die Schrift so riesig ist, kann ich nichts anderes sehen.

Ja, das mit dem Nibo-dings ... Haste gesehen?

MfG
:Weihnacht