Erkennung von Dieselfahrzeugen mit AWS DeepLens

Keine Kommentare

Wir wollen euch in dieser Artikelreihe anhand des Beispiels “Erkennung von Dieselfahrzeugen” unterschiedliche Machine- und Deep-Learning-Ansätze näherbringen. In diesem Artikel haben wir das Vorgehen auf Basis von Deep-Learning in neuronalen Netzen zusammengefasst. Als Hardware haben wir die AWS DeepLens verwendet, die mit ihrer eingebauten Intel-GPU die Möglichkeit bietet, neuronale Netze effizient in einem Edge Device zu verwenden. Für die Umsetzung haben wir das Google-Deep-Learning-Framework TensorFlow verwendet und ein neuronales Netz auf unseren Aufgabenstellung adaptiert. Die Zielsetzung ist in Teil 1 zusammengefasst. Exemplarisch erkennen wir die grüne Plakette, die bei einer Einführung der blauen Plakette als Marker für Fahrverbote genutzt werden kann. In Teil 2 haben wir darüber hinaus gezeigt, dass auch Diesel-Typschilder (z. B. TDI) erkannt werden können, was auch auf diesel Teil übertragbar ist, bzw. mit der Erkennung einer Umweltplakette kombiniert werden kann.

Beispiele für mögliche Diesel-Marker – Typkennzeichnungen

Die Links zu allen Teilen und unserem YouTube-Kanal finden sich hier:
>codecentric.ai Homepage
>Deep Diesel Teil 1: Machine und Deep Learning zur Erkennung von Umweltplaketten
>Deep Diesel – Teil 2: Machine-Learning-Dieselfilter HOG Detektor
>Deep Diesel – Teil 3: Deep-Learning-Dieselfilter mit der AWS DeepLens
>codecentric.ai-YouTube-Kanal für regelmäßige Machine- und Deep-Learning-Updates

Objekterkennung auf Basis von neuronalen Netzen

In Teil 2 haben wir charakteristische Eigenschaften von Dieselautos auf Basis geometrischer Features erkannt, wobei die Limitationen des Ansatzes deutlich wurden. Neuronale Netze beziehen mehr Informationen zur Erkennung von Features (Umweltplaketten, Typschildern, Fahrzeugtypen) eines Dieselfahrzeugs mit ein, z. B. Farbe, Position, Kontext etc. Im Vergleich zu einer reinen Klassifizierung von Bildern ist die Objekterkennung eine schwierige Aufgabe, denn anstelle der Ausgabe einer Klasse mit einem Output-Neuron soll auch eine Bounding Box und eine Wahrscheinlichkeit zurückgegeben werden sollen. Es gibt unterschiedliche Verfahren (z. B. Single Shot Detection, Faster R-CNN oder  R-FCN), die hier zur Anwendung kommen können. Details zu den unterschiedlichen Methoden finden sich im Paper Speed/accuracy trade-offs for modern convolutional object detectors.

Im Gegensatz zu “klassischen” Machine-Learning-Methoden starten wir mit dem Detektor nicht bei null, sondern bauen auf einem vortrainierten neuronalen Netz auf, dem wir lediglich die neuen Klassen von Objekten beibringen. Dies reduziert die Anzahl der benötigten Trainingsdaten drastisch, so dass wir mit wenigen hundert Bildern bereits erste Ergebnisse erzielen konnten. Da wir als Device die AWS DeepLens verwenden wollen, ergeben sich spezielle Anforderungen an die Architektur des neuronalen Netzes. Wir haben uns für eine Inception-v2-Architektur entschieden, die wir nach dem Training aufgrund von neuen Erkenntnissen anpassen mussten.

AWS DeepLens

Als Hardwareplattform nutzen wir eine AWS DeepLens, die die Kollegen von der letzten re:Invent mitgebracht haben. Für die Verprobung in unserem Szenario ist die “Deep-Learning-Kamera” aus verschiedenen Gründen gut geeignet: Sie funktioniert standalone nur mit Strom, hat einen Intel Gen-9 GPU, Unterstützung von mehreren Machine-Learning-Frameworks, eingebautes WLAN und eine Integration in AWS-IoT-Dienste für Messaging.

DeepLens UnboxingDeepLens Unboxing

Außerdem Logging, Deployment und Co. Auf der AWS DeepLens läuft ein Ubuntu Linux und es können bei Bedarf Monitor, Tastatur und Maus angestöpselt werden. Sowohl der Input- als auch der Output-Stream nach der Inference durch unseren Detektor sind lokal aufrufbar und werden bei Bedarf gestreamt.

