ich war hier: TutoriumMobileEingebetteteIntelligenzSS18

Tutorium Mobile und Eingebettete Intelligenz



Tutor: Timmy Schieck

Adressaten des Lehrangebotes:
Studenten des Studienganges "Mobile Computing"

Ziel des Tutoriums:
Es wird eine App fuer Android erstellt, die in der Lage ist, in die Luft "gemalte" Gesten mit einer hohen Zuverlässigkeit zu erkennen. z.B. Kreise, Linien, Quadrate, etc.
Die App führt die Erkennung mittels eine trainierten neuronalen Netzes durch, was zuvor auf einem Computer trainiert wurde.
Das Training dieses Netzes benötigt Trainings-und Testdaten, die vorher aufgezeichnet werden.

Es werden dazu drei Anwendungen geschrieben:
1. eine App zum aufzeichen und labeln der gewünschten Muster
2. ein Computerprogramm welches die aufgezeichneten Trainingsdaten so verarbeitet wie das Smartphone, und danach das neuronale Netz trainiert
3. eine App die das trainierte neuronale Netz ausführt und damit die Bewegungen erkennt

Wenn nicht anders angegeben, bin ich der Urheber der Bilder, in dieser Wiki.

1. Datengewinnung/-erhebung:

Die meisten Android-Smartphones verfügen über mindestens drei Sensoren zur Bewegungserkennung:

  • den (linearen) Beschleunigungssensor,
  • das Gyroskop sowie
  • den Schwerkraftsensor.

Es gibt weitere Sensoren, das sind aber die Grundlegenden.
Diese Sensoren werden genutzt um die Bewegungen in Signale umzuwandeln.

Genutztes Koordinatensystem

Das Koordinatensystem ist relativ zum Bildschirm des Telefons in seiner Standardausrichtung definiert.
Die Achsen werden nicht vertauscht, wenn sich die Bildschirmausrichtung des Geräts ändert.

Die X-Achse ist horizontal und zeigt nach rechts, die Y-Achse ist vertikal und zeigt nach oben und die
Z-Achse zeigt zur Außenseite der Vorderseite des Bildschirms. In diesem System haben Koordinaten hinter dem Bildschirm negative Z-Werte.

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/1.png)
Abb.: Achsen eines Smartphones:
(Quelle: developer.android.com)

Funktionsweise der App

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/2.png)
Abb.: Grafische Oberfläche der Aufzeichnungsanwendung

Auf der linken Seite wird die Geste eingestellt die aufgezeichnet wird. Zum Aufzeichnen wird der Knopf in der Mitte gedrückt und gehalten, wenn die Aufzeichnung beendet ist, den Knopf bitte loslassen. Danach schreibt die App selbständig die Dateien mit den entsprechenden Sensorwerten in den Speicher des Telefons.

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/3.png)
Abb.: Verzeichnis mit aufgezeichneten Datein auf Smartphone

In dem Bild lässt sich auch schon erkennen wie das Namesschema der Dateien ist:
  1. rot - Typ der Geste (quadrat, circle, hline...)
  1. grün - Zufallszahl
  1. blau - Sensortyp (lin_acc, magf, grav..., bitte beachten es sind mehr Sensoren, als oben aufgeführt)
  1. .csv

