Então, uma nova etapa chegou ao desenvolvimento do
tanque de framboesa .
Na
série anterior, verificou-se que a segmentação semântica fora da caixa era muito difícil para o Raspberry.
Brainstorming e comentários nos permitiram identificar as seguintes áreas de desenvolvimento:
- treine sua própria rede E-net para o tamanho de imagem desejado
- transferir o lançamento da rede neural do próprio Raspberry para um hardware especial, do qual o Intel Movidius (também conhecido como Neural Compute Stick ou NCS) foi mencionado com mais frequência.
Anexar um novo pedaço de ferro ao robô é a coisa mais interessante da robótica. Portanto, o trabalho meticuloso de treinar a rede neural foi adiado para tempos melhores.
Alguns dias - e o milagre pedaço de ferro da Intel em minhas mãos.
É muito grande e você não pode colocá-lo no conector USB inferior da framboesa. Como as portas USB certas foram obscurecidas por um tripé de câmera e a parte superior esquerda foi ocupada pelo módulo GPS, não havia muitas opções.
Como resultado, o GPS foi colocado em um cabo, desligado, e o cabo foi enrolado em um tripé, e o NCS entrou em seu lugar.
Nesta parte do hardware foi concluída.

Intel NCS
A Intel lançou recentemente a segunda versão do NCS, e a API era completamente incompatível com a versão anterior, que os usuários colocaram muita dor na Internet.
Como resultado, atualmente toda a base de conhecimento sobre a versão anterior é apenas lixo informativo.
A nova edição oferece a estrutura OpenVino, que inclui o OpenCV e muito mais, incluindo várias ferramentas para trabalhar com redes neurais.
Aqui estão alguns artigos introdutórios sobre NCS2 e OpenVino:
A introdução ao NCS mostrou-se bastante tranquila.
A Intel inicialmente deu suporte ao Raspbian, então não havia necessidade de dançar com um pandeiro.
O documento introdutório também foi muito claro e a instalação da estrutura OpenVino não causou problemas.
Acabou sendo um bom bônus o OpenVino incluir o OpenCV 4.1, o que economiza tempo, já que eu tive que criar versões anteriores do OpenCV no Raspberry.
Aqui está o que o NCS2 se parece sozinho:

Além disso, acabou sendo mais interessante.
O NCS suporta apenas seu próprio formato de rede neural, enquanto a Intel fornece a ferramenta Model Optimizer como parte do OpenVino para a conversão de gráficos das estruturas mais populares: Tensorflow, Caffe, Torch. Mais sobre isso será o próximo.
Além disso, a Intel também fornece
modelos de zoológico - um conjunto de modelos prontos para muitas ocasiões.
Entre eles, dois modelos para segmentação de rodovias:
Redes neurais na NCS
Para executar uma rede neural em um dispositivo, você precisa executar várias etapas.
Inicializar dispositivo
O nome MYRIAD, a idéia do plug-in e o carregamento dinâmico dele, o caminho para o qual deve ser especificado no programa - claramente se estendem do passado sombrio.
from openvino.inference_engine import IENetwork, IEPlugin ncs_plugin = IEPlugin(device="MYRIAD", plugin_dirs="/opt/intel/openvino/inference_engine/lib/armv7l")
Download do modelo
Em seguida, você precisa fazer o upload do modelo para o dispositivo.
Esta é uma operação difícil. Esse pequeno modelo que usei para segmentação leva cerca de 15 segundos para carregar.
A boa notícia é que você só precisa baixar o modelo uma vez e pode baixar vários modelos.
model = IENetwork(model=xml_path, weights=bin_path) net = ncs_plugin.load(network=model)
Executar cálculo
Agora o modelo pode ser usado.
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]
Processo único
De repente, descobriu-se que você não pode usar o NCS de dois processos diferentes ao mesmo tempo.
Qualquer pessoa atrasada não pode carregar o 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
Nem o Google nem o fórum de suporte da Intel tornaram possível entender qual era o problema - ou o dispositivo é realmente exclusivo ou simplesmente não sei como prepará-lo.
Segmentação OpenVino
Como já mencionado, pronto para uso, o OpenVino fornece um modelo e exemplos de segmentação de estradas.
Os resultados do teste são um tanto contraditórios. Às vezes é reconhecido de maneira torta, mas na maioria é normal.
A Enet funcionou melhor, mas ainda precisamos tentar a Enet no NCS, então vamos tentar com o que temos.