Interessant ist das Konzept zur Einbindung der AWS DeepLens und wie das Deployment des neuronalen Netzes (Model) und des ausführenden Codes (Lambda) funktioniert. Die AWS DeepLens wird dabei in AWS wie ein beliebiges IoT Device behandelt. Lokal läuft eine Greengrass-Instanz, die die Code Execution und das Messaging übernimmt. Greengrass ermöglicht es, Aufgaben, die sonst in der AWS Cloud ausgeführt werden, z. B. eine Lambda-Funktion ausführen, in ein ‘Edge Device’ zu verlagern. Beim Deployment wird einfach ein Paket, in unserem Fall bestehend aus neuronalem Netz und einem Python-Code-Paket, auf das Device gepusht und dort ausgeführt.

AWS-DeepLens-Inferenz-Architektur (Quelle: Amazon)

Für die AWS DeepLens werden einige Beispielprojekte angeboten, die mehr oder weniger als Single Click Deployment auf der Kamera landen und sofort dort lauffähig sind, darunter:

  • Objekterkennung (auf Basis von Apache MX)
  • Ein HotDog-Klassifizierer (HotDog or not)
  • Hund-oder-Katze-Klassifikation
  • Style Transfer
  • Gesichtserkennung
  • Aktivitäten erkennen
  • Kopfhaltung erkennen

Darüber hinaus sind direkt Modelle aus Amazon SageMaker, verfügbar, die relativ einfach in ein AWS DeepLens integrierbar sind. SageMaker ist eine Möglichkeit, Machine-Learning-Modelle in AWS komfortabel zu trainieren. Auf codecentric.ai findet Ihr hierzu ein Intro-Video.

Das ist uns aber in diesem Fall zu einfach, deswegen haben wir:

  1. ein externes Machine-Learning Framework verwendet
  2. dieses in der Cloud trainiert und evaluiert
  3. das Modell außerhalb der AWS DeepLens optimiert
  4. das Ergebnis auf die AWS DeepLens deployed

Die AWS DeepLens unterstützt mehrere Machine-Learning-Frameworks: Apache MXNet, Google TensorFlow sowie Berkleys Caffe Models. ‘Unterstützt’ bezieht sich insbesondere auf die Verfügbarkeit des Model Optimizers auf der AWS DeepLens, der ein Wrapper um das Intel Open Vino- Toolkit darstellt. Dieser optimiert die extern trainierten Modelle für die Intel GPU. Mit etwas Aufwand wird es wahrscheinlich auch möglich sein, weitere Frameworks auf der Plattform zum Laufen zu bekommen.

AWS Machine Learning EC2 Cloud-Instanz einrichten

Da wir für das Training eine leistungsstarke GPU benötigen, haben wir eine p3.2xlarge-Instanz mit 61 GB Speicher, 1 NVIDIA V100 GPU und 8 Virtual Cores gewählt.

Zum Aufsetzen unserer Trainingsumgebung haben wir das Deep Learning Base AMI (Amazon Linux) Image aus dem AWS Marketplace verwendet und auf die aktuellste TensorFlow-Version, die TensorFlow Models, Googles protobuf, Jupyter Notebook und TensorBoard upgegraded. Es empfiehlt sich, die Daten für das Training entweder in eine separate Elastic-Block-Storage-Partition oder bei wenig Daten in ein Git Repository zu laden. Wir haben zwei Anläufe mit der Auswahl des neuronalen Netzes gebraucht, da anscheinend Open Vino nicht alle Versionen korrekt unterstützt. Die letztendlich kompatible Version (.tgz) haben wir erst als Link in der Open Vino Dokumentation gefunden. Für die Optimierung des Modells auf die Intel GPU haben wir später eine Deep-Learning-Base-AMI- (Ubuntu-)Instanz eingerichtet, da sich die Einrichtung von Intel Open Vino hier als einfacher dargestellt hat.

Deep Learning EC2 ImagesEmpfohlene Deep Learning EC2 Images

Trainingsdaten sammeln und labeln

Als Trainingsdaten haben wir die gleiche Art von Bildern wie für den HOG Classifier verwendet. Für die AWS DeepLens haben wir uns auf die statischen Fotos unserer Firmenwagen beschränkt und keine Videos von vorbeifahrenden Fahrzeugen genommen. 

Für das Labeling kam hier LabelImg zum Einsatz.

LabelImg – Benziner steht Modell mit grüner Umweltplakette

TensorFlow verwendet sogenannte TensorFlow Records, die die Bild- und Trainingsdaten kombiniert als Bytestrom enthalten und so während des Trainings effizienter zugreifbar sind. Details zum Dateiformat finden sich hier.

Das aus LabelImg resultierende Pascal VOC Format lässt sich relativ einfach in die Tensorflow.records umwandeln. Im Git Repository SSD TensorFlow findet sich eine Beispielimplementierung zur Umwandlung pascalvoc_to_tfrecords.py. (Haben wir nicht ausprobiert, da wir den Konverter selber geschrieben haben.)

