0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

全新插件tflite_flutter

Tensorflowers 来源:TensorFlow 2020-09-27 14:42 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

如果您希望能有一种简单、高效且灵活的方式把 TensorFlow 模型集成到 Flutter 应用里,那请您一定不要错过我们今天介绍的这个全新插件tflite_flutter。这个插件的开发者是 Google Summer of Code (GSoC) 的一名实习生 Amish Garg。

tflite_flutter插件的核心特性:

插件提供了与 TFLite Java 和 Swift API 相似的 Dart API,所以其灵活性和在这些平台上的效果是完全一样的;

插件通过 dart:ffi 直接与 TensorFlow Lite C API 相绑定,所以它比其它平台集成方式更加高效;

无需编写特定平台的代码;

通过 NNAPI 提供加速支持,在 Android 上使用 GPU Delegate,在 iOS 上使用 Metal Delegate。

本文中,我们将使用 tflite_flutter 构建一个文字分类 Flutter 应用,带您体验 tflite_flutter 插件。首先从新建一个 Flutter 项目text_classification_app开始。

初始化配置

Linux 和 Mac用户

将 install.sh 拷贝到您应用的根目录,然后在根目录执行 sh install.sh,本例中就是目录 text_classification_app/。

Windows 用户

将 install.bat 文件拷贝到应用根目录,并在根目录运行批处理文件 install.bat,本例中就是目录 text_classification_app/。

它会自动从GitHub 仓库的 Releases 里下载最新的二进制资源,然后把它放到指定的目录下。

请点击到 README 文件里查看更多关于初始配置的信息。

tflite_flutter 的 GitHub 仓库
https://github.com/am15h/tflite_flutter_plugin

获取插件

在pubspec.yaml添加tflite_flutter: ^

最新版本情况参考插件的发布地址
https://pub.flutter-io.cn/packages/tflite_flutter

下载模型

要在移动端上运行 TensorFlow 训练模型,我们需要使用 .tflite 格式。如果需要了解如何将 TensorFlow 训练的模型转换为 .tflite 格式,请参阅官方指南。

这里我们准备使用 TensorFlow 官方站点上预训练的文字分类模型。

该预训练的模型可以预测当前段落的情感是积极还是消极。它是基于来自 Mass 等人的 Large Movie Review Dataset v1.0数据集进行训练的。数据集由基于 IMDB 电影评论所标记的积极或消极标签组成,查看更多信息。

将 text_classification.tflite 和 text_classification_vocab.txt 文件拷贝到 text_classification_app/assets/ 目录下。

在 pubspec.yaml 文件中添加 assets/。

assets: - assets/

现在万事俱备,我们可以开始写代码了。

模型转换器(Converter)的 Python API 指南
https://tensorflow.google.cn/lite/convert/python_api

预训练的文字分类模型(text_classification.tflite)
https://files.flutter-io.cn/posts/flutter-cn/2020/tensorflow-lite-plugin/text_classification.tflite

数据集(text_classification_vocab.txt)
https://files.flutter-io.cn/posts/flutter-cn/2020/tensorflow-lite-plugin/text_classification_vocab.txt

实现分类器

预处理

正如文字分类模型页面里所提到的。可以按照下面的步骤使用模型对段落进行分类:

对段落文本进行分词,然后使用预定义的词汇集将它转换为一组词汇 ID;

将生成的这组词汇 ID 输入 TensorFlow Lite 模型里;

从模型的输出里获取当前段落是积极或者是消极的概率值。

我们首先写一个方法对原始字符串进行分词,其中使用 text_classification_vocab.txt作为词汇集。

在 lib/文件夹下创建一个新文件 classifier.dart。

这里先写代码加载 text_classification_vocab.txt 到字典里。

import 'package:flutter/services.dart'; class Classifier { final _vocabFile = 'text_classification_vocab.txt'; Map _dict; Classifier() { _loadDictionary(); } void _loadDictionary() async { final vocab = await rootBundle.loadString('assets/$_vocabFile'); var dict = {}; final vocabList = vocab.split(' '); for (var i = 0; i < vocabList.length; i++) { var entry = vocabList[i].trim().split(' '); dict[entry[0]] = int.parse(entry[1]); } _dict = dict; print('Dictionary loaded successfully'); } }

△加载字典

现在我们来编写一个函数对原始字符串进行分词。

