Así que ha llegado una nueva etapa en el desarrollo del
tanque Raspberry .
En la
serie anterior, resultó que la segmentación semántica fuera de la caja era demasiado difícil para Raspberry.
La lluvia de ideas y los comentarios nos permitieron identificar las siguientes áreas de desarrollo:
- entrene su propia red E-net para el tamaño de imagen deseado
- transfiera el lanzamiento de una red neuronal desde la propia Raspberry a una pieza especial de hardware, de la cual se mencionó con mayor frecuencia Intel Movidius (también conocido como Neural Compute Stick, también conocido como NCS).
Adjuntar una nueva pieza de hierro al robot es lo más interesante en robótica, por lo que el trabajo minucioso de entrenar la red neuronal se ha pospuesto hasta tiempos mejores.
Unos días, y la milagrosa pieza de hierro de Intel en mis manos.
Es bastante grande y no se puede pegar en el conector USB inferior de la frambuesa. Dado que los puertos USB derechos estaban ocultos por el trípode de la cámara y la parte superior izquierda estaba ocupada por el módulo GPS, no había tantas opciones.
Como resultado, el GPS se colocó en un cable, se rechazó, y el cable se envolvió alrededor de un trípode, y el NCS se colocó en su lugar.
En esta parte del hardware se completó.

Intel NCS
Intel lanzó recientemente la segunda versión de NCS, y la API era completamente incompatible con la versión anterior, que los usuarios vertieron mucho dolor en Internet.
Como resultado, toda la base de conocimiento sobre la versión anterior es solo basura informativa.
La nueva edición ofrece el marco OpenVino, que incluye OpenCV y mucho más, incluidas varias herramientas para trabajar con redes neuronales.
Aquí hay algunos artículos introductorios sobre NCS2 y OpenVino:
Comenzar con NCS resultó ser bastante sencillo.
Intel inicialmente apoyó a Raspbian, por lo que no había necesidad de bailar con una pandereta.
El documento introductorio también fue muy claro y la instalación del marco OpenVino no causó ningún problema.
Resultó ser una buena ventaja que OpenVino incluye OpenCV 4.1, lo que ahorra tiempo, ya que tuve que construir versiones anteriores de OpenCV en Raspberry.
Así es como se ve NCS2 por sí solo:

Además resultó ser más interesante.
NCS solo admite su propio formato de red neuronal, mientras que Intel proporciona la herramienta Model Optimizer como parte de OpenVino para convertir gráficos de los marcos más populares: Tensorflow, Caffe, Torch. Más sobre esto será el próximo.
Además, Intel también ofrece
modelos zoológicos , un conjunto de modelos listos para usar en muchas ocasiones.
Entre ellos había dos modelos para la segmentación de carreteras:
Redes neuronales en NCS
Para ejecutar una red neuronal en un dispositivo, debe seguir varios pasos.
Inicializar dispositivo
El nombre MYRIAD, la idea del complemento y la carga dinámica del mismo, la ruta a la que debe especificarse en el programa, se extienden claramente desde el pasado oscuro.
from openvino.inference_engine import IENetwork, IEPlugin ncs_plugin = IEPlugin(device="MYRIAD", plugin_dirs="/opt/intel/openvino/inference_engine/lib/armv7l")
Descargar modelo
A continuación, debe cargar el modelo en el dispositivo.
Esta es una operación difícil. Ese pequeño modelo que utilicé para la segmentación tarda unos 15 segundos en cargarse.
La buena noticia es que solo necesita descargar el modelo una vez y puede descargar varios modelos.
model = IENetwork(model=xml_path, weights=bin_path) net = ncs_plugin.load(network=model)
Ejecutar cálculo
Ahora se puede usar el modelo.
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]
Proceso único
De repente resultó que no puedes usar NCS de dos procesos diferentes al mismo tiempo.
Cualquier persona que llegue tarde no puede cargar el modelo:
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 el foro de asistencia de Intel hicieron posible entender qué era el problema: el dispositivo es realmente exclusivo o simplemente no sé cómo cocinarlo.
Segmentación OpenVino
Como ya se mencionó, fuera de la caja, OpenVino proporciona un modelo de segmentación de carreteras y ejemplos.
Los resultados de la prueba son algo contradictorios. A veces se reconoce torcidamente, pero en la mayoría es normal.
Enet funcionó mejor, pero todavía tenemos que probar Enet en NCS, así que intentemos con lo que tenemos.