Training und Evaluierung

Mit einer leistungsstarken GPU dauert das Trainieren mit ein paar hundert Bildern nur wenige Minuten. Die vorliegenden gelabelten Bilder haben wir in zwei überschneidungsfreie Sets aufgeteilt:

Trainingsdaten 80 %, Evaluierungsdaten 20 %. Dabei benutzen wir die Evaluierungsdaten dazu zu beurteilen, ob wir beim Training in ein Overfitting geraten. (Hierzu vergleichen wir die Entwicklung der Loss-Funktion auf den Trainingsdaten mit der Entwicklung der Loss-Funktion auf den Evaluierungsdaten.)

Wir starten das Training mit:
python object_detection/train.py   --logtostderr --pipeline_config_path=/data/DeepDiesel/tdata/ssd_inception_v2_diesel.config   --train_dir=/data/DeepDiesel/tdata/train_out_new/

und lassen gleichzeitig das Ergebnis gegen die Evaluierungsdaten verproben mit:

python object_detection/eval.py   --logtostderr --checkpoint_dir=/data/DeepDiesel/tdata/train_out_new/   --pipeline_config_path=/data/DeepDiesel/tdata/ssd_inception_v2_diesel.config   --eval_dir=/data/DeepDiesel/tdata/train_out_new/

Ein passendes Template für die inception v2 config-Datei findet sich auch im TensorFlow Model Repository. Dort werden das Training und das Modell parametrisiert. Hier finden sich auch wichtige Inputs für die spätere Optimierung des Modells für die AWS DeepLens.

Für die Überwachung/Visualisierung des Trainings wird das TensorBoard verwendet, in dem sowohl die Performance des Trainings wiedergegeben wird als auch die Bilder aus dem Evaluierungs-Set durch den Detektor analysiert und die Struktur des Modells dargestellt werden kann.

tensorboard --logdir /data/DeepDiesel/tdata/train_out_new/


So ist TensorBoard ist dann auf Port 6006 auf der entsprechenden Maschine erreichbar (wenn in der Security Group die korrekte Inbound Rule Allow inbound tcp 6006 from my IP eingetragen ist.)

training nachverfolgen

Training nachverfolgen in TensorBoard

erfolgreich erkannte PlaketteErfolgreich erkannte Plakette

Am Ende des Trainings wird das Modell ‘eingefroren’, um effizient für die Detektion genutzt werden zu können.

python object_detection/export_inference_graph.py    --input_type image_tensor --pipeline_config_path /data/DeepDiesel/tdata/ssd_inception_v2_diesel.config    --trained_checkpoint_prefix /data/DeepDiesel/tdata/train_out_new/model.ckpt-263 --output_directory /data/DeepDiesel/frozen_diesel_new263.pb

mit dem Ergebnis

(tensorflow):frozen_diesel_263.pb ec2-user$ ls checkpoint model.ckpt.meta frozen_inference_graph.pb pipeline.config model.ckpt.data-00000-of-00001 saved_model model.ckpt.index

Hier ein video zum Thema Freezing von Tensorflow Modellen

Optimierung des Modells für die AWS DeepLens

Eigentlich sollte es möglich sein, mit der AWS DeepLens über das Modul mo den vorhandenen frozen_inference_graph.pb direkt in der Lambda-Funktion mit einem Aufruf von mo.optimize zur Laufzeit zu optimieren. Leider wurde zum aktuellen Zeitpunkt noch ein alte Open-Vino-Version mit der AWS DeepLens ausgeliefert und ein Upgrade nicht ohne Weiteres möglich. Daher haben wir uns entschieden, die Optimierung extern auf unserer AMI-Base-Ubuntu-Instanz durchzuführen. Open Vino gibt es direkt bei Intel herunterzuladen: https://software.intel.com/en-us/openvino-toolkit/choose-download/free-download-linux

Mit dem folgenden Aufruf wird das vorliegende Modell optimiert.

./mo.py --input_model /tmp/frozen_inference_graph.pb  --tensorflow_use_custom_operations_config extensions/front/tf/ssd_support.json --output="detection_boxes,detection_scores,num_detections" --input_shape="(1,300,300,3)"

Bei Problemen ist ein Blick in die Dokumentation von OpenVINO angeraten, insbesondere docs/TensorFlowObjectDetectionSSD.html erklärt wichtige Eckpunkte. Hier haben wir auch unseren Fehler in Bezug auf die falsche Version des zugrundeliegenden Modells erkannt.

Das Ergebnis sollte nun ein, dass die folgenden drei Dateien vorliegen:

frozen_inference_graph.bin
frozen_inference_graph.mapping
frozen_inference_graph.xml

AWS-DeepLens-Projekt und Deployment

