【深度学习】(12)--模型部署 <连接客户端与服务端>
文章目录
- 模型部署
- 一、模型部署的定义与目的
- 二、模型部署的步骤
- 三、模型部署的方式
- 四、Flask框架
- 五、实现模型部署
- 1. 搭建服务端
- 1.1 初始化Flask app
- 1.2 加载模型
- 1.3 数据预处理
- 1.4 构建装饰器
- 1.5 完整代码
- 2. 搭建客户端
- 2.1 服务端网址
- 2.2 发送请求
- 2.3 完整代码
- 六、运行使用
- 总结
模型部署
一、模型部署的定义与目的
模型部署是指将大模型运行在专属的计算资源上,使模型在独立的运行环境中高效、可靠地运行,并为业务应用提供推理服务。其目标是将机器学习模型应用于实际业务中,使最终用户或系统能够利用模型的输出,从而发挥其作用。
二、模型部署的步骤
- 导出模型:将训练好的模型导出为可部署的格式。
- 部署模型:将导出的模型部署到生产环境中,通常是以一个服务或一个库的形式。
- 测试模型:在生产环境中对模型进行测试,以确保其能够正常工作,并且输出结果符合预期。
- 监控模型:在生产环境中对模型进行监控,以便及时发现并解决问题。
三、模型部署的方式
模型的部署方式多种多样,可以根据具体的应用场景和需求而定。以下是一些常见的模型部署方式:
- 云端部署:将模型部署到云端服务器上,通过API接口提供服务,实现远程调用。这种方式可以实现大规模的分布式计算和存储,同时提供高可用性和可扩展性。在云端部署中,需要考虑数据的安全性和隐私保护,以及模型的并发处理能力。
- 嵌入式设备部署:将模型部署到嵌入式设备中,如智能手机、智能音箱、智能家居等。这种方式可以实现本地化的智能化应用,具有实时性、低延迟的优点。在嵌入式设备部署中,需要考虑设备的计算能力、存储空间等限制,以及模型的轻量化设计。
- 边缘计算部署:将模型部署到边缘设备上,如路由器、摄像头等。这种方式可以实现本地数据的实时处理和智能化分析,减少数据传输的延迟和成本。在边缘计算部署中,需要考虑设备的计算能力和数据处理能力,以及模型的实时性要求。
- 移动端部署:将模型部署到移动端设备上,如智能手机、平板电脑等。这种方式可以实现移动设备的智能化应用,提高用户体验。在移动端部署中,需要考虑设备的功耗和性能限制,以及模型的轻量化设计。
- FPGA和GPU部署:FPGA(Field-Programmable Gate Array)部署是将深度学习模型部署到FPGA芯片上,实现高效的硬件加速,提高模型的运行速度和效率。GPU(Graphics Processing Unit)部署是将深度学习模型部署到GPU上,利用GPU的并行计算能力,提高模型的运行速度和效率。这两种方式适用于对计算性能要求较高的场景,如实时图像处理、视频分析等。
四、Flask框架
-
优点:
- 轻量级:Flask是一个轻量级的框架,代码量少,灵活性高,适合快速开发小型应用程序。
- 简单易学:Flask的设计理念简洁明了,入门相对容易,对于初学者来说非常友好。可扩展性强:Flask提供了丰富的扩展库,开发者可以根据需求选择合适的扩展来扩展功能。
- 社区支持良好:Flask有一个庞大的社区,提供了丰富的资源和支持。
-
缺点:
- 功能相对较少:相比于一些大型框架如Django,Flask的功能相对较少,需要依赖扩展库来实现一些功能。
- 安全性考虑:由于Flask的轻量级特性,安全性方面的考虑需要开发者自行关注。
- 不适合大型应用:由于Flask的轻量级特性,它可能不适合开发大型复杂的应用程序。
五、实现模型部署
1. 搭建服务端
1.1 初始化Flask app
"""-----初始化Flask app-----"""
app = flask.Flask(__name__) # 创建一个Flask应用程序实例
model = None
use_gpu = False
1.2 加载模型
本片使用自带的残差网络模型,将网络模型输出转化为自己要求的输出类别数量:
def load_model():global model# 加载resnet18网络model = models.resnet18()num_ftrs = model.fc.in_featuresmodel.fc = nn.Sequential(nn.Linear(num_ftrs,102))checkpoint = torch.load('best.pth')model.load_state_dict(checkpoint['state_dict'])model.eval()# 是否使用gpuif use_gpu:model.cuda()
1.3 数据预处理
将图像转换为模型输入所需的格式:
def prepare_image(image,target_size):if image.mode !='RGB':image = image.convert('RGB')image = transforms.Resize(target_size)(image)image = transforms.ToTensor()(image)image = transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])(image)image = image[None]if use_gpu:image = image.cuda()return torch.tensor(image)
1.4 构建装饰器
@app.route是一个装饰器,用于将特定的URL路径绑定到一个视图函数上。当Web服务器接收到与该URL路径匹配且方法也匹配的HTTP请求时,就会调用相应的视图函数来处理该请求。
@app.route("/predict",methods = ["POST"])
def predict():# 做一个标志,刚开始无图像传入时为false,传入图像时为truedata = {"success":False}if flask.request.method == 'POST':if flask.request.files.get("image"):image = flask.request.files["image"].read()image = Image.open(io.BytesIO(image))image = prepare_image(image,target_size=(224,224))preds = F.softmax(model(image),dim=1)results = torch.topk(preds.cpu().data,k=3,dim=1)results = (results[0].cpu().numpy(),results[1].cpu().numpy())data['predictions'] = list()for prob,label in zip(results[0][0],results[1][0]):r = {"label":str(label),"probability":float(prob)}data['predictions'].append(r)data["success"] = Truereturn flask.jsonify(data)
1.5 完整代码
import io
import flask
import torch
import jsonify
import torch.nn.functional as F
from PIL import Image
from torch import nn
from torchvision import transforms,models,datasets"""-----初始化Flask app-----"""
app = flask.Flask(__name__) # 创建一个Flask应用程序实例model = None
use_gpu = False"""-----加载模型进来-----"""
def load_model():global model# 加载resnet18网络model = models.resnet18()num_ftrs = model.fc.in_featuresmodel.fc = nn.Sequential(nn.Linear(num_ftrs,102))checkpoint = torch.load('best.pth')model.load_state_dict(checkpoint['state_dict'])model.eval()# 是否使用gpuif use_gpu:model.cuda()"""-----数据预处理-----"""
def prepare_image(image,target_size):if image.mode !='RGB':image = image.convert('RGB')image = transforms.Resize(target_size)(image)image = transforms.ToTensor()(image)image = transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])(image)image = image[None]if use_gpu:image = image.cuda()return torch.tensor(image)# @app.route是一个装饰器,用于将特定的URL路径绑定到一个视图函数上。
# 当Web服务器接收到与该URL路径匹配且方法也匹配的HTTP请求时,就会调用相应的视图函数来处理该请求。
@app.route("/predict",methods = ["POST"])
def predict():# 做一个标志,刚开始无图像传入时为false,传入图像时为truedata = {"success":False}if flask.request.method == 'POST':if flask.request.files.get("image"):image = flask.request.files["image"].read()image = Image.open(io.BytesIO(image))image = prepare_image(image,target_size=(224,224))preds = F.softmax(model(image),dim=1)results = torch.topk(preds.cpu().data,k=3,dim=1)results = (results[0].cpu().numpy(),results[1].cpu().numpy())data['predictions'] = list()for prob,label in zip(results[0][0],results[1][0]):r = {"label":str(label),"probability":float(prob)}data['predictions'].append(r)data["success"] = Truereturn flask.jsonify(data)if __name__ == '__main__':print("Loading PyTorch model and Flask starting server...")print("Please wait until server has fully started")load_model() #加载模型# 再开启服务app.run(port='5012') # 端口
2. 搭建客户端
2.1 服务端网址
用于连接服务端:
-- 127.0.0.1:表示本地地址
-- 5012:表示端口
flask_url = 'http://127.0.0.1:5012/predict'
2.2 发送请求
def predict_result(image_path):image = open(image_path,'rb').read()payload = {'image':image}r = requests.post(flask_url,files=payload).json()# 向服务端发送一个POST请求,并尝试将返回的JSON响应解析为一个Python字典if r['success']:for (i,result) in enumerate(r['predictions']):print('{}.预测类别为{}:的概率{}'.format(i+1,result['label'],result['probability']))else:print('Reqquest failed')
2.3 完整代码
import requests
flask_url = 'http://127.0.0.1:5012/predict'def predict_result(image_path):image = open(image_path,'rb').read()payload = {'image':image}r = requests.post(flask_url,files=payload).json()# 向服务端发送一个POST请求,并尝试将返回的JSON响应解析为一个Python字典if r['success']:for (i,result) in enumerate(r['predictions']):print('{}.预测类别为{}:的概率{}'.format(i+1,result['label'],result['probability']))else:print('Reqquest failed')if __name__ == '__main__':predict_result('./train/6/image_07162.jpg')
六、运行使用
先行运行服务端,使得服务端打开,然后再运行客户端就可以连接上服务端,并使用服务端函数进行操作。
总结
本篇介绍了,如何进行模型部署,将客户端与服务端连接在一起,使客户可以借用服务端来操作。
相关文章:

