Tensorflow Lite on Raspberry Pi - Installation - tensorflow

In my current project I'm using machine learning on the Raspberry Pi for sensor fusion. Since I heard about the release of Tensorflow Lite I'm really interested to deploy and use it to run Lite models on the platform.
On the Tensorflow website are hints for Android and iOS, but I couldn't find any hints about any other platforms. Is there a (WIP) installation/compile guide out to bring TF Lite to the Raspi?
TIA

#all, if you are still in the trials to make tensorflow lite running on Raspberry Pi 3, my "pull-request" may be useful. Please look at https://github.com/tensorflow/tensorflow/pull/24194.
Following the steps, 2 apps (label_image and camera) can be running on Raspberry Pi 3.
Best,
--Jim

There is a very small section on Raspberry PI in the TFLite docs at https://www.tensorflow.org/mobile/tflite/devguide#raspberry_pi. That section links to this GitHub doc with instructions for building TFLite on Raspberry PI - tensorflow/rpi.md.
There is no official demo app yet, but the first location says one is planned. It will probably be shared at that same location when ready (that is where the Android and iOS demo apps are described).

You can install TensorFlow PIP on Raspberry pi with "pip install tensorflow" however, if you want only TFLite you can build a smaller pip that has only the tflite interpreter (you can then do conversion on another big machine).
Info on how to do it is here:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/pip_package
Then, you can use it. Here is an example of how you might use it!
import tflite_runtime as tflr
interpreter = tflr.lite.Interpreter(model_path="mobilenet_float.tflite")
interpreter.allocate()
input = interpreter.get_input_details()[0]
output = interpreter.get_input_details()[0]
cap = cv2.VideoCapture(0) # open 0th web camera
while 1:
ret, frame = cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = cv2.resize(frame, input.shape[2],input.shape[1])
frame = np.reshape(im, input.shape).astype(np.float32)/128.0-1.0
interpreter.set_tensor(input["index"], frame)
interpreter.invoke()
labels = interpreter.get_tensor(output["index"])
top_label_index = np.argmax(labels, axis=-1)
Hope this helps.

I would suggest next links:
The lightest way is by using TensorFlowLite interpreter only. You can find more information following this link: Install just the TensorFlow Lite interpreter
You have to remember, if you use interpreter only you have to follow a little bit different logic.
# Initiate the interpreter
interpreter = tf.lite.Interpreter(PATH_TO_SAVED_TFLITE_MODEL)
# Allocate memory for tensors
interpreter.allocate_tensors()
# Get input and output tensors
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# Add a batch dimension if needed (data_tensor - your data input)
input_data = tf.extend.dims(data_tensor, axis=0)
# Predict
interpreter.set_tensor(input_details[0]['index'], data_tensor)
interpreter.invoke()
# Obtain results
predictions = interpreter.get_tensor(output_details[0]['index'])
Build from source for the Raspberry Pi
Install TensorFlow with pip

Related

Test Intel Low Precision Optimization Tool using dummy dataset

I was trying out Intel Low Precision Optimization Tool in Linux. Initially I have created one environment named lpot_environment and installed tensorflow using the below command:
conda create -n lpot_environment python=3.7
pip install intel-tensorflow==2.3.0
Then I cloned the github repository as :
git clone https://github.com/intel/neural-compressor.git
I have the frozen model downloaded.
As an initial step toward intel lpot, I would like to run with a dummy dataloader. But I failed to find one.
It would be great if anybody send a code sample using dummy dataset in intel lpot.
You can use the below code to quantize a TensorFlow checkpoint and run with a dummy dataloader.
quantizer = Quantization('./conf.yaml')
dataset = quantizer.dataset('dummy_v2', \
input_shape=(100, 100, 3), label_shape=(1, ))
quantizer.model = common.Model('./model/public/rfcn-resnet101-coco-tf/rfcn_resnet101_coco_2018_01_28/')
quantizer.calib_dataloader = common.DataLoader(dataset)
quantized_model = quantizer()
Run quantization will create a dummy dataloader.

Custom object detection model to TensorFlow Lite, shape of model input

