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()]
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