本文手把手教你将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
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:

  1. 上文所提两文件均在/home/aistudio目录下,读者可自行下载进行实验
  2. 如果你需要转换自己的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. 将1处导入模型替换为自己的模型

  2. 将输入大小的shape替换为自己模型的输入大小shape

  3. 按需传入模型参数

  4. 将路径修改为你的模型参数的位置

  5. 修改输出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程序,看看模型的推理结果是否如预期。

In[1]
cd ./pd_model/
/home/aistudio/pd_model
In[3]
import zipfile
tar = zipfile.ZipFile('/home/aistudio/pd_model/model_with_code_zip.zip','r')
tar.extractall()
In[4]
cd ./model_with_code/
/home/aistudio/pd_model/model_with_code
In[5]
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)
In[6]
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
In[7]
#模型推理函数
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
In[8]
#将标签为32的图片进行预处理
img = process_img("/home/aistudio/n02085782_1039.jpg")
In[9]
#用PaddlePaddle模型推理图片标签
pred_label, pred_score = inference(img)
In[10]
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 官网,了解更多相关内容   

09-05 01:36