基于Paddle Serving的手写数字图像识别模型服务化部署

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、可部署模型准备
  • 二、服务端框架
  • 三、客户端实现
  • 实验示例


前言

本文章主要讲述Windows系统下的paddle模型服务化部署,目前Win系统只支持用web service的方式搭建local predictor预测服务,linux系统的RPC服务部署请参考https://aistudio.baidu.com/aistudio/projectdetail/545527

一、可部署模型准备

安装百度飞桨框架:

python -m pip install paddlepaddle==2.3.0 -i https://mirror.baidu.com/pypi/simple

安装服务端与客户端:

pip install paddle-serving-client -i https://mirror.baidu.com/pypi/simple
pip install paddle-serving-server -i https://mirror.baidu.com/pypi/simple
pip install paddle-serving-app -i https://mirror.baidu.com/pypi/simple

请参考上述连接文章训练好模型并将模型文件转化为可部署的server端与client端文件:
基于Paddle Serving的手写数字图像识别模型服务化部署_第1张图片
注意其中的conf.prototxt文件中feed与fetch分别为模型的输入与输出,需要打开查看,与下文服务端代码中的feed与fetch对应填上:
基于Paddle Serving的手写数字图像识别模型服务化部署_第2张图片

二、服务端框架

服务端基于paddle serving的web框架,具体设计原理可查阅官方文档:
https://github.com/PaddlePaddle/Serving/blob/develop/doc/Windows_Tutorial_CN.md
服务端代码如下(示例):

from PIL import Image
from paddle_serving_client import Client
from paddle_serving_app.reader import OCRReader
import cv2
import sys
import numpy as np
# import os
# from paddle_serving_client import Client
# from paddle_serving_app.reader import Sequential, URL2Image, ResizeByFactor
# from paddle_serving_app.reader import Div, Normalize, Transpose
# from paddle_serving_app.reader import DBPostProcess, FilterBoxes, GetRotateCropImage, SortedBoxes
# from paddle_serving_client.pipeline.channel import ChannelData
if sys.argv[1] == 'gpu':
    from paddle_serving_server.web_service import WebService
elif sys.argv[1] == 'cpu':
    print(3)
    from paddle_serving_server.web_service import WebService
    print(1)
from paddle_serving_app.local_predict import LocalPredictor
import time
import re
import base64


class NUMPICweb(WebService):
    def init_det_debugger(self, det_model_config):
        self.det_client = LocalPredictor()
        if sys.argv[1] == 'gpu':
            self.det_client.load_model_config(
                det_model_config, use_gpu=True, gpu_id=1)
        elif sys.argv[1] == 'cpu':
            self.det_client.load_model_config(det_model_config)
    def preprocess(self, feed=[],fetch=[]):
        data = base64.b64decode(feed[0]['image'].encode('utf8'))
        data = np.fromstring(data, np.uint8)
        im = cv2.imdecode(data, cv2.IMREAD_COLOR)
        cv2.imwrite('test.png',im)
        file = r"test.png"
        im = cv2.imread(file)
        im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)#转为灰度图
        im = 255-im#对图片反色处理
        im = im / 255.0 * 2.0 - 1.0#(255-im)/255.0
        #im = Image.open(file).convert('L')
        cv2.imshow('a',im)
        cv2.waitKey()
        im = cv2.resize(im,(28,28))  # resize image with high-quality 图像大小为28*28
        im = np.array(im).reshape(1, 1, 28, 28).astype(np.float32)  # 返回新形状的数组,把它变成一个 numpy 数组以匹配数据馈送格式。
        print(im)
        #im = (255-im)/255.0#im / 255.0 * 2.0 - 1.0
        feed = {"image":im}
        fetch = ['fc_2.tmp_2']
        #print(feed)
        fetch_map = self.det_client.predict(feed={"image":im}, fetch=['fc_2.tmp_2'])
        lab = fetch_map['fc_2.tmp_2']
        print(lab)
        print(np.argmax(lab[0]))
        return feed,fetch,False


    def postprocess(self, feed={}, fetch=[],fetch_map=None):
        res = {"res": [f"{np.argmax(fetch_map['fc_2.tmp_2'])}"]}
        return res

# class PICService(WebService):
#     def get_pipeline_response(self, read_op):
#         image_op = NUMPICOp(name="pic", input_ops=[read_op])
#         return image_op

pic_service = NUMPICweb(name="pic")
pic_service.load_model_config("serving_server_dir")#你模型的服务端路径
pic_service.prepare_server(workdir="workdir", port=9292)
pic_service.init_det_debugger(det_model_config="serving_server_dir")
if sys.argv[1] == 'gpu':
    pic_service.set_gpus("0")
    pic_service.run_debugger_service(gpu=True)
elif sys.argv[1] == 'cpu':
    pic_service.run_debugger_service()
pic_service.run_web_service()

其中preprocess为图片预处理,即对传入的base64数据进行解码,保存图片,转灰度以及反色等,因为这里的测试集图像是我自己画的白底黑字数字,训练用的图像都是黑底白字所以要保证预测的输入一致。postprocess为返回客户端的json数据,类似于python的字典格式,这俩个核心函数具体原理请参考上述Web Service设计官方文档。

三、客户端实现

代码如下(示例):

import requests
import json
import cv2
import base64
import os, sys
import time


def cv2_to_base64(image):
    #data = cv2.imencode('.jpg', image)[1]
    return base64.b64encode(image).decode(
        'utf8')  #data.tostring()).decode('utf8')


headers = {"Content-type": "application/json"}
url = "http://127.0.0.1:9292/pic/prediction"
test_img_dir = "D:/Mypy_pro/1/deep_learning/num_pic"#你的测试集数字图像路径
for img_file in os.listdir(test_img_dir):
    with open(os.path.join(test_img_dir, img_file), 'rb') as file:
        image_data1 = file.read()
    image = cv2_to_base64(image_data1)
    data = {"feed": [{"image":image}], "fetch": ['fc_2.tmp_2']}
    r = requests.post(url=url, headers=headers, data=json.dumps(data))
    print(r)

实验示例

手画的数字图片:
基于Paddle Serving的手写数字图像识别模型服务化部署_第3张图片
建议使用原始MNIST数据集的数字图片预测,自己手写的数字后面789基本识别不出来!
在工程目录下开启服务命令:python pic_web_server.py cpu
基于Paddle Serving的手写数字图像识别模型服务化部署_第4张图片
打开一个新的终端作为客户端:python pic-pipeline_http_client.py
基于Paddle Serving的手写数字图像识别模型服务化部署_第5张图片
博主也是新手小白,刚入手才不到俩三个星期,后续会持续更新并尝试pipeline serving服务部署,各位可参考大佬的文章https://blog.csdn.net/qianbin3200896/article/details/124330556,22年4月底写的,非常适合新手学习,有问题欢迎随时在评论区交流一起学习!

你可能感兴趣的:(paddle,paddlepaddle,python)