Ich habe das auch versucht, bei mir hat es funktioniert - Originalcode, ohne delay oder was anderes.
ich habe jetzt versucht, Mxt's verlinktes NN auf dem ESP8266 zum Laufen zu kriegen, aber die Routinen führen dazu, dass der esp dauernd rebootet (wschl wegen watchdog timeout) - fast wie ich es befürchtet habe.
Nach ein paar delay(1) zwischendrin rebootet er nicht mehr, aber es dauert nun sehr lange - mal gucken.....
http://robotics.hobbizine.com/arduinoann.html
- - - Aktualisiert - - -Code:// A Neural Network for Arduino // http://robotics.hobbizine.com/arduinoann.html // 2-layer Backpropagation net // modified by HaWe // version 0.0.2 #include <math.h> #define REPORT_N 100 /****************************************************************** * 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.00040; 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 ReportEvery_n; 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(115200); delay(1000); randomSeed(analogRead(3)); ReportEvery_n = 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 ; delay(1); 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++ ) { delay(1); 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 ******************************************************************/ ReportEvery_n = ReportEvery_n - 1; if (ReportEvery_n == 0) { Serial.println(); Serial.println(); Serial.print ("TrainingCycle: "); Serial.print (TrainingCycle); Serial.print (" Error = "); Serial.println (Error, 5); toTerminal(); if (TrainingCycle==1) { ReportEvery_n = REPORT_N-1; } else { ReportEvery_n = REPORT_N; } } /****************************************************************** * 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 (); ReportEvery_n = 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 (" "); } } }
Update:
konnte inzwischen ein paar delays wieder rausnehmen, klappt immer noch und ist wieder ein bisschen schneller.
- - - Aktualisiert - - -
jawohl, er hat das Training geschafft:
Code:TrainingCycle: 5375 Error = 0.00040 Training Pattern: 0 Input 1 1 1 1 1 1 0 Target 0 0 0 0 Output 0.00775 0.00009 0.00431 0.00639 Training Pattern: 1 Input 0 1 1 0 0 0 0 Target 0 0 0 1 Output 0.00092 0.00465 0.00439 0.99653 Training Pattern: 2 Input 1 1 0 1 1 0 1 Target 0 0 1 0 Output 0.00244 0.00013 0.99975 0.00190 Training Pattern: 3 Input 1 1 1 1 0 0 1 Target 0 0 1 1 Output 0.00038 0.00698 0.99533 0.99567 Training Pattern: 4 Input 0 1 1 0 0 1 1 Target 0 1 0 0 Output 0.00609 0.99732 0.00555 0.00466 Training Pattern: 5 Input 1 0 1 1 0 1 1 Target 0 1 0 1 Output 0.00173 0.99669 0.00484 0.99655 Training Pattern: 6 Input 0 0 1 1 1 1 1 Target 0 1 1 0 Output 0.00034 0.99465 0.99296 0.00011 Training Pattern: 7 Input 1 1 1 0 0 0 0 Target 0 1 1 1 Output 0.00005 0.99232 0.99417 1.00000 Training Pattern: 8 Input 1 1 1 1 1 1 1 Target 1 0 0 0 Output 0.99110 0.00002 0.00254 0.00019 Training Pattern: 9 Input 1 1 1 0 0 1 1 Target 1 0 0 1 Output 0.99327 0.00678 0.00002 0.99424 Training Set Solved! --------
Geändert von HaWe (01.11.2019 um 16:57 Uhr)
Ich habe das auch versucht, bei mir hat es funktioniert - Originalcode, ohne delay oder was anderes.
nin, er rebootet definitiv und startet dann neu:
Code:TrainingCycle: 100 Error = 0.04521 Training Pattern: 0 Input 1 1 1 1 1 1 0 Target 0 0 0 0 Output 0.06243 0.02479 0.05091 0.05631 Training Pattern: 1 Input 0 1 1 0 0 0 0 Target 0 0 0 1 Output 0.00231 0.06811 0.04512 0.94515 Training Pattern: 2 Input 1 1 0 1 1 0 1 Target 0 0 1 0 Output 0.04356 0.00191 0.98995 0.03381 Training Pattern: 3 Input 1 1 1 1 0 0 1 Target 0 0 1 1 Output 0.02843 0.06270 0.97317 0.97425 Training Pattern: 4 Input 0 1 1 0 0 1 1 Target 0 1 0 0 Output 0.05156 0.93669 0.03940 0.05695 Training Pattern: 5 Input 1 0 1 1 0 1 1 Target 0 1 0 1 Output 0.04218 0.96939 0.06712 0.98471 Training Pattern: 6 Input 0 0 1 1 1 1 1 Target 0 1 1 0 Output 0.00227 0.96866 0.92983 0.00949 Training Pattern: 7 Input 1 1 1 0 0 0 0 Target 0 1 1 1 Output 0.00317 0.92403 0.93362 0.99969 Training Pattern: 8 Input 1 1 1 1 1 1 1 Target 1 0 0 0 Output 0.91035 0.00619 0.03578 0.01782 Training Pattern: 9 Input 1 1 1 0 0 1 1 Target 1 0 0 1 Output 0.94078 0.07733 0.00163 0.93763 Soft WDT reset >>>stack>>> ctx: cont sp: 3ffffd30 end: 3fffffc0 offset: 01b0 3ffffee0: dc000000 3fba4933 35793c76 be0a39ef 3ffffef0: 9c5d2286 3f4dd77a 00000000 40201d95 3fffff00: 3ffe861d 3ffe861d 3ffee70c bff06660 3fffff10: 20000000 3ffee70c 00000006 4020baa3 3fffff20: 3ffee6c8 0000000c 3ffee70c 40201324 3fffff30: 3ffee5b4 3ffee514 0000001c 40be7a11 3fffff40: 00000007 3ffee700 3ffee734 40201dc0 3fffff50: 40100f78 002f51d8 3ffee6d4 3ffee734 3fffff60: 3ffee714 3ffee70c 00000006 402015e7 3fffff70: 0000000c 3ffee5a4 3ffe8688 4018fb97 3fffff80: 3a262eb6 00000070 b886e74e 3ffe866c 3fffff90: feefeffe 00000000 3ffee760 3ffee790 3fffffa0: 3fffdad0 00000000 3ffee760 40202634 3fffffb0: feefeffe feefeffe 3ffe8504 4010049d <<<stack<<< ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x4010f000, len 1384, room 16 tail 8 chksum 0x2d csum 0x2d v8b899c12 ~ld Initial/Untrained Outputs: Training Pattern: 0 Input 1 1 1 1 1 1 0 Target 0 0 0 0 Output 0.46877 0.38939 0.51073 0.54921 Training Pattern: 1 Input 0 1 1 0 0 0 0 Target 0 0 0 1 Output 0.47558 0.37645 0.46304 0.58882 Training Pattern: 2 Input 1 1 0 1 1 0 1 Target 0 0 1 0 Output 0.44487 0.38804 0.51166 0.58088 Training Pattern: 3 Input 1 1 1 1 0 0 1 Target 0 0 1 1 Output 0.46660 0.38491 0.47829 0.58919 Training Pattern: 4 Input 0 1 1 0 0 1 1 Target 0 1 0 0 Output 0.45748 0.37212 0.46751 0.59319 Training Pattern: 5 Input 1 0 1 1 0 1 1 Target 0 1 0 1 Output 0.49832 0.37738 0.48112 0.56172 Training Pattern: 6 Input 0 0 1 1 1 1 1 Target 0 1 1 0 Output 0.50337 0.38582 0.49144 0.56569 Training Pattern: 7 Input 1 1 1 0 0 0 0 Target 0 1 1 1 Output 0.46656 0.37699 0.46670 0.57934 Training Pattern: 8 Input 1 1 1 1 1 1 1 Target 1 0 0 0 Output 0.45989 0.38881 0.50251 0.56673 Training Pattern: 9 Input 1 1 1 0 0 1 1 Target 1 0 0 1 Output 0.44974 0.37243 0.47104 0.58365 TrainingCycle: 1 Error = 5.35015
Tatsache! Ist mir gar nicht aufgefallen, musste ich erst mal suchen gehen.
MfG
wenn du es jetzt laufen lässt (s.o., // version 0.0.2), wird der Zwischenstand alle 100 Iterationen angezeigt, da kann man den Lern-Fortschritt besser verfolgen.
Geändert von HaWe (01.11.2019 um 17:59 Uhr)
Hallo!
Ich möchte nochmal dran erinnern, was hier im Forum, für die breite Masse der User, fehlt.
Es kommen zwar, nun verstreut über verschiedene Threads, immer wieder Beispiele zu neuronalen Netzen,
davon gibt es auch sicher noch ganz viele, aber es ändert an der Problematik nichts. Deshalb nochmal zur
Erinnerung:
Mal ein Wunschzettel, welche Themen behandelt werden sollten:dass es jemand ganz genau erklärt, der die Essenz wirklich verstanden hat und das praktisch, auch an einem Programmbeispiel, mit meinetwegen nur 4 Neuronen in der ersten Schicht, Stück für Stück erklärt. Anhand eines Beispiels die programmtechnischen Zusammenhänge und Aufbau praktisch erläutert. Das Beispiel sollte funktionstüchtig sein.
1. Was sind Neuronen in einem NN?
2. Wie bilde ich ein Neuron im Programm (Arduino-C-Code) ab/nach?
3. Wie funktioniert die Gewichtung in einem NN, wie bilde ich dies im Programmcode ab/nach?
4. Wie "lernt" das Netz, wie bilde ich dies im Programmcode ab/nach?
5. Wie entsteht aus einem Eingangsmuster eine Zuordnung am Ausgang?
6. Wie speichere ich Gewichtungen aus dem Netz und lade sie wieder dort hinein, um das Netz verschiedene Aufgaben erledigen zu lassen?
7. Wie weiß ein Netz, wann es alles fertig ist mit Lernen und wann es das gelernte anwenden kann, also wie schalte ich ein Netz um, von Lernen auf Anwenden und wie sieht dies im Programmcode ganz genau aus, wie wird es realisiert?
Sicherlich fehlt hier noch mehr, was wichtig zu wissen ist. Diese Wunschliste darf gerne ergänzt werden!
Ansonsten: reichlich Links auf Bücher und Abhandlungen findet man zur Genüge bei den einschlägigen Suchmaschinen.
Ich denke, das muss nicht alles zusammengesucht und hier in die Threads kopiert werden. Viele Beispiele davon sind
nicht vollständig oder behandeln nur ganz bestimmte Aspekte eines neuronalen Netzes.
Freundliche Grüße
Moppi
ich bin nach wie vor der Meinung, dass damit das Forum hier samt möglicher Autoren überfordert ist. Man müsste wegen Copyrights selber neue Bilder malen und eigene mathematische Formeln per LaTeX einfügen, allein dieser Aufwand ist gewaltig und hier gar nicht zu schaffen - noch nicht mal verlinkte .png Bilder können hier eingefügt werden, und der Speicher für eigene geuploadede Bilder ist hier auch noch massiv begrenzt!!Mal ein Wunschzettel, welche Themen behandelt werden sollten:
1. Was sind Neuronen in einem NN?
2. Wie bilde ich ein Neuron im Programm (Arduino-C-Code) ab/nach?
3. Wie funktioniert die Gewichtung in einem NN, wie bilde ich dies im Programmcode ab/nach?
4. Wie "lernt" das Netz, wie bilde ich dies im Programmcode ab/nach?
5. Wie entsteht aus einem Eingangsmuster eine Zuordnung am Ausgang?
6. Wie speichere ich Gewichtungen aus dem Netz und lade sie wieder dort hinein, um das Netz verschiedene Aufgaben erledigen zu lassen?
7. Wie weiß ein Netz, wann es alles fertig ist mit Lernen und wann es das gelernte anwenden kann, also wie schalte ich ein Netz um, von Lernen auf Anwenden und wie sieht dies im Programmcode ganz genau aus, wie wird es realisiert?
Sicherlich fehlt hier noch mehr, was wichtig zu wissen ist. Diese Wunschliste darf gerne ergänzt werden!
Dazu gibt es aber ganze Bücher, die sich Schritt für Schritt damit beschäftigen.
Ich habe z.B.:
Uwe Lümmel, Jürgen Cleve: Lehr- und Übungsbuch Künstliche Intelligenz
Burkhard Lenze: Einführung in die Mathematik neuronaler Netze
Klaus Rädle: Neuronale Netze
Ich hatte allerdings oben schon einige Kurz-Tutorials verlinkt - besser als die es machen, könnte ich es auch nicht.
Suche z.B. in Wikipedia und per Google nach "Künstliches Neuron"
https://de.wikipedia.org/wiki/K%C3%BCnstliches_Neuron
mit schönen Bildern wie
Bild hier https://de.wikipedia.org/wiki/K%C3%B...el_deutsch.png,
Perzeptron,
Hebbsche Lernregel,
Perzeptron-Learning,
einschichtige Netze,
Feed-Forward-Netze,
mehrschichtoge Netze und dann auch nach
Backpropagation.
- - - Aktualisiert - - -
PS,
aber lies dir doch mal das hier sorgfältig durch https://de.wikipedia.org/wiki/K%C3%BCnstliches_Neuron ,
und wenn du dazu spezielle Verständnisfragen hast, dann frag einfach!
Geändert von HaWe (07.11.2019 um 18:13 Uhr)
Wie benötigen dieses Forum nicht, um Wissen zu Themen zu finden, auch in russischer Sprache oder in polnisch findet man interessante Ausführungen, wenngleich das meiste vermutlich in englisch verfasst wird.
Ich bin der Meinung, es sollte hier darum gehen, gemeinsam Lösungen zu erarbeiten, gemeinsam an Themen zu arbeiten. Irgendwie sollten doch die vielen kleinen Projekte zu Robotern, Steuerung usw., der einzelnen User, hier im "Roboternetz" unter ein Dach gebracht werden. Mit eine gemeinsamen Wissensbasis kann man sich doch besser verständigen; wenn diese auch noch in der Gemeinschaft gewachsen ist, um so besser. Nicht zuletzt deswegen ist ja sicher auch der RN-Standard für Schaltungen entstanden.
Es ist doch einen Versuch wert, für "Roboternetz" eine Entwicklung anzustoßen, die zukunftsorientiert ist, mit Themen, für die man sich gerne in diesem Forum austauschen mag.
MfG
Moppi
das ist aber jetzt eine ganz andere Fragestellung als
Zunächst braucht man für Projekte u.a. dieses gewisse Grundwissen.Mal ein Wunschzettel, welche Themen behandelt werden sollten:
1. Was sind Neuronen in einem NN?
2. Wie bilde ich ein Neuron im Programm (Arduino-C-Code) ab/nach?
3. Wie funktioniert die Gewichtung in einem NN, wie bilde ich dies im Programmcode ab/nach?
4. Wie "lernt" das Netz, wie bilde ich dies im Programmcode ab/nach?
5. Wie entsteht aus einem Eingangsmuster eine Zuordnung am Ausgang?
6. Wie speichere ich Gewichtungen aus dem Netz und lade sie wieder dort hinein, um das Netz verschiedene Aufgaben erledigen zu lassen?
7. Wie weiß ein Netz, wann es alles fertig ist mit Lernen und wann es das gelernte anwenden kann, also wie schalte ich ein Netz um, von Lernen auf Anwenden und wie sieht dies im Programmcode ganz genau aus, wie wird es realisiert?
Habe ich im Grunde ja gemacht, jetzt noch mal genauer in diesem Beitrag: https://www.roboternetz.de/community...l=1#post656114dann frag einfach
Aber da haben wir dann solche Antwort darauf:
Warum?ich bin nach wie vor der Meinung, dass damit das Forum hier samt möglicher Autoren überfordert ist.
Warum soll man überfordert sein?
Man kann ein Thema#1 aufmachen und fängt mit dem ersten Schritt an, etwas zu erklären. Dann lass doch das bei dem Beitrag, damit reichlich Kommentare angehängt werden können.
Für den nächsten Beitrag zu dem Thema NN, der dann auf dem Ersten aufbaut, mach ein neues Thema#2 auf, wo der nächste Schritt erklärt wird.
Usw.
Also nur so als Beispiel, das kann man vielleicht aber auch anders machen. Aber es sollte schon irgendwie eine Struktur haben. Querverweise zwischen den Themen kann man ja per Links einbauen.
MfG
Lesezeichen