{ "cells": [ { "cell_type": "markdown", "source": [ "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_notebook.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/master/golden_stick/zh_cn/deployment/mindspore_convert.ipynb) [![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_download_code.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/master/golden_stick/zh_cn/deployment/mindspore_convert.py) [![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/master/resource/_static/logo_source.svg)](https://gitee.com/mindspore/docs/blob/master/docs/golden_stick/docs/source_zh_cn/deployment/convert.ipynb)" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "source": [ "# 使用MindSpore Golden Stick进行模型转换\n", "\n", "有三种方式可以进行模型转换导出MindIR:\n", "\n", "1. 训练后导出MindIR;\n", "2. 从ckpt导出MindIR;\n", "3. 训练前配置算法自动导出MindIR。" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 必要前提\n", "\n", "首先下载数据集并构建Lenet网络,同时为了演示方便,我们实现了一个最简单的金箍棒算法,名为FooAlgo。" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "pycharm": { "is_executing": true } }, "outputs": [], "source": [ "import os\n", "import numpy as np\n", "from download import download\n", "\n", "import mindspore\n", "from mindspore import nn, Model, Tensor, export\n", "from mindspore.train import Accuracy\n", "from mindspore.train.callback import ModelCheckpoint\n", "import mindspore.dataset as ds\n", "import mindspore.dataset.vision as vision\n", "import mindspore.dataset.transforms as transforms\n", "from mindspore.dataset.vision import Inter\n", "from mindspore import dtype as mstype\n", "from mindspore.common.initializer import Normal\n", "from mindspore_gs import CompAlgo\n", "\n", "# Download data from open datasets\n", "url = \"https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/\" \\\n", " \"notebook/datasets/MNIST_Data.zip\"\n", "path = download(url, \"./\", kind=\"zip\", replace=True)\n", "\n", "def create_dataset(data_path, batch_size=32, num_parallel_workers=1):\n", " \"\"\"\n", " create dataset for train or test\n", " \"\"\"\n", " # define dataset\n", " mnist_ds = ds.MnistDataset(data_path)\n", "\n", " resize_height, resize_width = 32, 32\n", " rescale = 1.0 / 255.0\n", " rescale_nml = 1 / 0.3081\n", " shift_nml = -1 * 0.1307 / 0.3081\n", "\n", " # define map operations\n", " resize_op = vision.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) # Bilinear mode\n", " rescale_nml_op = vision.Rescale(rescale_nml * rescale, shift_nml)\n", " hwc2chw_op = vision.HWC2CHW()\n", " type_cast_op = transforms.TypeCast(mstype.int32)\n", "\n", " # apply map operations on images\n", " mnist_ds = mnist_ds.map(operations=type_cast_op, input_columns=\"label\", num_parallel_workers=num_parallel_workers)\n", " mnist_ds = mnist_ds.map(operations=resize_op, input_columns=\"image\", num_parallel_workers=num_parallel_workers)\n", " mnist_ds = mnist_ds.map(operations=rescale_nml_op, input_columns=\"image\", num_parallel_workers=num_parallel_workers)\n", " mnist_ds = mnist_ds.map(operations=hwc2chw_op, input_columns=\"image\", num_parallel_workers=num_parallel_workers)\n", "\n", " # apply DatasetOps\n", " mnist_ds = mnist_ds.shuffle(buffer_size=1024)\n", " mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)\n", "\n", " return mnist_ds\n", "\n", "train_dataset = create_dataset(\"MNIST_Data/train\", 32, 1)\n", "print(\"train dataset output shape: \", train_dataset.output_shapes())\n", "\n", "# initial network\n", "class LeNet5(nn.Cell):\n", " def __init__(self, num_class=10, num_channel=1, include_top=True):\n", " super(LeNet5, self).__init__()\n", " self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')\n", " self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')\n", " self.relu = nn.ReLU()\n", " self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)\n", " self.include_top = include_top\n", " if self.include_top:\n", " self.flatten = nn.Flatten()\n", " self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02))\n", " self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02))\n", " self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02))\n", "\n", "\n", " def construct(self, x):\n", " x = self.conv1(x)\n", " x = self.relu(x)\n", " x = self.max_pool2d(x)\n", " x = self.conv2(x)\n", " x = self.relu(x)\n", " x = self.max_pool2d(x)\n", " if not self.include_top:\n", " return x\n", " x = self.flatten(x)\n", " x = self.relu(self.fc1(x))\n", " x = self.relu(self.fc2(x))\n", " x = self.fc3(x)\n", " return x\n", "\n", "\n", "# set graph mode\n", "mindspore.set_context(mode=mindspore.GRAPH_MODE)\n", "\n", "# for demonstration convenience, we implemented one simplest MindSpore Golden Stick algorithm, called FooAlgo\n", "class FooAlgo(CompAlgo):\n", " def apply(self, network: nn.Cell) -> nn.Cell:\n", " return network\n", "\n", "print(\"init ok.\")" ] }, { "cell_type": "markdown", "source": [ "```python\n", "train dataset output shape: [[32, 1, 32, 32], [32]]\n", "init ok.\n", "```" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 训练后导出MindIR\n", "\n", "MindSpore Golden Stick各种算法均提供统一的 `convert` 接口对网络进行模型转换,转换后的网络使用 `mindspore.export` 接口导出MindIR。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "## 1) Create network and dataset.\n", "network = LeNet5(10)\n", "train_dataset = create_dataset(\"MNIST_Data/train\", 32, 1)\n", "## 2) Create an algorithm instance.\n", "algo = FooAlgo()\n", "## 3) Apply MindSpore Golden Stick algorithm to origin network.\n", "network_opt = algo.apply(network)\n", "## 4) Set up Model.\n", "net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction=\"mean\")\n", "net_opt = nn.Momentum(network_opt.trainable_params(), 0.01, 0.9)\n", "model = Model(network_opt, net_loss, net_opt, metrics={\"Accuracy\": Accuracy()})\n", "cbs = [ModelCheckpoint(prefix='network', directory='ckpt/')]\n", "## 5) Config callback in model.train, start training.\n", "cbs.extend(algo.callbacks())\n", "model.train(1, train_dataset, callbacks=cbs)\n", "## 6) Convert network.\n", "net_deploy = algo.convert(network_opt)\n", "## 7) Export MindIR\n", "inputs = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32)) # user define\n", "export(net_deploy, inputs, file_name=\"net_1.mindir\", file_format=\"MINDIR\")\n", "## 8) Test MindIR\n", "file_path = \"./net_1.mindir\"\n", "file_path = os.path.realpath(file_path)\n", "if not os.path.exists(file_path):\n", " print(\"Export MindIR failed!!!\")\n", "else:\n", " print(\"Export MindIR success! MindIR path is: \", file_path)\n", "test_inputs = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32))\n", "graph = mindspore.load(file_path)\n", "net = nn.GraphCell(graph)\n", "output = net(test_inputs)\n", "print(\"Test output MindIR success, result shape is: \", output.shape)" ] }, { "cell_type": "markdown", "source": [ "```python\n", "Export MindIR success! MindIR path is: /home/workspace/golden_stick/net_1.mindir\n", "Test output MindIR success, result shape is: (32, 10)\n", "```" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "source": [ "## 从ckpt导出\n", "\n", "使用训练后得到的ckpt文件,调用 `convert` 和 `mindspore.export` 接口导出MindIR。\n", "\n", "> 请先运行上一节示例代码,此小节需用到上节训练生成的ckpt文件。" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "## 1) Create network and dataset.\n", "network = LeNet5(10)\n", "train_dataset = create_dataset(\"MNIST_Data/train\", 32, 1)\n", "## 2) Create an algorithm instance.\n", "algo = FooAlgo()\n", "## 3) Apply MindSpore Golden Stick algorithm to origin network.\n", "network_opt = algo.apply(network)\n", "## 4) Convert network.\n", "net_deploy = algo.convert(network_opt, ckpt_path=\"ckpt/network-1_1875.ckpt\") # ckpt from previous section\n", "## 5) Export MindIR\n", "inputs = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32)) # user define\n", "export(net_deploy, inputs, file_name=\"net_2.mindir\", file_format=\"MINDIR\")\n", "## 6) Test MindIR\n", "file_path = \"./net_2.mindir\"\n", "file_path = os.path.realpath(file_path)\n", "if not os.path.exists(file_path):\n", " print(\"Export MindIR failed!!!\")\n", "else:\n", " print(\"Export MindIR success! MindIR path is: \", file_path)\n", "test_inputs = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32))\n", "graph = mindspore.load(file_path)\n", "net = nn.GraphCell(graph)\n", "output = net(test_inputs)\n", "print(\"Test output MindIR success, result shape is: \", output.shape)" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "source": [ "```python\n", "Export MindIR success! MindIR path is: /home/workspace/golden_stick/net_2.mindir\n", "Test output MindIR success, result shape is: (32, 10)\n", "```" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "source": [ "## 配置算法自动导出MindIR\n", "\n", "在训练前配置算法`set_save_mindir` 接口,在训练后自动生成MindIR。\n", "\n", "> a) 此种方式生成的MindIR在推理时,模型的输入shape需与训练时输入的数据集shape保持一致。\n", ">\n", "> b) 配置算法自动导出MindIR有两个必要的操作,`set_save_mindir(True)` 及在 `model.train` 中配回调函数时加入算法回调函数 `callbacks=algo.callbacks()` 。MindIR输出路径 `save_mindir_path` 若未配置则默认保存为 `./network.mindir` 。" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "## 1) Create network and dataset.\n", "network = LeNet5(10)\n", "train_dataset = create_dataset(\"MNIST_Data/train\", 32, 1)\n", "## 2) Create an algorithm instance.\n", "algo = FooAlgo()\n", "## 3) Enable automatically export MindIR after training.\n", "algo.set_save_mindir(save_mindir=True)\n", "## 4) Set MindIR output path, the default value for the path is 'network.mindir'.\n", "algo.set_save_mindir_path(save_mindir_path=\"net_3.mindir\")\n", "## 5) Apply MindSpore Golden Stick algorithm to origin network.\n", "network_opt = algo.apply(network)\n", "## 6) Set up Model.\n", "net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction=\"mean\")\n", "net_opt = nn.Momentum(network_opt.trainable_params(), 0.01, 0.9)\n", "model = Model(network_opt, net_loss, net_opt, metrics={\"Accuracy\": Accuracy()})\n", "## 7) Config callback in model.train, start training, then MindIR will be exported.\n", "model.train(1, train_dataset, callbacks=algo.callbacks())\n", "## 8) Test MindIR\n", "file_path = \"./net_3.mindir\"\n", "file_path = os.path.realpath(file_path)\n", "if not os.path.exists(file_path):\n", " print(\"Export MindIR failed!!!\")\n", "else:\n", " print(\"Export MindIR success! MindIR path is: \", file_path)\n", "test_inputs = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32))\n", "graph = mindspore.load(file_path)\n", "net = nn.GraphCell(graph)\n", "output = net(test_inputs)\n", "print(\"Test output MindIR success, result shape is: \", output.shape)" ], "metadata": { "collapsed": false } }, { "cell_type": "markdown", "source": [ "```python\n", "Export MindIR success! MindIR path is: /home/workspace/golden_stick/net_3.mindir\n", "Test output MindIR success, result shape is: (32, 10)\n", "```" ], "metadata": { "collapsed": false } } ], "metadata": { "kernelspec": { "display_name": "Python 3.7.5 ('mindspore')", "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.5" }, "vscode": { "interpreter": { "hash": "8c9da313289c39257cb28b126d2dadd33153d4da4d524f730c81a4aaccbd2ca7" } } }, "nbformat": 4, "nbformat_minor": 4 }