Himbeer-Pi-Robotertank mit Intel Neural Computer Stick 2

Damit ist eine neue Etappe in der Entwicklung des Himbeertanks gekommen .

In der vorherigen Serie stellte sich heraus, dass die semantische Segmentierung für Raspberry zu schwierig war.

Durch Brainstorming und Kommentare konnten wir die folgenden Entwicklungsbereiche identifizieren:

  • Trainieren Sie Ihr eigenes E-Net-Netzwerk für die gewünschte Bildgröße
  • Übertragen Sie den Start des neuronalen Netzwerks von Raspberry selbst auf eine spezielle Hardware, von der Intel Movidius (auch bekannt als Neural Compute Stick oder NCS) am häufigsten erwähnt wurde.

Das Anbringen eines neuen Stücks Eisen am Roboter ist das Interessanteste in der Robotik. Daher wurde die mühsame Arbeit des Trainings des neuronalen Netzwerks auf bessere Zeiten verschoben.

Ein paar Tage - und Intels Wunderstück Eisen in meinen Händen.

Es ist ziemlich groß und kann nicht in den unteren USB-Anschluss der Himbeere gesteckt werden. Da die rechten USB-Anschlüsse von einem Kamerastativ verdeckt wurden und oben links das GPS-Modul belegt war, gab es nicht so viele Optionen.

Infolgedessen wurde das GPS an ein Kabel angeschlossen, nach unten gedreht, und das Kabel wurde um ein Stativ gewickelt, und das NCS wurde an seine Stelle gesetzt.

Auf dieser Hardware wurde ein Teil abgeschlossen.



Intel NCS


Intel hat kürzlich die zweite Version von NCS veröffentlicht, und die API war vollständig inkompatibel mit der vorherigen Version, die den Benutzern im Internet große Schmerzen bereitete.

Infolgedessen ist die gesamte Wissensbasis über die vorherige Version derzeit nur Informationsmüll.

Die neue Ausgabe bietet das OpenVino-Framework, das OpenCV und vieles mehr enthält, einschließlich verschiedener Tools für die Arbeit mit neuronalen Netzen.

Hier sind einige einführende Artikel zu NCS2 und OpenVino:


Der Einstieg in NCS verlief reibungslos.

Intel unterstützte zunächst Raspbian, sodass nicht mit einem Tamburin getanzt werden musste.
Das Einführungsdokument war ebenfalls sehr klar und die Installation des OpenVino-Frameworks verursachte keine Probleme.

Es stellte sich als schöner Bonus heraus, dass OpenVino OpenCV 4.1 enthält, was Zeit spart, da ich frühere Versionen von OpenCV auf Raspberry selbst erstellen musste.

So sieht NCS2 für sich aus:



Weiter stellte sich heraus, dass es interessanter war.

NCS unterstützt nur sein eigenes neuronales Netzwerkformat, während Intel das Model Optimizer-Tool als Teil von OpenVino zum Konvertieren von Diagrammen der beliebtesten Frameworks bereitstellt: Tensorflow, Caffe, Torch. Mehr dazu folgt als nächstes.

Darüber hinaus bietet Intel auch den Modellzoo an - eine Reihe von vorgefertigten Modellen für viele Gelegenheiten.

Darunter waren zwei Modelle für die Straßensegmentierung:


Neuronale Netze bei NCS


Um ein neuronales Netzwerk auf einem Gerät auszuführen, müssen Sie mehrere Schritte ausführen.

Gerät initialisieren


Der Name MYRIAD, die Idee des Plug-Ins und dessen dynamisches Laden, dessen Pfad im Programm angegeben werden muss, reichen eindeutig aus der dunklen Vergangenheit.

from openvino.inference_engine import IENetwork, IEPlugin ncs_plugin = IEPlugin(device="MYRIAD", plugin_dirs="/opt/intel/openvino/inference_engine/lib/armv7l") 

Modell herunterladen


Als nächstes müssen Sie das Modell auf das Gerät hochladen.

Dies ist eine schwierige Operation. Das Laden dieses kleinen Modells, das ich für die Segmentierung verwendet habe, dauert ungefähr 15 Sekunden.

Die gute Nachricht ist, dass Sie das Modell nur einmal herunterladen müssen und mehrere Modelle herunterladen können.

  model = IENetwork(model=xml_path, weights=bin_path) net = ncs_plugin.load(network=model) 

Berechnung ausführen


Jetzt kann das Modell verwendet werden.

  input_blob = next(iter(model.inputs)) out_blob = next(iter(model.outputs)) n, c, h, w = model.inputs[input_blob].shape images = np.ndarray(shape=(n, c, h, w)) images[0] = image res = net.infer(inputs={input_blob: images}) res = res[out_blob] 

Einzelprozess