【深度学习】(12)--模型部署 <连接客户端与服务端>
文章目录 模型部署一、模型部署的定义与目的二、模型部署的步骤三、模型部署的方式四、Flask框架五、实现模型部署1. 搭建服务端1.1 初始化Flask app1.2 加载模型1.3 数据预处理1.4 构建装饰器1.5 完整代码 2. 搭建客户端2.1 服务端网址2.2 发送请求2.3 完整代码 六、运行使用 …...

优化SQL查询的最佳实践:提升数据库性能的关键
SQL 查询是数据库操作的核心,特别是当数据量庞大时,性能问题尤为明显。优化 SQL 查询不仅能减少响应时间,还能提高系统整体的可伸缩性。本文将从索引、查询结构、数据库设计和缓存等方面详细介绍如何优化 SQL 查询以提升性能。 一、索引的使…...

【AIGC视频生成】视频扩散模型(综述+最新进展)
文章目录 一、综述1.1 扩散模型1.1.1 Denoising Diffusion Probabilistic Models (DDPMs)1.1.2 Score-Based Generative Models (SGMs)1.1.3 Stochastic Differential Equations (Score SDEs) 1.2 相关任务1.3 数据集1.4 评价指标 二、年度进展1.runway gen2.1 Gen-1࿱…...