I need to export a custom object detection model, fine-tuned on a custom dataset, to TensorFlow Lite, so that it can run on Android devices.
I'm using TensorFlow 2.4.1 on Ubuntu 18.04, and so far this is what I did:
fine-tuned an 'ssd_mobilenet_v2_fpnlite_640x640_coco17_tpu-8' model, using a dataset of new images. I used the 'model_main_tf2.py' script from the repository;
I exported the model using 'exporter_main_v2.py'
python exporter_main_v2.py --input_type image_tensor --pipeline_config_path .\models\custom_model\pipeline.config --trained_checkpoint_dir .\models\custom_model\ --output_directory .\exported-models\custom_model
which produced a Saved Model (.pb file);
3. I tested the exported model for inference, and everything works fine. In the detection routine, I used:
def get_model_detection_function(model):
##Get a tf.function for detection
#tf.function
def detect_fn(image):
"""Detect objects in image."""
image, shapes = model.preprocess(image)
prediction_dict = model.predict(image, shapes)
detections = model.postprocess(prediction_dict, shapes)
return detections, prediction_dict, tf.reshape(shapes, [-1])
return detect_fn
and the shape of the produced image object is 640x640, as expected.
Then, I tried to convert this .pb model to tflite.
After updating to the nightly version of tensorflow (with the normal version, I got an error), I was actually able to produce a .tflite file by using this code:
import tensorflow as tf
from tflite_support import metadata as _metadata
saved_model_dir = 'exported-models/custom_model/'
## Convert the model
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.experimental_new_converter = True
converter.target_spec.supported_ops = [
tf.lite.OpsSet.TFLITE_BUILTINS, tf.lite.OpsSet.SELECT_TF_OPS]
tflite_model = converter.convert()
# Save the model.
with open('tflite/custom_model.tflite', 'wb') as f:
f.write(tflite_model)
I tried to use this model in AndroidStudio, following the instructions given here.
However, I'm getting a couple of errors:
something regarding 'Not a valid Tensorflow lite model' (have to check better on this);
the error:
java.lang.IllegalArgumentException: Cannot copy to a TensorFlowLite tensor (serving_default_input_tensor:0) with 3 bytes from a Java Buffer with 270000 bytes.
The second error seems to indicate there's something weird with the input expected from the tflite model.
I examined the file with Netron, and this is what I got:
the input is expected to have...1x1x1x3 shape, or am I misinterpreting the graph?
Should I somehow set the tensor input size when using the tflite exporter?
Anyway, what is the right way to export my custom model so that it can run on Android?
TF Ops are supported via the Flex delegate. I bet that is the problem. If you want to check if it is that, you can do:
Download benchmark app with flex delegate support for TF Ops. You can find it here, in the section Native benchmark binary: https://www.tensorflow.org/lite/performance/measurement. For example, for android is https://storage.googleapis.com/tensorflow-nightly-public/prod/tensorflow/release/lite/tools/nightly/latest/android_aarch64_benchmark_model_plus_flex
Connect your phone to your computer and where you have downloaded the apk, do adb push <apk_name> /data/local/tmp
Push your model adb push <tflite_model> /data/local/tmp
Open shell adb shell and go to folder cd /data/local/tmp. Then run the app with ./<apk_name> --graph=<tflite_model>
Info from:
https://www.tensorflow.org/lite/guide/ops_select
https://www.tensorflow.org/lite/performance/measurement

How to run yolov2-lite tflite in coral edge TPU USB accelerator?

I would like to make sure whether the following steps I executed to get the tflite of yolov2-lite model are correct or not?
Step1 Saving graph and weights to protobuf file
flow --model cfg/yolov2-tiny.cfg --load bin/yolov2-tiny.weights --savepb.
This command created build_graph folder with yolov2-tiny.pb and yolov2-tiny.meta.
Step2 Converting pb to tflite
I executed the below piece of code to get the yolov2-tiny.tflite
import tensorflow as tf
localpb = 'yolov2-tiny.pb'
tflite_file = 'yolov2-tiny.tflite'
print("{} -> {}".format(localpb, tflite_file))
converter = tf.lite.TFLiteConverter.from_frozen_graph(
localpb,
input_arrays= ['input'],
output_arrays= ['output']
)
tflite_model = converter.convert()
open(tflite_file,'wb').write(tflite_model)
interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()
If the above steps I followed to get this tflite are correct, then please suggest me the command to run this tflite file in coral edge TPU USB accelerator.
Thank you so much :)
unfortunately, yolo models are supported by the edgetpu compiler as of now. I recommend using mobile_ssd models.
For future reference, your pipeline should be:
1) Train the model
2) Convert to tflite
3) Compiled for EdgeTPU (the step that actually delegates the work onto the TPU)

