Réservoir de robot Raspberry Pi avec Intel Neural Computer Stick 2

Une nouvelle étape est donc venue dans le développement du Raspberry-tank .

Dans la série précédente, il s'est avéré que la segmentation sémantique hors de la boîte était trop difficile pour Raspberry.

Le brainstorming et le commentaire nous ont permis d'identifier les axes de développement suivants:

  • formez votre propre réseau E-net à la taille d'image souhaitée
  • transférer le lancement du réseau neuronal de Raspberry lui-même vers un matériel spécial, dont Intel Movidius (alias Neural Compute Stick alias NCS) a été le plus souvent mentionné.

Attacher un nouveau morceau de fer au robot est la chose la plus intéressante en robotique, donc le travail minutieux de formation du réseau neuronal a été reporté à des temps meilleurs.

Quelques jours - et le morceau de fer miracle d'Intel entre mes mains.

Il est assez grand et vous ne pouvez pas le coller dans le connecteur USB inférieur de la framboise. Étant donné que les ports USB droits étaient masqués par un trépied d'appareil photo et que le coin supérieur gauche était occupé par le module GPS, il n'y avait pas tellement d'options.

En conséquence, le GPS a été placé sur un câble, tourné vers le bas, et le câble a été enroulé autour d'un trépied, et le NCS est allé à sa place.

Sur cette partie matérielle a été achevée.



Intel NCS


Intel a récemment publié la deuxième version de NCS, et l'API était complètement incompatible avec la version précédente, dont les utilisateurs ont beaucoup souffert sur Internet.

Par conséquent, l'ensemble de la base de connaissances sur la version précédente n'est actuellement qu'une poubelle informative.

La nouvelle édition propose le cadre OpenVino, qui comprend OpenCV et bien plus encore, y compris divers outils pour travailler avec les réseaux de neurones.

Voici quelques articles d'introduction sur NCS2 et OpenVino:


Les premiers pas avec NCS se sont avérés assez faciles.

Intel a initialement pris en charge Raspbian, il n'était donc pas nécessaire de danser avec un tambourin.
Le document d'introduction était également très clair et l'installation du framework OpenVino n'a posé aucun problème.

Il s'est avéré être un bon bonus qu'OpenVino inclut OpenCV 4.1, ce qui fait gagner du temps, car j'ai dû créer moi-même les versions précédentes d'OpenCV sur Raspberry.

Voici à quoi ressemble NCS2 seul:



De plus, cela s'est avéré plus intéressant.

NCS ne prend en charge que son propre format de réseau de neurones, tandis qu'Intel fournit l'outil Model Optimizer dans le cadre d'OpenVino pour convertir les graphiques des frameworks les plus populaires: Tensorflow, Caffe, Torch. Plus d'informations à ce sujet seront les prochaines.

En outre, Intel propose également un zoo de modèles - un ensemble de modèles prêts à l'emploi pour de nombreuses occasions.

Parmi eux, deux modèles de segmentation routière:


Réseaux de neurones au NCS


Pour exécuter un réseau neuronal sur un appareil, vous devez prendre plusieurs mesures.

Initialiser l'appareil


Le nom MYRIAD, l'idée du plug-in et son chargement dynamique, dont le chemin doit être spécifié dans le programme - vont clairement du passé sombre.

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

Télécharger le modèle


Ensuite, vous devez télécharger le modèle sur l'appareil.

C'est une opération difficile. Ce petit modèle que j'ai utilisé pour la segmentation prend environ 15 secondes à charger.

La bonne nouvelle est que vous n'avez besoin de télécharger le modèle qu'une seule fois et que vous pouvez télécharger plusieurs modèles.

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

Exécuter le calcul


Maintenant, le modèle peut être utilisé.

  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] 

Processus unique


Il s'est avéré que vous ne pouvez pas utiliser NCS à partir de deux processus différents en même temps.
Toute personne en retard ne peut pas charger le modèle:

 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 

Ni Google ni le forum d'assistance Intel n'ont permis de comprendre ce qui se passait - soit l'appareil est vraiment exclusif, soit je ne sais tout simplement pas comment le cuisiner.

Segmentation d'OpenVino


Comme déjà mentionné, OpenVino fournit un modèle et des exemples de segmentation routière.

Les résultats des tests sont quelque peu contradictoires. Il est parfois reconnu de travers, mais dans la majorité des cas, il est normal.

Enet fonctionnait mieux, mais nous devons encore essayer Enet sous NCS, alors essayons avec ce que nous avons.



Fait intéressant, pour en savoir plus sur le modèle d'OpenVino et le recycler, ce n'est pas si simple.

Les utilisateurs sont intéressés , mais la personne d'Intel a strictement déclaré que le code et les données du modèle sont fermés, et ceux qui le souhaitent peuvent prendre un réseau neuronal similaire sur PyTorch , le former, le convertir et l'utiliser.

L'avantage de la vitesse est très important:
Si la segmentation Enet a pris 6 secondes, ce modèle a mis 0,8 seconde pour traiter une image (alors qu'il a fallu 14 secondes pour charger le modèle sur l'appareil, mais cela se fait en même temps).