如何下载3GPP协议?
一、进入3GPP网页 https://www.3gpp.org/ 二、点击“Specifications &Technologies” 三、点击“FTP Server” 网址: https://www.3gpp.org/specifications-technologies 四、找到“latest”,查看最新版 网址: https://www.3gpp.org/ftp…...

目标检测系统操作说明【用户使用指南】(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)
1.100多种【基于YOLOv8/v10/v11的目标检测系统】目录(pythonpyside6界面系统源码可训练的数据集也完成的训练模型) 2.目标检测系统【环境搭建过程】(GPU版本) 3.目标检测系统【环境详细配置过程】(CPU版本࿰…...

Vue中使用路由
目录 单页应用程序:SPA - Single Page Application路由 VueRouterVueRouter使用步骤组件存放目录问题 路由模块封装声明式导航 - 导航连接两个类名自定义匹配类名 声明式导航 - 跳转传参Vue路由 - 重定向Vue路由 - 404Vue路由 - 模式设置 编程式导航 - 基本跳转编程…...

【Linux】多线程安全之道:互斥、加锁技术与底层原理
目录 1.线程的互斥 1.1.进程线程间的互斥相关背景概念 1.2.互斥量mutex的基本概念 所以多线程之间为什么要有互斥? 为什么抢票会抢到负数,无法获得正确结果? 为什么--操作不是原子性的呢? 解决方式: 2.三种加锁…...

收藏多年的四款音频剪辑工具你pick哪一个?
在这个时代,音频剪辑已经成为音乐制作、播客、自媒体等领域的必备技能。而随着网络技术的飞速发展,我们不再需要安装庞大的软件,只需一个浏览器,就能轻松完成音频剪辑工作。今天,就让我为大家推荐几款优秀的在线音频剪…...

使用Redis进行在线人数统计时,有哪些性能优化技巧?
使用Redis进行在线人数统计时,性能优化是关键,以下是一些性能优化技巧: 选择合适的数据结构: 对于在线人数统计,可以选择使用Set数据结构,因为它具有自动去重和高效的集合操作特性,非常适合用于…...

前端模块循环依赖问题
模块循环依赖问题 在项目比较小的时候可能不怎么会遇到这个问题,但项目一旦有一定的体量后就可能会遇到了。 我之前做项目时就遇到这个问题,也是总结一篇文章。 比如这种类型的报错 commonjs存在的问题 先讲一下commonjs存在的问题。 CommonJS模块采…...

Springboot指定扫描路径
方式一:通过在启动类的SpringbootApplication中指定包扫描或类扫描 指定需要扫描的包 scanBasePackages{"待扫描包1","待扫描包2", . . . ," "} 指定需要扫描的类 scanBasePackageClasses{类1.class,类2.class,...} 方式二ÿ…...

【Flutter】Dart:环境搭建
Flutter 是一个基于 Dart 的跨平台开发框架,可以帮助我们快速构建移动应用程序。在开始 Flutter 开发之前,我们需要先搭建 Dart 的开发环境,并配置合适的编辑器,比如 VSCode。本教程将引导你一步步完成 Dart 和 Flutter 的环境搭建…...

OpenCV高级图形用户界面(10)创建一个新的窗口函数namedWindow()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 创建一个窗口。 函数 namedWindow 创建一个可以作为图像和跟踪条占位符的窗口。创建的窗口通过它们的名字来引用。 如果已经存在同名的窗口&am…...

水题四道。
我的 水题四道--题目目录 问题 A: 依次输出第k小整数 代码1 问题 B: 第k小整数(knumber) 代码2 树的统计 代码3 枪声问题 代码4 问题 A: 依次输出第k小整数 现有n个正整数,n≤10000,要求出这n个正整数中的第1小的整数,第2小的整数…...

upload-labs靶场Pass-05
upload-labs靶场Pass-05 大小写绕过 $deny_ext array(“.php”,“.php5”,“.php4”,“.php3”,“.php2”,“.html”,“.htm”,“.phtml”,“.pht”,“.pHp”,“.pHp5”,“.pHp4”,“.pHp3”,“.pHp2”,“.Html”,“.Htm”,“.pHtml”,“.jsp”,“.jspa”,“.jspx”,“.jsw”…...

【AIGC】解锁高效GPTs:ChatGPT-Builder中系统提示词Prompt的设计与应用
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯系统提示词系统提示词的作用与重要性系统提示词在构建GPTs中的作用结论 💯ChatGPT-Builder系统提示词的详细解读OpenAI为Builder编写的系统提示词系统提示词对…...

【JavaEE初阶】深入理解网络编程—使用UDP协议API实现回显服务器
前言 🌟🌟本期讲解关于TCP/UDP协议的原理理解~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废话不…...

C语言复习第3章 函数
目录 一、函数介绍1.1 函数是什么1.2 C语言中函数的分类1.3 函数原型1.4 高内聚 低耦合1.5 C语言main函数的位置 二、函数的参数2.1 实参和形参2.2 函数的参数(实参)可以是表达式2.3 传值与传址(swap函数)2.4 明确形参是实参的临时拷贝2.5 void(如果不写函数返回值 默认是int)2…...

Golang | Leetcode Golang题解之第491题非递减子序列
题目: 题解: var (temp []intans [][]int )func findSubsequences(nums []int) [][]int {ans [][]int{}dfs(0, math.MinInt32, nums)return ans }func dfs(cur, last int, nums []int) {if cur len(nums) {if len(temp) > 2 {t : make([]int, len(…...

conan安装方法简介
因为conan是使用python开发的,所以使用conan需要先安装python环境,这里就不展开python的安装方法了。 conan安装有多种方法,但是比较推荐也是比较简单的一种方法是使用python的pip包管理器安装,相关方法如下(Windows和…...

Java面试指南:Java基础介绍
这是《Java面试指南》系列的第1篇,本篇主要是介绍Java的一些基础内容: 1、Java语言的起源 2、Java EE、Java SE、Java ME介绍 3、Java语言的特点 4、Java和C的区别和联系? 5、面向对象和面向过程的比较 6、Java面向对象的三大特性:…...

【mod分享】波斯王子遗忘之沙高清重置,纹理,字体,贴图全部重置,特效增强,支持光追
各位好,今天小编给大家带来一款新的高清重置MOD,本次高清重置的游戏叫《波斯王子:遗忘之沙》。 《波斯王子:遗忘之沙》是由育碧(Ubisoft)开发并发行的一款动作类游戏,于2010年5月18日发行。游戏…...

【计网笔记】物理层
设备 中继器:延长信号传播长度集线器:RJ45接口,无碰撞检测 接口特性 不属于物理层接口规范定义范畴的是(C) A. 接口形状 B. 引脚功能 C. 物理地址 D. 信号电平 传输媒体 导引型媒体 双绞线 减少对相邻导线的电磁…...

《计算机视觉》—— 基于 dlib 库的方法将两张人脸图片进行换脸
声明:此篇文章所用的明星照片只为用于演示代码的效果,无诋毁她人肖像之意 一、案例实现的思想 此案例的核心是基于人脸68个关键点检测模型来实现的,人脸68个关键带点检测后的效果如下: 通过对上图中红色区域的转换,…...

查找与排序-交换排序
交换排序是基于“比较”和“交换”两种操作来实现的排序方法 。 由于选择“比较”的基准元素不同,可将交换排序分为以下两种: 冒泡排序快速排序 一、冒泡排序 1.冒泡排序基本思想 因为其实现与气泡从水中往上冒的过程类似而得名。 每一趟的…...

数据结构与算法:高级数据结构与实际应用
目录 14.1 跳表 14.2 Trie树 14.3 B树与 B树 14.4 其他高级数据结构 总结 数据结构与算法:高级数据结构与实际应用 本章将探讨一些高级数据结构,这些数据结构在提高数据存取效率和解决复杂问题上起到重要作用。这些高级数据结构包括跳表࿰…...

【win11】终端/命令提示符/powershell美化
文章目录 1.设置字体1.1. 打开win11的终端/命令提示符/powershell其中之一1.2. 打开终端设置,修改所有终端默认字体为新宋体 2. 修改powershell背景色为蓝色 win11的默认终端/命令提示符/powershell主题风格让人感觉与win10撕裂太大,尤其是字体、背景色&…...

三元损失(Triplet Loss)详解
文章目录 前言一、三元损失的核心思想二、数学公式三、损失函数的解释四、三元损失的优势五、应用场景前言 三元损失(Triplet Loss)是一种广泛应用于度量学习(Metric Learning)中的损失函数,尤其在人脸识别、图像检索等任务中表现优异。三元损失的基本思想是通过定义一个…...

1. 解读DLT698.45-2017通信规约--预连接响应
国家电网有限公司企业标准,面向对象的用电信息数据交换协议DLT698.45-2017 为提高用电信息采集系统的业务适应性、采集效率、安全性和数据溯源性,规范用电信息数据交换协议的通信架构、数据链路层、应用层、接口类与对象标识,制定本标准。 …...

基于小波图像去噪的MATLAB实现
论文背景 数字图像处理(Digital Image Processing,DIP)是指用计算机辅助技术对图像信号进行处理的过程。数字图像处理最早出现于 20世纪50年代,随着过去几十年来计算机、网络技术和通信的快速发展,为信号处理这个学科领域的发展奠定了基础&a…...