TensorFlow Lite for Android示例

一、 Lite 是针对移动和嵌入式设备的轻量级解决方案。Lite 支持、iOS 甚至 Pi。二、格式

生成的模型不能直接在移动端使用,需要离线转换为.file格式。

存储格式为。

是一个开源的免费软件库,用于实现序列化格式。它类似于 , , Avro。

因此,如果要在移动端使用,必须将训练好的模型文件转换成格式。官方提供toco实现模型格式的转换。

三、API

Lite 提供两种类型的 API,C++ 和 Java。任一 API 都需要加载和运行模型。

另一方面,Lite 的 Java API 使用类(解释器)来执行加载和运行模型的任务。后面的例子会看到如何使用它。

四、 Lite 实现手写数字识别 mnist。模型文件已包含在下面的演示中。(如果没有,需要自己训练,保存为pb文件,再转成格式)

对于一个识别类,首先需要初始化Lite解释器,以及输入输出。

    // The tensorflow lite file
    private lateinit var tflite: Interpreter
    // Input byte buffer
    private lateinit var inputBuffer: ByteBuffer
    // Output array [batch_size, 10]
    private lateinit var mnistOutput: Array
    init {
        try {

图片[1]-TensorFlow Lite for Android示例-唐朝资源网

tflite
= Interpreter(loadModelFile(activity)) inputBuffer = ByteBuffer.allocateDirect( BYTE_SIZE_OF_FLOAT * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE) inputBuffer.order(ByteOrder.nativeOrder()) mnistOutput = Array(DIM_BATCH_SIZE) { FloatArray(NUMBER_LENGTH) } Log.d(TAG, "Created a Tensorflow Lite MNIST Classifier.") } catch (e: IOException) { Log.e(TAG, "IOException loading the tflite file failed.") } }

从文件中加载 mnist.model:

    /**
     * Load the model file from the assets folder
     */
    @Throws(IOException::class)
    private fun loadModelFile(activity: Activity): MappedByteBuffer {
        val fileDescriptor = activity.assets.openFd(MODEL_PATH)
        val inputStream = FileInputStream(fileDescriptor.fileDescriptor)

        val fileChannel = inputStream.channel
        val startOffset = fileDescriptor.startOffset
        val declaredLength = fileDescriptor.declaredLength
        return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
    }

手写数字的真正识别在()方法中:

val digit = mnistClassifier.classify(Bitmap.createScaledBitmap(paintView.bitmap, PIXEL_WIDTH, PIXEL_WIDTH, false))

() 方法包含初始化、运行 mnist 模型和识别数字的预处理。

    /**
     * Classifies the number with the mnist model.
     *
     * @param bitmap
     * @return the identified number
     */
    fun classify(bitmap: Bitmap): Int {
        if (tflite == null) {
            Log.e(TAG, "Image classifier has not been initialized; Skipped.")
        }
        preProcess(bitmap)

        runModel()
        return postProcess()
    }
    /**
     * Converts it into the Byte Buffer to feed into the model
     *
     * @param bitmap
     */
    private fun preProcess(bitmap: Bitmap?) {
        if (bitmap == null || inputBuffer == null) {
            return
        }
        // Reset the image data
        inputBuffer.rewind()
        val width = bitmap.width
        val height = bitmap.height

图片[2]-TensorFlow Lite for Android示例-唐朝资源网

// The bitmap shape should be 28 x 28 val pixels = IntArray(width * height) bitmap.getPixels(pixels, 0, width, 0, 0, width, height) for (i in pixels.indices) { // Set 0 for white and 255 for black pixels val pixel = pixels[i] // The color of the input is black so the blue channel will be 0xFF. val channel = pixel and 0xff inputBuffer.putFloat((0xff - channel).toFloat()) } } /** * Run the TFLite model */ private fun runModel() = tflite.run(inputBuffer, mnistOutput) /** * Go through the output and find the number that was identified. * * @return the number that was identified (returns -1 if one wasn't found) */ private fun postProcess(): Int { for (i in 0 until mnistOutput[0].size) { val value = mnistOutput[0][i] if (value == 1f) { return i } } return -1 }

有一个地方需要注意,build 中必须添加以下语句。应用程序模块,否则无法加载模型。

影响:

五、总结

本次demo地址:

当然也可以运行官方的例子:

虽然不是很准确。. .

更有趣的 Lite 示例:

参考链接:

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片