PyTorch翻译官网教程-DEPLOYING PYTORCH IN PYTHON VIA A REST API WITH FLASK

这篇具有很好参考价值的文章主要介绍了PyTorch翻译官网教程-DEPLOYING PYTORCH IN PYTHON VIA A REST API WITH FLASK。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

官网链接

Deploying PyTorch in Python via a REST API with Flask — PyTorch Tutorials 2.0.1+cu117 documentation

通过flask的rest API在python中部署pytorch

在本教程中,我们将使用Flask部署PyTorch模型,并开放用于模型推断的REST API。特别是,我们将部署一个预训练的DenseNet 121模型来检测图像。

这是关于在生产环境中部署PyTorch模型的系列教程中的第一篇。使用Flask这种方式是迄今为止部署PyTorch模型的最简单方法,但它不适用于具有高性能要求的用例。

  • 如果你已经熟悉了TorchScript,你可以直接跳到我们的加载一个TorchScript模型在c++教程。(Loading a TorchScript Model in C++ )
  • 如果你需要对TorchScript进行复习,请查看我们的TorchScript入门教程。(Intro a TorchScript )

API定义

我们将首先定义API 路径、请求和响应类型。我们的API路径是 /predict它接受带有包含图像的文件参数的HTTP POST请求。响应将是JSON响应,其中包含预测结果。

{"class_id": "n02124075", "class_name": "Egyptian_cat"}{"class_id": "n02124075", "class_name": "Egyptian_cat"}

依赖项

运行以下命令安装所需的依赖项:

$ pip install Flask==2.0.1 torchvision==0.10.0

简单Web服务器

下面是一个简单的web服务器,摘自Flask的文档

from flask import Flask
app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello World!'

将上面的代码片段保存在一个名为app.py的文件中,现在你可以通过输入以下命令来运行Flask开发服务器:

$ FLASK_ENV=development FLASK_APP=app.py flask run

当您在web浏览器中访问http://localhost:5000/时,您将看到Hello World!文本

我们将对上面的代码片段做一些修改,使其适合我们的API定义。首先,我们将把方法重命名为predict。我们将把请求路径更新为/predict。由于图像文件将通过HTTP POST请求发送,我们将更新它,使其也只接受POST请求。

@app.route('/predict', methods=['POST'])
def predict():
    return 'Hello World!'

我们还将更改响应类型,以便它返回一个包含ImageNet类id和名称的JSON响应。更新后的app.py文件现在将是:

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'})

推理

在下一节中,我们将重点讨论如何编写推理代码。这将涉及两个部分,一个是我们准备图像,以便它可以馈送到DenseNet,接下来,我们将编写代码以从模型中获得实际预测。

准备图像

DenseNet模型要求图像为3通道RGB图像,大小为224 x 224。我们还将用所需的均值和标准差值对图像张量进行归一化。你可以在这里读到更多(here)。

我们将使用torchvision 库中的 transforms ,并构建一个变换管道,它可以根据要求变换我们的图像。你可以在这里阅读更多关于变换的内容(here)。

import io

import torchvision.transforms as transforms
from PIL import Image

def transform_image(image_bytes):
    my_transforms = transforms.Compose([transforms.Resize(255),
                                        transforms.CenterCrop(224),
                                        transforms.ToTensor(),
                                        transforms.Normalize(
                                            [0.485, 0.456, 0.406],
                                            [0.229, 0.224, 0.225])])
    image = Image.open(io.BytesIO(image_bytes))
    return my_transforms(image).unsqueeze(0)

上述方法接受字节数据的图像,应用一些列的transforms 并返回一个张量。为了测试上述方法,以字节模式读取图像文件(首先将../_static/img/sample_file.jpeg替换为计算机上文件的实际路径)并查看是否返回一个张量:

with open("../_static/img/sample_file.jpeg", 'rb') as f:
    image_bytes = f.read()
    tensor = transform_image(image_bytes=image_bytes)
    print(tensor)

预测

现在将使用预训练的DenseNet 121模型来预测图像类别。我们将使用torchvision库,加载模型并获得推理结果。虽然我们将在本例中使用预训练模型,但您可以对自己的模型使用相同的方法。了解更多关于加载模型的信息(tutorial)。

from torchvision import models

# Make sure to set `weights` as `'IMAGENET1K_V1'` to use the pretrained weights:
model = models.densenet121(weights='IMAGENET1K_V1')
# Since we are using our model only for inference, switch to `eval` mode:
model.eval()


def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    outputs = model.forward(tensor)
    _, y_hat = outputs.max(1)
    return y_hat


张量y_hat 将包含预测类别的索引id, 然而,我们需要一个人类可读的类名。为此,我们需要一个类别id和命名的映射。下载 imagenet_class_index.json 这个文件( this file),并记住保存它的位置(或者,如果您遵循本教程中的确切步骤,将其保存在教程/_static中)。这个文件包含ImageNet类别id到ImageNet类名的映射。我们将加载这个JSON文件并获取预测类别索引的类名。

import json

imagenet_class_index = json.load(open('../_static/imagenet_class_index.json'))

