能用!飞桨静态图模型部署

“深度学习有趣但艰难”


目录

动态图与静态图的区别

动态图转静态图模型

静态图模型部署


动态图与静态图的区别

 从形式上,飞桨的动态图模型与静态图模型的后缀就不一样,动态图模型的后缀为pdparams,静态图模型的后缀为pdiparams且一般伴随着pdmodel文件。

从编程范式,执行方式,应用场景三个方面来讲动态图与静态图的区别。

编程范式:

  • 静态图(描述式编程/声明式编程):在静态图中,代码先描述要做的事情但不立即执行。对于深度学习任务,需要先定义神经网络的结构,然后再执行整个图结构。这通常涉及预定义完整的神经网络结构,并将神经网络描述为Program的数据结构,随后进行编译优化。
  • 动态图(命令式编程):在动态图中,代码直接返回运算的结果,神经网络结构的定义和执行是同步的。它采用Python的编程风格,解析式地执行每一行网络代码,并同时返回计算结果。

执行方式:

  • 静态图:采用先编译后执行的方式。在代码中预定义完整的神经网络结构后,飞桨框架会对Program进行编译优化,再调用执行器获得计算结果。由于静态图在编译阶段就进行了优化,因此其执行性能往往更佳。
  • 动态图:由于采用Python实时执行的方式,其开销较大,在性能方面与C++有一定差距。但是,动态图在模型开发和调试阶段体验更佳、更易调试。

应用场景:

  • 静态图:由于其在性能上的优势,静态图更适用于生产环境和大规模部署的场景。同时,由于预先拥有完整网络结构,静态图也更利于全局优化。
  • 动态图:由于其实时性和易调试性,动态图在模型开发和调试阶段更为常用。它允许开发者在开发过程中实时查看和调整模型的运行结果,从而更快速地发现问题并进行修复。

动态图转静态图模型

from paddle.jit import to_static
from paddle.static import InputSpec
model = ResNet(10) 
# model 为空模型 只有模型结构无模型参数
params = paddle.load('ResNet_checkpoints/final.pdparams')
model.set_state_dict(params)
# 加载model 模型参数
net = to_static(model, input_spec=[InputSpec(shape=[None, 3, 32, 32])])
# shape为模型的输入shape 其中batch为None 意思是batch为多少都可以
paddle.jit.save(net,"inference_model/ResNet-my7")
# 保存到指定目录下

静态图模型部署

import os.path
from paddle.inference import Config
from paddle.inference import create_predictor
import numpy as np
import os
import cv2
from PIL import Image
import time

cDict = {
    'c0': "驾驶员正常驾驶",
    'c1': "右手使用手机打字",
    'c2': "使用右手打电话",
    'c3': "左手使用手机打字",
    'c4': "使用左手打电话",
    'c5': "调试车辆多媒体",
    'c6': "驾驶员喝水或进食",
    'c7': "驾驶员拿后排东西",
    'c8': "整理头发和化妆",
    'c9': "和其他乘客谈话",
}
labelDict = {'0': 'c7', '1': 'c3', '2': 'c4', '3': 'c9', '4': 'c5', '5': 'c1', '6': 'c8', '7': 'c2', '8': 'c0', '9': 'c6'}


def load_image(img):
    """
    预测图片预处理
    """
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, (224, 224))
    img = np.array(img).astype('float32')
    img = img.transpose((2, 0, 1)) / 255  # HWC to CHW 及归一化
    return img


def predict(model_path, params_path, data, label):
    # Init config
    config = Config(os.path.normpath(model_path), os.path.normpath(params_path))
    config.enable_use_gpu(2048*2, 0)
    # 允许该程序使用2048*2MB显存 0是第0号显卡

    config.switch_ir_optim()
    config.enable_memory_optim()
    # 优化内存

    # Create predictor
    predictor = create_predictor(config)

    input_names = predictor.get_input_names()
    input_tensor = predictor.get_input_handle(input_names[0])
    input_tensor.reshape(data.shape)
    input_tensor.copy_from_cpu(data)

    predictor.run()

    output_names = predictor.get_output_names()
    output_tensor = predictor.get_output_handle(output_names[0])
    output_data = output_tensor.copy_to_cpu()
    index = np.argmax(output_data)
    print(index)
    print(labelDict[str(index)])
    return cDict[labelDict[str(index)]]

猜你喜欢

转载自blog.csdn.net/m0_73938966/article/details/139047030