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

news2025/1/1 8:00:32

推理模块

模型训练完成后,需要单独再写一个推理模块来供用户测试或者使用,该模块可以命名为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)
            # 对输出进行解码,转换为mask
            preds = VOCSegmentation.decode_target(preds[0]).astype(np.uint8)


        # 转换成list
        result = 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_location
            display_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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1194752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MATLAB源码-第74期】基于matlab的OFDM-IM索引调制系统不同频偏误码率对比,对比OFDM系统。

操作环境: MATLAB 2022a 1、算法描述 OFDM-IM索引调制技术是一种新型的无线通信技术,它将正交频分复用(OFDM)和索引调制(IM)相结合,以提高频谱效率和系统容量。OFDM-IM索引调制技术的基本思想…

Spring -Spring之依赖注入源码解析(下)--实践(流程图)

IOC依赖注入流程图 注入的顺序及优先级:type-->Qualifier-->Primary-->PriOriry-->name

如何使用HadSky搭配内网穿透工具打造个人站点并公网访问

🌈个人主页:聆风吟 🔥系列专栏:Cpolar杂谈、数据结构、算法模板 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 前言一. 网站搭建1.1 网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 二. 本地网页发…

[工业自动化-10]:西门子S7-15xxx编程 - PLC主站 - 信号量:数字量

目录 前言: 一、工业现场常见信号的分类 二、IO数字量模块 2.1 概述 2.2 PLC的数字量是24V还是5V电压? 2.2 数字量模块的安装与接线 2.3 数字量模的注意事项 前言: 一、工业现场常见信号的分类 在工业自动化领域,常常需要使…

3DMAX汽车绑定动画模拟插件MadCar疯狂汽车使用教程

3DMAX汽车绑定动画模拟插件MadCar疯狂的汽车,用于通过模拟控制来快速装配轮式车辆及其动画。这个新版本允许装配任何数量的车轮的车辆,以及包括摩托车在内的任何相互布置。还支持任意数量的拖车。 每个车轮和悬架都有简化的行为设置以及微调&#xff0c…

xss 通过秘籍

终极测试代码 <sCr<ScRiPt>IPT>OonN"\/(hrHRefEF)</sCr</ScRiPt>IPT> 第一关&#xff08;没有任何过滤&#xff09; 使用终极测试代码&#xff0c;查看源码 发现没有任何过滤&#xff0c;直接使用javascrupt中的alert弹框 <script>aler…

企业级操作之STM32项目版本管理方法

在MCU开发过程中&#xff0c;有时候需要软件的迭代&#xff0c;比如从V1.9升级到V1.10&#xff0c;或者从V23.09.23升级到V23.09.24&#xff0c;我们常常通过手动改动字符串或者数组来实现这个功能&#xff0c;从现在开始&#xff0c;我们会使用Keil的内置宏__DATE__和__TIME__…

局域网内部服务器访问外部网络

​ 一、环境说明 如下图所示&#xff0c;局域网1中的服务器是可以访问外网的&#xff0c;局域网2中的服务器发出的数据包经过中间路由可以到达局域网1中的服务器。现在有一种需求需要使局域网2中的服务器也要能访问外网&#xff0c;这里考虑采用如下方法来实现。 ​​ 二、软…

基于element-plus定义表单配置化

文章目录 前言一、配置化的前提二、配置的相关组件1、新建form.vue组件2、新建input.vue组件3、新建select.vue组件4、新建v-html.vue组件5、新建upload.vue组件6、新建switch.vue组件7、新建radio.vue组件8、新建checkbox.vue组件9、新建date.vue组件10、新建time-picker.vue组…

Pytorch实战教程(一)-神经网络与模型训练

0. 前言 人工神经网络 (Artificial Neural Network, ANN) 是一种监督学习算法,其灵感来自人类大脑的运作方式。类似于人脑中神经元连接和激活的方式,神经网络接受输入,通过某些函数在网络中进行传递,导致某些后续神经元被激活,从而产生输出。函数越复杂,网络对于输入的数…

