Inhalte zur Vorlesungswoche #7, Informatik 1 im Wintersemester 2024/25
(EN google-translate)
(PL google-translate)
Themen
|
1 Einführung zu Künstliche Intelligenz (Wiederholung)
|
2 Einführung zu Neuronale Netze
75_Echtzeit3/01_NeuronaleNetze
75_Echtzeit3/01_NeuronaleNetze/01_Neuron
75_Echtzeit3/01_NeuronaleNetze/02_Backpropagation
75_Echtzeit3/01_NeuronaleNetze/03_Umsetzung
3 Programmierung eines sehr einfachen künstlichen Neurons
Erster Schritt: Implementierung der sigmoiden Funktion:
#include <iostream>
#include <math.h>
using namespace std;
//Aufgabe: Programmieren eines künstlichen Neurons:
//
//Wie kann man die sigmoide Funktion implementieren?
int main(void)
{
//Implementierung der sigmoiden Funktion:
double u;
double d=1.0;
cout<<"Geben Sie u ein:"<<endl;
cin>>u;
// e^x ist exp(x)
double out = 1.0/(1.0+exp(-d*u));
cout<<endl<<"sigmoid("<<u<<")="<<out<<endl<<endl;
cout<<endl<<"Hello world!"<<endl<<endl;
cout<<endl<<"exp(1)="<<exp(1.0)<<endl<<endl;
cout<<endl<<"exp(0)="<<exp(0.0)<<endl<<endl;
cout<<endl<<"exp(-10000000.0)="<<exp(-10000000.0)<<endl<<endl;
return 0;
}
Code 0-1: Erster Schritt: Implementierung der sigmoiden Funktion.
#include <iostream>
#include <math.h>
using namespace std;
//Aufgabe: Programmieren eines künstlichen Neurons:
//
//Wie kann man die sigmoide Funktion als C-Funktion implementieren?
double sigmoid(double d, double u)
{
double x = 1.0/(1.0+exp(-d*u));
return x;
}
int main(void)
{
//Implementierung der sigmoiden Funktion:
double u;
double d=1.0;
cout<<"Geben Sie u ein:"<<endl;
cin>>u;
// e^x ist exp(x)
double out = 1.0/(1.0+exp(-d*u));
double out2 = sigmoid(d,u);
double dd = 1.0;
double out3 = sigmoid(dd,u);
cout<<endl<<"sigmoid("<<u<<")="<<out<<endl<<endl;
cout<<endl<<"FUNKTION sigmoid("<<u<<")="<<out2<<endl<<endl;
cout<<endl<<"FUNKTION out3=sigmoid("<<u<<")="<<out3<<endl<<endl;
cout<<endl<<"Hello world!"<<endl<<endl;
cout<<endl<<"exp(1)="<<exp(1.0)<<endl<<endl;
cout<<endl<<"exp(0)="<<exp(0.0)<<endl<<endl;
cout<<endl<<"exp(-10000000.0)="<<exp(-10000000.0)<<endl<<endl;
return 0;
}
Code 0-2: Auslagerung der Berechnung in eine C-Funktion.
#include <iostream>
#include <math.h>
#define N 3
using namespace std;
//Aufgabe: Programmieren eines künstlichen Neurons:
//
//Wie kann man die sigmoide Funktion als C-Funktion implementieren?
double sigmoid(double d, double u)
{
double x = 1.0/(1.0+exp(-d*u));
return x;
}
int main(void)
{
double in[N]; //Drei Eingänge meines Neurons
double w[] = {0.5,0.7,0.9}; //Drei Gewichte, mit denen die Eingänge gewichtet werden.
//Der Benutzer gibt die drei Eingänge vor:
for(int i=0;i<N;i++)
{
cout<<"Geben Sie Input "<<i<<" ein:";
cin>>in[i];
cout<<endl;
}
double u = 0.0;
for(int i=0;i<N;i++)//gewichtete Summe bilden.
{
u = u + w[i]*in[i];
}
double out = sigmoid(1.0,u);
cout<<"Bei den genannten Eingängen liefert das Neuron den Wert "<<out<<endl;
return 0;
}
Code 0-3: Neuron mit drei Eingängen.
Umsetzung im Unterricht.
4 Programmierung eines sehr einfachen Neuronalen Netzes
Umsetzung im Unterricht.
5 Trainieren eines sehr einfachen Neuronalen Netzes
Umsetzung im Unterricht.
ÜBUNG
Aufgabe 1
Bild 0-1: Darstellung eines einfachen neuronalen Netzes "netz1".
|
a) Vollziehen Sie nach, dass das Programm unten wirklich die Netzstruktur oben abbildet. Beachten Sie, dass im Programm die gewichteten Summen als Argument der sigmoiden Funktion eingetragen sind. Das heisst beispielsweise , der Term in[0]*w[0]+in[1]*w[1] , der die gewichtete Summe bildet wird erst ausgewertet und das Ergebnis davon dann der Funktion als Input übergeben. Man hätte das Ergebnis der gewichteten Summe auch vor der Übergabe an die Funktion in einer Hilfsvariable zwischenspeichern können. Nur würde der Quelltext dann etwas an Übersichtlichkeit und Kompaktheit verlieren.
b) Schreiben Sie das nachfolgende Programm in geeigneter Weise so um, dass geprüft wird, ob die zu den Eingängen der Tabelle oben angegebenen Ausgänge auch stimmen. Anders gesagt: Das nachfolgende Programm soll so erweitert werden, dass bestimmte Werte für in[0] und in[1] durchgespielt werden und das daraus resultierende out[2] ausgegeben wird.
#include <iostream>
#include <math.h>
using namespace std;
double sigmoid(double d, double u)
{
double x = 1.0/(1.0+exp(-d*u));
return x;
}
int main(void)
{
double w[] = {-51.82,99.98,-16.26,6.34,45.94,-100.0};
double out[] = {0.0,0.0,0.0};
double in[] = {0.0,1.0};
double D=0.1;
//Berechnung der Ausgänge der Eingangsneuronenschicht:
out[0] = sigmoid(D,in[0]*w[0]+in[1]*w[1]);
out[1] = sigmoid(D,in[0]*w[2]+in[1]*w[3]);
//Berechnung der Ausgänge der Ausgangsneuronenschicht:
out[2] = sigmoid(D,out[0]*w[4]+out[1]*w[5]);
return 0;
}
Code 0-4: netz1.cpp
Aufgabe 2
Das nachfolgende Programm liefert die folgende Konsolenausgabe:
Test einer Funktion, die wie ein logisches UND-Gatter reagiert: false | false liefert 0 false | true liefert 0 true | false liefert 0 true | true liefert 1
Code 0-5: Konsolenausgabe.
#include <iostream>
#include <math.h>
using namespace std;
bool und(bool x, bool y)
{
bool z;
if(x==false && y==false)
z=false;
else if(x==false && y==true)
z=false;
else if(x==true && y==false)
z=false;
else //if(x==true && y==true)
z=true;
return z;
}
int main(void)
{
cout<<"Test einer Funktion, die wie ein logisches UND-Gatter reagiert:"<<endl;
cout<<"false | false liefert "<<und(false,false)<<endl;
cout<<"false | true liefert "<<und(false,true)<<endl;
cout<<"true | false liefert "<<und(true,false)<<endl;
cout<<"true | true liefert "<<und(true,true)<<endl;
return 0;
}
Code 0-6: Logisches UND-Gatter.
|
in0 in1 out 0 0 0 0 1 1 1 0 1 1 1 1
Code 0-7: Wahrheitstabelle eines logischen ODER-Gatters mit zwei Eingängen:
Aufgabe 3
|
|
|
Studentische Lösung zu Aufgabe 3:
#include <iostream>
#include <math.h>
using namespace std;
double sigmoid(double d, double u)
{
double x = 1.0/(1.0+exp(-d*u));
return x;
}
bool und(double x, double y)
{
double w[] = {-51.82,99.98,-16.26,6.34,45.94,-100.0};
double out[] = {0.0,0.0,0.0};
double D=0.1;
bool z;
//Berechnung der Ausgänge der Eingangsneuronenschicht:
out[0] = sigmoid(D,x*w[0]+y*w[1]);
out[1] = sigmoid(D,x*w[2]+y*w[3]);
//Berechnung der Ausgänge der Ausgangsneuronenschicht:
out[2] = sigmoid(D,out[0]*w[4]+out[1]*w[5]);
if(out[2]<0.5)
{
z = false;
}
else
{
z = true;
}
return z;
}
int main(void)
{
cout<<"Test einer Funktion, die wie ein logisches UND-Gatter reagiert:"<<endl;
cout<<"false | false liefert "<<und(0.0, 0.0)<<endl;
cout<<"false | true liefert "<<und(0.0, 1.0)<<endl;
cout<<"true | false liefert "<<und(1.0, 0.0)<<endl;
cout<<"true | true liefert "<<und(1.0, 1.0)<<endl;
return 0;
}
Code 0-8: Studentische Lösung zu Aufgabe 3.