使用Flask快速部署PyTorch模型

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

今天我将通过一个简单的案例:部署一个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服务已经可以工作了,现在让我们添加一些代码,将数据传递给我们的模型!

添加更多的导入

 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'] 

预测

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

 @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代码

 #pip install requests
 import requests
 
 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模型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第三代量子计算机交付,中国芯片开辟新道路,光刻机难挡中国芯

日前安徽本源量子宣布第三代超导量子计算系统正式上线&#xff0c;这是中国最先进的量子计算机&#xff0c;计算量子比特已达到72个&#xff0c;在全球已居于较为领先的水平&#xff0c;这对于中国芯片在原来的硅基芯片受到光刻机阻碍无疑是巨大的鼓舞。 据悉本源量子的第一代、…

一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库

前言 今天给大家分享一个小巧、快速、轻量级的 .NET NoSQL 嵌入式数据库&#xff1a;LiteDB。本篇文章主要是介绍LiteDB和在.NET中如何使用。 LiteDB介绍 LiteDB 是一个小巧、快速和轻量级的 .NET NoSQL 嵌入式数据库。 无服务器的 NoSQL 文档存储简单的 API&#xff0c;类似…

【研究僧毕业总结】第1024个创作日

目录 前言1. 机缘2. 收获3. 憧憬 前言 收到这封来信&#xff0c;代表从创作至今刚好满足1024天 1024&#xff0c;程序员的记忆 1. 机缘 从学生到社会&#xff0c;都在需求一个记录笔记的软件&#xff0c;而作为程序员&#xff0c;CSDN可云同步又可直接在云平台上看到 选择了…

高性价比蓝牙耳机有哪些?五款热门高性价比开放式蓝牙耳机推荐

想要一款音质超赞、佩戴舒适、价格又亲民的高性价比蓝牙耳机吗&#xff0c;在这那可就找对地方了&#xff0c;开放式蓝牙耳机就是那种让你在听音乐的同时&#xff0c;还能听到周围环境音的耳机&#xff0c;这种设计让你的听音体验更加舒适&#xff0c;那么哪款开放式蓝牙耳机最…

一款上传图片压缩工具及压缩图片的时机说明

某些图片需作下压缩处理&#xff0c;以便某些页面图片列表使用压缩图&#xff0c;从而提高页面图片的加载速度,图片压缩的时机可选在上传图片的时候&#xff08;新增时&#xff09;或者读取图片的时候。&#xff08;对已有图片作压缩&#xff0c;历史数据&#xff09;。访问图片…

Java--业务场景:获取请求的ip属地信息

文章目录 前言步骤在pom文件中引入下列依赖IpUtil工具类在Controller层编写接口&#xff0c;获取请求的IP属地测试接口 IpInfo类中的方法 前言 很多时候&#xff0c;项目里需要展示用户的IP属地信息&#xff0c;所以这篇文章就记录一下如何在Java Spring boot项目里获取请求的…

灵活使用Redis高可用

1 Redis高可用 1.1 Redis的高可用方式 主从复制&#xff1a; 主从复制时高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制的基础上实现高可用。主从复制主要实现了数据的多机备份&#xff0c;以及对于读操作的负载均衡和简单的故障恢复。缺陷&#xff1a;复制恢复无法…

回首2023,厉兵秣马,启航2024

目录 回首风波的20232023&#xff0c;感恩相遇暂停发文发文狂潮感恩有你备战2024学习之余跆拳道比赛做手工diy 学习心路年初学习伊始心路其后学习后来心路 必须看配图说明 未知的2024Flag 回首风波的2023 2023&#xff0c;感恩相遇 还记得&#xff0c;22年末&#xff0c;23年…

idea右上角浏览器图标没有idea内部浏览器怎么显示

idea右上角浏览器图标没有idea内部浏览器怎么显示 file -> settings -> tools -> web brosers 选择需要的浏览器&#xff0c;勾选上展示到编辑器中 打开上图的Built-in Preview&#xff0c;就会显示idea标志的内部显示了&#xff01;&#xff01;&#xff01;

第二证券:如何判断主力是在洗盘还是出货?

