“深度学习有趣但艰难”
目录
动态图与静态图的区别
从形式上,飞桨的动态图模型与静态图模型的后缀就不一样,动态图模型的后缀为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")
# 保存到指定目录下
# paddlex的动转静有点不一样
import paddle
from paddle.jit import to_static
from paddle.static import InputSpec
model = pdx.load_model('output/mobilenetv3_large_ssld2/best_model')
# params = paddle.load('output/mobilenetv3_large_ssld2/best_model/model.pdparams')
# model.set_state_dict(params)
net = to_static(model, input_spec=[InputSpec(shape=[None, 3, 224, 224])])
paddle.jit.save(net,"inference_model/mover")
静态图模型部署
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)]]