Die Dateien lassen sich entweder manuell per USB auf den PC übertragen (Ordner: Android/data/com.example.schieck.ga/files/*) oder per Email an eine zuvor eingestellte Adresse versenden. Sie enthalten die Bewegungsmuster die später genutzt werden um das neuronale Netz zu trainieren.

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/4.png)
Abb.: Inhalt einer csv Datei

In dem Bild sieht man was der Sensor eigentlich macht, es wird zu einem bestimmten Zeitpunkt ein bestimmter Zustand gemessen. Die App schreibt dann diese Zustände in die Dateien.
Es liegen also timestamp-value-paare vor.

Implementierung

Namensschema:
[Geste].[Zufallszahl].[Sensortyp].csv

Das Namensschema hat die Funktion, das nicht erst die Datei geöffnet werden muss um zu wissen, was sie enthält.
Die Zufallszall verhindert (oder macht es zumindest sehr unwahrscheinlich) das man nacharbeiten muss, und Dateien von Hand umbenennen, falls man Dateien aus mehreren Quellen hat.

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/5.png)

Damit die App Sensorwerte vom Betriebssystem empfangen kann, wird ein SensorManager genutzt und ein SensorEventListener (stellt Callback zur Verfügung, das die Sensorwerte vom Betriebssystem entgegenimmt) implementiert.
class MainActivity() : Activity(), SensorEventListener {
var sensor_manager: SensorManager? = null

...und im onCreate() Callback initialisiert.
sensor_manager = getSystemService(Context.SENSOR_SERVICE) as SensorManager


Zusatzlich wird ein Variable deklariert die die Abtastrate der Sensoren festlegt. Sie bieten nur grobe Richtwerte, da sich die in den Smartphones verbauten Sensoren, von Gerät zu Gerät unterscheiden, und sich damit auch die Abtastraten unterscheiden.
  • Abtastraten

val delay = SensorManager.SENSOR_DELAY_FASTEST

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/6.png)

Die Quellcodes können von mir direkt erhalten werden, bitte schreiben sie mich an. schieck@stud.fh-sm.de


2. Vorverarbeitung der Daten:

Anpassen der Zeitstempel
Um die timestamps besser überschauen zu können, wird von allen timestamps der niedrigste abgezogen, das geschieht mit:
fun adjustTimestamps(sample: Sample): Sample {
var first = sample.timestamp.first()
var retVal = sample

sample.timestamp.forEachIndexed { index, fl ->
retVal.timestamp[index] -= first
}
return retVal
}



Betragsquadrat berechnen

Mittels des Betragsquadrat werden aus den Werten für x, y und z, ein Wert gemacht. Dadurch wird erreicht das die Werte Orientierungsunabhängig sind.


TODO: hier gehört ne formel hin, aber
formel
...
formel
funktioniert nicht... fun AbsoluteSquare(sample: Sample): Sample {
val sampleSize = sample.x.size
val retVal = Sample(sample.sensor, sample.gesture)

for (i in 0 until sampleSize) {
val absSquare = Math.abs((sample.x[i] + sample.y[i] + sample.z[i]))
retVal.absoluteSquare.add(absSquare)
}
return retVal
}


Fehlende Werte ermitteln
Die Werte die von Android Sensoren zurückgeliefert werden, sind nicht äquidistant (gleicher zeitlicher Abstand zwischen den Messwerten). Das ist aber nötig um sie später einem maschinellem Lernalgorhythmus zuzuführen. Die Sensoren von Android Geräten haben i.d.R. eine Abtastrate von 20-80Hz. Daher ist, verbunden mit der Unsicherheit WANN bestimmte Sensoren, bestimmte Werte zurückliefern, eine starke Fluktuation zu erkennen.

 (image: https://ife.erdaxo.de/uploads/TutoriumMobileEingebetteteIntelligenzSS18/7.png)
Abb.: Nicht-Äquidistante Abstände bei den Timestamps


Um dieses Problem zu beheben kann man das Signal (linear) interpolieren. Dabei werden die fehlenden Punkte durch die Mittel der umliegenden Punkte aufgefüllt.

TODO: Formel für lineares interpolieren, die YAML für die wiki nervt echt, sie kommt nicht mal mit simplen formeln klar...
fun interpolate(sample: Sample): Sample {
require(count < 2) { "interpolate: illegal count!" }

val retVal = sample

for (i in 0 until sample.size) {
retVal.timestamp[i] = sample.timestamp.first() + i * (sample.timestamp.last() - sample.timestamp.first()) / sample.size
retVal.x[i] = sample.x.first() + i * (sample.x.last() - sample.x.first()) / sample.size
retVal.y[i] = sample.y.first() + i * (sample.y.last() - sample.y.first()) / sample.size
retVal.z[i] = sample.z.first() + i * (sample.z.last() - sample.z.first()) / sample.size
}
return retVal
}

Trainieren von OLVQ1





CategoryTutorienFKITSS18;CategoryTutorienFKITSS19

Diese Seite wurde noch nicht kommentiert.
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki