Tensorflow2.0+部署(tensorflow/serving)过程备忘记录Windows
Tensorflow2.0+部署(tensorflow/serving)过程备忘记录
部署思路:采用Tensorflow自带的serving进模型部署,采用容器docker
1.首先安装docker
下载地址(下载windows版本):https://desktop.docker.com/
- docker安装
安装就按正常流程一步一步安装即可 - window环境检查
win10,win11版本及以上
虚拟化是否开启(用处不知道,反正大家都开启了,网上有教程,可以搜搜)
- 安装wsl
下图是截别人的图

- 安装docker成功
(1)桌面会出现Docker Desktop图标,点击进入后界面如下

(2)给docker添加阿里云镜像源,为了后续下载东西更方便
注册、登录阿里云(支付宝、淘宝扫码都可)

(3)进入后,可以看到自己独立的镜像加速器,是一个网址,最下方一行是给docker配置镜像源的方法,或者直接在Docker Desktop里面,添加那一行命令即可

(4)打开Docker Desktop ,点击设置,Docker Engine,添加上图中的代码到窗口中,点击应用和重启按钮即可

(5)win+R,打开命令行,输入docker info,查看是否应用成功

2.安装tensorflow/serving服务
1.docker 拉取tensorflow/serving服务
安装tensorflow 2.6.0的GPU服务
docker pull tensorflow/serving:2.6.0-gpu
安装tensorflow 2.6.0的CPU服务
docker pull tensorflow/serving:2.6.0
2.查看是否拉取成功,其中,GPU版本比较大
docker images

3.准备模型测试
1.先拿官方例子测试一下,先下载一下tensorflow/serving2.6.0,然后在该目录结构下,找到 saved_model_half_plus_two_gpu例子,整体拷贝到想要放置的位置

2.开始发布一下该服务
(1)GPU版本,–gpus all 标注了下使用机器的所有GPU,我这边不加提示找不到GPU
注意:
下面的绝对路径表示模型存放的实际路径,最后一个参数项需要指定运行的容器和版本,里面的其他参数照猫画虎吧,很好理解,具体参数项也比较复杂
docker run --gpus all -t --rm -p 8501:8501 -v "C:/Users/lixia/.docker/tf_serving/saved_model_half_plus_two_gpu:/models/saved_model_half_plus_two_gpu" -e MODEL_NAME=saved_model_half_plus_two_gpu tensorflow/serving:2.6.0-gpu
出现了如下图,则表示发布成功

此时,在Docker Desktop中可以看到该服务信息

此时,浏览器访问localhost:8501,看是否能连通
http://localhost:8501/v1/models/saved_model_half_plus_two_gpu
出现该信息,则表示可以正常连通和访问了

3.测试调用一下该服务,是否能正常返回结果
#调用官方例子 线性回归小例子 y=0.5*x+2.0
import requests
import jsonurl='http://localhost:8501/v1/models/saved_model_half_plus_two_gpu:predict'
pdata = {"instances":[1.0, 2.0, 3.0]}
param = json.dumps(pdata)
res = requests.post(url, data= param)
print(res.text)

出现该结果表示部署成功

4.服务停止
(1)去Docker Desktop界面端中,手动终止,上面有图
(2)命令行的形式停止
查看运行中的服务
docker ps
终止服务 ****表示ID
docker stop ******

4.准备自己的模型部署测试
准备一个部署练习代码:是否佩戴口罩检测(YOLOv5)
1.首先需要有一个训练好的模型文件,如下图,是我训练好的一个模型

2.将.h5模型转换为.pb模型
直接使用TF自带的函数转(tf.keras.models.save_model),我的模型初始化+参数加载都在yolo.YOLO()中完成了
import tensorflow as tf
import yolodef export_serving_model(path,version=1):"""导出标准的模型格式:param path::return:"""#路径+模型名字+版本export_path = './yolov5_mask_detection/1'#调用模型,指定训练好的.h5文件model = yolo.YOLO()#导出模型tf.keras.models.save_model(model.yolo_model,export_path,overwrite=True,include_optimizer=True,save_format=None,signatures=None,options=None)
运行完后,会生产出下面文件结构的模型.pb文件,直接拷贝上上级整体目录结构即可yolov5_mask_detection

