引入

  • 动态图方便调试,静态图方便部署而且效率较高,各有各的优点
  • 通过 Paddle2.0 的动转静功能,就能相对完美的兼顾这两者的优势
  • 实现用动态图进行训练调试,训练完成后使用静态图模型进行部署
  • 本文将通过一个实例来展示如何将一个动态图模型转换至静态图
  • 并且通过导出的推理模型来完成模型的部署
  • 并测试不同方式下的模型运行效率

动态图vs静态图

  • 首先简单的介绍一下这两者的区别:

    • 静态图:计算之前先构建计算图,然后按照计算图进行计算,运行效率高,但调试比较麻烦
    • 动态图:计算的同时构建计算图,运行效率稍低,但是调试方便

运行速度对比

  • 通过实测,在 AIStudio 的CPU平台上,不同方式部署的速度如下表
  • 使用的模型为U2Netp
  • 测试使用的输入均为Batch size为1的320*320分辨率的三通道数据
  • 均测量第二次运行时的消耗时间,因为第一运行时可能需要一些额外的处理误差较大
  • 通过内置计时测量,结果可能存在些许误差
动态图 动转静(paddle.jit.load) 动转静(PaddleInference) 动转静(PaddleInference+MKLDNN)
2.1827 s 1.9110 s 1.8756 s 0.5750 s

动态图模型

  • 对于一个训练完成的动态图模型,一般由如下几个部分组成:

    • 模型代码——用于构建模型
    • 模型参数文件——用于保存模型参数
  • 所以加载一个动态图模型一般如下几步:
    • 实例化模型
    • 加载模型参数
    • 根据需要切换模型状态
  • 具体的加载方法如下:
# 模型预测
import os
import time
import paddle# 从模型代码中导入模型
from u2net import U2NETP# 实例化模型
model = U2NETP()# 加载预训练模型参数
model.set_dict(paddle.load([path to the pretrained model]))# 将模型设置为评估状态
model.eval()# 准备模型输入
x = paddle.randn([1, 3, 320, 320])# 模型预测
d0, _, _, _, _, _, _ = model(x)# 打印输出的形状
print(d0.shape)
[1, 1, 320, 320]
# 计算预测时间
start = time.time()
out = model(x)
end = time.time()
print('predict time: %.04f s' % (end - start))
predict time: 2.3866 s

模型动转静

  • 在Paddle2.0中,通过paddle.jit.to_static即可快速的将模型转换为静态图模型
  • 只需要简单的加上几行代码,就能完成转换
  • 而且转换之后可以直接像使用动态图模型那样使用
  • 不仅非常方便,而且运行速度也会有一定的提升
  • 具体的转换代码如下:
# 定义输入数据
input_spec = paddle.static.InputSpec(shape=[None, 3, 320, 320], dtype='float32', name='image')# 动态图转静态图
model = paddle.jit.to_static(model, input_spec=[input_spec])# 模型预测
d0, _, _, _, _, _, _ = model(x)# 打印输出的形状
print(d0.shape)
[1, 1, 320, 320]
# 计算预测时间
start = time.time()
out = model(x)
end = time.time()
print('predict time: %.04f s' % (end - start))
predict time: 1.9833 s

静态图模型保存

  • 除了直接使用转换完成的静态图模型之外
  • 当然也是可以将转换后的模型进行保存的
  • 保存的方法也非常简单,只需要调用Paddle.jit.save()即可
  • 存储的模型结构如下:
    • .pdmodel:Program 文件
    • .pdiparams:存储的持久参数变量文件
    • .pdiparams.info 存储一些变量描述信息至文件,这些额外的信息将在fine-tune训练中使用
  • 保存的代码如下:
# 保存推理模型
paddle.jit.save(model, [path to the save model])# 打印保存的模型文件名
print(os.listdir([save dir]))
['u2netp.pdiparams.info', 'u2netp.pdiparams', 'u2netp.pdmodel']

模型可视化

  • 通过VisualDL工具可以轻松的进行模型结构的可视化查看
  • 选择刚才保存后缀为.pdmodel的模型文件
  • 具体的可视化图像就像下图所示的那样:

静态图模型加载

  • 加载这样的保存的模型也是非常简单的
  • 只需要使用Paddle.jit.load()即可进行模型加载
  • 代码如下:
model = paddle.jit.load([path to the save model])
model.eval()# 模型预测
# 作为演示这里使用随机数作为输入
d0, _, _, _, _, _, _ = model(x)# 打印输出的形状
print(d0.shape)
[1, 1, 320, 320]
# 计算预测时间
start = time.time()
out = model(x)
end = time.time()
print('predict time: %.04f s' % (end - start))
predict time: 1.9530 s

PaddleInference预测部署

  • 导出的推理模型也可以使用PaddleInference高性能推理引擎来进行预测部署
  • 在CPU平台下还可以手动开启MKLDNN进行加速,效率将进一步提高
  • 下面就通过PaddleQuickInference进行快速部署
  • 更多详情请参考我的另一个项目:PaddleQuickInference
# 安装PaddleQuickInference
$ pip install ppqi
# 不启用MKLDNN加速
import numpy as np
from ppqi import InferenceModelmodel = InferenceModel(modelpath=[path to the save model], use_gpu=False, use_mkldnn=False
)
model.eval()x = np.random.randn(1, 3, 320, 320).astype('float32')d0, _, _, _, _ ,_, _ = model(x)# 打印输出的形状
print(d0.shape)
(1, 1, 320, 320)
# 计算预测时间
start = time.time()
out = model(x)
end = time.time()
print('predict time: %.04f s' % (end - start))
predict time: 1.8739 s
# 启用MKLDNN加速
model = InferenceModel(modelpath=[path to the save model], use_gpu=False, use_mkldnn=True
)
model.eval()d0, _, _, _, _ ,_, _ = model(x)# 打印输出的形状
print(d0.shape)
(1, 1, 320, 320)
# 计算预测时间
start = time.time()
out = model(x)
end = time.time()
print('predict time: %.04f s' % (end - start))
predict time: 0.5673 s

部署实例

  • 接下来通过加入数据预处理和后处理来完成完整的模型推理部署
import cv2
import time
import numpy as np
import matplotlib.pyplot as pltfrom ppqi import InferenceModel
from processor import preprocess, postprocess# 输入输出设置
img_path = [path to the input image]
output_dir = [output dir]# 数据预处理
img = preprocess(img_path)# 加载模型
model = InferenceModel(modelpath=[path to the save model], use_gpu=False, use_mkldnn=True
)
model.eval()# 模型推理
start = time.time()
d0, _, _, _, _ ,_, _ = model(img)
end = time.time()
print('predict time: %.04f s' % (end - start))# 结果后处理
mask_path, result_path = postprocess(d0, img_path, output_dir)# 图像显示
img = np.concatenate([cv2.imread(img_path),cv2.imread(mask_path),cv2.imread(result_path)
], 1)
plt.axis('off')
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
predict time: 0.7955 s

总结

  • 通过简单增加几行代码就可以将动态图模型转换为静态图模型
  • 在运行效率上静态图的效率在大多数情况下会好于动态图
  • 导出的推理模型也可以很方便的进行推理部署
  • 当然目前动转静功能还不是特别的成熟,可能会出现一些bug
  • 总之体验还不错,希望这个功能未来能越来越好