怎样判别主力是在洗盘仍是出货&#xff1f; 1、依据股票成交量判别 在洗盘时&#xff0c;个股的成交量与前几个生意相比较&#xff0c;呈现缩量的状况&#xff0c;而出货其成交量与前几个生意日相比较呈现放量的走势。 2、依据股票筹码分布判别 洗盘首要是将一些散户起浮筹…

面试算法108:单词演变

题目 输入两个长度相同但内容不同的单词&#xff08;beginWord和endWord&#xff09;和一个单词列表&#xff0c;求从beginWord到endWord的演变序列的最短长度&#xff0c;要求每步只能改变单词中的一个字母&#xff0c;并且演变过程中每步得到的单词都必须在给定的单词列表中…

Python 基础(四):序列

目录 简介2 基本使用2.1 索引2.2 切片2.3 相加2.4 相乘2.5 元素是否在序列中2.6 内置函数 简介 Python 中的序列是一块可存放多个值的连续内存空间&#xff0c;所有值按一定顺序排列&#xff0c;每个值所在位置都有一个编号&#xff0c;称其为索引&#xff0c;我们可以通过索引…

DAY2-English Learning

一、积累 1.trunk 案例&#xff1a; i put my luggage in the trunk of the car. 翻译&#xff1a;我把行李放在汽车的后备箱里。 2. solvent 例句&#xff1a;The sovlent is uesd to dissolve the paint. 翻译&#xff1a;溶剂是用来溶解油漆的。 3. 受伤的表达 1.cramp …

【大数据进阶第三阶段之Hue学习笔记】Hue的安装和使用

1、 Hue的安装 1.1 上传解压安装包 Hue的安装支持多种方式&#xff0c;包括rpm包的方式进行安装、tar.gz包的方式进行安装以及cloudera manager的方式来进行安装等&#xff0c;我们这里使用tar.gz包的方式来进行安装 Hue的压缩包的下载地址&#xff1a; http://archive.cloude…

hadoop自动获取时间

1、自动获取前15分钟 substr(from_unixtime(unix_timestamp(concat(substr(20240107100000,1,4),-,substr(20240107100000,5,2),-,substr(20240107100000,7,2), ,substr(20240107100000,9,2),:,substr(20240107100000,11,2),:,00))-15*60,yyyyMMddHHmmss),1) unix_timestam…

儿童护眼灯如何选择?适合儿童的护眼灯十大排行榜

为家里的孩子选择一款合适的护眼台灯&#xff0c;我想对于大多数家长来说&#xff0c;还是非常不容易的&#xff0c;需要综合考虑多个因素&#xff0c;包括色温、亮度与均匀度、无频闪、无眩光、显色指数、安全性和设计风格等。为了保护孩子的眼睛&#xff0c;可以说是费劲心思…

RTK使用步骤

RTK&#xff08;工作电压3.3V&#xff09;使用步骤 基准站&#xff08;蓝牙 WiFi&#xff09; 配置基本都在Web端&#xff0c;但配置USB-C的输入输出还是要到u-center Base Station模式 当开关设置为 Base 时&#xff0c;设备将进入 Base Station 模式。这在设备安装到固定位…

Yolov4重大的更新,结构组件

YOLO之父在2020年初宣布退出CV界&#xff0c;YOLOv4 的作者并不是YOLO系列 的原作者。YOLO V4是YOLO系列一个重大的更新&#xff0c;其在COCO数据集上的平均精度(AP)和帧率精度(FPS)分别提高了10% 和12%&#xff0c;并得到了Joseph Redmon的官方认可&#xff0c;被认为是当前最…

在生产环境中使用uWSGI来运行Flask应用

安装uwsgi pip install uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple安装不上则使用以下命令&#xff1a; conda install -c conda-forge uwsgi 当您成功安装uwsgi后&#xff0c;您可以通过以下步骤来测试uwsgi是否安装成功&#xff1a; 创建一个Python脚本&#xff…

【python基础教程】print输出函数和range()函数的正确使用方式

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 print()有多个参数&#xff0c;参数个数不固定。 有四个关键字参数&#xff08;sep end file flush&#xff09;&#xff0c;这四个关键字参数都有默认值。 print作用是将objects的内容输出到file中&#xff0c;objects中的…