{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# X2Paddle快速上手——PyTorch迁移至PaddlePaddle\n", "***X2Paddle简介***:X2Paddle支持将Caffe/TensorFlow/ONNX/PyTorch深度学习框架训练得到的模型,迁移至PaddlePaddle模型。 \n", "***X2Paddle代码GitHub链接***:[https://github.com/PaddlePaddle/X2Paddle](https://github.com/PaddlePaddle/X2Paddle) \n", "***【注意】***前往GitHub给[X2Paddle](https://github.com/PaddlePaddle/X2Paddle)点击Star,关注项目,即可随时了解X2Paddle的最新进展。 \n", "本教程用于帮助用户学习将PyTorch训练后的预测模型迁移至PaddlePaddle框架,以PyTorch版本的[AlexNet](https://github.com/pytorch/vision/blob/master/torchvision/models/alexnet.py)为例进行详细介绍。 \n", "\n", "## 安装及准备\n", "### 1. 安装X2Paddle\n", "***方式一:(推荐)***" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "! git clone https://github.com/PaddlePaddle/X2Paddle.git\n", "! cd X2Paddle\n", "! git checkout develop\n", "! python setup.py install" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***方式二:***" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "! pip install x2paddle==1.0.1 --index https://pypi.Python.org/simple/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. 安装PyTorch" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "! pip install torch==1.6.0 torchvision==0.7.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3. 安装PaddlePaddle" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "! pip install paddlepaddle==2.0.1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 模型迁移\n", "### 1. 获取AlexNet模型" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from torchvision.models import AlexNet\n", "from torchvision.models.utils import load_state_dict_from_url\n", "\n", "torch_model = AlexNet()\n", "torch_state_dict = load_state_dict_from_url('https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth')\n", "torch_model.load_state_dict(torch_state_dict)\n", "torch_model.eval()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. 转换\n", "PyTorch到PaddlePaddle的转换需要传入输入的示例,才可以进行转换,以下为构建输入的过程(输入也可为值随机初始化的Tensor):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from PIL import Image\n", "img = Image.open(\"dog_pt.png\")\n", "img = np.array(img).astype(\"float32\") / 255.0\n", "img -= [0.485, 0.456, 0.406]\n", "img /= [0.229, 0.224, 0.225]\n", "img = np.transpose(img, (2, 0, 1))\n", "img = np.expand_dims(img, 0)\n", "\n", "import torch\n", "input_tensor = torch.tensor(img)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***方式一:*** Trace方式 \n", "模型输入的shape固定,PyTorch模型基本均支持此方式转换。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from x2paddle.convert import pytorch2paddle\n", "save_dir = \"pd_model_trace\"\n", "jit_type = \"trace\"\n", "pytorch2paddle(module=torch_model, \n", " save_dir=save_dir, \n", " jit_type=jit_type, \n", " input_examples=[input_tensor])\n", "# module (torch.nn.Module): PyTorch的Module。\n", "# save_dir (str): 转换后模型的保存路径。\n", "# jit_type (str): 转换方式,此时为\"trace\"。\n", "# input_examples (list[torch.tensor]): torch.nn.Module的输入示例,list的长度必须与输入的长度一致。默认为None。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***方式二:*** Script方式 \n", "模型输入的shape可不固定,由于PyTorch的Script方式可识别的代码格式有限,所以PyTorch模型在此方式下转换的支持度较低。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from x2paddle.convert import pytorch2paddle\n", "save_dir = \"pd_model_script\"\n", "jit_type = \"script\"\n", "pytorch2paddle(module=torch_model, \n", " save_dir=save_dir, \n", " jit_type=jit_type, \n", " input_examples=[input_tensor])\n", "# module (torch.nn.Module): PyTorch的Module。\n", "# save_dir (str): 转换后模型的保存路径。\n", "# jit_type (str): 转换方式,此时为\"script\"。\n", "# input_examples (list[torch.tensor]): torch.nn.Module的输入示例,list的长度必须与输入的长度一致。默认为None。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## PaddlePaddle模型使用\n", "使用方式一转换的PaddlePaddle预测模型进行预测: \n", "(1)下载ImageNet类别文件" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "! wget https://raw.githubusercontent.com/Lasagne/Recipes/master/examples/resnet50/imagenet_classes.txt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(2)预测" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import paddle\n", "paddle.enable_static()\n", "exe = paddle.static.Executor(paddle.CPUPlace())\n", "[prog, inputs, outputs] = paddle.static.load_inference_model(path_prefix=\"pd_model_trace/inference_model\", \n", " executor=exe, \n", " model_filename=\"model.pdmodel\",\n", " params_filename=\"model.pdiparams\")\n", "print(img.shape)\n", "result = exe.run(prog, feed={inputs[0]: img}, fetch_list=outputs)\n", "max_index = np.argmax(result)\n", "with open('imagenet_classes.txt') as f:\n", " classes = [line.strip() for line in f.readlines()]\n", "print(\"The category of dog.jpg is: {}\".format(classes[max_index]))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 4 }