TensorFlow系列:第五讲:移动端部署模型
项目地址:https://github.com/LionJackson/imageClassification
Flutter项目地址:https://github.com/LionJackson/flutter_image
一. 模型转换
编写tflite模型工具类:
import osimport PIL
import tensorflow as tf
import keras
import numpy as np
from PIL.Image import Image
from matplotlib import pyplot as pltfrom utils.dataset_loader import DatasetLoader
from utils.utils import Utils"""
tflite模型工具类
"""class TFLiteUtil:def __init__(self, saved_model_dir, path_url):self.save_model_dir = saved_model_dirself.path_url = path_url# 训练的模型生成标签列表def get_folder_names(self):folder_names = []for root, dirs, files in os.walk(self.path_url + '/train'):for dir_name in dirs:folder_names.append(dir_name)with open(self.save_model_dir + '.label', 'w') as file:for name in folder_names:file.write(name + '\n')return folder_names# 模型转成tflite格式def convert_tflite(self):self.get_folder_names()converter = tf.lite.TFLiteConverter.from_saved_model(self.save_model_dir)tflite_model = converter.convert()# 将转换后的 TFLite 模型保存为文件with open(self.save_model_dir + '.tflite', 'wb') as f:f.write(tflite_model)print("转换成功,已保存为 tflite")# 加载keras并转成tflitedef convert_model_tflite(self):self.get_folder_names()model = keras.models.load_model(self.save_model_dir + ".keras")converter = tf.lite.TFLiteConverter.from_keras_model(model)converter.optimizations = [tf.lite.Optimize.DEFAULT]converter.target_spec.supported_types = [tf.float16]tflite_model = converter.convert()# 将转换后的 TFLite 模型保存为文件with open(self.save_model_dir + '.tflite', 'wb') as f:f.write(tflite_model)print("转换成功(model),已保存为 tflite")# 批量识别 进行可视化显示def batch_evaluation(self, class_mode='categorical', image_size=(224, 224), num_images=25):dataset_loader = DatasetLoader(self.path_url, image_size=image_size, class_mode=class_mode)train_ds, val_ds, test_ds, class_names = dataset_loader.load_data()interpreter = tf.lite.Interpreter(self.save_model_dir + '.tflite')interpreter.allocate_tensors()# 获取输入和输出张量的信息input_details = interpreter.get_input_details()output_details = interpreter.get_output_details()plt.figure(figsize=(10, 10))for images, labels in test_ds.take(1):outputs = []for img in images:img_expanded = np.expand_dims(img, axis=0)interpreter.set_tensor(input_details[0]['index'], img_expanded)interpreter.invoke()output = interpreter.get_tensor(output_details[0]['index'])outputs.append(output)for i in range(num_images):plt.subplot(5, 5, i + 1)image = np.array(images[i]).astype("uint8")plt.imshow(image)index = int(np.argmax(outputs[i]))prediction = outputs[i][0][index]percentage_str = "{:.2f}%".format(prediction * 100)plt.title(f"{class_names[index]}: {percentage_str}")plt.axis("off")plt.subplots_adjust(hspace=0.5, wspace=0.5)plt.show()# 查看tflite模型信息def tflite_analyzer(self):# 加载 TFLite 模型interpreter = tf.lite.Interpreter(model_path=self.save_model_dir + '.tflite')interpreter.allocate_tensors()# 获取输入和输出的详细信息input_details = interpreter.get_input_details()output_details = interpreter.get_output_details()# 打印输入和输出的详细信息print("Input Details:")for detail in input_details:print(detail)print("\nOutput Details:")for detail in output_details:print(detail)# 列出所有使用的算子tensor_details = interpreter.get_tensor_details()print("\nTensor Details:")for tensor_detail in tensor_details:print("Index:", tensor_detail['index'])print("Name:", tensor_detail['name'])print("Shape:", tensor_detail['shape'])print("Shape Signature:", tensor_detail['shape_signature'])print("dtype:", tensor_detail['dtype'])print("Quantization:", tensor_detail['quantization'])print("Quantization Parameters:", tensor_detail['quantization_parameters'])print("Sparsity Parameters:", tensor_detail['sparsity_parameters'])print()
引用工具类:
if __name__ == '__main__':# train()# model_util = ModelUtil(SAVED_MODEL_DIR, PATH_URL)# model_util.batch_evaluation()tflite_util = TFLiteUtil(SAVED_MODEL_DIR, PATH_URL)tflite_util.convert_tflite()tflite_util.tflite_analyzer()tflite_util.batch_evaluation()
此时会生成tflite模型文件:

二. 使用模型
创建flutter项目,引入以下库:
image: ^4.0.17path: ^1.8.3path_provider: ^2.0.15image_picker: ^0.8.8tflite_flutter: ^0.10.4camera: ^0.10.5+2
把模型文件拷贝到项目中:

核心代码:
import 'dart:developer';
import 'dart:io';
import 'dart:isolate';import 'package:camera/camera.dart';
import 'package:flutter/services.dart';
import 'package:image/image.dart';
import 'package:tflite_flutter/tflite_flutter.dart';import 'isolate_inference.dart';class ImageClassificationHelper {static const modelPath = 'assets/models/fruits.tflite';static const labelsPath = 'assets/models/fruits.label';late final Interpreter interpreter;late final List<String> labels;late final IsolateInference isolateInference;late Tensor inputTensor;late Tensor outputTensor;// Load modelFuture<void> _loadModel() async {final options = InterpreterOptions();// Use XNNPACK Delegateif (Platform.isAndroid) {options.addDelegate(XNNPackDelegate());}// Use GPU Delegate// doesn't work on emulator// if (Platform.isAndroid) {// options.addDelegate(GpuDelegateV2());// }// Use Metal Delegateif (Platform.isIOS) {options.addDelegate(GpuDelegate());}// Load model from assetsinterpreter = await Interpreter.fromAsset(modelPath, options: options);// Get tensor input shape [1, 224, 224, 3]inputTensor = interpreter.getInputTensors().first;// Get tensor output shape [1, 1001]outputTensor = interpreter.getOutputTensors().first;log('Interpreter loaded successfully');}// Load labels from assetsFuture<void> _loadLabels() async {final labelTxt = await rootBundle.loadString(labelsPath);labels = labelTxt.split('\n');}Future<void> initHelper() async {_loadLabels();_loadModel();isolateInference = IsolateInference();await isolateInference.start();}Future<Map<String, double>> _inference(InferenceModel inferenceModel) async {ReceivePort responsePort = ReceivePort();isolateInference.sendPort.send(inferenceModel..responsePort = responsePort.sendPort);// get inference result.var results = await responsePort.first;return results;}// inference camera frameFuture<Map<String, double>> inferenceCameraFrame(CameraImage cameraImage) async {var isolateModel = InferenceModel(cameraImage, null, interpreter.address,labels, inputTensor.shape, outputTensor.shape);return _inference(isolateModel);}// inference still imageFuture<Map<String, double>> inferenceImage(Image image) async {var isolateModel = InferenceModel(null, image, interpreter.address, labels,inputTensor.shape, outputTensor.shape);return _inference(isolateModel);}Future<void> close() async {isolateInference.close();}
}
页面部分:

相关文章:
TensorFlow系列:第五讲:移动端部署模型
项目地址:https://github.com/LionJackson/imageClassification Flutter项目地址:https://github.com/LionJackson/flutter_image 一. 模型转换 编写tflite模型工具类: import osimport PIL import tensorflow as tf import keras import …...
深度学习DeepLearning二元分类 学习笔记
文章目录 类别区分变量与概念逻辑回归Sigmoid函数公式决策边逻辑损失函数和代价函数逻辑回归的梯度下降泛化过拟合的解决方案正则化 类别区分 变量与概念 决策边置信度阈值threshold过拟合欠拟合正则化高偏差lambda(λ) 线性回归受个别极端值影响&…...
Eureka 介绍与使用
Eureka 是一个开源的服务发现框架,它主要用于在分布式系统中管理和发现服务实例。它由 Netflix 开发并开源,是 Netflix OSS 中的一部分。 使用 Eureka 可以方便地将新的服务实例注册到 Eureka 服务器,并且让其他服务通过 Eureka 服务器来发现…...
Java异常体系、UncaughtExceptionHandler、Spring MVC统一异常处理、Spring Boot统一异常处理
概述 所有异常都是继承自java.lang.Throwable类,Throwable有两个直接子类,Error和Exception。 Error用来表示程序底层或硬件有关的错误,这种错误和程序本身无关,如常见的NoClassDefFoundError。这种异常和程序本身无关࿰…...
bash终端快捷键
快捷键作用ShiftCtrlC复制ShiftCtrlV粘贴CtrlAltT新建终端ShiftPgUp/PgDn终端上下翻页滚动CtrlC终止命令CtrlD关闭终端CtrlA光标移动到最开始为止CtrlE光标移动到最末尾CtrlK删除此处到末尾的所有内容CtrlU删除此处至开始的所有内容CtrlD删除当前字符CtrlH删除当前字符的前一个…...
【Visual Studio】Visual Studio报错合集及解决办法
目录 Visual Studio报错:error LNK2001 Visual Studio报错:error C2061 Visual Studio报错:error C1075 Visual Studio报错:error C4430 Visual Studio报错error C3867 概述 持续更细Visual Studio报错及解决方法 Visual Studio报错:error LNK2001 问题 : error LNK2001…...
【微信小程序知识点】转发功能的实现
转发功能,主要帮助用户更流畅地与好友分享内容与服务。 想实现转发功能,有两种方式: 1.页面js文件必须声明onShareAppMessage事件监听函数,并自定义转发内容。只有定义了此事件处理函数,右上角菜单才会显示“转发”按…...
用python识别二维码(python实例二十三)
目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.识别二维码 3.1 代码构思 3.2 代码实例 3.3 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&…...
电脑文件夹怎么设置密码?让你的文件更安全!
在日常使用电脑的过程中,我们常常会有一些需要保护的个人文件或资料。为了防止这些文件被他人未经授权访问,对重要文件夹设置密码是一种有效的保护措施,可是电脑文件夹怎么设置密码呢?本文将介绍2种简单有效的方法帮助您为电脑文件…...
paddla模型转gguf
在使用ollama配置本地模型时,只支持gguf格式的模型,所以我们首先需要把自己的模型转化为bin格式,本文为paddle,onnx,pytorch格式的模型提供说明,safetensors格式比较简单请参考官方文档,或其它教…...
Memcached vs Redis——Java项目缓存选择
在Java项目开发中,缓存系统作为提升性能、优化资源利用的关键技术之一,扮演着至关重要的角色。Memcached和Redis作为两种流行的缓存解决方案,各有其独特的优势和应用场景。本文旨在通过分析项目大小、用户访问量、业务复杂度以及服务器部署情…...
大模型最新黑书:基于GPT-3、ChatGPT、GPT-4等Transformer架构的自然语言处理 PDF
今天给大家推荐一本丹尼斯罗斯曼(Denis Rothman)编写的关于大语言模型(LLM)权威教程<<大模型应用解决方案> 基于GPT-3、ChatGPT、GPT-4等Transformer架构的自然语言处理>!Google工程总监Antonio Gulli作序,这含金量不…...
【电子数据取证】电子数据司法鉴定
文章关键词:电子数据取证、司法鉴定服务、司法鉴定流程 一、定义 什么是司法鉴定? 在诉讼活动中鉴定人运用科学技术或者专业知识对诉讼涉及的专门性问题进行鉴别和判断并提供鉴定意见的活动。 电子数据司法鉴定 那么电子数据司法鉴定,就…...
使用 OpenCV 的 inRange 函数进行颜色分割
使用 OpenCV 的 inRange 函数进行颜色分割 在图像处理领域,颜色分割是一个常见的任务,常用于识别和提取图像中的特定颜色区域。OpenCV 提供了一个非常方便的函数 inRange 来实现这一功能。在这篇博客中,我们将详细介绍 inRange 函数的用法&a…...
OpenAI终止对中国提供API服务,对国内AI市场产生重大冲击?
6月25日,OpenAI突然宣布终止向包括中国在内的国家地区提供API服务,本月9日这一政策已经正式生效了! 有人说,这个事件给中国AI行业带来很大冲击!是这样吗?在展开讨论前,我们先来看看什么是API服务…...
JavaDS —— 栈 Stack 和 队列 Queue
栈的概念 栈是一种先进后出的线性表,只允许在固定的一端进行插入和删除操作。 进行插入和删除操作的一端被称为栈顶,另一端被称为栈底 栈的插入操作叫做进栈/压栈/入栈 栈的删除操作叫做出栈 现实生活中栈的例子: 栈的模拟实现 下面是Jav…...
C++进阶:继承和多态
文章目录 ❤️继承🩷继承与友元🧡继承和静态成员💛菱形继承及菱形虚拟继承💚继承和组合 ❤️多态🩷什么是多态?🧡多态的定义以及实现💛虚函数💚虚函数的重写💙…...
【八大排序】java版(上)(冒泡、快排、堆排、选择排序)
文章目录 一、冒泡排序(重点)思路代码 二、快排(面试重点)思路代码 三、堆排序(面试重点)思路代码 四、选择排序思路代码 一、冒泡排序(重点) 思路 前后两两数据进行比较,小的数据往前走,大的数据往后走,每一轮结束之后,最大的数…...
.Net Core 微服务之Consul(二)-集群搭建
引言: 集合上一期.Net Core 微服务之Consul(一)(.Net Core 微服务之Consul(一)-CSDN博客) 。 目录 一、 Consul集群搭建 1. 高可用 1.1 高可用性概念 1.2 高可用集群的基本原理 1.3 高可用集群的架构设计 1.3.1 主从复制架构 1.3.2 共享存储架构 1.3.3 负载均衡…...
C++ --> 类和对象(二)
前言 在前面简单的介绍了OOP,什么是类,在类中的this指针。接下来就深入理解类和对象。 默认成员函数 默认构造函数:用于在创建对象时初始化对象的成员变量。默认拷贝构造函数:用于使用已存在的对象来初始化新创建的对象。默认析构…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