传统企业数字化转型都要面临哪些挑战?_数据治理平台_光点科技

数字化转型已经成为传统企业发展的必经之路&#xff0c;但在这个过程中&#xff0c;企业往往会遭遇多方面的挑战。 1.文化和组织惯性 最大的挑战之一是企业文化和组织惯性的阻力。传统企业往往有着深厚的历史和根深蒂固的工作方式&#xff0c;员工和管理层可能对新的数字化工作…

FFMPEG库实现mp4/flv文件(H264+AAC)的封装与分离

ffmepeg 4.4&#xff08;亲测可用&#xff09; 一、使用FFMPEG库封装264视频和acc音频数据到 mp4/flv 文件中 封装流程 1.使用avformat_open_input分别打开视频和音频文件&#xff0c;初始化其AVFormatContext&#xff0c;使用avformat_find_stream_info获取编码器基本信息 2.使…

一文入门Springboot+actuator+Prometheus+Grafana

环境介绍 技术栈 springbootmybatis-plusmysqloracleactuatorPrometheusGrafana 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 本地主机应用 192.168.1.9:8007 PrometheusGrafana安装在同一台主机 http://…

CSS特效005:绘制一个环环相扣的五个环

css实战中&#xff0c;怎么制作这样的一个环环相扣的五个环呢&#xff1f; 绘制五个圈圈很容易&#xff0c;关键是要环环相扣&#xff0c;尤其要注意环环相交部分的处理。这里要用到transform-style: preserve-3d; 和 transform: rotateY( 1deg ) 等关键的css技术。 效果图 源…

无需公网IP!部署Apache服务器与内网穿透实现公网访问

Apache服务安装配置与结合内网穿透实现公网访问 文章目录 Apache服务安装配置与结合内网穿透实现公网访问前言1.Apache服务安装配置1.1 进入官网下载安装包1.2 Apache服务配置 2.安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpo…

密码学 - RSA签名算法

实验九 RSA签名算法- 一、实验目的 通过实验掌握GMP开源软件的用法&#xff0c;理解RSA数字签名算法&#xff0c;学会RSA数字签名算法程序设计&#xff0c;提高一般数字签名算法的设计能力。 二、实验要求 (1)基于GMP开源软件&#xff0c;实现RSA签名算法。 (2)要求有对应…

GEE:基于 Landsat 计算的 kNDVI 应用 APP

作者:CSDN @ _养乐多_ 本文记录了在Google Earth Engine(GEE)平台中,使用 Landsat 遥感数据计算 kNDVI 的应用 APP 链接,并介绍该 APP 的使用方法和步骤。该APP可以为用户展示 NDVI 和 kNDVI 的遥感影像,进行对比分析。该 APP 在 Google Earth Engine(GEE)平台中实现。…

在 Arduino IDE 2.0 中安装 ESP32 板(Windows、Mac OS X、Linux)

有一个新的 Arduino IDE——Arduino IDE 2.0&#xff08;测试版&#xff09;。在本教程中&#xff0c;您将学习如何在 Arduino IDE 2.0 中安装 ESP32 板并将代码上传到板。本教程与 Windows、Mac OS X 和 Linux 操作系统兼容。 据 Arduino 网站称&#xff1a;“ Arduino IDE 2.…

【微服务专题】手写模拟SpringBoot

目录 前言阅读对象阅读导航前置知识笔记正文一、工程项目准备1.1 新建项目1.1 pom.xml1.2 业务模拟 二、模拟SpringBoot启动&#xff1a;好戏开场2.1 启动配置类2.1.1 shen-base-springboot新增2.1.2 shen-example客户端新增启动类 三、run方法的实现3.1 步骤一&#xff1a;启动…

Javaweb之javascript的BOM对象的详细解析

1.5.2 BOM对象 接下来我们学习BOM对象&#xff0c;BOM的全称是Browser Object Model,翻译过来是浏览器对象模型。也就是JavaScript将浏览器的各个组成部分封装成了对象。我们要操作浏览器的部分功能&#xff0c;可以通过操作BOM对象的相关属性或者函数来完成。例如&#xff1a…