当前位置: 首页 > news >正文

第12章 PyTorch图像分割代码框架-3:推理与部署

推理模块

模型训练完成后,需要单独再写一个推理模块来供用户测试或者使用,该模块可以命名为test.py或者inference.py,导入训练好的模型文件和待测试的图像,输出该图像的分割结果。inference.py主体部分如代码11-7所示。

代码11-7 推理模块部分

# 导入相关库
import numpy as np
import torch
from PIL import Image
# 定义推理函数
def inference(model, test_img):img = Image.open(test_img)img = val_transform(img)img = img.unsqueeze(0).to('cuda')with torch.no_grad():outputs = model(img)preds = outputs.detach().max(dim=1)[1].cpu().numpy()print(preds.shape)pred = VOCSegmentation.decode_target(preds[0]).astype(np.uint8)Image.fromarray(pred).save(os.path.join('s%_pred.png' % test_img.split('.')[0]))

上述代码仅展示推理模块的主体部分,完整代码可参考本书配套的对应章节代码文件。实际执行时,我们可以在命令行通过传入待测试图像和模型文件执行inference.py。测试示例如下:

python inference.py --data_root 2007_000676.jpg --model deeplabv3plus_resnet101

测试图像和模型预测结果示例如图11-5所示。

751045d7e7b33675fd62088b1c733640.png

部署模块

虽然我们可以通过推理模块来测试模型效果,但推理毕竟不是面向用户级的使用体验。为了能够在常见的用户端使用我们的分割模型,还需要对模型进行工程化的部署(deployment)。根据分割模型的应用场景,一般最常见的部署场景是web端部署或者是基于C++的软件集成部署。web端部署一般基于Flask等后端部署框架来完成,形式上可以分为为REST APIweb应用两种表现形式。

一个web服务简单而言就是用户从客户端发送一个HTTP请求,然后服务器收到请求后生成HTML文档作为响应返回给客户端的过程。当返回的内容需要在前端页面上呈现时,这个服务就是一个web端的应用;当返回内容不需要在前端页面体现,而是直接以JSON等数据结构给用户时,这个服务就是一个REST API

Flask是一个基于Python的轻量级web应用框架,非常简洁和灵活,也便于初学者快速上手。简单几行代码即可快速定义一个web服务,如代码11-8所示。

# 导入flask相关模块
from flask import Flask, jsonify
# 创建应用
app = Flask(__name__)
# 定义预测路由
@app.route('/predict', methods=['POST'])
def predict():return jsonify({'class_id': 'IMAGE_NET_XXX', 'class_name': 'Cat'})

本节我们将分别展示基于PASCAL VOC 2012训练的Deeplab v3+模型的REST APIweb应用部署方式。

REST API部署

基于REST API部署相对较为简单,我们可以直接编写一个api.py的文件,将推理流程融入到Flask的预测路由函数中即可。在此之前需要先导入训练好的模型以及定义跟验证时同样的数据转换方法。基于上述策略可定义api.py如下:

代码11-9 REST API部署

# 导入相关库
import torch
from torchvision import transforms
from PIL import Image
import io
import numpy as np
from utils import ext_transforms_new as et
from datasets import VOCSegmentation
from flask import Flask, request, jsonify
import models# 创建应用
app = Flask(__name__)# 模型字典
model_map = {'deeplabv3plus_resnet50': models.deeplabv3plus_resnet50,'deeplabv3plus_resnet101': models.deeplabv3plus_resnet101,
}# 创建模型
model = model_map['deeplabv3plus_resnet101'](num_classes=21,
output_stride=16)# 导入模型
model.load_state_dict(torch.load('../checkpoints/deeplabv3plus_resnet101_voc.pth')['model_state'])
model.to('cuda')
model.eval()
print('model loaded.')# 定义数据转换方法
transform = et.Compose([transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]),
])# 定义模型预测路由
@app.route('/predict', methods=['POST'])
def predict():if request.method == 'POST':# 从请求中读取输入图像image = request.files['image'].read()image = Image.open(io.BytesIO(image))# 图像变换input_tensor = transform(image).unsqueeze(0).to('cuda')# 模型预测with torch.no_grad():output = model(input_tensor)preds = output.detach().max(dim=1)[1].cpu().numpy()print(preds.shape)# 对输出进行解码,转换为maskpreds = VOCSegmentation.decode_target(preds[0]).astype(np.uint8)# 转换成listresult = preds.tolist()return jsonify(result)if __name__ == '__main__':app.run(debug=True)

定义好app.py以后,直接在命令行启动该REST API服务:

python app.py

然后再单独启动一个Python终端,通过requests库发起post请求,传入一张待分割图像:

resp = requests.post("http://localhost:5000/predict", files={"image": open('./deployment/2007_000676.jpg', 'rb')})

