Pytorch: Convert 2D-CNN model to tflite - pytorch

I'd like to convert a model (eg Mobilenet V2) from pytorch to tflite in order to run it on a mobile device.
Has anyone managed to do so?
All I found, was a method that uses ONNX to convert the model into an inbetween state. However, this seems not to work properly, as Tensorflow expects a NHWC-channel order whereas onnx and pytorch work with NCHW channel order.
There is a discussion on github, however in my case the conversion worked without complaints until a "frozen tensorflow graph model", after trying to convert the model further to tflite, it complains about the channel order being wrong...
Here is my code so far:
import torch
import torch.onnx
import onnx
from onnx_tf.backend import prepare
# Create random input
input_data = torch.randn(1,3,224,224)
# Create network
model = torch.hub.load('pytorch/vision:v0.6.0', 'mobilenet_v2', pretrained=True)
model.eval()
# Forward Pass
output = model(input_data)
# Export model to onnx
filename_onnx = "mobilenet_v2.onnx"
filename_tf = "mobilenet_v2.pb"
torch.onnx.export(model, input_data, filename_onnx)
# Export model to tensorflow
onnx_model = onnx.load(filename_onnx)
tf_rep = prepare(onnx_model)
tf_rep.export_graph(filename_tf)
All working without errors until here (ignoring many tf warnings). Then I look up the names of the input and output tensors using netron ("input.1" and "473").
Finally I apply my usual tf-graph to tf-lite conversion script from bash:
tflite_convert \
--output_file=mobilenet_v2.tflite \
--graph_def_file=mobilenet_v2.pb \
--input_arrays=input.1 \
--output_arrays=473
My configuration:
torch 1.6.0.dev20200508 (needs pytorch-nightly to work with mobilenet V2 from torch.hub)
tensorflow-gpu 1.14.0
onnx 1.6.0
onnx-tf 1.5.0
Here is the exact error message I'm getting from tflite:
Unexpected value for attribute 'data_format'. Expected 'NHWC'
Fatal Python error: Aborted
UPDATE:
Updating my configuration:
torch 1.6.0.dev20200508
tensorflow-gpu 2.2.0
onnx 1.7.0
onnx-tf 1.5.0
using
tflite_convert \
--output_file=mobilenet_v2.tflite \
--graph_def_file=mobilenet_v2.pb \
--input_arrays=input.1 \
--output_arrays=473 \
--enable_v1_converter # <-- needed for conversion of frozen graphs
leading to another error:
Exception: <unknown>:0: error: loc("convolution"): 'tf.Conv2D' op is neither a custom op nor a flex op
Update:
Here is an onnx model of mobilenet v2 loaded via netron:
Here is a gdrive link to my converted onnx and pb file

#Ahwar posted a nice solution to this using a Google Colab notebook.
It uses
torch 1.5.0+cu101
torchsummary 1.5.1
torchtext 0.3.1
torchvision 0.6.0+cu101
tensorflow 1.15.2
tensorflow-addons 0.8.3
tensorflow-estimator 1.15.1
onnx 1.7.0
onnx-tf 1.5.0
The conversion is working and the model can be tested on my computer. However when pushing the model to the mobile phone it only works in CPU mode and is much slower (almost 10 fold) than a corresponding model created in tensorflow directly. GPU mode is not working on my mobile phone (in contrast to the corresponding model created in tensorflow directly)
Update:
Apparantly after converting the mobilenet v2 model, the tensorflow frozen graph contains many more convolution operations than the original pytorch model ( ~38 000 vs ~180 ) as discussed in this github issue.

https://github.com/alibaba/TinyNeuralNetwork
You can try this project to convert the pytorch model to tflite. It supports all models in torchvision, and can eliminate redundant operators, basically without performance loss

Related

convert tensorflow.keras model to keras model

I have an EfficientNet model (tensorflow.keras==2.4) and would like to use innvestigate to inspect the results, but it requires keras==2.2.4
Training code:
tensorflow.keras.__version__ # 2.4
model = tf.keras.applications.EfficientNetB1(**params)
# do training
model.save('testModel')
I have the model saved as file but can not load it into Keras 2.2.4. This is the point where I'm stuck, I couldn't figure out what to do to convert the model.
Use Innvestigate:
keras.__version__ # 2.2.4
keras.model.load_model('testModel') # Error
# some more stuff...
I also found this thread, might try it, but since efficient net has > 350 layers it is not really applicable
How to load tf.keras models with keras
I don't know if it's actually possible to convert models between tensorflow.keras and keras, I appreciate all help I can get.
Due to version incompatibility between tensorflow as keras, you were not able to load model.
Your issue will be resolved, once you upgrade keras and tensorflow to 2.5.

Convert Tensorflow.js into Tensorflow keras

I have a tensorflow.js model and want to transform it into a TensorFlow Keras model. Is that in general possible? I have seen, that the conversion from tensorflow.js into Keras is possible, but did not found the conversion back.
In terminal enter the following command and just edit the path for the input model and where the output should be saved.
tensorflowjs_converter \
--input_format=tfjs_layers_model \
--output_format=keras \
my_layers_model/model.json
my_keras_model/

Are there syntax differences between using Keras with a Tensorflow 2, Theano, or CNTK backend?

It looks like tf.keras is suggested if you're using a Tensorflow 2 backend, but what about using Theano or CNTK as a backend? I have never used Keras or any DL library.
Keras has officially decided to drop support of CNTK and Theano moving forward. Therefore, if you are using keras with tensorflow as the backend, you should use tf.keras.
For older versions for keras, you can use all three backend with no syntax change in your keras code.
Keras 2.2.5 was the last release of Keras implementing the 2.2.* API.
It was the last release to only support TensorFlow 1 (as well as
Theano and CNTK).
The current release is Keras 2.3.0, which makes significant API
changes and add support for TensorFlow 2.0. The 2.3.0 release will be
the last major release of multi-backend Keras. Multi-backend Keras is
superseded by tf.keras.
You can find the above information here.

what's the difference between "import keras" and "import tensorflow.keras"

I was wondering, what's the difference between importing keras from tensorflow using import tensorflow.keras or just pip installing keras alone and importing it using import keras as both seemed to work nicely so far, the only difference I noticed is that i get Using TensorFlow backend. in the command line every time I execute the one using keras.
Tensorflow.keras is an version of Keras API implemented specifically for use with Tensorflow. It is a part of Tensorflow repo and from TF version 2.0 will become main high level API replacing tf.layers and slim.
The only reason to use standalone keras is to maintain framework-agnostic code, i.e. use it with another backend.

CoreML - Cannot perform conversion from Keras to CoreML - Windows 10

I recently upgraded my keras from version 1.1.0 to 1.2.2 and I ran a CNN for hand gesture classification (the code was developed using keras 1.1.0). I saved the trained model and I tried to convert it to CoreML model using coremltools. The code is as shown below:
import coremltools
import theano
from keras import backend as K
K.set_image_dim_ordering('th')
coreml_model = coremltools.converters.keras.convert('hgm_2.h5')
coreml_model.save('hgm.mlmodel')
But it gave me the following error:
RuntimeError: keras not found or unsupported version or backend found. keras conversion API is disabled.
How can I fix this issue? I tried upgrading theano, but it gave the same error.
I have received a reply here. Currently the conversion is not supported for theano backend.

Resources