Classification des directions


Pour prendre des décisions sur la direction du mouvement, le réservoir utilise un réseau neuronal simple, comme décrit dans l' article correspondant .

Le réseau de neurones est formé sur Keras et fonctionne sur Raspberry via Tensorflow, qui dispose d'un adaptateur intégré pour ce format.

Le modèle est très simple et même sur Raspberry montre des résultats de vitesse acceptables.
(0,35 seconde par image).

Néanmoins, avec la glande Intel, vous pouvez vous attendre à obtenir de meilleurs résultats.
Parmi les formats qu'Intel Model Optimizer accepte pour la conversion, il y a Tensorflow, mais pas Keras.

La conversion de Keras en TF est une chose assez populaire, il y a suffisamment de matériel sur ce sujet, j'ai été guidé par cet article .

Le même auteur a un article plus complet , juste sur le sujet de la façon d'exécuter le modèle Keras sur OpenVino.

Vous pouvez également utiliser les conseils d'Intel .

En général, en compilant les sources, j'ai obtenu un script pour convertir le modèle Keras en TF:

 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) 

Le même code se trouve sur le github .

Le modèle TF résultant est ensuite distillé au format OpenVino:

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

Les tests ont montré que la classification de l'image prend 0,007 seconde.
Ce résultat est très agréable.

Tous les modèles formés (Keras, TF, OpenVino) sont également téléchargés sur le github .

Reconnaissance d'objets


La tâche de segmentation n'est pas la seule qu'un robot doit résoudre dans sa vie difficile.

Au début, il y avait un détecteur de chat, qui est devenu plus tard un détecteur universel basé sur MobileSSD et OpenCV-DNN.

Il est maintenant temps de tourner la même tâche sur le NCS.

Dans model_zoo d'Intel, les détecteurs d'une spécificité plus étroite basés sur MobileSSD suffisent, mais il n'y a pas d'analogue exact.

Cependant, ce réseau est répertorié comme compatible dans la liste des modèles TF pris en charge .

Fait intéressant, au moment de la rédaction, la version de MobileSSD 2018_01_28 est indiquée ici.

Cependant, OpenCV refuse de lire ce modèle:

 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' 

(Mais nous avons découvert qu'ils utilisent Jenkins).

Dans le même temps, la conversion vers OpenVino est réussie.

Si nous essayons de convertir la version de Mobile SSD compatible avec OpenCV-DNN (11_06_2017), alors nous obtenons ceci:

 [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) 

Quelque chose comme ça, techniquement OpenVino et OpenCV-DNN sont dans le même paquet, mais sont incompatibles avec les versions des réseaux de neurones utilisés.

Autrement dit, si vous souhaitez utiliser les deux approches simultanément, vous devez faire glisser deux versions de MobileSSD.

En termes de vitesse, la comparaison est certainement en faveur du NCS: 0,1 seconde contre 1,7.

En termes de qualité ... (Bien que ce ne soit pas une question de NCS, mais d'évolution du Mobile SSD).



Classification d'image


Le tank est capable de classer les images via Tensorflow, en utilisant Inception sur Imagenet.
Et j'ai utilisé Inception 2015-12-05, quand c'était un autre.

Il s'est avéré que j'étais loin derrière la vie, car les gars de Google ne sont pas pour rien en train de manger leur pain et ont déjà produit 4 versions!

Mais les gars d'Intel ne sont pas derrière eux et les 4 versions ont été prises en charge dans OpenVino.

Voici un article décrivant différentes versions d'Inception.
Mais on ne va pas chouchouter, on télécharge tout de suite le dernier, quatrième.

Nous classons l'image avec le chat et l'ordinateur portable sur la table.

Nous nous souvenons des résultats de la version actuelle:

  • ordinateur portable, ordinateur portable 62%
  • ordinateur portable, ordinateur portable 11%
  • 13 secondes
  • où est le chat?

Nous lisons maintenant les instructions pour convertir Inception en OpenVino.

La conversion est réussie, nous démarrons le classificateur sur NCS:

  • ordinateur portable, ordinateur portable 85%
  • ordinateur portable, ordinateur portable 8%
  • 0,2 secondes
  • il n'y a plus de chat

Conclusion


Ainsi, tous les scénarios qui nécessitaient Tensorflow ont été reproduits à l'aide de NCS, ce qui signifie que vous pouvez désactiver l'utilisation de Tensorflow.

Ce cadre est tout de même lourd pour Raspberry.

La vitesse à laquelle le NCS digère le réseau neuronal lui permet d'élargir ses horizons.

Il y a des tâches que le robot accomplit déjà, par exemple la segmentation et la classification sémantiques, mais il y en a d'autres comme la segmentation d'objets ou la transmission de vidéo avec des objets détectés en temps réel. (qui ne pouvait pas être pensé sur la framboise nue).

Les problèmes de multitraitement sont quelque peu déroutants, mais même s'ils ne peuvent pas être résolus, il existe toujours une option sous la forme d'encapsuler le NCS en tant que service distinct.

Les références


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


All Articles