Vorstudien zu den Projektthemen
(EN google-translate)
(PL google-translate)
Im folgenden soll zu jedem Projektthema ein Einstiegsprojekt umgesetzt werden, das in besserer Weise illustriert, wie die Themen zu interpretieren sind, als eine rein textliche Beschreibung. Außerdem werden dadurch Grundlagen vermittelt, die notwendig sind, um die Projekte erfolgreich zu behandeln. Da die KI-bezogenen Projekte aus dem Bereich Softcomputing stammen, soll dieser Begriff zunächst bestimmt werden und ein auf den hier vorliegenden Fokus (Implementierung auf eingebettete Systeme) begrenzter Überblick gegeben werden.
Softcomputing
Gebiet der Informatik, das sich teilweise mit Künstlicher Intelligenz überschneidet, in dem es darum geht, anstatt exakte Lösungen aufgrund vollständiger Information, gute Näherungslösungen bei unvollständiger Information zu finden.
Damit orientiert sich dieses Gebiet an den natürlichen menschlichen Gegebenheiten, wo es auch selten vollständige Informationen gibt, sondern einfache Anweisungen genügen müssen, um beispielsweise zu lernen, wie man Fahrad fährt.
Da diese Ansätze somit mit geringeren Informationsmengen klar kommen, ist auch deren Ressourcenbedarf i.d.R. geringer als bei vergleichbaren Standardlösungen, wie beispielsweise die Identifikation von Regelstrecken und die Auslegung eines Zustandsreglers mit Beobachter in der Regelungstechnik. Deshalb finden sich hier am ehesten Kandidaten an Grundtypen zur Lösung diverser informationstechnischer Aufgaben, die auch geeignet sind, auf eingebetteten Systemen implementiert zu werden.
In das Gebiet von Softcomputing fallen u.a.:
|
Siehe beispielsweise:
Neuro-Fuzzy
Neuro-Fuzzy ist ein Überbegriff, der verschiedene Ansätze Neuronale Netze und Fuzzy-Systeme kombiniert zu benutzen zusammenfaßt.
Im Allgemeinen besteht das Ziel der Kombination darin, die jeweiligen Nachteile des anderen Parts auszugleichen.
So zeichnen sich Neuronale Netze positiv dadurch aus, dass sie belernt werden können und dies auch während des Betriebs noch möglich ist. Andererseits ist das Wissen bei Neuronalen Netzen nicht explizit abrufbar, noch auf diese direkt übertragbar.
Bei Fuzzy-Systemen verhält es sich genau umgekehrt: Für Fuzzy-Systeme exisitert in ihrer Grundform kein Verfahren, um diese automatisch zu verbessern. Andererseits zeichnen sich Fuzzy-Systeme positiv dadurch aus, dass hier menschliches Wissen in Form von Wenn-Dann-Regeln auf Fuzzy-Sets direkt abgebildet werden kann und umgekehrt auch aus einem Fuzzy-System herausgelesen werden kann.
Folgende drei Grundansätze können bei Neuro-Fuzzy unterschieden werden:
|
Diese Aufteilung ist allerdings nur grob und die existierenden Ansätze sind sehr vielfältig und jeweils vom zu lösenden Problem abhängig. Allgemein repräsentieren sie aber in allen Fällen eine effizientere Lösungsstrategie, die weniger Ressourcen benötigt, als eine Konzentration auf einen einzigen Ansatz. Damit bilden sie einen vielversprechenden Einstiegspunkt, um unter den Kandidaten der KI-Techniken solche zu identifizieren, die prinzipiell gute Voraussetzungen dafür bieten, in eingebetteten Systemen eingesetzt zu werden.
Literatur zu Softcomputing und Neuro-Fuzzy
Autor | Titel | erschienen bei | Hinweise |
---|---|---|---|
Tettamanzi, A., Tomassini, M. | Softcomputing - Integrating Evolutionary, Neural, and Fuzzy Systems | Springer, Heidelberg, 2001 | Gute Auswahl an vertieft behandelten Techniken |
Borgelt, C. Klawonn, F., Kruse, R., Nauck, D. | Neuro-Fuzzy-Systeme | Vieweg, Wiesbaden, 2003 | Umfassend |
Zacher, S., Reuter, M. | Regelungstechnik für Ingenieure | Springer, Wiesbaden, 2008 | Neuro- und Fuzzy-Regler werden u.a. behandelt |
Aliev R.A., Kacprzyk, J., Pedrycz, W., Jamshidi, M., Sadikoglu, F.M. (Editoren) | 13th International Conference on Theory and Application of Fuzzy Systems and Soft Computing - ICAFS-2018 | Springer, Cham, 2019 | Konferenzband / aktuelle Forschung |
Tabelle 0-1: Literatur zu Softcomputing und Neuro-Fuzzy
Einstiegsprojekte zu den FPGA-Themen
FPGA#1 -- Gewinnung eines analogen Eingangs unter Verwendung mehrerer digitaler Eingänge und unter Einbeziehung der mit std_logic erfaßbaren Zwischenzustände am Beispiel eines analogen Entfernungssensors.
Ein erster Schritt könnte sein zunächst zu prüfen, inwieweit die einzelnen möglichen Zustände von STD_LOGIC durch Anschluß eines Potentiometers als Spannungsteiler an einem einfachen digitalen PMOD-Eingang abgerufen werden können und wie stabil diese Zustände sind, bzw. wie sauber die zugehörigen Bereiche definiert sind und ineinander übergehen.
Zustand | Bedeutung | sinnvoller Kandidat |
---|---|---|
'1' | Logisch 1 / true | JA |
'0' | Logisch 0 / false | JA |
'H' | schwache logische 1 | JA |
'L' | schwache logische 0 | JA |
'U' | nicht initialisiert | NEIN |
'X' | unbekannt | eventuell |
'Z' | fließend | NEIN |
'-' | nicht von Belang | NEIN |
Tabelle 0-2: Mögliche Zustände von std_logic und deren Bedeutung.
Bild 0-1: Anschluß eines Trimmpotentiometers (ev. Voltmeter ergänzen). ACHTUNG: PMOD-Buchse muß als digitaler Eingang konfiguriert sein (ohne Pullup).
Die oben als sinnvolle Kandidaten bezeichneten Zustände könnte mittels eines Programms bei ihrem Eintreten mit dem Aufleuchten einer bestimmten LED gekoppelt sein.
FPGA#2 -- Emulation einer einfachen UART/RS232 Verbindung an zwei digitalen Pins. Simples Sendebeispiel und simples Empfangsbeispiel als erster Test, dann Modularisierung mit Beispiel und Anleitung. Arduino dient als Zwischenstation zum PC. Eventuell Erweiterung hin zu einer Midi-Schnittstelle.
|
Funktion des nachfolgenden Beispiels:
|
Hinweise zur Emulation: https://www.vs.inf.ethz.ch/edu/WS9900/VS/VernetSys5.pdf
|
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity serial is Port ( MEINECLOCK : in STD_LOGIC; TXD : out STD_LOGIC); end serial; architecture Behavioral of serial is --constant pattern: STD_LOGIC_VECTOR(0 to 32) := "110_10000010_110_01000010_110_11000010"; -- !!!! to NICHT DOWNTO hier !!!! -- Pause zwischen Frames um 2 Zyklen verlängert: 11110 statt 110. constant pattern: STD_LOGIC_VECTOR(0 to 38) := "111101000001011110010000101111011000010"; signal zaehler : integer range 0 to 83332 := 0; --1200Baud signal index : integer range 0 to 39 := 0; signal logikpegel : std_logic := '1'; -- Beim Start sicherer High-Pegel begin process begin wait until rising_edge(MEINECLOCK); if (zaehler<83332) then zaehler <= zaehler+1; else zaehler <= 0; logikpegel <= pattern(index); index <= index +1; if (index=39) then index <= 0; end if; end if; end process; TXD <= logikpegel; end Behavioral;
Code 0-1: VHDL-File, das mit 1200Baud seriell ABCABCABC usw. sendet.
## 100MHz Clock auf Board NET "MEINECLOCK" LOC = "R4"; ## PMOD-Ausgang NET "TXD" LOC = "AB18"; NET "MEINECLOCK" IOSTANDARD = LVCMOS25; NET "TXD" IOSTANDARD = LVCMOS12;
Code 0-2: Zugehörige Constraints
//Leitet empfangene serielle //Daten von Serial1 an Serial0 (PC) weiter. void setup() { Serial.begin(9600); Serial1.begin(1200); } int zeichen = 32; void loop() { if(Serial1.available()) { Serial.write(Serial1.read()); } }
Code 0-3: Arduino-Programm zum Empfangen und Weiterleiten der Daten
Bild 0-2: Verbindung zwischen Nexys-Video und Arduino-Micro. AB18->RXD, GND->GND
Bild 0-3: Ausgabe auf Serial Monitor in der Arduino IDE.
FPGA#3 -- Recherche zu effizienten Möglichkeiten PWM-Signale zu erzeugen. Testfall: Ausgabe eines hörbaren, möglichst glatten Sinustones an einem Digitalen Ausgang durch hochfrequente Pulsung.
Siehe als Einstiegsbeispiel folgende Umsetzung zur Erzeugung und zyklischen Veränderung eines Pulsweiten modulierten Signals mit reinen VHDL-Mitteln unter Einsatz mehrerer parallel laufender Prozesse:
FPGA#4 -- Konzept und Umsetzung: Fuzzy-Implementierung auf einem FPGA.
Der Kompatibilität zu dem zuvor entwickelten diskreten Neuronalen Netz wegen, sollte der gleiche Zahlenbereich wie dort verwendet werden (2 Byte signed Integer, short in Java).
Gewisse Vereinfachungen bei der Möglichkeit, wie ein Fuzzy-Set geformt sein kann, sollten ausgenutzt werden, wie: Fuzzygrößen sind immer symmetrisch, im Ausgangsset ev. sogar alle gleich breit. An Testfall sollte die Brauchbarkeit belegt werden.
Für Hinweise zu einer konkreten Umsetzung siehe auch die nachfolgenden Fallbeispiele im KI-Bereich.
Einstiegsprojekte zu den KI-Themen
Als Beispielaufgabe wird die Beruhigung eines linearen Feder-Masse-Systems mittels eines Regelkreises benutzt. Die Einfachheit des Systems und auch die Einfachheit der Lösung bei der Regelung gewährleistet, dass nicht unnötig Arbeit in das Verständnis des Beispiels gesteckt werden muß.
Im Hinblick auf eine eventuelle nachfolgende Diskretisierung und Übertragung auf einen FPGA, wird auch das Modell selbst und dessen Integration so gewählt, das dies prinzipiell möglich ist:
|
$ \ddot x = -q \cdot x $
Formel 0-1: System.
$ T= \frac {2 \cdot pi}{ \sqrt q} $
Formel 0-2: Periode
$ q=\left( \frac {2 \cdot pi}{T}\right)^2 $
Formel 0-3: ...mit T=200 ergibt sich ungefähr für q=1/1000
Die Masse m wird der Einfachheit halber mit 1kg angesetzt.
Klassische Lösung zuerst: Zustandsregler.
Die maximal verfügbare Kraft soll begrenzt sein. Die Obergrenze wird einfach anhand der Lösung beim Zustandsregler festgelegt. Ansatz hier: technische Stabilität, EW bei -sqrt(q)+/-i*sqrt(q)
$ \ddot x = -q \cdot x + F $
Formel 0-4: System.
$ F = -r_1 \cdot x-r_2 \cdot v $
Formel 0-5: Regler.
q=1/1000 ppol([0,1;-q,0],[0;1],[-sqrt(q)+%i*sqrt(q),-2*sqrt(q)-%i*sqrt(q)]) ... r1,r2 mit ppol in Scilab bestimmen.
Code 0-4: liefert: r1=0.002, r2=0.0948683
clear; m = 1.0; C = 0.001; //q r1=0.002; r2=0.0948683; function f = rechteSeite(t,y) x = y(1,1); v = y(2,1); F = -r1*x-r2*v; f(1,1) = v; f(2,1) = -(C/m)*x + F/m; endfunction t = 0:10:2000; y0 = [10000,0]'; t0 = 0; y = ode(y0,t0,t,rechteSeite); x = y(1,:); v = y(2,:); F = -r1.*x-r2.*v; plot(t,y(1,:)',t,y(2,:)'); //plot(t,F);
Code 0-5: Scilab-Skript.
Bild 0-4: Verlauf von x (blau) und v (grün).
Bild 0-5: Verlauf der Stellkraft F. Somit kann als Limit für F ein Betrag von 20N angesetzt werden.
Dieses Beispiel ist ideal zur Regelung mit einem Zustandsregler. Beim invertierenden Pendel mit Aufschwingen läßt sich dagegen die Gesamtanforderung nicht mit klassischen Mitteln erfüllen.
(Aber schon eine Begrenzung der Kraft auf unterhalb von 20N würde das ändern.)
KI#1 -- Abbildung eines flexibel beschreibbaren Fuzzy-Systems auf ein "gängiges" Neuronales Netzwerk mit Nachweis des Fehleranteils und mit Codegenerator für Java. Hier funktioniert Backpropagation.
Das vorangehende Beispiel wird nach Java übertragen und dann ein Fuzzy-Regler implementiert.
KI#2 -- Abbildung eines flexibel beschreibbaren Fuzzy-Systems auf ein diskretisiertes Neuronales Netzwerk mit Nachweis des Fehleranteils und mit Codegenerator für VHDL. Hier funktioniert Backpropagation nicht.
Bild 0-6: Entwurf eines Fuzzy-Reglers für das "Beruhigungssystem" oben. In Hinblick auf die Implementierung wurden statt Namen für die Fuzzygrößen wurden "symbolische Indices" eingeführt. Der Regelsatz ist vollständig. Er kombiniert jede Fuzzy-Größe von x und v mit UND und ordnet jedem Paar eine Ausgangs-Fuzzygröße zu.
public class FuzzyRegler { float[] xset = {-10000.0,-5000.0,0.0,5000.0,10000.0}; float[] vset = {-300.0,-150.0,0.0,150.0,300.0}; float[] fset = {-60.0,-40.0,-20.0,0.0,20.0,40.0,60.0}; int[][] regeln = { { 2, 2, 1, 1, 0}, { 2, 1, 1, 0,-1}, { 1, 1, 0,-1,-1}, { 1, 0,-1,-1,-2}, { 0,-1,-1,-2,-2} }; /* //Etwas "laxere" Regeln als Alternative int[][] regeln = { { 2, 1, 1, 0, 0}, { 1, 1, 0, 0, 0}, { 1, 0, 0, 0,-1}, { 0, 0, 0,-1,-1}, { 0, 0,-1,-1,-2} }; */ //Merker für Erfülltheitsgrade: float[] e_xset = {0.0,0.0,0.0,0.0,0.0}; float[] e_vset = {0.0,0.0,0.0,0.0,0.0}; float[][] e_regeln = { {0.0,0.0,0.0,0.0,0.0}, {0.0,0.0,0.0,0.0,0.0}, {0.0,0.0,0.0,0.0,0.0}, {0.0,0.0,0.0,0.0,0.0}, {0.0,0.0,0.0,0.0,0.0} }; public float berechneF(float x, float v) { // 1. Erfülltheitsgrade der einzelnen Fuzzy-Größen aus den Eingangs-Fuzzy-Sets: //----------------- xset ---------------------------- for(int i=0;i<e_xset.length;i++) e_xset[i]=0.0; if(x<=xset[0]) e_xset[0]=1.0; else if(x>=xset[xset.length-1]) e_xset[xset.length-1]=1.0; else { for(int i=1;i<xset.length-1;i++) { if(x>xset[i-1] && x<=xset[i]) { e_xset[i] = (x-xset[i-1])/(xset[i]-xset[i-1]); e_xset[i-1] = 1.0 - e_xset[i]; } else if(x>xset[i] && x<=xset[i+1]) { e_xset[i+1] = (x-xset[i])/(xset[i+1]-xset[i]); e_xset[i] = 1.0 - e_xset[i+1]; } } } //----------------- vset ---------------------------- for(int i=0;i<e_vset.length;i++) e_vset[i]=0.0; if(v<=vset[0]) e_vset[0]=1.0; else if(v>=vset[vset.length-1]) e_vset[vset.length-1]=1.0; else { for(int i=1;i<vset.length-1;i++) { if(v>vset[i-1] && v<=vset[i]) { e_vset[i] = (v-vset[i-1])/(vset[i]-vset[i-1]); e_vset[i-1] = 1.0 - e_vset[i]; } else if(v>vset[i] && v<=vset[i+1]) { e_vset[i+1] = (v-vset[i])/(vset[i+1]-vset[i]); e_vset[i] = 1.0 - e_vset[i+1]; } } } // 2. Erfülltheitsgrade der Regeln: for(int i=0;i<e_vset.length;i++) { for(int k=0;k<e_xset.length;k++) { // MIN(x,v) if(e_xset[k]<e_vset[i]) e_regeln[i][k] = e_xset[k]; else e_regeln[i][k] = e_vset[i]; } } // 3. Schwerpunktbestimmung im Ausgangs-Fuzzyset float F=0.0; float zaehler = 0.0; float nenner = 0.0; for(int i=0;i<regeln.length;i++) { for(int k=0;k<regeln[i].length;k++) { int index = regeln[i][k] + 3; //index des zur aktuellen Regel gehörenden fset-Maximums float mitte = fset[index]; float basisbreite = fset[index+1] - fset[index-1]; float hoehe = e_regeln[i][k]; float steigung = 1.0/(fset[index]-fset[index-1]);// ... einer Trapezseite float delta = hoehe/steigung;// hoehe = steigung*delta => delta = hoehe/steigung float flaeche = hoehe*( basisbreite + (basisbreite-2.0*delta) )*0.5; nenner += flaeche; zaehler += flaeche*mitte; } } if(nenner>0.0) F = zaehler/nenner; return F; } }
Code 0-6: Klasse FuzzyRegler des Fuzzy-Reglers in nachfolgendem Projekt:
Bild 0-7: Auslenkung mit Zustandsregler (schwarz) und mit Fuzzy-Regler (rot).
Bild 0-8: Verwendung der "laxeren" Regeln (vergl. Quelltext FuzzyRegler). Auslenkung mit Zustandsregler (schwarz) und mit Fuzzy-Regler (rot).
Bild 0-9: Plot zu Beruhigung003HneuroZwischenschicht. schwarz=Zustandsregler, rot=Fuzzy-Regler, grün=belernter NN-Regler, blau=belernter NN-Regler nach Optimierung ("Tuning").
Hinweise - Diskussion - Zusammenfassung
|
KI#3 -- Untersuchung zu Reinforced Learning eines diskretisierten Neuronalen Netzes mit Unterstützung durch ein Fuzzy-System.
|
Empfehlung für einen Ansatz: Tatsächlich könnte sogar das Fuzzy-System den Gegner in einem Spiel repräsentieren und das NN mittels der durchgeführten Spiele trainieren.
KI#4 -- Fuzzy-Regler mit nachgeschaltetem vor belerntem Neuronalen Netz, das sich automatisch an Parameterveränderungen bei einem invertierenden Pendel anpaßt.
Diese Aufgabe fällt in die dritte Kategorie bei den Varianten von Neuro-Fuzzy: Hier ist ein NN dem Fuzzy-System vor- bzw. nachgeschaltet, um die Ein- bzw. Ausgaben vor- bzw. nachzuverarbeiten.
Der Nachteil dieses Ansatzes liegt darin, dass hier kein verstehbares Verhalten auf das NN übertragen wird, sondern lediglich die Plastizität (Lernfähigkeit) des NN ausgenutzt wird, um nicht ganz optimales Verhalten des Fuzzy-Systems auszugleichen.
Die Inflexibilität und Kompliziertheit was die Anpassungs- und Veränderbarkeit eines Fuzzy-Systems betrifft, wird hier also durch den Einsatz eines NN als Pre- oder Postprozessor kompensiert.
Wieder kann die Methode des Reinforced Learnings eingesetzt werden, wie sie beispielhaft in dem ausführlich dargestellten Projekt oben als "Tuning" bezeichnet wurde.
Hybride Systeme
Neuronale Netze, deren Struktur unmittelbar als Fuzzy-System interpretiert werden kann, stellen sicher die eleganteste und effizienteste Methodik bei Neuro-Fuzzy dar.
Hierbei müssen aber neuartige Schwellwertfunktionen und Verbindungsarten eingeführt werden, um diese Hybridheit tatsächlich umzusetzen.
Ansätze sehen grob erklärt wie folgt aus:
|
|
|
|
Da die Vorteile des hybriden Ansatzes aber erst zum Tragen kommen, wenn alle Fuzzy-Funktionen durch differenzierbare Funktionen ersetzt werden und darauf aufsetzend eigene Lernmethoden für die entstehenden speziellen Netze entwickelt werden, wird im Rahmen dieser Lehrveranstaltung auf die Einführung dieser Technik verzichtet. Einerseits müßte hier eine ganz eigene Theorie neu erlernt werden, was das Belernen, aber auch was die Interpretation der Netze als Fuzzy-Systeme anbelangt. Zum andern aber läuft die Forderung differenzierbare Funktionen und damit zwangsweise Fließkommazahlen zu verwenden konträr zu dem hier verfolgten Ansatz, leichtgewichtige, diskret umsetzbare KI-Techniken so anzupassen, dass sie sich gut auf eingebettete Systeme übertragen lassen.