Paddle2.0:使用动转静完成模型部署相关推荐

  1. 【基于 docker 的 Flask 的深度学习模型部署】

    文章目录 1.前言 2.docker简介 3.基于Falsk的REST API实现 4.编写dockerfile 5.基于docker的模型部署 1.前言 模型部署一直是深度学习算法走向落地的重要的一 ...

  2. 体验paddle2.0rc版本API-Model--实现Mnist数据集模型训练

    原文链接:体验paddle2.0rc版本API-Model–实现Mnist数据集模型训练:https://blog.csdn.net/weixin_44604887/article/details/1 ...

  3. html5.0笔记,动易sf5.0标签笔记.doc

    动易sf5.0标签笔记 网站首页标签调用 动易SiteFactory 文章模型标签作者:动易网络 文章来源:灯火 点击数:1617 更新时间:2011-4-16 20:20:52标签名: {PE.La ...

  4. Paddle2.0实现中文新闻文本标题分类

    Paddle2.0实现中文新闻文本标题分类 中文新闻文本标题分类Paddle2.0版本基线(非官方) 调优小建议 数据集地址 任务描述 数据说明 提交答案 代码思路说明 数据集解压 数据处理 数据读取 ...

  5. Paddle2.0实现PSPNet进行人体解析(图像分割)

    Paddle2.0实现PSPNet进行人体解析(图像分割) 项目背景 概述 前言 PSPNet介绍 为什么会提出PSPNet ? PSPNet 的效果为什么好 ? PSPNet 是怎样考虑上下文信息的 ...

  6. Paddle2.0 + CPM-LM:让AI帮你写文章吧

    引入 之前的两个项目分别介绍了GPT-2模型的构建,和如何使用GPT-2加载CPM模型实现问答机器人 由于之前项目所使用的解码方式为Greedy_Search,生成的文本固定且单一,并不适合与写作类型 ...

  7. 从0开始建立车辆仿真模型 – 车辆轮胎模型的建立

    从0开始建立车辆仿真模型 – 车辆轮胎模型的建立 本来还想继续把MBD有关代码生成的开发的细节再讲讲,后来我的"产品经理"炸了,开始催更物理模型的文章了,那就先来说说物理模型的话题 ...

  8. paddle2.0高层API实现自定义数据集文本分类中的情感分析任务

    paddle2.0高层API实现自定义数据集文本分类中的情感分析任务 本文包含了: - 自定义文本分类数据集继承 - 文本分类数据处理 - 循环神经网络RNN, LSTM - ·seq2vec· - ...

  9. paddle2.0高层API实现人脸关键点检测(人脸关键点检测综述_自定义网络_paddleHub_趣味ps)

    paddle2.0高层API实现人脸关键点检测(人脸关键点检测综述_自定义网络_paddleHub_趣味ps) 本文包含了: - 人脸关键点检测综述 - 人脸关键点检测数据集介绍以及数据处理实现 - ...

最新文章

  1. php定界符EOF讲解
  2. 分享一款颜色神器ColorSchemer Studio
  3. MySQL的高级运用_MYSQL之SQL高级运用(帮助你高效率编程)
  4. Android利用RecognizerIntent识别语音并简单实现打电话动作
  5. [C++11]继承构造函数
  6. Spring Boot微服务,Docker和Kubernetes研讨会–第2部分
  7. SVN 回滚(撤回)提交的代码
  8. Java虚拟机学习总结(1)——JVM内存模型
  9. [转载]Windows 2012 R2安装SharePoint 2013 手动安装工具软件
  10. windows之解决VMware虚拟机经常性卡死
  11. valgrind 报告 ecpg内存泄露 (二)
  12. 计算机项目答辩评分标准,课题答辩评分标准是什么
  13. PT100热敏电阻原理解析
  14. 戴尔 OptiPlex 3020重新安装win10系统的教程
  15. 用原生JS和CSS3做一个有趣的cube相册
  16. 在CentOS 8 下yum install curl时报错
  17. Vue + DataV + SignalR 数字化大屏展示
  18. CSS 选择器 CSS3选择器
  19. JAVA获取前一个月的第一天和最后一天
  20. 【Javascript】javascript 中的指针

热门文章

  1. Squid代理缓存服务器
  2. 五分钟学GIS | 室内导航
  3. ios测试续航软件,7款iPhone测试iOS14.5电池续航:这2款iPhone别升级了
  4. 由浅入深玩转华为WLAN—-5 AP上线与对接交换机接口配置注意事项
  5. Makefile:wildcard 、notdir和patsubst用法
  6. 新年、新气象,新计划、新打算
  7. impress.js
  8. 作为软件工程师你应该知道的100件事(上)
  9. 【“赤裸裸展现”时代下如何保障网上隐私?】
  10. 鲸鱼优化算法(Whale Optimization Algorithm,WOA)