ONNX parte 1

Source: Deep Learning on Medium


visualizando redes neurais

Import this:

Pytorch (https://pytorch.org/) é uma framework voltada para deep learning criada pelo Facebook, tem ganhado bastante popularidade tanto pelo desempenho quanto por ser bem mais simples e intuitiva de usar do que o Tensorflow (criado pelo Google)

ONNX (Open Neural Network Exchange) (https://onnx.ai/) fornece um formato aberto de serialização de redes neurais, na realidade é mais um ecossistema do que apenas um formato que permite interoperabilidade entre diversas frameworks, com o ONNX é possível criar e treinar uma rede neural no pytorch e depois executar no Tensorflow por exemplo.

Sobre o ONNX resolvi escrever uma trilogia, e como o Pytorch é a framework que mais domino, partirei dela para os exemplos, o plano é o seguinte:

1. Visualizar um grafo que represente uma rede neural (este post)
2. Exportar a rede neural para o Caffe2 e comparar desempenho
3. Criar uma aplicação completa usando o pytorch para treinamento e tensorflowjs usando o ONNX para permitir essa interoperabilidade. (admito que ainda não testei o https://github.com/chaosmail/tfjs-onnx, essa me parece uma boa hora)

Ao trabalho:

Para isso você vai precisar de:

* Pytorch
* ONNX
* GraphViz

Este é o link para o notebook que criei: https://github.com/demacdolincoln/pytorch_e_machine_learning/blob/master/basico/onnx_view.ipynb

Não vou me demorar no código, apenas vou falar de forma bem simples e direta sobre o modelo de rede neural e a visualização.

Abaixo temos uma simples rede neural convolucional, no caso ela redebe uma matriz de 1x28x28 e devolver um vetor de 32x1x1, enfim ao início teremos uma matriz de 28×28, o que equivale a 784 posições se fôssemos converter num array e terminamos com um vetor equivalente de apenas 32 posições, tornando mais viável o processamento dos dados.

<script src=”https://gist.github.com/demacdolincoln/f550a5da1cdd6547ffaa19a9f1849519.js“></script>

No próximo Post tratarei melhor do treinamento, no momento vou pular essa parte para ir direto para a exportação:

O Pytorch já vem com as baterias inclusas para exportar para o formato do ONNX mas ele ainda não importa desse formato, inclusive se for ver a lista dos recursos disponíveis nas frameworks em relação ao ONNX, vamos ver que há mais libs que apenas exportam do que importam para este formato.

“`
frag_iter = iter(train_data)
frag = frag_iter.next() # um fragmento do dataset

torch.onnx.export(cnn, frag[0], “convnet.onnx”, verbose=True)
“`
Como não-necessariamente teremos de treinar a rede neural, temos de passar um exemplo de entrada para validar a rede neural e garantir que vai funcionar quando futuramente for importada. Normalmente se passa uma matriz aleatórias usando o `torch.randn` mas se estiver em dúvidas sobre as dimensões de entrada e com o dataloader tudo tiver funcionado perfeitamente, não há mal nenhum em fazer como no exemplo acima.

O ONNX vem com um script incluso que gera um arquivo do GraphViz que poderemos exportar para SVG, PNG, JPG, etc.

python3 /usr/lib/python3.7/site-packages/onnx/tools/net_drawer.py — input convnet.onnx — output convnet.dot

dot -Grankdir=TB -Tpng convnet.dot -o convnet.png

2 coisas a dizer

  1. Para instalações do ONNX localmente pelo pip, o script está em `~/.local/lib/python…`
  2. Por padrão o script gera um arquivo do GraphViz com uma configuração que cria visualizações horizontais, para visualizações verticais usei o parâmetro Grankdir, é bem intuitivo o que passar para ele: TB = Top-Botton, LR = Left-Right, etc. Para outros formatos de saída é só alterar o que vem depois do parâmetro `-T`, ex: Tsvg para gerar um arquivo svg.

Antes de mostrar a saída, tem uma ferramenta muito útil para visualização da rede neural, o Netron (https://github.com/lutzroeder/Netron), funciona tanto com o Pytorch quanto com o ONNX. Ele cria um servidor web local com uma interface que nos permite explorar mais detalhes da rede neural que apenas a visualização como um grafo, podemos ver os arrays que compôem os pesos e bias, configurações dos métodos usados dentro da rede neural, etc.

Comparando…

pytorch netron, onnx graphviz, onnx netron

PyTorch saved on Netron | ONNX GraphViz | ONNX Netron view

Olhando as imagens acima, a primeira coisa que pensei foi “que estranho pelo graphviz indicar 3 entradas enquanto nas outras há apenas 1”, a explicação disso é apenas que pelo que foi gerado pelo script do ONNX deixa explícito que a rede neural tem como entrada um input, peso e bias, enquanto nos outros isso fica implícito para deixar a visualização mais limpa.

É interessante notar que pelo ONNX, tanto pelo GraphViz quanto pelo Netron, podemos ver mais detalhes sobre as operações internas não referentes diretamente aos algoritmos principais, como é o caso do simples `x = x.view(x.shape[0], -1)` que no ONNX ele é “aberto”e vemos as vísceras do processamento expostas:

GraphViz | ONNX

No próximo post vou explorar um pouco mais o ONNX com o Caffe2 (https://caffe2.ai/)


Aos poucos tenho escrito umas anotações sobre NLP, ainda estão em fase muito inicial, mas a que, interessar: https://demacdolincoln.github.io/anotacoes-nlp/posts/