def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    outputs = model.forward(tensor)
    _, y_hat = outputs.max(1)
    predicted_idx = str(y_hat.item())
    return imagenet_class_index[predicted_idx]


在使用imagenet_class_index字典之前,首先我们将把张量值转换为字符串值,因为imagenet_class_index字典中的键是字符串。我们将测试上述方法:

with open("../_static/img/sample_file.jpeg", 'rb') as f:
    image_bytes = f.read()
    print(get_prediction(image_bytes=image_bytes))

你应该得到这样的返回:

['n02124075', 'Egyptian_cat']

数组中的第一项是ImageNet类别id,第二项是人类可读的名称。

注意

您是否注意到model变量不是get_prediction方法的局部变量,或者说为什么model是一个全局变量?就内存和计算而言,加载模型可能是一项昂贵的操作。如果我们在get_prediction方法中加载模型,那么每次调用该方法时都会不必要地加载模型。因为我们正在构建一个web服务器,每秒可能有数千个请求,我们不应该浪费时间为每个推理加载模型。因此,我们只将模型加载到内存中一次。在生产系统中,为了能够大规模地处理请求,必须高效地使用计算,因此通常应该在处理请求之前加载模型。

在我们的API服务器中集成模型

在最后一部分中,我们将把模型添加到Flask API服务器中。由于我们的API服务器应该接受一个图像文件,我们将更新我们的预测方法来从请求中读取文件:

from flask import request

@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        # we will get the file from the request
        file = request.files['file']
        # convert that to bytes
        img_bytes = file.read()
        class_id, class_name = get_prediction(image_bytes=img_bytes)
        return jsonify({'class_id': class_id, 'class_name': class_name})

app.py文件现在已经完成。以下是完整版本;将路径替换为您保存文件的路径,它应该运行:

import io
import json

from torchvision import models
import torchvision.transforms as transforms
from PIL import Image
from flask import Flask, jsonify, request


app = Flask(__name__)
imagenet_class_index = json.load(open('<PATH/TO/.json/FILE>/imagenet_class_index.json'))
model = models.densenet121(weights='IMAGENET1K_V1')
model.eval()


def transform_image(image_bytes):
    my_transforms = transforms.Compose([transforms.Resize(255),
                                        transforms.CenterCrop(224),
                                        transforms.ToTensor(),
                                        transforms.Normalize(
                                            [0.485, 0.456, 0.406],
                                            [0.229, 0.224, 0.225])])
    image = Image.open(io.BytesIO(image_bytes))
    return my_transforms(image).unsqueeze(0)


def get_prediction(image_bytes):
    tensor = transform_image(image_bytes=image_bytes)
    outputs = model.forward(tensor)
    _, y_hat = outputs.max(1)
    predicted_idx = str(y_hat.item())
    return imagenet_class_index[predicted_idx]


@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        file = request.files['file']
        img_bytes = file.read()
        class_id, class_name = get_prediction(image_bytes=img_bytes)
        return jsonify({'class_id': class_id, 'class_name': class_name})


if __name__ == '__main__':
    app.run()

让我们测试一下我们的web服务器!运行:

$ FLASK_ENV=development FLASK_APP=app.py flask run


我们可以使用requests库向我们的应用发送POST请求:

import requests

resp = requests.post("http://localhost:5000/predict",
                     files={"file": open('<PATH/TO/.jpg/FILE>/cat.jpg','rb')})

打印rep .json()将显示以下内容:

{"class_id": "n02124075", "class_name": "Egyptian_cat"}

下一个步骤