Es stellte sich plötzlich heraus, dass Sie NCS nicht gleichzeitig aus zwei verschiedenen Prozessen verwenden können.
Wer zu spät kommt, kann das Modell nicht laden:

 E: [ncAPI] [ 684447] resetAll:348 Failed to connect to stalled device, rc: X_LINK_ERROR E: [ncAPI] [ 691700] ncDeviceOpen:672 Failed to find suitable device, rc: X_LINK_DEVICE_NOT_FOUND Traceback (most recent call last): net = ncs_plugin.load(network=model) File "ie_api.pyx", line 395, in openvino.inference_engine.ie_api.IEPlugin.load File "ie_api.pyx", line 406, in openvino.inference_engine.ie_api.IEPlugin.load RuntimeError: Can not init USB device: NC_ERROR 

Weder Google noch das Intel-Supportforum haben es möglich gemacht zu verstehen, worum es ging - entweder ist das Gerät wirklich exklusiv oder ich weiß einfach nicht, wie man es kocht.

OpenVino-Segmentierung


Wie bereits erwähnt, bietet OpenVino sofort ein Straßensegmentierungsmodell und Beispiele.

Die Testergebnisse sind etwas widersprüchlich. Es wird manchmal schief erkannt, aber in der Mehrzahl ist es normal.

Enet hat besser funktioniert, aber wir müssen Enet noch unter NCS ausprobieren. Versuchen wir es also mit dem, was wir haben.



Interessanterweise ist es nicht so einfach, mehr über das Modell von OpenVino zu erfahren und es neu zu trainieren.

Benutzer sind interessiert , aber die Person von Intel sagte streng, dass der Code und die Daten des Modells geschlossen sind und diejenigen, die dies wünschen, ein ähnliches neuronales Netzwerk auf PyTorch nutzen , trainieren, konvertieren und verwenden können.

Der Geschwindigkeitsvorteil ist sehr bedeutend:
Wenn die Enet-Segmentierung 6 Sekunden dauerte, benötigte dieses Modell 0,8 Sekunden, um ein Bild zu verarbeiten (während das Laden des Modells auf das Gerät 14 Sekunden dauerte, dies erfolgt jedoch gleichzeitig).

Klassifizierung der Richtungen


Um Entscheidungen über die Bewegungsrichtung zu treffen, verwendet der Tank ein einfaches neuronales Netzwerk, wie im entsprechenden Artikel beschrieben .

Das neuronale Netzwerk ist auf Keras trainiert und läuft auf Raspberry über Tensorflow, das über einen integrierten Adapter für dieses Format verfügt.

Das Modell ist sehr einfach und zeigt auch bei Raspberry akzeptable Geschwindigkeitsergebnisse.
(0,35 Sekunden pro Bild).

Trotzdem können Sie mit der Intel-Drüse bessere Ergebnisse erwarten.
Unter den Formaten, die Intels Model Optimizer für die Konvertierung akzeptiert, gibt es Tensorflow, aber keine Keras.

Das Konvertieren von Keras in TF ist eine ziemlich beliebte Sache. Es gibt genug Material zu diesem Thema. Ich wurde von diesem Artikel geleitet .

Der gleiche Autor hat einen ausführlicheren Artikel zum Thema Ausführen des Keras-Modells unter OpenVino.

Sie können auch die Anleitung von Intel verwenden .

Im Allgemeinen habe ich beim Kompilieren der Quellen ein Skript zum Konvertieren des Keras-Modells in TF erhalten:

 import tensorflow as tf from tensorflow.python.framework.graph_util import convert_variables_to_constants from keras import backend as K from keras.models import load_model from keras.models import model_from_json def load_keras_model(json_file, model_file): jf = open(json_file, 'r') loaded_model_json = jf.read() jf.close() loaded_model = model_from_json(loaded_model_json) loaded_model.load_weights(model_file) return loaded_model def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True): graph = session.graph with graph.as_default(): freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or [])) output_names = output_names or [] output_names += [v.op.name for v in tf.global_variables()] # Graph -> GraphDef ProtoBuf input_graph_def = graph.as_graph_def() if clear_devices: for node in input_graph_def.node: node.device = "" frozen_graph = convert_variables_to_constants(session, input_graph_def, output_names, freeze_var_names) return frozen_graph model = load_keras_model('./model.json', './model.h5') frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs]) tf.train.write_graph(frozen_graph, ".", "ktf_model.pb", as_text=False) 

Der gleiche Code liegt auf dem Github .

Das resultierende TF-Modell wird weiter in das OpenVino-Format destilliert:

 python mo_tf.py --input_model "model/ktf_model.pb" --log_level=DEBUG -b1 --data_type FP16 

Tests zeigten, dass die Klassifizierung des Bildes 0,007 Sekunden dauert.
Dieses Ergebnis ist sehr erfreulich.

Alle trainierten Modelle (Keras, TF, OpenVino) werden ebenfalls auf den Github hochgeladen.