这时候我们可以在服务端看到相关响应信息,如图11-6所示。状态码显示为200,说明请求成功,返回数据可以在requests返回对象中查看。

19997a22dadce27ae01c1529d19ee043.png

web端部署

REST API的部署方式更多的是方便开发者使用,对于普通用户可能不是那么友好。为了更加方便用户使用和更直观的展示模型效果,我们可以通过web端部署的方式,让用户上传图像作为输入,并将输入图像和分割结果直接在网页上显示。所以与API部署方式不同的是需要加上一个index.html的网页模板文件,将输入和分割结果在网页模板上进行渲染。同时原先的api.py文件也需要进行修改,修改后的文件可命名为app.py,主体部分如代码11-10所示。

代码11-10 web端应用app.py

# 创建应用
app = Flask(__name__)
# 定义上传和预测路由
@app.route('/', methods=['GET', 'POST'])
def upload_predict():# POST请求后读取图像if request.method == 'POST':image_file = request.files['image']if image_file:image_location = os.path.join(app.config['UPLOAD_FOLDER'],image_file.filename)image_file.save(image_location)# 图像变换image = Image.open(image_location).convert('RGB')input_tensor = transform(image).unsqueeze(0).to('cuda')# 模型预测with torch.no_grad():output = model(input_tensor)preds = output.detach().max(dim=1)[1].cpu().numpy()print(preds.shape)# mask解码preds = VOCSegmentation.decode_target(preds[0]).astype(np.uint8)# 保存图像到指定路径segmented_image = Image.fromarray(preds)segmented_image_path = image_location.replace('.jpg', '_segmented.jpg')segmented_image.save(segmented_image_path)display_input_path = '../' + image_locationdisplay_segmented_path = '../' + segmented_image_path# 渲染结果到网页return render_template('index.html', input_image=display_input_path, segmented_image=display_segmented_path)return render_template('index.html')

代码11-10api.py的主要区别在于读取图像部分是需要读取用户上传到指定目录下的图像,并且对输入图像和分割结果渲染呈现到网页端。index.html是网页HTML的模板文件,我们可以通过编辑该文件来实现自己想要的网页效果。

执行app.py文件启动web服务,然后打开服务运行地址:http:127.0.0.1:5000即可看到网页端效果,在网页点击“选择文件”上传输入图像,然后点击“Segment”执行模型分割,图11-7web部署后的使用效果图。

6125c0e3954cd6378861a5d0b4ed8636.png

总结

本章以PASCAL VOC 2012数据集和Deeplab v3+分割模型为例,给出了基于PyTorch的深度学习图像分割项目代码框架。一个相对完整的图像分割代码框架应包含:预处理模块、数据导入模块、模型模块、工具函数模块、配置模块、主函数模块、推理模块和部署模块。启中预处理、数据导入、模型、工具函数、配置和主函数模块均为模型训练阶段的工作模块,而推理和部署则属于模型训练完后的测试和使用阶段工作模块。

需要特别说明的是,本章的代码框架仅作为深度学习图像分割项目的一般性框架,具体使用时应根据项目的实际情况酌情参考。

后续全书内容和代码将在github上开源,请关注仓库:

https://github.com/luwill/Deep-Learning-Image-Segmentation

(本章完结,其余章节待续)

相关文章:

第12章 PyTorch图像分割代码框架-3:推理与部署

推理模块 模型训练完成后,需要单独再写一个推理模块来供用户测试或者使用,该模块可以命名为test.py或者inference.py,导入训练好的模型文件和待测试的图像,输出该图像的分割结果。inference.py主体部分如代码11-7所示。 代码11-7 …...

MYSQL---基础篇

