使用 Flask 快速部署 PyTorch 模型

news2024/11/19 1:45:09

对于数据科学项目来说,我们一直都很关注模型的训练和表现,但是在实际工作中如何启动和运行我们的模型是模型上线的最后一步也是最重要的工作。

今天我将通过一个简单的案例:部署一个PyTorch图像分类模型,介绍这个最重要的步骤。

在这里插入图片描述

我们这里使用PyTorch和Flask。可以使用pip install torch和pip install flask安装这些包。

web应用

为Flask创建一个文件app.py和一个路由:

from flask import Flask
import torch


app = Flask(__name__)

@app.route('/')
def home():
    return 'Welcome to the PyTorch Flask app!'

现在我们可以运行python app.py,如果没有问题,你可以访问http://localhost:5000/,应该会看到一条简单的消息——“Welcome to the PyTorch Flask app!”

这就说明我们flask的web服务已经可以工作了,现在让我们添加一些代码,将数据传递给我们的模型!

源码分享&技术交流

技术要学会分享、交流,不建议闭门造车。 本文技术由粉丝群小伙伴分享汇总。源码、数据、技术交流提升,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、添加微信号:dkl88191,备注:来自CSDN +学管系统
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:学管系统

添加更多的导入

 from flask import Flask, request, render_template  
 from PIL import Image  
 import torch  
 import torchvision.transforms as transforms

然后再将主页的内容换成一个HTML页面

 @app.route('/')  
 def home():  
     return render\_template('home.html')

创建一个templates文件夹,然后创建home.html。

 <html>
  <head>
    <title>PyTorch Image Classification</title>
  </head>
  <body>
    <h1>PyTorch Image Classification</h1>
    <form method="POST" enctype="multipart/form-data" action="/predict">
      <input type="file" name="image">
      <input type="submit" value="Predict">
    </form>
  </body>
</html>

HTML非常简单——有一个上传按钮,可以上传我们想要运行模型的任何数据(在我们的例子中是图像)。

以上都是基本的web应用的内容,下面就是要将这个web应用和我们的pytorch模型的推理结合。

加载模型

在home route上面,加载我们的模型。

 model = torch.jit.load('path/to/model.pth')

我们都知道,模型的输入是张量,所以对于图片来说,我们需要将其转换为张量、还要进行例如调整大小或其他形式的预处理(这与训练时的处理一样)。

我们处理的是图像,所以预处理很简单

def process_image(image):
    # Preprocess image for model
    transformation = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    ])
    image_tensor = transformation(image).unsqueeze(0)
    
    return image_tensor

我们还需要一个数组来表示类,本文只有2类

class_names = ['apple', 'banana'] #REPLACE THIS WITH YOUR CLASSES

预测

下一步就是创建一个路由,接收上传的图像,处理并使用模型进行预测,并返回每个类的概率。

 @app.route('/predict', methods=['POST'])
def predict():
    # Get uploaded image file
    image = request.files['image']

    # Process image and make prediction
    image_tensor = process_image(Image.open(image))
    output = model(image_tensor)

    # Get class probabilities
    probabilities = torch.nn.functional.softmax(output, dim=1)
    probabilities = probabilities.detach().numpy()[0]

    # Get the index of the highest probability
    class_index = probabilities.argmax()

    # Get the predicted class and probability
    predicted_class = class_names[class_index]
    probability = probabilities[class_index]

    # Sort class probabilities in descending order
    class_probs = list(zip(class_names, probabilities))
    class_probs.sort(key=lambda x: x[1], reverse=True)

    # Render HTML page with prediction results
    return render_template('predict.html', class_probs=class_probs,
                           predicted_class=predicted_class, probability=probability)

我们的/predict路由首先使用softmax函数获得类概率,然后获得最高概率的索引。它使用这个索引在类名列表中查找预测的类,并获得该类的概率。然后按降序对类别概率进行排序,并返回预测结果。

最后,我们的app.py文件应该是这样的:

from flask import Flask, request, render_template
from PIL import Image
import torch
import torchvision.transforms as transforms


model = torch.jit.load('path/to/model.pth')

@app.route('/')
def home():
    return render_template('home.html')

def process_image(image):
    # Preprocess image for model
    transformation = transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    ])
    image_tensor = transformation(image).unsqueeze(0)
    
    return image_tensor


class_names = ['apple', 'banana'] #REPLACE THIS WITH YOUR CLASSES

@app.route('/predict', methods=['POST'])
def predict():
    # Get uploaded image file
    image = request.files['image']

    # Process image and make prediction
    image_tensor = process_image(Image.open(image))
    output = model(image_tensor)

    # Get class probabilities
    probabilities = torch.nn.functional.softmax(output, dim=1)
    probabilities = probabilities.detach().numpy()[0]

    # Get the index of the highest probability
    class_index = probabilities.argmax()

    # Get the predicted class and probability
    predicted_class = class_names[class_index]
    probability = probabilities[class_index]

    # Sort class probabilities in descending order
    class_probs = list(zip(class_names, probabilities))
    class_probs.sort(key=lambda x: x[1], reverse=True)

    # Render HTML page with prediction results
    return render_template('predict.html', class_probs=class_probs,
                           predicted_class=predicted_class, probability=probability)

