diff --git a/docs/demo/dog_pt.png b/docs/demo/dog_pt.png new file mode 100644 index 0000000000000000000000000000000000000000..0be6b24e6d349029454696699721cf75ae578799 Binary files /dev/null and b/docs/demo/dog_pt.png differ diff --git a/docs/demo/dog_tf.png b/docs/demo/dog_tf.png new file mode 100644 index 0000000000000000000000000000000000000000..b6bce931d80f5ef6a3cf43531bef5f8673921f8b Binary files /dev/null and b/docs/demo/dog_tf.png differ diff --git a/docs/demo/pytorch2paddle.ipynb b/docs/demo/pytorch2paddle.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..c234f6103276ea788e6a4dcc67ef4f0da858c030 --- /dev/null +++ b/docs/demo/pytorch2paddle.ipynb @@ -0,0 +1,250 @@ +{ + "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 +} diff --git a/docs/demo/tensorflow2paddle.ipynb b/docs/demo/tensorflow2paddle.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..e9d4d0797ff86b94cf86a60a4048a36776674e16 --- /dev/null +++ b/docs/demo/tensorflow2paddle.ipynb @@ -0,0 +1,213 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# X2Paddle快速上手——TensorFlow迁移至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", + "本教程用于帮助用户学习将TensorFlow训练后的预测模型迁移至PaddlePaddle框架,以TensorFlow版本的[MobileNetV1](https://github.com/tensorflow/models/tree/master/research/slim)为例进行详细介绍。 \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. 安装TensorFlow" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! pip install tensorflow==1.14.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. 获取MobileNetV1的FrozenModel\n", + "由于X2Paddle只支持TensorFlow中FrozenModel的转换,如果为纯checkpoint模型,需要参考参考X2Paddle官方[文档](https://github.com/PaddlePaddle/X2Paddle/blob/develop/docs/user_guides/export_tf_model.md),将其转换为FrozenModel,本示例中提供的模型为FrozenModel,所以无需转换。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! wget http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_0.25_128.tgz\n", + "! tar zxvf mobilenet_v1_0.25_128.tgz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. 转换\n", + "需要传入的参数如下:\n", + "> --framework (-f):源模型类型,此处设置为tensorflow。 \n", + "> --save_dir (-s):指定转换后的模型保存目录路径。 \n", + "> --model (-m):指定tensorflow的pb模型。 \n", + "> --paddle_type (-pt):指定转换为动态图代码(dygraph)或者静态图代码(static),默认为dygraph。 \n", + "\n", + "***方式一:***生成静态图代码,并保存成静态图预测模型" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! x2paddle -f tensorflow -m ./mobilenet_v1_0.25_128_frozen.pb -s pd_model_static -pt static" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "***方式二:***生成动态图代码,并保存成静态图预测模型\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "! x2paddle -f tensorflow -m ./mobilenet_v1_0.25_128_frozen.pb -s pd_model_dygraph -pt dygraph" + ] + }, + { + "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": [ + "# 构造输入\n", + "import cv2\n", + "import numpy as np\n", + "img = cv2.imread(\"dog_tf.png\").astype(\"float32\") / 255.0\n", + "img = np.expand_dims(img, 0)\n", + "img -= 0.5\n", + "img *= 2.0\n", + " \n", + "# 进行预测\n", + "import paddle\n", + "import numpy as np\n", + "paddle.enable_static()\n", + "exe = paddle.static.Executor(paddle.CPUPlace())\n", + "[prog, inputs, outputs] = paddle.static.load_inference_model(path_prefix=\"pd_model_static/inference_model\", \n", + " executor=exe, \n", + " model_filename=\"model.pdmodel\",\n", + " params_filename=\"model.pdiparams\")\n", + "result = exe.run(prog, feed={inputs[0]: img}, fetch_list=outputs)\n", + "max_index = np.argmax(result[0])\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": "all", + "language": "python", + "name": "all" + }, + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}