Curiosamente, aprender más sobre el modelo de OpenVino y volver a entrenarlo no es tan simple.
Los usuarios
están interesados , pero la persona de Intel dijo estrictamente que el código y los datos del modelo están cerrados, y aquellos que lo deseen pueden tomar una
red neuronal similar en PyTorch , entrenarla, convertirla y usarla.
La ventaja de la velocidad es muy significativa:
Si la segmentación de Enet tardó 6 segundos, entonces este modelo tardó 0,8 segundos en procesar una imagen (mientras que tardó 14 segundos en cargar el modelo en el dispositivo, pero esto se hace al mismo tiempo).
Clasificación de direcciones
Para tomar decisiones sobre la dirección del movimiento, el tanque utiliza una red neuronal simple, como se describe en el
artículo correspondiente .
La red neuronal está entrenada en Keras y se ejecuta en Raspberry a través de Tensorflow, que tiene un adaptador incorporado para este formato.
El modelo es muy simple e incluso en Raspberry muestra resultados de velocidad aceptables.
(0,35 segundos por imagen).
Sin embargo, al tener la glándula Intel, puede esperar lograr mejores resultados.
Entre los formatos que acepta el Optimizador de modelos de Intel para la conversión, hay Tensorflow, pero no Keras.
Convertir Keras a TF es algo bastante popular, hay suficiente material sobre este tema,
este artículo me guió.
El mismo autor tiene un
artículo más extenso , solo sobre el tema de cómo ejecutar el modelo Keras en OpenVino.
También puede usar la
guía de Intel .
En general, compilando las fuentes, obtuve un script para convertir el modelo de Keras a 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()]
El mismo código se encuentra
en el github .
El modelo TF resultante se destila aún más en el formato OpenVino:
python mo_tf.py --input_model "model/ktf_model.pb" --log_level=DEBUG -b1 --data_type FP16
Las pruebas mostraron que la clasificación de la imagen toma 0.007 segundos.
Este resultado es muy agradable.
Todos los modelos entrenados (Keras, TF, OpenVino) también se cargan
en el github .
Reconocimiento de objetos
La tarea de segmentación no es la única que un robot tiene que resolver en su difícil vida.
Al principio había un detector de gatos, que luego se convirtió en un detector universal basado en MobileSSD y OpenCV-DNN.
Ahora es el momento de activar la misma tarea en el NCS.
En
model_zoo de Intel, los detectores de una especificidad más estrecha basados en MobileSSD son suficientes, pero no hay un análogo exacto.
Sin embargo, esta red figura como compatible en la
lista de modelos TF compatibles .
Curiosamente, al momento de escribir, la versión de MobileSSD 2018_01_28 se indica aquí.
Sin embargo, OpenCV se niega a leer este modelo:
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'
(Pero descubrimos que usan Jenkins).
Al mismo tiempo, la conversión a OpenVino es exitosa.
Si intentamos convertir la versión de Mobile SSD compatible con OpenCV-DNN (11_06_2017), obtenemos esto:
[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)
Algo así, técnicamente OpenVino y OpenCV-DNN están en el mismo paquete, pero son incompatibles con las versiones de las redes neuronales utilizadas.
Es decir, si desea utilizar ambos enfoques simultáneamente, debe arrastrar dos versiones de MobileSSD.
En términos de velocidad, la comparación está ciertamente a favor del NCS: 0.1 segundos versus 1.7.
En términos de calidad ... (Aunque esto no es una cuestión de la NCS, sino de la evolución de la SSD móvil).

Clasificación de la imagen
El tanque puede clasificar imágenes a través de Tensorflow, usando Inception en Imagenet.
Y usé Inception 2015-12-05, cuando era otro.
Resultó que estaba muy por detrás de la vida, porque los chicos de Google no están comiendo su pan por nada y ¡ya han producido 4 versiones!
Pero los chicos de Intel no están detrás de ellos y las 4 versiones fueron compatibles con OpenVino.
Aquí hay
un artículo que describe varias versiones de Inception.
Pero no vamos a jugar, descargamos inmediatamente el último, cuarto.
Clasificamos la imagen con el gato y la computadora portátil sobre la mesa.
Recordamos los resultados de la versión actual:
- computadora portátil, computadora portátil 62%
- cuaderno, computadora portátil 11%
- 13 segundos
- donde esta el gato
Ahora leemos las
instrucciones para convertir Inception a OpenVino.
La conversión es exitosa, comenzamos el clasificador en NCS:
- computadora portátil, computadora portátil 85%
- cuaderno, computadora portátil 8%
- 0.2 segundos
- no hay gato otra vez
Conclusión
Por lo tanto, todos los escenarios que requerían Tensorflow se reprodujeron usando NCS, y esto significa que puede optar por no usar Tensorflow.
De todos modos, este marco es pesado para Raspberry.
La velocidad con la que el NCS digiere la red neuronal le permite expandir sus horizontes.
Hay tareas que el robot ya realiza, por ejemplo, segmentación semántica y clasificación, pero hay otras como la segmentación de objetos o la transmisión de video con objetos detectados en tiempo real. (que no podría haberse pensado en la frambuesa desnuda).
Los problemas con el multiprocesamiento son algo confusos, pero incluso si no se pueden resolver, siempre hay una opción en forma de envolver el NCS como un servicio separado.
Referencias