Wir erstellen ein eigenes leeres DeepLens-Projekt mit einem Custom Model. Nun müssen wir sowohl das Modell spezifizieren, das wir hochladen wollen, als auch eine Lambda-Funktion erstellen, die auf der AWS DeepLens die Detektion durchführt (Inferenz).

In Bezug auf das Modell haben wir die Herausforderung, dass wir anstelle einer .pb-Datei (im TensorFlow-Fall) nun drei Modell-Dateien hochladen müssen. Leider wird das bisher nicht unterstützt. Workaround: Entweder werden die drei Dateien in ein Archiv gepackt und dann über die Lambda-Funktion zuerst entpackt oder manuell über scp in
/opt/awscam/artifacts kopiert. Das Modell muss in einem mit “deeplens-” beginnenden S3-Bucket abgelegt werden.deeplens

Das Projekt referenziert Modell und Inferenz-Funktion für das Deployment

Die Lambda-Funktion erstellen wir aus der Vorlage greengrass-hello-world, die alle wichtigen Module enthält. Eine gute Beispielimplementierung für die benötigte Inferenzfunktion findet sich in der AWS-Dokumentation.

Deployment Succeeded

Deployment Succeeded

 

Detektion von Fahrzeugen

Um das Ergebnis im ‘Real’-Einsatz zu erproben, haben wir die DeepLens mit dem von uns trainierten Modell auf unserem Firmenparkplatz zum Einsatz gebracht. Bei den ersten Versionen musste die Implementierung noch nachjustiert werden. Hier ein Beispiel, bei dem eine falsche Label-Map verwendet wurde und der Detektions-Threshold zu niedrig angesetzt war.

DeepLensÜberall sind Flugzeuge im Büro.

Die Performance unseres trainierten Netzes haben wir auf dem Firmenparkplatz überprüft. Dafür haben wir einen Bereich abgesperrt und die Kollegen informiert, dass wir Aufnahmen machen…

Aufgebaute DeepLens

Hier die  aufgebaute AWS DeepLens

Verwendung der Daten

Einwilligung in die Verwendung der Daten 😉

 

Detektion

Detektion im fließenden Verkehr

Im Ergebnis konnte die Performance der Erkennung im Vergleich zum HOG Classifier stark erhöht werden. Es wurden praktisch alle vorbeifahrenden Fahrzeuge korrekt erkannt. Wir haben bei verschiedenen Fahrgeschwindigkeiten die Detektion laufen lassen (6 km/h, 20 km/h, 30 km/h, 40 km/h und knapp 50 km/h) und haben praktisch jedes Mal in mindestens einem Frame die grüne Plakette erkannt. Schneller konnten wir auf unserem Parkplatz nicht testen. Der anwendbare Geschwindigkeitsbereich wird aber prinzipiell davon bestimmt, bis zu welcher Geschwindigkeit ein Frame ohne Bewegungsunschärfe aufgenommen werden kann. Mit besserer Optik und Aufnahmetechnik würde sich der Bereich weiter vergrößern.

Fazit und Ausblick

Der hier implementierte Detektor auf Basis der Google Object Detection API auf der AWS DeepLens hat in Bezug auf das Anwendungsszenario einen erheblichen Performancesprung gemacht. Die Implementierung hat noch an einigen Stellen an den Details der verwendeten Frameworks gehakt, konnte aber letztendlich erfolgreich mit einigen wenigen Workarounds abgeschlossen werden. Das Vorgehen lässt sich analog auf Real-Use-Cases übertragen. Insbesondere der Transfer auf die Erkennung von Typschildern oder andere charakteristische Features ist unter Verwendung von weiteren Streams kein Problem. Denkbar wäre auch die Nutzung von Daten aus existierender Verkehrsüberwachungsinfrastruktur (Blitzer, Mautbrücken, Kamerass, …).    Als Reaktion auf eine Detektion könnten zum Beispiel Events ausgelöst werden, die über den AWS IoT Message Broker and Consumer wie Apps oder IoT-Aktoren gesendet werden können. Darüber hinaus lassen sich mit relativ überschaubarem Aufwand Produktivsysteme für individuelle Use-Cases bauen. 

Die Links zu allen Teilen und unserem YouTube-Kanal finden sich hier:
>codecentric.ai Homepage
>Deep Diesel Teil 1: Machine und Deep Learning zur Erkennung von Umweltplaketten
>Deep Diesel – Teil 2: Machine-Learning-Dieselfilter HOG Detektor
>Deep Diesel – Teil 3: Deep-Learning-Dieselfilter mit der AWS DeepLens
>codecentric.ai-YouTube-Kanal für regelmäßige Machine- und Deep-Learning-Updates

Bei weitergehendem Interesse an dem Thema, Ergänzungen oder Fragen erreicht ihr mich unter kai.herings@codecentric.de, auf Twitter unter: https://twitter.com/kherings

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.