From 5aae07ed1c4a1d2bac30e269043e1cd5a13281be Mon Sep 17 00:00:00 2001 From: liyanliu Date: Fri, 11 Sep 2020 16:28:18 +0800 Subject: [PATCH] add Chinese and English hub tutorial --- .../source_en/advanced_use/hub_tutorial.md | 181 ++++++++++++++++++ .../source_zh_cn/advanced_use/hub_tutorial.md | 179 +++++++++++++++++ 2 files changed, 360 insertions(+) create mode 100644 tutorials/source_en/advanced_use/hub_tutorial.md create mode 100644 tutorials/source_zh_cn/advanced_use/hub_tutorial.md diff --git a/tutorials/source_en/advanced_use/hub_tutorial.md b/tutorials/source_en/advanced_use/hub_tutorial.md new file mode 100644 index 0000000000..13e98abd3f --- /dev/null +++ b/tutorials/source_en/advanced_use/hub_tutorial.md @@ -0,0 +1,181 @@ +## Submitting, Loading and Fine-tuning Models using MindSpore Hub + +`Ascend` `GPU` `MindSpore Hub` `Model Submission` `Model Loading` `Model Fine-tuning` `Beginner` `Intermediate` `Expert` + + + +- [Submitting, Loading and Fine-tuning Models using MindSpore Hub](#submitting-loading-and-fine-tuning-models-using-mindspore-hub) + - [Overview](#overview) + - [How to submit models](#how-to-submit-models) + - [Steps](#steps) + - [How to load models](#how-to-load-models) + - [Model Fine-tuning](#model-fine-tuning) + + + + + +### Overview + +For algorithm developers who are interested in publishing models into MindSpore Hub, this tutorial introduces the specific steps to submit models using GoogleNet as an example. It also describes how to load/fine-tune MindSpore Hub models for application developers who aim to do inference/transfer learning on new dataset. In summary, this tutorial helps the algorithm developers submit models efficiently and enables the application developers to perform inference or fine-tuning using MindSpore Hub APIs quickly. + +### How to submit models + +We accept publishing models to MindSpore Hub via PR in `hub` repo. Here we use GoogleNet as an example to list the steps of model submission to MindSpore Hub. + +#### Steps + +1. Host your pre-trained model in a storage location where we are able to access. + +2. Add a model generation python file called `mindspore_hub_conf.py` in your own repo using this [template](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/mindspore_hub_conf.py). + +3. Create a `{model_name}_{model_version}_{dataset}.md` file in `hub/mshub_res/assets` using this [template](https://gitee.com/mindspore/hub/blob/master/mshub_res/assets/mindspore/gpu/0.6/alexnet_v1_cifar10.md). For each pre-trained model, please run the following command to obtain a hash value required at `asset-sha256` of this `.md` file: + + ```python + cd ../tools + python get_sha256.py ../googlenet.ckpt + ``` + +4. Check the format of the markdown file locally using `hub/mshub_res/tools/md_validator.py` by running the following command: + + ```python + python md_validator.py ../assets/mindspore/ascend/0.7/googlenet_v1_cifar10.md + ``` + +5. Create a PR in `mindspore/hub` repo. + +Once your PR is merged into master branch here, your model will show up in [MindSpore Hub Website](https://hub.mindspore.com/mindspore) within 24 hours. For more information, please refer to the [README](https://gitee.com/mindspore/hub/blob/master/mshub_res/README.md). + +### How to load models + +`mindspore_hub.load` API is used to load the pre-trained model in a single line of code. The main process of model loading is as follows: + +- Search the model of interest on [MindSpore Hub Website](https://hub.mindspore.com/mindspore). + + For example, if you aim to perform image classification on CIFAR-10 dataset using GoogleNet, please search on [MindSpore Hub Website](https://hub.mindspore.com/mindspore) with the keyword `GoogleNet`. Then all related models will be returned. Once you enter into the related model page, you can get the website `url`. + +- Complete the task of loading model using `url` , as shown in the example below: + +```python +import mindspore_hub as mshub +import mindspore +from mindspore import context, Tensor, nn +from mindspore.train.model import Model +from mindspore.common import dtype as mstype +from mindspore.dataset.transforms import py_transforms +from PIL import Image +import cv2 + +context.set_context(mode=context.GRAPH_MODE, + device_target="Ascend", + device_id=0) + +model = "mindspore/ascend/0.7/googlenet_v1_cifar10" + +image = Image.open('cifar10/a.jpg') +transforms = py_transforms.ComposeOp([py_transforms.ToTensor()]) + +# Initialize the number of classes based on the pre-trained model. +network = mshub.load(model, num_classes=10) +network.set_train(False) +out = network(transforms(image)) +``` + +### Model Fine-tuning + +When loading a model with `mindspore_hub.load` API, we can add an extra argument to load the feature extraction part of the model only. So we can easily add new layers to perform transfer learning. *This feature can be found in the related model page when an extra argument (e.g., include_top) has been integrated into the model construction by the algorithm engineer.* + +We use Googlenet as example to illustrate how to load a model trained on ImageNet dataset and then perform transfer learning (re-training) on specific sub-task dataset. The main steps are listed below: + +1. Search the model of interest on [MindSpore Hub Website](https://hub.mindspore.com/mindspore) and get the related `url`. + +2. Load the model from MindSpore Hub using the `url`. *Note that the parameter `include_top` is provided by the model developer*. + + ```python + import mindspore + from mindspore import nn + from mindspore import context + import mindspore_hub as mshub + + context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", + save_graphs=False) + + network = mshub.load('mindspore/ascend/0.7/googlenet_v1_cifar10', include_top=False) + network.set_train(False) + ``` + +3. Add a new classification layer into current model architecture. + + ```python + # Check MindSpore Hub website to conclude that the last output shape is 1024. + last_channel = 1024 + + # The number of classes in target task is 26. + num_classes = 26 + classification_layer = nn.Dense(last_channel, num_classes) + classification_layer.set_train(True) + + train_network = nn.SequentialCell([network, classification_layer]) + ``` + +4. Define `loss` and `optimizer` for training. + + ```python + from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits + + # Wrap the backbone network with loss. + loss_fn = SoftmaxCrossEntropyWithLogits() + loss_net = nn.WithLossCell(train_network, loss_fn) + + # Create an optimizer. + optim = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), Tensor(lr), config.momentum, config.weight_decay) + + train_net = nn.TrainOneStepCell(loss_net, optim) + ``` + +5. Create dataset and start fine-tuning. + + ```python + from src.dataset import create_dataset + from mindspore.train.serialization import _exec_save_checkpoint + + dataset = create_dataset("/ssd/data/garbage/train", do_train=True, batch_size=32) + + epoch_size = 15 + for epoch in range(epoch_size): + for i, items in enumerate(dataset): + data, label = items + data = mindspore.Tensor(data) + label = mindspore.Tensor(label) + + loss = train_net(data, label) + print(f"epoch: {epoch}, loss: {loss}") + # Save the ckpt file for each epoch. + ckpt_path = f"./ckpt/garbage_finetune_epoch{epoch}.ckpt" + _exec_save_checkpoint(train_network, ckpt_path) + ``` + +6. Eval on test set. + + ```python + from mindspore.train.serialization import load_checkpoint, load_param_into_net + + network = mshub.load('mindspore/ascend/0.7/googlenet_v1_cifar10', include_top=False) + train_network = nn.SequentialCell([network, nn.Dense(last_channel, num_classes)]) + + # Load a pre-trained ckpt file. + ckpt_path = "./ckpt/garbage_finetune_epoch15.ckpt" + trained_ckpt = load_checkpoint(ckpt_path) + load_param_into_net(train_network, trained_ckpt) + + # Define loss and create model. + loss = SoftmaxCrossEntropyWithLogits() + model = Model(network, loss_fn=loss, metrics={'acc'}) + + eval_dataset = create_dataset("/ssd/data/garbage/train", do_train=False, + batch_size=32) + + res = model.eval(eval_dataset) + print("result:", res, "ckpt=", ckpt_path) + ``` + diff --git a/tutorials/source_zh_cn/advanced_use/hub_tutorial.md b/tutorials/source_zh_cn/advanced_use/hub_tutorial.md new file mode 100644 index 0000000000..5969c90d63 --- /dev/null +++ b/tutorials/source_zh_cn/advanced_use/hub_tutorial.md @@ -0,0 +1,179 @@ +## 使用MindSpore Hub提交、加载和微调模型 + +`Ascend` `GPU` `MindSpore Hub` `模型上传` `模型加载` `模型微调` `初级` `中级` `高级` + + + +- [使用MindSpore Hub提交、加载和微调模型](#使用MindSporeHub提交加载和微调模型) + - [概述](#概述) + - [模型上传](#模型上传) + - [步骤](#步骤) + - [模型加载](#模型加载) + - [模型微调](#模型微调) + + + + + +### 概述 + +本教程以Googlenet为例,对想要将模型发布到MindSpore Hub的算法开发者介绍了模型上传步骤,也对想要使用MindSpore Hub模型进行推理或者微调的开发应用者描述了具体操作流程。总之,本教程可以帮助算法开发者有效地提交模型,并使得应用开发者利用MindSpore Hub的接口快速实现模型推理或微调。 + +### 模型上传 + +我们接收用户通过向`hub`仓提交PR的方式向MindSpore Hub发布模型。这里我们用Googlenet为例,列出将模型提交到MindSpore Hub的步骤。 + +#### 步骤 + +1. 将你的预训练模型托管在我们可以访问的存储位置。 + +2. 按照 [模板](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/mindspore_hub_conf.py) 在你自己的代码仓中添加模型生成文件 `mindspore_hub_conf.py`。 + +3. 按照 [模板](https://gitee.com/mindspore/hub/blob/master/mshub_res/assets/mindspore/gpu/0.6/alexnet_v1_cifar10.md) 在 `hub/mshub_res/assets` 中创建`{model_name}_{model_version}_{dataset}.md` 文件。对于每个预训练模型,执行以下命令,用来获得`.md`文件`asset-sha256` 处所需的哈希值: + + ```python + cd ../tools + python get_sha256.py ../googlenet.ckpt + ``` + +4. 使用 `hub/mshub_res/tools/md_validator.py` 在本地核对`.md`文件的格式,执行的命令如下: + + ```python + python md_validator.py ../assets/mindspore/ascend/0.7/googlenet_v1_cifar10.md + ``` + +5. 在 `mindspore/hub` 仓创建PR。 + +一旦你的PR合并到 `mindspore/hub` 的master分支,你的模型将于24小时内在 [MindSpore Hub 网站](https://hub.mindspore.com/mindspore) 上显示。更多详细信息,请参考 [README](https://gitee.com/mindspore/hub/blob/master/mshub_res/README.md) 。 + +### 模型加载 + +`mindspore_hub.load` API用于加载预训练模型,可以实现一行代码加载模型。主要的模型加载流程如下: + +- 在MindSpore Hub官网上搜索感兴趣的模型。 + + 例如,想使用Googlenet对CIFAR-10数据集进行分类,可以在MindSpore Hub官网上使用关键词`GoogleNet`进行搜索。页面将会返回与Googlenet相关的所有模型。进入相关模型页面之后,获得详情页 `url`。 + +- 使用`url`完成模型的加载,示例代码如下: + + ```python + import mindspore_hub as mshub + import mindspore + from mindspore import context, Tensor, nn + from mindspore.train.model import Model + from mindspore.common import dtype as mstype + from mindspore.dataset.transforms import py_transforms + from PIL import Image + import cv2 + + context.set_context(mode=context.GRAPH_MODE, + device_target="Ascend", + device_id=0) + + model = "mindspore/ascend/0.7/googlenet_v1_cifar10" + + image = Image.open('cifar10/a.jpg') + transforms = py_transforms.ComposeOp([py_transforms.ToTensor()]) + + # Initialize the number of classes based on the pre-trained model. + network = mshub.load(model, num_classes=10) + network.set_train(False) + out = network(transforms(image)) + ``` + +### 模型微调 + +在使用 `mindspore_hub.load` 进行模型加载时,可以增加一个额外的参数项只加载神经网络的特征提取部分。这样我们就能很容易地在之后增加一些新的层进行迁移学习。*当算法工程师将额外的参数(例如 include_top)添加到模型构造中时,可以在模型的详情页中找到这个功能。* + +下面我们以GoogleNet为例,说明如何加载一个基于ImageNet的预训练模型,并在特定的子任务数据集上进行迁移学习(重训练)。主要的步骤如下: + +1. 在MindSpore Hub的官网上搜索感兴趣的模型,并从网站上获取特定的 `url`。 + +2. 使用 `url`进行MindSpore Hub模型的加载,*注意:`include_top` 参数需要模型开发者提供*。 + + ```python + import mindspore + from mindspore import nn + from mindspore import context + import mindspore_hub as mshub + + context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", + save_graphs=False) + + network = mshub.load('mindspore/ascend/0.7/googlenet_v1_cifar10', include_top=False) + network.set_train(False) + ``` + +3. 在现有模型结构基础上增加一个与新任务相关的分类层。 + + ```python + # Check MindSpore Hub website to conclude that the last output shape is 1024. + last_channel = 1024 + + # The number of classes in target task is 26. + num_classes = 26 + classification_layer = nn.Dense(last_channel, num_classes) + classification_layer.set_train(True) + + train_network = nn.SequentialCell([network, classification_layer]) + ``` + +4. 为模型训练选择损失函数和优化器。 + + ```python + from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits + + # Wrap the backbone network with loss. + loss_fn = SoftmaxCrossEntropyWithLogits() + loss_net = nn.WithLossCell(train_network, loss_fn) + + # Create an optimizer. + optim = opt = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), Tensor(lr), config.momentum, config.weight_decay) + train_net = nn.TrainOneStepCell(loss_net, optim) + ``` + +5. 构建数据集,开始重训练。 + + ```python + from src.dataset import create_dataset + from mindspore.train.serialization import _exec_save_checkpoint + + dataset = create_dataset("/ssd/data/garbage/train", do_train=True, batch_size=32) + + epoch_size = 15 + for epoch in range(epoch_size): + for i, items in enumerate(dataset): + data, label = items + data = mindspore.Tensor(data) + label = mindspore.Tensor(label) + + loss = train_net(data, label) + print(f"epoch: {epoch}, loss: {loss}") + # Save the ckpt file for each epoch. + ckpt_path = f"./ckpt/garbage_finetune_epoch{epoch}.ckpt" + _exec_save_checkpoint(train_network, ckpt_path) + ``` + +6. 在测试集上测试模型精度。 + + ```python + from mindspore.train.serialization import load_checkpoint, load_param_into_net + + network = mshub.load('mindspore/ascend/0.7/googlenet_v1_cifar10', include_top=False) + train_network = nn.SequentialCell([network, nn.Dense(last_channel, num_classes)]) + + # Load a pre-trained ckpt file. + ckpt_path = "./ckpt/garbage_finetune_epoch15.ckpt" + trained_ckpt = load_checkpoint(ckpt_path) + load_param_into_net(train_network, trained_ckpt) + + # Define loss and create model. + loss_fn = SoftmaxCrossEntropyWithLogits() + model = Model(network, loss_fn=loss, metrics={'acc'}) + + eval_dataset = create_dataset("/ssd/data/garbage/train", do_train=False, + batch_size=32) + + res = model.eval(eval_dataset) + print("result:", res, "ckpt=", ckpt_path) + ``` -- Gitee