import 'package:flutter/services.dart'; class Classifier { final _vocabFile = 'text_classification_vocab.txt'; // 单句的最大长度 final int _sentenceLen = 256; final String start = ''; final String pad = ''; final String unk = ''; Map _dict; List> tokenizeInputText(String text) { // 使用空格进行分词 final toks = text.split(' '); // 创建一个列表,它的长度等于 _sentenceLen,并且使用 的对应的字典值来填充 var vec = List.filled(_sentenceLen, _dict[pad].toDouble()); var index = 0; if (_dict.containsKey(start)) { vec[index++] = _dict[start].toDouble(); } // 对于句子里的每个单词,在映射里找到相应的索引值 for (var tok in toks) { if (index > _sentenceLen) { break; } vec[index++] = _dict.containsKey(tok) ? _dict[tok].toDouble() : _dict[unk].toDouble(); } // 按照我们的解释器输入 tensor 所需的格式 [1, 256] 返回 List> return [vec]; } }

△分词代码

使用 tflite_flutter 进行分析

这是本文的主体部分,这里我们会讨论 tflite_flutter 插件的用途。

此处的分析指的是在设备上基于输入的数据,使用 TensorFlow Lite 模型的处理过程。要使用 TensorFlow Lite 模型进行分析,需要通过解释器来运行它,了解更多。

创建解释器,加载模型

tflite_flutter 提供了一个方法直接通过资源创建解释器。

static Future fromAsset(String assetName, {InterpreterOptions options})

由于我们的模型在 assets/文件夹下,需要使用上面的方法来创建解析器。对于 InterpreterOptions 的相关说明,请参考这里。

import 'package:flutter/services.dart'; // 引入 tflite_flutter import 'package:tflite_flutter/tflite_flutter.dart'; class Classifier { // 模型文件的名称 final _modelFile = 'text_classification.tflite'; // TensorFlow Lite 解释器对象 Interpreter _interpreter; Classifier() { // 当分类器初始化以后加载模型 _loadModel(); } void _loadModel() async { // 使用 Interpreter.fromAsset 创建解释器 _interpreter = await Interpreter.fromAsset(_modelFile); print('Interpreter loaded successfully'); } }

△创建解释器的代码

如果您不希望将模型放在assets/目录下,tflite_flutter 还提供了工厂构造函数创建解释器,更多信息。

我们开始进行分析!

现在用下面方法启动分析:

void run(Object input, Object output);

注意这里的方法和 Java API 中的是一样的。

Object input 和 Object output 必须是与 Input Tensor 和 Output Tensor 维度相同的列表。

要查看 input tensor 和 output tensor 的维度,可以使用如下代码:

_interpreter.allocateTensors(); // 打印 input tensor 列表 print(_interpreter.getInputTensors()); // 打印 output tensor 列表 print(_interpreter.getOutputTensors());

在本例中 text_classification 模型的输出如下:

InputTensorList: [Tensor{_tensor: Pointer: address=0xbffcf280, name: embedding_input, type: TfLiteType.float32, shape: [1, 256], data: 1024] OutputTensorList: [Tensor{_tensor: Pointer: address=0xbffcf140, name: dense_1/Softmax, type: TfLiteType.float32, shape: [1, 2], data: 8]

现在,我们实现分类方法,该方法返回值为 1 表示积极,返回值为 0 表示消极。

int classify(String rawText) { // tokenizeInputText 返回形状为 [1, 256] 的 List> List> input = tokenizeInputText(rawText); // [1,2] 形状的输出 var output = List(2).reshape([1, 2]); // run 方法会运行分析并且存储输出的值 _interpreter.run(input, output); var result = 0; // 如果输出中第一个元素的值比第二个大,那么句子就是消极的 if ((output[0][0] as double) > (output[0][1] as double)) { result = 0; } else { result = 1; } return result; }

△用于分析的代码

在 tflite_flutter 的 extension ListShape on List 下面定义了一些使用的扩展:

// 将提供的列表进行矩阵变形,输入参数为元素总数并保持相等 // 用法:List(400).reshape([2,10,20]) // 返回 List List reshape(List shape) // 返回列表的形状 List get shape // 返回列表任意形状的元素数量 int get computeNumElements

最终的 classifier.dart 应该是这样的:

import 'package:flutter/services.dart'; // 引入 tflite_flutter import 'package:tflite_flutter/tflite_flutter.dart'; class Classifier { // 模型文件的名称 final _modelFile = 'text_classification.tflite'; final _vocabFile = 'text_classification_vocab.txt'; // 语句的最大长度 final int _sentenceLen = 256; final String start = ''; final String pad = ''; final String unk = ''; Map _dict; // TensorFlow Lite 解释器对象 Interpreter _interpreter; Classifier() { // 当分类器初始化的时候加载模型 _loadModel(); _loadDictionary(); } void _loadModel() async { // 使用 Intepreter.fromAsset 创建解析器 _interpreter = await Interpreter.fromAsset(_modelFile); print('Interpreter loaded successfully'); } void _loadDictionary() async { final vocab = await rootBundle.loadString('assets/$_vocabFile'); var dict = {}; final vocabList = vocab.split(' '); for (var i = 0; i < vocabList.length; i++) { var entry = vocabList[i].trim().split(' '); dict[entry[0]] = int.parse(entry[1]); } _dict = dict; print('Dictionary loaded successfully'); } int classify(String rawText) { // tokenizeInputText 返回形状为 [1, 256] 的 List> List> input = tokenizeInputText(rawText); //输出形状为 [1, 2] 的矩阵 var output = List(2).reshape([1, 2]); // run 方法会运行分析并且将结果存储在 output 中。 _interpreter.run(input, output); var result = 0; // 如果第一个元素的输出比第二个大,那么当前语句是消极的 if ((output[0][0] as double) > (output[0][1] as double)) { result = 0; } else { result = 1; } return result; } List> tokenizeInputText(String text) { // 用空格分词 final toks = text.split(' '); // 创建一个列表,它的长度等于 _sentenceLen,并且使用 对应的字典值来填充 var vec = List.filled(_sentenceLen, _dict[pad].toDouble()); var index = 0; if (_dict.containsKey(start)) { vec[index++] = _dict[start].toDouble(); } // 对于句子中的每个单词,在 dict 中找到相应的 index 值 for (var tok in toks) { if (index > _sentenceLen) { break; } vec[index++] = _dict.containsKey(tok) ? _dict[tok].toDouble() : _dict[unk].toDouble(); } // 按照我们的解释器输入 tensor 所需的形状 [1,256] 返回 List> return [vec]; } }

现在,可以根据您的喜好实现 UI 的代码,分类器的用法比较简单。

// 创建 Classifier 对象 Classifer _classifier = Classifier(); // 将目标语句作为参数,调用 classify 方法 _classifier.classify("I liked the movie"); // 返回 1 (积极的) _classifier.classify("I didn't liked the movie"); // 返回 0 (消极的)

△ 文字分类示例应用

了解更多关于 tflite_flutter 插件的信息,请访问 GitHub repo:am15h/tflite_flutter_plugin。

你问我答

问:tflite_flutter 和 tflite v1.0.5 有哪些区别?

tflite v1.0.5 侧重于为特定用途的应用场景提供高级特性,比如图片分类、物体检测等等。而新的 tflite_flutter 则提供了与 Java API 相同的特性和灵活性,而且可以用于任何 tflite 模型中,它还支持 delegate。

由于使用 dart:ffi (dart (ffi) C),tflite_flutter 非常快 (拥有低延时)。而 tflite 使用平台集成 (dart platform-channel (Java/Swift) JNI C)。

问:如何使用 tflite_flutter 创建图片分类应用?有没有类似 TensorFlow Lite Android Support Library 的依赖包?

TensorFlow Lite Flutter Helper Library为处理和控制输入及输出的 TFLite 模型提供了易用的架构。它的 API 设计和文档与 TensorFlow Lite Android Support Library 是一样的。更多信息请参考 TFLite Flutter Helper 的 GitHub 。

TFLite Flutter Helper 开发库 GitHub 仓库地址
https://github.com/am15h/tflite_flutter_helper

以上是本文的全部内容,欢迎大家对 tflite_flutter 插件进行反馈,请在 GitHub报 bug 或提出功能需求。谢谢关注,感谢 Flutter 团队的 Michael Thomsen。

向 tflite_flutter 插件提出建议和反馈
https://github.com/am15h/tflite_flutter_plugin/issues

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • iOS
    iOS
    +关注

    关注

    8

    文章

    3401

    浏览量

    155665
  • 插件
    +关注

    关注

    0

    文章

    346

    浏览量

    23630
  • tensorflow
    +关注

    关注

    13

    文章

    336

    浏览量

    62365

原文标题:社区分享 | 在 Flutter 中使用 TensorFlow Lite 插件实现文字分类

文章出处:【微信号:tensorflowers,微信公众号:Tensorflowers】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    将TensorFlowSavedModel转换为支持imx8mpNPU的tflite模型,没有成功是怎么回事?

    我想将TensorFlowSavedModel转换为支持imx8mpNPU的tflite模型。 我按照以下步骤作,但没有成功 Python 模型/研究/object_detection
    发表于 04-16 06:09

    eiQ Toolkit TFLite 转换器失败问题可能出在什么地方

    I am trying to convert an object detection model from tensorflow to tflite with int8 quantization
    发表于 04-15 08:21

    声智科技语音交互插件上线ClawHub

    核心突破:填补生态空白近日,声智科技自主研发的语音交互插件,包含ASR(自动语音识别)与TTS(语音合成)正式通过ClawHub官方审核并接入服务;与此同时,声智自研的LLM(大语言模型)插件也已成功接入OpenClaw(龙虾)官方插件
    的头像 发表于 04-08 17:55 1110次阅读

    工作流插件节点节点说明

    插件节点用于在工作流中调用插件运行指定工具。 插件是一系列工具的集合,每个工具都是一个可调用的API。插件广场上架的插件或已上架的团队
    发表于 03-23 16:54

    Flutter 移动端开发:集成淘宝 API 实现商品数据实时展示 APP

    在电商蓬勃发展的当下,移动端购物成为主流趋势。对于开发者而言,利用 Flutter 构建一个能够实时展示淘宝商品数据的 APP,既能满足用户便捷获取商品信息的需求,也能为电商业务拓展新的渠道
    的头像 发表于 11-13 09:36 476次阅读

    把edge impulse的文件存入sd卡,插入sd卡到开发板后openmv中还是显示找不到tflite模型和labels,怎么解决?

    把edge impulse的文件存入sd卡,插入sd卡到开发板后openmv中还是显示找不到tflite模型和labels。
    发表于 09-02 07:23

    如何进行tflite模型量化

    在windows上,如果我们按照上一期的方式安装了tflite2pb,是不能直接运行的。因为命令行工具是为linux编译的。
    的头像 发表于 08-13 11:45 1788次阅读
    如何进行<b class='flag-5'>tflite</b>模型量化

    Android Studio中的Gemini全面支持Dart和Flutter开发

    在 Android Studio 中创建 Android 应用的 Flutter 开发者将迎来一次重大的飞跃: Android Studio 中的 Gemini 已全面支持 Dart
    的头像 发表于 08-06 13:52 1493次阅读
    Android Studio中的Gemini全面支持Dart和<b class='flag-5'>Flutter</b>开发

    解锁本地设备交互:机智云端插件接入Gokit5实战指南(音量/亮度控制)

    插件使用说明机智云端插件目前支持Gokit5的按键亮度调节、播放音量调节,可用于自然语言控制设备。1、端插件是什么端插件是扣子插件的一种类
    的头像 发表于 07-30 18:03 797次阅读
    解锁本地设备交互:机智云端<b class='flag-5'>插件</b>接入Gokit5实战指南(音量/亮度控制)

    餐饮服务与软件创新的融合:解析海底捞APP的Flutter鸿蒙开发之路

    首版本上架华为应用市场,今年1月推出全量功能商用版本。基于HarmonyOS 5.0,结合Flutter混编开发的技术探索,以下内容将从功能实现细节、技术适配经验及生态共建启示三方面展开,为开发者提供可复用的鸿蒙开发思路。 一、 海底捞Flutter适配
    的头像 发表于 07-30 15:35 588次阅读
    餐饮服务与软件创新的融合:解析海底捞APP的<b class='flag-5'>Flutter</b>鸿蒙开发之路

    KiCad-Parasitics:KiCad 寄生参数分析插件

    “   这是一款用于分析 PCB 编辑器中走线(wires)寄生参数的插件。   ”     要使用该插件,您必须在电路板上标记两个点。通常情况下,最好是选择由同一根走线连接的两个焊盘。标记后,该
    的头像 发表于 06-25 11:14 2256次阅读
    KiCad-Parasitics:KiCad 寄生参数分析<b class='flag-5'>插件</b>

    用 VSCode 编写自己的 KiCad 插件(下)

    “  很多小伙伴都想自己开发 KiCad 插件,但不知从何入手。本文由华秋电子的另一位 KiCad 开发者波波同学撰写,分享了如何快速搭建环境,并开发一个简单的插件。  ”       所有环境配置
    的头像 发表于 06-19 11:44 3139次阅读
    用 VSCode 编写自己的 KiCad <b class='flag-5'>插件</b>(下)

    用VSCode编写自己的KiCad插件(上)详细步骤教程

    “  很多小伙伴都想自己开发 KiCad 插件,但不知从何入手。本文由华秋电子的另一位 KiCad 开发者波波同学撰写,分享了如何快速搭建环境,并开发一个简单的插件。  ” 目标     编写一个
    的头像 发表于 06-17 11:10 3365次阅读
    用VSCode编写自己的KiCad<b class='flag-5'>插件</b>(上)详细步骤教程

    使用 Flutter SDK 3.27.4构建HarmonyOS应用

    使用 Flutter SDK 3.27.4构建HarmonyOS应用 下载鸿蒙版flutter(3.27.4版本) 项目地址:https://gitcode.com/openharmony-sig
    的头像 发表于 06-11 09:15 1113次阅读

    Flutter on Raspberry Pi:从入门到精通的完整指南!

    在GoogleIO会议上展示了一个在树莓派上运行Flutter的可能性。然而,该会议并未提供全面的、一步一步的指南供用户参考。本文旨在填补这一空白,提供详细的操作步骤,帮助你在树莓派上运行
    的头像 发表于 06-06 15:37 1730次阅读
    <b class='flag-5'>Flutter</b> on Raspberry Pi:从入门到精通的完整指南!