Objekterkennung


Die Segmentierungsaufgabe ist nicht die einzige, die ein Roboter in seinem schwierigen Leben lösen muss.

Am Anfang stand ein Katzendetektor, der später zu einem universellen Detektor auf Basis von MobileSSD und OpenCV-DNN heranwuchs.

Jetzt ist es Zeit, dieselbe Aufgabe auf dem NCS auszuführen.

In Intels model_zoo reichen Detektoren mit einer engeren Spezifität basierend auf MobileSSD aus, aber es gibt kein genaues Analogon.

Dieses Netzwerk ist jedoch in der Liste der unterstützten TF-Modelle als kompatibel aufgeführt.

Interessanterweise ist zum Zeitpunkt des Schreibens die Version von MobileSSD 2018_01_28 hier angegeben.

OpenCV weigert sich jedoch, dieses Modell zu lesen:

 cv2.error: OpenCV(4.1.0-openvino) /home/jenkins/workspace/OpenCV/OpenVINO/build/opencv/modules/dnn/src/tensorflow/tf_importer.cpp:530: error: (-2:Unspecified error) Const input blob for weights not found in function 'getConstBlob' 

(Aber wir haben herausgefunden, dass sie Jenkins verwenden).

Gleichzeitig ist die Konvertierung zu OpenVino erfolgreich.

Wenn wir versuchen, die mit OpenCV-DNN kompatible Version der Mobile SSD (11_06_2017) zu konvertieren, erhalten wir Folgendes:

 [E0919 main.py:317] Unexpected exception happened during extracting attributes for node FeatureExtractor/MobilenetV1/Conv2d_13_pointwise_1_Conv2d_2_1x1_256/Relu6. Original exception message: operands could not be broadcast together with remapped shapes [original->remapped]: (0,) and requested shape (1,0,10,256) 

Technisch gesehen befinden sich OpenVino und OpenCV-DNN im selben Paket, sind jedoch nicht mit den Versionen der verwendeten neuronalen Netze kompatibel.

Wenn Sie also beide Ansätze gleichzeitig verwenden möchten, müssen Sie zwei Versionen von MobileSSD ziehen.

In Bezug auf die Geschwindigkeit spricht der Vergleich sicherlich für das NCS: 0,1 Sekunden gegenüber 1,7.

In Bezug auf die Qualität ... (Dies ist zwar keine Frage des NCS, sondern der Entwicklung der mobilen SSD).



Bildklassifizierung


Der Tank kann mithilfe von Inception on Imagenet Bilder über Tensorflow klassifizieren.
Und ich habe Inception 2015-12-05 verwendet, als es ein anderes war.

Es stellte sich heraus, dass ich weit hinter dem Leben zurückblieb, denn die Jungs von Google essen nicht umsonst ihr Brot und haben bereits 4 Versionen produziert!

Aber die Jungs von Intel stehen nicht hinter ihnen und alle 4 Versionen wurden in OpenVino unterstützt.

Hier ist ein Artikel , der verschiedene Versionen von Inception beschreibt.
Aber wir werden nicht spielen, wir laden sofort den letzten, vierten herunter.

Wir klassifizieren das Bild mit der Katze und dem Laptop auf dem Tisch.

Wir erinnern uns an die Ergebnisse der aktuellen Version:

  • Laptop, Laptop 62%
  • Notebook, Notebook 11%
  • 13 Sekunden
  • Wo ist die Katze?

Jetzt lesen wir die Anweisungen zum Konvertieren von Inception in OpenVino.

Die Konvertierung ist erfolgreich, wir starten den Klassifikator auf NCS:

  • Laptop, Laptop 85%
  • Notebook, Notebook 8%
  • 0,2 Sekunden
  • Es gibt keine Katze mehr

Fazit


Daher wurden alle Szenarien, für die Tensorflow erforderlich war, mit NCS reproduziert. Dies bedeutet, dass Sie die Verwendung von Tensorflow deaktivieren können.

Trotzdem ist dieses Framework für Raspberry schwer.

Die Geschwindigkeit, mit der das NCS das neuronale Netzwerk verdaut, ermöglicht es ihm, seinen Horizont zu erweitern.

Es gibt Aufgaben, die der Roboter bereits erledigt, beispielsweise die semantische Segmentierung und Klassifizierung, aber es gibt auch andere Aufgaben wie die Objektsegmentierung oder die Übertragung von Videos mit erkannten Objekten in Echtzeit. (woran man bei der nackten Himbeere nicht denken konnte).

Probleme mit der Mehrfachverarbeitung sind etwas verwirrend, aber selbst wenn sie nicht gelöst werden können, gibt es immer die Möglichkeit, das NCS als separaten Dienst zu verpacken.

Referenzen


Source: https://habr.com/ru/post/de459126/


All Articles