最后一个部分是实现predict.html模板,在templates目录创建一个名为predict.html的文件:

 <html>
  <head>
    <title>Prediction Results</title>
  </head>
  <body>
    <h1>Prediction Results</h1>
    <p>Predicted Class: {{ predicted_class }}</p>
    <p>Probability: {{ probability }}</p>
    <h2>Other Classes</h2>
    <ul>
      {% for class_name, prob in class_probs %}
        <li>{{ class_name }}: {{ prob }}</li>
      {% endfor %}
    </ul>
  </body>
</html>

这个HTML页面显示了预测的类别和概率,以及按概率降序排列的其他类别列表。

测试

使用python app.py运行服务,然后首页会显示我们创建的上传图片的按钮,可以通过按钮上传图片进行测试,这里我们还可以通过编程方式发送POST请求来测试您的模型。

下面就是发送POST请求的Python代码

import requests

# Set URL for Flask app
url = 'http://localhost:5000/predict'

# Set image file path
image_path = 'path/to/image.jpg'

# Read image file and set as payload
image = open(image_path, 'rb')
payload = {'image': image}

# Send POST request with image and get response
response = requests.post(url, headers=headers, data=payload)

print(response.text)

这段代码将向Flask应用程序发送一个POST请求,上传指定的图像文件。我们创建的Flask应用程会处理图像,做出预测并返回响应,最后响应将打印到控制台。

就是这样只要5分钟,我们就可以成功地部署一个ML模型。

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

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

相关文章

用一串Python代码爬取网站数据

如觉得博主文章写的不错或对你有所帮助的话&#xff0c;还望大家多多支持呀&#xff01;关注、点赞、收藏、评论。 目录一.编码问题二、文件编码三、基本方法四、登录五、断线重连六、正则匹配Excel操作转换网页特殊字符一.编码问题 因为涉及到中文&#xff0c;所以必然地涉及…

MV*系列架构模型

下文仅代表个人理解&#xff0c;可能会有偏差或错误&#xff0c;欢迎评论或私信讨论。 MVC 从软件架构模型角度 MVC 是比较“古老”的架构模型&#xff0c;后面的 MV* 都是基于它进行拓展。MVC 出现的意义是为了提高程序的可维护性与拓展性。在 View 层与 Model 层中添加了 C…

如何分享让人眼前一亮的代码

作为一名软件工程师&#xff0c;会经常需要在工作和写作中粘贴代码片段以作示例&#xff0c;如果不关注代码的格式随手一粘&#xff0c;别人看到的画风就可能是这样&#xff1a;那么&#xff0c;该如何才能快速且优雅地分享代码片段呢&#xff1f;Raycast ray.so 或许是一个值…

2020-12-31 学习74HC595真值表与时序图

考资料教你74hc595时序图怎么看知识详解 - 电子常识 - 电子发烧友网 74HC595是串行输入并行/串行输出的移位锁存器。SHCP是移位脉冲&#xff0c;前沿&#xff08;上升沿&#xff09;有效&#xff0c;STCP是锁存脉冲&#xff0c;前沿有效&#xff0c;DS是输入信号&#xff0c;M…

动态规划算法刷题笔记【线性dp】

递推 斐波那契(Fibonacii)数列的递推公式&#xff1a;F(n) F(n -1) F(n - 2) 错排问题&#xff1a;F(n) (n-1) * [F(n-1)F(n-2)] 解释 例题 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法 思路 要想跳到第…

代码随想录算法训练营第4天 24.两两交换链表中的节点、19. 删除链表的倒数第N个节点、160.链表相交

代码随想录算法训练营第4天 24.两两交换链表中的节点、19. 删除链表的倒数第N个节点、160.链表相交 两两交换链表中的节点 力扣题目链接(opens new window) 给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。 你不能只是单纯的改变节点内部…

C++中的多态

目录 多态的定义及实现 多态的构成条件 虚函数 虚函数重写 虚函数重写的两个例外&#xff1a; override 和 final(C11) 重载、覆盖(重写)、隐藏(重定义)的对比 抽象类 多态的原理 虚函数表 多态的概念&#xff1a;字面的意思就是多种形态&#xff0c;完成某个行为&…

利用MDK的FLM文件生成通用flash驱动

文章目录前言一、FLM文件是什么&#xff1f;二、FLM文件结构1.FlashPrg.c2.FlashPrg.c三、解析FLM文件1.解析flm文件四、设计flash驱动抽象层五、快速使用前言 在进行Flash操作时&#xff0c;一般我们需要设计一套Flash抽象层&#xff0c;至少要包括flash的init&#xff0c;re…

