模型部署:基于flask和pytorch

📅 发布时间:2026/7/12 12:03:51 👁️ 浏览次数:
模型部署:基于flask和pytorch
目录一、模型部署的目的和用到的技术二、系统架构设计1.整体架构c/s2.具体流程三、服务端实现1. 服务端功能概述2.导入所需库3.Flask应用初始化4. 模型加载函数5. 图像预处理函数6. API路由定义7. 服务启动四、客户端1. 客户端功能概述2. 客户端代码五、部署1. 环境配置2. 模型准备3. 启动服务4. 修改IP地址5. 客户端调用在深度学习领域模型训练只是整个项目生命周期的一部分。如何将训练好的模型部署到生产环境中让其他应用程序能够方便地调用是许多开发者面临的挑战。本文将详细介绍如何使用Flask框架和PyTorch构建一个完整的图像分类API服务实现模型的在线部署与调用。一、模型部署的目的和用到的技术提供实时预测服务让模型能够处理实时请求实现模型复用避免重复训练提高开发效率支持多端调用Web、移动端、桌面应用都可以通过API访问便于模型更新只需更新服务端客户端无需改动需要用到的Flask轻量级Web框架适合快速构建API服务PyTorch深度学习框架用于加载和运行模型RequestsPython HTTP库用于客户端请求PIL图像处理库Torchvision提供预训练模型和图像变换工具二、系统架构设计1.整体架构c/s客户端 (Client) → HTTP请求 → Flask服务器server → PyTorch模型 → 预测结果 客户端 (Client) ← HTTP响应 ← Flask服务器 ← 返回结果2.具体流程服务端启动加载预训练模型监听指定端口客户端请求发送图像文件到服务器服务器处理接收图像预处理模型推理结果返回将预测结果封装成JSON格式返回客户端展示解析结果并显示三、服务端实现1. 服务端功能概述根据代码注释服务端需要实现以下核心功能接收来自客户端的信息24小时运行将模型部署起来对图片进行识别将识别结果返回给客户端2.导入所需库import io import flask import torch import torch.nn.functional as F from PIL import Image from torch import nn from torchvision import transforms, modelsio处理字节流数据用于图像读取flaskWeb框架构建API服务torch 和 torch.nn.functionalPyTorch核心库和函数式接口PILPython图像处理库torchvision提供预训练模型和数据预处理工具3.Flask应用初始化app flask.Flask(__name__) model None use_gpu Falseapp flask.Flask(__name__)初始化Flask应用程序实例。__name__参数用于定位应用程序的根路径这样Flask就可以知道在哪里找到模板、静态文件等是Flask应用程序的起点为后续添加路由、配置等奠定了基础。model None全局变量用于存储加载的模型use_gpu False是否使用GPU进行推理4. 模型加载函数def load_model(): Load the pre-trained model, you can use your model just as easily. global model # 加载resnet18网络 model models.resnet18() num_ftrs model.fc.in_features model.fc nn.Sequential(nn.Linear(num_ftrs, 102)) # 修改最后的类别数 checkpoint torch.load(best.pth) model.load_state_dict(checkpoint[state_dict]) # 将模型指定为测试模式 model.eval() # 是否使用gpu if use_gpu: model.cuda()global model声明使用全局变量model在函数内部修改全局变量models.resnet18()加载ResNet18预训练网络结构model.fc.in_features获取原全连接层的输入特征数nn.Sequential(nn.Linear(num_ftrs, 102))修改最后的全连接层适配102类分类任务torch.load(best.pth)加载训练好的模型权重文件model.load_state_dict(checkpoint[state_dict])将权重加载到模型中model.eval()将模型设置为评估模式关闭Dropout和Batch Normalization的训练行为model.cuda()如果use_gpu为True将模型移动到GPU5. 图像预处理函数def prepare_image(image, target_size): if image.mode ! RGB: image image.convert(RGB) image transforms.Resize(target_size)(image) image transforms.ToTensor()(image) image transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])(image) image image[None] if use_gpu: image image.cuda() return torch.tensor(image)if image.mode ! RGB检查图像颜色模式如果不是RGB则转换transforms.Resize(target_size)(image)调整图像尺寸到目标大小(224×224)transforms.ToTensor()(image)将PIL图像转换为PyTorch张量并将像素值从[0,255]缩放到[0.0,1.0]transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])(image)使用ImageNet数据集的均值和标准差进行标准化image image[None]在第0维添加一个维度将形状从(C,H,W)变为(1,C,H,W)满足模型输入的batch要求return torch.tensor(image)返回处理后的张量6. API路由定义app.route(/predict, methods[POST]) def predict(): data {success: False} if flask.request.method POST: if flask.request.files.get(image): # 读取图像文件 image flask.request.files[image].read() image Image.open(io.BytesIO(image)) # 预处理图像 image prepare_image(image, target_size(224, 224)) preds F.softmax(model(image), dim1) results torch.topk(preds.cpu().data, k3, dim1) results (results[0].cpu().numpy(), results[1].cpu().numpy()) data[predictions] list() for prob, label in zip(results[0][0], results[1][0]): r {label: str(label), probability: float(prob)} data[predictions].append(r) data[success] True return flask.jsonify(data)app.route(/predict, methods[POST])装饰器将URL路径/predict与predict函数关联并指定只处理POST请求data {success: False}初始化返回数据success默认为Falseflask.request.files.get(image)获取上传的文件key为imageimage flask.request.files[image].read()读取文件的二进制数据Image.open(io.BytesIO(image))将二进制数据转换为PIL图像F.softmax(model(image), dim1)模型推理后应用softmax函数将输出转换为概率分布torch.topk(preds.cpu().data, k3, dim1)获取概率最高的前3个类别及其概率results[0].cpu().numpy()将概率值转换为numpy数组results[1].cpu().numpy()将类别索引转换为numpy数组循环遍历将结果封装成字典列表flask.jsonify(data)将字典转换为JSON格式的HTTP响应7. 服务启动if __name__ __main__: print(Loading PyTorch model and Flask starting server ...) print(Please wait until server has fully started) load_model() # 加载模型 # 开启服务 app.run(host0.0.0.0, port5010)if __name__ __main__判断是否直接运行此脚本load_model()启动时加载模型app.run(host0.0.0.0, port5010)启动Flask开发服务器host0.0.0.0表示监听所有网络接口允许局域网内的其他设备访问port5010指定端口号四、客户端1. 客户端功能概述根据代码注释客户端需要实现以下核心功能负责发送图片到指定的服务器接收服务器端返回的结果信息2. 客户端代码import requests flask_url http://192.168.31.83:5010/predict # url和端口携程自己的本地ip def predict_result(image_path): image open(image_path, rb).read() payload {image: image} r requests.post(flask_url, filespayload).json() # 向fLask_url服务发送一个P0ST请求并尝试将返回的JSON响应解析为一个Python字典 if r[success]: for (i, result) in enumerate(r[predictions]): print({}.预测类别为{}的概率{}.format(i 1, result[label], result[probability])) else: print(Request failed) if __name__ __main__: predict_result(flower.jpg)import requests导入requests库用于发送HTTP请求flask_url http://192.168.31.83:5010/predict服务器端API地址需要根据实际情况修改IP和端口open(image_path, rb).read()以二进制模式打开并读取图像文件payload {image: image}构建请求数据键名image必须与服务器端flask.request.files.get(image)一致requests.post(flask_url, filespayload).json()发送POST请求files参数用于上传文件.json()将响应解析为Python字典if r[success]检查服务器返回的success字段enumerate(r[predictions])遍历预测结果列表同时获取索引和值打印每个预测结果的类别和概率五、部署1. 环境配置# 创建虚拟环境可选 python -m venv venv # 激活虚拟环境Windows venv\Scripts\activate # 安装依赖 pip install flask torch torchvision pillow requests2. 模型准备确保在服务端目录下有训练好的模型文件best.pth。根据代码这个文件应该包含模型权重通过checkpoint[state_dict]访问3. 启动服务先执行server代码4. 修改IP地址客户端代码中的IP地址需要根据实际情况修改flask_url http://你的实际IP:5010/predict5. 客户端调用