3.将pb模型发布服务
(1)我直接拷贝到D盘根目录

(2)发布GPU服务
docker run --gpus all -t --rm -p 8501:8501 -v "D:/yolov5_mask_detection:/models/yolov5_mask_detection" -e MODEL_NAME=yolov5_mask_detection tensorflow/serving:2.6.0-gpu
(3)发布CPU服务
直接发布即可,发现GPU模型直接可以在CPU使用
docker run -t --rm -p 8501:8501 -v "D:/yolov5_mask_detection:/models/yolov5_mask_detection" -e MODEL_NAME=yolov5_mask_detection tensorflow/serving:2.6.0
出现如下,表示发布成功

4.调用模型
(1)新建一个裸的python环境,最好和tf用的版本一致,保不齐会出现问题啥的,如果缺少requests 、numpy、PIL库,pip install安装即可;
(2)调用代码前,如果不知道输入输出是啥,需要看下
进行conda环境,激活tf虚拟环境,输入命令查看
#打开anaconda命令行输入
conda activate tensorflow-gpu
#产看模型的输入输出和网络结构,绝对路径表示模型存放路径
saved_model_cli show --dir D:\yolov5_mask_detection\1 --all
输出参数包含三个,yolo_eval_1表示概率值;yolo_eval_2表示标签值;yolo_eval表示目标检测框