一、数据库操作 1.创建数据库:CREATE DATABASE db_test1; 2.使用数据库:use 数据库名; 3.删除数据库:DROP DATABASE [IF EXISTS] db_name; 4.创建表:CREATE TABLE table_name ( field1 datatype, field2…...

【启扬方案】启扬安卓屏一体机在医疗自助服务终端上的应用解决方案

为了解决传统医疗模式下的“看病难、看病慢”等问题,提高医疗品质、效率与效益,自助服务业务的推广成为智慧医疗领域实现信息化建设、高效运作的重要环节。 医疗自助服务终端是智慧医疗应用场景中最常见的智能设备之一,它通过与医院信息化系统…...

收藏!7个国内「小众」的程序员社区

技术社区是大量开发者的集聚地,在技术社区可以了解到行业的最新进展,学习最前沿的技术,认识有相同爱好的朋友,在一起学习和交流。 国内知名的技术社区有CSDN、博客园、开源中国、51CTO,还有近两年火热的掘金&#xff…...

LeetCode(4)删除有序数组中的重复项 II【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接: 80. 删除有序数组中的重复项 II 1.题目 给你一个有序数组 nums ,请你** 原地** 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数…...

C++ 同构字符串/ 单词规律

给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相…...

oracle 中 %TYPE %ROWTYPE

前言 PL/SQL 提供了 %TYPE 和 %ROWTYPE 两种特殊的变量,用于声明与表的列相匹配的变量和用户定义数据类型,前一个表示单属性的数据类型,后一个表示整个属性列表的结构,即元组的类型。 举例: -- 数据表TB_TRANS_RECO…...

Pytorch实战教程(五)-计算机视觉基础

0. 前言 计算机视觉是指通过计算机系统对图像和视频进行处理和分析,利用计算机算法和方法,使计算机能够模拟和理解人类的视觉系统。通过计算机视觉技术,计算机可以从图像和视频中提取有用的信息,实现对环境的感知和理解,从而帮助人们解决各种问题和提高效率。本节中,将介…...

51单片机PCF8591数字电压表数码管显示设计( proteus仿真+程序+设计报告+讲解视频)

PCF8591数字电压表数码管显示 1.主要功能:讲解视频:2.仿真3. 程序代码4. 设计报告5. 设计资料内容清单&&下载链接资料下载链接(可点击): 51单片机PCF8591数字电压表数码管设计( proteus仿真程序设计报告讲解视…...

普华永道于进博会首发“企业数据资源会计处理一体化平台”

11月6日,在第六届中国国际进口博览会上,普华永道发布企业数据资源会计处理一体化平台(英文名为Data Accounting Platform,简称DAP)。该产品以普华永道“五步法”数据资源入表路径为理论依据,依托多年来普华…...

IDEA 使用Reset Current Branch to Here 进行git 版本控制,图文操作

文章目录 一、总结区别(只针对本地仓库操作)Soft详细解释文件版本冲突处理 Mixed详细解释Hard详细解释Keep详细解释文件版本冲突处理 二、其他Revert commit 参考文档 一、总结区别(只针对本地仓库操作) Soft详细解释 Soft操作只…...

有趣的 TCP 抢带宽行为

昨天发了一篇 非技术文章,很多人找我讨论,浓缩成一句话,就是 “死道友而不死贫道”,我的简历上写着这些把戏能带来什么,我的 blog 上写着这么做是多么无耻,哈哈。 看看共享链路上如何挤占带宽: …...

HCIP---VRRP

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一. VRRP概述 VRRP---虚拟路由器冗余协议 VRRP(Virtual Router Redundancy Protocol)是一种用于在多个路由器之间创建虚拟路由器的协议。 VRRP使用了一系列协议来实现路…...

在家用Python搞副业,也能月入10000+

下班副业实现经济自由的时候,你还在床上躺着,天天摆烂吗?这样的生活真的是你想要的吗? 疫情在家接一些Python相关的小单子,既能给自己练手,还能赚是真香 从零基础开始真的一台电脑和一部手机就可以✅ 一次…...

play() failed because the user didn‘t interact with the document first.

起因: 进入页面视频不自动播放(有时候可以,有时候不行)。 原因: Chrome 在66版本后为了避免标签产生随机噪音,都在遵循autoplay政策。 解决方法: 为 video 标签设置静音状态即可(添…...

Java任意视频转MP4

Java任意视频转MP4 在做视频上传功能时候,用户可能上传不同类型的视频文件,导致需要特定播放器才能播放,为了解决视频格式统一问题需要把视频转码一下 ,转换成统一的MP4格式。我们直接使用第三方工具 FFmpeg FFmpeg介绍 FFmpeg…...

flutter实践:慎用Expanded

问题:在一个Android原生的弹框里显示flutter view,由于使用了Expanded导致组件未显示出来 最神奇的地方在于debug调试模式显示正常,然后用release版本发布时怎么都显示不出来,还导致点击后无响应ANR 问题代码: child: Stateful…...

华为防火墙vrrp+hrp双机热备负载分担(两端为交换机)

主要配置: FW1 hrp enable hrp interface GigabitEthernet1/0/2 remote 172.16.0.2 interface GigabitEthernet1/0/0 这里可以假想为接两条外线,一条外线对应一个vrrid undo shutdown ip address 1.1.1.2 255.255.255.0 vrrp vrid 3 virtual-ip 1.1.1…...

欧拉角(横滚角、俯仰角、偏航角)、旋转矩阵、四元数的转换与解决万向节死锁

1、概述 物体的位姿(位置和方向)的描述方法一般使用两个坐标系来表示,一个是世界坐标系或地面坐标系,这里我都叫做地面坐标系吧,属于参考坐标系;另一个是自身的坐标系,以飞机为例来讲述一些常见…...

Java Post请求参数格式为XML

方式一: public static void PostXml1(String url, String xml) throws IOException {OkHttpClient client new OkHttpClient().newBuilder().build();//okhttp3.MediaType mediaType okhttp3.MediaType.parse("application/xml");okhttp3.MediaType m…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

ES6从入门到精通:前言

ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...