本文手把手教你将pytorch模型转换为PaddlePaddle模型,并提供了PaddlePaddle模型使用使用实例。
下载安装命令 ## CPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle ## GPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu
本项目适合以下人群:
- 已有pytorch模型却苦于没有算力运行的你
- 希望快速将pytorch工程迁移为PaddlePaddle的你
- 希望快速使用PaddlePaddle又不想重现训练模型的你
- 垂涎aitduio的V100已久却不想花太多时间学习PaddlePaddle细节的你
1.将pytorch模型转换为PaddlePaddle模型
将pytorch模型转换为PaddlePaddle模型需要先把把pytorch转换为onnx模型,然后转换为PaddlePaddle模型。
note:由于aistudio不支持pytorch,你需要在本地完成此转换过程。
1.1 依赖库
在实践下述代码前,你需要确保本地环境满足以下依赖库:
- torch
- oxnn
pip install onnx==1.6.0
- onnxruntime
pip install onnxruntime==1.0.0
- paddlepaddle >= 1.6.0
- X2Paddle
git clone https://github.com/PaddlePaddle/X2Paddle.git
cd X2Paddle
git checkout develop
python setup.py install
1.2 实验环境:
本文所用pytorch模型为nasnetamobile ,用迁移训练在Stanford Dogs数据集全集上训练20个epochs所得。
- pytorch模型定义文件,本文采用nasnet_mobile.py
- pytorch模型参数,本文中所用为nasnet_mobile.pkl
note:
- 上文所提两文件均在/home/aistudio目录下,读者可自行下载进行实验
- 如果你需要转换自己的pytorch模型同样也需要提供模型定义文件和模型参数文件。
1.3 实验步骤:
实验步骤为先把pytorch转换为onnx模型,然后转换为PaddlePaddle模型。
1.3.1 把pytorch模型转换为onnx模型
定义一个py文件名为trans.py,具体代码如下:
#coding: utf-8
import torch
#import torchvision
# 1.导入pytorch模型定义
from nasnet_mobile import nasnetamobile
# 2.指定输入大小的shape
dummy_input = torch.randn(1, 3, 224, 224)
# 3. 构建pytorch model
model = nasnetamobile(121,pretrained=False)
# 4. 载入模型参数
model.load_state_dict(torch.load('/home/aistudio/data/data23875/nasnet_mobile.pkl', map_location='cpu'))
# 5.导出onnx模型文件
torch.onnx.export(model, dummy_input, "nasnet.onnx",verbose=True)
note:如果你想转换自己的模型,在此需要修改:(分别对应代码中5处注释)
-
将1处导入模型替换为自己的模型
-
将输入大小的shape替换为自己模型的输入大小shape
-
按需传入模型参数
-
将路径修改为你的模型参数的位置
-
修改输出onnx模型的名称
在本地终端中输入:
python trans.py
所转换的onnx模型存放在当前目录。
1.3.2 将onnx模型转换为PaddlePaddle模型
在本地终端输入以下代码:
x2paddle --framework=onnx --model=nasnet.onnx --save_dir=pd_model
最终的PaddlePaddle模型存放在pd_model目录。
pd_model目录下有两个文件夹
-->inference_model 只存放了模型参数。
-->model_with_code 不仅存放了模型参数,还生成了模型定义。
2. 转换所得PaddlePaddle模型应用示例
下面我们用一张图片看看转换所得PaddlePaddle模型是否可以正常运行。
我们有以下文件:
-->/home/aistudio/n02085782_1039.jpg 一张小狗的图片,类别标签为32
-->/home/aistudio/pd_model/model_with_code 转换所得Paddle模型的参数与模型定义(此部分为我在本地转换后上传)
note :为将图片以参数形式传入模型,/home/aistudio/pd_model/model_with_code/model.py中需修改两处.
5)def x2paddle_net():
修改为def x2paddle_net(input):
8)x2paddle_input_1 = fluid.layers.data(dtype='float32', shape=[1, 3, 224, 224], name='x2paddle_input_1', append_batch_size=False)
修改为x2paddle_input_1 = input
下面我们开始构建Paddle程序,看看模型的推理结果是否如预期。
cd ./pd_model/
/home/aistudio/pd_model
import zipfile
tar = zipfile.ZipFile('/home/aistudio/pd_model/model_with_code_zip.zip','r')
tar.extractall()
cd ./model_with_code/
/home/aistudio/pd_model/model_with_code
import argparse
import functools
import numpy as np
import paddle.fluid as fluid
from model import x2paddle_net
use_gpu=True
######Attack graph
adv_program=fluid.Program()
#完成初始化
with fluid.program_guard(adv_program):
input_layer = fluid.layers.data(name='image', shape=[3,224,224], dtype='float32')
#设置为可以计算梯度
input_layer.stop_gradient=False
# model definition
_,out_logits = x2paddle_net(input=input_layer)
out = fluid.layers.softmax(out_logits[0])
place = fluid.CUDAPlace(0) if use_gpu else fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
#记载模型参数
fluid.io.load_persistables(exe, "./")
#创建测试用评估模式
eval_program = adv_program.clone(for_test=True)
import cv2
#定义一个预处理图像的函数
def process_img(img_path="",image_shape=[3,224,224]):
mean = [0.485, 0.456, 0.406]
std = [0.229, 0.224, 0.225]
img = cv2.imread(img_path)
img = cv2.resize(img,(image_shape[1],image_shape[2]))
#img = cv2.resize(img,(256,256))
#img = crop_image(img, image_shape[1], True)
#RBG img [224,224,3]->[3,224,224]
img = img[:, :, ::-1].astype('float32').transpose((2, 0, 1)) / 255
#img = img.astype('float32').transpose((2, 0, 1)) / 255
img_mean = np.array(mean).reshape((3, 1, 1))
img_std = np.array(std).reshape((3, 1, 1))
img -= img_mean
img /= img_std
img=img.astype('float32')
img=np.expand_dims(img, axis=0)
return img
#模型推理函数
def inference(img):
fetch_list = [out.name]
result = exe.run(eval_program,
fetch_list=fetch_list,
feed={ 'image':img })
result = result[0][0]
pred_label = np.argmax(result)
pred_score = result[pred_label].copy()
return pred_label, pred_score
#将标签为32的图片进行预处理
img = process_img("/home/aistudio/n02085782_1039.jpg")
#用PaddlePaddle模型推理图片标签
pred_label, pred_score = inference(img)
print("预测图片{}的标签为{}".format("/home/aistudio/n02085782_1039.jpg",pred_label))
预测图片/home/aistudio/n02085782_1039.jpg的标签为32
可见模型可以如期推理出标签,那么我们的转换大功告成,接下来就可以在aistidio平台愉快的用所转换的模型做各种下游任务了。
在最后做一点小小的宣传,我是西安电子科技大学在读研究生,感兴趣的领域包括模型压缩,对抗样本,知识图谱。欢迎交流关注。来AI Studio互粉吧~等你哦~
使用AI Studio一键上手实践项目吧https://aistudio.baidu.com/aistudio/projectdetail/312508
下载安装命令 ## CPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle ## GPU版本安装命令 pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu
>> 访问 PaddlePaddle 官网,了解更多相关内容。