基于Flask的模型部署

基于Flask的模型部署

一、背景

Flask:一个使用Python编写的轻量级Web应用程序框架;

首先需要明确模型部署的两种方式:在线和离线;

在线:就是将模型部署到类似于服务器上,调用需要通过网络传输数据,再将结果返回;

离线:就是将模型直接部署在终端设备上,不需要联网,数据传输上比较快;

二、Flask简单部署分类模型

通过一个实际的分类案例,来说明整个实现的流程;

首先Flask分为服务端和设备端,服务端就是接受数据并处理,应用端只负责发送数据和展示结果;

实现步骤:

------服务端-------

1、初始化Flask app

可以理解为初始化一个服务器对象;

python 复制代码
app = flask.Flask(__name__)

2、加载模型

python 复制代码
def load_model():
    global model
    model = resnet50(pretrained=True)	# 这里模型可以替换成自己的模型
    model.eval()
    if use_gpu:
        model.cuda()

这里是所有模型通用的,如果是一些模型需要将模型结构的代码和模型文件都准备好;

3、数据预处理

推理部分的数据处理应该与模型训练前的处理保持一致,否则可能导致结果出现较大偏差;

python 复制代码
def prepare_image(image, target_size):
    if image.mode != 'RGB':
    image = image.convert("RGB")	# 转换图像为RGB类型
	
	# 缩放图像
    image = T.Resize(target_size)(image)
    image = T.ToTensor()(image)

    # 归一化
    image = T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])(image)

    # 这里表示可以配置多个图像作为一个batch
    image = image[None]
    if use_gpu:
        image = image.cuda()	# 使用GPU
    return Variable(image, volatile=True) 	#不需要求导

上述的数据处理是最基本并且简单的数据处理,在很多任务中的数据预处理会复杂很多;

4、开启服务

python 复制代码
# 注意这里的predict可以自行修改,但需要和后面的端口后缀保持一致
@app.route("/predict", methods=["POST"])	# 这里是python的装饰器
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))

            # 得到模型输出的结果,取出前K个结果
            preds = F.softmax(model(image), dim=1)
            results = torch.topk(preds.cpu().data, k=3, dim=1)
            results = (results[0].cpu().numpy(), results[1].cpu().numpy())
		   
		   # 结果保存到要传回的列表中
            data['predictions'] = list()

            # 根据标签值找到对应对象的实际类别
            for prob, label in zip(results[0][0], results[1][0]):
                label_name = idx2label[label]
                r = {"label": label_name, "probability": float(prob)}
                data['predictions'].append(r)

            # 设置返回列表调用成功
            data["success"] = True

    # 将数据转为json并返回
    return flask.jsonify(data)

这里是服务的具体执行程序,也就是接收数据和处理数据,并将结果返回;

这里可以做UI的可视化界面,本次只是演示效果就不进行设计;

执行该程序后,出现一个访问地址和端口号,如下图所示:

这里是部署到本地的服务器上,在实际工程中,一般是部署到一台公共服务器上,将服务开放为接口供但部分应用使用;

------应用端-------

1、初始化服务接口

python 复制代码
PyTorch_REST_API_URL = 'http://127.0.0.1:5000/predict'

2、请求服务并展示结果

python 复制代码
def predict_result(image_path):
    # 读取图像数据,保存到数组中
    image = open(image_path, 'rb').read()
    payload = {'image': image}

    # 请求服务
    r = requests.post(PyTorch_REST_API_URL, files=payload).json()

    # 确保服务返回成功
    if r['success']:
        # 遍历结果,并打印出来
        for (i, result) in enumerate(r['predictions']):
            print('{}. {}: {:.4f}'.format(i + 1, result['label'],
                                          result['probability']))
    # 如果服务请求失败,返回失败
    else:
        print('Request failed')

上面就是传入一张狗狗图像后打印的结果,可以看出服务能够正常运行;

总结:

虽然是一个简单的分类项目,但整体部署的流程以及一些代码的模板是不变的,换成别的任务可能会复杂一些,主要还是前后处理相对复杂一些,并且做UI界面的话也会相对复杂一些;

相关推荐
Li emily20 小时前
解决港股实时行情数据 API 接入难题
人工智能·python·fastapi
wfeqhfxz258878221 小时前
农田杂草检测与识别系统基于YOLO11实现六种杂草自动识别_1
python
mftang21 小时前
Python 字符串拼接成字节详解
开发语言·python
0思必得021 小时前
[Web自动化] Selenium设置相关执行文件路径
前端·爬虫·python·selenium·自动化
石去皿21 小时前
大模型面试通关指南:28道高频考题深度解析与实战要点
人工智能·python·面试·职场和发展
jasligea21 小时前
构建个人智能助手
开发语言·python·自然语言处理
测试秃头怪1 天前
面试大厂就靠这份软件测试八股文了【含答案】
自动化测试·软件测试·python·功能测试·面试·职场和发展·单元测试
测试杂货铺1 天前
软件测试面试题大全,你要的都在这。。
自动化测试·软件测试·python·功能测试·面试·职场和发展·测试用例
测试大圣1 天前
软件测试基础知识总结(超全的)
软件测试·python·功能测试·测试工具·职场和发展·单元测试·测试用例
sww_10261 天前
RAG检索增强 ETL最佳实战
人工智能·python·spring