Curiosamente, para aprender mais sobre o modelo no OpenVino e treinar novamente, não é tão simples.
Os usuários
estão interessados , mas a pessoa da Intel disse estritamente que o código e os dados do modelo estão fechados, e aqueles que desejarem podem usar uma
rede neural semelhante no PyTorch , treinar, converter e usá-lo.
A vantagem da velocidade é muito significativa:
Se a segmentação da Enet demorar 6 segundos, esse modelo levará 0,8 segundos para processar uma foto (enquanto levava 14 segundos para carregar o modelo no dispositivo, mas isso é feito ao mesmo tempo).
Classificação das direções
Para tomar decisões sobre a direção do movimento, o tanque usa uma rede neural simples, conforme descrito no
artigo correspondente .
A rede neural é treinada em Keras e é executada em Raspberry através do Tensorflow, que possui um adaptador interno para esse formato.
O modelo é muito simples e até o Raspberry mostra resultados de velocidade aceitáveis.
(0,35 segundos por foto).
No entanto, com a glândula Intel, você pode esperar obter melhores resultados.
Entre os formatos que o Model Optimizer da Intel aceita para conversão, há o Tensorflow, mas não o Keras.
Converter Keras para TF é uma coisa bastante popular, há material suficiente sobre esse tópico, fui guiado por
este artigo .
O mesmo autor tem um
artigo mais extenso , apenas sobre o tópico de como executar o modelo Keras no OpenVino.
Você também pode usar as
orientações da Intel .
Em geral, compilando as fontes, recebi um script para converter o modelo Keras em 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()]
O mesmo código está
no github .
O modelo TF resultante é mais destilado no formato OpenVino:
python mo_tf.py --input_model "model/ktf_model.pb" --log_level=DEBUG -b1 --data_type FP16
Os testes mostraram que a classificação da imagem leva 0,007 segundos.
Este resultado é muito agradável.
Todos os modelos treinados (Keras, TF, OpenVino) também são carregados
no github .
Reconhecimento de Objetos
A tarefa de segmentação não é a única que um robô precisa resolver em sua vida difícil.
No começo, havia um detector de gato, que mais tarde se transformou em um detector universal baseado no MobileSSD e OpenCV-DNN.
Agora é hora de ativar a mesma tarefa no NCS.
No
model_zoo da Intel, os detectores de especificidade mais restrita baseados no MobileSSD são suficientes, mas não há analógico exato.
No entanto, esta rede está listada como compatível na
lista de modelos TF suportados .
Curiosamente, no momento da redação deste artigo, a versão do MobileSSD 2018_01_28 é indicada aqui.
No entanto, o OpenCV se recusa a ler 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'
(Mas descobrimos que eles usam Jenkins).
Ao mesmo tempo, a conversão para o OpenVino é bem-sucedida.
Se tentarmos converter a versão do Mobile SSD compatível com o OpenCV-DNN (11_06_2017), obtemos o seguinte:
[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 assim, tecnicamente OpenVino e OpenCV-DNN estão no mesmo pacote, mas são incompatíveis com as versões das redes neurais usadas.
Ou seja, se você quiser usar as duas abordagens simultaneamente, precisará arrastar duas versões do MobileSSD.
Em termos de velocidade, a comparação é certamente a favor do NCS: 0,1 segundos versus 1,7.
Em termos de qualidade ... (Embora isso não seja uma questão do NCS, mas da evolução do SSD móvel).

Classificação da imagem
O tanque é capaz de classificar imagens através do Tensorflow, usando o Inception no Imagenet.
E eu usei o Inception 05-12-2015, quando era outro.
Aconteceu que eu estava muito atrasada na vida, porque os caras do Google não estão à toa comendo o pão e já produziram quatro versões!
Mas os caras da Intel não estão por trás deles e todas as quatro versões foram suportadas no OpenVino.
Aqui está
um artigo que descreve várias versões do Inception.
Mas não vamos brincar, baixamos imediatamente o último, quarto.
Classificamos a foto com o gato e o laptop em cima da mesa.
Lembramos os resultados da versão atual:
- laptop 62%
- notebook, notebook 11%
- 13 segundos
- onde esta o gato
Agora lemos as
instruções para converter o Inception em OpenVino.
A conversão foi bem-sucedida, iniciamos o classificador no NCS:
- laptop, computador portátil 85%
- notebook, notebook 8%
- 0,2 segundos
- não há gato de novo
Conclusão
Assim, todos os cenários que exigiam o Tensorflow foram reproduzidos usando o NCS, e isso significa que você pode optar por não usar o Tensorflow.
Mesmo assim, essa estrutura é pesada para o Raspberry.
A velocidade com que o NCS digere a rede neural permite expandir seus horizontes.
Há tarefas que o robô já realiza, por exemplo, segmentação e classificação semânticas, mas há outras como segmentação de objetos ou transmissão de vídeo com objetos detectados em tempo real. (que não poderia ter sido pensado na framboesa nua).
Os problemas com o multiprocessamento são um pouco confusos, mas mesmo que não possam ser resolvidos, sempre há uma opção na forma de o NCS agrupar um serviço separado.
Referências