Skip to content

A Test Demo that training model in Keras and convert .h5 to .tflite

Notifications You must be signed in to change notification settings

kehuantiantang/AndroidTensorflow

Repository files navigation

Demo

  • apk

TensorFlow官方版本, 一个预训练的apk Source App

  • 官方实例实现poents classification,实验成功

1. 先training模型

2. 部署到手机中

  • 第三方mnist实现,未测试

1. tf.keras mnist的实现

2. android模块

Problem

  • TensorFlow Lite操作数类型 默认只支持, float32和uint8的类型,这样就是意味着在放入到Android中,BYTE_SIZE_OF_FLOAT = 4 OR 1(float32, uint8, 32/8, 8/8, 非量化32, 量化8)
  • 支持操作函数
  • Android SDK over than 23
  • TensorFlow over than 1.8
  • 出现java.nio.BufferOverflowException
E/AndroidRuntime: FATAL EXCEPTION: CameraBackground
    Process: android.example.com.tflitecamerademo, PID: 7971
    java.nio.BufferOverflowException
        at java.nio.DirectByteBuffer.putFloat(DirectByteBuffer.java:459)
        at com.example.android.tflitecamerademo.ImageClassifier.convertBitmapToByteBuffer(ImageClassifier.java:207)

// 该问题是ByteBuffer.allocateDirect的大小问题,注意确认好,以下三个变量的大小
 ByteBuffer.allocateDirect(
            4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
  • 出现java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 270000 bytes and a ByteBuffer with 2700000 bytes. 该问题一般是由于DIM_IMG_SIZE_X, DIM_IMG_SIZE_Y, 或者是DIM_PIXEL_SIZE没有设置正确
  • 使用tflite或者是.h5文件在server端正确,到android端出现错误,无法正确识别 一个很重要的问题就是输入输出,输入一定要按照训练的时候来输入,如果你做了augmentation,均一化数据,这样在android中也需要均一化。 输出一般是softmax对应assert/xx.txt文件,顺序和训练时一定要对应,并且不能有多余换行,否则会报输出的错
// pixelValue is the real value take from photo range to 0 - 255, if has preprocessing, the value should minus or divide a number
imgData.putFloat(((pixelValue >> 16) & 0xFF) / IMAGE_STD);
imgData.putFloat(((pixelValue >> 8) & 0xFF) / IMAGE_STD);
imgData.putFloat((pixelValue & 0xFF)/ IMAGE_STD);
  • Android Bitmap出现NullPointException问题,可以按照以下comment进行更改
bitmap = Bitmap.createScaledBitmap(bitmap,getImageSizeX(),getImageSizeY(), true);
//        bitmap.getPixels(intValues, 0, getImageSizeX(), 0, 0, getImageSizeX(), getImageSizeY());
        bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());

Tools

  • 所有的转换方法都在,tf.contrib.lite这个tensorflow类下面 示例转换代码, bash version,转换到tflite, tensorflow r1.11, python version
# pb --> tflite, 注意指定好input and output layer
tflite_convert \
  --output_file=/tmp/foo.tflite \
  --graph_def_file=/tmp/mobilenet_v1_0.50_128/frozen_graph.pb \
  --input_arrays=input \
  --output_arrays=MobilenetV1/Predictions/Reshape_1
# floating-point --> tflite, 直接在tensorflow里面保存的checkpoint即可以完成变换
tflite_convert \
  --output_file=/tmp/foo.tflite \
  --saved_model_dir=/tmp/saved_model
# tf.keras --> tflite, 注意这个是tf下面的keras而不是原生Keras,原生需要通过.h5 --> .pb --> .tflite
tflite_convert \
  --output_file=/tmp/foo.tflite \
  --keras_model_file=/tmp/keras_model.h5
#一些多输入和多输出
tflite_convert \
  --graph_def_file=/tmp/inception_v1_2016_08_28_frozen.pb \
  --output_file=/tmp/foo.tflite \
  --input_shapes=1,28,28,96:1,28,28,16:1,28,28,192:1,28,28,64 \
  --input_arrays=InceptionV1/InceptionV1/Mixed_3b/Branch_1/Conv2d_0a_1x1/Relu,InceptionV1/InceptionV1/Mixed_3b/Branch_2/Conv2d_0a_1x1/Relu,InceptionV1/InceptionV1/Mixed_3b/Branch_3/MaxPool_0a_3x3/MaxPool,InceptionV1/InceptionV1/Mixed_3b/Branch_0/Conv2d_0a_1x1/Relu \
  --output_arrays=InceptionV1/Logits/Predictions/Reshape_1
  
tflite_convert \
  --graph_def_file=/tmp/inception_v1_2016_08_28_frozen.pb \
  --output_file=/tmp/foo.tflite \
  --input_arrays=input \
  --output_arrays=InceptionV1/InceptionV1/Mixed_3b/Branch_1/Conv2d_0a_1x1/Relu,InceptionV1/InceptionV1/Mixed_3b/Branch_2/Conv2d_0a_1x1/Relu

Useful Website

https://www.tensorflow.org/lite/

cpu and gpu performance in android

About

A Test Demo that training model in Keras and convert .h5 to .tflite

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published