C++STL之stack容器和优先级队列底层详解

一&#xff1a;stack容器1.1&#xff1a;容器适配器概念&#xff1a;容器适配器是用特定类封装作为其底层的容器&#xff0c;并提供一组特定的成员函数来访问元素&#xff0c;stack的底层容器可以是任意的类模板&#xff0c;或者一些其他的容器类&#xff0c;这些容器类应该支持…

JavaScript详解

目录 1.JavaScript基础知识 1.1 JavaScript概述 1.1.1 JavaScript历史 1.1.2 JavaScript是什么 1.1.3 JavaScript的作用 1.1.4 HTML/CSS/JS的关系 1.1.5 基本特点 1.1.6 浏览器执行JS简介 1.1.7 JavaScript脚本语言的组成 1.2 JavaScript使用方法 1.3 JavaScript输…

论文创新及观点2

题目 Zero-Shot Visual Recognition using Semantics-Preserving Adversarial Embedding Networks 摘要 基于visual-semantic embedding&#xff0c;的ZSL方法存在信息损失(semantic loss),的问题&#xff0c;在训练过程中&#xff0c;如果某些语义信息对分类的区分性不大&a…

「项目管理」如何做好研发FO角色?

角色定位 FO &#xff08;Feature Owner&#xff09;&#xff0c;项目某一阶段/版本迭代生命周期的总负责人。基于从需求发起、研发接入、上线等项目过程阶段&#xff0c;可以根据职责本位不同来推荐具体项目成员、干系人担任FO角色&#xff0c;前端、 客户端 、服务端、测试、…

Spring事务和事务传播机制

⭐️前言⭐️ 事务是作为一名后端程序员&#xff0c;必须去要了解清楚的东西&#xff0c;因为它决定了程序的正常运行以及与程序运行效率之间的权衡&#xff0c;这篇文章我们就来了解一下Spring事务和事务传播机制。 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &am…

【阶段三】Python机器学习08篇:机器学习项目实战:决策树分类模型

本篇的思维导图: 决策树模型简介 决策树模型的基本原理是通过对一系列问题进行if/else的推导,最终实现相关决策。 下图所示为一个典型的决策树模型——员工离职预测模型的简单演示。该决策树首先判断员工满意度是否小于5,若答案为“是”,则认为该员工会离…

07、ThingsBoard本地打镜像上传到harbor

1、Harbor是什么? Harbor是为企业用户设计的容器镜像仓库开源项目,包括了权限管理(RBAC)、LDAP、审计、安全漏洞扫描、镜像验真、管理界面、自我注册、HA等企业必需的功能,同时针对中国用户的特点,设计镜像复制和中文支持等功能。 2、安装Harbor 2.1、下载地址 Tags g…

【看表情包学Linux】探讨项目构建问题 | Makefile | 依赖关系与依赖方法 | 伪目标 PHONY

&#x1f923; 爆笑教程 &#x1f449; 《看表情包学Linux》&#x1f448; 猛戳订阅 &#x1f525; &#x1f4ad; 写在前面&#xff1a;本章我们要学习的是 makefile。会不会写 makefile&#xff0c;从一个侧面说明一个人是否具备完成大型工程的能力。一个工程中的源文件不计…

学计算机专业的你后悔了吗?

先说结论&#xff1a;不后悔。当年高考的时候&#xff0c;老师和我们说&#xff0c;将来环境、船舶、园林专业肯定特别吃香&#xff0c;填志愿的时候记得都选上。现在来看&#xff0c;这几个专业妥妥的天坑专业&#xff0c;前段时候还认识一个船舶专业的博士报培训班转计算机&a…

【GNN】图基本知识代码、nxworkx包的基本使用

一个写得很好的博客&#xff1a; 图或网络中的中心性&#xff1a;点度中心性、中介中心性、接近中心性、特征向量中心性、PageRank 特征向量中心性&#xff08;eigenvector centrality&#xff09; 特征向量中心性的基本思想是&#xff0c;一个节点的中心性是相邻节点中心性的函…

Kali Linux渗透测试小实践——Metasploit与后门木马

一、环境和工具准备 1.Metasploit Metasploit是一款开源的安全漏洞检测工具&#xff0c;可以帮助安全和IT专业人士识别安全性问题&#xff0c;验证漏洞的缓解措施&#xff0c;并管理专家驱动的安全性进行评估&#xff0c;提供真正的安全风险情报。这些功能包括智能开发&#…

MySQL常用基础 - 小白必看

MySQL数据库基本操作 一、DDL 概念&#xff1a;是一个数据定义语言 该语言部分包括&#xff1a; 1、对数据库的常用操作 创建数据库&#xff1a; 1、create database 数据库名 (直接删除) 2、create database if not exists 数据库名 &#xff08;判断数据库是否存在&…