ich versuche nur zu erreichen, dass wir die KI endlich von dem podest - ich bin nur was für absolute korypheen - runterstossen
Da bin ich ja bei Dir, deshalb erkläre ich das schon so, dass es verständlich ist.
Ich denke, "Künstliche Intelligenz" muss man zuerst mal durch so was wie "einstellbares Logikgatter" ersetzen. Um der Sache und der Grundfunktion dieses Quelltextes irgendwie gerecht zu werden.
Jetzt aber im ernst: ich wollte nur testen, was z.b. eine änderung an einem wert für konsequenzen für das ergebnis und die laufzteit hat...
Das hatte ich so auch etwa verstanden.
Die Eingangszustände nein. Die Ausgangszustände: nein.
Diese Zustände sind vorgegeben.
Für die Eingabe kannst Du digitale Signale verwenden "0" oder "1".
Eingang#1: Umgebungslichtsensor (Licht da: ja / nein)
Eingang#2: Endschalter an der Fahrzeugfront (an Hindernis gestoßen: ja / nein)
Für die Ausgabe kommt im Grunde auch "0" oder "1" raus:
Ausgang#1: Fahren oder Anhalten (Fahren = 1, Anhalten = 0)
Ausgang#2: Scheinwerfer (Licht an = 1, Licht aus = 0)
Mit einer Wahrheitstabelle kann man nun die Regeln aufstellen, wie zum Beispiel:
Wenn kein Umgebungslicht da ist und das Fahrzeug angestoßen ist, dann mache am Scheinwerfer das Licht aus und halte das Fahrzeug an.
Tabelle dafür:
Eingang#1,Eingang#2,Ausgang#1,Ausgang#2
----0------,----1------,------0------,----0------
Das entspräche einem Trainingsmuster (Pattern). Davon kannst Du so viele erstellen, wie der Speicher am Ende her gibt.
Das Programm lernt dann diese Regeln auswendig.
Später reagiert es auf die Eingangszustände mit den eingeübten Ausgangszuständen.
Falls Eingangszustände nicht definiert wurden, sie aber dennoch auftreten können, kann das KNN auch darauf reagieren, womöglich sogar "richtig", in unserm Verständnis, obwohl es diese Zustände nie trainiert hat. Erst hier zeigt sich dann die wirkliche Intelligenz, bis dahin kann man davon eigentlich noch nicht so recht sprechen (finde ich). Um das letztere Verhalten auszunutzen und das Netz möglichst intelligent zu machen, benötigt man mehr Schichten, u.U. einige Schichten mehr. Hier gibt es nur eine Zwischenschicht. Ohne diese eine Zwischenschicht würde das noch trauriger aussehen, mit der Intelligenz. Dann könnte das Netz sich noch nicht einmal eine XOR-Wahrheitstabelle "merken".
MfG
- - - Aktualisiert - - -
Mal kurz geschaut:
const int InputNodes = 2;
const int HiddenNodes = 2;
const int OutputNodes = 2;
const int PatternCount = 4:
Können zur Laufzeit nicht geändert werden, da der Compiler Speicherplatz für Arrays, aufgrund dieser Werte, organisiert.
Diese Werte sollten mit der Wahrheitstabelle übereinstimmen und dann muss neu kompiliert werden.
Gruß
- - - Aktualisiert - - -
den Quelltext mit den Eingabemöglichkeiten habe ich einmal angepasst, damit er wenigstens ein wenig funktioniert:
Code:
/******************************************************************
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
******************************************************************/
float LearningRate = 0.3;
float Momentum = 0.9;
float InitialWeightMax = 0.5;
float Success = 0.0004;
const int InputNodes = 2;
const int HiddenNodes = 2;
const int OutputNodes = 2;
const int PatternCount = 4; //zu trainierende Muster
const byte Input[PatternCount][InputNodes] =
{
{ 0, 0 },
{ 1, 0 },
{ 0, 1 },
{ 1, 1 }
};
//};
const byte Target[PatternCount][OutputNodes] =
{
{ 1, 1 },
{ 0, 1 },
{ 1, 0 },
{ 1, 0 }
};
/******************************************************************
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 ()
{
input_NN();
calculation();
}
/******************************************************************
Input
******************************************************************/
char str[10];
int charcount;
float intInput()
{
for(int i=0;i<10;i++)str[i]=0; // String-Puffer löschen
charcount = 0;
//memset(str, 0, sizeof(str)); // String-Puffer löschen
while (!Serial.available()); // Warten bis 1. Zeichen im Eingangspuffer
delay(100); // Warten auf weitere Zeichen im Eigangspuffer
while (Serial.available() && charcount < 10)
{
str[charcount] = Serial.read(); // Zeichen aus Eingangspuffer lesen
charcount++;
}
return atof(str); // String in Integer-Rückgabewert wandeln
}
void input_NN (void)
{
Serial.println();
Serial.println();
Serial.print("Geben Sie > LearningRate < (standard = 0.3)ein: ");
LearningRate = intInput();
Serial.println(LearningRate, 5);
Serial.print("Geben Sie > Momentum < (standard = 0.9)ein: ");
Momentum = intInput();
Serial.println(Momentum, 5);
Serial.print("Geben Sie > InitialWeightMax < (standard = 0.5)ein: ");
InitialWeightMax = intInput();
Serial.println(InitialWeightMax, 5);
Serial.print("Geben Sie > Success < (standard = 0.0004)ein: ");
Success = intInput();
Serial.println(Success, 5);
/*
Serial.print("Geben Sie > InputNodes < (standard = 2)ein: ");
InputNodes = intInput();
Serial.println(InputNodes);
Serial.print("Geben Sie > HiddenNodes < (standard = 2)ein: ");
HiddenNodes = intInput();
Serial.println(HiddenNodes);
Serial.print("Geben Sie > OutputNodes < (standard = 2)ein: ");
OutputNodes = intInput();
Serial.println(OutputNodes);
Serial.print("Geben Sie > PatternCount < (standard = 4)ein: ");
PatternCount = intInput();
Serial.println(PatternCount);
*/
/*
Serial.print("Das Ergebnis Wert1 * Wert2 ist = ");
long wert3 = (long)wert1 * wert2;
Serial.println(wert3);
*/
Serial.println();
}
void calculation()
{
/******************************************************************
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++)
{
yield();
/******************************************************************
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 (" ");
}
}
}
MfG
Lesezeichen