(3)调用代码,核心代码和上述官方例子一致,只不过加了些影像读取+预处理代码
代码如下:
import json
import time
import requests
import numpy as np
from PIL import Image
import ujson#---------------------------------------------------#
# 对输入图像进行resize,模型训练过程也采用了同样的方法
#---------------------------------------------------#
def resize_image(image, size, letterbox_image):iw, ih = image.sizew, h = sizeif letterbox_image:scale = min(w/iw, h/ih)nw = int(iw*scale)nh = int(ih*scale)image = image.resize((nw,nh), Image.BICUBIC)new_image = Image.new('RGB', size, (128,128,128))new_image.paste(image, ((w-nw)//2, (h-nh)//2))else:new_image = image.resize((w, h), Image.BICUBIC)return new_image
#---------------------------------------------------#
# 对输入图像进行归一化,模型训练过程也采用了同样的方法
#---------------------------------------------------#
def preprocess_input(image):image /= 255.0return image
#服务网址
url = 'http://localhost:8501/v1/models/yolov5_mask_detection:predict'
#计时器
tt1 = time.time()
#输入的影像路径
image = Image.open("1.jpg")
#影像需要重采样成640*640
image_data = resize_image(image, (640, 640), True)
#维度扩展,和模型训练保持一致
image_data = np.expand_dims(preprocess_input(np.array(image_data, dtype='float32')), 0)
#原始影像大小,主要是为了将描框放缩到初始影像大小时用到的参数
input_image_shape = np.expand_dims(np.array([image.size[1], image.size[0]], dtype='float32'), 0)
#构造输入的参数类型,有两个参数,第一个表示影像数据1*640*640*3,第二个表示初始影像宽高
# data = json.dumps({
# "signature_name": "serving_default",
# "inputs":
# {"input_1": image_data.tolist(), "input_2": input_image_shape.tolist()}
# })
#换一种json解析方法,速度更快
data = ujson.dumps({"signature_name": "serving_default","inputs":{"input_1": image_data.tolist(), "input_2": input_image_shape.tolist()}})
#构造headers
headers = {"content-type":"application/json"}
#发送请求
r = requests.post(url, data=data, headers=headers)
#计时器终止
tt2 = time.time()
print(tt2-tt1)
#打印返回的结果,这里表示所有框的位置
print(r.text)
注意:
实际测试中发现,大影像转json时,效率偏低,可以直接使用ujson进行替换,其他更优的办法暂时也不过多探讨
**1.安装ujson
pip install ujson

**2.测试记录
import ujson
****tt2 = time.time()# 构造输入的参数类型,有两个参数,第一个表示影像数据1*640*640*3,第二个表示初始影像宽高# -------------------------------------------------------------------------------------data = json.dumps({"signature_name": "serving_default","inputs":{"input_1": image_data.tolist(), "input_2": input_image_shape.tolist()}})tt21 = time.time()print("json方式:",tt21 - tt2)# ------------------------------------------------------------------------------------data = ujson.dumps({"signature_name": "serving_default","inputs":{"input_1": image_data.tolist(), "input_2": input_image_shape.tolist()}})tt22 = time.time()print("ujson方式:",tt22 - tt21)
效率大概提升一倍多,可以一定程度提升推理速度,大数据情况可以考虑,小数据无所谓

直接右键运行,得到结果,表示该程序检测出了9个目标,概率值+标签+目标框像素位置如下,通过解析json,可以得到目标检测结果

(4)我们看下,将检测结果标记到图上后,效果如下:

换个图片试一下

5.将docker环境整体打包到其他电脑测试(待续…)
有空了试试
6.一些备忘记录
1.conda 环境整体打包移植
//----------------------------------------------------------------------------------------------------------
conda 环境打包到其他电脑要将 Conda 环境打包并迁移到其他电脑上使用,可以按照以下步骤进行操作:导出 Conda 环境: 在源电脑上使用以下命令导出 Conda 环境的配置信息到一个 YAML 文件中:conda env export > environment.yml
复制环境文件: 将生成的 environment.yml 文件复制到目标电脑上。创建 Conda 环境: 在目标电脑上使用以下命令根据导出的环境文件创建相同的 Conda 环境:conda env create -f environment.yml
激活环境: 激活新创建的 Conda 环境:conda activate <environment_name>
相关文章:
Tensorflow2.0+部署(tensorflow/serving)过程备忘记录Windows
Tensorflow2.0部署(tensorflow/serving)过程备忘记录 部署思路:采用Tensorflow自带的serving进模型部署,采用容器docker 1.首先安装docker 下载地址(下载windows版本):https://desktop.docke…...
Docker的安装跟基础使用一篇文章包会
目录 国内源安装新版本 1、清理环境 2、配置docker yum源 3、安装启动 4、启动Docker服务 5、修改docker数据存放位置 6、配置加速器 现在我们已经完成了docker的安装和初始配置。以下为基本测试使用 自带源安装的版本太低 docker官方源安装的话速度太慢了 所以本篇文…...
SQL技巧笔记(一):连续3人的连号问题—— LeetCode601.体育馆的人流量
SQL 技巧笔记 前言:我发现大数据招聘岗位上的应聘流程都是需要先进行笔试,其中占比很大的部分是SQL题目,经过一段时间的学习之后,今天开了一个力扣年会员,我觉得我很有必要去多练习笔试题目,这些题目是有技…...
LeetCode 1976.到达目的地的方案数:单源最短路的Dijkstra算法
【LetMeFly】1976.到达目的地的方案数:单源最短路的Dijkstra算法 力扣题目链接:https://leetcode.cn/problems/number-of-ways-to-arrive-at-destination/ 你在一个城市里,城市由 n 个路口组成,路口编号为 0 到 n - 1 ÿ…...
vulnhub-----Hackademic靶机
文章目录 1.C段扫描2.端口扫描3.服务扫描4.web分析5.sql注入6.目录扫描7.写马php反弹shell木马 8.反弹shell9.内核提权 1.C段扫描 kali:192.168.9.27 靶机:192.168.9.25 ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0,…...
十秒学会Ubuntu命令行:从入门到进阶
一、引言 在使用Ubuntu操作系统时,命令行界面(CLI)是不可或缺的一部分。对于初学者来说,掌握基本的命令行操作可以帮助他们更高效地管理系统和软件。 本文将介绍一些常见的Ubuntu命令以及如何解决与命令行相关的问题。 目录 一、…...
华为智慧教室3.0的晨光,点亮教育智能化变革
“教室外有更大的世界,但世界上没有比教室更伟大的地方。” 我们在求学阶段,都听说过这句话,但往往是在走出校园之后,才真正理解了这句话。为了让走出校园的孩子能够有能力,有勇气探索广阔的世界。我们应该准备最好的教…...
深度学习预测分析API:金融领域的Game Changer
🚀 引言 在这个AI遍地开花的时代,谁能成为金融领域的真正Game Changer?那必然是是深度学习预测分析API。如大脑般高效运转的系统不仅颠覆了传统操作,更是以无与伦比的速度和精度赋予了金融数据以全新的生命。 💼 广泛…...
外贸网站做Google SEO 用wordpress模板的优势
易于优化:WordPress模板是专门为搜索引擎优化(SEO)设计的。从一开始,WordPress模板就考虑到了搜索引擎的因素,因此在构建网站时已经考虑了如何优化网站的结构和内容。使用WordPress模板可以简化优化过程,让您的网站更容易被搜索引…...
后端面试题整理-1
1.Maven 依赖传递产生版本冲突怎么解决? 升级或降级依赖版本:通过修改相关依赖的版本号,选择与项目其他依赖兼容的版本。可以通过查看 Maven 依赖树来确定哪些依赖冲突,并找出合适的版本号进行调整。排除依赖:对于特定…...
Python图像处理之光斑分析
文章目录 质心目标截取光斑半径 python图像处理教程:初步📷插值变换📷形态学处理📷滤波 光斑是工程中经常出现的图像数据,其特点是目标明确,分布清晰。对光斑图像的分析,主要包括质心定位、目标…...
软件测试 - 测试用例基本理论
1. 概念 为了特定的目的(该目的是检验代码是否满足用户需求)而设计的文档,文档包含测试输入、执行条件、预期结果等。文档的形式一般是excel表格。 比如说我们买了一台电脑,新买的笔记本检查完外观之后第一步需要查看电脑是否能够正常开机,…...
在 Flutter 中使用 flutter_gen 简化图像资产管理
你是否厌倦了在 Flutter 项目中手动管理图像资产的繁琐任务? 告别手工输入资源路径的痛苦,欢迎使用“Flutter Gen”高效资源管理的时代。在本文中,我将带您从手动处理图像资源的挫折到动态生成它们的便利。 选择1:痛苦手动添加–…...
两天学会微服务网关Gateway-Gateway过滤器
锋哥原创的微服务网关Gateway视频教程: Gateway微服务网关视频教程(无废话版)_哔哩哔哩_bilibiliGateway微服务网关视频教程(无废话版)共计17条视频,包括:1_Gateway简介、2_Gateway工作原理、3…...
图像处理 mask掩膜
1,图像算术运算 图像的算术运算有很多种,比如两幅图像可以相加,相减,相乘,相除,位运算,平方根,对数,绝对值等;图像也可以放大,缩小,旋…...
信驰达ESP32-C3/RTL8720CM WiFi开发板RF-WT01上线
为方便客户快速选型和验证WiFi模块,深圳市信驰达科技有限公司推出了WiFi开发板RF-WT01,支持适配信驰达RF-WM-ESP32B1、RF-WM-20CMB1、RF-WM-11AFB1、RF-WM-20DNB1 4款WiFi串口模块使用,方便客户实现对信驰达WiFi模块的快速测试和评估。 图1RF…...
【产品经理方法论——产品的基本概念】
1. 产品学三元素 产品学有三个元素:用户、需求、产品 产品学的内容:根据用户的需求设计产品,使用产品服务用户 仅仅通过三个元素无法说明每个元素的概念,因为三个元素互为说明关系。 通过引入人/群体来说明三个元素的关系。 需…...
推特API(Twitter API)V2 查询用户信息
前面章节已经介绍使用code换取Token的整个流程了,这里不再重复阐述了,下面我们介绍如何使用Token查询用户信息等操作。 1.引入相关依赖Maven <dependency> <groupId>oauth.signpost</groupId> <artifactId>signpost-co…...
在Elasticsearch IK分词器中更新、停用某些专有名词
在Elasticsearch IK分词器中更新、停用某些专有名词 目前IK分词器对于现有的新名词或者流行语没有做区分比如"白嫖" “奥利给”,或者对一些没有用的字比如 “的” "地"进行分词其实没有必要过多的分词只会占用宝贵的内存空间,所以如…...
时钟显示 html JavaScript
sf.html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>时间</title><script>function showTime(){var timenew Date();var datetime.getDate();var yeartime.getFullYear();var monthtime.getMonth()1;var …...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