How can I view weights in a .tflite file?

I get the pre-trained .pb file of MobileNet and find it's not quantized while the fully quantized model should be converted into .tflite format. Since I'm not familiar with tools for mobile app developing, how can I get the fully quantized weights of MobileNet from .tflite file. More precisely, how can I extract quantized parameters and view its numerical values ?
The Netron model viewer has nice view and export of data, as well as a nice network diagram view.
https://github.com/lutzroeder/netron
I'm also in the process of studying how TFLite works. What I found may not be the best approach and I would appreciate any expert opinions. Here's what I found so far using flatbuffer python API.
First you'll need to compile the schema with flatbuffer. The output will be a folder called tflite.
flatc --python tensorflow/contrib/lite/schema/schema.fbs
Then you can load the model and get the tensor you want. Tensor has a method called Buffer() which is, according to the schema,
An index that refers to the buffers table at the root of the model.
So it points you to the location of the data.
from tflite import Model
buf = open('/path/to/mode.tflite', 'rb').read()
model = Model.Model.GetRootAsModel(buf, 0)
subgraph = model.Subgraphs(0)
# Check tensor.Name() to find the tensor_idx you want
tensor = subgraph.Tensors(tensor_idx)
buffer_idx = tensor.Buffer()
buffer = model.Buffers(buffer_idx)
After that you'll be able to read the data by calling buffer.Data()
Reference:
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/schema/schema.fbs
https://github.com/google/flatbuffers/tree/master/samples
Using TensorFlow 2.0, you can extract the weights and some information regarding the tensor (shape, dtype, name, quantization) with the following script - inspired from TensorFlow documentation
import tensorflow as tf
import h5py
# Load TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path="v3-large_224_1.0_uint8.tflite")
interpreter.allocate_tensors()
# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# get details for each layer
all_layers_details = interpreter.get_tensor_details()
f = h5py.File("mobilenet_v3_weights_infos.hdf5", "w")
for layer in all_layers_details:
# to create a group in an hdf5 file
grp = f.create_group(str(layer['index']))
# to store layer's metadata in group's metadata
grp.attrs["name"] = layer['name']
grp.attrs["shape"] = layer['shape']
# grp.attrs["dtype"] = all_layers_details[i]['dtype']
grp.attrs["quantization"] = layer['quantization']
# to store the weights in a dataset
grp.create_dataset("weights", data=interpreter.get_tensor(layer['index']))
f.close()
You can view it using Netron app
macOS: Download the .dmg file or run brew install netron
Linux: Download the .AppImage file or run snap install netron
Windows: Download the .exe installer or run winget install netron
Browser: Start the browser version.
Python Server: Run pip install netron and netron [FILE] or netron.start('[FILE]').

Problems with running model zoo models for Tensorflow object detection API

I am running Google's tensorflow object-detection API's jupyter notebook on an Ubuntu 16.04 Parallels desktop on my Mac. I wanted to test out one of the non-default models (i.e. not SSD with Mobilenet) to see how the accuracy of the bounding boxes may change on an object-detection task.
I changed the section on Model Preparation in the notebook as follows:
# What model to download.
MODEL_NAME = 'ssd_mobilenet_v1_coco_11_06_2017'
MODEL_NAME = 'ssd_inception_v2_coco_11_06_2017'
MODEL_NAME = 'rfcn_resnet101_coco_11_06_2017'
#MODEL_NAME = 'faster_rcnn_resnet101_coco_11_06_2017'
#MODEL_NAME = 'faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017'
MODEL_FILE = MODEL_NAME + '.tar.gz'
DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'
# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt')
NUM_CLASSES = 90
I then jump to executing the cell that loads the frozen Tensorflow model into memory. Unfortunately, if I try any of the last 3 models (rfcn_resnet101_coco_11_06_2017, faster_rcnn_resnet101_coco_11_06_2017, faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017), the notebook crashes in Firefox and I get the following error message:
The kernel appears to have died. It will restart automatically.
So I am unable to test out the last 3 models, even though I have downloaded the tar.gz files and extracted them in the object_detection folder. Could somebody please explain what I may be doing wrong?
Thank you for your time!
As it turns out, this issue was caused because I was not allocating sufficient memory to Parallels. The script worked after I allocated more memory. Thanks for the tip Jonathan!