模型部署:基于flask和pytorch 📅 发布时间:2026/7/12 12:03:51 👁️ 浏览次数: 目录一、模型部署的目的和用到的技术二、系统架构设计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. 客户端调用
MySQL单表分页优化 前言 最近做项目,涉及MySQL的join分页显示,实际上大部分场景都是单表分页,展示一些数据。当然也有时候需要多表join等操作,多表分页时就比较复杂,而且具有表结构连接特定性,一般我们可以使用代码拆分使操作… 2026/5/17 9:34:40
Redis八股 1.什么是缓存穿透缓存后,不再存在ID访问数据库布隆过滤器我们假设ID缓存了,经过HASH计算,得到0000000000111111111这样的。那么布隆内部维护了一堆数组,将对应号位的置1下次再次hash,如果全是1就代表存在也会存在hash冲… 2026/3/18 16:17:39
OpenClaw 记忆系统:长期记忆与上下文管理 引言一、OpenClaw记忆系统概述1.1 记忆系统的设计理念OpenClaw记忆系统的核心理念是"文本大于记忆"(Text > Brain)。这一理念源于对AI记忆局限性的深刻认识:无论AI系统的上下文窗口有多大,它都无法真正"记住&qu… 2026/3/18 16:17:16
JNI实战指南:打通Java与C/C++的底层交互与性能优化 1. 项目概述:为什么我们需要深入理解JNI?如果你是一个有几年经验的Java开发者,可能已经习惯了“一次编写,到处运行”的承诺。但当你遇到一个性能瓶颈,或者需要调用一个用C/C写的、已经存在了十几年的硬件驱动库时&… 2026/7/12 12:02:59
Matlab卫星轨道动态仿真工具包:含28组实测PG数据与三维可视化脚本 本文还有配套的精品资源,点击获取 简介:直接运行zhuchengxu.m或main.m,就能生成卫星轨道三维轨迹图、速度矢量图、地心距离随时间变化曲线等结果。工具包内置weixingguidao.m做轨道动力学计算,shujuchuli.m读取Excel格式的实测… 2026/7/12 12:02:59
Git 2.55.0 在 macOS 上的 3 种安装方案对比:Homebrew vs 官方安装包 vs Xcode CLI Git 2.55.0 在 macOS 上的 3 种安装方案深度评测与选择指南对于 macOS 开发者而言,Git 作为版本控制的核心工具,其安装方式的选择直接影响开发环境的稳定性和工作效率。当前主流安装方案各具特色:Homebrew 提供灵活的版本管理,官方… 2026/7/12 11:58:58
Cisco Packet Tracer 8.2 企业园区网部署:5台路由器静态/动态路由混合配置实战 Cisco Packet Tracer 8.2 企业园区网混合路由配置实战指南 当企业网络规模扩展到多个分厂和办公区域时,如何设计高效可靠的路由方案成为网络工程师的核心挑战。本文将基于Cisco Packet Tracer 8.2模拟器,通过一个包含总厂网络中心、两个分厂和无线会议室… 2026/7/12 11:56:58
瑞萨 CS+ for CC 新建工程 4 步配置:从编译错误到成功运行的完整排错 瑞萨CS for CC工程配置实战:从编译错误到稳定运行的深度排错指南当你第一次在瑞萨CS for CC中创建新工程时,可能会遇到各种棘手的编译错误。这些错误往往不是代码本身的问题,而是工程配置的细节没有到位。本文将带你深入理解四个关键配置环节… 2026/7/12 11:54:58
软件工程导论实验避坑:数据流图绘制的3个常见逻辑错误与修正 数据流图绘制实战避坑指南:数字化校园系统案例解析在软件工程实践中,数据流图(DFD)作为系统分析的核心工具,其绘制质量直接影响后续开发效率。但教学观察显示,约78%的初学者会在首次绘制时犯下典型逻辑错误… 2026/7/12 11:50:57
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/12 0:01:13
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/12 0:01:13
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/12 0:03:14
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/12 0:01:13
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/12 0:01:13
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/12 0:03:14