我们编写的服务器非常简单,可能无法完成生产应用程序所需的所有功能。所以,这里有一些你可以做的事情来让它变得更好:文章来源地址https://www.toymoban.com/news/detail-564507.html

  • 请求路径 /predict假定请求中总是有一个图像文件。这可能并不适用于所有请求。我们的用户可以发送带有不同参数的图像或根本不发送图像。
  • 用户也可以发送非图像类型的文件。由于我们不处理错误,这将破坏我们的服务器。显式添加异常的错误处理路径,将使我们能够更好地处理错误输入
  • 尽管该模型可以识别大量的图像类别,但它可能无法识别所有的图像。优化实现以处理模型无法识别图像中的任何内容的情况。
  • 我们以开发模式运行Flask服务器,这种模式不适合部署到生产环境中。您可以查看本教程,了解如何在生产环境中部署Flask服务器。(this tutorial
  • 您还可以通过创建带有表单的页面来添加UI,该表单接受图像并显示预测结果。请查看类似项目的演示及其源代码。(source code.
  • 在本教程中,我们只展示了如何构建一个每次可以返回单个图像预测的服务。我们可以修改我们的服务,使其能够一次返回多个图像的预测结果。此外,service-streamer库会自动将请求排队到您的服务中,并将它们采样到可以馈送到模型中的小批量中。您可以查看本教程(this tutorial.)。
  • 最后,我们鼓励您查看页面顶部链接的关于部署PyTorch模型的其他教程.

到了这里,关于PyTorch翻译官网教程-DEPLOYING PYTORCH IN PYTHON VIA A REST API WITH FLASK的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • PyTorch翻译官网教程8-SAVE AND LOAD THE MODEL

    Save and Load the Model — PyTorch Tutorials 2.0.1+cu117 documentation 在本节中,我们将了解如何通过保存、加载和运行模型预测来持久化模型状态。 PyTorch模型将学习到的参数存储在一个名为state_dict的内部状态字典中。这些可以通过 torch.save 方法持久化 输出 要加载模型权重,需要首先创

    2024年02月16日
    浏览(35)
  • PyTorch翻译官网教程6-AUTOMATIC DIFFERENTIATION WITH TORCH.AUTOGRAD

    Automatic Differentiation with torch.autograd — PyTorch Tutorials 2.0.1+cu117 documentation 当训练神经网络时,最常用的算法是方向传播算法。在该算法中,根据损失函数与给定参数的梯度来调整模型参数(权重)。 为了计算这些梯度,PyTorch有一个内置的微分引擎,名为torch.autograd。它支持任

    2024年02月16日
    浏览(48)
  • PyTorch翻译官网教程-FAST TRANSFORMER INFERENCE WITH BETTER TRANSFORMER

    Fast Transformer Inference with Better Transformer — PyTorch Tutorials 2.0.1+cu117 documentation 本教程介绍了作为PyTorch 1.12版本的一部分的Better Transformer (BT)。在本教程中,我们将展示如何使用更好的 Transformer 与 torchtext 进行生产推理。Better Transformer是一个具备生产条件fastpath并且可以加速在CP

    2024年02月13日
    浏览(43)
  • PyTorch翻译官网教程-LANGUAGE MODELING WITH NN.TRANSFORMER AND TORCHTEXT

    Language Modeling with nn.Transformer and torchtext — PyTorch Tutorials 2.0.1+cu117 documentation 这是一个关于训练模型使用nn.Transformer来预测序列中的下一个单词的教程。 PyTorch 1.2版本包含了一个基于论文Attention is All You Need的标准 transformer 模块。与循环神经网络( RNNs )相比, transformer 模型已被

    2024年02月13日
    浏览(39)
  • PyTorch翻译官网教程-NLP FROM SCRATCH: GENERATING NAMES WITH A CHARACTER-LEVEL RNN

    NLP From Scratch: Generating Names with a Character-Level RNN — PyTorch Tutorials 2.0.1+cu117 documentation 这是我们关于“NLP From Scratch”的三篇教程中的第二篇。在第一个教程中 /intermediate/char_rnn_classification_tutorial 我们使用RNN将名字按其原始语言进行分类。这一次,我们将通过语言中生成名字。

    2024年02月13日
    浏览(44)
  • PyTorch翻译官网教程-NLP FROM SCRATCH: CLASSIFYING NAMES WITH A CHARACTER-LEVEL RNN

    NLP From Scratch: Classifying Names with a Character-Level RNN — PyTorch Tutorials 2.0.1+cu117 documentation 我们将建立和训练一个基本的字符级递归神经网络(RNN)来分类单词。本教程以及另外两个“from scratch”的自然语言处理(NLP)教程 NLP From Scratch: Generating Names with a Character-Level RNN 和 NLP From Scratch

    2024年02月12日
    浏览(59)
  • GPT最佳实践-翻译官网

    https://platform.openai.com/docs/guides/gpt-best-practices/gpt-best-practices 本指南分享了从 GPT 获得更好结果的策略和战术。有时可以结合使用此处描述的方法以获得更大的效果。我们鼓励进行实验以找到最适合您的方法。 此处演示的一些示例目前仅适用于我们功能最强大的模型 gpt-4 .如果

    2024年02月09日
    浏览(50)
  • 【python】python结合js逆向,让有道翻译成为你的翻译官,实现本地免费实时翻译

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者等等。 🏆《博客》:Python全栈,前后端开发,人工智能,js逆向,App逆

    2024年03月23日
    浏览(43)
  • 【Pytorch】Tutorials个人翻译集合

    本文记录Pytorch Tutorials文档的翻译文章集合. 由于本人英语能力有限(only-CET4), 欢迎指正翻译中的错误 。 【Pytorch】Pytorch文档学习1:Tensors 【Pytorch】Pytorch文档学习2:DATASETS DATALOADERS 【Pytorch】Pytorch文档学习3:TRANSFORMS 【Pytorch】Pytorch文档学习4:BUILD THE NEURAL NETWORK 【Pytorc

    2024年02月10日
    浏览(37)
  • NLP实战6:seq2seq翻译实战-Pytorch复现-小白版

    目录 一、前期准备 1. 搭建语言类 2. 文本处理函数 3. 文件读取函数 二、Seq2Seq 模型 1. 编码器(Encoder) 2. 解码器(Decoder) 三、训练 1. 数据预处理 2. 训练函数 四、训练与评估 🍨 本文为[🔗365天深度学习训练营]内部限免文章(版权归 *K同学啊* 所有) 🍖 作者:[K同学啊] 📌

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包