From 1558a8d3674736b8bfcf8892d1d4fd260b8b3713 Mon Sep 17 00:00:00 2001 From: SebastianHan Date: Mon, 14 Sep 2020 09:28:18 +0800 Subject: [PATCH 001/100] fix gpu video pic --- tutorials/source_en/quick_start/quick_video.md | 2 +- .../quick_start/quick_video/gpu_operator_development.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/source_en/quick_start/quick_video.md b/tutorials/source_en/quick_start/quick_video.md index a46f6ae41d..b11de9ebd0 100644 --- a/tutorials/source_en/quick_start/quick_video.md +++ b/tutorials/source_en/quick_start/quick_video.md @@ -269,7 +269,7 @@ Provides video tutorials from installation to try-on, helping you quickly use Mi class="video-item-wraper" style="width: 33.3%;display: flex;justify-content: center;align-items: center;padding: 10px;box-sizing: border-box;"> - (This document contains Hands-on Tutorial Series. Gitee does not support display. Please check tutorials on the official website) -M6F&5@4_R4j%||A98bV}U<+eGtfH|0NIja^yvu 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 literal 0 HcmV?d00001 diff --git a/docs/source_en/images/architecture.eddx b/docs/note/source_en/images/architecture.eddx similarity index 100% rename from docs/source_en/images/architecture.eddx rename to docs/note/source_en/images/architecture.eddx diff --git a/docs/source_en/images/architecture.png b/docs/note/source_en/images/architecture.png similarity index 100% rename from docs/source_en/images/architecture.png rename to docs/note/source_en/images/architecture.png diff --git a/docs/source_en/images/help_seeking_path.png b/docs/note/source_en/images/help_seeking_path.png similarity index 100% rename from docs/source_en/images/help_seeking_path.png rename to docs/note/source_en/images/help_seeking_path.png diff --git a/docs/source_en/index.rst b/docs/note/source_en/index.rst similarity index 100% rename from docs/source_en/index.rst rename to docs/note/source_en/index.rst diff --git a/lite/docs/source_en/index.rst b/docs/note/source_en/index_lite.rst similarity index 100% rename from lite/docs/source_en/index.rst rename to docs/note/source_en/index_lite.rst diff --git a/docs/source_en/network_list.md b/docs/note/source_en/network_list.md similarity index 99% rename from docs/source_en/network_list.md rename to docs/note/source_en/network_list.md index 897111be50..d8cc516092 100644 --- a/docs/source_en/network_list.md +++ b/docs/note/source_en/network_list.md @@ -1,60 +1,60 @@ -# Network List - -`Linux` `Ascend` `GPU` `CPU` `Model Development` `Intermediate` `Expert` - - - -- [Network List](#network-list) - - [Model Zoo](#model-zoo) - - [Pre-trained Models](#pre-trained-models) - - - - - -## Model Zoo - -| Domain | Sub Domain | Network | Ascend | GPU | CPU -|:------ |:------| :----------- |:------ |:------ |:----- -|Computer Vision (CV) | Image Classification | [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | Supported | Supported | Doing -| Computer Vision (CV) | Image Classification | [GoogleNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/src/googlenet.py) | Supported | Doing | Doing -| Computer Vision (CV) | Image Classification | [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py) | Supported | Supported | Supported -| Computer Vision (CV) | Image Classification | [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported | Supported | Doing -|Computer Vision (CV) | Image Classification | [ResNet-101](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing -|Computer Vision (CV) | Image Classification | [SE-ResNet50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing -|Computer Vision (CV) | Image Classification | [ResNext50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnext50/src/image_classification.py) | Supported | Supported | Doing -| Computer Vision (CV) | Image Classification | [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py) | Supported | Doing | Doing -| Computer Vision (CV) | Image Classification | [InceptionV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/inceptionv3/src/inception_v3.py) | Supported | Doing | Doing -| Computer Vision (CV) | Mobile Image Classification
Image Classification
Semantic Tegmentation | [MobileNetV2](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv2/src/mobilenetV2.py) | Supported | Supported | Doing -| Computer Vision (CV) | Mobile Image Classification
Image Classification
Semantic Tegmentation | [MobileNetV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv3/src/mobilenetV3.py) | Doing | Supported | Doing -|Computer Vision (CV) | Targets Detection | [SSD](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/ssd/src/ssd.py) | Supported |Doing | Doing -| Computer Vision (CV) | Targets Detection | [YoloV3-ResNet18](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_resnet18/src/yolov3.py) | Supported | Doing | Doing -| Computer Vision (CV) | Targets Detection | [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | Supported | Doing | Doing -| Computer Vision (CV) | Targets Detection | [FasterRCNN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/faster_rcnn/src/FasterRcnn/faster_rcnn_r50.py) | Supported | Doing | Doing -| Computer Vision (CV) | Semantic Segmentation | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/deeplabv3.py) | Supported | Doing | Doing -| Computer Vision(CV) | Targets Detection | [WarpCTC](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/warpctc/src/warpctc.py) | Doing | Supported | Doing -| Natural Language Processing (NLP) | Natural Language Understanding | [BERT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | Supported | Doing | Doing -| Natural Language Processing (NLP) | Natural Language Understanding | [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py) | Supported | Doing | Doing -| Natural Language Processing (NLP) | Natural Language Understanding | [SentimentNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/lstm/src/lstm.py) | Doing | Supported | Supported -| Natural Language Processing (NLP) | Natural Language Understanding | [MASS](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/mass/src/transformer/transformer_for_train.py) | Supported | Doing | Doing -| Natural Language Processing (NLP) | Natural Language Understanding | [TinyBert](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/tinybert/src/tinybert_model.py) | Supported | Supported | Doing -| Recommender | Recommender System, CTR prediction | [DeepFM](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/deepfm/src/deepfm.py) | Supported | Supported | Doing -| Recommender | Recommender System, Search ranking | [Wide&Deep](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/wide_and_deep/src/wide_and_deep.py) | Supported | Supported | Doing -| Graph Neural Networks(GNN)| Text Classification | [GCN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gcn/src/gcn.py) | Supported | Doing | Doing -| Graph Neural Networks(GNN)| Text Classification | [GAT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gat/src/gat.py) | Supported | Doing | Doing - -> You can also use [MindWizard Tool](https://gitee.com/mindspore/mindinsight/tree/master/mindinsight/wizard/) to quickly generate classic network scripts. - -## Pre-trained Models -*It refers to the released MindSpore version. The hardware platforms that support model training are CPU, GPU and Ascend. As shown in the table below, ✓ indicates that the pre-trained model run on the selected platform. - -| Domain | Sub Domain| Network | Dataset | CPU | GPU | Ascend | 0.5.0-beta* -|:------ |:------ | :------- |:------ |:------ |:------ |:----- |:----- -|Computer Vision (CV) | Image Classification| [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | CIFAR-10| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/alexnet/alexnet_ascend_0.5.0_cifar10_official_classification_20200716.tar.gz) -|Computer Vision (CV) | Image Classification| [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py)| MNIST | | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/lenet/lenet_ascend_0.5.0_mnist_official_classification_20200716.tar.gz) -|Computer Vision (CV) | Image Classification| [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py)| CIFAR-10 | | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/vgg/vgg16_ascend_0.5.0_cifar10_official_classification_20200715.tar.gz) -|Computer Vision (CV) | Image Classification| [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | CIFAR-10| | | ✓ |[Download](http://download.mindspore.cn/model_zoo/official/cv/resnet/resnet50_v1.5_ascend_0.3.0_cifar10_official_classification_20200718.tar.gz) -|Computer Vision (CV) | Targets Detection| [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | COCO 2014| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/yolo/yolov3_darknet53_ascend_0.5.0_coco2014_official_object_detection_20200717.tar.gz) -| Natural Language Processing (NLP) | Natural Language Understanding| [BERT_Base](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | zhwiki | | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_base_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) -| Natural Language Processing (NLP) | Natural Language Understanding| [BERT_NEZHA](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py)| zhwiki| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_nezha_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) -| Natural Language Processing (NLP) | Natural Language Understanding| [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py)| WMT English-German| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/nlp/transformer/transformer_ascend_0.5.0_wmtende_official_machine_translation_20200713.tar.gz) +# Network List + +`Linux` `Ascend` `GPU` `CPU` `Model Development` `Intermediate` `Expert` + + + +- [Network List](#network-list) + - [Model Zoo](#model-zoo) + - [Pre-trained Models](#pre-trained-models) + + + + + +## Model Zoo + +| Domain | Sub Domain | Network | Ascend | GPU | CPU +|:------ |:------| :----------- |:------ |:------ |:----- +|Computer Vision (CV) | Image Classification | [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | Supported | Supported | Doing +| Computer Vision (CV) | Image Classification | [GoogleNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/src/googlenet.py) | Supported | Doing | Doing +| Computer Vision (CV) | Image Classification | [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py) | Supported | Supported | Supported +| Computer Vision (CV) | Image Classification | [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported | Supported | Doing +|Computer Vision (CV) | Image Classification | [ResNet-101](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing +|Computer Vision (CV) | Image Classification | [SE-ResNet50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing +|Computer Vision (CV) | Image Classification | [ResNext50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnext50/src/image_classification.py) | Supported | Supported | Doing +| Computer Vision (CV) | Image Classification | [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py) | Supported | Doing | Doing +| Computer Vision (CV) | Image Classification | [InceptionV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/inceptionv3/src/inception_v3.py) | Supported | Doing | Doing +| Computer Vision (CV) | Mobile Image Classification
Image Classification
Semantic Tegmentation | [MobileNetV2](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv2/src/mobilenetV2.py) | Supported | Supported | Doing +| Computer Vision (CV) | Mobile Image Classification
Image Classification
Semantic Tegmentation | [MobileNetV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv3/src/mobilenetV3.py) | Doing | Supported | Doing +|Computer Vision (CV) | Targets Detection | [SSD](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/ssd/src/ssd.py) | Supported |Doing | Doing +| Computer Vision (CV) | Targets Detection | [YoloV3-ResNet18](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_resnet18/src/yolov3.py) | Supported | Doing | Doing +| Computer Vision (CV) | Targets Detection | [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | Supported | Doing | Doing +| Computer Vision (CV) | Targets Detection | [FasterRCNN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/faster_rcnn/src/FasterRcnn/faster_rcnn_r50.py) | Supported | Doing | Doing +| Computer Vision (CV) | Semantic Segmentation | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/deeplabv3.py) | Supported | Doing | Doing +| Computer Vision(CV) | Targets Detection | [WarpCTC](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/warpctc/src/warpctc.py) | Doing | Supported | Doing +| Natural Language Processing (NLP) | Natural Language Understanding | [BERT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | Supported | Doing | Doing +| Natural Language Processing (NLP) | Natural Language Understanding | [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py) | Supported | Doing | Doing +| Natural Language Processing (NLP) | Natural Language Understanding | [SentimentNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/lstm/src/lstm.py) | Doing | Supported | Supported +| Natural Language Processing (NLP) | Natural Language Understanding | [MASS](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/mass/src/transformer/transformer_for_train.py) | Supported | Doing | Doing +| Natural Language Processing (NLP) | Natural Language Understanding | [TinyBert](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/tinybert/src/tinybert_model.py) | Supported | Supported | Doing +| Recommender | Recommender System, CTR prediction | [DeepFM](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/deepfm/src/deepfm.py) | Supported | Supported | Doing +| Recommender | Recommender System, Search ranking | [Wide&Deep](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/wide_and_deep/src/wide_and_deep.py) | Supported | Supported | Doing +| Graph Neural Networks(GNN)| Text Classification | [GCN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gcn/src/gcn.py) | Supported | Doing | Doing +| Graph Neural Networks(GNN)| Text Classification | [GAT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gat/src/gat.py) | Supported | Doing | Doing + +> You can also use [MindWizard Tool](https://gitee.com/mindspore/mindinsight/tree/master/mindinsight/wizard/) to quickly generate classic network scripts. + +## Pre-trained Models +*It refers to the released MindSpore version. The hardware platforms that support model training are CPU, GPU and Ascend. As shown in the table below, ✓ indicates that the pre-trained model run on the selected platform. + +| Domain | Sub Domain| Network | Dataset | CPU | GPU | Ascend | 0.5.0-beta* +|:------ |:------ | :------- |:------ |:------ |:------ |:----- |:----- +|Computer Vision (CV) | Image Classification| [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | CIFAR-10| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/alexnet/alexnet_ascend_0.5.0_cifar10_official_classification_20200716.tar.gz) +|Computer Vision (CV) | Image Classification| [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py)| MNIST | | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/lenet/lenet_ascend_0.5.0_mnist_official_classification_20200716.tar.gz) +|Computer Vision (CV) | Image Classification| [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py)| CIFAR-10 | | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/vgg/vgg16_ascend_0.5.0_cifar10_official_classification_20200715.tar.gz) +|Computer Vision (CV) | Image Classification| [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | CIFAR-10| | | ✓ |[Download](http://download.mindspore.cn/model_zoo/official/cv/resnet/resnet50_v1.5_ascend_0.3.0_cifar10_official_classification_20200718.tar.gz) +|Computer Vision (CV) | Targets Detection| [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | COCO 2014| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/cv/yolo/yolov3_darknet53_ascend_0.5.0_coco2014_official_object_detection_20200717.tar.gz) +| Natural Language Processing (NLP) | Natural Language Understanding| [BERT_Base](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | zhwiki | | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_base_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) +| Natural Language Processing (NLP) | Natural Language Understanding| [BERT_NEZHA](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py)| zhwiki| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_nezha_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) +| Natural Language Processing (NLP) | Natural Language Understanding| [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py)| WMT English-German| | | ✓ | [Download](http://download.mindspore.cn/model_zoo/official/nlp/transformer/transformer_ascend_0.5.0_wmtende_official_machine_translation_20200713.tar.gz) diff --git a/docs/source_en/operator_list.md b/docs/note/source_en/operator_list.md similarity index 100% rename from docs/source_en/operator_list.md rename to docs/note/source_en/operator_list.md diff --git a/lite/docs/source_en/operator_list.md b/docs/note/source_en/operator_list_lite.md similarity index 100% rename from lite/docs/source_en/operator_list.md rename to docs/note/source_en/operator_list_lite.md diff --git a/docs/source_en/roadmap.md b/docs/note/source_en/roadmap.md similarity index 100% rename from docs/source_en/roadmap.md rename to docs/note/source_en/roadmap.md diff --git a/docs/source_zh_cn/_static/logo_source.png b/docs/note/source_zh_cn/_static/logo_source.png similarity index 100% rename from docs/source_zh_cn/_static/logo_source.png rename to docs/note/source_zh_cn/_static/logo_source.png diff --git a/docs/source_zh_cn/architecture.md b/docs/note/source_zh_cn/architecture.md similarity index 100% rename from docs/source_zh_cn/architecture.md rename to docs/note/source_zh_cn/architecture.md diff --git a/lite/docs/source_zh_cn/architecture.md b/docs/note/source_zh_cn/architecture_lite.md similarity index 100% rename from lite/docs/source_zh_cn/architecture.md rename to docs/note/source_zh_cn/architecture_lite.md diff --git a/docs/source_zh_cn/benchmark.md b/docs/note/source_zh_cn/benchmark.md similarity index 100% rename from docs/source_zh_cn/benchmark.md rename to docs/note/source_zh_cn/benchmark.md diff --git a/docs/source_zh_cn/community.rst b/docs/note/source_zh_cn/community.rst similarity index 100% rename from docs/source_zh_cn/community.rst rename to docs/note/source_zh_cn/community.rst diff --git a/docs/source_zh_cn/conf.py b/docs/note/source_zh_cn/conf.py similarity index 100% rename from docs/source_zh_cn/conf.py rename to docs/note/source_zh_cn/conf.py diff --git a/docs/source_zh_cn/constraints_on_network_construction.md b/docs/note/source_zh_cn/constraints_on_network_construction.md similarity index 100% rename from docs/source_zh_cn/constraints_on_network_construction.md rename to docs/note/source_zh_cn/constraints_on_network_construction.md diff --git a/docs/source_zh_cn/design.rst b/docs/note/source_zh_cn/design.rst similarity index 100% rename from docs/source_zh_cn/design.rst rename to docs/note/source_zh_cn/design.rst diff --git a/docs/source_zh_cn/design/mindarmour/differential_privacy_design.md b/docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md similarity index 98% rename from docs/source_zh_cn/design/mindarmour/differential_privacy_design.md rename to docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md index 2762196556..b919d27912 100644 --- a/docs/source_zh_cn/design/mindarmour/differential_privacy_design.md +++ b/docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md @@ -1,70 +1,70 @@ -# 差分隐私 - -`Linux` `Ascend` `模型开发` `模型调优` `框架开发` `企业` `高级` `贡献者` - - - -- [差分隐私](#差分隐私) - - [总体设计](#总体设计) - - [差分隐私优化器](#差分隐私优化器) - - [差分隐私的噪声机制](#差分隐私的噪声机制) - - [Monitor](#monitor) - - [代码实现](#代码实现) - - [参考文献](#参考文献) - - - - - -## 总体设计 - -MindArmour的Differential-Privacy模块实现了差分隐私训练的能力。模型的训练主要由构建训练数据集、计算损失、计算梯度以及更新模型参数等过程组成,目前MindArmour的差分隐私训练主要着力于计算梯度的过程,通过相应的算法对梯度进行裁剪、加噪等处理,从而保护用户数据隐私。 - -![dp_arch](./images/dp_arch.png) - -

图1 差分隐私总体设计
- -图1是差分隐私训练的总体设计,主要由差分隐私噪声机制(DP Mechanisms)、差分隐私优化器(DP Optimizer)、差分隐私监控器(Privacy Monitor)组成。 - - -### 差分隐私优化器 - -差分隐私优化器继承了MindSpore优化器的能力,并使用差分隐私的噪声机制对梯度加扰保护。目前,MindArmour提供三类差分隐私优化器:固定高斯优化器、自适应高斯优化器、自适应裁剪优化器,每类差分隐私优化器从不同的角度为SGD、Momentum等常规优化器增加差分隐私保护的能力。 - -* 固定高斯优化器,是一种非自适应高斯噪声的差分隐私优化器。其优势在于可以严格控制差分隐私预算ϵ,缺点是在模型训练过程中,每个Step添加的噪声量固定,若迭代次数过大,训练后期的噪声使得模型收敛困难,甚至导致性能大幅下跌,模型可用性差。 -* 自适应高斯优化器,通过自适应调整标准差,来调整高斯分布噪声的大小,在模型训练初期,添加的噪声量较大,随着模型逐渐收敛,噪声量逐渐减小,噪声对于模型可用性的影响减小。自适应高斯噪声的缺点是不能严格控制差分隐私预算。 -* 自适应裁剪优化器,是一种自适应调整调整裁剪粒度的差分隐私优化器,梯度裁剪是差分隐私训练的一个重要操作,自适应裁剪优化器能够自适应的控制梯度裁剪的的比例在给定的范围波动,控制迭代训练过程中梯度裁剪的粒度。 - -### 差分隐私的噪声机制 - -噪声机制是构建差分隐私训练能力的基础,不同的噪声机制满足不同差分隐私优化器的需求,包括固定高斯分布噪声、自适应高斯分布噪声、自适应裁剪高斯分布噪声、拉普拉斯分布噪声等多种机制。 - -### Monitor - -Monitor提供RDP、ZCDP等回调函数,用于监测模型的差分隐私预算。 - -* ZCDP[2] - - ZCDP,zero-concentrated differential privacy,是一种宽松的差分隐私定义,利用Rényi散度来度量随机函数在相邻数据集上的分布差异。 - -* RDP[3] - - RDP,Rényi Differential Privacy,是一种更通用的基于R'enyi散度的差分隐私定义,利用Rényi散度来度量两个相邻数据集的分布差异。 - -相对于传统差分隐私,ZCDP和RDP都能能够提供更加严格的隐私预算上界保证。 - - -## 代码实现 - -* [mechanisms.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/mechanisms/mechanisms.py): 这个文件实现了差分隐私训练所需的噪声生成机制,包括简单高斯噪声、自适应高斯噪声、自适应裁剪高斯噪声等。 -* [optimizer.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/optimizer/optimizer.py): 这个文件实现了使用噪声生成机制在反向传播时添加噪声的根本逻辑。 -* [monitor.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/monitor/monitor.py): 实现了计算差分隐私预算的回调函数,模型训练过程中,会反馈当前的差分隐私预算。 -* [model.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/train/model.py): 这个文件实现了计算损失和梯度的逻辑,差分隐私训练的梯度截断逻辑在此文件中实现,且model.py是用户使用差分隐私训练能力的入口。 - -## 参考文献 - -[1] Dwork, Cynthia, and Jing Lei. "Differential privacy and robust statistics." *Proceedings of the forty-first annual ACM symposium on Theory of computing*. 2009. - -[2] Lee, Jaewoo, and Daniel Kifer. "Concentrated differentially private gradient descent with adaptive per-iteration privacy budget." *Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining*. 2018. - -[3] Mironov, Ilya. "Rényi differential privacy." *2017 IEEE 30th Computer Security Foundations Symposium (CSF)*. IEEE, 2017. +# 差分隐私 + +`Linux` `Ascend` `模型开发` `模型调优` `框架开发` `企业` `高级` `贡献者` + + + +- [差分隐私](#差分隐私) + - [总体设计](#总体设计) + - [差分隐私优化器](#差分隐私优化器) + - [差分隐私的噪声机制](#差分隐私的噪声机制) + - [Monitor](#monitor) + - [代码实现](#代码实现) + - [参考文献](#参考文献) + + + + + +## 总体设计 + +MindArmour的Differential-Privacy模块实现了差分隐私训练的能力。模型的训练主要由构建训练数据集、计算损失、计算梯度以及更新模型参数等过程组成,目前MindArmour的差分隐私训练主要着力于计算梯度的过程,通过相应的算法对梯度进行裁剪、加噪等处理,从而保护用户数据隐私。 + +![dp_arch](./images/dp_arch.png) + +
图1 差分隐私总体设计
+ +图1是差分隐私训练的总体设计,主要由差分隐私噪声机制(DP Mechanisms)、差分隐私优化器(DP Optimizer)、差分隐私监控器(Privacy Monitor)组成。 + + +### 差分隐私优化器 + +差分隐私优化器继承了MindSpore优化器的能力,并使用差分隐私的噪声机制对梯度加扰保护。目前,MindArmour提供三类差分隐私优化器:固定高斯优化器、自适应高斯优化器、自适应裁剪优化器,每类差分隐私优化器从不同的角度为SGD、Momentum等常规优化器增加差分隐私保护的能力。 + +* 固定高斯优化器,是一种非自适应高斯噪声的差分隐私优化器。其优势在于可以严格控制差分隐私预算ϵ,缺点是在模型训练过程中,每个Step添加的噪声量固定,若迭代次数过大,训练后期的噪声使得模型收敛困难,甚至导致性能大幅下跌,模型可用性差。 +* 自适应高斯优化器,通过自适应调整标准差,来调整高斯分布噪声的大小,在模型训练初期,添加的噪声量较大,随着模型逐渐收敛,噪声量逐渐减小,噪声对于模型可用性的影响减小。自适应高斯噪声的缺点是不能严格控制差分隐私预算。 +* 自适应裁剪优化器,是一种自适应调整调整裁剪粒度的差分隐私优化器,梯度裁剪是差分隐私训练的一个重要操作,自适应裁剪优化器能够自适应的控制梯度裁剪的的比例在给定的范围波动,控制迭代训练过程中梯度裁剪的粒度。 + +### 差分隐私的噪声机制 + +噪声机制是构建差分隐私训练能力的基础,不同的噪声机制满足不同差分隐私优化器的需求,包括固定高斯分布噪声、自适应高斯分布噪声、自适应裁剪高斯分布噪声、拉普拉斯分布噪声等多种机制。 + +### Monitor + +Monitor提供RDP、ZCDP等回调函数,用于监测模型的差分隐私预算。 + +* ZCDP[2] + + ZCDP,zero-concentrated differential privacy,是一种宽松的差分隐私定义,利用Rényi散度来度量随机函数在相邻数据集上的分布差异。 + +* RDP[3] + + RDP,Rényi Differential Privacy,是一种更通用的基于R'enyi散度的差分隐私定义,利用Rényi散度来度量两个相邻数据集的分布差异。 + +相对于传统差分隐私,ZCDP和RDP都能能够提供更加严格的隐私预算上界保证。 + + +## 代码实现 + +* [mechanisms.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/mechanisms/mechanisms.py): 这个文件实现了差分隐私训练所需的噪声生成机制,包括简单高斯噪声、自适应高斯噪声、自适应裁剪高斯噪声等。 +* [optimizer.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/optimizer/optimizer.py): 这个文件实现了使用噪声生成机制在反向传播时添加噪声的根本逻辑。 +* [monitor.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/monitor/monitor.py): 实现了计算差分隐私预算的回调函数,模型训练过程中,会反馈当前的差分隐私预算。 +* [model.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/train/model.py): 这个文件实现了计算损失和梯度的逻辑,差分隐私训练的梯度截断逻辑在此文件中实现,且model.py是用户使用差分隐私训练能力的入口。 + +## 参考文献 + +[1] Dwork, Cynthia, and Jing Lei. "Differential privacy and robust statistics." *Proceedings of the forty-first annual ACM symposium on Theory of computing*. 2009. + +[2] Lee, Jaewoo, and Daniel Kifer. "Concentrated differentially private gradient descent with adaptive per-iteration privacy budget." *Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining*. 2018. + +[3] Mironov, Ilya. "Rényi differential privacy." *2017 IEEE 30th Computer Security Foundations Symposium (CSF)*. IEEE, 2017. diff --git a/docs/source_zh_cn/design/mindarmour/fuzzer_design.md b/docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md similarity index 98% rename from docs/source_zh_cn/design/mindarmour/fuzzer_design.md rename to docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md index 81a730c30a..f7554141b1 100644 --- a/docs/source_zh_cn/design/mindarmour/fuzzer_design.md +++ b/docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md @@ -1,73 +1,73 @@ -# AI模型安全测试 - -`Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` - - - -- [AI模型安全测试](#ai模型安全测试) - - [背景](#背景) - - [Fuzzer设计图](#Fuzzer设计图) - - [Fuzzer流程](#Fuzzer流程) - - [代码实现](#代码实现) - - [参考文献](#参考文献) - - - - - -## 背景 - -不同于[传统程序的Fuzz安全测试](https://zhuanlan.zhihu.com/p/43432370),MindArmour针对深度神经网络,提供AI模型安全测试模块Fuzzer。根据神经网络的特点,引入神经元覆盖率[1]的概念,作为Fuzz的测试指导,引导Fuzz朝神经元覆盖率增加的方向生成样本,让输入能够激活更多的神经元,神经元值的分布范围更广,以充分测试DNN,探索不同类型的模型输出结果、模型错误行为。 - -## Fuzzer设计图 - -AI模型安全测试设计图如下。 - -![fuzz_architecture](./images/fuzz_architecture.png) - -在用户接口层,需要用户提供原始数据集`DataSet`、被测试模型`Model`和配置Fuzzer参数`Fuzzer configuration`。Fuzzer模块对模型和数据进行Fuzz测试后,返回安全评估报告`Security Report`。 - -Fuzzer架构主要包括三个模块: - -1. Natural Threat/Adversarial Example Generator(数据变异模块): - - 随机选择变异方法对种子数据变异生成多个变种。支持多种样本的变异策略, 包括: - - - 图像仿射变换方法如:平移、旋转、缩放、错切。 - - 基于图像像素值变化的方法如:改变对比度、亮度、模糊、加噪。 - - 基于对抗攻击的白盒、黑盒对抗样本生成方法,如FGSM、PGD、MDIIM。 - -2. Fuzzer moduler(变异指导模块): - - 对变异生成的数据进行fuzz测试,观察神经元覆盖率的变化情况,如果生成的数据使得神经元覆盖率增加,则加入变异的种子队列,用于下一轮的数据变异。目前支持的神经元覆盖率指标包括KMNC、NBC、SNAC[2]。 - -3. Evaluation(评估模块): - - 评估Fuzzer效果,生成数据的质量,变异方法的强度。支持3个类型5种指标,包括通用评价指标:accuracy,神经元覆盖率指标:kmnc, nbc,snac,对抗攻击评价指标:attack_success_rate。 - -## Fuzzer流程 - -![fuzz_process](./images/fuzz_process.png) - -具体的Fuzzer流程如下: - -1. 根据策略从种子队列中选择一个种子A。 -2. 随机选择变异策略,对种子A进行变异,生成多个变种数据A1,A2... -3. 用目标模型对变种A1,A2...进行预测,如果变种使得目标模型预测错误,则改变种进入Failed tests。 -4. 若目标模型对于变种的预测结果是正确的,用神经元覆盖率指标进行分析。 -5. 如果变种使得覆盖率增加,那么将该变种放入种子队列,用于下一轮变异。 - -通过多轮循环,我们获得一系列变异数据Fuzzed Tests,并进一步分析,从多个角度给出安全报告。可以用于深入分析神经网络模型的缺陷,从而针对这些缺陷,进行模型增强等,改善提升模型的通用性、鲁棒性。 - -## 代码实现 - -1. [fuzzing.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/fuzzing.py):Fuzzer总体流程。 -2. [model_coverage_metrics.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/model_coverage_metrics.py):神经元覆盖率指标,包括KMNC,NBC,SNAC。 -3. [image_transform.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/image_transform.py):图像变异方法,包括基于像素值的变化方法和仿射变化方法。 -4. [adversarial attacks](https://gitee.com/mindspore/mindarmour/tree/master/mindarmour/adv_robustness/attacks):对抗样本攻击方法,包含多种黑盒、白盒攻击方法。 - -## 参考文献 - -[1] Pei K, Cao Y, Yang J, et al. Deepxplore: Automated whitebox testing of deep learning systems[C]//Proceedings of the 26th Symposium on Operating Systems Principles. ACM, 2017: 1-18. - -[2]Ma L, Juefei-Xu F, Zhang F, et al. Deepgauge: Multi-granularity testing criteria for deep learning systems[C]//Proceedings of the 33rd ACM/IEEE International Conference on Automated Software Engineering. ACM, 2018: 120-131. +# AI模型安全测试 + +`Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` + + + +- [AI模型安全测试](#ai模型安全测试) + - [背景](#背景) + - [Fuzzer设计图](#Fuzzer设计图) + - [Fuzzer流程](#Fuzzer流程) + - [代码实现](#代码实现) + - [参考文献](#参考文献) + + + + + +## 背景 + +不同于[传统程序的Fuzz安全测试](https://zhuanlan.zhihu.com/p/43432370),MindArmour针对深度神经网络,提供AI模型安全测试模块Fuzzer。根据神经网络的特点,引入神经元覆盖率[1]的概念,作为Fuzz的测试指导,引导Fuzz朝神经元覆盖率增加的方向生成样本,让输入能够激活更多的神经元,神经元值的分布范围更广,以充分测试DNN,探索不同类型的模型输出结果、模型错误行为。 + +## Fuzzer设计图 + +AI模型安全测试设计图如下。 + +![fuzz_architecture](./images/fuzz_architecture.png) + +在用户接口层,需要用户提供原始数据集`DataSet`、被测试模型`Model`和配置Fuzzer参数`Fuzzer configuration`。Fuzzer模块对模型和数据进行Fuzz测试后,返回安全评估报告`Security Report`。 + +Fuzzer架构主要包括三个模块: + +1. Natural Threat/Adversarial Example Generator(数据变异模块): + + 随机选择变异方法对种子数据变异生成多个变种。支持多种样本的变异策略, 包括: + + - 图像仿射变换方法如:平移、旋转、缩放、错切。 + - 基于图像像素值变化的方法如:改变对比度、亮度、模糊、加噪。 + - 基于对抗攻击的白盒、黑盒对抗样本生成方法,如FGSM、PGD、MDIIM。 + +2. Fuzzer moduler(变异指导模块): + + 对变异生成的数据进行fuzz测试,观察神经元覆盖率的变化情况,如果生成的数据使得神经元覆盖率增加,则加入变异的种子队列,用于下一轮的数据变异。目前支持的神经元覆盖率指标包括KMNC、NBC、SNAC[2]。 + +3. Evaluation(评估模块): + + 评估Fuzzer效果,生成数据的质量,变异方法的强度。支持3个类型5种指标,包括通用评价指标:accuracy,神经元覆盖率指标:kmnc, nbc,snac,对抗攻击评价指标:attack_success_rate。 + +## Fuzzer流程 + +![fuzz_process](./images/fuzz_process.png) + +具体的Fuzzer流程如下: + +1. 根据策略从种子队列中选择一个种子A。 +2. 随机选择变异策略,对种子A进行变异,生成多个变种数据A1,A2... +3. 用目标模型对变种A1,A2...进行预测,如果变种使得目标模型预测错误,则改变种进入Failed tests。 +4. 若目标模型对于变种的预测结果是正确的,用神经元覆盖率指标进行分析。 +5. 如果变种使得覆盖率增加,那么将该变种放入种子队列,用于下一轮变异。 + +通过多轮循环,我们获得一系列变异数据Fuzzed Tests,并进一步分析,从多个角度给出安全报告。可以用于深入分析神经网络模型的缺陷,从而针对这些缺陷,进行模型增强等,改善提升模型的通用性、鲁棒性。 + +## 代码实现 + +1. [fuzzing.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/fuzzing.py):Fuzzer总体流程。 +2. [model_coverage_metrics.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/model_coverage_metrics.py):神经元覆盖率指标,包括KMNC,NBC,SNAC。 +3. [image_transform.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/image_transform.py):图像变异方法,包括基于像素值的变化方法和仿射变化方法。 +4. [adversarial attacks](https://gitee.com/mindspore/mindarmour/tree/master/mindarmour/adv_robustness/attacks):对抗样本攻击方法,包含多种黑盒、白盒攻击方法。 + +## 参考文献 + +[1] Pei K, Cao Y, Yang J, et al. Deepxplore: Automated whitebox testing of deep learning systems[C]//Proceedings of the 26th Symposium on Operating Systems Principles. ACM, 2017: 1-18. + +[2]Ma L, Juefei-Xu F, Zhang F, et al. Deepgauge: Multi-granularity testing criteria for deep learning systems[C]//Proceedings of the 33rd ACM/IEEE International Conference on Automated Software Engineering. ACM, 2018: 120-131. diff --git a/docs/source_zh_cn/design/mindarmour/images/dp_arch.png b/docs/note/source_zh_cn/design/mindarmour/images/dp_arch.png similarity index 100% rename from docs/source_zh_cn/design/mindarmour/images/dp_arch.png rename to docs/note/source_zh_cn/design/mindarmour/images/dp_arch.png diff --git a/docs/source_zh_cn/design/mindarmour/images/fuzz_architecture.png b/docs/note/source_zh_cn/design/mindarmour/images/fuzz_architecture.png similarity index 100% rename from docs/source_zh_cn/design/mindarmour/images/fuzz_architecture.png rename to docs/note/source_zh_cn/design/mindarmour/images/fuzz_architecture.png diff --git a/docs/source_zh_cn/design/mindarmour/images/fuzz_process.png b/docs/note/source_zh_cn/design/mindarmour/images/fuzz_process.png similarity index 100% rename from docs/source_zh_cn/design/mindarmour/images/fuzz_process.png rename to docs/note/source_zh_cn/design/mindarmour/images/fuzz_process.png diff --git a/docs/source_zh_cn/design/mindinsight/graph_visual_design.md b/docs/note/source_zh_cn/design/mindinsight/graph_visual_design.md similarity index 100% rename from docs/source_zh_cn/design/mindinsight/graph_visual_design.md rename to docs/note/source_zh_cn/design/mindinsight/graph_visual_design.md diff --git a/docs/source_zh_cn/design/mindinsight/images/analyser_class_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/analyser_class_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/analyser_class_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/analyser_class_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/context_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/context_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/context_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/context_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/graph_visual_class_design.png b/docs/note/source_zh_cn/design/mindinsight/images/graph_visual_class_design.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/graph_visual_class_design.png rename to docs/note/source_zh_cn/design/mindinsight/images/graph_visual_class_design.png diff --git a/docs/source_zh_cn/design/mindinsight/images/graph_visual_main.png b/docs/note/source_zh_cn/design/mindinsight/images/graph_visual_main.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/graph_visual_main.png rename to docs/note/source_zh_cn/design/mindinsight/images/graph_visual_main.png diff --git a/docs/source_zh_cn/design/mindinsight/images/graph_visual_right_side.png b/docs/note/source_zh_cn/design/mindinsight/images/graph_visual_right_side.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/graph_visual_right_side.png rename to docs/note/source_zh_cn/design/mindinsight/images/graph_visual_right_side.png diff --git a/docs/source_zh_cn/design/mindinsight/images/module_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/module_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/module_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/module_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/parser_module_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/parser_module_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/parser_module_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/parser_module_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/proposer_class_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/proposer_class_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/proposer_class_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/proposer_class_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/proposer_module_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/proposer_module_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/proposer_module_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/proposer_module_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/tensor_histogram.png b/docs/note/source_zh_cn/design/mindinsight/images/tensor_histogram.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/tensor_histogram.png rename to docs/note/source_zh_cn/design/mindinsight/images/tensor_histogram.png diff --git a/docs/source_zh_cn/design/mindinsight/images/tensor_table.png b/docs/note/source_zh_cn/design/mindinsight/images/tensor_table.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/tensor_table.png rename to docs/note/source_zh_cn/design/mindinsight/images/tensor_table.png diff --git a/docs/source_zh_cn/design/mindinsight/images/time_order_profiler.png b/docs/note/source_zh_cn/design/mindinsight/images/time_order_profiler.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/time_order_profiler.png rename to docs/note/source_zh_cn/design/mindinsight/images/time_order_profiler.png diff --git a/docs/source_zh_cn/design/mindinsight/images/training_visualization_architecture.png b/docs/note/source_zh_cn/design/mindinsight/images/training_visualization_architecture.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/training_visualization_architecture.png rename to docs/note/source_zh_cn/design/mindinsight/images/training_visualization_architecture.png diff --git a/docs/source_zh_cn/design/mindinsight/images/training_visualization_data_flow.png b/docs/note/source_zh_cn/design/mindinsight/images/training_visualization_data_flow.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/training_visualization_data_flow.png rename to docs/note/source_zh_cn/design/mindinsight/images/training_visualization_data_flow.png diff --git a/docs/source_zh_cn/design/mindinsight/images/training_visualization_data_model.png b/docs/note/source_zh_cn/design/mindinsight/images/training_visualization_data_model.png similarity index 100% rename from docs/source_zh_cn/design/mindinsight/images/training_visualization_data_model.png rename to docs/note/source_zh_cn/design/mindinsight/images/training_visualization_data_model.png diff --git a/docs/source_zh_cn/design/mindinsight/profiler_design.md b/docs/note/source_zh_cn/design/mindinsight/profiler_design.md similarity index 98% rename from docs/source_zh_cn/design/mindinsight/profiler_design.md rename to docs/note/source_zh_cn/design/mindinsight/profiler_design.md index 0171bd3f9b..cb0832e23e 100644 --- a/docs/source_zh_cn/design/mindinsight/profiler_design.md +++ b/docs/note/source_zh_cn/design/mindinsight/profiler_design.md @@ -1,174 +1,174 @@ -# Profiler设计文档 - -`Linux` `Ascend` `GPU` `模型开发` `模型调优` `框架开发` `中级` `高级` `贡献者` - - - -- [Profiler设计文档](#profiler设计文档) - - [背景](#背景) - - [Profiler框架设计](#profiler架构设计) - - [上下文](#上下文) - - [模块层级结构](#模块层级结构) - - [内部模块交互](#内部模块交互) - - [子模块设计](#准备训练脚本) - - [ProfilerAPI和Controller](#profiler-api-controller) - - [ProfilerAPI和Controller模块介绍](#profiler-api-controller模块介绍) - - [Analyser](#analyser) - - [Analyser模块介绍](#analyser模块介绍) - - [Analyser模块设计](#analyser模块设计) - - [Parser](#parser) - - [Parser模块介绍](#parser模块介绍) - - [Parser模块设计](#parser模块设计) - - [Proposer](#proposer) - - [Proposer模块介绍](#proposer模块介绍) - - [Proposer模块设计](#proposer模块设计) - - - - - -## 背景 - -为了支持用户在MindSpore进行模型开发性能调试,需要提供易用的Profile工具,直观地展现网络模型各维度的性能信息,为用户提供易用、丰富的性能分析功能,帮助用户快速定位网络中性能问题。 - -## Profiler架构设计 -这一章将介绍Profiler的架构设计,第一节从整体Profiler的角度出发介绍其上下文交互关系,第二节将打开Profiler内部,介绍模块层架结构以及模块划分,第三节将介绍模块间的交互调用关系。 - -### 上下文 - -Profiler是MindSpore调试调优工具的一部分,在整个使用过程中的上下文环境如下图所示: - -![context_profiler.png](./images/context_profiler.png) - -图1:上下文关系图 - -如上图所示,Profiler与其他部分的交互包括: - -1. 在训练脚本中调用MindSpore的Profiler向MindSpore的ada通信模块发送启动收集性能数据的命令,最终由ada生成性能原始数据; - -2. MindSpore侧Profiler将在用户脚本中对原始数据进行解析,并在用户指定的文件夹下面生成中间数据结果; - -3. Mindinsight侧Profiler对接中间数据,提供可视化Profiler功能供用户使用。 -### 模块层级结构 - -模块层级划分如下: - -![module_profiler.png](./images/module_profiler.png) - -图2:层级模块关系图 - - -如上图所示,各个模块功能介绍如下: -1. ProfilerAPI是代码侧对用户提供的调用入口,为用户提供了性能收集启动接口以及分析接口; -2. Controller是ProfilerAPI下层的模块,被ProfilerAPI中的启动接口调用,负责控制下方性能收集功能的启动停止,原始数据会被ada写入固定位置; -3. Parser是性能原始数据解析模块,由于性能原始数据是在设备侧收集的信息,所以信息不能直接被用户所理解,该模块负责将信息进行解析、组合、转换,最终形成用户可理解、上层可分析的中间结果; -4. Analyser获取下层Parser解析出的中间结果,负责对中间结果的封装、筛选、排序,最终按照信息分类,返回各个类别对应的信息,提供给上层的表现层Profiler API、RESTful使用; -5. 通过RESTful调用后端Analyser提供的common API,获取目标数据,以RESTful接口对接前端。 - -### 内部模块交互 -从用户角度,有两种使用形式API、RESTful,我们以API为例,阐述一个完整的内部模块交互流程: - -![time_order_profiler.png](./images/time_order_profiler.png) - -图3:模块交互图 - -如上图所示,各个模块交互流程如下: - -1. ProfilerAPI会调用下层Controller的控制函数,控制下层收集模块进行收集,目前收集模块(ada)是以常驻进程的方式接受命令,并独立工作收集性能信息的; - -2. 用户在训练结束后会调用ProfilerAPI的分析接口; - -3. Profiler API分析接口首先使用Parser模块对性能数据进行解析,产生中间结果,再调用Aalayser进行中间结果分析,最终将各类信息返回至用户侧。 - -## 子模块设计 -### ProfilerAPI和Controller - -#### ProfilerAPI和Controller模块说明 -ProfilerAPI为用户在训练脚本侧提供入口API,用户通过ProfilerAPI启动性能收集以及对性能数据进行分析。 -ProfilerAPI通过Controller下发命令,完成对ada启动的控制。 - -#### ProfilerAPI和Controller模块设计 -ProfilerAPI模块,属于上层应用接口层,由训练脚本集成。功能分为两部分: - -- 训练前调用底层Controller接口,下发命令,启动profiling统计任务。 - -- 训练完成后,调用底层Controller接口,下发命令,停止性能统计任务,再调用Analyser、Parser模块接口解析数据文件,生成算子性能统计、training trace统计等结果数据。 - - -Controller模块提供对上层接口,并调用底层性能收集模块接口,下发启动和停止性能收集的命令。 - -最终生成的性能原始数据主要包含: - -- `hwts.log.data.45.dev.profiler_default_tag`文件:存储算子执行信息,包括task的开始/结束,stream id的信息等; -- `DATA_PREPROCESS.dev.AICPU`文件:AI CPU算子的执行各阶段的执行时间信息; -- `Framework.host.task_desc_info`文件:存储算子id与算子名称的对应关系,以及每个算子的输入输出信息; -- `training_trace.46.dev.profiler_default_tag`文件:存储每个step的开始结束时刻,迭代间隙、迭代前向反向、迭代拖尾的时刻信息。 - -### Parser -#### Parser模块介绍 -Parser是原始性能数据解析模块,由于原始性能数据是在设备侧收集的信息,所以信息不能直接被用户所理解,该模块负责将信息进行解析、组合、转换,最终形成用户可理解、上层可分析的中间结果。 -#### Parser模块设计 -![parser_module_profiler.png](./images/parser_module_profiler.png) - -图4:Parser模块图 - -如上图所示,Parser模块主要由HWTS Parser、AI CPU Parser、Framework Parser、Training Trace Parser组成,每个模块对应解析一种原始数据,通过解析原始数据得到用户能读懂的中间文件。 - -- HWTS Parser:解析`hwts.log.data.45.dev.profiler_default_tag`文件,获得Device基于task的统计信息,如每个task的开始/结束,stream id等数据,用于算子执行时间的计算。 -- AI CPU Parser:解析`DATA_PREPROCESS.dev.AICPU`文件,获得AI CPU算子的执行各阶段的执行时间信息。 -- Framework Parser:解析`Framework.host.task_desc_info`文件,用于获取AI Core算子与task的对应关系,算子关键信息等内容。 -- Training Trace Parser:解析`training_trace.46.dev.profiler_default_tag`文件,用于分析训练各阶段的时间。 - -### Analyser - -#### Analyser模块介绍 -分析器的作用是对解析阶段生成的中间结果,进行筛选、排序、查询、分页等相关操作。 - -#### Analyser模块设计 - -该模块负责解析Parser生成的中间文件,为上层数据分析提供通用接口,将分析后的数据返回给上层展示给用户,由于各种中间文件有一定的共同点,可以抽象出公共内容,所以Analyser类设计如下图所示: - -![analyser_class_profiler.png](./images/analyser_class_profiler.png) - -图5:Analyser类图 - -如上图所示,针对期望查询的不同内容,实现多个Analyser,每个Analyser可以定义筛选、排序、分页条件。每个Analyser知道自己需要哪些中间文件来进行数据的合并、筛选、排序。Analyser与Parser是通过Parser生成的中间文件关联起来的,本身不存在函数调用的情况,这样对两个模块进行了解耦。 - -针对算子信息的Analyser,目前存在两种: - -- 针对算子类型平均信息的筛选。 -- 针对每个算子详细平均信息的筛选,分别在两个Analyser中实现(AicoreTypeAnalyser、AicoreDetailAnalyser)。 - -为了隐藏Analyser内部实现,方便调用,使用简单工厂模式,通过AnalyserFactory获取指定的Analyser。 - - -### Proposer -#### Proposer模块介绍 -Proposer是Profiler性能优化建议模块,Proposer调用Analyser模块获取性能数据,通过调优规则对性能数据进行分析,输出调优建议由UI、API接口展示给用户。 - -#### Proposer模块设计 - -模块划分如下所示: - -![proposer_module_profiler.png](./images/proposer_module_profiler.png) - -图6:Proposer模块图 - -模块设计如上图所示: - -- Proposer提供接口用于API、RESTful调用以获取优化建议。 -- Proposer调用Analyser接口,获取性能数据并根据优化规则,获得优化建议。 -- Proposer调用Analyser工厂获得Analyser对象。 - -调用Analyser对象的query接口获取信息,包括:按时间排序TOP N的AICore、AICoreType、AICpu算子信息、traning trace各阶段的时间信息。 - -模块类设计如下所示: - -![proposer_class_profiler.png](./images/proposer_class_profiler.png) - -图7:Proposer类图 - -如上模块类图所示: - -- 各类型Proposer继承抽象类Proposer并实现analyze方法; +# Profiler设计文档 + +`Linux` `Ascend` `GPU` `模型开发` `模型调优` `框架开发` `中级` `高级` `贡献者` + + + +- [Profiler设计文档](#profiler设计文档) + - [背景](#背景) + - [Profiler框架设计](#profiler架构设计) + - [上下文](#上下文) + - [模块层级结构](#模块层级结构) + - [内部模块交互](#内部模块交互) + - [子模块设计](#准备训练脚本) + - [ProfilerAPI和Controller](#profiler-api-controller) + - [ProfilerAPI和Controller模块介绍](#profiler-api-controller模块介绍) + - [Analyser](#analyser) + - [Analyser模块介绍](#analyser模块介绍) + - [Analyser模块设计](#analyser模块设计) + - [Parser](#parser) + - [Parser模块介绍](#parser模块介绍) + - [Parser模块设计](#parser模块设计) + - [Proposer](#proposer) + - [Proposer模块介绍](#proposer模块介绍) + - [Proposer模块设计](#proposer模块设计) + + + + + +## 背景 + +为了支持用户在MindSpore进行模型开发性能调试,需要提供易用的Profile工具,直观地展现网络模型各维度的性能信息,为用户提供易用、丰富的性能分析功能,帮助用户快速定位网络中性能问题。 + +## Profiler架构设计 +这一章将介绍Profiler的架构设计,第一节从整体Profiler的角度出发介绍其上下文交互关系,第二节将打开Profiler内部,介绍模块层架结构以及模块划分,第三节将介绍模块间的交互调用关系。 + +### 上下文 + +Profiler是MindSpore调试调优工具的一部分,在整个使用过程中的上下文环境如下图所示: + +![context_profiler.png](./images/context_profiler.png) + +图1:上下文关系图 + +如上图所示,Profiler与其他部分的交互包括: + +1. 在训练脚本中调用MindSpore的Profiler向MindSpore的ada通信模块发送启动收集性能数据的命令,最终由ada生成性能原始数据; + +2. MindSpore侧Profiler将在用户脚本中对原始数据进行解析,并在用户指定的文件夹下面生成中间数据结果; + +3. Mindinsight侧Profiler对接中间数据,提供可视化Profiler功能供用户使用。 +### 模块层级结构 + +模块层级划分如下: + +![module_profiler.png](./images/module_profiler.png) + +图2:层级模块关系图 + + +如上图所示,各个模块功能介绍如下: +1. ProfilerAPI是代码侧对用户提供的调用入口,为用户提供了性能收集启动接口以及分析接口; +2. Controller是ProfilerAPI下层的模块,被ProfilerAPI中的启动接口调用,负责控制下方性能收集功能的启动停止,原始数据会被ada写入固定位置; +3. Parser是性能原始数据解析模块,由于性能原始数据是在设备侧收集的信息,所以信息不能直接被用户所理解,该模块负责将信息进行解析、组合、转换,最终形成用户可理解、上层可分析的中间结果; +4. Analyser获取下层Parser解析出的中间结果,负责对中间结果的封装、筛选、排序,最终按照信息分类,返回各个类别对应的信息,提供给上层的表现层Profiler API、RESTful使用; +5. 通过RESTful调用后端Analyser提供的common API,获取目标数据,以RESTful接口对接前端。 + +### 内部模块交互 +从用户角度,有两种使用形式API、RESTful,我们以API为例,阐述一个完整的内部模块交互流程: + +![time_order_profiler.png](./images/time_order_profiler.png) + +图3:模块交互图 + +如上图所示,各个模块交互流程如下: + +1. ProfilerAPI会调用下层Controller的控制函数,控制下层收集模块进行收集,目前收集模块(ada)是以常驻进程的方式接受命令,并独立工作收集性能信息的; + +2. 用户在训练结束后会调用ProfilerAPI的分析接口; + +3. Profiler API分析接口首先使用Parser模块对性能数据进行解析,产生中间结果,再调用Aalayser进行中间结果分析,最终将各类信息返回至用户侧。 + +## 子模块设计 +### ProfilerAPI和Controller + +#### ProfilerAPI和Controller模块说明 +ProfilerAPI为用户在训练脚本侧提供入口API,用户通过ProfilerAPI启动性能收集以及对性能数据进行分析。 +ProfilerAPI通过Controller下发命令,完成对ada启动的控制。 + +#### ProfilerAPI和Controller模块设计 +ProfilerAPI模块,属于上层应用接口层,由训练脚本集成。功能分为两部分: + +- 训练前调用底层Controller接口,下发命令,启动profiling统计任务。 + +- 训练完成后,调用底层Controller接口,下发命令,停止性能统计任务,再调用Analyser、Parser模块接口解析数据文件,生成算子性能统计、training trace统计等结果数据。 + + +Controller模块提供对上层接口,并调用底层性能收集模块接口,下发启动和停止性能收集的命令。 + +最终生成的性能原始数据主要包含: + +- `hwts.log.data.45.dev.profiler_default_tag`文件:存储算子执行信息,包括task的开始/结束,stream id的信息等; +- `DATA_PREPROCESS.dev.AICPU`文件:AI CPU算子的执行各阶段的执行时间信息; +- `Framework.host.task_desc_info`文件:存储算子id与算子名称的对应关系,以及每个算子的输入输出信息; +- `training_trace.46.dev.profiler_default_tag`文件:存储每个step的开始结束时刻,迭代间隙、迭代前向反向、迭代拖尾的时刻信息。 + +### Parser +#### Parser模块介绍 +Parser是原始性能数据解析模块,由于原始性能数据是在设备侧收集的信息,所以信息不能直接被用户所理解,该模块负责将信息进行解析、组合、转换,最终形成用户可理解、上层可分析的中间结果。 +#### Parser模块设计 +![parser_module_profiler.png](./images/parser_module_profiler.png) + +图4:Parser模块图 + +如上图所示,Parser模块主要由HWTS Parser、AI CPU Parser、Framework Parser、Training Trace Parser组成,每个模块对应解析一种原始数据,通过解析原始数据得到用户能读懂的中间文件。 + +- HWTS Parser:解析`hwts.log.data.45.dev.profiler_default_tag`文件,获得Device基于task的统计信息,如每个task的开始/结束,stream id等数据,用于算子执行时间的计算。 +- AI CPU Parser:解析`DATA_PREPROCESS.dev.AICPU`文件,获得AI CPU算子的执行各阶段的执行时间信息。 +- Framework Parser:解析`Framework.host.task_desc_info`文件,用于获取AI Core算子与task的对应关系,算子关键信息等内容。 +- Training Trace Parser:解析`training_trace.46.dev.profiler_default_tag`文件,用于分析训练各阶段的时间。 + +### Analyser + +#### Analyser模块介绍 +分析器的作用是对解析阶段生成的中间结果,进行筛选、排序、查询、分页等相关操作。 + +#### Analyser模块设计 + +该模块负责解析Parser生成的中间文件,为上层数据分析提供通用接口,将分析后的数据返回给上层展示给用户,由于各种中间文件有一定的共同点,可以抽象出公共内容,所以Analyser类设计如下图所示: + +![analyser_class_profiler.png](./images/analyser_class_profiler.png) + +图5:Analyser类图 + +如上图所示,针对期望查询的不同内容,实现多个Analyser,每个Analyser可以定义筛选、排序、分页条件。每个Analyser知道自己需要哪些中间文件来进行数据的合并、筛选、排序。Analyser与Parser是通过Parser生成的中间文件关联起来的,本身不存在函数调用的情况,这样对两个模块进行了解耦。 + +针对算子信息的Analyser,目前存在两种: + +- 针对算子类型平均信息的筛选。 +- 针对每个算子详细平均信息的筛选,分别在两个Analyser中实现(AicoreTypeAnalyser、AicoreDetailAnalyser)。 + +为了隐藏Analyser内部实现,方便调用,使用简单工厂模式,通过AnalyserFactory获取指定的Analyser。 + + +### Proposer +#### Proposer模块介绍 +Proposer是Profiler性能优化建议模块,Proposer调用Analyser模块获取性能数据,通过调优规则对性能数据进行分析,输出调优建议由UI、API接口展示给用户。 + +#### Proposer模块设计 + +模块划分如下所示: + +![proposer_module_profiler.png](./images/proposer_module_profiler.png) + +图6:Proposer模块图 + +模块设计如上图所示: + +- Proposer提供接口用于API、RESTful调用以获取优化建议。 +- Proposer调用Analyser接口,获取性能数据并根据优化规则,获得优化建议。 +- Proposer调用Analyser工厂获得Analyser对象。 + +调用Analyser对象的query接口获取信息,包括:按时间排序TOP N的AICore、AICoreType、AICpu算子信息、traning trace各阶段的时间信息。 + +模块类设计如下所示: + +![proposer_class_profiler.png](./images/proposer_class_profiler.png) + +图7:Proposer类图 + +如上模块类图所示: + +- 各类型Proposer继承抽象类Proposer并实现analyze方法; - API、CLI通过调用工厂ProposerFactory获取Proposer,并调用Proposer.analyze函数获取各类型的Proposer分析的优化建议。 \ No newline at end of file diff --git a/docs/source_zh_cn/design/mindinsight/tensor_visual_design.md b/docs/note/source_zh_cn/design/mindinsight/tensor_visual_design.md similarity index 100% rename from docs/source_zh_cn/design/mindinsight/tensor_visual_design.md rename to docs/note/source_zh_cn/design/mindinsight/tensor_visual_design.md diff --git a/docs/source_zh_cn/design/mindinsight/training_visual_design.md b/docs/note/source_zh_cn/design/mindinsight/training_visual_design.md similarity index 100% rename from docs/source_zh_cn/design/mindinsight/training_visual_design.md rename to docs/note/source_zh_cn/design/mindinsight/training_visual_design.md diff --git a/docs/source_zh_cn/design/mindspore/distributed_training_design.md b/docs/note/source_zh_cn/design/mindspore/distributed_training_design.md similarity index 100% rename from docs/source_zh_cn/design/mindspore/distributed_training_design.md rename to docs/note/source_zh_cn/design/mindspore/distributed_training_design.md diff --git a/docs/source_zh_cn/design/mindspore/images/auto_parallel.png b/docs/note/source_zh_cn/design/mindspore/images/auto_parallel.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/auto_parallel.png rename to docs/note/source_zh_cn/design/mindspore/images/auto_parallel.png diff --git a/docs/source_zh_cn/design/mindspore/images/data_parallel.png b/docs/note/source_zh_cn/design/mindspore/images/data_parallel.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/data_parallel.png rename to docs/note/source_zh_cn/design/mindspore/images/data_parallel.png diff --git a/docs/source_zh_cn/design/mindspore/images/ir/cf.dot b/docs/note/source_zh_cn/design/mindspore/images/ir/cf.dot similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/cf.dot rename to docs/note/source_zh_cn/design/mindspore/images/ir/cf.dot diff --git a/docs/source_zh_cn/design/mindspore/images/ir/cf.png b/docs/note/source_zh_cn/design/mindspore/images/ir/cf.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/cf.png rename to docs/note/source_zh_cn/design/mindspore/images/ir/cf.png diff --git a/docs/source_zh_cn/design/mindspore/images/ir/closure.dot b/docs/note/source_zh_cn/design/mindspore/images/ir/closure.dot similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/closure.dot rename to docs/note/source_zh_cn/design/mindspore/images/ir/closure.dot diff --git a/docs/source_zh_cn/design/mindspore/images/ir/closure.png b/docs/note/source_zh_cn/design/mindspore/images/ir/closure.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/closure.png rename to docs/note/source_zh_cn/design/mindspore/images/ir/closure.png diff --git a/docs/source_zh_cn/design/mindspore/images/ir/hof.dot b/docs/note/source_zh_cn/design/mindspore/images/ir/hof.dot similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/hof.dot rename to docs/note/source_zh_cn/design/mindspore/images/ir/hof.dot diff --git a/docs/source_zh_cn/design/mindspore/images/ir/hof.png b/docs/note/source_zh_cn/design/mindspore/images/ir/hof.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/hof.png rename to docs/note/source_zh_cn/design/mindspore/images/ir/hof.png diff --git a/docs/source_zh_cn/design/mindspore/images/ir/ir.dot b/docs/note/source_zh_cn/design/mindspore/images/ir/ir.dot similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/ir.dot rename to docs/note/source_zh_cn/design/mindspore/images/ir/ir.dot diff --git a/docs/source_zh_cn/design/mindspore/images/ir/ir.png b/docs/note/source_zh_cn/design/mindspore/images/ir/ir.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/ir/ir.png rename to docs/note/source_zh_cn/design/mindspore/images/ir/ir.png diff --git a/docs/source_zh_cn/design/mindspore/images/operator_split.png b/docs/note/source_zh_cn/design/mindspore/images/operator_split.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/operator_split.png rename to docs/note/source_zh_cn/design/mindspore/images/operator_split.png diff --git a/docs/source_zh_cn/design/mindspore/images/tensor_redistribution.png b/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/tensor_redistribution.png rename to docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution.png diff --git a/docs/source_zh_cn/design/mindspore/images/tensor_redistribution1.png b/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution1.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/tensor_redistribution1.png rename to docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution1.png diff --git a/docs/source_zh_cn/design/mindspore/images/tensor_redistribution2.png b/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution2.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/tensor_redistribution2.png rename to docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution2.png diff --git a/docs/source_zh_cn/design/mindspore/images/tensor_redistribution3.png b/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution3.png similarity index 100% rename from docs/source_zh_cn/design/mindspore/images/tensor_redistribution3.png rename to docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution3.png diff --git a/docs/source_zh_cn/design/mindspore/ir.md b/docs/note/source_zh_cn/design/mindspore/ir.md similarity index 100% rename from docs/source_zh_cn/design/mindspore/ir.md rename to docs/note/source_zh_cn/design/mindspore/ir.md diff --git a/docs/source_zh_cn/glossary.md b/docs/note/source_zh_cn/glossary.md similarity index 100% rename from docs/source_zh_cn/glossary.md rename to docs/note/source_zh_cn/glossary.md diff --git a/lite/docs/source_zh_cn/glossary.md b/docs/note/source_zh_cn/glossary_lite.md similarity index 100% rename from lite/docs/source_zh_cn/glossary.md rename to docs/note/source_zh_cn/glossary_lite.md diff --git a/docs/source_zh_cn/help_seeking_path.md b/docs/note/source_zh_cn/help_seeking_path.md similarity index 100% rename from docs/source_zh_cn/help_seeking_path.md rename to docs/note/source_zh_cn/help_seeking_path.md diff --git a/docs/note/source_zh_cn/images/MindSpore-Lite-architecture.png b/docs/note/source_zh_cn/images/MindSpore-Lite-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..abf28796690f5649f8bc92382dfd4c2c83187620 GIT binary patch literal 55828 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 literal 0 HcmV?d00001 diff --git a/docs/source_zh_cn/images/architecture.eddx b/docs/note/source_zh_cn/images/architecture.eddx similarity index 100% rename from docs/source_zh_cn/images/architecture.eddx rename to docs/note/source_zh_cn/images/architecture.eddx diff --git a/docs/source_zh_cn/images/architecture.png b/docs/note/source_zh_cn/images/architecture.png similarity index 100% rename from docs/source_zh_cn/images/architecture.png rename to docs/note/source_zh_cn/images/architecture.png diff --git a/docs/source_zh_cn/images/help_seeking_path.png b/docs/note/source_zh_cn/images/help_seeking_path.png similarity index 100% rename from docs/source_zh_cn/images/help_seeking_path.png rename to docs/note/source_zh_cn/images/help_seeking_path.png diff --git a/docs/source_zh_cn/index.rst b/docs/note/source_zh_cn/index.rst similarity index 100% rename from docs/source_zh_cn/index.rst rename to docs/note/source_zh_cn/index.rst diff --git a/lite/docs/source_zh_cn/index.rst b/docs/note/source_zh_cn/index_lite.rst similarity index 100% rename from lite/docs/source_zh_cn/index.rst rename to docs/note/source_zh_cn/index_lite.rst diff --git a/docs/source_zh_cn/network_list.md b/docs/note/source_zh_cn/network_list.md similarity index 99% rename from docs/source_zh_cn/network_list.md rename to docs/note/source_zh_cn/network_list.md index 351a5223c2..638b9518ac 100644 --- a/docs/source_zh_cn/network_list.md +++ b/docs/note/source_zh_cn/network_list.md @@ -1,60 +1,60 @@ -# 网络支持 - -`Linux` `Ascend` `GPU` `CPU` `模型开发` `中级` `高级` - - - -- [网络支持](#网络支持) - - [Model Zoo](#model-zoo) - - [预训练模型](#预训练模型) - - - - - -## Model Zoo - -| 领域 | 子领域 | 网络 | Ascend | GPU | CPU -|:---- |:------- |:---- |:---- |:---- |:---- -|计算机视觉(CV) | 图像分类(Image Classification) | [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | Supported | Supported | Doing -| 计算机视觉(CV) | 图像分类(Image Classification) | [GoogleNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/src/googlenet.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 图像分类(Image Classification) | [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py) | Supported | Supported | Supported -| 计算机视觉(CV) | 图像分类(Image Classification) | [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported | Supported | Doing -|计算机视觉(CV) | 图像分类(Image Classification) | [ResNet-101](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing -|计算机视觉(CV) | 图像分类(Image Classification) | [SE-ResNet50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing -|计算机视觉(CV) | 图像分类(Image Classification) | [ResNext50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnext50/src/image_classification.py) | Supported | Supported | Doing -| 计算机视觉(CV) | 图像分类(Image Classification) | [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 图像分类(Image Classification) | [InceptionV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/inceptionv3/src/inception_v3.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 移动端图像分类(Mobile Image Classification)
目标检测(Image Classification)
语义分割(Semantic Tegmentation) | [MobileNetV2](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv2/src/mobilenetV2.py) | Supported | Supported | Doing -| 计算机视觉(CV) | 移动端图像分类(Mobile Image Classification)
目标检测(Image Classification)
语义分割(Semantic Tegmentation) | [MobileNetV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv3/src/mobilenetV3.py) | Doing | Supported | Doing -|计算机视觉(CV) | 目标检测(Targets Detection) | [SSD](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/ssd/src/ssd.py) | Supported |Doing | Doing -| 计算机视觉(CV) | 目标检测(Targets Detection) | [YoloV3-ResNet18](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_resnet18/src/yolov3.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 目标检测(Targets Detection) | [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 目标检测(Targets Detection) | [FasterRCNN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/faster_rcnn/src/FasterRcnn/faster_rcnn_r50.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 语义分割(Semantic Segmentation) | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/deeplabv3.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 目标检测(Targets Detection) | [WarpCTC](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/warpctc/src/warpctc.py) | Doing | Supported | Doing -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [BERT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | Supported | Doing | Doing -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py) | Supported | Doing | Doing -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [SentimentNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/lstm/src/lstm.py) | Doing | Supported | Supported -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [MASS](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/mass/src/transformer/transformer_for_train.py) | Supported | Doing | Doing -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [TinyBert](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/tinybert/src/tinybert_model.py) | Supported | Supported | Doing -| 推荐(Recommender) | 推荐系统、点击率预估(Recommender System, CTR prediction) | [DeepFM](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/deepfm/src/deepfm.py) | Supported | Supported | Doing -| 推荐(Recommender) | 推荐系统、搜索、排序(Recommender System, Search ranking) | [Wide&Deep](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/wide_and_deep/src/wide_and_deep.py) | Supported | Supported | Doing -| 图神经网络(GNN) | 文本分类(Text Classification) | [GCN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gcn/src/gcn.py) | Supported | Doing | Doing -| 图神经网络(GNN) | 文本分类(Text Classification) | [GAT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gat/src/gat.py) | Supported | Doing | Doing - -> 你也可以使用 [MindWizard工具](https://gitee.com/mindspore/mindinsight/tree/master/mindinsight/wizard/) 快速生成经典网络脚本。 - -## 预训练模型 -*代表MindSpore已发布的版本号,支持网络训练的硬件平台有CPU、GPU和Ascend,以下表格中 ✓ 代表模型是基于选中的硬件平台训练而来。 - -| 领域 | 子领域 | 网络 |数据集 | CPU | GPU | Ascend | 0.5.0-beta* -|:---- |:----- |:---- |:---- |:---- |:---- |:---- |:------ -|计算机视觉(CV) | 图像分类(Image Classification) | [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | CIFAR-10 | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/alexnet/alexnet_ascend_0.5.0_cifar10_official_classification_20200716.tar.gz) -|计算机视觉(CV) | 图像分类(Image Classification)| [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py)| MNIST | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/lenet/lenet_ascend_0.5.0_mnist_official_classification_20200716.tar.gz) -|计算机视觉(CV) | 图像分类(Image Classification)| [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py)|CIFAR-10 | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/vgg/vgg16_ascend_0.5.0_cifar10_official_classification_20200715.tar.gz) -|计算机视觉(CV) | 图像分类(Image Classification)| [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) |CIFAR-10 | | | ✓ |[下载](http://download.mindspore.cn/model_zoo/official/cv/resnet/resnet50_v1.5_ascend_0.3.0_cifar10_official_classification_20200718.tar.gz) -|计算机视觉(CV) | 目标检测(Targets Detection)| [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/cv/yolov3_darknet53) |COCO 2014 | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/yolo/yolov3_darknet53_ascend_0.5.0_coco2014_official_object_detection_20200717.tar.gz) -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding)| [BERT_Base](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | zhwiki | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_base_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding)| [BERT_NEZHA](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py)| zhwiki | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_nezha_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) -| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding)| [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py)|WMT English-German | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/nlp/transformer/transformer_ascend_0.5.0_wmtende_official_machine_translation_20200713.tar.gz) +# 网络支持 + +`Linux` `Ascend` `GPU` `CPU` `模型开发` `中级` `高级` + + + +- [网络支持](#网络支持) + - [Model Zoo](#model-zoo) + - [预训练模型](#预训练模型) + + + + + +## Model Zoo + +| 领域 | 子领域 | 网络 | Ascend | GPU | CPU +|:---- |:------- |:---- |:---- |:---- |:---- +|计算机视觉(CV) | 图像分类(Image Classification) | [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | Supported | Supported | Doing +| 计算机视觉(CV) | 图像分类(Image Classification) | [GoogleNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/src/googlenet.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 图像分类(Image Classification) | [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py) | Supported | Supported | Supported +| 计算机视觉(CV) | 图像分类(Image Classification) | [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported | Supported | Doing +|计算机视觉(CV) | 图像分类(Image Classification) | [ResNet-101](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing +|计算机视觉(CV) | 图像分类(Image Classification) | [SE-ResNet50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) | Supported |Doing | Doing +|计算机视觉(CV) | 图像分类(Image Classification) | [ResNext50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnext50/src/image_classification.py) | Supported | Supported | Doing +| 计算机视觉(CV) | 图像分类(Image Classification) | [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 图像分类(Image Classification) | [InceptionV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/inceptionv3/src/inception_v3.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 移动端图像分类(Mobile Image Classification)
目标检测(Image Classification)
语义分割(Semantic Tegmentation) | [MobileNetV2](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv2/src/mobilenetV2.py) | Supported | Supported | Doing +| 计算机视觉(CV) | 移动端图像分类(Mobile Image Classification)
目标检测(Image Classification)
语义分割(Semantic Tegmentation) | [MobileNetV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/mobilenetv3/src/mobilenetV3.py) | Doing | Supported | Doing +|计算机视觉(CV) | 目标检测(Targets Detection) | [SSD](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/ssd/src/ssd.py) | Supported |Doing | Doing +| 计算机视觉(CV) | 目标检测(Targets Detection) | [YoloV3-ResNet18](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_resnet18/src/yolov3.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 目标检测(Targets Detection) | [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 目标检测(Targets Detection) | [FasterRCNN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/faster_rcnn/src/FasterRcnn/faster_rcnn_r50.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 语义分割(Semantic Segmentation) | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/deeplabv3.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 目标检测(Targets Detection) | [WarpCTC](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/warpctc/src/warpctc.py) | Doing | Supported | Doing +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [BERT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | Supported | Doing | Doing +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py) | Supported | Doing | Doing +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [SentimentNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/lstm/src/lstm.py) | Doing | Supported | Supported +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [MASS](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/mass/src/transformer/transformer_for_train.py) | Supported | Doing | Doing +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [TinyBert](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/tinybert/src/tinybert_model.py) | Supported | Supported | Doing +| 推荐(Recommender) | 推荐系统、点击率预估(Recommender System, CTR prediction) | [DeepFM](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/deepfm/src/deepfm.py) | Supported | Supported | Doing +| 推荐(Recommender) | 推荐系统、搜索、排序(Recommender System, Search ranking) | [Wide&Deep](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/recommend/wide_and_deep/src/wide_and_deep.py) | Supported | Supported | Doing +| 图神经网络(GNN) | 文本分类(Text Classification) | [GCN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gcn/src/gcn.py) | Supported | Doing | Doing +| 图神经网络(GNN) | 文本分类(Text Classification) | [GAT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/gnn/gat/src/gat.py) | Supported | Doing | Doing + +> 你也可以使用 [MindWizard工具](https://gitee.com/mindspore/mindinsight/tree/master/mindinsight/wizard/) 快速生成经典网络脚本。 + +## 预训练模型 +*代表MindSpore已发布的版本号,支持网络训练的硬件平台有CPU、GPU和Ascend,以下表格中 ✓ 代表模型是基于选中的硬件平台训练而来。 + +| 领域 | 子领域 | 网络 |数据集 | CPU | GPU | Ascend | 0.5.0-beta* +|:---- |:----- |:---- |:---- |:---- |:---- |:---- |:------ +|计算机视觉(CV) | 图像分类(Image Classification) | [AlexNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/alexnet/src/alexnet.py) | CIFAR-10 | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/alexnet/alexnet_ascend_0.5.0_cifar10_official_classification_20200716.tar.gz) +|计算机视觉(CV) | 图像分类(Image Classification)| [LeNet](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/src/lenet.py)| MNIST | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/lenet/lenet_ascend_0.5.0_mnist_official_classification_20200716.tar.gz) +|计算机视觉(CV) | 图像分类(Image Classification)| [VGG16](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/vgg16/src/vgg.py)|CIFAR-10 | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/vgg/vgg16_ascend_0.5.0_cifar10_official_classification_20200715.tar.gz) +|计算机视觉(CV) | 图像分类(Image Classification)| [ResNet-50](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py) |CIFAR-10 | | | ✓ |[下载](http://download.mindspore.cn/model_zoo/official/cv/resnet/resnet50_v1.5_ascend_0.3.0_cifar10_official_classification_20200718.tar.gz) +|计算机视觉(CV) | 目标检测(Targets Detection)| [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/cv/yolov3_darknet53) |COCO 2014 | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/cv/yolo/yolov3_darknet53_ascend_0.5.0_coco2014_official_object_detection_20200717.tar.gz) +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding)| [BERT_Base](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | zhwiki | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_base_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding)| [BERT_NEZHA](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py)| zhwiki | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/nlp/bert/bert_nezha_ascend_0.5.0_cn-wiki_official_nlp_20200720.tar.gz) +| 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding)| [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py)|WMT English-German | | | ✓ | [下载](http://download.mindspore.cn/model_zoo/official/nlp/transformer/transformer_ascend_0.5.0_wmtende_official_machine_translation_20200713.tar.gz) diff --git a/docs/source_zh_cn/operator_list.md b/docs/note/source_zh_cn/operator_list.md similarity index 100% rename from docs/source_zh_cn/operator_list.md rename to docs/note/source_zh_cn/operator_list.md diff --git a/lite/docs/source_zh_cn/operator_list.md b/docs/note/source_zh_cn/operator_list_lite.md similarity index 100% rename from lite/docs/source_zh_cn/operator_list.md rename to docs/note/source_zh_cn/operator_list_lite.md diff --git a/docs/source_zh_cn/roadmap.md b/docs/note/source_zh_cn/roadmap.md similarity index 100% rename from docs/source_zh_cn/roadmap.md rename to docs/note/source_zh_cn/roadmap.md diff --git a/docs/source_zh_cn/technical_white_paper.md b/docs/note/source_zh_cn/technical_white_paper.md similarity index 100% rename from docs/source_zh_cn/technical_white_paper.md rename to docs/note/source_zh_cn/technical_white_paper.md diff --git a/docs/programming_guide/Makefile b/docs/programming_guide/Makefile new file mode 100644 index 0000000000..1eff895270 --- /dev/null +++ b/docs/programming_guide/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source_zh_cn +BUILDDIR = build_zh_cn + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/programming_guide/requirements.txt b/docs/programming_guide/requirements.txt new file mode 100644 index 0000000000..162b500402 --- /dev/null +++ b/docs/programming_guide/requirements.txt @@ -0,0 +1,6 @@ +sphinx >= 2.2.1, <= 2.4.4 +recommonmark +sphinx-markdown-tables +sphinx_rtd_theme +numpy +jieba diff --git a/api/source_zh_cn/programming_guide/api_structure.md b/docs/programming_guide/source_zh_cn/api_structure.md similarity index 100% rename from api/source_zh_cn/programming_guide/api_structure.md rename to docs/programming_guide/source_zh_cn/api_structure.md diff --git a/api/source_zh_cn/programming_guide/augmentation.md b/docs/programming_guide/source_zh_cn/augmentation.md similarity index 100% rename from api/source_zh_cn/programming_guide/augmentation.md rename to docs/programming_guide/source_zh_cn/augmentation.md diff --git a/api/source_zh_cn/programming_guide/auto_augmentation.md b/docs/programming_guide/source_zh_cn/auto_augmentation.md similarity index 100% rename from api/source_zh_cn/programming_guide/auto_augmentation.md rename to docs/programming_guide/source_zh_cn/auto_augmentation.md diff --git a/api/source_zh_cn/programming_guide/auto_parallel_context.md b/docs/programming_guide/source_zh_cn/auto_parallel_context.md similarity index 100% rename from api/source_zh_cn/programming_guide/auto_parallel_context.md rename to docs/programming_guide/source_zh_cn/auto_parallel_context.md diff --git a/api/source_zh_cn/programming_guide/callback.md b/docs/programming_guide/source_zh_cn/callback.md similarity index 100% rename from api/source_zh_cn/programming_guide/callback.md rename to docs/programming_guide/source_zh_cn/callback.md diff --git a/api/source_zh_cn/programming_guide/cell.md b/docs/programming_guide/source_zh_cn/cell.md similarity index 100% rename from api/source_zh_cn/programming_guide/cell.md rename to docs/programming_guide/source_zh_cn/cell.md diff --git a/api/source_zh_cn/programming_guide/component.md b/docs/programming_guide/source_zh_cn/component.md similarity index 100% rename from api/source_zh_cn/programming_guide/component.md rename to docs/programming_guide/source_zh_cn/component.md diff --git a/api/source_zh_cn/programming_guide/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md similarity index 100% rename from api/source_zh_cn/programming_guide/dataset_conversion.md rename to docs/programming_guide/source_zh_cn/dataset_conversion.md diff --git a/api/source_zh_cn/programming_guide/dataset_loading.md b/docs/programming_guide/source_zh_cn/dataset_loading.md similarity index 100% rename from api/source_zh_cn/programming_guide/dataset_loading.md rename to docs/programming_guide/source_zh_cn/dataset_loading.md diff --git a/api/source_zh_cn/programming_guide/images/api_structure.png b/docs/programming_guide/source_zh_cn/images/api_structure.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/api_structure.png rename to docs/programming_guide/source_zh_cn/images/api_structure.png diff --git a/api/source_zh_cn/programming_guide/images/batch.png b/docs/programming_guide/source_zh_cn/images/batch.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/batch.png rename to docs/programming_guide/source_zh_cn/images/batch.png diff --git a/api/source_zh_cn/programming_guide/images/cifar.png b/docs/programming_guide/source_zh_cn/images/cifar.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/cifar.png rename to docs/programming_guide/source_zh_cn/images/cifar.png diff --git a/api/source_zh_cn/programming_guide/images/cifar2.png b/docs/programming_guide/source_zh_cn/images/cifar2.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/cifar2.png rename to docs/programming_guide/source_zh_cn/images/cifar2.png diff --git a/api/source_zh_cn/programming_guide/images/concat.png b/docs/programming_guide/source_zh_cn/images/concat.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/concat.png rename to docs/programming_guide/source_zh_cn/images/concat.png diff --git a/api/source_zh_cn/programming_guide/images/ctrans_invert.png b/docs/programming_guide/source_zh_cn/images/ctrans_invert.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/ctrans_invert.png rename to docs/programming_guide/source_zh_cn/images/ctrans_invert.png diff --git a/api/source_zh_cn/programming_guide/images/ctrans_resize.png b/docs/programming_guide/source_zh_cn/images/ctrans_resize.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/ctrans_resize.png rename to docs/programming_guide/source_zh_cn/images/ctrans_resize.png diff --git a/api/source_zh_cn/programming_guide/images/map.png b/docs/programming_guide/source_zh_cn/images/map.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/map.png rename to docs/programming_guide/source_zh_cn/images/map.png diff --git a/api/source_zh_cn/programming_guide/images/mnist.png b/docs/programming_guide/source_zh_cn/images/mnist.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/mnist.png rename to docs/programming_guide/source_zh_cn/images/mnist.png diff --git a/api/source_zh_cn/programming_guide/images/project.png b/docs/programming_guide/source_zh_cn/images/project.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/project.png rename to docs/programming_guide/source_zh_cn/images/project.png diff --git a/api/source_zh_cn/programming_guide/images/pytrans_compose.png b/docs/programming_guide/source_zh_cn/images/pytrans_compose.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/pytrans_compose.png rename to docs/programming_guide/source_zh_cn/images/pytrans_compose.png diff --git a/api/source_zh_cn/programming_guide/images/randomcrop.png b/docs/programming_guide/source_zh_cn/images/randomcrop.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/randomcrop.png rename to docs/programming_guide/source_zh_cn/images/randomcrop.png diff --git a/api/source_zh_cn/programming_guide/images/randomhorizontalflip.png b/docs/programming_guide/source_zh_cn/images/randomhorizontalflip.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/randomhorizontalflip.png rename to docs/programming_guide/source_zh_cn/images/randomhorizontalflip.png diff --git a/api/source_zh_cn/programming_guide/images/rename.png b/docs/programming_guide/source_zh_cn/images/rename.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/rename.png rename to docs/programming_guide/source_zh_cn/images/rename.png diff --git a/api/source_zh_cn/programming_guide/images/repeat.png b/docs/programming_guide/source_zh_cn/images/repeat.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/repeat.png rename to docs/programming_guide/source_zh_cn/images/repeat.png diff --git a/api/source_zh_cn/programming_guide/images/shuffle.png b/docs/programming_guide/source_zh_cn/images/shuffle.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/shuffle.png rename to docs/programming_guide/source_zh_cn/images/shuffle.png diff --git a/api/source_zh_cn/programming_guide/images/take.png b/docs/programming_guide/source_zh_cn/images/take.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/take.png rename to docs/programming_guide/source_zh_cn/images/take.png diff --git a/api/source_zh_cn/programming_guide/images/tranform_bad.png b/docs/programming_guide/source_zh_cn/images/tranform_bad.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/tranform_bad.png rename to docs/programming_guide/source_zh_cn/images/tranform_bad.png diff --git a/api/source_zh_cn/programming_guide/images/tranform_good_1.png b/docs/programming_guide/source_zh_cn/images/tranform_good_1.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/tranform_good_1.png rename to docs/programming_guide/source_zh_cn/images/tranform_good_1.png diff --git a/api/source_zh_cn/programming_guide/images/tranform_good_2.png b/docs/programming_guide/source_zh_cn/images/tranform_good_2.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/tranform_good_2.png rename to docs/programming_guide/source_zh_cn/images/tranform_good_2.png diff --git a/api/source_zh_cn/programming_guide/images/tranform_good_3.png b/docs/programming_guide/source_zh_cn/images/tranform_good_3.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/tranform_good_3.png rename to docs/programming_guide/source_zh_cn/images/tranform_good_3.png diff --git a/api/source_zh_cn/programming_guide/images/tranform_pipeline.png b/docs/programming_guide/source_zh_cn/images/tranform_pipeline.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/tranform_pipeline.png rename to docs/programming_guide/source_zh_cn/images/tranform_pipeline.png diff --git a/api/source_zh_cn/programming_guide/images/zip.png b/docs/programming_guide/source_zh_cn/images/zip.png similarity index 100% rename from api/source_zh_cn/programming_guide/images/zip.png rename to docs/programming_guide/source_zh_cn/images/zip.png diff --git a/api/source_zh_cn/programming_guide/nn.md b/docs/programming_guide/source_zh_cn/nn.md similarity index 100% rename from api/source_zh_cn/programming_guide/nn.md rename to docs/programming_guide/source_zh_cn/nn.md diff --git a/api/source_zh_cn/programming_guide/operator.md b/docs/programming_guide/source_zh_cn/operator.md similarity index 96% rename from api/source_zh_cn/programming_guide/operator.md rename to docs/programming_guide/source_zh_cn/operator.md index a62e225025..0bf4eb35f4 100644 --- a/api/source_zh_cn/programming_guide/operator.md +++ b/docs/programming_guide/source_zh_cn/operator.md @@ -1,454 +1,454 @@ -# 算子组件 - -算子组件指常用的算子及其操作,按功能大致可分为张量操作,网络操作,数组操作,图像操作,编码操作,调试操作,量化操作等七个模块。所有的算子在Ascend芯片或者CPU, GPU的支持情况,参见[这里](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html "list") - - -这七类算子操作的相互关系见下: - - - -- [算子组件](#算子组件) - - [张量操作](#张量操作) - - [标量运算](#标量运算) - - [加法](#加法) - - [Element-wise 除法](#element-wise-除法) - - [Element-wise 乘](#element-wise-乘) - - [三角函数](#求三角函数) - - [向量运算](#向量运算) - - [Concat](#concat-算子) - - [Squeeze](#squeeze) - - [Sparse2Dense](#求sparse2dense改变tensor维度使其变稠密) - - [ScalarCast](#scalarcast) - - [矩阵运算](#矩阵运算) - - [矩阵乘法](#矩阵乘法) - - [常见范数](#常见范数) - - [广播机制](#广播机制) - - [网络操作](#网络操作) - - [特征提取](#特征提取) - - [卷积操作](#卷积操作) - - [卷积的反向传播操作](#卷积的反向传播算子操作) - - [激活函数](#激活函数) - - [LossFunction](#lossfunction) - - [L1 Loss](#l1loss) - - [优化算法](#优化算法) - - [SGD](#sgd) - - [数组操作](#数组操作) - - [DType](#dtype) - - [Cast](#cast) - - [Shape](#shape) - - [图像操作](#图像操作) - - [编码运算](#编码运算) - - [BoundingBoxEncode](#boundingboxencode) - - [BoundingBoxDecode](#boundingboxdecode) - - [IOU](#iou-计算) - - [调试操作](#调试操作) - - [Debug](#debug) - - [HookBackward](#hookbackward) - - [量化操作](#量化操作) - - [MinMaxUpdatePerLayer](#minmaxupdateperlayer) - - - - - -## 张量操作 - - -主要包括张量的结构操作和张量的数学运算。 -张量结构操作诸如:张量创建,索引切片,维度变换,合并分割。 -张量数学运算主要有:标量运算,向量运算,矩阵运算。另外我们会介绍张量运算的广播机制。 -本篇我们介绍张量的数学运算。 - - - -### 标量运算 -张量的数学运算符可以分为标量运算符、向量运算符、以及矩阵运算符。 -加减乘除乘方,以及三角函数,指数,对数等常见函数,逻辑比较运算符等都是标量运算符。 -标量运算符的特点是对张量实施逐元素运算。 -有些标量运算符对常用的数学运算符进行了重载。并且支持类似numpy的广播特性。 - -举例说明: -```python -import numpy as np -import mindspore # 导入mindspore包 -from mindspore import Tensor # 导入mindspore下的Tensor包 -import mindspore.ops.operations as P -input_x = mindspore.Tensor(np.array([1.0, 2.0, 4.0]), mindspore.float32) -input_y = 3.0 -input_x**input_y -``` - -真实输入为: -```python -print(input_x) -[ 1. 8. 64.] -``` - -真实输出为: -```python -print(input_x**input_y) -[ 1. 8. 64.] -``` - -#### 加法 -```python -input_x + input_y -[4.0 5.0 7.0] -``` - -除普通加外,还有element-wise加法: -```python -net = NetAddN() -input_x = Tensor(np.array([1, 2, 3]), mindspore.float32) -input_y = Tensor(np.array([4, 5, 6]), mindspore.float32) -net(input_x, input_y, input_x, input_y)[10.0, 14.0, 18.0] -``` - -#### Element-wise 除法 -```python -input_x = Tensor(np.array([-4.0, 5.0, 6.0]), mindspore.float32) -input_y = Tensor(np.array([3.0, 2.0, 3.0]), mindspore.float32) -div = P.Div() -div(input_x, input_y) -``` - -求FloorDiv: -```python -input_x = Tensor(np.array([2, 4, -1]), mindspore.int32)) -input_y = Tensor(np.array([3, 3, 3]), mindspore.int32) -floor_div = P.FloorDiv() -floor_div(input_x, input_y)[0, 1, -1] -``` - -#### Element-wise 乘 -```python -input_x = Tensor(np.array([1.0, 2.0, 3.0]), mindspore.float32) -input_y = Tensor(np.array([4.0, 5.0, 6.0]), mindspore.float32) -mul = P.Mul() -mul(input_x, input_y) -``` - -真实输出: -```python -[4, 10, 18] -``` - -#### 求三角函数: -```python -acos = P.ACos() -input_x = Tensor(np.array([0.74, 0.04, 0.30, 0.56]), mindspore.float32) -output = acos(input_x) -``` - -### 向量运算 -向量运算符只在一个特定轴上运算,将一个向量映射到一个标量或者另外一个向量。 - -#### Concat 算子: -```python -data1 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) -data2 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) -op = P.Concat() -output = op((data1, data2)) -``` - -#### Squeeze -```python -input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32) -squeeze = P.Squeeze(2) -output = squeeze(input_tensor) -``` - -#### 求Sparse2Dense(改变tensor维度使其变稠密): -```python -indices = Tensor([[0, 1], [1, 2]]) -values = Tensor([1, 2], dtype=ms.float32) -dense_shape = (3, 4) -out = P.SparseToDense()(indices, values, dense_shape) -``` - -#### ScalarCast: -```python -scalar_cast = P.ScalarCast() -output = scalar_cast(255.0, mindspore.int32) -``` - -### 矩阵运算 -矩阵运算包括: 矩阵乘法,矩阵范数,矩阵行列式,矩阵求特征值,矩阵分解等运算。 - -#### 矩阵乘法: -```python -input_x = Tensor(np.ones(shape=[1, 3]), mindspore.float32) -input_y = Tensor(np.ones(shape=[3, 4]), mindspore.float32) -matmul = P.MatMul() -output = matmul(input_x, input_y) -``` - -#### 常见范数: - -```python -input_x = Tensor(np.ones([128, 64, 32, 64]), mindspore.float32) -scale = Tensor(np.ones([64]), mindspore.float32) -bias = Tensor(np.ones([64]), mindspore.float32) -mean = Tensor(np.ones([64]), mindspore.float32) -variance = Tensor(np.ones([64]), mindspore.float32) -batch_norm = P.BatchNorm() -output = batch_norm(input_x, scale, bias, mean, variance) -``` - -#### 广播机制 - -Broadcast 广播一个tensor到整个group -举例说明: -```python -from mindspore import Tensor -from mindspore.communication import init -import mindspore.nn as nn -import mindspore.ops.operations as P -init() -class Net(nn.Cell): - def __init__(self): - super(Net, self).__init__() - self.broadcast = P.Broadcast(1) - - def construct(self, x): - return self.broadcast((x,)) - -input_ = Tensor(np.ones([2, 8]).astype(np.float32)) -net = Net() -output = net(input_) -``` - -## 网络操作 - - -网络操作包括特征提取, 激活函数, LossFunction, 优化算法等: - -### 特征提取 - -#### 卷积操作 -举例说明: -```python -input = Tensor(np.ones([10, 32, 32, 32]), mindspore.float32) -weight = Tensor(np.ones([32, 32, 3, 3]), mindspore.float32)) -conv2d = P.Conv2D(out_channel=32, kernel_size=3) -conv2d(input, weight) -``` - -#### 卷积的反向传播算子操作: -输出结果: -```python -dout = Tensor(np.ones([10, 32, 30, 30]), mindspore.float32) -weight = Tensor(np.ones([32, 32, 3, 3]), mindspore.float32) -x = Tensor(np.ones([10, 32, 32, 32])) -conv2d_backprop_input = P.Conv2DBackpropInput(out_channel=32, kernel_size=3) -conv2d_backprop_input(dout, weight, F.shape(x)) -``` - -### 激活函数 -举例说明: -```python -input_x = Tensor(np.array([1, 2, 3, 4, 5]), mindspore.float32) -softmax = P.Softmax() -softmax(input_x) -``` - -输出结果: -```python -[0.01165623, 0.03168492, 0.08612854, 0.23412167, 0.6364086] -``` - -### LossFunction - -#### L1Loss: -举例说明: -```python -loss = P.SmoothL1Loss() -input_data = Tensor(np.array([1, 2, 3]), mindspore.float32) -target_data = Tensor(np.array([1, 2, 2]), mindspore.float32) -loss(input_data, target_data) -``` - -输出结果: -```python -[0, 0, 0.5] -``` - -### 优化算法 -#### SGD: -```python -sgd = P.SGD() -parameters = Tensor(np.array([2, -0.5, 1.7, 4]), mindspore.float32) -gradient = Tensor(np.array([1, -1, 0.5, 2]), mindspore.float32) -learning_rate = Tensor(0.01, mindspore.float32) -accum = Tensor(np.array([0.1, 0.3, -0.2, -0.1]), mindspore.float32) -momentum = Tensor(0.1, mindspore.float32) -stat = Tensor(np.array([1.5, -0.3, 0.2, -0.7]), mindspore.float32) -result = sgd(parameters, gradient, learning_rate, accum, momentum, stat) -``` - -## 数组操作 - - - -数组操作指操作对象是一些数组的操作。 - -### DType -返回跟输入的数据类型一致的并且适配Mindspore的tensor变量, 常用于Mindspore 工程内。 -举例说明: -```python -input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32) -type = P.DType()(input_tensor) -``` - -### Cast -转换输入的数据类型并且输出与目标数据类型相同的变量 -举例说明: -```python -input_np = np.random.randn(2, 3, 4, 5).astype(np.float32) -input_x = Tensor(input_np) -type_dst = mindspore.float16 -cast = P.Cast() -result = cast(input_x, type_dst) -``` - -### Shape -返回输入数据的形状 -举例说明: -```python -input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32) -shape = P.Shape() -output = shape(input_tensor) -``` - -## 图像操作 - - -图像操作包括图像预处理操作, 如图像剪切(Crop,便于得到大量训练样本)和大小变化(Reise,用于构建图像金子塔等): - -举例说明: -```python -class CropAndResizeNet(nn.Cell): - def __init__(self, crop_size): - super(CropAndResizeNet, self).__init__() - self.crop_and_resize = P.CropAndResize() - self.crop_size = crop_size - @ms_function - def construct(self, x, boxes, box_index): - return self.crop_and_resize(x, boxes, box_index, self.crop_size) - -BATCH_SIZE = 1 -NUM_BOXES = 5 -IMAGE_HEIGHT = 256 -IMAGE_WIDTH = 256 -CHANNELS = 3 -image = np.random.normal(size=[BATCH_SIZE, IMAGE_HEIGHT, IMAGE_WIDTH, CHANNELS]).astype(np.float32) -boxes = np.random.uniform(size=[NUM_BOXES, 4]).astype(np.float32) -box_index = np.random.uniform(size=[NUM_BOXES], low=0, high=BATCH_SIZE).astype(np.int32) -crop_size = (24, 24) -crop_and_resize = CropAndResizeNet(crop_size=crop_size) -output = crop_and_resize(Tensor(image), Tensor(boxes), Tensor(box_index)) -print(output.asnumpy()) -``` - -## 编码运算 - - -编码运算包括 BoundingBox Encoding和 BoundingBox Decoding, IOU计算等。 - -### BoundingBoxEncode -对物体所在区域方框进行编码,得到类似PCA的更精简信息,以便做后续类似特征提取,物体检测,图像恢复等任务。 - -举例说明: -```python -anchor_box = Tensor([[4,1,2,1],[2,2,2,3]],mindspore.float32) -groundtruth_box = Tensor([[3,1,2,2],[1,2,1,4]],mindspore.float32) -boundingbox_encode = P.BoundingBoxEncode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0)) -boundingbox_encode(anchor_box, groundtruth_box) -``` -输出结果为: -```python -[[5.0000000e-01 5.0000000e-01 -6.5504000e+04 6.9335938e-01] - [-1.0000000e+00 2.5000000e-01 0.0000000e+00 4.0551758e-01]] -``` - -### BoundingBoxDecode -编码器对区域位置信息解码之后,用此算子进行解码。 - -举例说明: -```python -anchor_box = Tensor([[4,1,2,1],[2,2,2,3]],mindspore.float32) -deltas = Tensor([[3,1,2,2],[1,s2,1,4]],mindspore.float32) -boundingbox_decode = P.BoundingBoxDecode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0), max_shape=(768, 1280), wh_ratio_clip=0.016) -boundingbox_decode(anchor_box, deltas) -``` -输出结果: -```python -[[4.1953125 0. 0. 5.1953125] - [2.140625 0. 3.859375 60.59375]] -``` - -### IOU 计算: -计算预测的物体所在方框和真实物体所在方框的交集区域与并集区域的占比大小。其常作为一种损失函数,用以优化模型。 - -举例说明: -```python -iou = P.IOU() -anchor_boxes = Tensor(np.random.randint(1.0, 5.0, [3, 4]), mindspore.float16) -gt_boxes = Tensor(np.random.randint(1.0, 5.0, [3, 4]), mindspore.float16) -``` - -## 调试操作 -调试操作指的是用于调试网络的一些常用算子及其操作, 例如Debug等 - -### Debug -输出tensor变量的数值, 方便用户随时随地打印想了解或者debug必需的某变量数值。 - -参考示例: -```python -class DebugNN(nn.Cell): - def __init__(self,): - self.debug = nn.Debug() - - def construct(self, x, y): - x = self.add(x, y) - self.debug(x) - return x -``` - -### HookBackward -打印中间变量的梯度,这一算子特别常用,遂举例在此,虽目前仅支持Pynative 形式 -参考示例: -```python -def hook_fn(grad_out): - print(grad_out) - -grad_all = GradOperation(get_all=True) -hook = P.HookBackward(hook_fn) - -def hook_test(x, y): - z = x * y - z = hook(z) - z = z * y - return z - -def backward(x, y): - return grad_all(hook_test)(x, y) - -backward(1, 2) -``` - -## 量化操作 - - -量化操作指对tensor做量化或者反量化操作。 量化操作指将浮点数用整数的加和表示,利用整数加和并行加速时速度快的优点, 实 -现在可接受精度损失下的性能提升。反量化指其反过程,其在精度要求高的地方常被用到。 - -### MinMaxUpdatePerLayer -完成在训练时的量化和反量化操作 -举例说明: -```python -input_tensor = Tensor(np.random.rand(3, 16, 5, 5), mstype.float32) -min_tensor = Tensor(np.array([-6]), mstype.float32) -max_tensor = Tensor(np.array([6]), mstype.float32) -output_tensor = FakeQuantPerLayer(num_bits=8)(input_tensor, min_tensor, max_tensor) -``` +# 算子组件 + +算子组件指常用的算子及其操作,按功能大致可分为张量操作,网络操作,数组操作,图像操作,编码操作,调试操作,量化操作等七个模块。所有的算子在Ascend芯片或者CPU, GPU的支持情况,参见[这里](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html "list") + + +这七类算子操作的相互关系见下: + + + +- [算子组件](#算子组件) + - [张量操作](#张量操作) + - [标量运算](#标量运算) + - [加法](#加法) + - [Element-wise 除法](#element-wise-除法) + - [Element-wise 乘](#element-wise-乘) + - [三角函数](#求三角函数) + - [向量运算](#向量运算) + - [Concat](#concat-算子) + - [Squeeze](#squeeze) + - [Sparse2Dense](#求sparse2dense改变tensor维度使其变稠密) + - [ScalarCast](#scalarcast) + - [矩阵运算](#矩阵运算) + - [矩阵乘法](#矩阵乘法) + - [常见范数](#常见范数) + - [广播机制](#广播机制) + - [网络操作](#网络操作) + - [特征提取](#特征提取) + - [卷积操作](#卷积操作) + - [卷积的反向传播操作](#卷积的反向传播算子操作) + - [激活函数](#激活函数) + - [LossFunction](#lossfunction) + - [L1 Loss](#l1loss) + - [优化算法](#优化算法) + - [SGD](#sgd) + - [数组操作](#数组操作) + - [DType](#dtype) + - [Cast](#cast) + - [Shape](#shape) + - [图像操作](#图像操作) + - [编码运算](#编码运算) + - [BoundingBoxEncode](#boundingboxencode) + - [BoundingBoxDecode](#boundingboxdecode) + - [IOU](#iou-计算) + - [调试操作](#调试操作) + - [Debug](#debug) + - [HookBackward](#hookbackward) + - [量化操作](#量化操作) + - [MinMaxUpdatePerLayer](#minmaxupdateperlayer) + + + + + +## 张量操作 + + +主要包括张量的结构操作和张量的数学运算。 +张量结构操作诸如:张量创建,索引切片,维度变换,合并分割。 +张量数学运算主要有:标量运算,向量运算,矩阵运算。另外我们会介绍张量运算的广播机制。 +本篇我们介绍张量的数学运算。 + + + +### 标量运算 +张量的数学运算符可以分为标量运算符、向量运算符、以及矩阵运算符。 +加减乘除乘方,以及三角函数,指数,对数等常见函数,逻辑比较运算符等都是标量运算符。 +标量运算符的特点是对张量实施逐元素运算。 +有些标量运算符对常用的数学运算符进行了重载。并且支持类似numpy的广播特性。 + +举例说明: +```python +import numpy as np +import mindspore # 导入mindspore包 +from mindspore import Tensor # 导入mindspore下的Tensor包 +import mindspore.ops.operations as P +input_x = mindspore.Tensor(np.array([1.0, 2.0, 4.0]), mindspore.float32) +input_y = 3.0 +input_x**input_y +``` + +真实输入为: +```python +print(input_x) +[ 1. 8. 64.] +``` + +真实输出为: +```python +print(input_x**input_y) +[ 1. 8. 64.] +``` + +#### 加法 +```python +input_x + input_y +[4.0 5.0 7.0] +``` + +除普通加外,还有element-wise加法: +```python +net = NetAddN() +input_x = Tensor(np.array([1, 2, 3]), mindspore.float32) +input_y = Tensor(np.array([4, 5, 6]), mindspore.float32) +net(input_x, input_y, input_x, input_y)[10.0, 14.0, 18.0] +``` + +#### Element-wise 除法 +```python +input_x = Tensor(np.array([-4.0, 5.0, 6.0]), mindspore.float32) +input_y = Tensor(np.array([3.0, 2.0, 3.0]), mindspore.float32) +div = P.Div() +div(input_x, input_y) +``` + +求FloorDiv: +```python +input_x = Tensor(np.array([2, 4, -1]), mindspore.int32)) +input_y = Tensor(np.array([3, 3, 3]), mindspore.int32) +floor_div = P.FloorDiv() +floor_div(input_x, input_y)[0, 1, -1] +``` + +#### Element-wise 乘 +```python +input_x = Tensor(np.array([1.0, 2.0, 3.0]), mindspore.float32) +input_y = Tensor(np.array([4.0, 5.0, 6.0]), mindspore.float32) +mul = P.Mul() +mul(input_x, input_y) +``` + +真实输出: +```python +[4, 10, 18] +``` + +#### 求三角函数: +```python +acos = P.ACos() +input_x = Tensor(np.array([0.74, 0.04, 0.30, 0.56]), mindspore.float32) +output = acos(input_x) +``` + +### 向量运算 +向量运算符只在一个特定轴上运算,将一个向量映射到一个标量或者另外一个向量。 + +#### Concat 算子: +```python +data1 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) +data2 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) +op = P.Concat() +output = op((data1, data2)) +``` + +#### Squeeze +```python +input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32) +squeeze = P.Squeeze(2) +output = squeeze(input_tensor) +``` + +#### 求Sparse2Dense(改变tensor维度使其变稠密): +```python +indices = Tensor([[0, 1], [1, 2]]) +values = Tensor([1, 2], dtype=ms.float32) +dense_shape = (3, 4) +out = P.SparseToDense()(indices, values, dense_shape) +``` + +#### ScalarCast: +```python +scalar_cast = P.ScalarCast() +output = scalar_cast(255.0, mindspore.int32) +``` + +### 矩阵运算 +矩阵运算包括: 矩阵乘法,矩阵范数,矩阵行列式,矩阵求特征值,矩阵分解等运算。 + +#### 矩阵乘法: +```python +input_x = Tensor(np.ones(shape=[1, 3]), mindspore.float32) +input_y = Tensor(np.ones(shape=[3, 4]), mindspore.float32) +matmul = P.MatMul() +output = matmul(input_x, input_y) +``` + +#### 常见范数: + +```python +input_x = Tensor(np.ones([128, 64, 32, 64]), mindspore.float32) +scale = Tensor(np.ones([64]), mindspore.float32) +bias = Tensor(np.ones([64]), mindspore.float32) +mean = Tensor(np.ones([64]), mindspore.float32) +variance = Tensor(np.ones([64]), mindspore.float32) +batch_norm = P.BatchNorm() +output = batch_norm(input_x, scale, bias, mean, variance) +``` + +#### 广播机制 + +Broadcast 广播一个tensor到整个group +举例说明: +```python +from mindspore import Tensor +from mindspore.communication import init +import mindspore.nn as nn +import mindspore.ops.operations as P +init() +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.broadcast = P.Broadcast(1) + + def construct(self, x): + return self.broadcast((x,)) + +input_ = Tensor(np.ones([2, 8]).astype(np.float32)) +net = Net() +output = net(input_) +``` + +## 网络操作 + + +网络操作包括特征提取, 激活函数, LossFunction, 优化算法等: + +### 特征提取 + +#### 卷积操作 +举例说明: +```python +input = Tensor(np.ones([10, 32, 32, 32]), mindspore.float32) +weight = Tensor(np.ones([32, 32, 3, 3]), mindspore.float32)) +conv2d = P.Conv2D(out_channel=32, kernel_size=3) +conv2d(input, weight) +``` + +#### 卷积的反向传播算子操作: +输出结果: +```python +dout = Tensor(np.ones([10, 32, 30, 30]), mindspore.float32) +weight = Tensor(np.ones([32, 32, 3, 3]), mindspore.float32) +x = Tensor(np.ones([10, 32, 32, 32])) +conv2d_backprop_input = P.Conv2DBackpropInput(out_channel=32, kernel_size=3) +conv2d_backprop_input(dout, weight, F.shape(x)) +``` + +### 激活函数 +举例说明: +```python +input_x = Tensor(np.array([1, 2, 3, 4, 5]), mindspore.float32) +softmax = P.Softmax() +softmax(input_x) +``` + +输出结果: +```python +[0.01165623, 0.03168492, 0.08612854, 0.23412167, 0.6364086] +``` + +### LossFunction + +#### L1Loss: +举例说明: +```python +loss = P.SmoothL1Loss() +input_data = Tensor(np.array([1, 2, 3]), mindspore.float32) +target_data = Tensor(np.array([1, 2, 2]), mindspore.float32) +loss(input_data, target_data) +``` + +输出结果: +```python +[0, 0, 0.5] +``` + +### 优化算法 +#### SGD: +```python +sgd = P.SGD() +parameters = Tensor(np.array([2, -0.5, 1.7, 4]), mindspore.float32) +gradient = Tensor(np.array([1, -1, 0.5, 2]), mindspore.float32) +learning_rate = Tensor(0.01, mindspore.float32) +accum = Tensor(np.array([0.1, 0.3, -0.2, -0.1]), mindspore.float32) +momentum = Tensor(0.1, mindspore.float32) +stat = Tensor(np.array([1.5, -0.3, 0.2, -0.7]), mindspore.float32) +result = sgd(parameters, gradient, learning_rate, accum, momentum, stat) +``` + +## 数组操作 + + + +数组操作指操作对象是一些数组的操作。 + +### DType +返回跟输入的数据类型一致的并且适配Mindspore的tensor变量, 常用于Mindspore 工程内。 +举例说明: +```python +input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32) +type = P.DType()(input_tensor) +``` + +### Cast +转换输入的数据类型并且输出与目标数据类型相同的变量 +举例说明: +```python +input_np = np.random.randn(2, 3, 4, 5).astype(np.float32) +input_x = Tensor(input_np) +type_dst = mindspore.float16 +cast = P.Cast() +result = cast(input_x, type_dst) +``` + +### Shape +返回输入数据的形状 +举例说明: +```python +input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32) +shape = P.Shape() +output = shape(input_tensor) +``` + +## 图像操作 + + +图像操作包括图像预处理操作, 如图像剪切(Crop,便于得到大量训练样本)和大小变化(Reise,用于构建图像金子塔等): + +举例说明: +```python +class CropAndResizeNet(nn.Cell): + def __init__(self, crop_size): + super(CropAndResizeNet, self).__init__() + self.crop_and_resize = P.CropAndResize() + self.crop_size = crop_size + @ms_function + def construct(self, x, boxes, box_index): + return self.crop_and_resize(x, boxes, box_index, self.crop_size) + +BATCH_SIZE = 1 +NUM_BOXES = 5 +IMAGE_HEIGHT = 256 +IMAGE_WIDTH = 256 +CHANNELS = 3 +image = np.random.normal(size=[BATCH_SIZE, IMAGE_HEIGHT, IMAGE_WIDTH, CHANNELS]).astype(np.float32) +boxes = np.random.uniform(size=[NUM_BOXES, 4]).astype(np.float32) +box_index = np.random.uniform(size=[NUM_BOXES], low=0, high=BATCH_SIZE).astype(np.int32) +crop_size = (24, 24) +crop_and_resize = CropAndResizeNet(crop_size=crop_size) +output = crop_and_resize(Tensor(image), Tensor(boxes), Tensor(box_index)) +print(output.asnumpy()) +``` + +## 编码运算 + + +编码运算包括 BoundingBox Encoding和 BoundingBox Decoding, IOU计算等。 + +### BoundingBoxEncode +对物体所在区域方框进行编码,得到类似PCA的更精简信息,以便做后续类似特征提取,物体检测,图像恢复等任务。 + +举例说明: +```python +anchor_box = Tensor([[4,1,2,1],[2,2,2,3]],mindspore.float32) +groundtruth_box = Tensor([[3,1,2,2],[1,2,1,4]],mindspore.float32) +boundingbox_encode = P.BoundingBoxEncode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0)) +boundingbox_encode(anchor_box, groundtruth_box) +``` +输出结果为: +```python +[[5.0000000e-01 5.0000000e-01 -6.5504000e+04 6.9335938e-01] + [-1.0000000e+00 2.5000000e-01 0.0000000e+00 4.0551758e-01]] +``` + +### BoundingBoxDecode +编码器对区域位置信息解码之后,用此算子进行解码。 + +举例说明: +```python +anchor_box = Tensor([[4,1,2,1],[2,2,2,3]],mindspore.float32) +deltas = Tensor([[3,1,2,2],[1,s2,1,4]],mindspore.float32) +boundingbox_decode = P.BoundingBoxDecode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0), max_shape=(768, 1280), wh_ratio_clip=0.016) +boundingbox_decode(anchor_box, deltas) +``` +输出结果: +```python +[[4.1953125 0. 0. 5.1953125] + [2.140625 0. 3.859375 60.59375]] +``` + +### IOU 计算: +计算预测的物体所在方框和真实物体所在方框的交集区域与并集区域的占比大小。其常作为一种损失函数,用以优化模型。 + +举例说明: +```python +iou = P.IOU() +anchor_boxes = Tensor(np.random.randint(1.0, 5.0, [3, 4]), mindspore.float16) +gt_boxes = Tensor(np.random.randint(1.0, 5.0, [3, 4]), mindspore.float16) +``` + +## 调试操作 +调试操作指的是用于调试网络的一些常用算子及其操作, 例如Debug等 + +### Debug +输出tensor变量的数值, 方便用户随时随地打印想了解或者debug必需的某变量数值。 + +参考示例: +```python +class DebugNN(nn.Cell): + def __init__(self,): + self.debug = nn.Debug() + + def construct(self, x, y): + x = self.add(x, y) + self.debug(x) + return x +``` + +### HookBackward +打印中间变量的梯度,这一算子特别常用,遂举例在此,虽目前仅支持Pynative 形式 +参考示例: +```python +def hook_fn(grad_out): + print(grad_out) + +grad_all = GradOperation(get_all=True) +hook = P.HookBackward(hook_fn) + +def hook_test(x, y): + z = x * y + z = hook(z) + z = z * y + return z + +def backward(x, y): + return grad_all(hook_test)(x, y) + +backward(1, 2) +``` + +## 量化操作 + + +量化操作指对tensor做量化或者反量化操作。 量化操作指将浮点数用整数的加和表示,利用整数加和并行加速时速度快的优点, 实 +现在可接受精度损失下的性能提升。反量化指其反过程,其在精度要求高的地方常被用到。 + +### MinMaxUpdatePerLayer +完成在训练时的量化和反量化操作 +举例说明: +```python +input_tensor = Tensor(np.random.rand(3, 16, 5, 5), mstype.float32) +min_tensor = Tensor(np.array([-6]), mstype.float32) +max_tensor = Tensor(np.array([6]), mstype.float32) +output_tensor = FakeQuantPerLayer(num_bits=8)(input_tensor, min_tensor, max_tensor) +``` diff --git a/api/source_zh_cn/programming_guide/ops.md b/docs/programming_guide/source_zh_cn/ops.md similarity index 100% rename from api/source_zh_cn/programming_guide/ops.md rename to docs/programming_guide/source_zh_cn/ops.md diff --git a/api/source_zh_cn/programming_guide/optim.md b/docs/programming_guide/source_zh_cn/optim.md similarity index 100% rename from api/source_zh_cn/programming_guide/optim.md rename to docs/programming_guide/source_zh_cn/optim.md diff --git a/api/source_zh_cn/programming_guide/parameter.md b/docs/programming_guide/source_zh_cn/parameter.md similarity index 100% rename from api/source_zh_cn/programming_guide/parameter.md rename to docs/programming_guide/source_zh_cn/parameter.md diff --git a/api/source_zh_cn/programming_guide/pipeline.md b/docs/programming_guide/source_zh_cn/pipeline.md similarity index 100% rename from api/source_zh_cn/programming_guide/pipeline.md rename to docs/programming_guide/source_zh_cn/pipeline.md diff --git a/api/source_zh_cn/programming_guide/sampler.md b/docs/programming_guide/source_zh_cn/sampler.md similarity index 100% rename from api/source_zh_cn/programming_guide/sampler.md rename to docs/programming_guide/source_zh_cn/sampler.md diff --git a/api/source_zh_cn/programming_guide/security_and_privacy.md b/docs/programming_guide/source_zh_cn/security_and_privacy.md similarity index 100% rename from api/source_zh_cn/programming_guide/security_and_privacy.md rename to docs/programming_guide/source_zh_cn/security_and_privacy.md diff --git a/api/source_zh_cn/programming_guide/tensor.md b/docs/programming_guide/source_zh_cn/tensor.md similarity index 100% rename from api/source_zh_cn/programming_guide/tensor.md rename to docs/programming_guide/source_zh_cn/tensor.md diff --git a/api/source_zh_cn/programming_guide/tokenizer.md b/docs/programming_guide/source_zh_cn/tokenizer.md similarity index 100% rename from api/source_zh_cn/programming_guide/tokenizer.md rename to docs/programming_guide/source_zh_cn/tokenizer.md diff --git a/api/source_zh_cn/programming_guide/type.md b/docs/programming_guide/source_zh_cn/type.md similarity index 100% rename from api/source_zh_cn/programming_guide/type.md rename to docs/programming_guide/source_zh_cn/type.md diff --git a/lite/docs/source_en/architecture_lite.md b/lite/docs/source_en/architecture_lite.md new file mode 100644 index 0000000000..6458577572 --- /dev/null +++ b/lite/docs/source_en/architecture_lite.md @@ -0,0 +1,19 @@ +# Overall Architecture + + + +The overall architecture of MindSpore Lite is as follows: + +![architecture](./images/MindSpore-Lite-architecture.png) + +- **Frontend:** generates models. You can use the model building API to build models and convert third-party models and models trained by MindSpore to MindSpore Lite models. Third-party models include TensorFlow Lite, Caffe 1.0, and ONNX models. + +- **IR:** defines the tensors, operators, and graphs of MindSpore. + +- **Backend:** optimizes graphs based on IR, including graph high level optimization (GHLO), graph low level optimization (GLLO), and quantization. GHLO is responsible for hardware-independent optimization, such as operator fusion and constant folding. GLLO is responsible for hardware-related optimization. Quantizer supports quantization methods after training, such as weight quantization and activation value quantization. + +- **Runtime:** inference runtime of intelligent devices. Sessions are responsible for session management and provide external APIs. The thread pool and parallel primitives are responsible for managing the thread pool used for graph execution. Memory allocation is responsible for memory overcommitment of each operator during graph execution. The operator library provides the CPU and GPU operators. + +- **Micro:** runtime of IoT devices, including the model generation .c file, thread pool, memory overcommitment, and operator library. + +Runtime and Micro share the underlying infrastructure layers, such as the operator library, memory allocation, thread pool, and parallel primitives. diff --git a/lite/docs/source_en/glossary_lite.md b/lite/docs/source_en/glossary_lite.md new file mode 100644 index 0000000000..8b59622929 --- /dev/null +++ b/lite/docs/source_en/glossary_lite.md @@ -0,0 +1,12 @@ +# Glossary + + + +| Acronym and Abbreviation | Description | +| ----- | ----- | +| MindSpore Lite | MindSpore AI engine is applied to the intelligent terminal and resource constrained scenes on the edge side. | +| MindSpore Micro | MindSpore AI engine with smaller package size for IOT devices. | +| GHLO | Graph high-level optimization. | +| GLLO | Graph low-level optimization. | +| RT | Runtime. | + diff --git a/lite/docs/source_en/index_lite.rst b/lite/docs/source_en/index_lite.rst new file mode 100644 index 0000000000..abecfe957e --- /dev/null +++ b/lite/docs/source_en/index_lite.rst @@ -0,0 +1,16 @@ +.. MindSpore documentation master file, created by + sphinx-quickstart on Thu Aug 17 10:00:00 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +MindSpore Lite Documentation +============================ + +.. toctree:: + :glob: + :maxdepth: 1 + + architecture + apicc/apicc + operator_list + glossary diff --git a/lite/docs/source_en/operator_list_lite.md b/lite/docs/source_en/operator_list_lite.md new file mode 100644 index 0000000000..6038b5c956 --- /dev/null +++ b/lite/docs/source_en/operator_list_lite.md @@ -0,0 +1,111 @@ +# Operator List + + + +> √ The checked items are the operators supported by MindSpore Lite。 + +| Operation | CPU
FP16 | CPU
FP32 | CPU
Int8 | CPU
UInt8 | GPU
FP16 | GPU
FP32 | Tensorflow
Lite op supported | Caffe
Lite op supported | Onnx
Lite op supported | +|-----------------------|----------|----------|-----------|----------|----------|------------------|----------|----------|----------| +| Abs | | √ | √ | √ | | | Abs | | Abs | +| Add | √ | √ | √ | √ | | √ | Add | | Add | +| AddN | | √ | | | | | AddN | | | +| Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | +| Argmin | | √ | √ | √ | | | Argmin | | | +| AvgPool | √ | √ | √ | √ | | √ | MeanPooling| Pooling | AveragePool | +| BatchNorm | √ | √ | √ | √ | | √ | | BatchNorm | BatchNormalization | +| BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | +| BiasAdd | | √ | √ | √ | | √ | | | BiasAdd | +| Broadcast | | √ | | | | | BroadcastTo | | Expand | +| Cast | √ | √ | | √ | | | Cast, DEQUANTIZE* | | Cast | +| Ceil | | √ | √ | √ | | | Ceil | | Ceil | +| Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | +| Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | +| Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | +| Cos | | √ | √ | √ | | | Cos | | Cos | +| Crop | | √ | √ | √ | | | | Crop | | +| DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | +| DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | +| DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | +| Div | √ | √ | √ | √ | | √ | Div, RealDiv | | Div | +| Eltwise | √ | √ | | | | | | Eltwise | | +| Elu | | √ | | | | | Elu | | Elu | +| Equal | √ | √ | √ | √ | | | Equal | | Equal | +| Exp | | √ | | | | | Exp | | Exp | +| ExpandDims | | √ | | | | | | | | +| Fill | | √ | | | | | Fill | | | +| Flatten | | √ | | | | | | Flatten | | +| Floor | | √ | √ | √ | | | flOOR | | Floor | +| FloorDiv | √ | √ | | | | | FloorDiv | | | +| FloorMod | √ | √ | | | | | FloorMod | | | +| FullConnection | | √ | √ | √ | | | FullyConnected | InnerProduct | | +| GatherNd | | √ | √ | √ | | | GatherND | | | +| GatherV2 | | √ | √ | √ | | | Gather | | Gather | +| Greater | √ | √ | √ | √ | | | Greater | | Greater | +| GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | +| Hswish | √ | √ | √ | √ | | | HardSwish | | | +| LeakyReLU | √ | √ | | | | √ | LeakyRelu | | LeakyRelu | +| Less | √ | √ | √ | √ | | | Less | | Less | +| LessEqual | √ | √ | √ | √ | | | LessEqual | | | +| LRN | | √ | | | | | LocalResponseNorm | | Lrn | +| Log | | √ | √ | √ | | | Log | | Log | +| LogicalAnd | √ | √ | | | | | LogicalAnd | | | +| LogicalNot | | √ | √ | √ | | | LogicalNot | | | +| LogicalOr | √ | √ | | | | | LogicalOr | | | +| LSTM | | √ | | | | | | | | +| MatMul | | √ | √ | √ | √ | √ | | | MatMul | +| Maximum | √ | √ | | | | | Maximum | | Max | +| MaxPool | √ | √ | √ | √ | | √ | MaxPooling | Pooling | MaxPool | +| Minimum | √ | √ | | | | | Minimum | | Min | +| Mul | √ | √ | √ | √ | | √ | Mul | | Mul | +| NotEqual | √ | √ | √ | √ | | | NotEqual | | | +| OneHot | | √ | | | | | OneHot | | | +| Pad | | √ | √ | √ | | | Pad | | Pad | +| Pow | | √ | √ | √ | | | Pow | Power | Power | +| PReLU | | √ | | | | √ | | PReLU | | +| Range | | √ | | | | | Range | | | +| Rank | | √ | | | | | Rank | | | +| ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | +| ReduceMean | √ | √ | √ | √ | | | Mean | | ReduceMean | +| ReduceMin | √ | √ | √ | √ | | | ReduceMin | | ReduceMin | +| ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | +| ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | +| ReduceSumSquare | √ | √ | √ | √ | | | | | | +| ReLU | √ | √ | √ | √ | | √ | Relu | ReLU | Relu | +| ReLU6 | √ | √ | √ | √ | | √ | Relu6 | ReLU6 | Clip* | +| Reshape | √ | √ | √ | √ | | √ | Reshape | Reshape | Reshape,Flatten | +| Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | +| Reverse | | √ | | | | | reverse | | | +| ReverseSequence | | √ | | | | | ReverseSequence | | | +| Round | | √ | √ | √ | | | Round | | | +| Rsqrt | | √ | √ | √ | | | Rsqrt | | | +| Scale | | √ | | | | | | Scale | | +| ScatterNd | | √ | | | | | ScatterNd | | | +| Shape | | √ | | | | | Shape | | Shape | +| Sigmoid | √ | √ | √ | √ | | √ | Logistic | Sigmoid | Sigmoid | +| Sin | | √ | √ | √ | | | Sin | | Sin | +| Slice | | √ | √ | √ | √ | √ | Slice | | Slice | +| Softmax | √ | √ | √ | √ | | √ | Softmax | Softmax | Softmax | +| SpaceToBatch | | √ | | | | | | | | +| SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | +| SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | +| SparseToDense | | √ | | | | | SpareToDense | | | +| Split | √ | √ | √ | √ | | | Split, SplitV | | | +| Sqrt | | √ | √ | √ | | | Sqrt | | Sqrt | +| Square | | √ | √ | √ | | | Square | | | +| SquaredDifference | | √ | | | | | SquaredDifference | | | +| Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | +| StridedSlice | | √ | √ | √ | | | StridedSlice| | | +| Stack | | √ | | | | | Stack | | | +| Sub | √ | √ | √ | √ | | √ | Sub | | Sub | +| Tanh | √ | √ | | | | | Tanh | TanH | | +| Tile | | √ | | | | | Tile | | Tile | +| TopK | | √ | √ | √ | | | TopKV2 | | | +| Transpose | √ | √ | | | | √ | Transpose | Permute | Transpose | +| Unique | | √ | | | | | Unique | | | +| Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | +| Unstack | | √ | | | | | Unstack | | | +| Where | | √ | | | | | Where | | | +| ZerosLike | | √ | | | | | ZerosLike | | | + +* Clip: only support convert clip(0, 6) to Relu6. +* DEQUANTIZE: only support to convert fp16 to fp32. diff --git a/lite/docs/source_zh_cn/architecture_lite.md b/lite/docs/source_zh_cn/architecture_lite.md new file mode 100644 index 0000000000..ce86fa9829 --- /dev/null +++ b/lite/docs/source_zh_cn/architecture_lite.md @@ -0,0 +1,20 @@ +# 总体架构 + + + +MindSpore Lite框架的总体架构如下所示: + +![architecture](images/MindSpore-Lite-architecture.png) + +- **前端(Frontend):** 负责模型生成,用户可以通过模型构建接口构建模型,将第三方模型和MindSpore训练的模型转换为MindSpore Lite模型,其中第三方模型包括TensorFlow Lite、Caffe 1.0和ONNX模型。 + +- **IR:** 负责MindSpore的Tensor定义、算子定义和图定义。 + +- **Backend:** 基于IR进行图优化,包括GHLO、GLLO和量化三部分。其中,GHLO负责和硬件无关的优化,如算子融合、常量折叠等;GLLO负责与硬件相关的优化;量化Quantizer支持权重量化、激活值量化等训练后量化手段。 + +- **Runtime:** 智能终端的推理运行时,其中session负责会话管理,提供对外接口;线程池和并行原语负责图执行使用的线程池管理,内存分配负责图执行中各个算子的内存复用,算子库提供CPU和GPU算子。 + +- **Micro:** IoT设备的运行时,包括模型生成.c文件、线程池、内存复用和算子库。 + +其中,Runtime和Micro共享底层的算子库、内存分配、线程池、并行原语等基础设施层。 + diff --git a/lite/docs/source_zh_cn/glossary_lite.md b/lite/docs/source_zh_cn/glossary_lite.md new file mode 100644 index 0000000000..b9cf41a4c6 --- /dev/null +++ b/lite/docs/source_zh_cn/glossary_lite.md @@ -0,0 +1,12 @@ +# 术语 + + + +| 术语/缩略语 | 说明 | +| ----- | ----- | +| MindSpore Lite | 应用在智能终端,边缘册资源受限场景的MindSpore AI 引擎。 | +| MindSpore Micro | 应用在IoT设备的,包大小更小的MindSpore AI引擎。 | +| GHLO | Graph high-level optimization,图高层优化。 | +| GLLO | Graph low-level optimization,图底层优化。 | +| RT | Runtime运行时。 | + diff --git a/lite/docs/source_zh_cn/index_lite.rst b/lite/docs/source_zh_cn/index_lite.rst new file mode 100644 index 0000000000..20ecdbb72c --- /dev/null +++ b/lite/docs/source_zh_cn/index_lite.rst @@ -0,0 +1,16 @@ +.. MindSpore documentation master file, created by + sphinx-quickstart on Thu Aug 17 10:00:00 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +MindSpore端侧文档 +================== + +.. toctree:: + :glob: + :maxdepth: 1 + + architecture + apicc/apicc + operator_list + glossary diff --git a/lite/docs/source_zh_cn/operator_list_lite.md b/lite/docs/source_zh_cn/operator_list_lite.md new file mode 100644 index 0000000000..3384d8baf9 --- /dev/null +++ b/lite/docs/source_zh_cn/operator_list_lite.md @@ -0,0 +1,111 @@ +# 算子支持 + + + +> √勾选的项为MindSpore Lite所支持的算子。 + +| 操作名 | CPU
FP16 | CPU
FP32 | CPU
Int8 | CPU
UInt8 | GPU
FP16 | GPU
FP32 | 支持的Tensorflow
Lite op | 支持的Caffe
Lite op | 支持的Onnx
Lite op | +|-----------------------|----------|----------|----------|-----------|----------|-------------------|----------|----------|---------| +| Abs | | √ | √ | √ | | | Abs | | Abs | +| Add | √ | √ | √ | √ | | √ | Add | | Add | +| AddN | | √ | | | | | AddN | | | +| Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | +| Argmin | | √ | √ | √ | | | Argmin | | | +| AvgPool | √ | √ | √ | √ | | √ | MeanPooling| Pooling | AveragePool | +| BatchNorm | √ | √ | √ | √ | | √ | | BatchNorm | BatchNormalization | +| BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | +| BiasAdd | | √ | √ | √ | | √ | | | BiasAdd | +| Broadcast | | √ | | | | | BroadcastTo | | Expand | +| Cast | √ | √ | | √ | | | Cast, DEQUANTIZE* | | Cast | +| Ceil | | √ | √ | √ | | | Ceil | | Ceil | +| Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | +| Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | +| Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | +| Cos | | √ | √ | √ | | | Cos | | Cos | +| Crop | | √ | √ | √ | | | | Crop | | +| DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | +| DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | +| DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | +| Div | √ | √ | √ | √ | | √ | Div, RealDiv | | Div | +| Eltwise | √ | √ | | | | | | Eltwise | | +| Elu | | √ | | | | | Elu | | Elu | +| Equal | √ | √ | √ | √ | | | Equal | | Equal | +| Exp | | √ | | | | | Exp | | Exp | +| ExpandDims | | √ | | | | | | | | +| Fill | | √ | | | | | Fill | | | +| Flatten | | √ | | | | | | Flatten | | +| Floor | | √ | √ | √ | | | flOOR | | Floor | +| FloorDiv | √ | √ | | | | | FloorDiv | | | +| FloorMod | √ | √ | | | | | FloorMod | | | +| FullConnection | | √ | √ | √ | | | FullyConnected | InnerProduct | | +| GatherNd | | √ | √ | √ | | | GatherND | | | +| GatherV2 | | √ | √ | √ | | | Gather | | Gather | +| Greater | √ | √ | √ | √ | | | Greater | | Greater | +| GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | +| Hswish | √ | √ | √ | √ | | | HardSwish | | | +| LeakyReLU | √ | √ | | | | √ | LeakyRelu | | LeakyRelu | +| Less | √ | √ | √ | √ | | | Less | | Less | +| LessEqual | √ | √ | √ | √ | | | LessEqual | | | +| LRN | | √ | | | | | LocalResponseNorm | | Lrn | +| Log | | √ | √ | √ | | | Log | | Log | +| LogicalAnd | √ | √ | | | | | LogicalAnd | | | +| LogicalNot | | √ | √ | √ | | | LogicalNot | | | +| LogicalOr | √ | √ | | | | | LogicalOr | | | +| LSTM | | √ | | | | | | | | +| MatMul | | √ | √ | √ | √ | √ | | | MatMul | +| Maximum | √ | √ | | | | | Maximum | | Max | +| MaxPool | √ | √ | √ | √ | | √ | MaxPooling | Pooling | MaxPool | +| Minimum | √ | √ | | | | | Minimum | | Min | +| Mul | √ | √ | √ | √ | | √ | Mul | | Mul | +| NotEqual | √ | √ | √ | √ | | | NotEqual | | | +| OneHot | | √ | | | | | OneHot | | | +| Pad | | √ | √ | √ | | | Pad | | Pad | +| Pow | | √ | √ | √ | | | Pow | Power | Power | +| PReLU | | √ | | | | √ | | PReLU | | +| Range | | √ | | | | | Range | | | +| Rank | | √ | | | | | Rank | | | +| ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | +| ReduceMean | √ | √ | √ | √ | | | Mean | | ReduceMean | +| ReduceMin | √ | √ | √ | √ | | | ReduceMin | | ReduceMin | +| ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | +| ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | +| ReduceSumSquare | √ | √ | √ | √ | | | | | | +| ReLU | √ | √ | √ | √ | | √ | Relu | ReLU | Relu | +| ReLU6 | √ | √ | √ | √ | | √ | Relu6 | ReLU6 | Clip* | +| Reshape | √ | √ | √ | √ | | √ | Reshape | Reshape | Reshape,Flatten | +| Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | +| Reverse | | √ | | | | | reverse | | | +| ReverseSequence | | √ | | | | | ReverseSequence | | | +| Round | | √ | √ | √ | | | Round | | | +| Rsqrt | | √ | √ | √ | | | Rsqrt | | | +| Scale | | √ | | | | | | Scale | | +| ScatterNd | | √ | | | | | ScatterNd | | | +| Shape | | √ | | | | | Shape | | Shape | +| Sigmoid | √ | √ | √ | √ | | √ | Logistic | Sigmoid | Sigmoid | +| Sin | | √ | √ | √ | | | Sin | | Sin | +| Slice | | √ | √ | √ | √ | √ | Slice | | Slice | +| Softmax | √ | √ | √ | √ | | √ | Softmax | Softmax | Softmax | +| SpaceToBatch | | √ | | | | | | | | +| SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | +| SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | +| SparseToDense | | √ | | | | | SpareToDense | | | +| Split | √ | √ | √ | √ | | | Split, SplitV | | | +| Sqrt | | √ | √ | √ | | | Sqrt | | Sqrt | +| Square | | √ | √ | √ | | | Square | | | +| SquaredDifference | | √ | | | | | SquaredDifference | | | +| Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | +| StridedSlice | | √ | √ | √ | | | StridedSlice| | | +| Stack | | √ | | | | | Stack | | | +| Sub | √ | √ | √ | √ | | √ | Sub | | Sub | +| Tanh | √ | √ | | | | | Tanh | TanH | | +| Tile | | √ | | | | | Tile | | Tile | +| TopK | | √ | √ | √ | | | TopKV2 | | | +| Transpose | √ | √ | | | | √ | Transpose | Permute | Transpose | +| Unique | | √ | | | | | Unique | | | +| Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | +| Unstack | | √ | | | | | Unstack | | | +| Where | | √ | | | | | Where | | | +| ZerosLike | | √ | | | | | ZerosLike | | | + +* Clip: 仅支持将clip(0, 6)转换为Relu6. +* DEQUANTIZE: 仅支持将fp16转换为fp32. diff --git a/tutorials/inference/Makefile b/tutorials/inference/Makefile new file mode 100644 index 0000000000..1eff895270 --- /dev/null +++ b/tutorials/inference/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source_zh_cn +BUILDDIR = build_zh_cn + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tutorials/requirements.txt b/tutorials/inference/requirements.txt similarity index 100% rename from tutorials/requirements.txt rename to tutorials/inference/requirements.txt diff --git a/tutorials/lite/Makefile b/tutorials/lite/Makefile new file mode 100644 index 0000000000..1eff895270 --- /dev/null +++ b/tutorials/lite/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source_zh_cn +BUILDDIR = build_zh_cn + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/lite/tutorials/requirements.txt b/tutorials/lite/requirements.txt similarity index 100% rename from lite/tutorials/requirements.txt rename to tutorials/lite/requirements.txt diff --git a/lite/tutorials/source_en/_static/logo_source.png b/tutorials/lite/source_en/_static/logo_source.png similarity index 100% rename from lite/tutorials/source_en/_static/logo_source.png rename to tutorials/lite/source_en/_static/logo_source.png diff --git a/lite/tutorials/source_en/build.md b/tutorials/lite/source_en/build.md similarity index 100% rename from lite/tutorials/source_en/build.md rename to tutorials/lite/source_en/build.md diff --git a/lite/tutorials/source_en/conf.py b/tutorials/lite/source_en/conf.py similarity index 100% rename from lite/tutorials/source_en/conf.py rename to tutorials/lite/source_en/conf.py diff --git a/lite/tutorials/source_en/images/lite_quick_start_app_result.png b/tutorials/lite/source_en/images/lite_quick_start_app_result.png similarity index 100% rename from lite/tutorials/source_en/images/lite_quick_start_app_result.png rename to tutorials/lite/source_en/images/lite_quick_start_app_result.png diff --git a/lite/tutorials/source_en/images/lite_quick_start_home.png b/tutorials/lite/source_en/images/lite_quick_start_home.png similarity index 100% rename from lite/tutorials/source_en/images/lite_quick_start_home.png rename to tutorials/lite/source_en/images/lite_quick_start_home.png diff --git a/lite/tutorials/source_en/images/lite_quick_start_project_structure.png b/tutorials/lite/source_en/images/lite_quick_start_project_structure.png similarity index 100% rename from lite/tutorials/source_en/images/lite_quick_start_project_structure.png rename to tutorials/lite/source_en/images/lite_quick_start_project_structure.png diff --git a/lite/tutorials/source_en/images/lite_quick_start_run_app.PNG b/tutorials/lite/source_en/images/lite_quick_start_run_app.PNG similarity index 100% rename from lite/tutorials/source_en/images/lite_quick_start_run_app.PNG rename to tutorials/lite/source_en/images/lite_quick_start_run_app.PNG diff --git a/lite/tutorials/source_en/images/lite_quick_start_sdk.png b/tutorials/lite/source_en/images/lite_quick_start_sdk.png similarity index 100% rename from lite/tutorials/source_en/images/lite_quick_start_sdk.png rename to tutorials/lite/source_en/images/lite_quick_start_sdk.png diff --git a/lite/tutorials/source_en/images/side_infer_process.png b/tutorials/lite/source_en/images/side_infer_process.png similarity index 100% rename from lite/tutorials/source_en/images/side_infer_process.png rename to tutorials/lite/source_en/images/side_infer_process.png diff --git a/lite/tutorials/source_en/index.rst b/tutorials/lite/source_en/index.rst similarity index 100% rename from lite/tutorials/source_en/index.rst rename to tutorials/lite/source_en/index.rst diff --git a/lite/tutorials/source_en/quick_start/quick_start.md b/tutorials/lite/source_en/quick_start/quick_start.md similarity index 100% rename from lite/tutorials/source_en/quick_start/quick_start.md rename to tutorials/lite/source_en/quick_start/quick_start.md diff --git a/lite/tutorials/source_en/use/benchmark_tool.md b/tutorials/lite/source_en/use/benchmark_tool.md similarity index 100% rename from lite/tutorials/source_en/use/benchmark_tool.md rename to tutorials/lite/source_en/use/benchmark_tool.md diff --git a/lite/tutorials/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md similarity index 100% rename from lite/tutorials/source_en/use/converter_tool.md rename to tutorials/lite/source_en/use/converter_tool.md diff --git a/lite/tutorials/source_en/use/evaluating_the_model.rst b/tutorials/lite/source_en/use/evaluating_the_model.rst similarity index 100% rename from lite/tutorials/source_en/use/evaluating_the_model.rst rename to tutorials/lite/source_en/use/evaluating_the_model.rst diff --git a/lite/tutorials/source_en/use/runtime.md b/tutorials/lite/source_en/use/runtime.md similarity index 100% rename from lite/tutorials/source_en/use/runtime.md rename to tutorials/lite/source_en/use/runtime.md diff --git a/lite/tutorials/source_en/use/timeprofiler_tool.md b/tutorials/lite/source_en/use/timeprofiler_tool.md similarity index 100% rename from lite/tutorials/source_en/use/timeprofiler_tool.md rename to tutorials/lite/source_en/use/timeprofiler_tool.md diff --git a/lite/tutorials/source_zh_cn/_static/logo_source.png b/tutorials/lite/source_zh_cn/_static/logo_source.png similarity index 100% rename from lite/tutorials/source_zh_cn/_static/logo_source.png rename to tutorials/lite/source_zh_cn/_static/logo_source.png diff --git a/lite/tutorials/source_zh_cn/build.md b/tutorials/lite/source_zh_cn/build.md similarity index 100% rename from lite/tutorials/source_zh_cn/build.md rename to tutorials/lite/source_zh_cn/build.md diff --git a/lite/tutorials/source_zh_cn/conf.py b/tutorials/lite/source_zh_cn/conf.py similarity index 100% rename from lite/tutorials/source_zh_cn/conf.py rename to tutorials/lite/source_zh_cn/conf.py diff --git a/lite/tutorials/source_zh_cn/images/lite_quick_start_app_result.png b/tutorials/lite/source_zh_cn/images/lite_quick_start_app_result.png similarity index 100% rename from lite/tutorials/source_zh_cn/images/lite_quick_start_app_result.png rename to tutorials/lite/source_zh_cn/images/lite_quick_start_app_result.png diff --git a/lite/tutorials/source_zh_cn/images/lite_quick_start_home.png b/tutorials/lite/source_zh_cn/images/lite_quick_start_home.png similarity index 100% rename from lite/tutorials/source_zh_cn/images/lite_quick_start_home.png rename to tutorials/lite/source_zh_cn/images/lite_quick_start_home.png diff --git a/lite/tutorials/source_zh_cn/images/lite_quick_start_install.png b/tutorials/lite/source_zh_cn/images/lite_quick_start_install.png similarity index 100% rename from lite/tutorials/source_zh_cn/images/lite_quick_start_install.png rename to tutorials/lite/source_zh_cn/images/lite_quick_start_install.png diff --git a/lite/tutorials/source_zh_cn/images/lite_quick_start_project_structure.png b/tutorials/lite/source_zh_cn/images/lite_quick_start_project_structure.png similarity index 100% rename from lite/tutorials/source_zh_cn/images/lite_quick_start_project_structure.png rename to tutorials/lite/source_zh_cn/images/lite_quick_start_project_structure.png diff --git a/lite/tutorials/source_zh_cn/images/lite_quick_start_run_app.PNG b/tutorials/lite/source_zh_cn/images/lite_quick_start_run_app.PNG similarity index 100% rename from lite/tutorials/source_zh_cn/images/lite_quick_start_run_app.PNG rename to tutorials/lite/source_zh_cn/images/lite_quick_start_run_app.PNG diff --git a/lite/tutorials/source_zh_cn/images/lite_quick_start_sdk.png b/tutorials/lite/source_zh_cn/images/lite_quick_start_sdk.png similarity index 100% rename from lite/tutorials/source_zh_cn/images/lite_quick_start_sdk.png rename to tutorials/lite/source_zh_cn/images/lite_quick_start_sdk.png diff --git a/lite/tutorials/source_zh_cn/images/side_infer_process.png b/tutorials/lite/source_zh_cn/images/side_infer_process.png similarity index 100% rename from lite/tutorials/source_zh_cn/images/side_infer_process.png rename to tutorials/lite/source_zh_cn/images/side_infer_process.png diff --git a/lite/tutorials/source_zh_cn/index.rst b/tutorials/lite/source_zh_cn/index.rst similarity index 100% rename from lite/tutorials/source_zh_cn/index.rst rename to tutorials/lite/source_zh_cn/index.rst diff --git a/lite/tutorials/source_zh_cn/quick_start/quick_start.md b/tutorials/lite/source_zh_cn/quick_start/quick_start.md similarity index 100% rename from lite/tutorials/source_zh_cn/quick_start/quick_start.md rename to tutorials/lite/source_zh_cn/quick_start/quick_start.md diff --git a/lite/tutorials/source_zh_cn/use/benchmark_tool.md b/tutorials/lite/source_zh_cn/use/benchmark_tool.md similarity index 100% rename from lite/tutorials/source_zh_cn/use/benchmark_tool.md rename to tutorials/lite/source_zh_cn/use/benchmark_tool.md diff --git a/lite/tutorials/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md similarity index 100% rename from lite/tutorials/source_zh_cn/use/converter_tool.md rename to tutorials/lite/source_zh_cn/use/converter_tool.md diff --git a/lite/tutorials/source_zh_cn/use/evaluating_the_model.rst b/tutorials/lite/source_zh_cn/use/evaluating_the_model.rst similarity index 100% rename from lite/tutorials/source_zh_cn/use/evaluating_the_model.rst rename to tutorials/lite/source_zh_cn/use/evaluating_the_model.rst diff --git a/lite/tutorials/source_zh_cn/use/post_training_quantization.md b/tutorials/lite/source_zh_cn/use/post_training_quantization.md similarity index 100% rename from lite/tutorials/source_zh_cn/use/post_training_quantization.md rename to tutorials/lite/source_zh_cn/use/post_training_quantization.md diff --git a/lite/tutorials/source_zh_cn/use/runtime.md b/tutorials/lite/source_zh_cn/use/runtime.md similarity index 100% rename from lite/tutorials/source_zh_cn/use/runtime.md rename to tutorials/lite/source_zh_cn/use/runtime.md diff --git a/lite/tutorials/source_zh_cn/use/timeprofiler_tool.md b/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md similarity index 100% rename from lite/tutorials/source_zh_cn/use/timeprofiler_tool.md rename to tutorials/lite/source_zh_cn/use/timeprofiler_tool.md diff --git a/tutorials/training/Makefile b/tutorials/training/Makefile new file mode 100644 index 0000000000..1eff895270 --- /dev/null +++ b/tutorials/training/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source_zh_cn +BUILDDIR = build_zh_cn + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/tutorials/training/requirements.txt b/tutorials/training/requirements.txt new file mode 100644 index 0000000000..1339620038 --- /dev/null +++ b/tutorials/training/requirements.txt @@ -0,0 +1,5 @@ +sphinx >= 2.2.1, <= 2.4.4 +recommonmark +sphinx-markdown-tables +sphinx_rtd_theme +jieba diff --git a/tutorials/source_en/_static/logo_source.png b/tutorials/training/source_en/_static/logo_source.png similarity index 100% rename from tutorials/source_en/_static/logo_source.png rename to tutorials/training/source_en/_static/logo_source.png diff --git a/tutorials/source_en/advanced_use/checkpoint_for_hybrid_parallel.md b/tutorials/training/source_en/advanced_use/checkpoint_for_hybrid_parallel.md similarity index 100% rename from tutorials/source_en/advanced_use/checkpoint_for_hybrid_parallel.md rename to tutorials/training/source_en/advanced_use/checkpoint_for_hybrid_parallel.md diff --git a/tutorials/source_en/advanced_use/computer_vision_application.md b/tutorials/training/source_en/advanced_use/computer_vision_application.md similarity index 100% rename from tutorials/source_en/advanced_use/computer_vision_application.md rename to tutorials/training/source_en/advanced_use/computer_vision_application.md diff --git a/tutorials/source_en/advanced_use/customized_debugging_information.md b/tutorials/training/source_en/advanced_use/customized_debugging_information.md similarity index 100% rename from tutorials/source_en/advanced_use/customized_debugging_information.md rename to tutorials/training/source_en/advanced_use/customized_debugging_information.md diff --git a/tutorials/source_en/advanced_use/dashboard.md b/tutorials/training/source_en/advanced_use/dashboard.md similarity index 98% rename from tutorials/source_en/advanced_use/dashboard.md rename to tutorials/training/source_en/advanced_use/dashboard.md index 7c875e1c81..8094cd7947 100644 --- a/tutorials/source_en/advanced_use/dashboard.md +++ b/tutorials/training/source_en/advanced_use/dashboard.md @@ -1,202 +1,202 @@ -# Dashboard - -`Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` - - - -- [Dashboard](#dashboard) - - [Overview](#overview) - - [Scalar Visualization](#scalar-visualization) - - [Parameter Distribution Visualization](#parameter-distribution-visualization) - - [Computational Graph Visualization](#computational-graph-visualization) - - [Dataset Graph Visualization](#dataset-graph-visualization) - - [Image Visualization](#image-visualization) - - [Tensor Visualization](#tensor-visualization) - - [Notices](#notices) - - - - - -## Overview - -Training dashboard is an important part of mindinsight's visualization component, and its tags include scalar visualization, parameter distribution visualization, computational visualization, data visualization, image visualization and tensor visualization. - -Access the Training Dashboard by selecting a specific training from the training list. - -## Scalar Visualization - -Scalar visualization is used to display the change trend of scalars during training. - -![scalar.png](./images/scalar.png) - -Figure 1: Scalar trend chart - -Figure 1 shows a change process of loss values during the neural network training. The horizontal coordinate indicates the training step, and the vertical coordinate indicates the loss value. - -Buttons from left to right in the upper right corner of the figure are used to display the chart in full screen, switch the Y-axis scale, enable or disable the rectangle selection, roll back the chart step by step, and restore the chart. - -- Full-screen display: Display the scalar curve in full screen. Click the button again to restore it. -- Switch Y-axis scale: Perform logarithmic conversion on the Y-axis coordinate. -- Enable/Disable rectangle selection: Draw a rectangle to select and zoom in a part of the chart. You can perform rectangle selection again on the zoomed-in chart. -- Step-by-step Rollback: Cancel operations step by step after continuously drawing rectangles to select and zooming in the same area. -- Restore chart: Restore a chart to the original state. - -There can set the threshold value to highlight the value or delete the threshold value in the lower right corner of the figure. As shown in the figure, the threshold set is less than 1.5, highlighted in red shows what is below the threshold, and it is intuitive to see the expected data value or some unusual value. - -![scalar_select.png](./images/scalar_select.png) - -Figure 2: Scalar visualization function area - -Figure 2 shows the scalar visualization function area, which allows you to view scalar information by selecting different tags, different dimensions of the horizontal axis, and smoothness. - -- Tag selection: Select the required tags to view the corresponding scalar information. -- Horizontal axis: Select any of Step, Relative Time, and Absolute Time as the horizontal axis of the scalar curve. -- Smoothness: adjust the smoothness to smooth the scalar curve. -- Scalar synthesis: Synthesize two scalar curves and display them in a chart to facilitate comparison between the two curves or view the synthesized chart. - -![scalar_compound.png](./images/scalar_compound.png) - -Figure 3: Scalar synthesis of Accuracy and Loss curves - -Figure 3 shows the scalar synthesis of the Accuracy and Loss curves. The function area of scalar synthesis is similar to that of scalar visualization. Different from the scalar visualization function area, the scalar synthesis function allows you to select a maximum of two tags at a time to synthesize and display their curves. - -## Parameter Distribution Visualization - -The parameter distribution in a form of a histogram displays tensors specified by a user. - -![histogram.png](./images/histogram.png) - -Figure 4: Histogram - -Figure 4 shows tensors recorded by a user in a form of a histogram. Click the upper right corner to zoom in the histogram. - -![histogram_func.png](./images/histogram_func.png) - -Figure 5: Function area of the parameter distribution histogram - -Figure 5 shows the function area of the parameter distribution histogram, including: - -- Tag selection: Select the required tags to view the corresponding histogram. -- Vertical axis: Select any of `Step`, `Relative time`, and `Absolute time` as the data displayed on the vertical axis of the histogram. -- Angle of view: Select either `Front` or `Top`. `Front` view refers to viewing the histogram from the front view. In this case, data between different steps is overlapped. `Top` view refers to viewing the histogram at an angle of 45 degrees. In this case, data between different steps can be presented. - -## Computational Graph Visualization - -Computational graph visualization is used to display the graph structure, data flow direction, and control flow direction of a computational graph. It supports visualization of summary log files and pb files generated by `save_graphs` configuration in `context`. - -![graph.png](./images/graph.png) - -Figure 6: Computational graph display area - -Figure 6 shows the network structure of a computational graph. As shown in the figure, select an operator in the area of the display area. The operator has two inputs and one outputs (the solid line indicates the data flow direction of the operator). - -![graph_sidebar.png](./images/graph_sidebar.png) - -Figure 7: Computational graph function area - -Figure 7 shows the function area of the computational graph, including: - -- File selection box: View the computational graphs of different files. -- Search box: Enter a node name and press Enter to view the node. -- Thumbnail: Display the thumbnail of the entire network structure. When viewing an extra large image structure, you can view the currently browsed area. -- Node information: Display the basic information of the selected node, including the node name, properties, input node, and output node. -- Legend: Display the meaning of each icon in the computational graph. - -## Dataset Graph Visualization - -Dataset graph visualization is used to display data processing and augmentation information of a single model training. - -![data_function.png](./images/data_function.png) - -Figure 8: Dataset graph function area - -Figure 8 shows the dataset graph function area which includes the following content: - -- Legend: Display the meaning of each icon in the data lineage graph. -- Data processing pipeline: Display the data processing pipeline used for training. Select a single node in the graph to view details. -- Node information: Display basic information about the selected node, including names and parameters of the data processing and augmentation operators. - -## Image Visualization - -Image visualization is used to display images specified by users. - -![image.png](./images/image_vi.png) - -Figure 9: Image visualization - -Figure 9 shows how to view images of different steps by sliding the Step slider. - -![image_function.png](./images/image_function.png) - -Figure 10: Image visualization function area - -Figure 10 shows the function area of image visualization. You can view image information by selecting different tags, brightness, and contrast. - -- Tag: Select the required tags to view the corresponding image information. -- Brightness adjustment: Adjust the brightness of all displayed images. -- Contrast adjustment: Adjust the contrast of all displayed images. - -## Tensor Visualization - -Tensor visualization is used to display tensors in the form of table and histogram. - -![tensor_function.png](./images/tensor_function.png) - -Figure 11: Tensor visualization function area - -Figure 11 shows the function area of tensor visualization. - -- Tag selection: Select the required tags to view the corresponding table data or histogram. -- View: Select `Table` or `Histogram` to display tensor data. In the `Histogram` view, there are the options of `Vertical axis` and `Angle of view`. -- Vertical axis: Select any of `Step`, `Relative time`, and `Absolute time` as the data displayed on the vertical axis of the histogram. -- Angle of view: Select either `Front` or `Top`. `Front` view refers to viewing the histogram from the front view. In this case, data between different steps is overlapped. `Top` view refers to viewing the histogram at an angle of 45 degrees. In this case, data between different steps can be presented. - -![tensor_table.png](./images/tensor_table.png) - -Figure 12: Table display - -Figure 12 shows tensors recorded by a user in a form of a table which includes the following function: - -- Click the small square button on the right side of the table to zoom in the table. -- The white box in the table shows the tensor data under which dimension is currently displayed, where the colon `:` represents all values of the current dimension, you can enter the corresponding index or `:` in the box and press `Enter` or click the button of tick on the back to query tensor data for specific dimensions. - Assuming a certain dimension is 32, the index range is -32 to 31. Note: tensor data from 0 to 2 dimensions can be queried. Tensor data of more than two dimensions is not supported, in other word, the query conditions of more than two colons `:` cannot be set. -- Query the tensor data of a specific step by dragging the hollow circle below the table. - -![tensor_histogram.png](./images/tensor_histogram.png) - -Figure 13: Histogram display - -Figure 13 shows tensors recorded by a user in a form of a histogram. Click the upper right corner to zoom in the histogram. - -## Notices - - -1. Currently MindSpore supports recording computational graph after operator fusion for Ascend 910 AI processor only. - -2. When using the Summary operator to collect data in training, 'HistogramSummary' operator affects performance, so please use as little as possible. - -3. To limit memory usage, MindInsight limits the number of tags and steps: - - There are 300 tags at most in each training dashboard. Total number of scalar tags, image tags, computation graph tags, parameter distribution(histogram) tags, tensor tags can not exceed 300. Specially, there are 10 computation graph tags and 6 tensor tags at most. When tags exceed limit, MindInsight preserves the most recently processed tags. - - There are 1000 steps at most for each scalar tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. - - There are 10 steps at most for each image tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. - - There are 50 steps at most for each parameter distribution(histogram) tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. - - There are 20 steps at most for each tensor tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. - -4. Since `TensorSummary` will record complete tensor data, the amount of data is usually relatively large. In order to limit memory usage and ensure performance, MindInsight make the following restrictions with the size of tensor and the number of value responsed and displayed on the front end: - - MindInsight supports loading tensor containing up to 10 million values. - - After the tensor is loaded, in the tensor-visible table view, you can view a maximum of 100,000 values. If the value obtained by the selected dimension query exceeds this limit, it cannot be displayed. - -5. Since tensor visualizatioin (`TensorSummary`) records raw tensor data, it requires a large amount of storage space. Before using `TensorSummary` and during training, please check that the system storage space is sufficient. - The storage space occupied by the tensor visualizatioin function can be reduced by the following methods: - 1) Avoid using `TensorSummary` to record larger tensor. - - 2) Reduce the number of `TensorSummary` operators in the network. - - After using the function, please clean up the training logs that are no longer needed in time to free up disk space. - - Remarks: The method of estimating the space usage of `TensorSummary` is as follows: - - The size of a `TensorSummary` data = the number of values in the tensor * 4 bytes. Assuming that the size of the tensor recorded by `TensorSummary` is 32 * 1 * 256 * 256, then a `TensorSummary` data needs about 32 * 1 * 256 * 256 * 4 bytes = 8,388,608 bytes = 8MiB. `TensorSummary` will record data of 20 steps by default. Then the required space when recording these 20 sets of data is about 20 * 8 MiB = 160MiB. It should be noted that due to the overhead of data structure and other factors, the actual storage space used will be slightly larger than 160MiB. - +# Dashboard + +`Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` + + + +- [Dashboard](#dashboard) + - [Overview](#overview) + - [Scalar Visualization](#scalar-visualization) + - [Parameter Distribution Visualization](#parameter-distribution-visualization) + - [Computational Graph Visualization](#computational-graph-visualization) + - [Dataset Graph Visualization](#dataset-graph-visualization) + - [Image Visualization](#image-visualization) + - [Tensor Visualization](#tensor-visualization) + - [Notices](#notices) + + + + + +## Overview + +Training dashboard is an important part of mindinsight's visualization component, and its tags include scalar visualization, parameter distribution visualization, computational visualization, data visualization, image visualization and tensor visualization. + +Access the Training Dashboard by selecting a specific training from the training list. + +## Scalar Visualization + +Scalar visualization is used to display the change trend of scalars during training. + +![scalar.png](./images/scalar.png) + +Figure 1: Scalar trend chart + +Figure 1 shows a change process of loss values during the neural network training. The horizontal coordinate indicates the training step, and the vertical coordinate indicates the loss value. + +Buttons from left to right in the upper right corner of the figure are used to display the chart in full screen, switch the Y-axis scale, enable or disable the rectangle selection, roll back the chart step by step, and restore the chart. + +- Full-screen display: Display the scalar curve in full screen. Click the button again to restore it. +- Switch Y-axis scale: Perform logarithmic conversion on the Y-axis coordinate. +- Enable/Disable rectangle selection: Draw a rectangle to select and zoom in a part of the chart. You can perform rectangle selection again on the zoomed-in chart. +- Step-by-step Rollback: Cancel operations step by step after continuously drawing rectangles to select and zooming in the same area. +- Restore chart: Restore a chart to the original state. + +There can set the threshold value to highlight the value or delete the threshold value in the lower right corner of the figure. As shown in the figure, the threshold set is less than 1.5, highlighted in red shows what is below the threshold, and it is intuitive to see the expected data value or some unusual value. + +![scalar_select.png](./images/scalar_select.png) + +Figure 2: Scalar visualization function area + +Figure 2 shows the scalar visualization function area, which allows you to view scalar information by selecting different tags, different dimensions of the horizontal axis, and smoothness. + +- Tag selection: Select the required tags to view the corresponding scalar information. +- Horizontal axis: Select any of Step, Relative Time, and Absolute Time as the horizontal axis of the scalar curve. +- Smoothness: adjust the smoothness to smooth the scalar curve. +- Scalar synthesis: Synthesize two scalar curves and display them in a chart to facilitate comparison between the two curves or view the synthesized chart. + +![scalar_compound.png](./images/scalar_compound.png) + +Figure 3: Scalar synthesis of Accuracy and Loss curves + +Figure 3 shows the scalar synthesis of the Accuracy and Loss curves. The function area of scalar synthesis is similar to that of scalar visualization. Different from the scalar visualization function area, the scalar synthesis function allows you to select a maximum of two tags at a time to synthesize and display their curves. + +## Parameter Distribution Visualization + +The parameter distribution in a form of a histogram displays tensors specified by a user. + +![histogram.png](./images/histogram.png) + +Figure 4: Histogram + +Figure 4 shows tensors recorded by a user in a form of a histogram. Click the upper right corner to zoom in the histogram. + +![histogram_func.png](./images/histogram_func.png) + +Figure 5: Function area of the parameter distribution histogram + +Figure 5 shows the function area of the parameter distribution histogram, including: + +- Tag selection: Select the required tags to view the corresponding histogram. +- Vertical axis: Select any of `Step`, `Relative time`, and `Absolute time` as the data displayed on the vertical axis of the histogram. +- Angle of view: Select either `Front` or `Top`. `Front` view refers to viewing the histogram from the front view. In this case, data between different steps is overlapped. `Top` view refers to viewing the histogram at an angle of 45 degrees. In this case, data between different steps can be presented. + +## Computational Graph Visualization + +Computational graph visualization is used to display the graph structure, data flow direction, and control flow direction of a computational graph. It supports visualization of summary log files and pb files generated by `save_graphs` configuration in `context`. + +![graph.png](./images/graph.png) + +Figure 6: Computational graph display area + +Figure 6 shows the network structure of a computational graph. As shown in the figure, select an operator in the area of the display area. The operator has two inputs and one outputs (the solid line indicates the data flow direction of the operator). + +![graph_sidebar.png](./images/graph_sidebar.png) + +Figure 7: Computational graph function area + +Figure 7 shows the function area of the computational graph, including: + +- File selection box: View the computational graphs of different files. +- Search box: Enter a node name and press Enter to view the node. +- Thumbnail: Display the thumbnail of the entire network structure. When viewing an extra large image structure, you can view the currently browsed area. +- Node information: Display the basic information of the selected node, including the node name, properties, input node, and output node. +- Legend: Display the meaning of each icon in the computational graph. + +## Dataset Graph Visualization + +Dataset graph visualization is used to display data processing and augmentation information of a single model training. + +![data_function.png](./images/data_function.png) + +Figure 8: Dataset graph function area + +Figure 8 shows the dataset graph function area which includes the following content: + +- Legend: Display the meaning of each icon in the data lineage graph. +- Data processing pipeline: Display the data processing pipeline used for training. Select a single node in the graph to view details. +- Node information: Display basic information about the selected node, including names and parameters of the data processing and augmentation operators. + +## Image Visualization + +Image visualization is used to display images specified by users. + +![image.png](./images/image_vi.png) + +Figure 9: Image visualization + +Figure 9 shows how to view images of different steps by sliding the Step slider. + +![image_function.png](./images/image_function.png) + +Figure 10: Image visualization function area + +Figure 10 shows the function area of image visualization. You can view image information by selecting different tags, brightness, and contrast. + +- Tag: Select the required tags to view the corresponding image information. +- Brightness adjustment: Adjust the brightness of all displayed images. +- Contrast adjustment: Adjust the contrast of all displayed images. + +## Tensor Visualization + +Tensor visualization is used to display tensors in the form of table and histogram. + +![tensor_function.png](./images/tensor_function.png) + +Figure 11: Tensor visualization function area + +Figure 11 shows the function area of tensor visualization. + +- Tag selection: Select the required tags to view the corresponding table data or histogram. +- View: Select `Table` or `Histogram` to display tensor data. In the `Histogram` view, there are the options of `Vertical axis` and `Angle of view`. +- Vertical axis: Select any of `Step`, `Relative time`, and `Absolute time` as the data displayed on the vertical axis of the histogram. +- Angle of view: Select either `Front` or `Top`. `Front` view refers to viewing the histogram from the front view. In this case, data between different steps is overlapped. `Top` view refers to viewing the histogram at an angle of 45 degrees. In this case, data between different steps can be presented. + +![tensor_table.png](./images/tensor_table.png) + +Figure 12: Table display + +Figure 12 shows tensors recorded by a user in a form of a table which includes the following function: + +- Click the small square button on the right side of the table to zoom in the table. +- The white box in the table shows the tensor data under which dimension is currently displayed, where the colon `:` represents all values of the current dimension, you can enter the corresponding index or `:` in the box and press `Enter` or click the button of tick on the back to query tensor data for specific dimensions. + Assuming a certain dimension is 32, the index range is -32 to 31. Note: tensor data from 0 to 2 dimensions can be queried. Tensor data of more than two dimensions is not supported, in other word, the query conditions of more than two colons `:` cannot be set. +- Query the tensor data of a specific step by dragging the hollow circle below the table. + +![tensor_histogram.png](./images/tensor_histogram.png) + +Figure 13: Histogram display + +Figure 13 shows tensors recorded by a user in a form of a histogram. Click the upper right corner to zoom in the histogram. + +## Notices + + +1. Currently MindSpore supports recording computational graph after operator fusion for Ascend 910 AI processor only. + +2. When using the Summary operator to collect data in training, 'HistogramSummary' operator affects performance, so please use as little as possible. + +3. To limit memory usage, MindInsight limits the number of tags and steps: + - There are 300 tags at most in each training dashboard. Total number of scalar tags, image tags, computation graph tags, parameter distribution(histogram) tags, tensor tags can not exceed 300. Specially, there are 10 computation graph tags and 6 tensor tags at most. When tags exceed limit, MindInsight preserves the most recently processed tags. + - There are 1000 steps at most for each scalar tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. + - There are 10 steps at most for each image tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. + - There are 50 steps at most for each parameter distribution(histogram) tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. + - There are 20 steps at most for each tensor tag in each training dashboard. When steps exceed limit, MindInsight will sample steps randomly to meet this limit. + +4. Since `TensorSummary` will record complete tensor data, the amount of data is usually relatively large. In order to limit memory usage and ensure performance, MindInsight make the following restrictions with the size of tensor and the number of value responsed and displayed on the front end: + - MindInsight supports loading tensor containing up to 10 million values. + - After the tensor is loaded, in the tensor-visible table view, you can view a maximum of 100,000 values. If the value obtained by the selected dimension query exceeds this limit, it cannot be displayed. + +5. Since tensor visualizatioin (`TensorSummary`) records raw tensor data, it requires a large amount of storage space. Before using `TensorSummary` and during training, please check that the system storage space is sufficient. + The storage space occupied by the tensor visualizatioin function can be reduced by the following methods: + 1) Avoid using `TensorSummary` to record larger tensor. + + 2) Reduce the number of `TensorSummary` operators in the network. + + After using the function, please clean up the training logs that are no longer needed in time to free up disk space. + + Remarks: The method of estimating the space usage of `TensorSummary` is as follows: + + The size of a `TensorSummary` data = the number of values in the tensor * 4 bytes. Assuming that the size of the tensor recorded by `TensorSummary` is 32 * 1 * 256 * 256, then a `TensorSummary` data needs about 32 * 1 * 256 * 256 * 4 bytes = 8,388,608 bytes = 8MiB. `TensorSummary` will record data of 20 steps by default. Then the required space when recording these 20 sets of data is about 20 * 8 MiB = 160MiB. It should be noted that due to the overhead of data structure and other factors, the actual storage space used will be slightly larger than 160MiB. + 6. The training log file is large when using `TensorSummary` because the complete tensor data is recorded. MindInsight needs more time to parse the training log file, please be patient. \ No newline at end of file diff --git a/tutorials/source_en/advanced_use/debugging_in_pynative_mode.md b/tutorials/training/source_en/advanced_use/debugging_in_pynative_mode.md similarity index 100% rename from tutorials/source_en/advanced_use/debugging_in_pynative_mode.md rename to tutorials/training/source_en/advanced_use/debugging_in_pynative_mode.md diff --git a/tutorials/source_en/advanced_use/differential_privacy.md b/tutorials/training/source_en/advanced_use/differential_privacy.md similarity index 98% rename from tutorials/source_en/advanced_use/differential_privacy.md rename to tutorials/training/source_en/advanced_use/differential_privacy.md index 57bd79f4ad..13ea9770f5 100644 --- a/tutorials/source_en/advanced_use/differential_privacy.md +++ b/tutorials/training/source_en/advanced_use/differential_privacy.md @@ -1,358 +1,358 @@ -# Differential Privacy in Machine Learning - -`Linux` `Ascend` `Model Development` `Model Optimization` `Enterprise` `Expert` - - - -- [Differential Privacy in Machine Learning](#differential-privacy-in-machine-learning) - - [Overview](#overview) - - [Implementation](#implementation) - - [Importing Library Files](#importing-library-files) - - [Configuring Parameters](#configuring-parameters) - - [Preprocessing the Dataset](#preprocessing-the-dataset) - - [Creating the Model](#creating-the-model) - - [Introducing the Differential Privacy](#introducing-the-differential-privacy) - - [References](#references) - - - - - -## Overview - -Differential privacy is a mechanism for protecting user data privacy. What is privacy? Privacy refers to the attributes of individual users. Common attributes shared by a group of users may not be considered as privacy. For example, if we say "smoking people have a higher probability of getting lung cancer", it does not disclose privacy. However, if we say "Zhang San smokes and gets lung cancer", it discloses the privacy of Zhang San. Assume that there are 100 patients in a hospital and 10 of them have lung cancer. If the information of any 99 patients are known, we can infer whether the remaining one has lung cancer. This behavior of stealing privacy is called differential attack. Differential privacy is a method for preventing differential attacks. By adding noise, the query results of two datasets with only one different record are nearly indistinguishable. In the above example, after differential privacy is used, the statistic information of the 100 patients achieved by the attacker is almost the same as that of the 99 patients. Therefore, the attacker can hardly infer the information of the remaining one patient. - -**Differential privacy in machine learning** - -Machine learning algorithms usually update model parameters and learn data features based on a large amount of data. Ideally, these models can learn the common features of a class of entities and achieve good generalization, such as "smoking patients are more likely to get lung cancer" rather than models with individual features, such as "Zhang San is a smoker who gets lung cancer." However, machine learning algorithms do not distinguish between general and individual features. The published machine learning models, especially the deep neural networks, may unintentionally memorize and expose the features of individual entities in training data. This can be exploited by malicious attackers to reveal Zhang San's privacy information from the published model. Therefore, it is necessary to use differential privacy to protect machine learning models from privacy leakage. - -**Differential privacy definition** [1] - -$Pr[\mathcal{K}(D)\in S] \le e^{\epsilon} Pr[\mathcal{K}(D') \in S]+\delta$ - -For datasets $D$ and $D'$ that differ on only one record, the probability of obtaining the same result from $\mathcal{K}(D)$ and $\mathcal{K}(D')$ by using a randomized algorithm $\mathcal{K}$ must meet the preceding formula. $\epsilon$ indicates the differential privacy budget and $\delta$ indicates the perturbation. The smaller the values of $\epsilon$ and $\delta$, the closer the data distribution output by $\mathcal{K}$ on $D$ and $D'$. - -**Differential privacy measurement** - -Differential privacy can be measured using $\epsilon$ and $\delta$. - -- $\epsilon$: specifies the upper limit of the output probability that can be changed when a record is added to or deleted from the dataset. We usually hope that $\epsilon$ is a small constant. A smaller value indicates stricter differential privacy conditions. -- $\delta$: limits the probability of arbitrary model behavior change. Generally, this parameter is set to a small constant. You are advised to set this parameter to a value less than the reciprocal of the size of a training dataset. - -**Differential privacy implemented by MindArmour** - -MindArmour differential privacy module Differential-Privacy implements the differential privacy optimizer. Currently, SGD, Momentum, and Adam are supported. They are differential privacy optimizers based on the Gaussian mechanism. Gaussian noise mechanism supports both non-adaptive policy and adaptive policy The non-adaptive policy use a fixed noise parameter for each step while the adaptive policy changes the noise parameter along time or iteration step. An advantage of using the non-adaptive Gaussian noise is that a differential privacy budget $\epsilon$ can be strictly controlled. However, a disadvantage is that in a model training process, the noise amount added in each step is fixed. In the later training stage, large noise makes the model convergence difficult, and even causes the performance to decrease greatly and the model usability to be poor. Adaptive noise can solve this problem. In the initial model training stage, the amount of added noise is large. As the model converges, the amount of noise decreases gradually, and the impact of noise on model availability decreases. The disadvantage is that the differential privacy budget cannot be strictly controlled. Under the same initial value, the $\epsilon$ of the adaptive differential privacy is greater than that of the non-adaptive differential privacy. Rényi differential privacy (RDP) [2] is also provided to monitor differential privacy budgets. - -The LeNet model and MNIST dataset are used as an example to describe how to use the differential privacy optimizer to train a neural network model on MindSpore. - -> This example is for the Ascend 910 AI processor. You can download the complete sample code from . - -## Implementation - -### Importing Library Files - -The following are the required public modules, MindSpore modules, and differential privacy feature modules. - -```python -import os -from easydict import EasyDict as edict - -import mindspore.nn as nn -from mindspore import context -from mindspore.train.callback import ModelCheckpoint -from mindspore.train.callback import CheckpointConfig -from mindspore.train.callback import LossMonitor -from mindspore.nn.metrics import Accuracy -from mindspore.train.serialization import load_checkpoint, load_param_into_net -import mindspore.dataset as ds -import mindspore.dataset.vision.c_transforms as CV -import mindspore.dataset.transforms.c_transforms as C -from mindspore.dataset.vision import Inter -import mindspore.common.dtype as mstype - -from mindarmour.diff_privacy import DPModel -from mindarmour.diff_privacy import PrivacyMonitorFactory -from mindarmour.diff_privacy import NoiseMechanismsFactory -from mindarmour.diff_privacy import ClipMechanismsFactory -from mindarmour.utils.logger import LogUtil -from lenet5_net import LeNet5 -from lenet5_config import mnist_cfg as cfg - -LOGGER = LogUtil.get_instance() -LOGGER.set_level('INFO') -TAG = 'Lenet5_train' -``` - -### Configuring Parameters - -1. Set the running environment, dataset path, model training parameters, checkpoint storage parameters, and differential privacy parameters. Replace 'data_path' with you data path. For more configurations, see . - - ```python - cfg = edict({ - 'num_classes': 10, # the number of classes of model's output - 'lr': 0.01, # the learning rate of model's optimizer - 'momentum': 0.9, # the momentum value of model's optimizer - 'epoch_size': 10, # training epochs - 'batch_size': 256, # batch size for training - 'image_height': 32, # the height of training samples - 'image_width': 32, # the width of training samples - 'save_checkpoint_steps': 234, # the interval steps for saving checkpoint file of the model - 'keep_checkpoint_max': 10, # the maximum number of checkpoint files would be saved - 'device_target': 'Ascend', # device used - 'data_path': './MNIST_unzip', # the path of training and testing data set - 'dataset_sink_mode': False, # whether deliver all training data to device one time - 'micro_batches': 32, # the number of small batches split from an original batch - 'norm_bound': 1.0, # the clip bound of the gradients of model's training parameters - 'initial_noise_multiplier': 0.05, # the initial multiplication coefficient of the noise added to training - # parameters' gradients - 'noise_mechanisms': 'Gaussian', # the method of adding noise in gradients while training - 'clip_mechanisms': 'Gaussian', # the method of adaptive clipping gradients while training - 'clip_decay_policy': 'Linear', # Decay policy of adaptive clipping, decay_policy must be in ['Linear', 'Geometric']. - 'clip_learning_rate': 0.001, # Learning rate of update norm clip. - 'target_unclipped_quantile': 0.9, # Target quantile of norm clip. - 'fraction_stddev': 0.01, # The stddev of Gaussian normal which used in empirical_fraction. - 'optimizer': 'Momentum' # the base optimizer used for Differential privacy training - }) - ``` - -2. Configure necessary information, including the environment information and execution mode. - - ```python - context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) - ``` - - For details about the API configuration, see the `context.set_context`. - -### Preprocessing the Dataset - -Load the dataset and convert the dataset format to a MindSpore data format. - -```python -def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, - num_parallel_workers=1, sparse=True): - """ - create dataset for training or testing - """ - # define dataset - ds1 = ds.MnistDataset(data_path) - - # define operation parameters - resize_height, resize_width = 32, 32 - rescale = 1.0 / 255.0 - shift = 0.0 - - # define map operations - resize_op = CV.Resize((resize_height, resize_width), - interpolation=Inter.LINEAR) - rescale_op = CV.Rescale(rescale, shift) - hwc2chw_op = CV.HWC2CHW() - type_cast_op = C.TypeCast(mstype.int32) - - # apply map operations on images - if not sparse: - one_hot_enco = C.OneHot(10) - ds1 = ds1.map(operations=one_hot_enco, input_columns="label", - num_parallel_workers=num_parallel_workers) - type_cast_op = C.TypeCast(mstype.float32) - ds1 = ds1.map(operations=type_cast_op, input_columns="label", - num_parallel_workers=num_parallel_workers) - ds1 = ds1.map(operations=resize_op, input_columns="image", - num_parallel_workers=num_parallel_workers) - ds1 = ds1.map(operations=rescale_op, input_columns="image", - num_parallel_workers=num_parallel_workers) - ds1 = ds1.map(operations=hwc2chw_op, input_columns="image", - num_parallel_workers=num_parallel_workers) - - # apply DatasetOps - buffer_size = 10000 - ds1 = ds1.shuffle(buffer_size=buffer_size) - ds1 = ds1.batch(batch_size, drop_remainder=True) - ds1 = ds1.repeat(repeat_size) - - return ds1 -``` - -### Creating the Model - -The LeNet model is used as an example. You can also create and train your own model. - -```python -from mindspore import nn -from mindspore.common.initializer import TruncatedNormal - - -def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): - weight = weight_variable() - return nn.Conv2d(in_channels, out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, - weight_init=weight, has_bias=False, pad_mode="valid") - - -def fc_with_initialize(input_channels, out_channels): - weight = weight_variable() - bias = weight_variable() - return nn.Dense(input_channels, out_channels, weight, bias) - - -def weight_variable(): - return TruncatedNormal(0.05) - - -class LeNet5(nn.Cell): - """ - LeNet network - """ - def __init__(self): - super(LeNet5, self).__init__() - self.conv1 = conv(1, 6, 5) - self.conv2 = conv(6, 16, 5) - self.fc1 = fc_with_initialize(16*5*5, 120) - self.fc2 = fc_with_initialize(120, 84) - self.fc3 = fc_with_initialize(84, 10) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` - -Load the LeNet network, define the loss function, configure the checkpoint parameters, and load data by using the `generate_mnist_dataset` function defined in the preceding information. - -```python -network = LeNet5() -net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") -config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps, - keep_checkpoint_max=cfg.keep_checkpoint_max) -ckpoint_cb = ModelCheckpoint(prefix="checkpoint_lenet", - directory='./trained_ckpt_file/', - config=config_ck) - -# get training dataset -ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), - cfg.batch_size) -``` - -### Introducing the Differential Privacy - -1. Set parameters of a differential privacy optimizer. - - - Determine whether values of the `micro_batches` and `batch_size` parameters meet the requirements. The value of `batch_size` must be an integer multiple of `micro_batches`. - - Instantiate a differential privacy factory class. - - Set a noise mechanism for the differential privacy. Currently, the Gaussian noise mechanism with a fixed standard deviation (`Gaussian`) and the Gaussian noise mechanism with an adaptive standard deviation (`AdaGaussian`) are supported. - - Set an optimizer type. Currently, `SGD`, `Momentum`, and `Adam` are supported. - - Set up a differential privacy budget monitor RDP to observe changes in the differential privacy budget $\epsilon$ in each step. - - ```python - if cfg.micro_batches and cfg.batch_size % cfg.micro_batches != 0: - raise ValueError( - "Number of micro_batches should divide evenly batch_size") - # Create a factory class of DP noise mechanisms, this method is adding noise - # in gradients while training. Initial_noise_multiplier is suggested to be - # greater than 1.0, otherwise the privacy budget would be huge, which means - # that the privacy protection effect is weak. Mechanisms can be 'Gaussian' - # or 'AdaGaussian', in which noise would be decayed with 'AdaGaussian' - # mechanism while be constant with 'Gaussian' mechanism. - noise_mech = NoiseMechanismsFactory().create(cfg.noise_mechanisms, - norm_bound=cfg.norm_bound, - initial_noise_multiplier=cfg.initial_noise_multiplier, - decay_policy=None) - # Create a factory class of clip mechanisms, this method is to adaptive clip - # gradients while training, decay_policy support 'Linear' and 'Geometric', - # learning_rate is the learning rate to update clip_norm, - # target_unclipped_quantile is the target quantile of norm clip, - # fraction_stddev is the stddev of Gaussian normal which used in - # empirical_fraction, the formula is - # $empirical_fraction + N(0, fraction_stddev)$. - clip_mech = ClipMechanismsFactory().create(cfg.clip_mechanisms, - decay_policy=cfg.clip_decay_policy, - learning_rate=cfg.clip_learning_rate, - target_unclipped_quantile=cfg.target_unclipped_quantile, - fraction_stddev=cfg.fraction_stddev) - net_opt = nn.Momentum(params=network.trainable_params(), - learning_rate=cfg.lr, momentum=cfg.momentum) - # Create a monitor for DP training. The function of the monitor is to - # compute and print the privacy budget(eps and delta) while training. - rdp_monitor = PrivacyMonitorFactory.create('rdp', - num_samples=60000, - batch_size=cfg.batch_size, - initial_noise_multiplier=cfg.initial_noise_multiplier, - per_print_times=234, - noise_decay_mode=None) - ``` - -2. Package the LeNet model as a differential privacy model by transferring the network to `DPModel`. - - ```python - # Create the DP model for training. - model = DPModel(micro_batches=cfg.micro_batches, - norm_bound=cfg.norm_bound, - noise_mech=noise_mech, - clip_mech=clip_mech, - network=network, - loss_fn=net_loss, - optimizer=net_opt, - metrics={"Accuracy": Accuracy()}) - ``` - -3. Train and test the model. - - ```python - LOGGER.info(TAG, "============== Starting Training ==============") - model.train(cfg['epoch_size'], ds_train, - callbacks=[ckpoint_cb, LossMonitor(), rdp_monitor], - dataset_sink_mode=cfg.dataset_sink_mode) - - LOGGER.info(TAG, "============== Starting Testing ==============") - ckpt_file_name = 'trained_ckpt_file/checkpoint_lenet-10_234.ckpt' - param_dict = load_checkpoint(ckpt_file_name) - load_param_into_net(network, param_dict) - ds_eval = generate_mnist_dataset(os.path.join(cfg.data_path, 'test'), - batch_size=cfg.batch_size) - acc = model.eval(ds_eval, dataset_sink_mode=False) - LOGGER.info(TAG, "============== Accuracy: %s ==============", acc) - ``` - -4. Run the following command. - - Execute the script: - - ```bash - python lenet5_dp.py - ``` - - In the preceding command, replace `lenet5_dp.py` with the name of your script. - -5. Display the result. - - The accuracy of the LeNet model without differential privacy is 99%, and the accuracy of the LeNet model with Gaussian noise and adaptive clip differential privacy is mostly more than 95%. - ``` - ============== Starting Training ============== - ... - ============== Starting Testing ============== - ... - ============== Accuracy: 0.9698 ============== - ``` - -### References - -[1] C. Dwork and J. Lei. Differential privacy and robust statistics. In STOC, pages 371–380. ACM, 2009. - -[2] Ilya Mironov. Rényi differential privacy. In IEEE Computer Security Foundations Symposium, 2017. - -[3] Abadi, M. e. a., 2016. *Deep learning with differential privacy.* s.l.:Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security. - - - +# Differential Privacy in Machine Learning + +`Linux` `Ascend` `Model Development` `Model Optimization` `Enterprise` `Expert` + + + +- [Differential Privacy in Machine Learning](#differential-privacy-in-machine-learning) + - [Overview](#overview) + - [Implementation](#implementation) + - [Importing Library Files](#importing-library-files) + - [Configuring Parameters](#configuring-parameters) + - [Preprocessing the Dataset](#preprocessing-the-dataset) + - [Creating the Model](#creating-the-model) + - [Introducing the Differential Privacy](#introducing-the-differential-privacy) + - [References](#references) + + + + + +## Overview + +Differential privacy is a mechanism for protecting user data privacy. What is privacy? Privacy refers to the attributes of individual users. Common attributes shared by a group of users may not be considered as privacy. For example, if we say "smoking people have a higher probability of getting lung cancer", it does not disclose privacy. However, if we say "Zhang San smokes and gets lung cancer", it discloses the privacy of Zhang San. Assume that there are 100 patients in a hospital and 10 of them have lung cancer. If the information of any 99 patients are known, we can infer whether the remaining one has lung cancer. This behavior of stealing privacy is called differential attack. Differential privacy is a method for preventing differential attacks. By adding noise, the query results of two datasets with only one different record are nearly indistinguishable. In the above example, after differential privacy is used, the statistic information of the 100 patients achieved by the attacker is almost the same as that of the 99 patients. Therefore, the attacker can hardly infer the information of the remaining one patient. + +**Differential privacy in machine learning** + +Machine learning algorithms usually update model parameters and learn data features based on a large amount of data. Ideally, these models can learn the common features of a class of entities and achieve good generalization, such as "smoking patients are more likely to get lung cancer" rather than models with individual features, such as "Zhang San is a smoker who gets lung cancer." However, machine learning algorithms do not distinguish between general and individual features. The published machine learning models, especially the deep neural networks, may unintentionally memorize and expose the features of individual entities in training data. This can be exploited by malicious attackers to reveal Zhang San's privacy information from the published model. Therefore, it is necessary to use differential privacy to protect machine learning models from privacy leakage. + +**Differential privacy definition** [1] + +$Pr[\mathcal{K}(D)\in S] \le e^{\epsilon} Pr[\mathcal{K}(D') \in S]+\delta$ + +For datasets $D$ and $D'$ that differ on only one record, the probability of obtaining the same result from $\mathcal{K}(D)$ and $\mathcal{K}(D')$ by using a randomized algorithm $\mathcal{K}$ must meet the preceding formula. $\epsilon$ indicates the differential privacy budget and $\delta$ indicates the perturbation. The smaller the values of $\epsilon$ and $\delta$, the closer the data distribution output by $\mathcal{K}$ on $D$ and $D'$. + +**Differential privacy measurement** + +Differential privacy can be measured using $\epsilon$ and $\delta$. + +- $\epsilon$: specifies the upper limit of the output probability that can be changed when a record is added to or deleted from the dataset. We usually hope that $\epsilon$ is a small constant. A smaller value indicates stricter differential privacy conditions. +- $\delta$: limits the probability of arbitrary model behavior change. Generally, this parameter is set to a small constant. You are advised to set this parameter to a value less than the reciprocal of the size of a training dataset. + +**Differential privacy implemented by MindArmour** + +MindArmour differential privacy module Differential-Privacy implements the differential privacy optimizer. Currently, SGD, Momentum, and Adam are supported. They are differential privacy optimizers based on the Gaussian mechanism. Gaussian noise mechanism supports both non-adaptive policy and adaptive policy The non-adaptive policy use a fixed noise parameter for each step while the adaptive policy changes the noise parameter along time or iteration step. An advantage of using the non-adaptive Gaussian noise is that a differential privacy budget $\epsilon$ can be strictly controlled. However, a disadvantage is that in a model training process, the noise amount added in each step is fixed. In the later training stage, large noise makes the model convergence difficult, and even causes the performance to decrease greatly and the model usability to be poor. Adaptive noise can solve this problem. In the initial model training stage, the amount of added noise is large. As the model converges, the amount of noise decreases gradually, and the impact of noise on model availability decreases. The disadvantage is that the differential privacy budget cannot be strictly controlled. Under the same initial value, the $\epsilon$ of the adaptive differential privacy is greater than that of the non-adaptive differential privacy. Rényi differential privacy (RDP) [2] is also provided to monitor differential privacy budgets. + +The LeNet model and MNIST dataset are used as an example to describe how to use the differential privacy optimizer to train a neural network model on MindSpore. + +> This example is for the Ascend 910 AI processor. You can download the complete sample code from . + +## Implementation + +### Importing Library Files + +The following are the required public modules, MindSpore modules, and differential privacy feature modules. + +```python +import os +from easydict import EasyDict as edict + +import mindspore.nn as nn +from mindspore import context +from mindspore.train.callback import ModelCheckpoint +from mindspore.train.callback import CheckpointConfig +from mindspore.train.callback import LossMonitor +from mindspore.nn.metrics import Accuracy +from mindspore.train.serialization import load_checkpoint, load_param_into_net +import mindspore.dataset as ds +import mindspore.dataset.vision.c_transforms as CV +import mindspore.dataset.transforms.c_transforms as C +from mindspore.dataset.vision import Inter +import mindspore.common.dtype as mstype + +from mindarmour.diff_privacy import DPModel +from mindarmour.diff_privacy import PrivacyMonitorFactory +from mindarmour.diff_privacy import NoiseMechanismsFactory +from mindarmour.diff_privacy import ClipMechanismsFactory +from mindarmour.utils.logger import LogUtil +from lenet5_net import LeNet5 +from lenet5_config import mnist_cfg as cfg + +LOGGER = LogUtil.get_instance() +LOGGER.set_level('INFO') +TAG = 'Lenet5_train' +``` + +### Configuring Parameters + +1. Set the running environment, dataset path, model training parameters, checkpoint storage parameters, and differential privacy parameters. Replace 'data_path' with you data path. For more configurations, see . + + ```python + cfg = edict({ + 'num_classes': 10, # the number of classes of model's output + 'lr': 0.01, # the learning rate of model's optimizer + 'momentum': 0.9, # the momentum value of model's optimizer + 'epoch_size': 10, # training epochs + 'batch_size': 256, # batch size for training + 'image_height': 32, # the height of training samples + 'image_width': 32, # the width of training samples + 'save_checkpoint_steps': 234, # the interval steps for saving checkpoint file of the model + 'keep_checkpoint_max': 10, # the maximum number of checkpoint files would be saved + 'device_target': 'Ascend', # device used + 'data_path': './MNIST_unzip', # the path of training and testing data set + 'dataset_sink_mode': False, # whether deliver all training data to device one time + 'micro_batches': 32, # the number of small batches split from an original batch + 'norm_bound': 1.0, # the clip bound of the gradients of model's training parameters + 'initial_noise_multiplier': 0.05, # the initial multiplication coefficient of the noise added to training + # parameters' gradients + 'noise_mechanisms': 'Gaussian', # the method of adding noise in gradients while training + 'clip_mechanisms': 'Gaussian', # the method of adaptive clipping gradients while training + 'clip_decay_policy': 'Linear', # Decay policy of adaptive clipping, decay_policy must be in ['Linear', 'Geometric']. + 'clip_learning_rate': 0.001, # Learning rate of update norm clip. + 'target_unclipped_quantile': 0.9, # Target quantile of norm clip. + 'fraction_stddev': 0.01, # The stddev of Gaussian normal which used in empirical_fraction. + 'optimizer': 'Momentum' # the base optimizer used for Differential privacy training + }) + ``` + +2. Configure necessary information, including the environment information and execution mode. + + ```python + context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) + ``` + + For details about the API configuration, see the `context.set_context`. + +### Preprocessing the Dataset + +Load the dataset and convert the dataset format to a MindSpore data format. + +```python +def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1, sparse=True): + """ + create dataset for training or testing + """ + # define dataset + ds1 = ds.MnistDataset(data_path) + + # define operation parameters + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + + # define map operations + resize_op = CV.Resize((resize_height, resize_width), + interpolation=Inter.LINEAR) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = C.TypeCast(mstype.int32) + + # apply map operations on images + if not sparse: + one_hot_enco = C.OneHot(10) + ds1 = ds1.map(operations=one_hot_enco, input_columns="label", + num_parallel_workers=num_parallel_workers) + type_cast_op = C.TypeCast(mstype.float32) + ds1 = ds1.map(operations=type_cast_op, input_columns="label", + num_parallel_workers=num_parallel_workers) + ds1 = ds1.map(operations=resize_op, input_columns="image", + num_parallel_workers=num_parallel_workers) + ds1 = ds1.map(operations=rescale_op, input_columns="image", + num_parallel_workers=num_parallel_workers) + ds1 = ds1.map(operations=hwc2chw_op, input_columns="image", + num_parallel_workers=num_parallel_workers) + + # apply DatasetOps + buffer_size = 10000 + ds1 = ds1.shuffle(buffer_size=buffer_size) + ds1 = ds1.batch(batch_size, drop_remainder=True) + ds1 = ds1.repeat(repeat_size) + + return ds1 +``` + +### Creating the Model + +The LeNet model is used as an example. You can also create and train your own model. + +```python +from mindspore import nn +from mindspore.common.initializer import TruncatedNormal + + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + return TruncatedNormal(0.05) + + +class LeNet5(nn.Cell): + """ + LeNet network + """ + def __init__(self): + super(LeNet5, self).__init__() + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16*5*5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, 10) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` + +Load the LeNet network, define the loss function, configure the checkpoint parameters, and load data by using the `generate_mnist_dataset` function defined in the preceding information. + +```python +network = LeNet5() +net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") +config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps, + keep_checkpoint_max=cfg.keep_checkpoint_max) +ckpoint_cb = ModelCheckpoint(prefix="checkpoint_lenet", + directory='./trained_ckpt_file/', + config=config_ck) + +# get training dataset +ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), + cfg.batch_size) +``` + +### Introducing the Differential Privacy + +1. Set parameters of a differential privacy optimizer. + + - Determine whether values of the `micro_batches` and `batch_size` parameters meet the requirements. The value of `batch_size` must be an integer multiple of `micro_batches`. + - Instantiate a differential privacy factory class. + - Set a noise mechanism for the differential privacy. Currently, the Gaussian noise mechanism with a fixed standard deviation (`Gaussian`) and the Gaussian noise mechanism with an adaptive standard deviation (`AdaGaussian`) are supported. + - Set an optimizer type. Currently, `SGD`, `Momentum`, and `Adam` are supported. + - Set up a differential privacy budget monitor RDP to observe changes in the differential privacy budget $\epsilon$ in each step. + + ```python + if cfg.micro_batches and cfg.batch_size % cfg.micro_batches != 0: + raise ValueError( + "Number of micro_batches should divide evenly batch_size") + # Create a factory class of DP noise mechanisms, this method is adding noise + # in gradients while training. Initial_noise_multiplier is suggested to be + # greater than 1.0, otherwise the privacy budget would be huge, which means + # that the privacy protection effect is weak. Mechanisms can be 'Gaussian' + # or 'AdaGaussian', in which noise would be decayed with 'AdaGaussian' + # mechanism while be constant with 'Gaussian' mechanism. + noise_mech = NoiseMechanismsFactory().create(cfg.noise_mechanisms, + norm_bound=cfg.norm_bound, + initial_noise_multiplier=cfg.initial_noise_multiplier, + decay_policy=None) + # Create a factory class of clip mechanisms, this method is to adaptive clip + # gradients while training, decay_policy support 'Linear' and 'Geometric', + # learning_rate is the learning rate to update clip_norm, + # target_unclipped_quantile is the target quantile of norm clip, + # fraction_stddev is the stddev of Gaussian normal which used in + # empirical_fraction, the formula is + # $empirical_fraction + N(0, fraction_stddev)$. + clip_mech = ClipMechanismsFactory().create(cfg.clip_mechanisms, + decay_policy=cfg.clip_decay_policy, + learning_rate=cfg.clip_learning_rate, + target_unclipped_quantile=cfg.target_unclipped_quantile, + fraction_stddev=cfg.fraction_stddev) + net_opt = nn.Momentum(params=network.trainable_params(), + learning_rate=cfg.lr, momentum=cfg.momentum) + # Create a monitor for DP training. The function of the monitor is to + # compute and print the privacy budget(eps and delta) while training. + rdp_monitor = PrivacyMonitorFactory.create('rdp', + num_samples=60000, + batch_size=cfg.batch_size, + initial_noise_multiplier=cfg.initial_noise_multiplier, + per_print_times=234, + noise_decay_mode=None) + ``` + +2. Package the LeNet model as a differential privacy model by transferring the network to `DPModel`. + + ```python + # Create the DP model for training. + model = DPModel(micro_batches=cfg.micro_batches, + norm_bound=cfg.norm_bound, + noise_mech=noise_mech, + clip_mech=clip_mech, + network=network, + loss_fn=net_loss, + optimizer=net_opt, + metrics={"Accuracy": Accuracy()}) + ``` + +3. Train and test the model. + + ```python + LOGGER.info(TAG, "============== Starting Training ==============") + model.train(cfg['epoch_size'], ds_train, + callbacks=[ckpoint_cb, LossMonitor(), rdp_monitor], + dataset_sink_mode=cfg.dataset_sink_mode) + + LOGGER.info(TAG, "============== Starting Testing ==============") + ckpt_file_name = 'trained_ckpt_file/checkpoint_lenet-10_234.ckpt' + param_dict = load_checkpoint(ckpt_file_name) + load_param_into_net(network, param_dict) + ds_eval = generate_mnist_dataset(os.path.join(cfg.data_path, 'test'), + batch_size=cfg.batch_size) + acc = model.eval(ds_eval, dataset_sink_mode=False) + LOGGER.info(TAG, "============== Accuracy: %s ==============", acc) + ``` + +4. Run the following command. + + Execute the script: + + ```bash + python lenet5_dp.py + ``` + + In the preceding command, replace `lenet5_dp.py` with the name of your script. + +5. Display the result. + + The accuracy of the LeNet model without differential privacy is 99%, and the accuracy of the LeNet model with Gaussian noise and adaptive clip differential privacy is mostly more than 95%. + ``` + ============== Starting Training ============== + ... + ============== Starting Testing ============== + ... + ============== Accuracy: 0.9698 ============== + ``` + +### References + +[1] C. Dwork and J. Lei. Differential privacy and robust statistics. In STOC, pages 371–380. ACM, 2009. + +[2] Ilya Mironov. Rényi differential privacy. In IEEE Computer Security Foundations Symposium, 2017. + +[3] Abadi, M. e. a., 2016. *Deep learning with differential privacy.* s.l.:Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security. + + + diff --git a/tutorials/source_en/advanced_use/distributed_training_ascend.md b/tutorials/training/source_en/advanced_use/distributed_training_ascend.md similarity index 100% rename from tutorials/source_en/advanced_use/distributed_training_ascend.md rename to tutorials/training/source_en/advanced_use/distributed_training_ascend.md diff --git a/tutorials/source_en/advanced_use/distributed_training_tutorials.rst b/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst similarity index 100% rename from tutorials/source_en/advanced_use/distributed_training_tutorials.rst rename to tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst diff --git a/tutorials/source_en/advanced_use/gradient_accumulation.md b/tutorials/training/source_en/advanced_use/gradient_accumulation.md similarity index 97% rename from tutorials/source_en/advanced_use/gradient_accumulation.md rename to tutorials/training/source_en/advanced_use/gradient_accumulation.md index acb3af83cf..0cd34505ef 100644 --- a/tutorials/source_en/advanced_use/gradient_accumulation.md +++ b/tutorials/training/source_en/advanced_use/gradient_accumulation.md @@ -1,266 +1,266 @@ -# Gradient Accumulation - -`Linux` `Ascend` `GPU` `Model Optimization` `Intermediate` `Expert` - - - -- [Gradient Accumulation](#gradient-accumulation) - - [Overview](#overview) - - [Creating a Gradient Accumulation Model](#creating-a-gradient-accumulation-model) - - [Importing Library Files](#importing-library-files) - - [Loading the Dataset](#loading-the-dataset) - - [Defining the Network](#defining-the-network) - - [Defining the Training Model](#defining-the-training-model) - - [Defining the Training Process](#defining-the-training-process) - - [Training and Saving the Model](#training-and-saving-the-model) - - [Experiment Result](#experiment-result) - - - - - -## Overview - -This tutorial describes the gradient accumulation training method to solve the problem that some large-scale networks cannot train large batch_size due to insufficient memory. - -In a traditional training method, after a loss and a gradient are calculated, a parameter is directly updated by using the obtained gradient. - -Different from the traditional training method, the concept of mini-batch is introduced to the gradient accumulation. The loss and gradient are computed for each mini-batch data, but the model parameters are not updated immediately. Instead, the obtained gradients are accumulated first, and then after the number (N) of mini-batches is specified, the accumulated gradient is used to update the network parameters. Before the next training, the accumulated gradients are cleared and re-accumulated. - -The ultimate objective is to achieve the same effect as training with N x mini-batch data. - -> This tutorial is applicable to GPUs and Ascend 910 AI Processors. You can download the main training sample code from . - -## Creating a Gradient Accumulation Model - -The MNIST dataset is used as an example to describe how to customize a simple model to implement gradient accumulation. - -### Importing Library Files -The following are the required public modules and MindSpore modules and library files. - -```python -import argparse -import os -from collections.abc import Iterable - -import mindspore.nn as nn -from mindspore import ParameterTuple -from mindspore import context -from mindspore.nn import Cell -from mindspore.ops import composite as C -from mindspore.ops import functional as F -from mindspore.ops import operations as P -from mindspore.train.dataset_helper import DatasetHelper -from mindspore.train.serialization import save_checkpoint -from model_zoo.official.cv.lenet.src.dataset import create_dataset -from model_zoo.official.cv.lenet.src.lenet import LeNet5 -``` - -### Loading the Dataset - -Use the `MnistDataset` API provided by the dataset of MindSpore to load the MNIST dataset. The code is imported from [dataset.py]() in the lenet directory of model_zoo. - -### Defining the Network - -The following uses the LeNet network as an example. You can also use other networks, such as ResNet-50 and BERT. The code is imported from [lenet.py]() in the lenet directory of model_zoo. - -### Defining the Training Model -The training process is divided into three parts: forward and backward training, parameter update, and accumulated gradient clearance. -- `TrainForwardBackward` calculates the loss and gradient, and uses grad_sum to implement gradient accumulation. -- `TrainOptim` updates parameters. -- `TrainClear` clears the gradient accumulation variable grad_sum. - -```python -_sum_op = C.MultitypeFuncGraph("grad_sum_op") -_clear_op = C.MultitypeFuncGraph("clear_op") - - -@_sum_op.register("Tensor", "Tensor") -def _cumulative_gard(grad_sum, grad): - """Apply gard sum to cumulative gradient.""" - add = P.AssignAdd() - return add(grad_sum, grad) - - -@_clear_op.register("Tensor", "Tensor") -def _clear_grad_sum(grad_sum, zero): - """Apply zero to clear grad_sum.""" - success = True - success = F.depend(success, F.assign(grad_sum, zero)) - return success - - -class TrainForwardBackward(Cell): - def __init__(self, network, optimizer, grad_sum, sens=1.0): - super(TrainForwardBackward, self).__init__(auto_prefix=False) - self.network = network - self.network.set_grad() - self.network.add_flags(defer_inline=True) - self.weights = ParameterTuple(network.trainable_params()) - self.optimizer = optimizer - self.grad_sum = grad_sum - self.grad = C.GradOperation(get_by_list=True, sens_param=True) - self.sens = sens - self.hyper_map = C.HyperMap() - - def construct(self, *inputs): - weights = self.weights - loss = self.network(*inputs) - sens = P.Fill()(P.DType()(loss), P.Shape()(loss), self.sens) - grads = self.grad(self.network, weights)(*inputs, sens) - return F.depend(loss, self.hyper_map(F.partial(_sum_op), self.grad_sum, grads)) - - -class TrainOptim(Cell): - def __init__(self, optimizer, grad_sum): - super(TrainOptim, self).__init__(auto_prefix=False) - self.optimizer = optimizer - self.grad_sum = grad_sum - - def construct(self): - return self.optimizer(self.grad_sum) - - -class TrainClear(Cell): - def __init__(self, grad_sum, zeros): - super(TrainClear, self).__init__(auto_prefix=False) - self.grad_sum = grad_sum - self.zeros = zeros - self.hyper_map = C.HyperMap() - - def construct(self): - seccess = self.hyper_map(F.partial(_clear_op), self.grad_sum, self.zeros) - return seccess -``` - -### Defining the Training Process -Each mini-batch calculates the loss and gradient through forward and backward training, and uses mini_steps to control the accumulated times before each parameter update. After the number of accumulation times is reached, the parameter is updated and the accumulated gradient variable is cleared. - - -```python -class GradientAccumulation: - def __init__(self, network, loss_fn, optimizer): - self._network = network - self._loss_fn = loss_fn - self._optimizer = optimizer - - params = self._optimizer.parameters - self._grad_sum = params.clone(prefix="grad_sum", init='zeros') - self._zeros = params.clone(prefix="zeros", init='zeros') - self._train_forward_backward = self._build_train_forward_backward_network() - self._train_optim = self._build_train_optim() - self._train_clear = self._build_train_clear() - - @staticmethod - def _transform_callbacks(callbacks): - """Transform callback to a list.""" - if callbacks is None: - return [] - - if isinstance(callbacks, Iterable): - return list(callbacks) - - return [callbacks] - - def _build_train_forward_backward_network(self): - """Build forward and backward network""" - network = self._network - network = nn.WithLossCell(network, self._loss_fn) - loss_scale = 1.0 - network = TrainForwardBackward(network, self._optimizer, self._grad_sum, loss_scale).set_train() - return network - - def _build_train_optim(self): - """Build optimizer network""" - network = TrainOptim(self._optimizer, self._grad_sum).set_train() - return network - - def _build_train_clear(self): - """Build clear network""" - network = TrainClear(self._grad_sum, self._zeros).set_train() - return network - - def train_process(self, epoch, train_dataset, mini_steps=None): - """ - Training process. The data would be passed to network directly. - """ - dataset_helper = DatasetHelper(train_dataset, dataset_sink_mode=False, epoch_num=epoch) - - for i in range(epoch): - step = 0 - for k, next_element in enumerate(dataset_helper): - loss = self._train_forward_backward(*next_element) - if (k + 1) % mini_steps == 0: - step += 1 - print("epoch:", i + 1, "step:", step, "loss is ", loss) - self._train_optim() - self._train_clear() - - train_dataset.reset() - - save_checkpoint(self._train_forward_backward, "gradient_accumulation.ckpt", ) -``` - -### Training and Saving the Model -Call the network, optimizer, and loss function, and then customize the `train_process` API of `GradientAccumulation` to train the model. - -```python -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='MindSpore Gard Cumulative Example') - parser.add_argument('--device_target', type=str, default="Ascend", choices=['Ascend', 'GPU'], - help='device where the code will be implemented (default: Ascend)') - parser.add_argument('--data_path', type=str, default="./Data", - help='path where the dataset is saved') - args = parser.parse_args() - - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target) - ds_train = create_dataset(os.path.join(args.data_path, "train"), 32) - - network = LeNet5(10) - net_loss = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction="mean") - net_opt = nn.Momentum(network.trainable_params(), 0.01, 0.9) - model = GradientAccumulation(network, net_loss, net_opt) - - print("============== Starting Training ==============") - model.train_process(10, ds_train, mini_steps=4) -``` - -## Experiment Result -After 10 epochs, the accuracy on the test set is about 96.31%. - -**Training Execution** -1. Run the training code and view the running result. - ```shell - $ python train.py --data_path=./MNIST_Data - ``` - The output is as follows. The loss value decreases during training. - - ```shell - epoch: 1 step: 27 loss is 0.3660637 - epoch: 1 step: 28 loss is 0.25238192 - ... - epoch: 3 step: 2 loss is 0.12296932 - epoch: 3 step: 3 loss is 0.15799297 - ... - epoch: 10 step: 448 loss is 0.06443884 - epoch: 10 step: 449 loss is 0.0067842817 - ``` - -2. Check the saved checkpoint files. - - The model file `gradient_accumulation.ckpt` is saved during training. - -**Model Validation** - -Use the saved checkpoint file to load the validation dataset through [eval.py]() in the lenet directory of model_zoo. - -```shell -$ python eval.py --data_path=./MNIST_Data --ckpt_path=./gradient_accumulation.ckpt -``` - -The output is as follows. The accuracy of the validation dataset is about 96.31%, which is the same as the result when the value of batch_size is 32. - -```shell -============== Starting Testing ============== -============== {'Accuracy': 0.9631730769230769} ============== +# Gradient Accumulation + +`Linux` `Ascend` `GPU` `Model Optimization` `Intermediate` `Expert` + + + +- [Gradient Accumulation](#gradient-accumulation) + - [Overview](#overview) + - [Creating a Gradient Accumulation Model](#creating-a-gradient-accumulation-model) + - [Importing Library Files](#importing-library-files) + - [Loading the Dataset](#loading-the-dataset) + - [Defining the Network](#defining-the-network) + - [Defining the Training Model](#defining-the-training-model) + - [Defining the Training Process](#defining-the-training-process) + - [Training and Saving the Model](#training-and-saving-the-model) + - [Experiment Result](#experiment-result) + + + + + +## Overview + +This tutorial describes the gradient accumulation training method to solve the problem that some large-scale networks cannot train large batch_size due to insufficient memory. + +In a traditional training method, after a loss and a gradient are calculated, a parameter is directly updated by using the obtained gradient. + +Different from the traditional training method, the concept of mini-batch is introduced to the gradient accumulation. The loss and gradient are computed for each mini-batch data, but the model parameters are not updated immediately. Instead, the obtained gradients are accumulated first, and then after the number (N) of mini-batches is specified, the accumulated gradient is used to update the network parameters. Before the next training, the accumulated gradients are cleared and re-accumulated. + +The ultimate objective is to achieve the same effect as training with N x mini-batch data. + +> This tutorial is applicable to GPUs and Ascend 910 AI Processors. You can download the main training sample code from . + +## Creating a Gradient Accumulation Model + +The MNIST dataset is used as an example to describe how to customize a simple model to implement gradient accumulation. + +### Importing Library Files +The following are the required public modules and MindSpore modules and library files. + +```python +import argparse +import os +from collections.abc import Iterable + +import mindspore.nn as nn +from mindspore import ParameterTuple +from mindspore import context +from mindspore.nn import Cell +from mindspore.ops import composite as C +from mindspore.ops import functional as F +from mindspore.ops import operations as P +from mindspore.train.dataset_helper import DatasetHelper +from mindspore.train.serialization import save_checkpoint +from model_zoo.official.cv.lenet.src.dataset import create_dataset +from model_zoo.official.cv.lenet.src.lenet import LeNet5 +``` + +### Loading the Dataset + +Use the `MnistDataset` API provided by the dataset of MindSpore to load the MNIST dataset. The code is imported from [dataset.py]() in the lenet directory of model_zoo. + +### Defining the Network + +The following uses the LeNet network as an example. You can also use other networks, such as ResNet-50 and BERT. The code is imported from [lenet.py]() in the lenet directory of model_zoo. + +### Defining the Training Model +The training process is divided into three parts: forward and backward training, parameter update, and accumulated gradient clearance. +- `TrainForwardBackward` calculates the loss and gradient, and uses grad_sum to implement gradient accumulation. +- `TrainOptim` updates parameters. +- `TrainClear` clears the gradient accumulation variable grad_sum. + +```python +_sum_op = C.MultitypeFuncGraph("grad_sum_op") +_clear_op = C.MultitypeFuncGraph("clear_op") + + +@_sum_op.register("Tensor", "Tensor") +def _cumulative_gard(grad_sum, grad): + """Apply gard sum to cumulative gradient.""" + add = P.AssignAdd() + return add(grad_sum, grad) + + +@_clear_op.register("Tensor", "Tensor") +def _clear_grad_sum(grad_sum, zero): + """Apply zero to clear grad_sum.""" + success = True + success = F.depend(success, F.assign(grad_sum, zero)) + return success + + +class TrainForwardBackward(Cell): + def __init__(self, network, optimizer, grad_sum, sens=1.0): + super(TrainForwardBackward, self).__init__(auto_prefix=False) + self.network = network + self.network.set_grad() + self.network.add_flags(defer_inline=True) + self.weights = ParameterTuple(network.trainable_params()) + self.optimizer = optimizer + self.grad_sum = grad_sum + self.grad = C.GradOperation(get_by_list=True, sens_param=True) + self.sens = sens + self.hyper_map = C.HyperMap() + + def construct(self, *inputs): + weights = self.weights + loss = self.network(*inputs) + sens = P.Fill()(P.DType()(loss), P.Shape()(loss), self.sens) + grads = self.grad(self.network, weights)(*inputs, sens) + return F.depend(loss, self.hyper_map(F.partial(_sum_op), self.grad_sum, grads)) + + +class TrainOptim(Cell): + def __init__(self, optimizer, grad_sum): + super(TrainOptim, self).__init__(auto_prefix=False) + self.optimizer = optimizer + self.grad_sum = grad_sum + + def construct(self): + return self.optimizer(self.grad_sum) + + +class TrainClear(Cell): + def __init__(self, grad_sum, zeros): + super(TrainClear, self).__init__(auto_prefix=False) + self.grad_sum = grad_sum + self.zeros = zeros + self.hyper_map = C.HyperMap() + + def construct(self): + seccess = self.hyper_map(F.partial(_clear_op), self.grad_sum, self.zeros) + return seccess +``` + +### Defining the Training Process +Each mini-batch calculates the loss and gradient through forward and backward training, and uses mini_steps to control the accumulated times before each parameter update. After the number of accumulation times is reached, the parameter is updated and the accumulated gradient variable is cleared. + + +```python +class GradientAccumulation: + def __init__(self, network, loss_fn, optimizer): + self._network = network + self._loss_fn = loss_fn + self._optimizer = optimizer + + params = self._optimizer.parameters + self._grad_sum = params.clone(prefix="grad_sum", init='zeros') + self._zeros = params.clone(prefix="zeros", init='zeros') + self._train_forward_backward = self._build_train_forward_backward_network() + self._train_optim = self._build_train_optim() + self._train_clear = self._build_train_clear() + + @staticmethod + def _transform_callbacks(callbacks): + """Transform callback to a list.""" + if callbacks is None: + return [] + + if isinstance(callbacks, Iterable): + return list(callbacks) + + return [callbacks] + + def _build_train_forward_backward_network(self): + """Build forward and backward network""" + network = self._network + network = nn.WithLossCell(network, self._loss_fn) + loss_scale = 1.0 + network = TrainForwardBackward(network, self._optimizer, self._grad_sum, loss_scale).set_train() + return network + + def _build_train_optim(self): + """Build optimizer network""" + network = TrainOptim(self._optimizer, self._grad_sum).set_train() + return network + + def _build_train_clear(self): + """Build clear network""" + network = TrainClear(self._grad_sum, self._zeros).set_train() + return network + + def train_process(self, epoch, train_dataset, mini_steps=None): + """ + Training process. The data would be passed to network directly. + """ + dataset_helper = DatasetHelper(train_dataset, dataset_sink_mode=False, epoch_num=epoch) + + for i in range(epoch): + step = 0 + for k, next_element in enumerate(dataset_helper): + loss = self._train_forward_backward(*next_element) + if (k + 1) % mini_steps == 0: + step += 1 + print("epoch:", i + 1, "step:", step, "loss is ", loss) + self._train_optim() + self._train_clear() + + train_dataset.reset() + + save_checkpoint(self._train_forward_backward, "gradient_accumulation.ckpt", ) +``` + +### Training and Saving the Model +Call the network, optimizer, and loss function, and then customize the `train_process` API of `GradientAccumulation` to train the model. + +```python +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='MindSpore Gard Cumulative Example') + parser.add_argument('--device_target', type=str, default="Ascend", choices=['Ascend', 'GPU'], + help='device where the code will be implemented (default: Ascend)') + parser.add_argument('--data_path', type=str, default="./Data", + help='path where the dataset is saved') + args = parser.parse_args() + + context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target) + ds_train = create_dataset(os.path.join(args.data_path, "train"), 32) + + network = LeNet5(10) + net_loss = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction="mean") + net_opt = nn.Momentum(network.trainable_params(), 0.01, 0.9) + model = GradientAccumulation(network, net_loss, net_opt) + + print("============== Starting Training ==============") + model.train_process(10, ds_train, mini_steps=4) +``` + +## Experiment Result +After 10 epochs, the accuracy on the test set is about 96.31%. + +**Training Execution** +1. Run the training code and view the running result. + ```shell + $ python train.py --data_path=./MNIST_Data + ``` + The output is as follows. The loss value decreases during training. + + ```shell + epoch: 1 step: 27 loss is 0.3660637 + epoch: 1 step: 28 loss is 0.25238192 + ... + epoch: 3 step: 2 loss is 0.12296932 + epoch: 3 step: 3 loss is 0.15799297 + ... + epoch: 10 step: 448 loss is 0.06443884 + epoch: 10 step: 449 loss is 0.0067842817 + ``` + +2. Check the saved checkpoint files. + + The model file `gradient_accumulation.ckpt` is saved during training. + +**Model Validation** + +Use the saved checkpoint file to load the validation dataset through [eval.py]() in the lenet directory of model_zoo. + +```shell +$ python eval.py --data_path=./MNIST_Data --ckpt_path=./gradient_accumulation.ckpt +``` + +The output is as follows. The accuracy of the validation dataset is about 96.31%, which is the same as the result when the value of batch_size is 32. + +```shell +============== Starting Testing ============== +============== {'Accuracy': 0.9631730769230769} ============== ``` \ No newline at end of file diff --git a/tutorials/source_en/advanced_use/graph_kernel_fusion.md b/tutorials/training/source_en/advanced_use/graph_kernel_fusion.md similarity index 100% rename from tutorials/source_en/advanced_use/graph_kernel_fusion.md rename to tutorials/training/source_en/advanced_use/graph_kernel_fusion.md diff --git a/tutorials/source_en/advanced_use/host_device_training.md b/tutorials/training/source_en/advanced_use/host_device_training.md similarity index 100% rename from tutorials/source_en/advanced_use/host_device_training.md rename to tutorials/training/source_en/advanced_use/host_device_training.md diff --git a/tutorials/source_en/advanced_use/hub_tutorial.md b/tutorials/training/source_en/advanced_use/hub_tutorial.md similarity index 97% rename from tutorials/source_en/advanced_use/hub_tutorial.md rename to tutorials/training/source_en/advanced_use/hub_tutorial.md index 13e98abd3f..a47f655f0d 100644 --- a/tutorials/source_en/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_en/advanced_use/hub_tutorial.md @@ -1,181 +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) - ``` - +## 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_en/advanced_use/images/adv_attack_result.png b/tutorials/training/source_en/advanced_use/images/adv_attack_result.png similarity index 100% rename from tutorials/source_en/advanced_use/images/adv_attack_result.png rename to tutorials/training/source_en/advanced_use/images/adv_attack_result.png diff --git a/tutorials/source_en/advanced_use/images/checkpoint_integration_process.jpg b/tutorials/training/source_en/advanced_use/images/checkpoint_integration_process.jpg similarity index 100% rename from tutorials/source_en/advanced_use/images/checkpoint_integration_process.jpg rename to tutorials/training/source_en/advanced_use/images/checkpoint_integration_process.jpg diff --git a/tutorials/source_en/advanced_use/images/cifar10.jpg b/tutorials/training/source_en/advanced_use/images/cifar10.jpg similarity index 100% rename from tutorials/source_en/advanced_use/images/cifar10.jpg rename to tutorials/training/source_en/advanced_use/images/cifar10.jpg diff --git a/tutorials/source_en/advanced_use/images/data_chart.png b/tutorials/training/source_en/advanced_use/images/data_chart.png similarity index 100% rename from tutorials/source_en/advanced_use/images/data_chart.png rename to tutorials/training/source_en/advanced_use/images/data_chart.png diff --git a/tutorials/source_en/advanced_use/images/data_function.png b/tutorials/training/source_en/advanced_use/images/data_function.png similarity index 100% rename from tutorials/source_en/advanced_use/images/data_function.png rename to tutorials/training/source_en/advanced_use/images/data_function.png diff --git a/tutorials/source_en/advanced_use/images/data_label.png b/tutorials/training/source_en/advanced_use/images/data_label.png similarity index 100% rename from tutorials/source_en/advanced_use/images/data_label.png rename to tutorials/training/source_en/advanced_use/images/data_label.png diff --git a/tutorials/source_en/advanced_use/images/data_op_profile.png b/tutorials/training/source_en/advanced_use/images/data_op_profile.png similarity index 100% rename from tutorials/source_en/advanced_use/images/data_op_profile.png rename to tutorials/training/source_en/advanced_use/images/data_op_profile.png diff --git a/tutorials/source_en/advanced_use/images/data_table.png b/tutorials/training/source_en/advanced_use/images/data_table.png similarity index 100% rename from tutorials/source_en/advanced_use/images/data_table.png rename to tutorials/training/source_en/advanced_use/images/data_table.png diff --git a/tutorials/source_en/advanced_use/images/gpu_activity_profiler.png b/tutorials/training/source_en/advanced_use/images/gpu_activity_profiler.png similarity index 100% rename from tutorials/source_en/advanced_use/images/gpu_activity_profiler.png rename to tutorials/training/source_en/advanced_use/images/gpu_activity_profiler.png diff --git a/tutorials/source_en/advanced_use/images/gpu_op_ui_profiler.png b/tutorials/training/source_en/advanced_use/images/gpu_op_ui_profiler.png similarity index 100% rename from tutorials/source_en/advanced_use/images/gpu_op_ui_profiler.png rename to tutorials/training/source_en/advanced_use/images/gpu_op_ui_profiler.png diff --git a/tutorials/source_en/advanced_use/images/graph.png b/tutorials/training/source_en/advanced_use/images/graph.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph.png rename to tutorials/training/source_en/advanced_use/images/graph.png diff --git a/tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png b/tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png rename to tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png diff --git a/tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png b/tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png rename to tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png diff --git a/tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png b/tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png rename to tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png diff --git a/tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png b/tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png rename to tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png diff --git a/tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png b/tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png rename to tutorials/training/source_en/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png diff --git a/tutorials/source_en/advanced_use/images/graph_sidebar.png b/tutorials/training/source_en/advanced_use/images/graph_sidebar.png similarity index 100% rename from tutorials/source_en/advanced_use/images/graph_sidebar.png rename to tutorials/training/source_en/advanced_use/images/graph_sidebar.png diff --git a/tutorials/source_en/advanced_use/images/histogram.png b/tutorials/training/source_en/advanced_use/images/histogram.png similarity index 100% rename from tutorials/source_en/advanced_use/images/histogram.png rename to tutorials/training/source_en/advanced_use/images/histogram.png diff --git a/tutorials/source_en/advanced_use/images/histogram_func.png b/tutorials/training/source_en/advanced_use/images/histogram_func.png similarity index 100% rename from tutorials/source_en/advanced_use/images/histogram_func.png rename to tutorials/training/source_en/advanced_use/images/histogram_func.png diff --git a/tutorials/source_en/advanced_use/images/image_function.png b/tutorials/training/source_en/advanced_use/images/image_function.png similarity index 100% rename from tutorials/source_en/advanced_use/images/image_function.png rename to tutorials/training/source_en/advanced_use/images/image_function.png diff --git a/tutorials/source_en/advanced_use/images/image_vi.png b/tutorials/training/source_en/advanced_use/images/image_vi.png similarity index 100% rename from tutorials/source_en/advanced_use/images/image_vi.png rename to tutorials/training/source_en/advanced_use/images/image_vi.png diff --git a/tutorials/source_en/advanced_use/images/lineage_label.png b/tutorials/training/source_en/advanced_use/images/lineage_label.png similarity index 100% rename from tutorials/source_en/advanced_use/images/lineage_label.png rename to tutorials/training/source_en/advanced_use/images/lineage_label.png diff --git a/tutorials/source_en/advanced_use/images/lineage_model_chart.png b/tutorials/training/source_en/advanced_use/images/lineage_model_chart.png similarity index 100% rename from tutorials/source_en/advanced_use/images/lineage_model_chart.png rename to tutorials/training/source_en/advanced_use/images/lineage_model_chart.png diff --git a/tutorials/source_en/advanced_use/images/lineage_model_table.png b/tutorials/training/source_en/advanced_use/images/lineage_model_table.png similarity index 100% rename from tutorials/source_en/advanced_use/images/lineage_model_table.png rename to tutorials/training/source_en/advanced_use/images/lineage_model_table.png diff --git a/tutorials/source_en/advanced_use/images/minddata_profile.png b/tutorials/training/source_en/advanced_use/images/minddata_profile.png similarity index 100% rename from tutorials/source_en/advanced_use/images/minddata_profile.png rename to tutorials/training/source_en/advanced_use/images/minddata_profile.png diff --git a/tutorials/source_en/advanced_use/images/mix_precision.eddx b/tutorials/training/source_en/advanced_use/images/mix_precision.eddx similarity index 100% rename from tutorials/source_en/advanced_use/images/mix_precision.eddx rename to tutorials/training/source_en/advanced_use/images/mix_precision.eddx diff --git a/tutorials/source_en/advanced_use/images/mix_precision.jpg b/tutorials/training/source_en/advanced_use/images/mix_precision.jpg similarity index 100% rename from tutorials/source_en/advanced_use/images/mix_precision.jpg rename to tutorials/training/source_en/advanced_use/images/mix_precision.jpg diff --git a/tutorials/source_en/advanced_use/images/multi_scalars.png b/tutorials/training/source_en/advanced_use/images/multi_scalars.png similarity index 100% rename from tutorials/source_en/advanced_use/images/multi_scalars.png rename to tutorials/training/source_en/advanced_use/images/multi_scalars.png diff --git a/tutorials/source_en/advanced_use/images/multi_scalars_select.png b/tutorials/training/source_en/advanced_use/images/multi_scalars_select.png similarity index 100% rename from tutorials/source_en/advanced_use/images/multi_scalars_select.png rename to tutorials/training/source_en/advanced_use/images/multi_scalars_select.png diff --git a/tutorials/source_en/advanced_use/images/op_statistics.PNG b/tutorials/training/source_en/advanced_use/images/op_statistics.PNG similarity index 100% rename from tutorials/source_en/advanced_use/images/op_statistics.PNG rename to tutorials/training/source_en/advanced_use/images/op_statistics.PNG diff --git a/tutorials/source_en/advanced_use/images/op_type_statistics.PNG b/tutorials/training/source_en/advanced_use/images/op_type_statistics.PNG similarity index 100% rename from tutorials/source_en/advanced_use/images/op_type_statistics.PNG rename to tutorials/training/source_en/advanced_use/images/op_type_statistics.PNG diff --git a/tutorials/source_en/advanced_use/images/performance_overall.png b/tutorials/training/source_en/advanced_use/images/performance_overall.png similarity index 100% rename from tutorials/source_en/advanced_use/images/performance_overall.png rename to tutorials/training/source_en/advanced_use/images/performance_overall.png diff --git a/tutorials/source_en/advanced_use/images/scalar.png b/tutorials/training/source_en/advanced_use/images/scalar.png similarity index 100% rename from tutorials/source_en/advanced_use/images/scalar.png rename to tutorials/training/source_en/advanced_use/images/scalar.png diff --git a/tutorials/source_en/advanced_use/images/scalar_compound.png b/tutorials/training/source_en/advanced_use/images/scalar_compound.png similarity index 100% rename from tutorials/source_en/advanced_use/images/scalar_compound.png rename to tutorials/training/source_en/advanced_use/images/scalar_compound.png diff --git a/tutorials/source_en/advanced_use/images/scalar_select.png b/tutorials/training/source_en/advanced_use/images/scalar_select.png similarity index 100% rename from tutorials/source_en/advanced_use/images/scalar_select.png rename to tutorials/training/source_en/advanced_use/images/scalar_select.png diff --git a/tutorials/source_en/advanced_use/images/step_trace.png b/tutorials/training/source_en/advanced_use/images/step_trace.png similarity index 100% rename from tutorials/source_en/advanced_use/images/step_trace.png rename to tutorials/training/source_en/advanced_use/images/step_trace.png diff --git a/tutorials/source_en/advanced_use/images/synchronization_training_and_evaluation.png b/tutorials/training/source_en/advanced_use/images/synchronization_training_and_evaluation.png similarity index 100% rename from tutorials/source_en/advanced_use/images/synchronization_training_and_evaluation.png rename to tutorials/training/source_en/advanced_use/images/synchronization_training_and_evaluation.png diff --git a/tutorials/source_en/advanced_use/images/targets.png b/tutorials/training/source_en/advanced_use/images/targets.png similarity index 100% rename from tutorials/source_en/advanced_use/images/targets.png rename to tutorials/training/source_en/advanced_use/images/targets.png diff --git a/tutorials/source_en/advanced_use/images/tensor_function.png b/tutorials/training/source_en/advanced_use/images/tensor_function.png similarity index 100% rename from tutorials/source_en/advanced_use/images/tensor_function.png rename to tutorials/training/source_en/advanced_use/images/tensor_function.png diff --git a/tutorials/source_en/advanced_use/images/tensor_histogram.png b/tutorials/training/source_en/advanced_use/images/tensor_histogram.png similarity index 100% rename from tutorials/source_en/advanced_use/images/tensor_histogram.png rename to tutorials/training/source_en/advanced_use/images/tensor_histogram.png diff --git a/tutorials/source_en/advanced_use/images/tensor_table.png b/tutorials/training/source_en/advanced_use/images/tensor_table.png similarity index 100% rename from tutorials/source_en/advanced_use/images/tensor_table.png rename to tutorials/training/source_en/advanced_use/images/tensor_table.png diff --git a/tutorials/source_en/advanced_use/images/timeline.png b/tutorials/training/source_en/advanced_use/images/timeline.png similarity index 100% rename from tutorials/source_en/advanced_use/images/timeline.png rename to tutorials/training/source_en/advanced_use/images/timeline.png diff --git a/tutorials/source_en/advanced_use/lineage_and_scalars_comparision.md b/tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md similarity index 98% rename from tutorials/source_en/advanced_use/lineage_and_scalars_comparision.md rename to tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md index b120a5f0ff..6823b61801 100644 --- a/tutorials/source_en/advanced_use/lineage_and_scalars_comparision.md +++ b/tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md @@ -1,110 +1,110 @@ -# Lineage and Scalars Comparision - -`Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` - - - -- [Lineage and Scalars Comparision](#lineage-and-scalars-comparision) - - [Overview](#overview) - - [Model Lineage](#model-lineage) - - [Dataset Lineage](#dataset-lineage) - - [Scalars Comparision](#scalars-comparision) - - [Notices](#notices) - - - - - -## Overview - -Model lineage, data lineage and comparison Kanban in mindinsight are the same as training dashboard. In the visualization of training data, different scalar trend charts are observed by comparison dashboard to find problems, and then the lineage function is used to locate the problem causes, so as to give users the ability of efficient tuning in data enhancement and deep neural network. - -## Model Lineage - -Model lineage visualization is used to display the parameter information of all training models. - -![image.png](./images/lineage_label.png) - -Figure 1: Model parameter selection area - -Figure 1 shows the model parameter selection area, which lists the model parameter tags that can be viewed. You can select required tags to view the corresponding model parameters. - -![image.png](./images/lineage_model_chart.png) - -Figure 2: Model lineage function area - -Figure 2 shows the model lineage function area, which visualizes the model parameter information. You can select a specific area in the column to display the model information within the area. - -![image.png](./images/lineage_model_table.png) - -Figure 3: Model list - -Figure 3 shows all model information in groups. You can sort the model information in ascending or descending order by specified column. - -The overview page on the left shows information about optimization objective and related parameters. - -![targets.png](./images/targets.png) - -Figure 4: Overview page - -Figure 4 shows the optimization objective distribution, parameter importance, and scatter plots. - -## Dataset Lineage - -Dataset lineage visualization is used to display data processing and augmentation information of all model trainings. - -![data_label.png](./images/data_label.png) - -Figure 5: Data processing and augmentation operator selection area - -Figure 5 shows the data processing and augmentation operator selection area, which lists names of data processing and augmentation operators that can be viewed. You can select required tags to view related parameters. - -![data_chart.png](./images/data_chart.png) - -Figure 6: Dataset lineage function area - -Figure 6 shows the dataset lineage function area, which visualizes the parameter information used for data processing and augmentation. You can select a specific area in the column to display the parameter information within the area. - -![data_table.png](./images/data_table.png) - -Figure 7: Dataset lineage list - -Figure 7 shows the data processing and augmentation information of all model trainings. - -> If user filters the model lineage and then switches to the data lineage page, the line chart will show the latest filtered column in model lineage. - -## Scalars Comparision - -Scalars Comparision can be used to compare scalar curves between multiple trainings - -![multi_scalars.png](./images/multi_scalars.png) - -Figure 8: Scalars comparision curve area - -Figure 8 shows the scalar curve comparision between multiple trainings. The horizontal coordinate indicates the training step, and the vertical coordinate indicates the scalar value. - -Buttons from left to right in the upper right corner of the figure are used to display the chart in full screen, switch the Y-axis scale, enable or disable the rectangle selection, roll back the chart step by step, and restore the chart. - -- Full-screen Display: Display the scalar curve in full screen. Click the button again to restore it. -- Switch Y-axis Scale: Perform logarithmic conversion on the Y-axis coordinate. -- Enable/Disable Rectangle Selection: Draw a rectangle to select and zoom in a part of the chart. You can perform rectangle selection again on the zoomed-in chart. -- Step-by-step Rollback: Cancel operations step by step after continuously drawing rectangles to select and zooming in the same area. -- Restore Chart: Restore a chart to the original state. - -![multi_scalars_select.png](./images/multi_scalars_select.png) - -Figure 9: Scalars comparision function area - -Figure 9 shows the scalars comparision function area, which allows you to view scalar information by selecting different trainings or tags, different dimensions of the horizontal axis, and smoothness. - -- Training: Select or filter the required trainings to view the corresponding scalar information. -- Tag: Select the required tags to view the corresponding scalar information. -- Horizontal Axis: Select any of Step, Relative Time, and Absolute Time as the horizontal axis of the scalar curve. -- Smoothness: Adjust the smoothness to smooth the scalar curve. - -## Notices - -To ensure performance, MindInsight implements scalars comparision with the cache mechanism and the following restrictions: -- The scalars comparision supports only for trainings in cache. -- The maximum of 15 latest trainings (sorted by modification time) can be retained in the cache. +# Lineage and Scalars Comparision + +`Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` + + + +- [Lineage and Scalars Comparision](#lineage-and-scalars-comparision) + - [Overview](#overview) + - [Model Lineage](#model-lineage) + - [Dataset Lineage](#dataset-lineage) + - [Scalars Comparision](#scalars-comparision) + - [Notices](#notices) + + + + + +## Overview + +Model lineage, data lineage and comparison Kanban in mindinsight are the same as training dashboard. In the visualization of training data, different scalar trend charts are observed by comparison dashboard to find problems, and then the lineage function is used to locate the problem causes, so as to give users the ability of efficient tuning in data enhancement and deep neural network. + +## Model Lineage + +Model lineage visualization is used to display the parameter information of all training models. + +![image.png](./images/lineage_label.png) + +Figure 1: Model parameter selection area + +Figure 1 shows the model parameter selection area, which lists the model parameter tags that can be viewed. You can select required tags to view the corresponding model parameters. + +![image.png](./images/lineage_model_chart.png) + +Figure 2: Model lineage function area + +Figure 2 shows the model lineage function area, which visualizes the model parameter information. You can select a specific area in the column to display the model information within the area. + +![image.png](./images/lineage_model_table.png) + +Figure 3: Model list + +Figure 3 shows all model information in groups. You can sort the model information in ascending or descending order by specified column. + +The overview page on the left shows information about optimization objective and related parameters. + +![targets.png](./images/targets.png) + +Figure 4: Overview page + +Figure 4 shows the optimization objective distribution, parameter importance, and scatter plots. + +## Dataset Lineage + +Dataset lineage visualization is used to display data processing and augmentation information of all model trainings. + +![data_label.png](./images/data_label.png) + +Figure 5: Data processing and augmentation operator selection area + +Figure 5 shows the data processing and augmentation operator selection area, which lists names of data processing and augmentation operators that can be viewed. You can select required tags to view related parameters. + +![data_chart.png](./images/data_chart.png) + +Figure 6: Dataset lineage function area + +Figure 6 shows the dataset lineage function area, which visualizes the parameter information used for data processing and augmentation. You can select a specific area in the column to display the parameter information within the area. + +![data_table.png](./images/data_table.png) + +Figure 7: Dataset lineage list + +Figure 7 shows the data processing and augmentation information of all model trainings. + +> If user filters the model lineage and then switches to the data lineage page, the line chart will show the latest filtered column in model lineage. + +## Scalars Comparision + +Scalars Comparision can be used to compare scalar curves between multiple trainings + +![multi_scalars.png](./images/multi_scalars.png) + +Figure 8: Scalars comparision curve area + +Figure 8 shows the scalar curve comparision between multiple trainings. The horizontal coordinate indicates the training step, and the vertical coordinate indicates the scalar value. + +Buttons from left to right in the upper right corner of the figure are used to display the chart in full screen, switch the Y-axis scale, enable or disable the rectangle selection, roll back the chart step by step, and restore the chart. + +- Full-screen Display: Display the scalar curve in full screen. Click the button again to restore it. +- Switch Y-axis Scale: Perform logarithmic conversion on the Y-axis coordinate. +- Enable/Disable Rectangle Selection: Draw a rectangle to select and zoom in a part of the chart. You can perform rectangle selection again on the zoomed-in chart. +- Step-by-step Rollback: Cancel operations step by step after continuously drawing rectangles to select and zooming in the same area. +- Restore Chart: Restore a chart to the original state. + +![multi_scalars_select.png](./images/multi_scalars_select.png) + +Figure 9: Scalars comparision function area + +Figure 9 shows the scalars comparision function area, which allows you to view scalar information by selecting different trainings or tags, different dimensions of the horizontal axis, and smoothness. + +- Training: Select or filter the required trainings to view the corresponding scalar information. +- Tag: Select the required tags to view the corresponding scalar information. +- Horizontal Axis: Select any of Step, Relative Time, and Absolute Time as the horizontal axis of the scalar curve. +- Smoothness: Adjust the smoothness to smooth the scalar curve. + +## Notices + +To ensure performance, MindInsight implements scalars comparision with the cache mechanism and the following restrictions: +- The scalars comparision supports only for trainings in cache. +- The maximum of 15 latest trainings (sorted by modification time) can be retained in the cache. - The maximum of 5 trainings can be selected for scalars comparision at the same time. \ No newline at end of file diff --git a/tutorials/source_en/advanced_use/mindinsight_commands.md b/tutorials/training/source_en/advanced_use/mindinsight_commands.md similarity index 100% rename from tutorials/source_en/advanced_use/mindinsight_commands.md rename to tutorials/training/source_en/advanced_use/mindinsight_commands.md diff --git a/tutorials/source_en/advanced_use/mixed_precision.md b/tutorials/training/source_en/advanced_use/mixed_precision.md similarity index 100% rename from tutorials/source_en/advanced_use/mixed_precision.md rename to tutorials/training/source_en/advanced_use/mixed_precision.md diff --git a/tutorials/source_en/advanced_use/model_security.md b/tutorials/training/source_en/advanced_use/model_security.md similarity index 100% rename from tutorials/source_en/advanced_use/model_security.md rename to tutorials/training/source_en/advanced_use/model_security.md diff --git a/tutorials/source_en/advanced_use/network_migration.md b/tutorials/training/source_en/advanced_use/network_migration.md similarity index 100% rename from tutorials/source_en/advanced_use/network_migration.md rename to tutorials/training/source_en/advanced_use/network_migration.md diff --git a/tutorials/source_en/advanced_use/nlp_application.md b/tutorials/training/source_en/advanced_use/nlp_application.md similarity index 100% rename from tutorials/source_en/advanced_use/nlp_application.md rename to tutorials/training/source_en/advanced_use/nlp_application.md diff --git a/tutorials/source_en/advanced_use/parameter_server_training.md b/tutorials/training/source_en/advanced_use/parameter_server_training.md similarity index 100% rename from tutorials/source_en/advanced_use/parameter_server_training.md rename to tutorials/training/source_en/advanced_use/parameter_server_training.md diff --git a/tutorials/source_en/advanced_use/performance_profiling.md b/tutorials/training/source_en/advanced_use/performance_profiling.md similarity index 100% rename from tutorials/source_en/advanced_use/performance_profiling.md rename to tutorials/training/source_en/advanced_use/performance_profiling.md diff --git a/tutorials/source_en/advanced_use/performance_profiling_gpu.md b/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md similarity index 97% rename from tutorials/source_en/advanced_use/performance_profiling_gpu.md rename to tutorials/training/source_en/advanced_use/performance_profiling_gpu.md index d3327f4f1a..7a5745fd62 100644 --- a/tutorials/source_en/advanced_use/performance_profiling_gpu.md +++ b/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md @@ -1,120 +1,120 @@ -# Performance Profiler(GPU) - -`Linux` `GPU` `Model Optimization` `Intermediate` `Expert` - - - -- [Performance Profiler(GPU)](#performance-profiler-gpu) - - [Overview](#overview) - - [Operation Process](#operation-process) - - [Preparing the Training Script](#preparing-the-training-script) - - [Launch MindInsight](#launch-mindinsight) - - [Performance Analysis](#performance-analysis) - - [Operator Performance Analysis](#operator-performance-analysis) - - [Timeline Analysis](#timeline-analysis) - - - - - -## Overview -Performance data like operators' execution time is recorded in files and can be viewed on the web page, this can help the user optimize the performance of neural networks. - -## Operation Process - -> The GPU operation process is the same as that in Ascend chip. -> -> - -## Preparing the Training Script - -To enable the performance profiling of neural networks, MindSpore Profiler APIs should be added into the script.Only the output_path in parameters is worked in GPU now. Then, at the end of the training, `Profiler.analyse()` should be called to finish profiling and generate the perforamnce analyse results. - -> The sample code is the same as that in Ascend chip: -> -> - -Users can get profiling data by user-defined callback: - -```python -class StopAtStep(Callback): - def __init__(self, start_step, stop_step): - super(StopAtStep, self).__init__() - self.start_step = start_step - self.stop_step = stop_step - self.already_analysed = False - - def step_begin(self, run_context): - cb_params = run_context.original_args() - step_num = cb_params.cur_step_num - if step_num == self.start_step: - self.profiler = Profiler() - - def step_end(self, run_context): - cb_params = run_context.original_args() - step_num = cb_params.cur_step_num - if step_num == self.stop_step and not self.already_analysed: - self.profiler.analyse() - self.already_analysed = True - - def end(self, run_context): - if not self.already_analysed: - self.profiler.analyse() -``` - -The code above is just a example. Users should implement callback by themselves. - -## Launch MindInsight - -The MindInsight launch command can refer to [MindInsight Commands](https://www.mindspore.cn/tutorial/en/master/advanced_use/mindinsight_commands.html). - - -### Performance Analysis - -Users can access the Performance Profiler by selecting a specific training from the training list, and click the performance profiling link. And the Performance Profiler only support operation analysis and Timeline Analysis now, the others modules will publish soon. - -![performance_overall.png](./images/performance_overall.png) - -Figure 1:Overall Performance - -Figure 1 displays the overall performance of the training, including the overall data of Step Trace, Operator Performance, MindData Performance and Timeline. Operator Performance Analysis is supportted only: -- Operator Performance: It will collect the average execution time of operators and operator types. The overall performance page will show the pie graph for different operator types. - -Users can click the detail link to see the details of each components. - -#### Operator Performance Analysis - -The operator performance analysis component is used to display the execution time of the operators during MindSpore run. - -![gpu_op_ui_profiler.png](./images/gpu_op_ui_profiler.png) - -Figure 2: Statistics for Operator Types - -Figure 2 displays the statistics for the operator types, including: - -- Choose pie or bar graph to show the proportion time occupied by each operator type. The time of one operator type is calculated by accumulating the execution time of operators belong to this type. -- Display top 20 operator types with longest average execution time, show the proportion of total time and average execution time (ms) of each operator type. - -The bottom half of Figure 2 displays the statistics table for the operators' details, including: - -- Choose All: Display statistics for the operators, including operator position information, type, execution time, full scope time etc. The table will be sorted by average execution time by default. -- Choose Type: Display statistics for the operator types, including operator type name, execution time, execution frequency and proportion of total time, average execution time. Users can click on each line, querying for all the operators belong to this type. -- Search: There is a search box on the right, which can support fuzzy search for operators/operator types. - -![gpu_activity_profiler.png](./images/gpu_activity_profiler.png) - -Figure 3: Statistics for Kernel Activities - -Figure 3 displays the statistics for the Kernel, including: - -- Pie graph to show the proportion time occupied by each kernel activity. And the top 15 kernel activities with longest exection time. -- The statistical table's column include activity name, operation name, execution frequency, total time, average time. -- The search box on the right, which can support fuzzy search for activity name/operator full name. - -#### Timeline Analysis - -The usage is almost same as that in Ascend. The difference is GPU Timeline displays the operation information and CUDA activity. - -> The usage is follow as: -> +# Performance Profiler(GPU) + +`Linux` `GPU` `Model Optimization` `Intermediate` `Expert` + + + +- [Performance Profiler(GPU)](#performance-profiler-gpu) + - [Overview](#overview) + - [Operation Process](#operation-process) + - [Preparing the Training Script](#preparing-the-training-script) + - [Launch MindInsight](#launch-mindinsight) + - [Performance Analysis](#performance-analysis) + - [Operator Performance Analysis](#operator-performance-analysis) + - [Timeline Analysis](#timeline-analysis) + + + + + +## Overview +Performance data like operators' execution time is recorded in files and can be viewed on the web page, this can help the user optimize the performance of neural networks. + +## Operation Process + +> The GPU operation process is the same as that in Ascend chip. +> +> + +## Preparing the Training Script + +To enable the performance profiling of neural networks, MindSpore Profiler APIs should be added into the script.Only the output_path in parameters is worked in GPU now. Then, at the end of the training, `Profiler.analyse()` should be called to finish profiling and generate the perforamnce analyse results. + +> The sample code is the same as that in Ascend chip: +> +> + +Users can get profiling data by user-defined callback: + +```python +class StopAtStep(Callback): + def __init__(self, start_step, stop_step): + super(StopAtStep, self).__init__() + self.start_step = start_step + self.stop_step = stop_step + self.already_analysed = False + + def step_begin(self, run_context): + cb_params = run_context.original_args() + step_num = cb_params.cur_step_num + if step_num == self.start_step: + self.profiler = Profiler() + + def step_end(self, run_context): + cb_params = run_context.original_args() + step_num = cb_params.cur_step_num + if step_num == self.stop_step and not self.already_analysed: + self.profiler.analyse() + self.already_analysed = True + + def end(self, run_context): + if not self.already_analysed: + self.profiler.analyse() +``` + +The code above is just a example. Users should implement callback by themselves. + +## Launch MindInsight + +The MindInsight launch command can refer to [MindInsight Commands](https://www.mindspore.cn/tutorial/en/master/advanced_use/mindinsight_commands.html). + + +### Performance Analysis + +Users can access the Performance Profiler by selecting a specific training from the training list, and click the performance profiling link. And the Performance Profiler only support operation analysis and Timeline Analysis now, the others modules will publish soon. + +![performance_overall.png](./images/performance_overall.png) + +Figure 1:Overall Performance + +Figure 1 displays the overall performance of the training, including the overall data of Step Trace, Operator Performance, MindData Performance and Timeline. Operator Performance Analysis is supportted only: +- Operator Performance: It will collect the average execution time of operators and operator types. The overall performance page will show the pie graph for different operator types. + +Users can click the detail link to see the details of each components. + +#### Operator Performance Analysis + +The operator performance analysis component is used to display the execution time of the operators during MindSpore run. + +![gpu_op_ui_profiler.png](./images/gpu_op_ui_profiler.png) + +Figure 2: Statistics for Operator Types + +Figure 2 displays the statistics for the operator types, including: + +- Choose pie or bar graph to show the proportion time occupied by each operator type. The time of one operator type is calculated by accumulating the execution time of operators belong to this type. +- Display top 20 operator types with longest average execution time, show the proportion of total time and average execution time (ms) of each operator type. + +The bottom half of Figure 2 displays the statistics table for the operators' details, including: + +- Choose All: Display statistics for the operators, including operator position information, type, execution time, full scope time etc. The table will be sorted by average execution time by default. +- Choose Type: Display statistics for the operator types, including operator type name, execution time, execution frequency and proportion of total time, average execution time. Users can click on each line, querying for all the operators belong to this type. +- Search: There is a search box on the right, which can support fuzzy search for operators/operator types. + +![gpu_activity_profiler.png](./images/gpu_activity_profiler.png) + +Figure 3: Statistics for Kernel Activities + +Figure 3 displays the statistics for the Kernel, including: + +- Pie graph to show the proportion time occupied by each kernel activity. And the top 15 kernel activities with longest exection time. +- The statistical table's column include activity name, operation name, execution frequency, total time, average time. +- The search box on the right, which can support fuzzy search for activity name/operator full name. + +#### Timeline Analysis + +The usage is almost same as that in Ascend. The difference is GPU Timeline displays the operation information and CUDA activity. + +> The usage is follow as: +> > \ No newline at end of file diff --git a/tutorials/source_en/advanced_use/quantization_aware.md b/tutorials/training/source_en/advanced_use/quantization_aware.md similarity index 100% rename from tutorials/source_en/advanced_use/quantization_aware.md rename to tutorials/training/source_en/advanced_use/quantization_aware.md diff --git a/tutorials/source_en/advanced_use/serving.md b/tutorials/training/source_en/advanced_use/serving.md similarity index 100% rename from tutorials/source_en/advanced_use/serving.md rename to tutorials/training/source_en/advanced_use/serving.md diff --git a/tutorials/source_en/advanced_use/summary_record.md b/tutorials/training/source_en/advanced_use/summary_record.md similarity index 100% rename from tutorials/source_en/advanced_use/summary_record.md rename to tutorials/training/source_en/advanced_use/summary_record.md diff --git a/tutorials/source_en/advanced_use/synchronization_training_and_evaluation.md b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md similarity index 100% rename from tutorials/source_en/advanced_use/synchronization_training_and_evaluation.md rename to tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md diff --git a/tutorials/source_en/advanced_use/visualization_tutorials.rst b/tutorials/training/source_en/advanced_use/visualization_tutorials.rst similarity index 95% rename from tutorials/source_en/advanced_use/visualization_tutorials.rst rename to tutorials/training/source_en/advanced_use/visualization_tutorials.rst index 17b1532bba..e0a749ab35 100644 --- a/tutorials/source_en/advanced_use/visualization_tutorials.rst +++ b/tutorials/training/source_en/advanced_use/visualization_tutorials.rst @@ -1,12 +1,12 @@ -Training Process Visualization -============================== - -.. toctree:: - :maxdepth: 1 - - summary_record - dashboard - lineage_and_scalars_comparision - performance_profiling - performance_profiling_gpu - mindinsight_commands +Training Process Visualization +============================== + +.. toctree:: + :maxdepth: 1 + + summary_record + dashboard + lineage_and_scalars_comparision + performance_profiling + performance_profiling_gpu + mindinsight_commands diff --git a/tutorials/source_en/conf.py b/tutorials/training/source_en/conf.py similarity index 100% rename from tutorials/source_en/conf.py rename to tutorials/training/source_en/conf.py diff --git a/tutorials/source_en/index.rst b/tutorials/training/source_en/index.rst similarity index 100% rename from tutorials/source_en/index.rst rename to tutorials/training/source_en/index.rst diff --git a/tutorials/source_en/quick_start/images/LeNet_5.jpg b/tutorials/training/source_en/quick_start/images/LeNet_5.jpg similarity index 100% rename from tutorials/source_en/quick_start/images/LeNet_5.jpg rename to tutorials/training/source_en/quick_start/images/LeNet_5.jpg diff --git a/tutorials/source_en/quick_start/quick_start.md b/tutorials/training/source_en/quick_start/quick_start.md similarity index 100% rename from tutorials/source_en/quick_start/quick_start.md rename to tutorials/training/source_en/quick_start/quick_start.md diff --git a/tutorials/source_en/quick_start/quick_video.md b/tutorials/training/source_en/quick_start/quick_video.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video.md rename to tutorials/training/source_en/quick_start/quick_video.md diff --git a/tutorials/source_en/quick_start/quick_video/ascend910.md b/tutorials/training/source_en/quick_start/quick_video/ascend910.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/ascend910.md rename to tutorials/training/source_en/quick_start/quick_video/ascend910.md diff --git a/tutorials/source_en/quick_start/quick_video/community.md b/tutorials/training/source_en/quick_start/quick_video/community.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/community.md rename to tutorials/training/source_en/quick_start/quick_video/community.md diff --git a/tutorials/source_en/quick_start/quick_video/cpu_operator_development.md b/tutorials/training/source_en/quick_start/quick_video/cpu_operator_development.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/cpu_operator_development.md rename to tutorials/training/source_en/quick_start/quick_video/cpu_operator_development.md diff --git a/tutorials/source_en/quick_start/quick_video/cpu_ubuntu.md b/tutorials/training/source_en/quick_start/quick_video/cpu_ubuntu.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/cpu_ubuntu.md rename to tutorials/training/source_en/quick_start/quick_video/cpu_ubuntu.md diff --git a/tutorials/source_en/quick_start/quick_video/cpu_windows.md b/tutorials/training/source_en/quick_start/quick_video/cpu_windows.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/cpu_windows.md rename to tutorials/training/source_en/quick_start/quick_video/cpu_windows.md diff --git a/tutorials/source_en/quick_start/quick_video/customized_debugging.md b/tutorials/training/source_en/quick_start/quick_video/customized_debugging.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/customized_debugging.md rename to tutorials/training/source_en/quick_start/quick_video/customized_debugging.md diff --git a/tutorials/source_en/quick_start/quick_video/gpu.md b/tutorials/training/source_en/quick_start/quick_video/gpu.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/gpu.md rename to tutorials/training/source_en/quick_start/quick_video/gpu.md diff --git a/tutorials/source_en/quick_start/quick_video/gpu_operator_development.md b/tutorials/training/source_en/quick_start/quick_video/gpu_operator_development.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/gpu_operator_development.md rename to tutorials/training/source_en/quick_start/quick_video/gpu_operator_development.md diff --git a/tutorials/source_en/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md b/tutorials/training/source_en/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md rename to tutorials/training/source_en/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md diff --git a/tutorials/source_en/quick_start/quick_video/mindInsight_dashboard.md b/tutorials/training/source_en/quick_start/quick_video/mindInsight_dashboard.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/mindInsight_dashboard.md rename to tutorials/training/source_en/quick_start/quick_video/mindInsight_dashboard.md diff --git a/tutorials/source_en/quick_start/quick_video/mindInsight_installation_and_common_commands.md b/tutorials/training/source_en/quick_start/quick_video/mindInsight_installation_and_common_commands.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/mindInsight_installation_and_common_commands.md rename to tutorials/training/source_en/quick_start/quick_video/mindInsight_installation_and_common_commands.md diff --git a/tutorials/source_en/quick_start/quick_video/quick_start_video.md b/tutorials/training/source_en/quick_start/quick_video/quick_start_video.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/quick_start_video.md rename to tutorials/training/source_en/quick_start/quick_video/quick_start_video.md diff --git a/tutorials/source_en/quick_start/quick_video/saving_and_loading_model_parameters.md b/tutorials/training/source_en/quick_start/quick_video/saving_and_loading_model_parameters.md similarity index 100% rename from tutorials/source_en/quick_start/quick_video/saving_and_loading_model_parameters.md rename to tutorials/training/source_en/quick_start/quick_video/saving_and_loading_model_parameters.md diff --git a/tutorials/source_en/use/custom_operator.md b/tutorials/training/source_en/use/custom_operator.md similarity index 100% rename from tutorials/source_en/use/custom_operator.md rename to tutorials/training/source_en/use/custom_operator.md diff --git a/tutorials/source_en/use/data_preparation/converting_datasets.md b/tutorials/training/source_en/use/data_preparation/converting_datasets.md similarity index 100% rename from tutorials/source_en/use/data_preparation/converting_datasets.md rename to tutorials/training/source_en/use/data_preparation/converting_datasets.md diff --git a/tutorials/source_en/use/data_preparation/data_preparation.rst b/tutorials/training/source_en/use/data_preparation/data_preparation.rst similarity index 100% rename from tutorials/source_en/use/data_preparation/data_preparation.rst rename to tutorials/training/source_en/use/data_preparation/data_preparation.rst diff --git a/tutorials/source_en/use/data_preparation/data_processing_and_augmentation.md b/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md similarity index 100% rename from tutorials/source_en/use/data_preparation/data_processing_and_augmentation.md rename to tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md diff --git a/tutorials/source_en/use/data_preparation/loading_the_datasets.md b/tutorials/training/source_en/use/data_preparation/loading_the_datasets.md similarity index 100% rename from tutorials/source_en/use/data_preparation/loading_the_datasets.md rename to tutorials/training/source_en/use/data_preparation/loading_the_datasets.md diff --git a/tutorials/source_en/use/defining_the_network.rst b/tutorials/training/source_en/use/defining_the_network.rst similarity index 100% rename from tutorials/source_en/use/defining_the_network.rst rename to tutorials/training/source_en/use/defining_the_network.rst diff --git a/tutorials/source_en/use/images/batch.png b/tutorials/training/source_en/use/images/batch.png similarity index 100% rename from tutorials/source_en/use/images/batch.png rename to tutorials/training/source_en/use/images/batch.png diff --git a/tutorials/source_en/use/images/dataset_pipeline.eddx b/tutorials/training/source_en/use/images/dataset_pipeline.eddx similarity index 100% rename from tutorials/source_en/use/images/dataset_pipeline.eddx rename to tutorials/training/source_en/use/images/dataset_pipeline.eddx diff --git a/tutorials/source_en/use/images/dataset_pipeline.png b/tutorials/training/source_en/use/images/dataset_pipeline.png similarity index 100% rename from tutorials/source_en/use/images/dataset_pipeline.png rename to tutorials/training/source_en/use/images/dataset_pipeline.png diff --git a/tutorials/source_en/use/images/image.png b/tutorials/training/source_en/use/images/image.png similarity index 100% rename from tutorials/source_en/use/images/image.png rename to tutorials/training/source_en/use/images/image.png diff --git a/tutorials/source_en/use/images/image_random_crop.png b/tutorials/training/source_en/use/images/image_random_crop.png similarity index 100% rename from tutorials/source_en/use/images/image_random_crop.png rename to tutorials/training/source_en/use/images/image_random_crop.png diff --git a/tutorials/source_en/use/images/image_resized.png b/tutorials/training/source_en/use/images/image_resized.png similarity index 100% rename from tutorials/source_en/use/images/image_resized.png rename to tutorials/training/source_en/use/images/image_resized.png diff --git a/tutorials/source_en/use/images/map.eddx b/tutorials/training/source_en/use/images/map.eddx similarity index 100% rename from tutorials/source_en/use/images/map.eddx rename to tutorials/training/source_en/use/images/map.eddx diff --git a/tutorials/source_en/use/images/map.png b/tutorials/training/source_en/use/images/map.png similarity index 100% rename from tutorials/source_en/use/images/map.png rename to tutorials/training/source_en/use/images/map.png diff --git a/tutorials/source_en/use/images/repeat.png b/tutorials/training/source_en/use/images/repeat.png similarity index 100% rename from tutorials/source_en/use/images/repeat.png rename to tutorials/training/source_en/use/images/repeat.png diff --git a/tutorials/source_en/use/images/shuffle.png b/tutorials/training/source_en/use/images/shuffle.png similarity index 100% rename from tutorials/source_en/use/images/shuffle.png rename to tutorials/training/source_en/use/images/shuffle.png diff --git a/tutorials/source_en/use/images/zip.png b/tutorials/training/source_en/use/images/zip.png similarity index 100% rename from tutorials/source_en/use/images/zip.png rename to tutorials/training/source_en/use/images/zip.png diff --git a/tutorials/source_en/use/multi_platform_inference.md b/tutorials/training/source_en/use/multi_platform_inference.md similarity index 100% rename from tutorials/source_en/use/multi_platform_inference.md rename to tutorials/training/source_en/use/multi_platform_inference.md diff --git a/tutorials/source_en/use/saving_and_loading_model_parameters.md b/tutorials/training/source_en/use/saving_and_loading_model_parameters.md similarity index 100% rename from tutorials/source_en/use/saving_and_loading_model_parameters.md rename to tutorials/training/source_en/use/saving_and_loading_model_parameters.md diff --git a/tutorials/source_zh_cn/_static/logo_notebook.png b/tutorials/training/source_zh_cn/_static/logo_notebook.png similarity index 100% rename from tutorials/source_zh_cn/_static/logo_notebook.png rename to tutorials/training/source_zh_cn/_static/logo_notebook.png diff --git a/tutorials/source_zh_cn/_static/logo_source.png b/tutorials/training/source_zh_cn/_static/logo_source.png similarity index 100% rename from tutorials/source_zh_cn/_static/logo_source.png rename to tutorials/training/source_zh_cn/_static/logo_source.png diff --git a/tutorials/source_zh_cn/advanced_use/auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/auto_augmentation.md rename to tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md diff --git a/tutorials/source_zh_cn/advanced_use/auto_data_acceleration.rst b/tutorials/training/source_zh_cn/advanced_use/auto_data_acceleration.rst similarity index 100% rename from tutorials/source_zh_cn/advanced_use/auto_data_acceleration.rst rename to tutorials/training/source_zh_cn/advanced_use/auto_data_acceleration.rst diff --git a/tutorials/source_zh_cn/advanced_use/bert_poetry.md b/tutorials/training/source_zh_cn/advanced_use/bert_poetry.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/bert_poetry.md rename to tutorials/training/source_zh_cn/advanced_use/bert_poetry.md diff --git a/tutorials/source_zh_cn/advanced_use/cache.md b/tutorials/training/source_zh_cn/advanced_use/cache.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/cache.md rename to tutorials/training/source_zh_cn/advanced_use/cache.md diff --git a/tutorials/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md b/tutorials/training/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md rename to tutorials/training/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md index 36f8ef9995..394ac2947c 100644 --- a/tutorials/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md +++ b/tutorials/training/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md @@ -1,552 +1,552 @@ - - -# 手动设置并行场景模型参数的保存和加载 - -`Linux` `Ascend` `GPU` `模型训练` `中级` `高级` - - - -- [手动设置并行场景模型参数的保存和加载](#手动设置并行场景模型参数的保存和加载) - - [概述](#概述) - - [背景](#背景) - - [使用场景](#使用场景) - - [对保存的CheckPoint文件做合并处理](#对保存的checkpoint文件做合并处理) - - [整体流程](#整体流程) - - [准备工作](#准备工作) - - [按逻辑顺序导入CheckPoint文件](#按逻辑顺序导入checkpoint文件) - - [获取模型参数切分策略](#获取模型参数切分策略) - - [对模型并行的参数做合并处理](#对模型并行的参数做合并处理) - - [保存数据生成新的CheckPoint文件](#保存数据生成新的checkpoint文件) - - [加载合并保存的CheckPoint文件](#加载合并保存的checkpoint文件) - - [整体流程](#整体流程-1) - - [步骤1:加载CheckPoint文件](#步骤1加载checkpoint文件) - - [步骤2:对模型并行参数做切分处理](#步骤2对模型并行参数做切分处理) - - [步骤3:将修改后的参数数据加载到网络中](#步骤3将修改后的参数数据加载到网络中) - - [示例](#示例) - - [示例场景说明](#示例场景说明) - - [示例代码](#示例代码) - - - - - -## 概述 - -### 背景 - -MindSpore模型并行场景下,每个实例进程只保存有本节点对应的参数数据。对于模型并行的Cell,其在每个节点上的参数数据,都是完整参数数据的一个切片。比如完整参数数据shape为[8, 8],每个节点上的参数数据为其中的一部分,如shape[2, 8]。 - -对于自动切分的模型并行场景(Auto Parallel),切分逻辑由MindSpore自动生成,MindSpore的CheckPoint模块可以支持自动合并保存和基于合并保存的加载能力。 - -对于用户手动设置的并行场景(HyBrid Parallel),切分逻辑由用户自己实现,MindSpore在每个节点上保存相同的模型参数切分策略文件和本节点上的数据,用户需要自己实现CheckPoint文件的合并保存与加载功能。本教程用于指导用户在手动切分场景下,实现CheckPoint的合并保存与加载能力。 - -### 使用场景 - -如果你遇到如下两个场景,需要参考本教程操作,完成CheckPoint的合并保存与加载: - -场景1:多卡训练,单卡推理。 - - 以在64卡上训练,并在单卡上推理为例,整体操作流程如下: - -1. 执行训练,自动生成CheckPoint文件和模型参数切分策略文件。 - -2. 用户对保存的CheckPoint文件做合并处理。 - - 根据具体的切分逻辑,对于存在切分的具体模型参数做合并处理,生成新CheckPoint文件。 - -3. 在单卡环境加载新的CheckPoint文件,之后再根据需要调用export接口导出用于推理的模型。 - -若CheckPoint的保存环境和加载环境集群的卡数相同,比如在同一训练环境保存加载CheckPoint,或者单卡训练单卡推理,则可以不需要做合并保存和加载。 - -场景2:训练分为多阶段,每个阶段的集群大小不一样。 - -​ 以训练阶段一是64卡训练环境,阶段二是56卡训练环境为例,整体操作流程如下: - -1. 执行阶段一训练,自动生成CheckPoint文件和模型参数切分策略文件。 - -2. 用户对保存的CheckPoint文件做合并处理。 - - 根据具体的切分逻辑,对于存在切分的具体模型参数做合并处理,生成新CheckPoint文件。 - -3. 在阶段二集群上加载合并保存的CheckPoint文件。 - - 在加载过程中,用户需要根据新的训练环境配置,重新切分CheckPoint文件中的参数数据。 - -4. 执行阶段二训练。 - - - - -## 对保存的CheckPoint文件做合并处理 - -### 整体流程 - -首先,执行准备工作,按逻辑顺序将待合并处理的CheckPoint文件导入网络,获取模型全量参数并添加至列表中,再获取模型参数切分策略。对应下图中的Step1和Step2。 - -其次,更新参数列表,对涉及模型并行的参数做合并处理。对应下图中的Step3。 - -最后,将更新之后的参数列表,通过MindSpore提供的API保存到文件,生成新的CheckPoint文件。对应下图中的Step4。 - -![img](./images/checkpoint_integration_process.jpg) - -### 准备工作 - -#### 按逻辑顺序导入CheckPoint文件 - -定义网络,调用`load_checkpoint`、`load_param_into_net`接口,按逻辑顺序将CheckPoint文件导入网络,之后调用`parameters_and_names`接口获取网络里所有的参数数据。 -``` -net = Net() -opt = Momentum(learning_rate=0.01, momentum=0.9, params=net.get_parameters()) -net = TrainOneStepCell(net, opt) -param_dicts = [] -for i in range(rank_size): - file_name = os.path.join("./node"+str(i), "CKP_1-4_32.ckpt") # checkpoint file name of current node - param_dict = load_checkpoint(file_name) - load_param_into_net(net, param_dict) - param_dict = {} - for _, param in net.parameters_and_names(): - param_dict[param.name] = param - param_dicts.append(param_dict) -``` - -其中, - -- `rank_size`:之前分布式训练的节点数。 -- `load_checkpoint`:通过该接口加载CheckPoint模型参数文件,返回一个参数字典。 -- `load_param_into_net`:模型参数数据加载到网络中。 - -#### 获取模型参数切分策略 - -调用`build_searched_strategy`接口,得到模型各个参数的切分策略。 -``` -strategy = build_searched_strategy("./strategy_train.cpkt") -``` - -其中, - -- `strategy_train.ckpt`:保存的模型参数切分策略文件名称,训练网络之前由用户调用`set_auto_parallel_context`接口自定义`strategy_ckpt_save_file`参数生成。 - -### 对模型并行的参数做合并处理 - -下面以一个具体的模型参数为例,说明下参数合并处理的具体流程。 - -参数名称为"model_parallel_weight",切分逻辑为4卡场景。 - -1. 针对涉及模型并行的参数,获取所有节点上的参数数据。 - - ``` - sliced_parameters = [] - for i in range(4): - parameter = param_dicts[i].get("model_parallel_weight") - sliced_parameters.append(parameter) - ``` - > 如果要保证参数更新速度不变,需要对优化器中保存的参数,如“moments.model_parallel_weight”,同样做合并处理。 - -2. 调用`merge_sliced_parameter`接口进行参数合并。 - - ``` - merged_parameter = merge_sliced_parameter(sliced_parameters, strategy) - ``` - -> 如果存在多个模型并行的参数,则需要重复步骤1到步骤2循环逐个处理。 - -### 保存数据生成新的CheckPoint文件 - -1. 将`param_dict`转换为list类型数据。 - - ``` - param_list = [] - for (key, value) in param_dict.items(): - each_param = {} - each_param["name"] = key - if isinstance(value.data, Tensor): - param_data = value.data - else: - param_data = Tensor(value.data) - each_param["data"] = param_data - param_list.append(each_param) - ``` - -2. 调用`save_checkpoint`接口,将参数数据写入文件,生成新的CheckPoint文件。 - ``` - save_checkpoint(param_list, “./CKP-Integrated_1-4_32.ckpt”) - ``` - 其中, - - `save_checkpoint`: 通过该接口将网络模型参数信息存入文件。 - - `CKP-Integrated_1-4_32.ckpt`: 新生成的CheckPoint模型参数文件名称。 - -## 加载合并保存的CheckPoint文件 - -### 整体流程 - -如果需要将合并保存的CheckPoint加载到多卡训练或推理中,在模型参数真正加载到网络前,需要对于涉及并行的参数数据按照新的逻辑切分。 -如下步骤在训练前脚本里实现,步骤1和3同单机CheckPoint加载的逻辑,步骤2为新增,用于涉及并行的模型参数的切分。 -对于加载到单卡训练/推理的场景,不涉及数据切分,则步骤2可省略。 - -### 步骤1:加载CheckPoint文件 - -调用`load_checkpoint`接口,从CheckPoint文件中加载模型参数数据。 - -``` -param_dict = load_checkpoint("./CKP-Integrated_1-4_32.ckpt") -``` - -- `load_checkpoint`:通过该接口加载CheckPoint模型参数文件,返回一个参数字典。 -- `CKP-Integrated_1-4_32.ckpt`:需要加载的CheckPoint模型参数文件名称。 - -### 步骤2:对模型并行参数做切分处理 - -下面以一个具体的模型参数为例,参数名称为“model_parallel_weight", 数据值为Tensor [[1, 2, 3, 4], [5, 6, 7, 8]],切分逻辑为2卡场景,按[2, 1]切分。 -切分后数据分布情况如下: - -| Device0 | Device1 | -| ------------------- | -------------------- | -| Value [1, 2, 3, 4] | Value [5, 6, 7, 8] | - -1. 对模型参数数据做切分。 - - 如下代码示例,在维度0上,将数据切分为两个切片。 - ``` - new_param = parameter_dict[“model_parallel_weight”] - slice_list = np.split(new_param.data.asnumpy(), 2, axis=0) - new_param_moments = parameter_dict[“moments.model_parallel_weight”] - slice_moments_list = np.split(new_param_moments.data.asnumpy(), 2, axis=0) - ``` - - 切分后的数据情况: - - slice_list[0] --- [1, 2, 3, 4] 对应device0 - slice_list[1] --- [5, 6, 7, 8] 对应device1 - - 与`slice_list`类似,`slice_moments_list` 也被切分为两个shape为[1, 4]的Tensor。 - -2. 在每个节点分别加载对应的数据切片。 - - 获取本节点的rank_id,根据rank_id加载数据。 - ``` - rank = get_rank() - tensor_slice = Tensor(slice_list[rank]) - tensor_slice_moments = Tensor(slice_moments_list[rank]) - ``` - - `get_rank`:获取当前设备在集群中的ID。 - -3. 修改模型参数数据值。 - - ``` - new_param.set_data(tensor_slice, True) - new_param_moments.set_data(tensor_slice_moments, True) - ``` - - - `set_data`:设置模型参数的值,接口参数类型为Tensor 或number。 - -### 步骤3:将修改后的参数数据加载到网络中 - -调用`load_param_into_net`接口,将模型参数数据加载到网络中。 -``` -net = Net() -opt = Momentum(learning_rate=0.01, momentum=0.9, params=parallel_net.get_parameters()) -load_param_into_net(net, param_dict) -load_param_into_net(opt, param_dict) -``` - -## 示例 - -### 示例场景说明 - -整体场景:训练分为两个阶段,两阶段的集群规模不一致,模拟FC层MatMul算子并行。 - -用户流程: - -1. 执行阶段1训练:阶段1为4卡训练环境,每卡上MatMul算子weight的shape为[2, 8],训练过程中自动导出CheckPoint。 - -2. 执行脚本对CheckPoint文件做合并处理,根据具体的切分逻辑,对于存在切分的具体模型参数做合并处理,生成合并的CheckPoint文件。 - -3. 执行阶段2训练:阶段2为2卡训练环境,每卡上MatMul算子weight的shape为[4, 8],从合并后的CheckPoint文件加载初始化模型参数数据,之后执行训练。 - -> 具体分布式环境配置和训练部分代码,此处不做详细说明,可以参考[分布式并行训练](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_ascend.html) -章节。 -> -> 本文档附上对CheckPoint文件做合并处理以及分布式训练前加载CheckPoint文件的示例代码,仅作为参考,实际请参考具体情况实现。 - -### 示例代码 - -1. 执行脚本对CheckPoint文件做合并处理。 - - 脚本执行命令: - ``` - python ./integrate_checkpoint.py "待合并的CheckPoint文件名称" "合并生成的CheckPoint文件路径&名称" "策略文件路径&名称" "节点数" - ``` - - integrate_checkpoint.py: - - ``` - import numpy as np - import os - import mindspore.nn as nn - from mindspore import Tensor, Parameter - from mindspore.ops import operations as P - from mindspore.train.serialization import save_checkpoint, load_checkpoint, build_searched_strategy, merge_sliced_parameter - - class Net(nn.Cell): - def __init__(self,weight_init): - super(Net, self).__init__() - self.weight = Parameter(Tensor(weight_init), "model_parallel_weight", layerwise_parallel=True) - self.fc = P.MatMul(transpose_b=True) - - def construct(self, x): - x = self.fc(x, self.weight1) - return x - - def integrate_ckpt_file(old_ckpt_file, new_ckpt_file, strategy_file, rank_size): - weight = np.ones([2, 8]).astype(np.float32) - net = Net(weight) - opt = Momentum(learning_rate=0.01, momentum=0.9, params=net.get_parameters()) - net = TrainOneStepCell(net, opt) - - # load CheckPoint into net in rank id order - param_dicts = [] - for i in range(rank_size): - file_name = os.path.join("./node"+str(i), old_ckpt_file) - param_dict = load_checkpoint(file_name) - load_param_into_net(net, param_dict) - param_dict = {} - for _, param in net.parameters_and_names(): - param_dict[param.name] = param - param_dicts.append(param_dict) - - strategy = build_searched_strategy(strategy_file) - param_dict = {} - - for paramname in ["model_parallel_weight", "moments.model_parallel_weight"]: - # get layer wise model parallel parameter - sliced_parameters = [] - for i in range(rank_size): - parameter = param_dicts[i].get(paramname) - sliced_parameters.append(parameter) - - # merge the parallel parameters of the model - merged_parameter = merge_sliced_parameter(sliced_parameters, strategy) - param_dict[paramname] = merged_parameter - - # convert param_dict to list type data - param_list = [] - for (key, value) in param_dict.items(): - each_param = {} - each_param["name"] = key - if isinstance(value.data, Tensor): - param_data = value.data - else: - param_data = Tensor(value.data) - each_param["data"] = param_data - param_list.append(each_param) - - # call the API to generate a new CheckPoint file - save_checkpoint(param_list, new_ckpt_file) - - return - - if __name__ == "__main__": - try: - old_ckpt_file = sys.argv[1] - new_ckpt_file = sys.argv[2] - strategy_file = sys.argv[3] - rank_size = int(sys.argv[4]) - integrate_ckpt_file(old_ckpt_file, new_ckpt_file, strategy_file, rank_size) - except: - print("Fail to integrate checkpoint file) - sys.exit(-1) - ``` - - 执行结果: - - 脚本执行前,CheckPoint文件中参数值: - ``` - device0: - name is model_parallel_weight - value is - [[0.87537426 1.0448935 0.86736983 0.8836905 0.77354026 0.69588304 0.9183654 0.7792076] - [0.87224025 0.8726848 0.771446 0.81967723 0.88974726 0.7988162 0.72919345 0.7677011]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_weight - value is - [[0.2567724 -0.07485991 0.282002 0.2456022 0.454939 0.619168 0.18964815 0.45714882] - [0.25946522 0.24344791 0.45677605 0.3611395 0.23378398 0.41439137 0.5312468 0.4696194]] - - device1: - name is model_parallel_weight - value is - [[0.9210751 0.9050457 0.9827775 0.920396 0.9240526 0.9750359 1.0275179 1.0819869] - [0.73605865 0.84631145 0.9746683 0.9386582 0.82902765 0.83565056 0.9702136 1.0514659]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_weight - value is - [[0.2417504 0.28193963 0.06713893 0.21510397 0.23380603 0.11424308 0.0218009 -0.11969765] - [0.45955992 0.22664294 0.01990281 0.0731914 0.27125207 0.27298513 -0.01716102 -0.15327111]] - - device2: - name is model_parallel_weight - value is - [[1.0108461 0.8689414 0.91719437 0.8805056 0.7994629 0.8999671 0.7585804 1.0287056 ] - [0.90653455 0.60146594 0.7206475 0.8306303 0.8364681 0.89625114 0.7354735 0.8447268]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_weight - value is - [[0.03440702 0.41419312 0.24817684 0.30765256 0.48516113 0.24904746 0.57791173 0.00955463] - [0.13458519 0.6690533 0.49259356 0.28319967 0.25951773 0.16777472 0.45696738 0.24933104]] - - device3: - name is model_parallel_weight - value is - [[0.7147005 0.9168278 0.80178416 0.6258351 0.8413766 0.5909515 0.696347 0.71359116] - [0.20506378 0.03691584 0.2454556 0.12978578 0.19065076 0.23904312 0.27509746 0.34614682]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_parallel_weight - value is - [[0.14152306 0.5040985 0.24455397 0.10907605 0.11319532 0.19538902 0.01208619 0.40430856] - [-0.7773164 -0.47611716 -0.6041424 -0.6144473 -0.2651842 -0.31909415 -0.4510405 -0.12860501]] - ``` - - 脚本执行后,CheckPoint文件中参数值: - - ``` - name is model_parallel_weight - value is - [[1.1138763 1.0962057 1.3516843 1.0812817 1.1579804 1.1078343 1.0906502 1.3207073] - [0.916671 1.0781671 1.0368758 0.9680898 1.1735439 1.0628364 0.9960786 1.0135143] - [0.8828271 0.7963984 0.90675324 0.9830291 0.89010954 0.897052 0.7890109 0.89784735] - [1.0011744 1.0840297 1.0201758 1.0882459 0.94232416 1.0775206 1.0195118 1.0528734] - [1.0053468 0.98402303 0.99762845 0.97587246 1.0259694 1.0055295 0.99420834 0.9496847] - [1.0851002 1.0295962 1.0999886 1.0958165 0.9765328 1.146529 1.0970603 1.1388365] - [0.7147005 0.9168278 0.80178416 0.6258351 0.8413766 0.5909515 0.696347 0.71359116] - [0.20506378 0.03691584 0.2454556 0.12978578 0.19065076 0.23904312 0.27509746 0.34614682]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_parallel_weight - value is - [[0.2567724 -0.07485991 0.282002 0.2456022 0.454939 0.619168 0.18964815 0.45714882] - [0.25946522 0.24344791 0.45677605 0.3611395 0.23378398 0.41439137 0.5312468 0.4696194 ] - [0.2417504 0.28193963 0.06713893 0.21510397 0.23380603 0.11424308 0.0218009 -0.11969765] - [0.45955992 0.22664294 0.01990281 0.0731914 0.27125207 0.27298513 -0.01716102 -0.15327111] - [0.03440702 0.41419312 0.24817684 0.30765256 0.48516113 0.24904746 0.57791173 0.00955463] - [0.13458519 0.6690533 0.49259356 0.28319967 0.25951773 0.16777472 0.45696738 0.24933104] - [0.14152306 0.5040985 0.24455397 0.10907605 0.11319532 0.19538902 0.01208619 0.40430856] - [-0.7773164 -0.47611716 -0.6041424 -0.6144473 -0.2651842 -0.31909415 -0.4510405 - -0.12860501]] - ``` - - -2. 执行阶段2训练,训练前加载CheckPoint文件。其中训练代码部分,需要根据实际情况补充。 - - ``` - import numpy as np - import os - import mindspore.nn as nn - from mindspore import context - from mindspore.communication.management import init - from mindspore import Tensor, Parameter - from mindspore.ops import operations as P - from mindspore.train.serialization import load_checkpoint, load_param_into_net - - from mindspore.communication.management import init - devid = int(os.getenv('DEVICE_ID')) - context.set_context(mode=context.GRAPH_MODE,device_target='Ascend',save_graphs=True, device_id=devid) - init() - - class Net(nn.Cell): - def __init__(self,weight_init): - super(Net, self).__init__() - self.weight = Parameter(Tensor(weight_init), "model_parallel_weight", layerwise_parallel=True) - self.fc = P.MatMul(transpose_b=True) - - def construct(self, x): - x = self.fc(x, self.weight1) - return x - def train_mindspore_impl_fc(input, label, ckpt_file): - param_dict = load_checkpoint(ckpt_file) - - for paramname in ["model_parallel_weight", "moments.model_parallel_weight"]: - # get layer wise model parallel parameter - new_param = parameter_dict[paramname] - # split the model parameter data - slice_list = np.split(new_param.data.asnumpy(), 2, axis=0) - # Load the corresponding data slice - rank = get_rank() - tensor_slice = Tensor(slice_list[rank]) - # modify model parameter data values - new_param.set_data(tensor_slice, True) - - # load the modified parameter data into the network - weight = np.ones([4, 8]).astype(np.float32) - net = Net(weight) - load_param_into_net(net, param_dict) - opt = Momentum(learning_rate=0.01, momentum=0.9, params=parallel_net.get_parameters()) - load_param_into_net(opt, param_dict) - # train code - ... - - if __name__ == "__main__": - input = np.random.random((4, 8)).astype(np.float32) - print("mean = ", np.mean(input,axis=1, keepdims=True)) - label = np.random.random((4, 4)).astype(np.float32) - train_mindspore_impl_fc(input, label, weight1) - ``` - - 其中, - - - `mode=context.GRAPH_MODE`:使用分布式训练需要指定运行模式为图模式(PyNative模式不支持并行)。 - - `device_id`:卡物理序号,即卡所在机器中的实际序号。 - - `init`:完成分布式训练初始化操作。 - - 加载后的参数值: - - ``` - device0: - name is model_parallel_weight - value is - [[0.87537426 1.0448935 0.86736983 0.8836905 0.77354026 0.69588304 0.9183654 0.7792076] - [0.87224025 0.8726848 0.771446 0.81967723 0.88974726 0.7988162 0.72919345 0.7677011] - [0.8828271 0.7963984 0.90675324 0.9830291 0.89010954 0.897052 0.7890109 0.89784735] - [1.0011744 1.0840297 1.0201758 1.0882459 0.94232416 1.0775206 1.0195118 1.0528734]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_weight - value is - [[0.2567724 -0.07485991 0.282002 0.2456022 0.454939 0.619168 0.18964815 0.45714882] - [0.25946522 0.24344791 0.45677605 0.3611395 0.23378398 0.41439137 0.5312468 0.4696194] - [0.2417504 0.28193963 0.06713893 0.21510397 0.23380603 0.11424308 0.0218009 -0.11969765] - [0.45955992 0.22664294 0.01990281 0.0731914 0.27125207 0.27298513 -0.01716102 -0.15327111]] - - device1: - name is model_parallel_weight - value is - [[1.0053468 0.98402303 0.99762845 0.97587246 1.0259694 1.0055295 0.99420834 0.9496847] - [1.0851002 1.0295962 1.0999886 1.0958165 0.9765328 1.146529 1.0970603 1.1388365] - [0.7147005 0.9168278 0.80178416 0.6258351 0.8413766 0.5909515 0.696347 0.71359116] - [0.20506378 0.03691584 0.2454556 0.12978578 0.19065076 0.23904312 0.27509746 0.34614682]] - name is learning_rate - value is [0.01] - name is momentum - value is [0.9] - name is moments.model_weight - value is - [[0.03440702 0.41419312 0.24817684 0.30765256 0.48516113 0.24904746 0.57791173 0.00955463] - [0.13458519 0.6690533 0.49259356 0.28319967 0.25951773 0.16777472 0.45696738 0.24933104] - [0.14152306 0.5040985 0.24455397 0.10907605 0.11319532 0.19538902 0.01208619 0.40430856] - [-0.7773164 -0.47611716 -0.6041424 -0.6144473 -0.2651842 -0.31909415 -0.4510405 -0.12860501]] - ``` + + +# 手动设置并行场景模型参数的保存和加载 + +`Linux` `Ascend` `GPU` `模型训练` `中级` `高级` + + + +- [手动设置并行场景模型参数的保存和加载](#手动设置并行场景模型参数的保存和加载) + - [概述](#概述) + - [背景](#背景) + - [使用场景](#使用场景) + - [对保存的CheckPoint文件做合并处理](#对保存的checkpoint文件做合并处理) + - [整体流程](#整体流程) + - [准备工作](#准备工作) + - [按逻辑顺序导入CheckPoint文件](#按逻辑顺序导入checkpoint文件) + - [获取模型参数切分策略](#获取模型参数切分策略) + - [对模型并行的参数做合并处理](#对模型并行的参数做合并处理) + - [保存数据生成新的CheckPoint文件](#保存数据生成新的checkpoint文件) + - [加载合并保存的CheckPoint文件](#加载合并保存的checkpoint文件) + - [整体流程](#整体流程-1) + - [步骤1:加载CheckPoint文件](#步骤1加载checkpoint文件) + - [步骤2:对模型并行参数做切分处理](#步骤2对模型并行参数做切分处理) + - [步骤3:将修改后的参数数据加载到网络中](#步骤3将修改后的参数数据加载到网络中) + - [示例](#示例) + - [示例场景说明](#示例场景说明) + - [示例代码](#示例代码) + + + + + +## 概述 + +### 背景 + +MindSpore模型并行场景下,每个实例进程只保存有本节点对应的参数数据。对于模型并行的Cell,其在每个节点上的参数数据,都是完整参数数据的一个切片。比如完整参数数据shape为[8, 8],每个节点上的参数数据为其中的一部分,如shape[2, 8]。 + +对于自动切分的模型并行场景(Auto Parallel),切分逻辑由MindSpore自动生成,MindSpore的CheckPoint模块可以支持自动合并保存和基于合并保存的加载能力。 + +对于用户手动设置的并行场景(HyBrid Parallel),切分逻辑由用户自己实现,MindSpore在每个节点上保存相同的模型参数切分策略文件和本节点上的数据,用户需要自己实现CheckPoint文件的合并保存与加载功能。本教程用于指导用户在手动切分场景下,实现CheckPoint的合并保存与加载能力。 + +### 使用场景 + +如果你遇到如下两个场景,需要参考本教程操作,完成CheckPoint的合并保存与加载: + +场景1:多卡训练,单卡推理。 + + 以在64卡上训练,并在单卡上推理为例,整体操作流程如下: + +1. 执行训练,自动生成CheckPoint文件和模型参数切分策略文件。 + +2. 用户对保存的CheckPoint文件做合并处理。 + + 根据具体的切分逻辑,对于存在切分的具体模型参数做合并处理,生成新CheckPoint文件。 + +3. 在单卡环境加载新的CheckPoint文件,之后再根据需要调用export接口导出用于推理的模型。 + +若CheckPoint的保存环境和加载环境集群的卡数相同,比如在同一训练环境保存加载CheckPoint,或者单卡训练单卡推理,则可以不需要做合并保存和加载。 + +场景2:训练分为多阶段,每个阶段的集群大小不一样。 + +​ 以训练阶段一是64卡训练环境,阶段二是56卡训练环境为例,整体操作流程如下: + +1. 执行阶段一训练,自动生成CheckPoint文件和模型参数切分策略文件。 + +2. 用户对保存的CheckPoint文件做合并处理。 + + 根据具体的切分逻辑,对于存在切分的具体模型参数做合并处理,生成新CheckPoint文件。 + +3. 在阶段二集群上加载合并保存的CheckPoint文件。 + + 在加载过程中,用户需要根据新的训练环境配置,重新切分CheckPoint文件中的参数数据。 + +4. 执行阶段二训练。 + + + + +## 对保存的CheckPoint文件做合并处理 + +### 整体流程 + +首先,执行准备工作,按逻辑顺序将待合并处理的CheckPoint文件导入网络,获取模型全量参数并添加至列表中,再获取模型参数切分策略。对应下图中的Step1和Step2。 + +其次,更新参数列表,对涉及模型并行的参数做合并处理。对应下图中的Step3。 + +最后,将更新之后的参数列表,通过MindSpore提供的API保存到文件,生成新的CheckPoint文件。对应下图中的Step4。 + +![img](./images/checkpoint_integration_process.jpg) + +### 准备工作 + +#### 按逻辑顺序导入CheckPoint文件 + +定义网络,调用`load_checkpoint`、`load_param_into_net`接口,按逻辑顺序将CheckPoint文件导入网络,之后调用`parameters_and_names`接口获取网络里所有的参数数据。 +``` +net = Net() +opt = Momentum(learning_rate=0.01, momentum=0.9, params=net.get_parameters()) +net = TrainOneStepCell(net, opt) +param_dicts = [] +for i in range(rank_size): + file_name = os.path.join("./node"+str(i), "CKP_1-4_32.ckpt") # checkpoint file name of current node + param_dict = load_checkpoint(file_name) + load_param_into_net(net, param_dict) + param_dict = {} + for _, param in net.parameters_and_names(): + param_dict[param.name] = param + param_dicts.append(param_dict) +``` + +其中, + +- `rank_size`:之前分布式训练的节点数。 +- `load_checkpoint`:通过该接口加载CheckPoint模型参数文件,返回一个参数字典。 +- `load_param_into_net`:模型参数数据加载到网络中。 + +#### 获取模型参数切分策略 + +调用`build_searched_strategy`接口,得到模型各个参数的切分策略。 +``` +strategy = build_searched_strategy("./strategy_train.cpkt") +``` + +其中, + +- `strategy_train.ckpt`:保存的模型参数切分策略文件名称,训练网络之前由用户调用`set_auto_parallel_context`接口自定义`strategy_ckpt_save_file`参数生成。 + +### 对模型并行的参数做合并处理 + +下面以一个具体的模型参数为例,说明下参数合并处理的具体流程。 + +参数名称为"model_parallel_weight",切分逻辑为4卡场景。 + +1. 针对涉及模型并行的参数,获取所有节点上的参数数据。 + + ``` + sliced_parameters = [] + for i in range(4): + parameter = param_dicts[i].get("model_parallel_weight") + sliced_parameters.append(parameter) + ``` + > 如果要保证参数更新速度不变,需要对优化器中保存的参数,如“moments.model_parallel_weight”,同样做合并处理。 + +2. 调用`merge_sliced_parameter`接口进行参数合并。 + + ``` + merged_parameter = merge_sliced_parameter(sliced_parameters, strategy) + ``` + +> 如果存在多个模型并行的参数,则需要重复步骤1到步骤2循环逐个处理。 + +### 保存数据生成新的CheckPoint文件 + +1. 将`param_dict`转换为list类型数据。 + + ``` + param_list = [] + for (key, value) in param_dict.items(): + each_param = {} + each_param["name"] = key + if isinstance(value.data, Tensor): + param_data = value.data + else: + param_data = Tensor(value.data) + each_param["data"] = param_data + param_list.append(each_param) + ``` + +2. 调用`save_checkpoint`接口,将参数数据写入文件,生成新的CheckPoint文件。 + ``` + save_checkpoint(param_list, “./CKP-Integrated_1-4_32.ckpt”) + ``` + 其中, + - `save_checkpoint`: 通过该接口将网络模型参数信息存入文件。 + - `CKP-Integrated_1-4_32.ckpt`: 新生成的CheckPoint模型参数文件名称。 + +## 加载合并保存的CheckPoint文件 + +### 整体流程 + +如果需要将合并保存的CheckPoint加载到多卡训练或推理中,在模型参数真正加载到网络前,需要对于涉及并行的参数数据按照新的逻辑切分。 +如下步骤在训练前脚本里实现,步骤1和3同单机CheckPoint加载的逻辑,步骤2为新增,用于涉及并行的模型参数的切分。 +对于加载到单卡训练/推理的场景,不涉及数据切分,则步骤2可省略。 + +### 步骤1:加载CheckPoint文件 + +调用`load_checkpoint`接口,从CheckPoint文件中加载模型参数数据。 + +``` +param_dict = load_checkpoint("./CKP-Integrated_1-4_32.ckpt") +``` + +- `load_checkpoint`:通过该接口加载CheckPoint模型参数文件,返回一个参数字典。 +- `CKP-Integrated_1-4_32.ckpt`:需要加载的CheckPoint模型参数文件名称。 + +### 步骤2:对模型并行参数做切分处理 + +下面以一个具体的模型参数为例,参数名称为“model_parallel_weight", 数据值为Tensor [[1, 2, 3, 4], [5, 6, 7, 8]],切分逻辑为2卡场景,按[2, 1]切分。 +切分后数据分布情况如下: + +| Device0 | Device1 | +| ------------------- | -------------------- | +| Value [1, 2, 3, 4] | Value [5, 6, 7, 8] | + +1. 对模型参数数据做切分。 + + 如下代码示例,在维度0上,将数据切分为两个切片。 + ``` + new_param = parameter_dict[“model_parallel_weight”] + slice_list = np.split(new_param.data.asnumpy(), 2, axis=0) + new_param_moments = parameter_dict[“moments.model_parallel_weight”] + slice_moments_list = np.split(new_param_moments.data.asnumpy(), 2, axis=0) + ``` + + 切分后的数据情况: + + slice_list[0] --- [1, 2, 3, 4] 对应device0 + slice_list[1] --- [5, 6, 7, 8] 对应device1 + + 与`slice_list`类似,`slice_moments_list` 也被切分为两个shape为[1, 4]的Tensor。 + +2. 在每个节点分别加载对应的数据切片。 + + 获取本节点的rank_id,根据rank_id加载数据。 + ``` + rank = get_rank() + tensor_slice = Tensor(slice_list[rank]) + tensor_slice_moments = Tensor(slice_moments_list[rank]) + ``` + - `get_rank`:获取当前设备在集群中的ID。 + +3. 修改模型参数数据值。 + + ``` + new_param.set_data(tensor_slice, True) + new_param_moments.set_data(tensor_slice_moments, True) + ``` + + - `set_data`:设置模型参数的值,接口参数类型为Tensor 或number。 + +### 步骤3:将修改后的参数数据加载到网络中 + +调用`load_param_into_net`接口,将模型参数数据加载到网络中。 +``` +net = Net() +opt = Momentum(learning_rate=0.01, momentum=0.9, params=parallel_net.get_parameters()) +load_param_into_net(net, param_dict) +load_param_into_net(opt, param_dict) +``` + +## 示例 + +### 示例场景说明 + +整体场景:训练分为两个阶段,两阶段的集群规模不一致,模拟FC层MatMul算子并行。 + +用户流程: + +1. 执行阶段1训练:阶段1为4卡训练环境,每卡上MatMul算子weight的shape为[2, 8],训练过程中自动导出CheckPoint。 + +2. 执行脚本对CheckPoint文件做合并处理,根据具体的切分逻辑,对于存在切分的具体模型参数做合并处理,生成合并的CheckPoint文件。 + +3. 执行阶段2训练:阶段2为2卡训练环境,每卡上MatMul算子weight的shape为[4, 8],从合并后的CheckPoint文件加载初始化模型参数数据,之后执行训练。 + +> 具体分布式环境配置和训练部分代码,此处不做详细说明,可以参考[分布式并行训练](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_ascend.html) +章节。 +> +> 本文档附上对CheckPoint文件做合并处理以及分布式训练前加载CheckPoint文件的示例代码,仅作为参考,实际请参考具体情况实现。 + +### 示例代码 + +1. 执行脚本对CheckPoint文件做合并处理。 + + 脚本执行命令: + ``` + python ./integrate_checkpoint.py "待合并的CheckPoint文件名称" "合并生成的CheckPoint文件路径&名称" "策略文件路径&名称" "节点数" + ``` + + integrate_checkpoint.py: + + ``` + import numpy as np + import os + import mindspore.nn as nn + from mindspore import Tensor, Parameter + from mindspore.ops import operations as P + from mindspore.train.serialization import save_checkpoint, load_checkpoint, build_searched_strategy, merge_sliced_parameter + + class Net(nn.Cell): + def __init__(self,weight_init): + super(Net, self).__init__() + self.weight = Parameter(Tensor(weight_init), "model_parallel_weight", layerwise_parallel=True) + self.fc = P.MatMul(transpose_b=True) + + def construct(self, x): + x = self.fc(x, self.weight1) + return x + + def integrate_ckpt_file(old_ckpt_file, new_ckpt_file, strategy_file, rank_size): + weight = np.ones([2, 8]).astype(np.float32) + net = Net(weight) + opt = Momentum(learning_rate=0.01, momentum=0.9, params=net.get_parameters()) + net = TrainOneStepCell(net, opt) + + # load CheckPoint into net in rank id order + param_dicts = [] + for i in range(rank_size): + file_name = os.path.join("./node"+str(i), old_ckpt_file) + param_dict = load_checkpoint(file_name) + load_param_into_net(net, param_dict) + param_dict = {} + for _, param in net.parameters_and_names(): + param_dict[param.name] = param + param_dicts.append(param_dict) + + strategy = build_searched_strategy(strategy_file) + param_dict = {} + + for paramname in ["model_parallel_weight", "moments.model_parallel_weight"]: + # get layer wise model parallel parameter + sliced_parameters = [] + for i in range(rank_size): + parameter = param_dicts[i].get(paramname) + sliced_parameters.append(parameter) + + # merge the parallel parameters of the model + merged_parameter = merge_sliced_parameter(sliced_parameters, strategy) + param_dict[paramname] = merged_parameter + + # convert param_dict to list type data + param_list = [] + for (key, value) in param_dict.items(): + each_param = {} + each_param["name"] = key + if isinstance(value.data, Tensor): + param_data = value.data + else: + param_data = Tensor(value.data) + each_param["data"] = param_data + param_list.append(each_param) + + # call the API to generate a new CheckPoint file + save_checkpoint(param_list, new_ckpt_file) + + return + + if __name__ == "__main__": + try: + old_ckpt_file = sys.argv[1] + new_ckpt_file = sys.argv[2] + strategy_file = sys.argv[3] + rank_size = int(sys.argv[4]) + integrate_ckpt_file(old_ckpt_file, new_ckpt_file, strategy_file, rank_size) + except: + print("Fail to integrate checkpoint file) + sys.exit(-1) + ``` + + 执行结果: + + 脚本执行前,CheckPoint文件中参数值: + ``` + device0: + name is model_parallel_weight + value is + [[0.87537426 1.0448935 0.86736983 0.8836905 0.77354026 0.69588304 0.9183654 0.7792076] + [0.87224025 0.8726848 0.771446 0.81967723 0.88974726 0.7988162 0.72919345 0.7677011]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_weight + value is + [[0.2567724 -0.07485991 0.282002 0.2456022 0.454939 0.619168 0.18964815 0.45714882] + [0.25946522 0.24344791 0.45677605 0.3611395 0.23378398 0.41439137 0.5312468 0.4696194]] + + device1: + name is model_parallel_weight + value is + [[0.9210751 0.9050457 0.9827775 0.920396 0.9240526 0.9750359 1.0275179 1.0819869] + [0.73605865 0.84631145 0.9746683 0.9386582 0.82902765 0.83565056 0.9702136 1.0514659]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_weight + value is + [[0.2417504 0.28193963 0.06713893 0.21510397 0.23380603 0.11424308 0.0218009 -0.11969765] + [0.45955992 0.22664294 0.01990281 0.0731914 0.27125207 0.27298513 -0.01716102 -0.15327111]] + + device2: + name is model_parallel_weight + value is + [[1.0108461 0.8689414 0.91719437 0.8805056 0.7994629 0.8999671 0.7585804 1.0287056 ] + [0.90653455 0.60146594 0.7206475 0.8306303 0.8364681 0.89625114 0.7354735 0.8447268]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_weight + value is + [[0.03440702 0.41419312 0.24817684 0.30765256 0.48516113 0.24904746 0.57791173 0.00955463] + [0.13458519 0.6690533 0.49259356 0.28319967 0.25951773 0.16777472 0.45696738 0.24933104]] + + device3: + name is model_parallel_weight + value is + [[0.7147005 0.9168278 0.80178416 0.6258351 0.8413766 0.5909515 0.696347 0.71359116] + [0.20506378 0.03691584 0.2454556 0.12978578 0.19065076 0.23904312 0.27509746 0.34614682]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_parallel_weight + value is + [[0.14152306 0.5040985 0.24455397 0.10907605 0.11319532 0.19538902 0.01208619 0.40430856] + [-0.7773164 -0.47611716 -0.6041424 -0.6144473 -0.2651842 -0.31909415 -0.4510405 -0.12860501]] + ``` + + 脚本执行后,CheckPoint文件中参数值: + + ``` + name is model_parallel_weight + value is + [[1.1138763 1.0962057 1.3516843 1.0812817 1.1579804 1.1078343 1.0906502 1.3207073] + [0.916671 1.0781671 1.0368758 0.9680898 1.1735439 1.0628364 0.9960786 1.0135143] + [0.8828271 0.7963984 0.90675324 0.9830291 0.89010954 0.897052 0.7890109 0.89784735] + [1.0011744 1.0840297 1.0201758 1.0882459 0.94232416 1.0775206 1.0195118 1.0528734] + [1.0053468 0.98402303 0.99762845 0.97587246 1.0259694 1.0055295 0.99420834 0.9496847] + [1.0851002 1.0295962 1.0999886 1.0958165 0.9765328 1.146529 1.0970603 1.1388365] + [0.7147005 0.9168278 0.80178416 0.6258351 0.8413766 0.5909515 0.696347 0.71359116] + [0.20506378 0.03691584 0.2454556 0.12978578 0.19065076 0.23904312 0.27509746 0.34614682]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_parallel_weight + value is + [[0.2567724 -0.07485991 0.282002 0.2456022 0.454939 0.619168 0.18964815 0.45714882] + [0.25946522 0.24344791 0.45677605 0.3611395 0.23378398 0.41439137 0.5312468 0.4696194 ] + [0.2417504 0.28193963 0.06713893 0.21510397 0.23380603 0.11424308 0.0218009 -0.11969765] + [0.45955992 0.22664294 0.01990281 0.0731914 0.27125207 0.27298513 -0.01716102 -0.15327111] + [0.03440702 0.41419312 0.24817684 0.30765256 0.48516113 0.24904746 0.57791173 0.00955463] + [0.13458519 0.6690533 0.49259356 0.28319967 0.25951773 0.16777472 0.45696738 0.24933104] + [0.14152306 0.5040985 0.24455397 0.10907605 0.11319532 0.19538902 0.01208619 0.40430856] + [-0.7773164 -0.47611716 -0.6041424 -0.6144473 -0.2651842 -0.31909415 -0.4510405 + -0.12860501]] + ``` + + +2. 执行阶段2训练,训练前加载CheckPoint文件。其中训练代码部分,需要根据实际情况补充。 + + ``` + import numpy as np + import os + import mindspore.nn as nn + from mindspore import context + from mindspore.communication.management import init + from mindspore import Tensor, Parameter + from mindspore.ops import operations as P + from mindspore.train.serialization import load_checkpoint, load_param_into_net + + from mindspore.communication.management import init + devid = int(os.getenv('DEVICE_ID')) + context.set_context(mode=context.GRAPH_MODE,device_target='Ascend',save_graphs=True, device_id=devid) + init() + + class Net(nn.Cell): + def __init__(self,weight_init): + super(Net, self).__init__() + self.weight = Parameter(Tensor(weight_init), "model_parallel_weight", layerwise_parallel=True) + self.fc = P.MatMul(transpose_b=True) + + def construct(self, x): + x = self.fc(x, self.weight1) + return x + def train_mindspore_impl_fc(input, label, ckpt_file): + param_dict = load_checkpoint(ckpt_file) + + for paramname in ["model_parallel_weight", "moments.model_parallel_weight"]: + # get layer wise model parallel parameter + new_param = parameter_dict[paramname] + # split the model parameter data + slice_list = np.split(new_param.data.asnumpy(), 2, axis=0) + # Load the corresponding data slice + rank = get_rank() + tensor_slice = Tensor(slice_list[rank]) + # modify model parameter data values + new_param.set_data(tensor_slice, True) + + # load the modified parameter data into the network + weight = np.ones([4, 8]).astype(np.float32) + net = Net(weight) + load_param_into_net(net, param_dict) + opt = Momentum(learning_rate=0.01, momentum=0.9, params=parallel_net.get_parameters()) + load_param_into_net(opt, param_dict) + # train code + ... + + if __name__ == "__main__": + input = np.random.random((4, 8)).astype(np.float32) + print("mean = ", np.mean(input,axis=1, keepdims=True)) + label = np.random.random((4, 4)).astype(np.float32) + train_mindspore_impl_fc(input, label, weight1) + ``` + + 其中, + + - `mode=context.GRAPH_MODE`:使用分布式训练需要指定运行模式为图模式(PyNative模式不支持并行)。 + - `device_id`:卡物理序号,即卡所在机器中的实际序号。 + - `init`:完成分布式训练初始化操作。 + + 加载后的参数值: + + ``` + device0: + name is model_parallel_weight + value is + [[0.87537426 1.0448935 0.86736983 0.8836905 0.77354026 0.69588304 0.9183654 0.7792076] + [0.87224025 0.8726848 0.771446 0.81967723 0.88974726 0.7988162 0.72919345 0.7677011] + [0.8828271 0.7963984 0.90675324 0.9830291 0.89010954 0.897052 0.7890109 0.89784735] + [1.0011744 1.0840297 1.0201758 1.0882459 0.94232416 1.0775206 1.0195118 1.0528734]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_weight + value is + [[0.2567724 -0.07485991 0.282002 0.2456022 0.454939 0.619168 0.18964815 0.45714882] + [0.25946522 0.24344791 0.45677605 0.3611395 0.23378398 0.41439137 0.5312468 0.4696194] + [0.2417504 0.28193963 0.06713893 0.21510397 0.23380603 0.11424308 0.0218009 -0.11969765] + [0.45955992 0.22664294 0.01990281 0.0731914 0.27125207 0.27298513 -0.01716102 -0.15327111]] + + device1: + name is model_parallel_weight + value is + [[1.0053468 0.98402303 0.99762845 0.97587246 1.0259694 1.0055295 0.99420834 0.9496847] + [1.0851002 1.0295962 1.0999886 1.0958165 0.9765328 1.146529 1.0970603 1.1388365] + [0.7147005 0.9168278 0.80178416 0.6258351 0.8413766 0.5909515 0.696347 0.71359116] + [0.20506378 0.03691584 0.2454556 0.12978578 0.19065076 0.23904312 0.27509746 0.34614682]] + name is learning_rate + value is [0.01] + name is momentum + value is [0.9] + name is moments.model_weight + value is + [[0.03440702 0.41419312 0.24817684 0.30765256 0.48516113 0.24904746 0.57791173 0.00955463] + [0.13458519 0.6690533 0.49259356 0.28319967 0.25951773 0.16777472 0.45696738 0.24933104] + [0.14152306 0.5040985 0.24455397 0.10907605 0.11319532 0.19538902 0.01208619 0.40430856] + [-0.7773164 -0.47611716 -0.6041424 -0.6144473 -0.2651842 -0.31909415 -0.4510405 -0.12860501]] + ``` diff --git a/tutorials/source_zh_cn/advanced_use/computer_vision_application.md b/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/computer_vision_application.md rename to tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md diff --git a/tutorials/source_zh_cn/advanced_use/customized_debugging_information.md b/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/customized_debugging_information.md rename to tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md diff --git a/tutorials/source_zh_cn/advanced_use/dashboard.md b/tutorials/training/source_zh_cn/advanced_use/dashboard.md similarity index 98% rename from tutorials/source_zh_cn/advanced_use/dashboard.md rename to tutorials/training/source_zh_cn/advanced_use/dashboard.md index 898695dfe2..110dfa34ff 100644 --- a/tutorials/source_zh_cn/advanced_use/dashboard.md +++ b/tutorials/training/source_zh_cn/advanced_use/dashboard.md @@ -1,200 +1,200 @@ -# 训练看板 - -`Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` - - - -- [训练看板](#训练看板) - - [概述](#概述) - - [标量可视化](#标量可视化) - - [参数分布图可视化](#参数分布图可视化) - - [计算图可视化](#计算图可视化) - - [数据图可视化](#数据图可视化) - - [图像可视化](#图像可视化) - - [张量可视化](#张量可视化) - - [注意事项](#注意事项) - - - -   - - -## 概述 - -训练看板是MindInsight的可视化组件的重要组成部分,而训练看板的标签包含:标量可视化、参数分布图可视化、计算图可视化、数据图可视化、图像可视化和张量可视化等。 - -用户从训练列表中选择指定的训练,进入训练看板。 - -## 标量可视化 - -标量可视化用于展示训练过程中,标量的变化趋势情况。 - -![scalar.png](./images/scalar.png) - -图1:标量趋势图 - -图1展示了神经网络在训练过程中损失值的变化过程。横坐标是训练步骤,纵坐标是损失值。 - -图中右上角有几个按钮功能,从左到右功能分别是全屏展示,切换Y轴比例,开启/关闭框选,分步回退和还原图形。 - -- 全屏展示即全屏展示该标量曲线,再点击一次即可恢复。 -- 切换Y轴比例是指可以将Y轴坐标进行对数转换。 -- 开启/关闭框选是指可以框选图中部分区域,并放大查看该区域, 可以在已放大的图形上叠加框选。 -- 分步回退是指对同一个区域连续框选并放大查看时,可以逐步撤销操作。 -- 还原图形是指进行了多次框选后,点击此按钮可以将图还原回原始状态。 - -图中右下角可以设置阈值并高亮显示或者删除阈值。如图所示,设置的阈值为小于1.5,红色高亮部分显示出超出阈值的部分,能够直观地看到预期的数据值或者一些异常的数值。 - -![scalar_select.png](./images/scalar_select.png) - -图2:标量可视化功能区 - -图2展示的标量可视化的功能区,提供了根据选择不同标签,水平轴的不同维度和平滑度来查看标量信息的功能。 - -- 标签选择:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的标量信息。 -- 水平轴:可以选择“步骤”、“相对时间”、“绝对时间”中的任意一项,来作为标量曲线的水平轴。 -- 平滑度:可以通过调整平滑度,对标量曲线进行平滑处理。 -- 标量合成:可以选中两条标量曲线进行合成并展示在一个图中,以方便对两条曲线进行对比或者查看合成后的图。 - -![scalar_compound.png](./images/scalar_compound.png) - -图3:Accuracy和Loss的标量合成图 - -图3展示Accuracy曲线和Loss曲线的标量合成图。标量合成的功能区与标量可视化的功能区相似。其中与标量可视化功能区不一样的地方,在于标签选择时,标量合成功能最多只能同时选择两个标签,将其曲线合成并展示。 - -## 参数分布图可视化 - -参数分布图用于将用户所指定的张量以直方图的形式进行展示。 - -![histogram.png](./images/histogram.png) - -图4: 直方图展示 - -图4将用户所记录的张量以直方图的形式进行展示。点击图中右上角,可以将图放大。 - -![histogram_func.png](./images/histogram_func.png) - -图5: 参数分布图功能区 - -图5展示参数分布图的功能区,包含以下内容: - -- 标签选择:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的直方图。 -- 纵轴:可以选择`步骤`、`相对时间`、`绝对时间`中的任意一项,来作为直方图纵轴显示的数据。 -- 视角:可以选择`正视`和`俯视`中的一种。`正视`是指从正面的角度查看直方图,此时不同步骤之间的数据会覆盖在一起。`俯视`是指偏移以45度角俯视直方图区域,这时可以呈现不同步骤之间数据的差异。 - -## 计算图可视化 - -计算图可视化用于展示计算图的图结构,数据流以及控制流的走向,支持展示summary日志文件与通过`context`的`save_graphs`参数导出的`pb`文件。 - -![graph.png](./images/graph.png) - -图6:计算图展示区 - -图6展示了计算图的网络结构。如图中所展示的,在展示区中,选中其中一个算子(图中圈红算子),可以看到该算子有两个输入和一个输出(实线代表算子的数据流走向)。 - -![graph_sidebar.png](./images/graph_sidebar.png) - -图7:计算图功能区 - -图7展示了计算图可视化的功能区,包含以下内容: - -- 文件选择框: 可以选择查看不同文件的计算图。 -- 搜索框:可以对节点进行搜索,输入节点名称点击回车,即可展示该节点。 -- 缩略图:展示整个网络图结构的缩略图,在查看超大图结构时,方便查看当前浏览的区域。 -- 节点信息:展示选中的节点的基本信息,包括节点的名称、属性、输入节点、输出节点等信息。 -- 图例:展示的是计算图中各个图标的含义。 - -## 数据图可视化 - -数据图可视化用于展示单次模型训练的数据处理和数据增强信息。 - -![data_function.png](./images/data_function.png) - -图8:数据图功能区 - -图8展示的数据图功能区包含以下内容: - -- 图例:展示数据溯源图中各个图标的含义。 -- 数据处理流水线:展示训练所使用的数据处理流水线,可以选择图中的单个节点查看详细信息。 -- 节点信息:展示选中的节点的基本信息,包括使用的数据处理和增强算子的名称、参数等。 - -## 图像可视化 - -图像可视化用于展示用户所指定的图片。 - -![image.png](./images/image_vi.png) - -图9:图像可视化 - -图9展示通过滑动图中“步骤”滑条,查看不同步骤的图片。 - -![image_function.png](./images/image_function.png) - -图10:图像可视化功能区 - -图10展示图像可视化的功能区,提供了选择查看不同标签,不同亮度和不同对比度来查看图片信息。 - -- 标签:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的图片信息。 -- 亮度调整:可以调整所展示的所有图片亮度。 -- 对比度调整:可以调整所展示的所有图片对比度。 - -## 张量可视化 - -张量可视化用于将张量以表格以及直方图的形式进行展示。 - -![tensor_function.png](./images/tensor_function.png) - -图11:张量可视化功能区 - -图11展示张量可视化的功能区,包含以下内容: - -- 标签选择:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的表格数据或者直方图。 -- 视图:可以选择`表格`或者`直方图`来展示tensor数据。在`直方图`视图下存在`纵轴`和`视角`的功能选择。 -- 纵轴:可以选择`步骤`、`相对时间`、`绝对时间`中的任意一项,来作为直方图纵轴显示的数据。 -- 视角:可以选择`正视`和`俯视`中的一种。`正视`是指从正面的角度查看直方图,此时不同步骤之间的数据会覆盖在一起。`俯视`是指偏移以45度角俯视直方图区域,这时可以呈现不同步骤之间数据的差异。 - -![tensor_table.png](./images/tensor_table.png) - -图12:表格展示 - -图12将用户所记录的张量以表格的形式展示,包含以下功能: - -- 点击表格右边小方框按钮,可以将表格放大。 -- 表格中白色方框显示当前展示的是哪个维度下的张量数据,其中冒号`:`表示当前维度的所有值,可以在方框输入对应的索引或者`:`后按`Enter`键或者点击后边的打勾按钮来查询特定维度的张量数据。 - 假设某维度是32,则其索引范围是-32到31。注意:可以查询0维到2维的张量数据,不支持查询超过两维的张量数据,即不能设置超过两个冒号`:`的查询条件。 -- 拖拽表格下方的空心圆圈可以查询特定步骤的张量数据。 - -![tensor_histogram.png](./images/tensor_histogram.png) - -图13: 直方图展示 - -图13将用户所记录的张量以直方图的形式进行展示。点击图中右上角,可以将图放大。 - -## 注意事项 - -1. 目前MindSpore仅支持在Ascend 910 AI处理器上导出算子融合后的计算图。 -2. 在训练中使用Summary算子收集数据时,`HistogramSummary` 算子会影响性能,所以请尽量少地使用。 -3. 为了控制内存占用,MindInsight对标签(tag)数目和步骤(step)数目进行了限制: - - 每个训练看板的最大标签数量为300个标签。标量标签、图片标签、计算图标签、参数分布图(直方图)标签、张量标签的数量总和不得超过300个。特别地,每个训练看板最多有10个计算图标签、6个张量标签。当实际标签数量超过这一限制时,将依照MindInsight的处理顺序,保留最近处理的300个标签。 - - 每个训练看板的每个标量标签最多有1000个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 - - 每个训练看板的每个图片标签最多有10个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 - - 每个训练看板的每个参数分布图(直方图)标签最多有50个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 - - 每个训练看板的每个张量标签最多有20个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 -4. 由于`TensorSummary`会记录完整Tensor数据,数据量通常会比较大,为了控制内存占用和出于性能上的考虑,MindInsight对Tensor的大小以及返回前端展示的数值个数进行以下限制: - - MindInsight最大支持加载含有1千万个数值的Tensor。 - - Tensor加载后,在张量可视的表格视图下,最大支持查看10万个数值,如果所选择的维度查询得到的数值超过这一限制,则无法显示。 - -5. 由于张量可视(`TensorSummary`)会记录原始张量数据,需要的存储空间较大。使用`TensorSummary`前和训练过程中请注意检查系统存储空间充足。 - - 通过以下方法可以降低张量可视功能的存储空间占用: - - 1)避免使用`TensorSummary`记录较大的Tensor。 - - 2)减少网络中`TensorSummary`算子的使用个数。 - - 功能使用完毕后,请及时清理不再需要的训练日志,以释放磁盘空间。 - - 备注:估算`TensorSummary`空间使用量的方法如下: - - 一个`TensorSummary数据的大小 = Tensor中的数值个数 * 4 bytes`。假设使用`TensorSummary`记录的Tensor大小为`32 * 1 * 256 * 256`,则一个`TensorSummary`数据大约需要`32 * 1 * 256 * 256 * 4 bytes = 8,388,608 bytes = 8MiB`。`TensorSummary`默认会记录20个步骤的数据,则记录这20组数据需要的空间约为`20 * 8 MiB = 160MiB`。需要注意的是,由于数据结构等因素的开销,实际使用的存储空间会略大于160MiB。 +# 训练看板 + +`Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` + + + +- [训练看板](#训练看板) + - [概述](#概述) + - [标量可视化](#标量可视化) + - [参数分布图可视化](#参数分布图可视化) + - [计算图可视化](#计算图可视化) + - [数据图可视化](#数据图可视化) + - [图像可视化](#图像可视化) + - [张量可视化](#张量可视化) + - [注意事项](#注意事项) + + + +   + + +## 概述 + +训练看板是MindInsight的可视化组件的重要组成部分,而训练看板的标签包含:标量可视化、参数分布图可视化、计算图可视化、数据图可视化、图像可视化和张量可视化等。 + +用户从训练列表中选择指定的训练,进入训练看板。 + +## 标量可视化 + +标量可视化用于展示训练过程中,标量的变化趋势情况。 + +![scalar.png](./images/scalar.png) + +图1:标量趋势图 + +图1展示了神经网络在训练过程中损失值的变化过程。横坐标是训练步骤,纵坐标是损失值。 + +图中右上角有几个按钮功能,从左到右功能分别是全屏展示,切换Y轴比例,开启/关闭框选,分步回退和还原图形。 + +- 全屏展示即全屏展示该标量曲线,再点击一次即可恢复。 +- 切换Y轴比例是指可以将Y轴坐标进行对数转换。 +- 开启/关闭框选是指可以框选图中部分区域,并放大查看该区域, 可以在已放大的图形上叠加框选。 +- 分步回退是指对同一个区域连续框选并放大查看时,可以逐步撤销操作。 +- 还原图形是指进行了多次框选后,点击此按钮可以将图还原回原始状态。 + +图中右下角可以设置阈值并高亮显示或者删除阈值。如图所示,设置的阈值为小于1.5,红色高亮部分显示出超出阈值的部分,能够直观地看到预期的数据值或者一些异常的数值。 + +![scalar_select.png](./images/scalar_select.png) + +图2:标量可视化功能区 + +图2展示的标量可视化的功能区,提供了根据选择不同标签,水平轴的不同维度和平滑度来查看标量信息的功能。 + +- 标签选择:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的标量信息。 +- 水平轴:可以选择“步骤”、“相对时间”、“绝对时间”中的任意一项,来作为标量曲线的水平轴。 +- 平滑度:可以通过调整平滑度,对标量曲线进行平滑处理。 +- 标量合成:可以选中两条标量曲线进行合成并展示在一个图中,以方便对两条曲线进行对比或者查看合成后的图。 + +![scalar_compound.png](./images/scalar_compound.png) + +图3:Accuracy和Loss的标量合成图 + +图3展示Accuracy曲线和Loss曲线的标量合成图。标量合成的功能区与标量可视化的功能区相似。其中与标量可视化功能区不一样的地方,在于标签选择时,标量合成功能最多只能同时选择两个标签,将其曲线合成并展示。 + +## 参数分布图可视化 + +参数分布图用于将用户所指定的张量以直方图的形式进行展示。 + +![histogram.png](./images/histogram.png) + +图4: 直方图展示 + +图4将用户所记录的张量以直方图的形式进行展示。点击图中右上角,可以将图放大。 + +![histogram_func.png](./images/histogram_func.png) + +图5: 参数分布图功能区 + +图5展示参数分布图的功能区,包含以下内容: + +- 标签选择:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的直方图。 +- 纵轴:可以选择`步骤`、`相对时间`、`绝对时间`中的任意一项,来作为直方图纵轴显示的数据。 +- 视角:可以选择`正视`和`俯视`中的一种。`正视`是指从正面的角度查看直方图,此时不同步骤之间的数据会覆盖在一起。`俯视`是指偏移以45度角俯视直方图区域,这时可以呈现不同步骤之间数据的差异。 + +## 计算图可视化 + +计算图可视化用于展示计算图的图结构,数据流以及控制流的走向,支持展示summary日志文件与通过`context`的`save_graphs`参数导出的`pb`文件。 + +![graph.png](./images/graph.png) + +图6:计算图展示区 + +图6展示了计算图的网络结构。如图中所展示的,在展示区中,选中其中一个算子(图中圈红算子),可以看到该算子有两个输入和一个输出(实线代表算子的数据流走向)。 + +![graph_sidebar.png](./images/graph_sidebar.png) + +图7:计算图功能区 + +图7展示了计算图可视化的功能区,包含以下内容: + +- 文件选择框: 可以选择查看不同文件的计算图。 +- 搜索框:可以对节点进行搜索,输入节点名称点击回车,即可展示该节点。 +- 缩略图:展示整个网络图结构的缩略图,在查看超大图结构时,方便查看当前浏览的区域。 +- 节点信息:展示选中的节点的基本信息,包括节点的名称、属性、输入节点、输出节点等信息。 +- 图例:展示的是计算图中各个图标的含义。 + +## 数据图可视化 + +数据图可视化用于展示单次模型训练的数据处理和数据增强信息。 + +![data_function.png](./images/data_function.png) + +图8:数据图功能区 + +图8展示的数据图功能区包含以下内容: + +- 图例:展示数据溯源图中各个图标的含义。 +- 数据处理流水线:展示训练所使用的数据处理流水线,可以选择图中的单个节点查看详细信息。 +- 节点信息:展示选中的节点的基本信息,包括使用的数据处理和增强算子的名称、参数等。 + +## 图像可视化 + +图像可视化用于展示用户所指定的图片。 + +![image.png](./images/image_vi.png) + +图9:图像可视化 + +图9展示通过滑动图中“步骤”滑条,查看不同步骤的图片。 + +![image_function.png](./images/image_function.png) + +图10:图像可视化功能区 + +图10展示图像可视化的功能区,提供了选择查看不同标签,不同亮度和不同对比度来查看图片信息。 + +- 标签:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的图片信息。 +- 亮度调整:可以调整所展示的所有图片亮度。 +- 对比度调整:可以调整所展示的所有图片对比度。 + +## 张量可视化 + +张量可视化用于将张量以表格以及直方图的形式进行展示。 + +![tensor_function.png](./images/tensor_function.png) + +图11:张量可视化功能区 + +图11展示张量可视化的功能区,包含以下内容: + +- 标签选择:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的表格数据或者直方图。 +- 视图:可以选择`表格`或者`直方图`来展示tensor数据。在`直方图`视图下存在`纵轴`和`视角`的功能选择。 +- 纵轴:可以选择`步骤`、`相对时间`、`绝对时间`中的任意一项,来作为直方图纵轴显示的数据。 +- 视角:可以选择`正视`和`俯视`中的一种。`正视`是指从正面的角度查看直方图,此时不同步骤之间的数据会覆盖在一起。`俯视`是指偏移以45度角俯视直方图区域,这时可以呈现不同步骤之间数据的差异。 + +![tensor_table.png](./images/tensor_table.png) + +图12:表格展示 + +图12将用户所记录的张量以表格的形式展示,包含以下功能: + +- 点击表格右边小方框按钮,可以将表格放大。 +- 表格中白色方框显示当前展示的是哪个维度下的张量数据,其中冒号`:`表示当前维度的所有值,可以在方框输入对应的索引或者`:`后按`Enter`键或者点击后边的打勾按钮来查询特定维度的张量数据。 + 假设某维度是32,则其索引范围是-32到31。注意:可以查询0维到2维的张量数据,不支持查询超过两维的张量数据,即不能设置超过两个冒号`:`的查询条件。 +- 拖拽表格下方的空心圆圈可以查询特定步骤的张量数据。 + +![tensor_histogram.png](./images/tensor_histogram.png) + +图13: 直方图展示 + +图13将用户所记录的张量以直方图的形式进行展示。点击图中右上角,可以将图放大。 + +## 注意事项 + +1. 目前MindSpore仅支持在Ascend 910 AI处理器上导出算子融合后的计算图。 +2. 在训练中使用Summary算子收集数据时,`HistogramSummary` 算子会影响性能,所以请尽量少地使用。 +3. 为了控制内存占用,MindInsight对标签(tag)数目和步骤(step)数目进行了限制: + - 每个训练看板的最大标签数量为300个标签。标量标签、图片标签、计算图标签、参数分布图(直方图)标签、张量标签的数量总和不得超过300个。特别地,每个训练看板最多有10个计算图标签、6个张量标签。当实际标签数量超过这一限制时,将依照MindInsight的处理顺序,保留最近处理的300个标签。 + - 每个训练看板的每个标量标签最多有1000个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 + - 每个训练看板的每个图片标签最多有10个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 + - 每个训练看板的每个参数分布图(直方图)标签最多有50个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 + - 每个训练看板的每个张量标签最多有20个步骤的数据。当实际步骤的数目超过这一限制时,将对数据进行随机采样,以满足这一限制。 +4. 由于`TensorSummary`会记录完整Tensor数据,数据量通常会比较大,为了控制内存占用和出于性能上的考虑,MindInsight对Tensor的大小以及返回前端展示的数值个数进行以下限制: + - MindInsight最大支持加载含有1千万个数值的Tensor。 + - Tensor加载后,在张量可视的表格视图下,最大支持查看10万个数值,如果所选择的维度查询得到的数值超过这一限制,则无法显示。 + +5. 由于张量可视(`TensorSummary`)会记录原始张量数据,需要的存储空间较大。使用`TensorSummary`前和训练过程中请注意检查系统存储空间充足。 + + 通过以下方法可以降低张量可视功能的存储空间占用: + + 1)避免使用`TensorSummary`记录较大的Tensor。 + + 2)减少网络中`TensorSummary`算子的使用个数。 + + 功能使用完毕后,请及时清理不再需要的训练日志,以释放磁盘空间。 + + 备注:估算`TensorSummary`空间使用量的方法如下: + + 一个`TensorSummary数据的大小 = Tensor中的数值个数 * 4 bytes`。假设使用`TensorSummary`记录的Tensor大小为`32 * 1 * 256 * 256`,则一个`TensorSummary`数据大约需要`32 * 1 * 256 * 256 * 4 bytes = 8,388,608 bytes = 8MiB`。`TensorSummary`默认会记录20个步骤的数据,则记录这20组数据需要的空间约为`20 * 8 MiB = 160MiB`。需要注意的是,由于数据结构等因素的开销,实际使用的存储空间会略大于160MiB。 6. 当使用`TensorSummary`时,由于记录完整Tensor数据,训练日志文件较大,MindInsight需要更多时间解析训练日志文件,请耐心等待。 \ No newline at end of file diff --git a/tutorials/source_zh_cn/advanced_use/data_processing_acceleration.md b/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/data_processing_acceleration.md rename to tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md diff --git a/tutorials/source_zh_cn/advanced_use/dataset_conversion.md b/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/dataset_conversion.md rename to tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md diff --git a/tutorials/source_zh_cn/advanced_use/debugging_in_pynative_mode.md b/tutorials/training/source_zh_cn/advanced_use/debugging_in_pynative_mode.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/debugging_in_pynative_mode.md rename to tutorials/training/source_zh_cn/advanced_use/debugging_in_pynative_mode.md diff --git a/tutorials/source_zh_cn/advanced_use/deep_probability_program.md b/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/deep_probability_program.md rename to tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md index 13e92b1452..93436976f5 100644 --- a/tutorials/source_zh_cn/advanced_use/deep_probability_program.md +++ b/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md @@ -1,432 +1,432 @@ -# 深度概率编程 -`Ascend` `GPU` `全流程` `初级` `中级` `高级` - - - -- [深度概率编程](#深度概率编程) - - [概述](#概述) - - [贝叶斯神经网络](#贝叶斯神经网络) - - [处理数据集](#处理数据集) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [训练网络](#训练网络) - - [变分推断](#变分推断) - - [定义变分自编码器](#定义变分自编码器) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [处理数据](#处理数据) - - [训练网络](#训练网络) - - [DNN一键转换成BNN](#DNN一键转换成BNN) - - [定义DNN模型](#定义DNN模型) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [功能一:转换整个模型](#功能一:转换整个模型) - - [功能二:转换指定类型的层](#功能二:转换指定类型的层) - - [不确定性估计](#不确定性估计) - - - -## 概述 -MindSpore深度概率编程(MindSpore Deep Probabilistic Programming, MDP)的目标是将深度学习和贝叶斯学习结合,并能面向不同的开发者。具体来说,对于专业的贝叶斯学习用户,提供概率采样、推理算法和模型构建库;另一方面,为不熟悉贝叶斯深度学习的用户提供了高级的API,从而不用更改深度学习编程逻辑,即可利用贝叶斯模型。 - -本章将详细介绍深度概率编程在MindSpore上的应用。 - -### 贝叶斯神经网络 -本例子利用贝叶斯神经网络实现一个简单的图片分类功能,整体流程如下: -1. 处理MNIST数据集。 -2. 定义贝叶斯LeNet网络。 -3. 定义损失函数和优化器。 -4. 加载数据集并进行训练。 - -#### 处理数据集 -本例子使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 - -#### 定义贝叶斯神经网络 -本例子使用的是贝叶斯LeNet。利用bnn_layers构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,bnn_layers和普通的神经网络层可以互相组合。 - -``` -import mindspore.nn as nn -from mindspore.nn.probability import bnn_layers -import mindspore.ops.operations as P - -class BNNLeNet5(nn.Cell): - """ - bayesian Lenet network - - Args: - num_class (int): Num classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> BNNLeNet5(num_class=10) - - """ - def __init__(self, num_class=10): - super(BNNLeNet5, self).__init__() - self.num_class = num_class - self.conv1 = bnn_layers.ConvReparam(1, 6, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") - self.conv2 = bnn_layers.ConvReparam(6, 16, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") - self.fc1 = bnn_layers.DenseReparam(16 * 5 * 5, 120) - self.fc2 = bnn_layers.DenseReparam(120, 84) - self.fc3 = bnn_layers.DenseReparam(84, self.num_class) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - self.reshape = P.Reshape() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` -#### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。损失函数是深度学习的训练目标,也叫目标函数,可以理解为神经网络的输出(Logits)和标签(Labels)之间的距离,是一个标量数据。 -常见的损失函数包括均方误差、L2损失、Hinge损失、交叉熵等等。图像分类应用通常采用交叉熵损失(CrossEntropy)。 -优化器用于神经网络求解(训练)。由于神经网络参数规模庞大,无法直接求解,因而深度学习中采用随机梯度下降算法(SGD)及其改进算法进行求解。MindSpore封装了常见的优化器,如SGD、Adam、Momemtum等等。本例采用Adam优化器,通常需要设定两个参数,学习率(learnin _rate)和权重衰减项(weight decay)。 -MindSpore中定义损失函数和优化器的代码样例如下: - -``` -# loss function definition -criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - -# optimization definition -optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) -``` - -#### 训练网络 -贝叶斯神经网络的训练过程与DNN基本相同,唯一不同的是将`WithLossCell`替换为适用于BNN的`WithBNNLossCell`。除了`backbone`和`loss_fn`两个参数之外,`WithBNNLossCell`增加了`dnn_factor`和`bnn_factor`两个参数。`dnn_factor`是由损失函数计算得到的网络整体损失的系数,`bnn_factor`是每个贝叶斯层的KL散度的系数,这两个参数是用来平衡网络整体损失和贝叶斯层的KL散度的,防止KL散度的值过大掩盖了网络整体损失。 - -``` -net_with_loss = bnn_layers.WithBNNLossCell(network, criterion, dnn_factor=60000, bnn_factor=0.000001) -train_bnn_network = TrainOneStepCell(net_with_loss, optimizer) -train_bnn_network.set_train() - -train_set = create_dataset('./mnist_data/train', 64, 1) -test_set = create_dataset('./mnist_data/test', 64, 1) - -epoch = 10 - -for i in range(epoch): - train_loss, train_acc = train_model(train_bnn_network, network, train_set) - - valid_acc = validate_model(network, test_set) - - print('Epoch: {} \tTraining Loss: {:.4f} \tTraining Accuracy: {:.4f} \tvalidation Accuracy: {:.4f}'. - format(i, train_loss, train_acc, valid_acc)) -``` -其中,`train_model`和`validate_model`在MindSpore中的代码样例如下: - -``` -def train_model(train_net, net, dataset): - accs = [] - loss_sum = 0 - for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].astype(np.float32)) - label = Tensor(data['label'].astype(np.int32)) - loss = train_net(train_x, label) - output = net(train_x) - log_output = P.LogSoftmax(axis=1)(output) - acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) - accs.append(acc) - loss_sum += loss.asnumpy() - - loss_sum = loss_sum / len(accs) - acc_mean = np.mean(accs) - return loss_sum, acc_mean - - -def validate_model(net, dataset): - accs = [] - for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].astype(np.float32)) - label = Tensor(data['label'].astype(np.int32)) - output = net(train_x) - log_output = P.LogSoftmax(axis=1)(output) - acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) - accs.append(acc) - - acc_mean = np.mean(accs) - return acc_mean -``` - -### 变分推断 -#### 定义变分自编码器 -我们只需要自定义编码器和解码器,编码器和解码器都是神经网络。 - -``` -class Encoder(nn.Cell): - def __init__(self): - super(Encoder, self).__init__() - self.fc1 = nn.Dense(1024, 800) - self.fc2 = nn.Dense(800, 400) - self.relu = nn.ReLU() - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - return x - - -class Decoder(nn.Cell): - def __init__(self): - super(Decoder, self).__init__() - self.fc1 = nn.Dense(400, 1024) - self.sigmoid = nn.Sigmoid() - self.reshape = P.Reshape() - - def construct(self, z): - z = self.fc1(z) - z = self.reshape(z, IMAGE_SHAPE) - z = self.sigmoid(z) - return z - - -encoder = Encoder() -decoder = Decoder() -vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) -``` -### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用的损失函数是ELBO,ELBO是变分推断专用的损失函数;本例使用的优化器是Adam。 -MindSpore中定义损失函数和优化器的代码样例如下: - -``` -# loss function definition -net_loss = ELBO(latent_prior='Normal', output_prior='Normal') - -# optimization definition -optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) - -net_with_loss = nn.WithLossCell(vae, net_loss) -``` -#### 处理数据 -本例使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 - -#### 训练网络 -使用`SVI`接口对VAE网络进行训练。 - -``` -from mindspore.nn.probability.infer import SVI - -vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) -vae = vi.run(train_dataset=ds_train, epochs=10) -trained_loss = vi.get_train_loss() -``` -通过`vi.run`可以得到训练好的网络,使用`vi.get_train_loss`可以得到训练之后的损失。 -#### 生成新样本或重构输入样本 -利用训练好的VAE网络,我们可以生成新的样本或重构输入样本。 - -``` -IMAGE_SHAPE = (-1, 1, 32, 32) -generated_sample = vae.generate_sample(64, IMAGE_SHAPE) -for sample in ds_train.create_dict_iterator(): - sample_x = Tensor(sample['image'], dtype=mstype.float32) - reconstructed_sample = vae.reconstruct_sample(sample_x) -``` - -### DNN一键转换成BNN -对于不熟悉贝叶斯模型的DNN研究人员,MDP提供了高级API`TransformToBNN`,支持DNN模型一键转换成BNN模型。 -#### 定义DNN模型 -本例使用的DNN模型是LeNet。 - -``` -from mindspore.common.initializer import TruncatedNormal -import mindspore.nn as nn -import mindspore.ops.operations as P - -def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): - """weight initial for conv layer""" - weight = weight_variable() - return nn.Conv2d(in_channels, out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, - weight_init=weight, has_bias=False, pad_mode="valid") - - -def fc_with_initialize(input_channels, out_channels): - """weight initial for fc layer""" - weight = weight_variable() - bias = weight_variable() - return nn.Dense(input_channels, out_channels, weight, bias) - - -def weight_variable(): - """weight initial""" - return TruncatedNormal(0.02) - - -class LeNet5(nn.Cell): - """ - Lenet network - - Args: - num_class (int): Num classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> LeNet5(num_class=10) - - """ - def __init__(self, num_class=10): - super(LeNet5, self).__init__() - self.num_class = num_class - self.conv1 = conv(1, 6, 5) - self.conv2 = conv(6, 16, 5) - self.fc1 = fc_with_initialize(16 * 5 * 5, 120) - self.fc2 = fc_with_initialize(120, 84) - self.fc3 = fc_with_initialize(84, self.num_class) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - self.reshape = P.Reshape() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` -#### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,Adam作为优化器。 - -``` -network = LeNet5() - -# loss function definition -criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - -# optimization definition -optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) - -net_with_loss = WithLossCell(network, criterion) -train_network = TrainOneStepCell(net_with_loss, optimizer) -``` -#### 实例化TransformToBNN -`TransformToBNN`的`__init__`函数定义如下: - -``` -class TransformToBNN: - def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): - net_with_loss = trainable_dnn.network - self.optimizer = trainable_dnn.optimizer - self.backbone = net_with_loss.backbone_network - self.loss_fn = getattr(net_with_loss, "_loss_fn") - self.dnn_factor = dnn_factor - self.bnn_factor = bnn_factor - self.bnn_loss_file = None -``` -参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 -MindSpore中实例化`TransformToBNN`的代码如下: - -``` -from mindspore.nn.probability import transforms - -bnn_transformer = transforms.TransformToBNN(train_network, 60000, 0.000001) -``` -#### 功能一:转换整个模型 -`transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下: - -``` - def transform_to_bnn_model(self, - get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, - "out_channels": dp.out_channels, "activation": dp.activation}, - get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, - "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, - "stride": dp.stride, "has_bias": dp.has_bias, - "padding": dp.padding, "dilation": dp.dilation, - "group": dp.group}, - add_dense_args=None, - add_conv_args=None): - r""" - Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. - - Args: - get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: - {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. - get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: - {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, - "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. - add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. - add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. - - Returns: - Cell, a trainable BNN model wrapped by TrainOneStepCell. - """ -``` -参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 -在MindSpore中将整个DNN模型转换成BNN模型的代码如下: - -``` -train_bnn_network = bnn_transformer.transform_to_bnn_model() -``` -#### 功能二:转换指定类型的层 -`transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(nn.Dense或者nn.Conv2d)转换为对应的贝叶斯层。其定义如下: - -``` - def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): - r""" - Transform a specific type of layers in DNN model to corresponding BNN layer. - - Args: - dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are - nn.Dense, nn.Conv2d. - bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are - DenseReparameterization, ConvReparameterization. - get_args (dict): The arguments gotten from the DNN layer. Default: None. - add_args (dict): The new arguments added to BNN layer. Default: None. - - Returns: - Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. - """ -``` -参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 - -### 不确定性估计 -不确定性估计工具箱基于MindSpore Deep probability Programming (MDP),适用于主流的深度学习模型,如回归、分类、目标检测等。在推理阶段,利用不确定性估计工具箱,开发人员只需通过训练模型和训练数据集,指定需要估计的任务和样本,即可得到任意不确定性(aleatoric uncertainty)和认知不确定性(epistemic uncertainty)。基于不确定性信息,开发人员可以更好地理解模型和数据集。 -以分类任务为例,本例中使用的模型是LeNet,数据集为MNist,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。为了评估测试示例的不确定性,使用工具箱的方法如下: - -``` -from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation -from mindspore.train.serialization import load_checkpoint, load_param_into_net - -network = LeNet5() -param_dict = load_checkpoint('checkpoint_lenet.ckpt') -load_param_into_net(network, param_dict) -# get train and eval dataset -ds_train = create_dataset('workspace/mnist/train') -ds_eval = create_dataset('workspace/mnist/test') -evaluation = UncertaintyEvaluation(model=network, - train_dataset=ds_train, - task_type='classification', - num_classes=10, - epochs=1, - epi_uncer_model_path=None, - ale_uncer_model_path=None, - save_model=False) -for eval_data in ds_eval.create_dict_iterator(): - eval_data = Tensor(eval_data['image'], mstype.float32) - epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) - aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) -``` - - +# 深度概率编程 +`Ascend` `GPU` `全流程` `初级` `中级` `高级` + + + +- [深度概率编程](#深度概率编程) + - [概述](#概述) + - [贝叶斯神经网络](#贝叶斯神经网络) + - [处理数据集](#处理数据集) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [训练网络](#训练网络) + - [变分推断](#变分推断) + - [定义变分自编码器](#定义变分自编码器) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [处理数据](#处理数据) + - [训练网络](#训练网络) + - [DNN一键转换成BNN](#DNN一键转换成BNN) + - [定义DNN模型](#定义DNN模型) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [功能一:转换整个模型](#功能一:转换整个模型) + - [功能二:转换指定类型的层](#功能二:转换指定类型的层) + - [不确定性估计](#不确定性估计) + + + +## 概述 +MindSpore深度概率编程(MindSpore Deep Probabilistic Programming, MDP)的目标是将深度学习和贝叶斯学习结合,并能面向不同的开发者。具体来说,对于专业的贝叶斯学习用户,提供概率采样、推理算法和模型构建库;另一方面,为不熟悉贝叶斯深度学习的用户提供了高级的API,从而不用更改深度学习编程逻辑,即可利用贝叶斯模型。 + +本章将详细介绍深度概率编程在MindSpore上的应用。 + +### 贝叶斯神经网络 +本例子利用贝叶斯神经网络实现一个简单的图片分类功能,整体流程如下: +1. 处理MNIST数据集。 +2. 定义贝叶斯LeNet网络。 +3. 定义损失函数和优化器。 +4. 加载数据集并进行训练。 + +#### 处理数据集 +本例子使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 + +#### 定义贝叶斯神经网络 +本例子使用的是贝叶斯LeNet。利用bnn_layers构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,bnn_layers和普通的神经网络层可以互相组合。 + +``` +import mindspore.nn as nn +from mindspore.nn.probability import bnn_layers +import mindspore.ops.operations as P + +class BNNLeNet5(nn.Cell): + """ + bayesian Lenet network + + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + Examples: + >>> BNNLeNet5(num_class=10) + + """ + def __init__(self, num_class=10): + super(BNNLeNet5, self).__init__() + self.num_class = num_class + self.conv1 = bnn_layers.ConvReparam(1, 6, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") + self.conv2 = bnn_layers.ConvReparam(6, 16, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") + self.fc1 = bnn_layers.DenseReparam(16 * 5 * 5, 120) + self.fc2 = bnn_layers.DenseReparam(120, 84) + self.fc3 = bnn_layers.DenseReparam(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` +#### 定义损失函数和优化器 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。损失函数是深度学习的训练目标,也叫目标函数,可以理解为神经网络的输出(Logits)和标签(Labels)之间的距离,是一个标量数据。 +常见的损失函数包括均方误差、L2损失、Hinge损失、交叉熵等等。图像分类应用通常采用交叉熵损失(CrossEntropy)。 +优化器用于神经网络求解(训练)。由于神经网络参数规模庞大,无法直接求解,因而深度学习中采用随机梯度下降算法(SGD)及其改进算法进行求解。MindSpore封装了常见的优化器,如SGD、Adam、Momemtum等等。本例采用Adam优化器,通常需要设定两个参数,学习率(learnin _rate)和权重衰减项(weight decay)。 +MindSpore中定义损失函数和优化器的代码样例如下: + +``` +# loss function definition +criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + +# optimization definition +optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) +``` + +#### 训练网络 +贝叶斯神经网络的训练过程与DNN基本相同,唯一不同的是将`WithLossCell`替换为适用于BNN的`WithBNNLossCell`。除了`backbone`和`loss_fn`两个参数之外,`WithBNNLossCell`增加了`dnn_factor`和`bnn_factor`两个参数。`dnn_factor`是由损失函数计算得到的网络整体损失的系数,`bnn_factor`是每个贝叶斯层的KL散度的系数,这两个参数是用来平衡网络整体损失和贝叶斯层的KL散度的,防止KL散度的值过大掩盖了网络整体损失。 + +``` +net_with_loss = bnn_layers.WithBNNLossCell(network, criterion, dnn_factor=60000, bnn_factor=0.000001) +train_bnn_network = TrainOneStepCell(net_with_loss, optimizer) +train_bnn_network.set_train() + +train_set = create_dataset('./mnist_data/train', 64, 1) +test_set = create_dataset('./mnist_data/test', 64, 1) + +epoch = 10 + +for i in range(epoch): + train_loss, train_acc = train_model(train_bnn_network, network, train_set) + + valid_acc = validate_model(network, test_set) + + print('Epoch: {} \tTraining Loss: {:.4f} \tTraining Accuracy: {:.4f} \tvalidation Accuracy: {:.4f}'. + format(i, train_loss, train_acc, valid_acc)) +``` +其中,`train_model`和`validate_model`在MindSpore中的代码样例如下: + +``` +def train_model(train_net, net, dataset): + accs = [] + loss_sum = 0 + for _, data in enumerate(dataset.create_dict_iterator()): + train_x = Tensor(data['image'].astype(np.float32)) + label = Tensor(data['label'].astype(np.int32)) + loss = train_net(train_x, label) + output = net(train_x) + log_output = P.LogSoftmax(axis=1)(output) + acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) + accs.append(acc) + loss_sum += loss.asnumpy() + + loss_sum = loss_sum / len(accs) + acc_mean = np.mean(accs) + return loss_sum, acc_mean + + +def validate_model(net, dataset): + accs = [] + for _, data in enumerate(dataset.create_dict_iterator()): + train_x = Tensor(data['image'].astype(np.float32)) + label = Tensor(data['label'].astype(np.int32)) + output = net(train_x) + log_output = P.LogSoftmax(axis=1)(output) + acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) + accs.append(acc) + + acc_mean = np.mean(accs) + return acc_mean +``` + +### 变分推断 +#### 定义变分自编码器 +我们只需要自定义编码器和解码器,编码器和解码器都是神经网络。 + +``` +class Encoder(nn.Cell): + def __init__(self): + super(Encoder, self).__init__() + self.fc1 = nn.Dense(1024, 800) + self.fc2 = nn.Dense(800, 400) + self.relu = nn.ReLU() + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + return x + + +class Decoder(nn.Cell): + def __init__(self): + super(Decoder, self).__init__() + self.fc1 = nn.Dense(400, 1024) + self.sigmoid = nn.Sigmoid() + self.reshape = P.Reshape() + + def construct(self, z): + z = self.fc1(z) + z = self.reshape(z, IMAGE_SHAPE) + z = self.sigmoid(z) + return z + + +encoder = Encoder() +decoder = Decoder() +vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) +``` +### 定义损失函数和优化器 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用的损失函数是ELBO,ELBO是变分推断专用的损失函数;本例使用的优化器是Adam。 +MindSpore中定义损失函数和优化器的代码样例如下: + +``` +# loss function definition +net_loss = ELBO(latent_prior='Normal', output_prior='Normal') + +# optimization definition +optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) + +net_with_loss = nn.WithLossCell(vae, net_loss) +``` +#### 处理数据 +本例使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 + +#### 训练网络 +使用`SVI`接口对VAE网络进行训练。 + +``` +from mindspore.nn.probability.infer import SVI + +vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) +vae = vi.run(train_dataset=ds_train, epochs=10) +trained_loss = vi.get_train_loss() +``` +通过`vi.run`可以得到训练好的网络,使用`vi.get_train_loss`可以得到训练之后的损失。 +#### 生成新样本或重构输入样本 +利用训练好的VAE网络,我们可以生成新的样本或重构输入样本。 + +``` +IMAGE_SHAPE = (-1, 1, 32, 32) +generated_sample = vae.generate_sample(64, IMAGE_SHAPE) +for sample in ds_train.create_dict_iterator(): + sample_x = Tensor(sample['image'], dtype=mstype.float32) + reconstructed_sample = vae.reconstruct_sample(sample_x) +``` + +### DNN一键转换成BNN +对于不熟悉贝叶斯模型的DNN研究人员,MDP提供了高级API`TransformToBNN`,支持DNN模型一键转换成BNN模型。 +#### 定义DNN模型 +本例使用的DNN模型是LeNet。 + +``` +from mindspore.common.initializer import TruncatedNormal +import mindspore.nn as nn +import mindspore.ops.operations as P + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + """weight initial for conv layer""" + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + """weight initial for fc layer""" + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + """weight initial""" + return TruncatedNormal(0.02) + + +class LeNet5(nn.Cell): + """ + Lenet network + + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + Examples: + >>> LeNet5(num_class=10) + + """ + def __init__(self, num_class=10): + super(LeNet5, self).__init__() + self.num_class = num_class + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16 * 5 * 5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` +#### 定义损失函数和优化器 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,Adam作为优化器。 + +``` +network = LeNet5() + +# loss function definition +criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + +# optimization definition +optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) + +net_with_loss = WithLossCell(network, criterion) +train_network = TrainOneStepCell(net_with_loss, optimizer) +``` +#### 实例化TransformToBNN +`TransformToBNN`的`__init__`函数定义如下: + +``` +class TransformToBNN: + def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): + net_with_loss = trainable_dnn.network + self.optimizer = trainable_dnn.optimizer + self.backbone = net_with_loss.backbone_network + self.loss_fn = getattr(net_with_loss, "_loss_fn") + self.dnn_factor = dnn_factor + self.bnn_factor = bnn_factor + self.bnn_loss_file = None +``` +参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 +MindSpore中实例化`TransformToBNN`的代码如下: + +``` +from mindspore.nn.probability import transforms + +bnn_transformer = transforms.TransformToBNN(train_network, 60000, 0.000001) +``` +#### 功能一:转换整个模型 +`transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下: + +``` + def transform_to_bnn_model(self, + get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, + "out_channels": dp.out_channels, "activation": dp.activation}, + get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, + "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, + "stride": dp.stride, "has_bias": dp.has_bias, + "padding": dp.padding, "dilation": dp.dilation, + "group": dp.group}, + add_dense_args=None, + add_conv_args=None): + r""" + Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. + + Args: + get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. + get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, + "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. + add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. + add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. + + Returns: + Cell, a trainable BNN model wrapped by TrainOneStepCell. + """ +``` +参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 +在MindSpore中将整个DNN模型转换成BNN模型的代码如下: + +``` +train_bnn_network = bnn_transformer.transform_to_bnn_model() +``` +#### 功能二:转换指定类型的层 +`transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(nn.Dense或者nn.Conv2d)转换为对应的贝叶斯层。其定义如下: + +``` + def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): + r""" + Transform a specific type of layers in DNN model to corresponding BNN layer. + + Args: + dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are + nn.Dense, nn.Conv2d. + bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are + DenseReparameterization, ConvReparameterization. + get_args (dict): The arguments gotten from the DNN layer. Default: None. + add_args (dict): The new arguments added to BNN layer. Default: None. + + Returns: + Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. + """ +``` +参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 + +### 不确定性估计 +不确定性估计工具箱基于MindSpore Deep probability Programming (MDP),适用于主流的深度学习模型,如回归、分类、目标检测等。在推理阶段,利用不确定性估计工具箱,开发人员只需通过训练模型和训练数据集,指定需要估计的任务和样本,即可得到任意不确定性(aleatoric uncertainty)和认知不确定性(epistemic uncertainty)。基于不确定性信息,开发人员可以更好地理解模型和数据集。 +以分类任务为例,本例中使用的模型是LeNet,数据集为MNist,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。为了评估测试示例的不确定性,使用工具箱的方法如下: + +``` +from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation +from mindspore.train.serialization import load_checkpoint, load_param_into_net + +network = LeNet5() +param_dict = load_checkpoint('checkpoint_lenet.ckpt') +load_param_into_net(network, param_dict) +# get train and eval dataset +ds_train = create_dataset('workspace/mnist/train') +ds_eval = create_dataset('workspace/mnist/test') +evaluation = UncertaintyEvaluation(model=network, + train_dataset=ds_train, + task_type='classification', + num_classes=10, + epochs=1, + epi_uncer_model_path=None, + ale_uncer_model_path=None, + save_model=False) +for eval_data in ds_eval.create_dict_iterator(): + eval_data = Tensor(eval_data['image'], mstype.float32) + epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) + aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) +``` + + diff --git a/tutorials/source_zh_cn/advanced_use/differential_privacy.md b/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/differential_privacy.md rename to tutorials/training/source_zh_cn/advanced_use/differential_privacy.md index 6813d7f001..1418b34ae6 100644 --- a/tutorials/source_zh_cn/advanced_use/differential_privacy.md +++ b/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md @@ -1,358 +1,358 @@ -# 机器学习中的差分隐私 - -`Linux` `Ascend` `模型开发` `模型调优` `企业` `高级` - - - -- [机器学习中的差分隐私](#机器学习中的差分隐私) - - [概述](#概述) - - [实现阶段](#实现阶段) - - [导入需要的库文件](#导入需要的库文件) - - [参数配置](#参数配置) - - [预处理数据集](#预处理数据集) - - [建立模型](#建立模型) - - [引入差分隐私](#引入差分隐私) - - [引用](#引用) - - - - - -## 概述 - -差分隐私是一种保护用户数据隐私的机制。什么是隐私,隐私指的是单个用户的某些属性,一群用户的某一些属性可以不看做隐私。例如:“抽烟的人有更高的几率会得肺癌”,这个不泄露隐私,但是“张三抽烟,得了肺癌”,这个就泄露了张三的隐私。如果我们知道A医院,今天就诊的100个病人,其中有10个肺癌,并且我们知道了其中99个人的患病信息,就可以推测剩下一个人是否患有肺癌。这种窃取隐私的行为叫做差分攻击。差分隐私是防止差分攻击的方法,通过添加噪声,使得差别只有一条记录的两个数据集,通过模型推理获得相同结果的概率非常接近。也就是说,用了差分隐私后,攻击者知道的100个人的患病信息和99个人的患病信息几乎是一样的,从而无法推测出剩下1个人的患病情况。 - -**机器学习中的差分隐私** - -机器学习算法一般是用大量数据并更新模型参数,学习数据特征。在理想情况下,这些算法学习到一些泛化性较好的模型,例如“吸烟患者更容易得肺癌”,而不是特定的个体特征,例如“张三是个吸烟者,患有肺癌”。然而,机器学习算法并不会区分通用特征还是个体特征。当我们用机器学习来完成某个重要的任务,例如肺癌诊断,发布的机器学习模型,可能在无意中透露训练集中的个体特征,恶意攻击者可能从发布的模型获得关于张三的隐私信息,因此使用差分隐私技术来保护机器学习模型是十分必要的。 - -**差分隐私定义**[1]为: - -$Pr[\mathcal{K}(D)\in S] \le e^{\epsilon} Pr[\mathcal{K}(D') \in S]+\delta$ - -对于两个差别只有一条记录的数据集$D, D'$,通过随机算法$\mathcal{K}$,输出为结果集合$S$子集的概率满足上面公式,$\epsilon$为差分隐私预算,$\delta$ 为扰动,$\epsilon, \delta$越小,$\mathcal{K}$在$D, D'$上输出的数据分布越接近。 - -**差分隐私的度量** - -差分隐私可以用$\epsilon, \delta$ 度量。 - -- $\epsilon$:数据集中增加或者减少一条记录,引起的输出概率可以改变的上限。我们通常希望$\epsilon$是一个较小的常数,值越小表示差分隐私条件越严格。 -- $\delta$:用于限制模型行为任意改变的概率,通常设置为一个小的常数,推荐设置小于训练数据集大小的倒数。 - -**MindArmour实现的差分隐私** - -MindArmour的差分隐私模块Differential-Privacy,实现了差分隐私优化器。目前支持基于高斯机制的差分隐私SGD、Momentum、Adam优化器。其中,高斯噪声机制支持固定标准差的非自适应高斯噪声和随着时间或者迭代步数变化而变化的自适应高斯噪声,使用非自适应高斯噪声的优势在于可以严格控制差分隐私预算$\epsilon$,缺点是在模型训练过程中,每个Step添加的噪声量固定,在训练后期,较大的噪声使得模型收敛困难,甚至导致性能大幅下跌,模型可用性差。自适应噪声很好的解决了这个问题,在模型训练初期,添加的噪声量较大,随着模型逐渐收敛,噪声量逐渐减小,噪声对于模型可用性的影响减小。自适应噪声的缺点是不能严格控制差分隐私预算,在同样的初始值下,自适应差分隐私的$\epsilon$比非自适应的大。同时还提供RDP(R’enyi differential privacy)[2]用于监测差分隐私预算。 - -这里以LeNet模型,MNIST 数据集为例,说明如何在MindSpore上使用差分隐私优化器训练神经网络模型。 - -> 本例面向Ascend 910 AI处理器,你可以在这里下载完整的样例代码: - -## 实现阶段 - -### 导入需要的库文件 - -下列是我们需要的公共模块、MindSpore相关模块和差分隐私特性模块。 - -```python -import os -from easydict import EasyDict as edict - -import mindspore.nn as nn -from mindspore import context -from mindspore.train.callback import ModelCheckpoint -from mindspore.train.callback import CheckpointConfig -from mindspore.train.callback import LossMonitor -from mindspore.nn.metrics import Accuracy -from mindspore.train.serialization import load_checkpoint, load_param_into_net -import mindspore.dataset as ds -import mindspore.dataset.vision.c_transforms as CV -import mindspore.dataset.transforms.c_transforms as C -from mindspore.dataset.vision.import Inter -import mindspore.common.dtype as mstype - -from mindarmour.diff_privacy import DPModel -from mindarmour.diff_privacy import NoiseMechanismsFactory -from mindarmour.diff_privacy import ClipMechanismsFactory -from mindarmour.diff_privacy import PrivacyMonitorFactory -from mindarmour.utils.logger import LogUtil -from lenet5_net import LeNet5 -from lenet5_config import mnist_cfg as cfg - -LOGGER = LogUtil.get_instance() -LOGGER.set_level('INFO') -TAG = 'Lenet5_train' -``` - -### 参数配置 - -1. 设置运行环境、数据集路径、模型训练参数、checkpoint存储参数、差分隐私参数,`data_path`数据路径替换成你的数据集所在路径。更多配置可以参考。 - - ```python - cfg = edict({ - 'num_classes': 10, # the number of classes of model's output - 'lr': 0.01, # the learning rate of model's optimizer - 'momentum': 0.9, # the momentum value of model's optimizer - 'epoch_size': 10, # training epochs - 'batch_size': 256, # batch size for training - 'image_height': 32, # the height of training samples - 'image_width': 32, # the width of training samples - 'save_checkpoint_steps': 234, # the interval steps for saving checkpoint file of the model - 'keep_checkpoint_max': 10, # the maximum number of checkpoint files would be saved - 'device_target': 'Ascend', # device used - 'data_path': './MNIST_unzip', # the path of training and testing data set - 'dataset_sink_mode': False, # whether deliver all training data to device one time - 'micro_batches': 32, # the number of small batches split from an original batch - 'norm_bound': 1.0, # the clip bound of the gradients of model's training parameters - 'initial_noise_multiplier': 0.05, # the initial multiplication coefficient of the noise added to training - # parameters' gradients - 'noise_mechanisms': 'Gaussian', # the method of adding noise in gradients while training - 'clip_mechanisms': 'Gaussian', # the method of adaptive clipping gradients while training - 'clip_decay_policy': 'Linear', # Decay policy of adaptive clipping, decay_policy must be in ['Linear', 'Geometric']. - 'clip_learning_rate': 0.001, # Learning rate of update norm clip. - 'target_unclipped_quantile': 0.9, # Target quantile of norm clip. - 'fraction_stddev': 0.01, # The stddev of Gaussian normal which used in empirical_fraction. - 'optimizer': 'Momentum' # the base optimizer used for Differential privacy training - }) - ``` - -2. 配置必要的信息,包括环境信息、执行的模式。 - - ```python - context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) - ``` - - 详细的接口配置信息,请参见`context.set_context`接口说明。 - -### 预处理数据集 - -加载数据集并处理成MindSpore数据格式。 - -```python -def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, - num_parallel_workers=1, sparse=True): - """ - create dataset for training or testing - """ - # define dataset - ds1 = ds.MnistDataset(data_path) - - # define operation parameters - resize_height, resize_width = 32, 32 - rescale = 1.0 / 255.0 - shift = 0.0 - - # define map operations - resize_op = CV.Resize((resize_height, resize_width), - interpolation=Inter.LINEAR) - rescale_op = CV.Rescale(rescale, shift) - hwc2chw_op = CV.HWC2CHW() - type_cast_op = C.TypeCast(mstype.int32) - - # apply map operations on images - if not sparse: - one_hot_enco = C.OneHot(10) - ds1 = ds1.map(input_columns="label", operations=one_hot_enco, - num_parallel_workers=num_parallel_workers) - type_cast_op = C.TypeCast(mstype.float32) - ds1 = ds1.map(operations=type_cast_op, input_columns="label", - num_parallel_workers=num_parallel_workers) - ds1 = ds1.map(operations=resize_op, input_columns="image", - num_parallel_workers=num_parallel_workers) - ds1 = ds1.map(operations=rescale_op, input_columns="image", - num_parallel_workers=num_parallel_workers) - ds1 = ds1.map(operations=hwc2chw_op, input_columns="image", - num_parallel_workers=num_parallel_workers) - - # apply DatasetOps - buffer_size = 10000 - ds1 = ds1.shuffle(buffer_size=buffer_size) - ds1 = ds1.batch(batch_size, drop_remainder=True) - ds1 = ds1.repeat(repeat_size) - - return ds1 -``` - -### 建立模型 - -这里以LeNet模型为例,您也可以建立训练自己的模型。 - -```python -from mindspore import nn -from mindspore.common.initializer import TruncatedNormal - - -def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): - weight = weight_variable() - return nn.Conv2d(in_channels, out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, - weight_init=weight, has_bias=False, pad_mode="valid") - - -def fc_with_initialize(input_channels, out_channels): - weight = weight_variable() - bias = weight_variable() - return nn.Dense(input_channels, out_channels, weight, bias) - - -def weight_variable(): - return TruncatedNormal(0.05) - - -class LeNet5(nn.Cell): - """ - LeNet network - """ - def __init__(self): - super(LeNet5, self).__init__() - self.conv1 = conv(1, 6, 5) - self.conv2 = conv(6, 16, 5) - self.fc1 = fc_with_initialize(16*5*5, 120) - self.fc2 = fc_with_initialize(120, 84) - self.fc3 = fc_with_initialize(84, 10) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` - -加载LeNet网络,定义损失函数、配置checkpoint、用上述定义的数据加载函数`generate_mnist_dataset`载入数据。 - -```python -network = LeNet5() -net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") -config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps, - keep_checkpoint_max=cfg.keep_checkpoint_max) -ckpoint_cb = ModelCheckpoint(prefix="checkpoint_lenet", - directory='./trained_ckpt_file/', - config=config_ck) - -# get training dataset -ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), - cfg.batch_size) -``` - -### 引入差分隐私 - -1. 配置差分隐私优化器的参数。 - - - 判断`micro_batches`和`batch_size`参数是否符合要求,`batch_size`必须要整除`micro_batches`。 - - 实例化差分隐私工厂类。 - - 设置差分隐私的噪声机制,目前mechanisms支持固定标准差的高斯噪声机制:`Gaussian`和自适应调整标准差的高斯噪声机制:`AdaGaussian`。 - - 设置优化器类型,目前支持`SGD`、`Momentum`和`Adam`。 - - 设置差分隐私预算监测器RDP,用于观测每个step中的差分隐私预算$\epsilon$的变化。 - - ```python - if cfg.micro_batches and cfg.batch_size % cfg.micro_batches != 0: - raise ValueError( - "Number of micro_batches should divide evenly batch_size") - # Create a factory class of DP noise mechanisms, this method is adding noise - # in gradients while training. Initial_noise_multiplier is suggested to be - # greater than 1.0, otherwise the privacy budget would be huge, which means - # that the privacy protection effect is weak. Mechanisms can be 'Gaussian' - # or 'AdaGaussian', in which noise would be decayed with 'AdaGaussian' - # mechanism while be constant with 'Gaussian' mechanism. - noise_mech = NoiseMechanismsFactory().create(cfg.noise_mechanisms, - norm_bound=cfg.norm_bound, - initial_noise_multiplier=cfg.initial_noise_multiplier, - decay_policy=None) - # Create a factory class of clip mechanisms, this method is to adaptive clip - # gradients while training, decay_policy support 'Linear' and 'Geometric', - # learning_rate is the learning rate to update clip_norm, - # target_unclipped_quantile is the target quantile of norm clip, - # fraction_stddev is the stddev of Gaussian normal which used in - # empirical_fraction, the formula is - # $empirical_fraction + N(0, fraction_stddev)$. - clip_mech = ClipMechanismsFactory().create(cfg.clip_mechanisms, - decay_policy=cfg.clip_decay_policy, - learning_rate=cfg.clip_learning_rate, - target_unclipped_quantile=cfg.target_unclipped_quantile, - fraction_stddev=cfg.fraction_stddev) - net_opt = nn.Momentum(params=network.trainable_params(), - learning_rate=cfg.lr, momentum=cfg.momentum) - # Create a monitor for DP training. The function of the monitor is to - # compute and print the privacy budget(eps and delta) while training. - rdp_monitor = PrivacyMonitorFactory.create('rdp', - num_samples=60000, - batch_size=cfg.batch_size, - initial_noise_multiplier=cfg.initial_noise_multiplier, - per_print_times=234, - noise_decay_mode=None) - ``` - -2. 将LeNet模型包装成差分隐私模型,只需要将网络传入`DPModel`即可。 - - ```python - # Create the DP model for training. - model = DPModel(micro_batches=cfg.micro_batches, - norm_bound=cfg.norm_bound, - noise_mech=noise_mech, - clip_mech=clip_mech, - network=network, - loss_fn=net_loss, - optimizer=net_opt, - metrics={"Accuracy": Accuracy()}) - ``` - -3. 模型训练与测试。 - - ```python - LOGGER.info(TAG, "============== Starting Training ==============") - model.train(cfg['epoch_size'], ds_train, - callbacks=[ckpoint_cb, LossMonitor(), rdp_monitor], - dataset_sink_mode=cfg.dataset_sink_mode) - - LOGGER.info(TAG, "============== Starting Testing ==============") - ckpt_file_name = 'trained_ckpt_file/checkpoint_lenet-10_234.ckpt' - param_dict = load_checkpoint(ckpt_file_name) - load_param_into_net(network, param_dict) - ds_eval = generate_mnist_dataset(os.path.join(cfg.data_path, 'test'), - batch_size=cfg.batch_size) - acc = model.eval(ds_eval, dataset_sink_mode=False) - LOGGER.info(TAG, "============== Accuracy: %s ==============", acc) - ``` - -4. 运行命令。 - - 运行脚本,可在命令行输入命令: - - ```bash - python lenet_dp.py - ``` - - 其中`lenet5_dp.py`替换成你的脚本的名字。 - -5. 结果展示。 - - 不加差分隐私的LeNet模型精度稳定在99%,加了Gaussian噪声,自适应Clip的差分隐私LeNet模型收敛,精度稳定在95%左右。 - ``` - ============== Starting Training ============== - ... - ============== Starting Testing ============== - ... - ============== Accuracy: 0.9698 ============== - ``` - -### 引用 - -[1] C. Dwork and J. Lei. Differential privacy and robust statistics. In STOC, pages 371–380. ACM, 2009. - -[2] Ilya Mironov. Rényi differential privacy. In IEEE Computer Security Foundations Symposium, 2017. - -[3] Abadi, M. e. a., 2016. *Deep learning with differential privacy.* s.l.:Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security. - - - +# 机器学习中的差分隐私 + +`Linux` `Ascend` `模型开发` `模型调优` `企业` `高级` + + + +- [机器学习中的差分隐私](#机器学习中的差分隐私) + - [概述](#概述) + - [实现阶段](#实现阶段) + - [导入需要的库文件](#导入需要的库文件) + - [参数配置](#参数配置) + - [预处理数据集](#预处理数据集) + - [建立模型](#建立模型) + - [引入差分隐私](#引入差分隐私) + - [引用](#引用) + + + + + +## 概述 + +差分隐私是一种保护用户数据隐私的机制。什么是隐私,隐私指的是单个用户的某些属性,一群用户的某一些属性可以不看做隐私。例如:“抽烟的人有更高的几率会得肺癌”,这个不泄露隐私,但是“张三抽烟,得了肺癌”,这个就泄露了张三的隐私。如果我们知道A医院,今天就诊的100个病人,其中有10个肺癌,并且我们知道了其中99个人的患病信息,就可以推测剩下一个人是否患有肺癌。这种窃取隐私的行为叫做差分攻击。差分隐私是防止差分攻击的方法,通过添加噪声,使得差别只有一条记录的两个数据集,通过模型推理获得相同结果的概率非常接近。也就是说,用了差分隐私后,攻击者知道的100个人的患病信息和99个人的患病信息几乎是一样的,从而无法推测出剩下1个人的患病情况。 + +**机器学习中的差分隐私** + +机器学习算法一般是用大量数据并更新模型参数,学习数据特征。在理想情况下,这些算法学习到一些泛化性较好的模型,例如“吸烟患者更容易得肺癌”,而不是特定的个体特征,例如“张三是个吸烟者,患有肺癌”。然而,机器学习算法并不会区分通用特征还是个体特征。当我们用机器学习来完成某个重要的任务,例如肺癌诊断,发布的机器学习模型,可能在无意中透露训练集中的个体特征,恶意攻击者可能从发布的模型获得关于张三的隐私信息,因此使用差分隐私技术来保护机器学习模型是十分必要的。 + +**差分隐私定义**[1]为: + +$Pr[\mathcal{K}(D)\in S] \le e^{\epsilon} Pr[\mathcal{K}(D') \in S]+\delta$ + +对于两个差别只有一条记录的数据集$D, D'$,通过随机算法$\mathcal{K}$,输出为结果集合$S$子集的概率满足上面公式,$\epsilon$为差分隐私预算,$\delta$ 为扰动,$\epsilon, \delta$越小,$\mathcal{K}$在$D, D'$上输出的数据分布越接近。 + +**差分隐私的度量** + +差分隐私可以用$\epsilon, \delta$ 度量。 + +- $\epsilon$:数据集中增加或者减少一条记录,引起的输出概率可以改变的上限。我们通常希望$\epsilon$是一个较小的常数,值越小表示差分隐私条件越严格。 +- $\delta$:用于限制模型行为任意改变的概率,通常设置为一个小的常数,推荐设置小于训练数据集大小的倒数。 + +**MindArmour实现的差分隐私** + +MindArmour的差分隐私模块Differential-Privacy,实现了差分隐私优化器。目前支持基于高斯机制的差分隐私SGD、Momentum、Adam优化器。其中,高斯噪声机制支持固定标准差的非自适应高斯噪声和随着时间或者迭代步数变化而变化的自适应高斯噪声,使用非自适应高斯噪声的优势在于可以严格控制差分隐私预算$\epsilon$,缺点是在模型训练过程中,每个Step添加的噪声量固定,在训练后期,较大的噪声使得模型收敛困难,甚至导致性能大幅下跌,模型可用性差。自适应噪声很好的解决了这个问题,在模型训练初期,添加的噪声量较大,随着模型逐渐收敛,噪声量逐渐减小,噪声对于模型可用性的影响减小。自适应噪声的缺点是不能严格控制差分隐私预算,在同样的初始值下,自适应差分隐私的$\epsilon$比非自适应的大。同时还提供RDP(R’enyi differential privacy)[2]用于监测差分隐私预算。 + +这里以LeNet模型,MNIST 数据集为例,说明如何在MindSpore上使用差分隐私优化器训练神经网络模型。 + +> 本例面向Ascend 910 AI处理器,你可以在这里下载完整的样例代码: + +## 实现阶段 + +### 导入需要的库文件 + +下列是我们需要的公共模块、MindSpore相关模块和差分隐私特性模块。 + +```python +import os +from easydict import EasyDict as edict + +import mindspore.nn as nn +from mindspore import context +from mindspore.train.callback import ModelCheckpoint +from mindspore.train.callback import CheckpointConfig +from mindspore.train.callback import LossMonitor +from mindspore.nn.metrics import Accuracy +from mindspore.train.serialization import load_checkpoint, load_param_into_net +import mindspore.dataset as ds +import mindspore.dataset.vision.c_transforms as CV +import mindspore.dataset.transforms.c_transforms as C +from mindspore.dataset.vision.import Inter +import mindspore.common.dtype as mstype + +from mindarmour.diff_privacy import DPModel +from mindarmour.diff_privacy import NoiseMechanismsFactory +from mindarmour.diff_privacy import ClipMechanismsFactory +from mindarmour.diff_privacy import PrivacyMonitorFactory +from mindarmour.utils.logger import LogUtil +from lenet5_net import LeNet5 +from lenet5_config import mnist_cfg as cfg + +LOGGER = LogUtil.get_instance() +LOGGER.set_level('INFO') +TAG = 'Lenet5_train' +``` + +### 参数配置 + +1. 设置运行环境、数据集路径、模型训练参数、checkpoint存储参数、差分隐私参数,`data_path`数据路径替换成你的数据集所在路径。更多配置可以参考。 + + ```python + cfg = edict({ + 'num_classes': 10, # the number of classes of model's output + 'lr': 0.01, # the learning rate of model's optimizer + 'momentum': 0.9, # the momentum value of model's optimizer + 'epoch_size': 10, # training epochs + 'batch_size': 256, # batch size for training + 'image_height': 32, # the height of training samples + 'image_width': 32, # the width of training samples + 'save_checkpoint_steps': 234, # the interval steps for saving checkpoint file of the model + 'keep_checkpoint_max': 10, # the maximum number of checkpoint files would be saved + 'device_target': 'Ascend', # device used + 'data_path': './MNIST_unzip', # the path of training and testing data set + 'dataset_sink_mode': False, # whether deliver all training data to device one time + 'micro_batches': 32, # the number of small batches split from an original batch + 'norm_bound': 1.0, # the clip bound of the gradients of model's training parameters + 'initial_noise_multiplier': 0.05, # the initial multiplication coefficient of the noise added to training + # parameters' gradients + 'noise_mechanisms': 'Gaussian', # the method of adding noise in gradients while training + 'clip_mechanisms': 'Gaussian', # the method of adaptive clipping gradients while training + 'clip_decay_policy': 'Linear', # Decay policy of adaptive clipping, decay_policy must be in ['Linear', 'Geometric']. + 'clip_learning_rate': 0.001, # Learning rate of update norm clip. + 'target_unclipped_quantile': 0.9, # Target quantile of norm clip. + 'fraction_stddev': 0.01, # The stddev of Gaussian normal which used in empirical_fraction. + 'optimizer': 'Momentum' # the base optimizer used for Differential privacy training + }) + ``` + +2. 配置必要的信息,包括环境信息、执行的模式。 + + ```python + context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) + ``` + + 详细的接口配置信息,请参见`context.set_context`接口说明。 + +### 预处理数据集 + +加载数据集并处理成MindSpore数据格式。 + +```python +def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1, sparse=True): + """ + create dataset for training or testing + """ + # define dataset + ds1 = ds.MnistDataset(data_path) + + # define operation parameters + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + + # define map operations + resize_op = CV.Resize((resize_height, resize_width), + interpolation=Inter.LINEAR) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = C.TypeCast(mstype.int32) + + # apply map operations on images + if not sparse: + one_hot_enco = C.OneHot(10) + ds1 = ds1.map(input_columns="label", operations=one_hot_enco, + num_parallel_workers=num_parallel_workers) + type_cast_op = C.TypeCast(mstype.float32) + ds1 = ds1.map(operations=type_cast_op, input_columns="label", + num_parallel_workers=num_parallel_workers) + ds1 = ds1.map(operations=resize_op, input_columns="image", + num_parallel_workers=num_parallel_workers) + ds1 = ds1.map(operations=rescale_op, input_columns="image", + num_parallel_workers=num_parallel_workers) + ds1 = ds1.map(operations=hwc2chw_op, input_columns="image", + num_parallel_workers=num_parallel_workers) + + # apply DatasetOps + buffer_size = 10000 + ds1 = ds1.shuffle(buffer_size=buffer_size) + ds1 = ds1.batch(batch_size, drop_remainder=True) + ds1 = ds1.repeat(repeat_size) + + return ds1 +``` + +### 建立模型 + +这里以LeNet模型为例,您也可以建立训练自己的模型。 + +```python +from mindspore import nn +from mindspore.common.initializer import TruncatedNormal + + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + return TruncatedNormal(0.05) + + +class LeNet5(nn.Cell): + """ + LeNet network + """ + def __init__(self): + super(LeNet5, self).__init__() + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16*5*5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, 10) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` + +加载LeNet网络,定义损失函数、配置checkpoint、用上述定义的数据加载函数`generate_mnist_dataset`载入数据。 + +```python +network = LeNet5() +net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") +config_ck = CheckpointConfig(save_checkpoint_steps=cfg.save_checkpoint_steps, + keep_checkpoint_max=cfg.keep_checkpoint_max) +ckpoint_cb = ModelCheckpoint(prefix="checkpoint_lenet", + directory='./trained_ckpt_file/', + config=config_ck) + +# get training dataset +ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), + cfg.batch_size) +``` + +### 引入差分隐私 + +1. 配置差分隐私优化器的参数。 + + - 判断`micro_batches`和`batch_size`参数是否符合要求,`batch_size`必须要整除`micro_batches`。 + - 实例化差分隐私工厂类。 + - 设置差分隐私的噪声机制,目前mechanisms支持固定标准差的高斯噪声机制:`Gaussian`和自适应调整标准差的高斯噪声机制:`AdaGaussian`。 + - 设置优化器类型,目前支持`SGD`、`Momentum`和`Adam`。 + - 设置差分隐私预算监测器RDP,用于观测每个step中的差分隐私预算$\epsilon$的变化。 + + ```python + if cfg.micro_batches and cfg.batch_size % cfg.micro_batches != 0: + raise ValueError( + "Number of micro_batches should divide evenly batch_size") + # Create a factory class of DP noise mechanisms, this method is adding noise + # in gradients while training. Initial_noise_multiplier is suggested to be + # greater than 1.0, otherwise the privacy budget would be huge, which means + # that the privacy protection effect is weak. Mechanisms can be 'Gaussian' + # or 'AdaGaussian', in which noise would be decayed with 'AdaGaussian' + # mechanism while be constant with 'Gaussian' mechanism. + noise_mech = NoiseMechanismsFactory().create(cfg.noise_mechanisms, + norm_bound=cfg.norm_bound, + initial_noise_multiplier=cfg.initial_noise_multiplier, + decay_policy=None) + # Create a factory class of clip mechanisms, this method is to adaptive clip + # gradients while training, decay_policy support 'Linear' and 'Geometric', + # learning_rate is the learning rate to update clip_norm, + # target_unclipped_quantile is the target quantile of norm clip, + # fraction_stddev is the stddev of Gaussian normal which used in + # empirical_fraction, the formula is + # $empirical_fraction + N(0, fraction_stddev)$. + clip_mech = ClipMechanismsFactory().create(cfg.clip_mechanisms, + decay_policy=cfg.clip_decay_policy, + learning_rate=cfg.clip_learning_rate, + target_unclipped_quantile=cfg.target_unclipped_quantile, + fraction_stddev=cfg.fraction_stddev) + net_opt = nn.Momentum(params=network.trainable_params(), + learning_rate=cfg.lr, momentum=cfg.momentum) + # Create a monitor for DP training. The function of the monitor is to + # compute and print the privacy budget(eps and delta) while training. + rdp_monitor = PrivacyMonitorFactory.create('rdp', + num_samples=60000, + batch_size=cfg.batch_size, + initial_noise_multiplier=cfg.initial_noise_multiplier, + per_print_times=234, + noise_decay_mode=None) + ``` + +2. 将LeNet模型包装成差分隐私模型,只需要将网络传入`DPModel`即可。 + + ```python + # Create the DP model for training. + model = DPModel(micro_batches=cfg.micro_batches, + norm_bound=cfg.norm_bound, + noise_mech=noise_mech, + clip_mech=clip_mech, + network=network, + loss_fn=net_loss, + optimizer=net_opt, + metrics={"Accuracy": Accuracy()}) + ``` + +3. 模型训练与测试。 + + ```python + LOGGER.info(TAG, "============== Starting Training ==============") + model.train(cfg['epoch_size'], ds_train, + callbacks=[ckpoint_cb, LossMonitor(), rdp_monitor], + dataset_sink_mode=cfg.dataset_sink_mode) + + LOGGER.info(TAG, "============== Starting Testing ==============") + ckpt_file_name = 'trained_ckpt_file/checkpoint_lenet-10_234.ckpt' + param_dict = load_checkpoint(ckpt_file_name) + load_param_into_net(network, param_dict) + ds_eval = generate_mnist_dataset(os.path.join(cfg.data_path, 'test'), + batch_size=cfg.batch_size) + acc = model.eval(ds_eval, dataset_sink_mode=False) + LOGGER.info(TAG, "============== Accuracy: %s ==============", acc) + ``` + +4. 运行命令。 + + 运行脚本,可在命令行输入命令: + + ```bash + python lenet_dp.py + ``` + + 其中`lenet5_dp.py`替换成你的脚本的名字。 + +5. 结果展示。 + + 不加差分隐私的LeNet模型精度稳定在99%,加了Gaussian噪声,自适应Clip的差分隐私LeNet模型收敛,精度稳定在95%左右。 + ``` + ============== Starting Training ============== + ... + ============== Starting Testing ============== + ... + ============== Accuracy: 0.9698 ============== + ``` + +### 引用 + +[1] C. Dwork and J. Lei. Differential privacy and robust statistics. In STOC, pages 371–380. ACM, 2009. + +[2] Ilya Mironov. Rényi differential privacy. In IEEE Computer Security Foundations Symposium, 2017. + +[3] Abadi, M. e. a., 2016. *Deep learning with differential privacy.* s.l.:Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security. + + + diff --git a/tutorials/source_zh_cn/advanced_use/distributed_training_ascend.md b/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/distributed_training_ascend.md rename to tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md diff --git a/tutorials/source_zh_cn/advanced_use/distributed_training_gpu.md b/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/distributed_training_gpu.md rename to tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md diff --git a/tutorials/source_zh_cn/advanced_use/distributed_training_tutorials.rst b/tutorials/training/source_zh_cn/advanced_use/distributed_training_tutorials.rst similarity index 100% rename from tutorials/source_zh_cn/advanced_use/distributed_training_tutorials.rst rename to tutorials/training/source_zh_cn/advanced_use/distributed_training_tutorials.rst diff --git a/tutorials/source_zh_cn/advanced_use/fuzzer.md b/tutorials/training/source_zh_cn/advanced_use/fuzzer.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/fuzzer.md rename to tutorials/training/source_zh_cn/advanced_use/fuzzer.md index 516b9a7467..a1740ae530 100644 --- a/tutorials/source_zh_cn/advanced_use/fuzzer.md +++ b/tutorials/training/source_zh_cn/advanced_use/fuzzer.md @@ -1,195 +1,195 @@ -# AI模型安全测试 - -`Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` - - - -- [AI模型安全测试](#ai模型安全测试) - - [概述](#概述) - - [实现阶段](#实现阶段) - - [导入需要的库文件](#引入相关包) - - [参数配置](#参数配置) - - [运用Fuzzer](#运用Fuzzer) - - -   - -## 概述 - -传统软件的决策逻辑由代码逻辑决定,传统软件通过代码行覆盖率来判断当前测试是否充分,理想情况下覆盖率越高,代码测试越充分。然而,对于深度神经网络而言,程序的决策逻辑由训练数据、网络模型结构和参数通过某种黑盒机制决定,代码行覆盖率已不足以评估测试的充分性。需要根据深度网络的特点选择更为适合的测试评价准则,指导神经网络进行更为充分的测试,发现更多的边缘错误用例,从而确保模型的通用性、鲁棒性。 - -MindArmour的Fuzzer模块以神经元覆盖率作为测试评价准则。神经元覆盖率,是指通过一组输入观察到的、激活的神经元数量和神经元输出值的范围。我们通过神经元覆盖率来指导输入变异,让输入能够激活更多的神经元,神经元值的分布范围更广,从而探索不同类型的模型输出结果、错误行为。 - -这里以LeNet模型,MNIST数据集为例,说明如何使用Fuzzer。 - -> 本例面向CPU、GPU、Ascend 910 AI处理器,你可以在这里下载完整的样例代码: - -## 实现阶段 - -### 导入需要的库文件 - -下列是我们需要的公共模块、MindSpore相关模块和Fuzzer特性模块,以及配置日志标签和日志等级。 - -```python -import sys - -import numpy as np -from mindspore import Model -from mindspore import context -from mindspore.train.serialization import load_checkpoint, load_param_into_net - -from lenet5_net import LeNet5 -from mindarmour.fuzzing.fuzzing import Fuzzer -from mindarmour.fuzzing.model_coverage_metrics import ModelCoverageMetrics -from mindarmour.utils.logger import LogUtil - -LOGGER = LogUtil.get_instance() -TAG = 'Fuzz_test' -LOGGER.set_level('INFO') -``` - -### 参数配置 - -配置必要的信息,包括环境信息、执行的模式。 - -```python -context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) -``` - -详细的接口配置信息,请参见`context.set_context`接口说明。 - -### 运用Fuzzer - -1. 建立LeNet模型,加载MNIST数据集,操作同[模型安全]() - - ```python - ... - # Lenet model - model = Model(net) - # get training data - data_list = "./MNIST_unzip/train" - batch_size = 32 - ds = generate_mnist_dataset(data_list, batch_size, sparse=False) - train_images = [] - for data in ds.create_tuple_iterator(): - images = data[0].astype(np.float32) - train_images.append(images) - train_images = np.concatenate(train_images, axis=0) - - # get test data - data_list = "./MNIST_unzip/test" - batch_size = 32 - ds = generate_mnist_dataset(data_list, batch_size, sparse=False) - test_images = [] - test_labels = [] - for data in ds.create_tuple_iterator(): - images = data[0].astype(np.float32) - labels = data[1] - test_images.append(images) - test_labels.append(labels) - test_images = np.concatenate(test_images, axis=0) - test_labels = np.concatenate(test_labels, axis=0) - ``` - -2. Fuzzer参数配置。 - - 设置数据变异方法及参数。目前支持的数据变异方法包含三类: - - - 图像仿射变换方法:Translate、Scale、Shear、Rotate。 - - 基于图像像素值变化的方法: Contrast、Brightness、Blur、Noise。 - - 基于对抗攻击的白盒、黑盒对抗样本生成方法:FGSM、PGD、MDIIM。 - - 数据变异方法一定要包含基于图像像素值变化的方法。 - - 前两种图像变化方法的可配置参数,以及推荐参数范围请参考:对应的类方法,也可以均设置为`'auto_param': True`,变异参数将在推荐范围内随机生成。 - - 基于对抗攻击方法的参数配置请参考对应的攻击方法类。 - - ```python - mutate_config = [{'method': 'Blur', - 'params': {'auto_param': True}}, - {'method': 'Contrast', - 'params': {'auto_param': True}}, - {'method': 'Translate', - 'params': {'auto_param': True}}, - {'method': 'Brightness', - 'params': {'auto_param': True}}, - {'method': 'Noise', - 'params': {'auto_param': True}}, - {'method': 'Scale', - 'params': {'auto_param': True}}, - {'method': 'Shear', - 'params': {'auto_param': True}}, - {'method': 'FGSM', - 'params': {'eps': 0.3, 'alpha': 0.1}} - ] - ``` - - 设置评价指标,目前支持5种评价指标,包括: - - 通用评价指标:accuracy。 - - 神经元覆盖率指标:kmnc, nbc,snac。 - - 对抗攻击评价指标:attack_success_rate。 - 也可以设置为‘auto’,默认使用所有评价指标。 - - ```python - eval_metrics =['accuracy', 'kmnc', 'attack_success_rate'] - ``` - -3. 初始化种子队列,种子队列中的每个种子,包含3个值:原始图片、图片标签。 - - ```python - # make initial seeds - initial_seeds = [] - for img, label in zip(test_images, test_labels): - initial_seeds.append([img, label]) - initial_seeds = initial_seeds[:100] - ``` - -4. 测试Fuzz测试前的神经元覆盖率。 - - ```python - segmented_num=1000 - neuron_num=10 - model_coverage_test = ModelCoverageMetrics(model, segmented_num, neuron_num, train_images) - model_coverage_test.calculate_coverage(np.array(test_images[:100]).astype(np.float32)) - LOGGER.info(TAG, 'KMNC of this test is : %s', model_coverage_test.get_kmnc()) - ``` - - 结果: - - ```python - KMNC of this test is : 0.0851 - ``` - -5. Fuzz测试。 - - ```python - model_fuzz_test = Fuzzer(model, train_images, neuron_num, segmented_num) - _, _, _, _, metrics = model_fuzz_test.fuzzing(mutate_config, initial_seeds, eval_metrics=eval_metrics) - ``` - -6. 实验结果。 - - ```python - if metrics: - for key in metrics: - LOGGER.info(TAG, key + ': %s', metrics[key]) - ``` - - Fuzz测试后结果如下: - - ```python - Accuracy: 0.7929 - Attack_success_rate: 0.3939 - Neural_coverage_KMNC: 0.4797 - ``` - - Fuzz测试前种子的KMNC神经元覆盖率为8.5%,Fuzz后,KMNC神经元覆盖率为47.97%,神经元覆盖率提升,样本的多样性提升。Fuzz后,模型对于Fuzz生成样本的准确率为79.29%,使用了对抗攻击方法的样本,攻击成功率为47.97%。由于初始化种子、变异方法和相应的参数均为随机选择的,结果有一定的浮动是正常的。 - - 原始图片: - - ![fuzz_seed](./images/fuzz_seed.png) - -​ Fuzz生成的变异图片: - +# AI模型安全测试 + +`Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` + + + +- [AI模型安全测试](#ai模型安全测试) + - [概述](#概述) + - [实现阶段](#实现阶段) + - [导入需要的库文件](#引入相关包) + - [参数配置](#参数配置) + - [运用Fuzzer](#运用Fuzzer) + + +   + +## 概述 + +传统软件的决策逻辑由代码逻辑决定,传统软件通过代码行覆盖率来判断当前测试是否充分,理想情况下覆盖率越高,代码测试越充分。然而,对于深度神经网络而言,程序的决策逻辑由训练数据、网络模型结构和参数通过某种黑盒机制决定,代码行覆盖率已不足以评估测试的充分性。需要根据深度网络的特点选择更为适合的测试评价准则,指导神经网络进行更为充分的测试,发现更多的边缘错误用例,从而确保模型的通用性、鲁棒性。 + +MindArmour的Fuzzer模块以神经元覆盖率作为测试评价准则。神经元覆盖率,是指通过一组输入观察到的、激活的神经元数量和神经元输出值的范围。我们通过神经元覆盖率来指导输入变异,让输入能够激活更多的神经元,神经元值的分布范围更广,从而探索不同类型的模型输出结果、错误行为。 + +这里以LeNet模型,MNIST数据集为例,说明如何使用Fuzzer。 + +> 本例面向CPU、GPU、Ascend 910 AI处理器,你可以在这里下载完整的样例代码: + +## 实现阶段 + +### 导入需要的库文件 + +下列是我们需要的公共模块、MindSpore相关模块和Fuzzer特性模块,以及配置日志标签和日志等级。 + +```python +import sys + +import numpy as np +from mindspore import Model +from mindspore import context +from mindspore.train.serialization import load_checkpoint, load_param_into_net + +from lenet5_net import LeNet5 +from mindarmour.fuzzing.fuzzing import Fuzzer +from mindarmour.fuzzing.model_coverage_metrics import ModelCoverageMetrics +from mindarmour.utils.logger import LogUtil + +LOGGER = LogUtil.get_instance() +TAG = 'Fuzz_test' +LOGGER.set_level('INFO') +``` + +### 参数配置 + +配置必要的信息,包括环境信息、执行的模式。 + +```python +context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) +``` + +详细的接口配置信息,请参见`context.set_context`接口说明。 + +### 运用Fuzzer + +1. 建立LeNet模型,加载MNIST数据集,操作同[模型安全]() + + ```python + ... + # Lenet model + model = Model(net) + # get training data + data_list = "./MNIST_unzip/train" + batch_size = 32 + ds = generate_mnist_dataset(data_list, batch_size, sparse=False) + train_images = [] + for data in ds.create_tuple_iterator(): + images = data[0].astype(np.float32) + train_images.append(images) + train_images = np.concatenate(train_images, axis=0) + + # get test data + data_list = "./MNIST_unzip/test" + batch_size = 32 + ds = generate_mnist_dataset(data_list, batch_size, sparse=False) + test_images = [] + test_labels = [] + for data in ds.create_tuple_iterator(): + images = data[0].astype(np.float32) + labels = data[1] + test_images.append(images) + test_labels.append(labels) + test_images = np.concatenate(test_images, axis=0) + test_labels = np.concatenate(test_labels, axis=0) + ``` + +2. Fuzzer参数配置。 + + 设置数据变异方法及参数。目前支持的数据变异方法包含三类: + + - 图像仿射变换方法:Translate、Scale、Shear、Rotate。 + - 基于图像像素值变化的方法: Contrast、Brightness、Blur、Noise。 + - 基于对抗攻击的白盒、黑盒对抗样本生成方法:FGSM、PGD、MDIIM。 + + 数据变异方法一定要包含基于图像像素值变化的方法。 + + 前两种图像变化方法的可配置参数,以及推荐参数范围请参考:对应的类方法,也可以均设置为`'auto_param': True`,变异参数将在推荐范围内随机生成。 + + 基于对抗攻击方法的参数配置请参考对应的攻击方法类。 + + ```python + mutate_config = [{'method': 'Blur', + 'params': {'auto_param': True}}, + {'method': 'Contrast', + 'params': {'auto_param': True}}, + {'method': 'Translate', + 'params': {'auto_param': True}}, + {'method': 'Brightness', + 'params': {'auto_param': True}}, + {'method': 'Noise', + 'params': {'auto_param': True}}, + {'method': 'Scale', + 'params': {'auto_param': True}}, + {'method': 'Shear', + 'params': {'auto_param': True}}, + {'method': 'FGSM', + 'params': {'eps': 0.3, 'alpha': 0.1}} + ] + ``` + + 设置评价指标,目前支持5种评价指标,包括: + - 通用评价指标:accuracy。 + - 神经元覆盖率指标:kmnc, nbc,snac。 + - 对抗攻击评价指标:attack_success_rate。 + 也可以设置为‘auto’,默认使用所有评价指标。 + + ```python + eval_metrics =['accuracy', 'kmnc', 'attack_success_rate'] + ``` + +3. 初始化种子队列,种子队列中的每个种子,包含3个值:原始图片、图片标签。 + + ```python + # make initial seeds + initial_seeds = [] + for img, label in zip(test_images, test_labels): + initial_seeds.append([img, label]) + initial_seeds = initial_seeds[:100] + ``` + +4. 测试Fuzz测试前的神经元覆盖率。 + + ```python + segmented_num=1000 + neuron_num=10 + model_coverage_test = ModelCoverageMetrics(model, segmented_num, neuron_num, train_images) + model_coverage_test.calculate_coverage(np.array(test_images[:100]).astype(np.float32)) + LOGGER.info(TAG, 'KMNC of this test is : %s', model_coverage_test.get_kmnc()) + ``` + + 结果: + + ```python + KMNC of this test is : 0.0851 + ``` + +5. Fuzz测试。 + + ```python + model_fuzz_test = Fuzzer(model, train_images, neuron_num, segmented_num) + _, _, _, _, metrics = model_fuzz_test.fuzzing(mutate_config, initial_seeds, eval_metrics=eval_metrics) + ``` + +6. 实验结果。 + + ```python + if metrics: + for key in metrics: + LOGGER.info(TAG, key + ': %s', metrics[key]) + ``` + + Fuzz测试后结果如下: + + ```python + Accuracy: 0.7929 + Attack_success_rate: 0.3939 + Neural_coverage_KMNC: 0.4797 + ``` + + Fuzz测试前种子的KMNC神经元覆盖率为8.5%,Fuzz后,KMNC神经元覆盖率为47.97%,神经元覆盖率提升,样本的多样性提升。Fuzz后,模型对于Fuzz生成样本的准确率为79.29%,使用了对抗攻击方法的样本,攻击成功率为47.97%。由于初始化种子、变异方法和相应的参数均为随机选择的,结果有一定的浮动是正常的。 + + 原始图片: + + ![fuzz_seed](./images/fuzz_seed.png) + +​ Fuzz生成的变异图片: + ![fuzz_res](./images/fuzz_res.png) \ No newline at end of file diff --git a/tutorials/source_zh_cn/advanced_use/gradient_accumulation.md b/tutorials/training/source_zh_cn/advanced_use/gradient_accumulation.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/gradient_accumulation.md rename to tutorials/training/source_zh_cn/advanced_use/gradient_accumulation.md diff --git a/tutorials/source_zh_cn/advanced_use/graph_kernel_fusion.md b/tutorials/training/source_zh_cn/advanced_use/graph_kernel_fusion.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/graph_kernel_fusion.md rename to tutorials/training/source_zh_cn/advanced_use/graph_kernel_fusion.md diff --git a/tutorials/source_zh_cn/advanced_use/host_device_training.md b/tutorials/training/source_zh_cn/advanced_use/host_device_training.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/host_device_training.md rename to tutorials/training/source_zh_cn/advanced_use/host_device_training.md diff --git a/tutorials/source_zh_cn/advanced_use/hub_tutorial.md b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/hub_tutorial.md rename to tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md index 5969c90d63..3467a32d8a 100644 --- a/tutorials/source_zh_cn/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md @@ -1,179 +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) - ``` +## 使用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) + ``` diff --git a/tutorials/source_zh_cn/advanced_use/images/adv_attack_result.png b/tutorials/training/source_zh_cn/advanced_use/images/adv_attack_result.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/adv_attack_result.png rename to tutorials/training/source_zh_cn/advanced_use/images/adv_attack_result.png diff --git a/tutorials/source_zh_cn/advanced_use/images/auto_augmentation.png b/tutorials/training/source_zh_cn/advanced_use/images/auto_augmentation.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/auto_augmentation.png rename to tutorials/training/source_zh_cn/advanced_use/images/auto_augmentation.png diff --git a/tutorials/source_zh_cn/advanced_use/images/bert_model.PNG b/tutorials/training/source_zh_cn/advanced_use/images/bert_model.PNG similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/bert_model.PNG rename to tutorials/training/source_zh_cn/advanced_use/images/bert_model.PNG diff --git a/tutorials/source_zh_cn/advanced_use/images/checkpoint_integration_process.jpg b/tutorials/training/source_zh_cn/advanced_use/images/checkpoint_integration_process.jpg similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/checkpoint_integration_process.jpg rename to tutorials/training/source_zh_cn/advanced_use/images/checkpoint_integration_process.jpg diff --git a/tutorials/source_zh_cn/advanced_use/images/cifar10.jpg b/tutorials/training/source_zh_cn/advanced_use/images/cifar10.jpg similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/cifar10.jpg rename to tutorials/training/source_zh_cn/advanced_use/images/cifar10.jpg diff --git a/tutorials/source_zh_cn/advanced_use/images/cifar10_c_transforms.png b/tutorials/training/source_zh_cn/advanced_use/images/cifar10_c_transforms.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/cifar10_c_transforms.png rename to tutorials/training/source_zh_cn/advanced_use/images/cifar10_c_transforms.png diff --git a/tutorials/source_zh_cn/advanced_use/images/cloud_train_job1.png b/tutorials/training/source_zh_cn/advanced_use/images/cloud_train_job1.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/cloud_train_job1.png rename to tutorials/training/source_zh_cn/advanced_use/images/cloud_train_job1.png diff --git a/tutorials/source_zh_cn/advanced_use/images/cloud_train_job2.png b/tutorials/training/source_zh_cn/advanced_use/images/cloud_train_job2.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/cloud_train_job2.png rename to tutorials/training/source_zh_cn/advanced_use/images/cloud_train_job2.png diff --git a/tutorials/source_zh_cn/advanced_use/images/compose.png b/tutorials/training/source_zh_cn/advanced_use/images/compose.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/compose.png rename to tutorials/training/source_zh_cn/advanced_use/images/compose.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_chart.png b/tutorials/training/source_zh_cn/advanced_use/images/data_chart.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_chart.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_chart.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_conversion_concept.png b/tutorials/training/source_zh_cn/advanced_use/images/data_conversion_concept.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_conversion_concept.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_conversion_concept.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_enhancement_performance_scheme.png b/tutorials/training/source_zh_cn/advanced_use/images/data_enhancement_performance_scheme.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_enhancement_performance_scheme.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_enhancement_performance_scheme.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_function.png b/tutorials/training/source_zh_cn/advanced_use/images/data_function.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_function.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_function.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_label.png b/tutorials/training/source_zh_cn/advanced_use/images/data_label.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_label.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_label.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_loading_performance_scheme.png b/tutorials/training/source_zh_cn/advanced_use/images/data_loading_performance_scheme.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_loading_performance_scheme.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_loading_performance_scheme.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_op_profile.png b/tutorials/training/source_zh_cn/advanced_use/images/data_op_profile.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_op_profile.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_op_profile.png diff --git a/tutorials/source_zh_cn/advanced_use/images/data_table.png b/tutorials/training/source_zh_cn/advanced_use/images/data_table.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/data_table.png rename to tutorials/training/source_zh_cn/advanced_use/images/data_table.png diff --git a/tutorials/source_zh_cn/advanced_use/images/dataset_pipeline.png b/tutorials/training/source_zh_cn/advanced_use/images/dataset_pipeline.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/dataset_pipeline.png rename to tutorials/training/source_zh_cn/advanced_use/images/dataset_pipeline.png diff --git a/tutorials/source_zh_cn/advanced_use/images/finetune.PNG b/tutorials/training/source_zh_cn/advanced_use/images/finetune.PNG similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/finetune.PNG rename to tutorials/training/source_zh_cn/advanced_use/images/finetune.PNG diff --git a/tutorials/source_zh_cn/advanced_use/images/fuzz_res.png b/tutorials/training/source_zh_cn/advanced_use/images/fuzz_res.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/fuzz_res.png rename to tutorials/training/source_zh_cn/advanced_use/images/fuzz_res.png diff --git a/tutorials/source_zh_cn/advanced_use/images/fuzz_seed.png b/tutorials/training/source_zh_cn/advanced_use/images/fuzz_seed.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/fuzz_seed.png rename to tutorials/training/source_zh_cn/advanced_use/images/fuzz_seed.png diff --git a/tutorials/source_zh_cn/advanced_use/images/gpu_activity_profiler.png b/tutorials/training/source_zh_cn/advanced_use/images/gpu_activity_profiler.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/gpu_activity_profiler.png rename to tutorials/training/source_zh_cn/advanced_use/images/gpu_activity_profiler.png diff --git a/tutorials/source_zh_cn/advanced_use/images/gpu_op_ui_profiler.png b/tutorials/training/source_zh_cn/advanced_use/images/gpu_op_ui_profiler.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/gpu_op_ui_profiler.png rename to tutorials/training/source_zh_cn/advanced_use/images/gpu_op_ui_profiler.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph.png b/tutorials/training/source_zh_cn/advanced_use/images/graph.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png b/tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_after.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png b/tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_basic_before.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png b/tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_after.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png b/tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_before.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png b/tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph_kernel_fusion_example_fuse_composite_middle.png diff --git a/tutorials/source_zh_cn/advanced_use/images/graph_sidebar.png b/tutorials/training/source_zh_cn/advanced_use/images/graph_sidebar.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/graph_sidebar.png rename to tutorials/training/source_zh_cn/advanced_use/images/graph_sidebar.png diff --git a/tutorials/source_zh_cn/advanced_use/images/histogram.png b/tutorials/training/source_zh_cn/advanced_use/images/histogram.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/histogram.png rename to tutorials/training/source_zh_cn/advanced_use/images/histogram.png diff --git a/tutorials/source_zh_cn/advanced_use/images/histogram_func.png b/tutorials/training/source_zh_cn/advanced_use/images/histogram_func.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/histogram_func.png rename to tutorials/training/source_zh_cn/advanced_use/images/histogram_func.png diff --git a/tutorials/source_zh_cn/advanced_use/images/image_function.png b/tutorials/training/source_zh_cn/advanced_use/images/image_function.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/image_function.png rename to tutorials/training/source_zh_cn/advanced_use/images/image_function.png diff --git a/tutorials/source_zh_cn/advanced_use/images/image_vi.png b/tutorials/training/source_zh_cn/advanced_use/images/image_vi.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/image_vi.png rename to tutorials/training/source_zh_cn/advanced_use/images/image_vi.png diff --git a/tutorials/source_zh_cn/advanced_use/images/introduce.PNG b/tutorials/training/source_zh_cn/advanced_use/images/introduce.PNG similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/introduce.PNG rename to tutorials/training/source_zh_cn/advanced_use/images/introduce.PNG diff --git a/tutorials/source_zh_cn/advanced_use/images/lineage_label.png b/tutorials/training/source_zh_cn/advanced_use/images/lineage_label.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/lineage_label.png rename to tutorials/training/source_zh_cn/advanced_use/images/lineage_label.png diff --git a/tutorials/source_zh_cn/advanced_use/images/lineage_model_chart.png b/tutorials/training/source_zh_cn/advanced_use/images/lineage_model_chart.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/lineage_model_chart.png rename to tutorials/training/source_zh_cn/advanced_use/images/lineage_model_chart.png diff --git a/tutorials/source_zh_cn/advanced_use/images/lineage_model_table.png b/tutorials/training/source_zh_cn/advanced_use/images/lineage_model_table.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/lineage_model_table.png rename to tutorials/training/source_zh_cn/advanced_use/images/lineage_model_table.png diff --git a/tutorials/source_zh_cn/advanced_use/images/minddata_profile.png b/tutorials/training/source_zh_cn/advanced_use/images/minddata_profile.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/minddata_profile.png rename to tutorials/training/source_zh_cn/advanced_use/images/minddata_profile.png diff --git a/tutorials/source_zh_cn/advanced_use/images/mindrecord.png b/tutorials/training/source_zh_cn/advanced_use/images/mindrecord.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/mindrecord.png rename to tutorials/training/source_zh_cn/advanced_use/images/mindrecord.png diff --git a/tutorials/source_zh_cn/advanced_use/images/mix_precision.eddx b/tutorials/training/source_zh_cn/advanced_use/images/mix_precision.eddx similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/mix_precision.eddx rename to tutorials/training/source_zh_cn/advanced_use/images/mix_precision.eddx diff --git a/tutorials/source_zh_cn/advanced_use/images/mix_precision.jpg b/tutorials/training/source_zh_cn/advanced_use/images/mix_precision.jpg similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/mix_precision.jpg rename to tutorials/training/source_zh_cn/advanced_use/images/mix_precision.jpg diff --git a/tutorials/source_zh_cn/advanced_use/images/multi_scalars.png b/tutorials/training/source_zh_cn/advanced_use/images/multi_scalars.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/multi_scalars.png rename to tutorials/training/source_zh_cn/advanced_use/images/multi_scalars.png diff --git a/tutorials/source_zh_cn/advanced_use/images/multi_scalars_select.png b/tutorials/training/source_zh_cn/advanced_use/images/multi_scalars_select.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/multi_scalars_select.png rename to tutorials/training/source_zh_cn/advanced_use/images/multi_scalars_select.png diff --git a/tutorials/source_zh_cn/advanced_use/images/op_statistics.PNG b/tutorials/training/source_zh_cn/advanced_use/images/op_statistics.PNG similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/op_statistics.PNG rename to tutorials/training/source_zh_cn/advanced_use/images/op_statistics.PNG diff --git a/tutorials/source_zh_cn/advanced_use/images/op_type_statistics.PNG b/tutorials/training/source_zh_cn/advanced_use/images/op_type_statistics.PNG similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/op_type_statistics.PNG rename to tutorials/training/source_zh_cn/advanced_use/images/op_type_statistics.PNG diff --git a/tutorials/source_zh_cn/advanced_use/images/operator_fusion.png b/tutorials/training/source_zh_cn/advanced_use/images/operator_fusion.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/operator_fusion.png rename to tutorials/training/source_zh_cn/advanced_use/images/operator_fusion.png diff --git a/tutorials/source_zh_cn/advanced_use/images/performance_overall.png b/tutorials/training/source_zh_cn/advanced_use/images/performance_overall.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/performance_overall.png rename to tutorials/training/source_zh_cn/advanced_use/images/performance_overall.png diff --git a/tutorials/source_zh_cn/advanced_use/images/pipeline.png b/tutorials/training/source_zh_cn/advanced_use/images/pipeline.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/pipeline.png rename to tutorials/training/source_zh_cn/advanced_use/images/pipeline.png diff --git a/tutorials/source_zh_cn/advanced_use/images/scalar.png b/tutorials/training/source_zh_cn/advanced_use/images/scalar.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/scalar.png rename to tutorials/training/source_zh_cn/advanced_use/images/scalar.png diff --git a/tutorials/source_zh_cn/advanced_use/images/scalar_compound.png b/tutorials/training/source_zh_cn/advanced_use/images/scalar_compound.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/scalar_compound.png rename to tutorials/training/source_zh_cn/advanced_use/images/scalar_compound.png diff --git a/tutorials/source_zh_cn/advanced_use/images/scalar_select.png b/tutorials/training/source_zh_cn/advanced_use/images/scalar_select.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/scalar_select.png rename to tutorials/training/source_zh_cn/advanced_use/images/scalar_select.png diff --git a/tutorials/source_zh_cn/advanced_use/images/shuffle.png b/tutorials/training/source_zh_cn/advanced_use/images/shuffle.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/shuffle.png rename to tutorials/training/source_zh_cn/advanced_use/images/shuffle.png diff --git a/tutorials/source_zh_cn/advanced_use/images/shuffle_performance_scheme.png b/tutorials/training/source_zh_cn/advanced_use/images/shuffle_performance_scheme.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/shuffle_performance_scheme.png rename to tutorials/training/source_zh_cn/advanced_use/images/shuffle_performance_scheme.png diff --git a/tutorials/source_zh_cn/advanced_use/images/step_trace.png b/tutorials/training/source_zh_cn/advanced_use/images/step_trace.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/step_trace.png rename to tutorials/training/source_zh_cn/advanced_use/images/step_trace.png diff --git a/tutorials/source_zh_cn/advanced_use/images/synchronization_training_and_evaluation.png b/tutorials/training/source_zh_cn/advanced_use/images/synchronization_training_and_evaluation.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/synchronization_training_and_evaluation.png rename to tutorials/training/source_zh_cn/advanced_use/images/synchronization_training_and_evaluation.png diff --git a/tutorials/source_zh_cn/advanced_use/images/targets.png b/tutorials/training/source_zh_cn/advanced_use/images/targets.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/targets.png rename to tutorials/training/source_zh_cn/advanced_use/images/targets.png diff --git a/tutorials/source_zh_cn/advanced_use/images/tensor_function.png b/tutorials/training/source_zh_cn/advanced_use/images/tensor_function.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/tensor_function.png rename to tutorials/training/source_zh_cn/advanced_use/images/tensor_function.png diff --git a/tutorials/source_zh_cn/advanced_use/images/tensor_histogram.png b/tutorials/training/source_zh_cn/advanced_use/images/tensor_histogram.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/tensor_histogram.png rename to tutorials/training/source_zh_cn/advanced_use/images/tensor_histogram.png diff --git a/tutorials/source_zh_cn/advanced_use/images/tensor_table.png b/tutorials/training/source_zh_cn/advanced_use/images/tensor_table.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/tensor_table.png rename to tutorials/training/source_zh_cn/advanced_use/images/tensor_table.png diff --git a/tutorials/source_zh_cn/advanced_use/images/timeline.png b/tutorials/training/source_zh_cn/advanced_use/images/timeline.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/timeline.png rename to tutorials/training/source_zh_cn/advanced_use/images/timeline.png diff --git a/tutorials/source_zh_cn/advanced_use/images/train_log_1_Ascend.png b/tutorials/training/source_zh_cn/advanced_use/images/train_log_1_Ascend.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/train_log_1_Ascend.png rename to tutorials/training/source_zh_cn/advanced_use/images/train_log_1_Ascend.png diff --git a/tutorials/source_zh_cn/advanced_use/images/train_log_8_Ascend.png b/tutorials/training/source_zh_cn/advanced_use/images/train_log_8_Ascend.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/train_log_8_Ascend.png rename to tutorials/training/source_zh_cn/advanced_use/images/train_log_8_Ascend.png diff --git a/tutorials/source_zh_cn/advanced_use/images/train_log_8_Ascend_clu.png b/tutorials/training/source_zh_cn/advanced_use/images/train_log_8_Ascend_clu.png similarity index 100% rename from tutorials/source_zh_cn/advanced_use/images/train_log_8_Ascend_clu.png rename to tutorials/training/source_zh_cn/advanced_use/images/train_log_8_Ascend_clu.png diff --git a/tutorials/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md b/tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md rename to tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md index eca4a19f99..3022aa5b4d 100644 --- a/tutorials/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md +++ b/tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md @@ -1,111 +1,111 @@ -# 溯源和对比看板 - -`Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` - - - -- [溯源和对比看板](#溯源和对比看板) - - [概述](#概述) - - [模型溯源](#模型溯源) - - [数据溯源](#数据溯源) - - [对比看板](#对比看板) - - [注意事项](#注意事项) - - - -   - - -## 概述 - -MindInsight中的模型溯源、数据溯源和对比看板同训练看板一样属于可视化组件中的重要组成部分,在对训练数据的可视化中,通过对比看板观察不同标量趋势图发现问题,再使用溯源功能定位问题原因,给用户在数据增强和深度神经网络中提供高效调优的能力。 - -## 模型溯源 - -模型溯源可视化用于展示所有训练的模型参数信息。 - -![image.png](./images/lineage_label.png) - -图1:模型参数选择区 - -图1展示的模型参数选择区,列举了可供查看的模型参数标签。用户可以通过勾选所需的标签,查看相应的模型参数。 - -![image.png](./images/lineage_model_chart.png) - -图2:模型溯源功能区 - -图2展示的模型溯源功能区,图像化展示了模型的参数信息。用户可以通过选择列的特定区域,展示区域范围内的模型信息。 - -![image.png](./images/lineage_model_table.png) - -图3:模型列表 - -图3分组展示所有模型信息,用户可以按指定列进行升序或降序展示模型信息。 - -左侧概览页展示优化目标和相关参数的信息。 - -![targets.png](./images/targets.png) - -图4:概览页 - -图4展示的是优化目标分布、参数重要性和散点图。 - -## 数据溯源 - -数据溯源可视化用于展示所有训练的数据处理和数据增强信息。 - -![data_label.png](./images/data_label.png) - -图5:数据处理和增强算子选择区 - -图5展示的数据处理和数据增强算子选择区,列举了可供查看的数据处理和增强算子的名称。用户可以通过勾选所需的标签,查看相应的参数等信息。 - -![data_chart.png](./images/data_chart.png) - -图6:数据溯源功能区 - -图6展示的数据溯源功能区,图像化展示了数据处理和数据增强使用的参数信息。用户可以通过选择列的特定区域,展示区域范围内的参数信息。 - -![data_table.png](./images/data_table.png) - -图7:数据溯源列表 - -图7展示所有模型训练的数据处理和数据增强信息。 - -> 如果用户筛选模型溯源随后切换到数据溯源页面时,折线图将展示最新一次筛选过的模型溯源列。 - -## 对比看板 - -对比看板可视用于多个训练之间的标量曲线对比。 - -![multi_scalars.png](./images/multi_scalars.png) - -图8: 标量对比曲线图 - -图8展示了多个训练之间的标量曲线对比效果,横坐标是训练步骤,纵坐标是标量值。 - -图中右上角有几个按钮功能,从左到右功能分别是全屏展示,切换Y轴比例,开启/关闭框选,分步回退和还原图形。 - -- 全屏展示即全屏展示该标量曲线,再点击一次即可恢复。 -- 切换Y轴比例是指可以将Y轴坐标进行对数转换。 -- 开启/关闭框选是指可以框选图中部分区域,并放大查看该区域, 可以在已放大的图形上叠加框选。 -- 分步回退是指对同一个区域连续框选并放大查看时,可以逐步撤销操作。 -- 还原图形是指进行了多次框选后,点击此按钮可以将图还原回原始状态。 - -![multi_scalars_select.png](./images/multi_scalars_select.png) - -图9:对比看板可视功能区 - -图9展示的对比看板可视的功能区,提供了根据选择不同训练或标签,水平轴的不同维度和平滑度来进行标量对比的功能。 - -- 训练: 提供了对所有训练进行多项选择的功能,用户可以通过勾选或关键字筛选所需的训练。 -- 标签:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的标量信息。 -- 水平轴:可以选择“步骤”、“相对时间”、“绝对时间”中的任意一项,来作为标量曲线的水平轴。 -- 平滑度:可以通过调整平滑度,对标量曲线进行平滑处理。 - -## 注意事项 - -出于性能上的考虑,MindInsight对比看板使用缓存机制加载训练的标量曲线数据,并进行以下限制: -- 对比看板只支持在缓存中的训练进行比较标量曲线对比。 -- 缓存最多保留最新(按修改时间排列)的15个训练。 +# 溯源和对比看板 + +`Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` + + + +- [溯源和对比看板](#溯源和对比看板) + - [概述](#概述) + - [模型溯源](#模型溯源) + - [数据溯源](#数据溯源) + - [对比看板](#对比看板) + - [注意事项](#注意事项) + + + +   + + +## 概述 + +MindInsight中的模型溯源、数据溯源和对比看板同训练看板一样属于可视化组件中的重要组成部分,在对训练数据的可视化中,通过对比看板观察不同标量趋势图发现问题,再使用溯源功能定位问题原因,给用户在数据增强和深度神经网络中提供高效调优的能力。 + +## 模型溯源 + +模型溯源可视化用于展示所有训练的模型参数信息。 + +![image.png](./images/lineage_label.png) + +图1:模型参数选择区 + +图1展示的模型参数选择区,列举了可供查看的模型参数标签。用户可以通过勾选所需的标签,查看相应的模型参数。 + +![image.png](./images/lineage_model_chart.png) + +图2:模型溯源功能区 + +图2展示的模型溯源功能区,图像化展示了模型的参数信息。用户可以通过选择列的特定区域,展示区域范围内的模型信息。 + +![image.png](./images/lineage_model_table.png) + +图3:模型列表 + +图3分组展示所有模型信息,用户可以按指定列进行升序或降序展示模型信息。 + +左侧概览页展示优化目标和相关参数的信息。 + +![targets.png](./images/targets.png) + +图4:概览页 + +图4展示的是优化目标分布、参数重要性和散点图。 + +## 数据溯源 + +数据溯源可视化用于展示所有训练的数据处理和数据增强信息。 + +![data_label.png](./images/data_label.png) + +图5:数据处理和增强算子选择区 + +图5展示的数据处理和数据增强算子选择区,列举了可供查看的数据处理和增强算子的名称。用户可以通过勾选所需的标签,查看相应的参数等信息。 + +![data_chart.png](./images/data_chart.png) + +图6:数据溯源功能区 + +图6展示的数据溯源功能区,图像化展示了数据处理和数据增强使用的参数信息。用户可以通过选择列的特定区域,展示区域范围内的参数信息。 + +![data_table.png](./images/data_table.png) + +图7:数据溯源列表 + +图7展示所有模型训练的数据处理和数据增强信息。 + +> 如果用户筛选模型溯源随后切换到数据溯源页面时,折线图将展示最新一次筛选过的模型溯源列。 + +## 对比看板 + +对比看板可视用于多个训练之间的标量曲线对比。 + +![multi_scalars.png](./images/multi_scalars.png) + +图8: 标量对比曲线图 + +图8展示了多个训练之间的标量曲线对比效果,横坐标是训练步骤,纵坐标是标量值。 + +图中右上角有几个按钮功能,从左到右功能分别是全屏展示,切换Y轴比例,开启/关闭框选,分步回退和还原图形。 + +- 全屏展示即全屏展示该标量曲线,再点击一次即可恢复。 +- 切换Y轴比例是指可以将Y轴坐标进行对数转换。 +- 开启/关闭框选是指可以框选图中部分区域,并放大查看该区域, 可以在已放大的图形上叠加框选。 +- 分步回退是指对同一个区域连续框选并放大查看时,可以逐步撤销操作。 +- 还原图形是指进行了多次框选后,点击此按钮可以将图还原回原始状态。 + +![multi_scalars_select.png](./images/multi_scalars_select.png) + +图9:对比看板可视功能区 + +图9展示的对比看板可视的功能区,提供了根据选择不同训练或标签,水平轴的不同维度和平滑度来进行标量对比的功能。 + +- 训练: 提供了对所有训练进行多项选择的功能,用户可以通过勾选或关键字筛选所需的训练。 +- 标签:提供了对所有标签进行多项选择的功能,用户可以通过勾选所需的标签,查看对应的标量信息。 +- 水平轴:可以选择“步骤”、“相对时间”、“绝对时间”中的任意一项,来作为标量曲线的水平轴。 +- 平滑度:可以通过调整平滑度,对标量曲线进行平滑处理。 + +## 注意事项 + +出于性能上的考虑,MindInsight对比看板使用缓存机制加载训练的标量曲线数据,并进行以下限制: +- 对比看板只支持在缓存中的训练进行比较标量曲线对比。 +- 缓存最多保留最新(按修改时间排列)的15个训练。 - 用户最多同时对比5个训练的标量曲线。 \ No newline at end of file diff --git a/tutorials/source_zh_cn/advanced_use/membership_inference.md b/tutorials/training/source_zh_cn/advanced_use/membership_inference.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/membership_inference.md rename to tutorials/training/source_zh_cn/advanced_use/membership_inference.md diff --git a/tutorials/source_zh_cn/advanced_use/mindinsight_commands.md b/tutorials/training/source_zh_cn/advanced_use/mindinsight_commands.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/mindinsight_commands.md rename to tutorials/training/source_zh_cn/advanced_use/mindinsight_commands.md diff --git a/tutorials/source_zh_cn/advanced_use/mixed_precision.md b/tutorials/training/source_zh_cn/advanced_use/mixed_precision.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/mixed_precision.md rename to tutorials/training/source_zh_cn/advanced_use/mixed_precision.md diff --git a/tutorials/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md b/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md rename to tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md diff --git a/tutorials/source_zh_cn/advanced_use/model_scripts_transformation.md b/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/model_scripts_transformation.md rename to tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md diff --git a/tutorials/source_zh_cn/advanced_use/model_security.md b/tutorials/training/source_zh_cn/advanced_use/model_security.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/model_security.md rename to tutorials/training/source_zh_cn/advanced_use/model_security.md diff --git a/tutorials/source_zh_cn/advanced_use/network_migration.md b/tutorials/training/source_zh_cn/advanced_use/network_migration.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/network_migration.md rename to tutorials/training/source_zh_cn/advanced_use/network_migration.md diff --git a/tutorials/source_zh_cn/advanced_use/nlp_application.md b/tutorials/training/source_zh_cn/advanced_use/nlp_application.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/nlp_application.md rename to tutorials/training/source_zh_cn/advanced_use/nlp_application.md diff --git a/tutorials/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md b/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md rename to tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md diff --git a/tutorials/source_zh_cn/advanced_use/parameter_server_training.md b/tutorials/training/source_zh_cn/advanced_use/parameter_server_training.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/parameter_server_training.md rename to tutorials/training/source_zh_cn/advanced_use/parameter_server_training.md diff --git a/tutorials/source_zh_cn/advanced_use/performance_profiling.md b/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/performance_profiling.md rename to tutorials/training/source_zh_cn/advanced_use/performance_profiling.md diff --git a/tutorials/source_zh_cn/advanced_use/performance_profiling_gpu.md b/tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/performance_profiling_gpu.md rename to tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md index 68a7ef86cb..bc7002b089 100644 --- a/tutorials/source_zh_cn/advanced_use/performance_profiling_gpu.md +++ b/tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md @@ -1,121 +1,121 @@ -# 性能调试(GPU) - -`Linux` `GPU` `模型调优` `中级` `高级` - - - -- [性能调试(GPU)](#性能调试-gpu) - - [概述](#概述) - - [操作流程](#操作流程) - - [准备训练脚本](#准备训练脚本) - - [启动MindInsight](#启动mindinsight) - - [性能分析](#性能分析) - - [算子性能分析](#算子性能分析) - - [Timeline分析](#timeline分析) - - - - - -## 概述 -将训练过程中的算子耗时等信息记录到文件中,通过可视化界面供用户查看分析,帮助用户更高效地调试神经网络性能。 - -## 操作流程 - -> 操作流程可以参考Ascend 910上profiler的操作: -> -> - -## 准备训练脚本 - -为了收集神经网络的性能数据,需要在训练脚本中添加MindSpore Profiler相关接口。 -- `set_context`之后,需要初始化MindSpore `Profiler`对象,GPU场景下初始化Profiler对象时只有output_path参数有效。 -- 在训练结束后,调用`Profiler.analyse()`停止性能数据收集并生成性能分析结果。 - -> 样例代码与Ascend使用方式一致可以参考: -> -> - -GPU场景下还可以用自定义callback的方式收集性能数据,示例如下: - -```python -class StopAtStep(Callback): - def __init__(self, start_step, stop_step): - super(StopAtStep, self).__init__() - self.start_step = start_step - self.stop_step = stop_step - self.already_analysed = False - - def step_begin(self, run_context): - cb_params = run_context.original_args() - step_num = cb_params.cur_step_num - if step_num == self.start_step: - self.profiler = Profiler() - - def step_end(self, run_context): - cb_params = run_context.original_args() - step_num = cb_params.cur_step_num - if step_num == self.stop_step and not self.already_analysed: - self.profiler.analyse() - self.already_analysed = True - - def end(self, run_context): - if not self.already_analysed: - self.profiler.analyse() -``` - -以上代码仅供参考,用户可根据所需场景自由实现。 - -## 启动MindInsight - -启动命令请参考[MindInsight相关命令](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/mindinsight_commands.html)。 - - -### 性能分析 - -用户从训练列表中选择指定的训练,点击性能调试,可以查看该次训练的性能数据(目前GPU场景只支持算子耗时排名统计和Timeline功能,其他功能敬请期待)。 - -![performance_overall.png](./images/performance_overall.png) - -图1:性能数据总览 - -图1展示了性能数据总览页面,包含了迭代轨迹(Step Trace)、算子性能、MindData性能和Timeline等组件的数据总体呈现。目前GPU场景下只支持算子性能统计功能: -- 算子性能:统计单算子以及各算子类型的执行时间,进行排序展示;总览页中展示了各算子类型平均执行时间占比的饼状图。 - -用户可以点击查看详情链接,进入组件页面进行详细分析。 - -#### 算子性能分析 - -使用算子性能分析组件可以对MindSpore运行过程中的各个算子的执行时间进行统计展示。 - -![gpu_op_ui_profiler.png](./images/gpu_op_ui_profiler.png) - -图2:算子类别统计分析 - -图2展示了按算子类别进行统计分析的结果,包含以下内容: -- 可以选择饼图/柱状图展示各算子类别的时间占比,每个算子类别的执行时间会统计属于该类别的算子执行时间总和以及平均执行时间。 -- 统计前20个平均执行时间最长的算子类别。 - -图2下半部分展示了算子性能统计表,包含以下内容: -- 选择全部:按单个算子的统计结果进行排序展示,展示维度包括算子位置(Device/Host)、算子类型、算子执行时间、算子全名等;默认按算子平均执行时间排序。 -- 选择分类:按算子类别的统计结果进行排序展示,展示维度包括算子分类名称、算子类别执行时间、执行频次、执行总时间的比例、平均执行时间。点击每个算子类别,可以进一步查看该类别下所有单个算子的统计信息。 -- 搜索:在右侧搜索框中输入字符串,支持对算子名称/类别进行模糊搜索。 - -![gpu_activity_profiler.png](./images/gpu_activity_profiler.png) - -图3:内核信息分析 - -图3展示了CUDA activity信息统计,包含以下内容: - -- 统计图表:展示了各个kernel activity的占比以及前15个算子的耗时信息。 -- 内核信息列表:信息列表展示activity的名称、所属算子名称、执行次数、总时间、平均时间等信息。 -- 搜索:可以通过name(activity名称)以及op_full_name(所属算子名称)进程部分匹配的搜索。 - -#### Timeline分析 - -GPU场景下,Timeline分析的使用方法和Ascend场景相同,不同之处是,GPU Timeline展示的是算子信息和CUDA activity的信息。使用方法参考: - -> 样例代码与Ascend使用方式一致可以参考: -> -> - +# 性能调试(GPU) + +`Linux` `GPU` `模型调优` `中级` `高级` + + + +- [性能调试(GPU)](#性能调试-gpu) + - [概述](#概述) + - [操作流程](#操作流程) + - [准备训练脚本](#准备训练脚本) + - [启动MindInsight](#启动mindinsight) + - [性能分析](#性能分析) + - [算子性能分析](#算子性能分析) + - [Timeline分析](#timeline分析) + + + + + +## 概述 +将训练过程中的算子耗时等信息记录到文件中,通过可视化界面供用户查看分析,帮助用户更高效地调试神经网络性能。 + +## 操作流程 + +> 操作流程可以参考Ascend 910上profiler的操作: +> +> + +## 准备训练脚本 + +为了收集神经网络的性能数据,需要在训练脚本中添加MindSpore Profiler相关接口。 +- `set_context`之后,需要初始化MindSpore `Profiler`对象,GPU场景下初始化Profiler对象时只有output_path参数有效。 +- 在训练结束后,调用`Profiler.analyse()`停止性能数据收集并生成性能分析结果。 + +> 样例代码与Ascend使用方式一致可以参考: +> +> + +GPU场景下还可以用自定义callback的方式收集性能数据,示例如下: + +```python +class StopAtStep(Callback): + def __init__(self, start_step, stop_step): + super(StopAtStep, self).__init__() + self.start_step = start_step + self.stop_step = stop_step + self.already_analysed = False + + def step_begin(self, run_context): + cb_params = run_context.original_args() + step_num = cb_params.cur_step_num + if step_num == self.start_step: + self.profiler = Profiler() + + def step_end(self, run_context): + cb_params = run_context.original_args() + step_num = cb_params.cur_step_num + if step_num == self.stop_step and not self.already_analysed: + self.profiler.analyse() + self.already_analysed = True + + def end(self, run_context): + if not self.already_analysed: + self.profiler.analyse() +``` + +以上代码仅供参考,用户可根据所需场景自由实现。 + +## 启动MindInsight + +启动命令请参考[MindInsight相关命令](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/mindinsight_commands.html)。 + + +### 性能分析 + +用户从训练列表中选择指定的训练,点击性能调试,可以查看该次训练的性能数据(目前GPU场景只支持算子耗时排名统计和Timeline功能,其他功能敬请期待)。 + +![performance_overall.png](./images/performance_overall.png) + +图1:性能数据总览 + +图1展示了性能数据总览页面,包含了迭代轨迹(Step Trace)、算子性能、MindData性能和Timeline等组件的数据总体呈现。目前GPU场景下只支持算子性能统计功能: +- 算子性能:统计单算子以及各算子类型的执行时间,进行排序展示;总览页中展示了各算子类型平均执行时间占比的饼状图。 + +用户可以点击查看详情链接,进入组件页面进行详细分析。 + +#### 算子性能分析 + +使用算子性能分析组件可以对MindSpore运行过程中的各个算子的执行时间进行统计展示。 + +![gpu_op_ui_profiler.png](./images/gpu_op_ui_profiler.png) + +图2:算子类别统计分析 + +图2展示了按算子类别进行统计分析的结果,包含以下内容: +- 可以选择饼图/柱状图展示各算子类别的时间占比,每个算子类别的执行时间会统计属于该类别的算子执行时间总和以及平均执行时间。 +- 统计前20个平均执行时间最长的算子类别。 + +图2下半部分展示了算子性能统计表,包含以下内容: +- 选择全部:按单个算子的统计结果进行排序展示,展示维度包括算子位置(Device/Host)、算子类型、算子执行时间、算子全名等;默认按算子平均执行时间排序。 +- 选择分类:按算子类别的统计结果进行排序展示,展示维度包括算子分类名称、算子类别执行时间、执行频次、执行总时间的比例、平均执行时间。点击每个算子类别,可以进一步查看该类别下所有单个算子的统计信息。 +- 搜索:在右侧搜索框中输入字符串,支持对算子名称/类别进行模糊搜索。 + +![gpu_activity_profiler.png](./images/gpu_activity_profiler.png) + +图3:内核信息分析 + +图3展示了CUDA activity信息统计,包含以下内容: + +- 统计图表:展示了各个kernel activity的占比以及前15个算子的耗时信息。 +- 内核信息列表:信息列表展示activity的名称、所属算子名称、执行次数、总时间、平均时间等信息。 +- 搜索:可以通过name(activity名称)以及op_full_name(所属算子名称)进程部分匹配的搜索。 + +#### Timeline分析 + +GPU场景下,Timeline分析的使用方法和Ascend场景相同,不同之处是,GPU Timeline展示的是算子信息和CUDA activity的信息。使用方法参考: + +> 样例代码与Ascend使用方式一致可以参考: +> +> + diff --git a/tutorials/source_zh_cn/advanced_use/quantization_aware.md b/tutorials/training/source_zh_cn/advanced_use/quantization_aware.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/quantization_aware.md rename to tutorials/training/source_zh_cn/advanced_use/quantization_aware.md diff --git a/tutorials/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md b/tutorials/training/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md similarity index 97% rename from tutorials/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md rename to tutorials/training/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md index b63c08ab95..35dd89dd17 100644 --- a/tutorials/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md +++ b/tutorials/training/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md @@ -1,464 +1,464 @@ -# ResNet-50二阶优化实践 - -`Linux` `Ascend` `GPU` `模型开发` `模型调优` `高级` - - - -- [ResNet-50二阶优化实践](#resnet-50二阶优化实践) - - [概述](#概述) - - [准备环节](#准备环节) - - [准备数据集](#准备数据集) - - [配置分布式环境变量](#配置分布式环境变量) - - [加载处理数据集](#加载处理数据集) - - [定义网络](#定义网络) - - [定义损失函数及THOR优化器](#定义损失函数及thor优化器) - - [定义损失函数](#定义损失函数) - - [定义优化器](#定义优化器) - - [训练网络](#训练网络) - - [配置模型保存](#配置模型保存) - - [配置训练网络](#配置训练网络) - - [运行脚本](#运行脚本) - - [模型推理](#模型推理) - - -   - -## 概述 - -常见的优化算法可分为一阶优化算法和二阶优化算法。经典的一阶优化算法如SGD等,计算量小、计算速度快,但是收敛的速度慢,所需的迭代次数多。而二阶优化算法使用目标函数的二阶导数来加速收敛,能更快地收敛到模型最优值,所需要的迭代次数少,但由于二阶优化算法过高的计算成本,导致其总体执行时间仍然慢于一阶,故目前在深度神经网络训练中二阶优化算法的应用并不普遍。二阶优化算法的主要计算成本在于二阶信息矩阵(Hessian矩阵、[FIM矩阵](https://arxiv.org/pdf/1808.07172.pdf)等)的求逆运算,时间复杂度约为$O(n^3)$。 - -MindSpore开发团队在现有的自然梯度算法的基础上,对FIM矩阵采用近似、切分等优化加速手段,极大的降低了逆矩阵的计算复杂度,开发出了可用的二阶优化器THOR。使用8块Ascend 910 AI处理器,THOR可以在72min内完成ResNet50-v1.5网络和ImageNet数据集的训练,相比于SGD+Momentum速度提升了近一倍。 - - -本篇教程将主要介绍如何在Ascend 910 以及GPU上,使用MindSpore提供的二阶优化器THOR训练ResNet50-v1.5网络和ImageNet数据集。 -> 你可以在这里下载完整的示例代码: - 。 - -### 示例代码目录结构 - -```shell -├── resnet_thor - ├── README.md - ├── scripts - ├── run_distribute_train.sh # launch distributed training for Ascend 910 - └── run_eval.sh # launch inference for Ascend 910 - ├── run_distribute_train_gpu.sh # launch distributed training for GPU - └── run_eval_gpu.sh # launch inference for GPU - ├── src - ├── crossentropy.py # CrossEntropy loss function - ├── config.py # parameter configuration - ├── dataset_helper.py # dataset helper for minddata dataset - ├── grad_reducer_thor.py # grad reduce for thor - ├── model_thor.py # model for train - ├── resnet_thor.py # resnet50_thor backone - ├── thor.py # thor optimizer - ├── thor_layer.py # thor layer - └── dataset.py # data preprocessing - ├── eval.py # infer script - └── train.py # train script - -``` - -整体执行流程如下: -1. 准备ImageNet数据集,处理需要的数据集; -2. 定义ResNet50网络; -3. 定义损失函数和THOR优化器; -4. 加载数据集并进行训练,训练完成后,查看结果及保存模型文件; -5. 加载保存的模型,进行推理。 - - -## 准备环节 - -实践前,确保已经正确安装MindSpore。如果没有,可以通过[MindSpore安装页面](https://www.mindspore.cn/install)安装MindSpore。 - -### 准备数据集 - -下载完整的ImageNet2012数据集,将数据集解压分别存放到本地工作区的`ImageNet2012/ilsvrc`、`ImageNet2012/ilsvrc_eval`路径下。 - -目录结构如下: - -``` -└─ImageNet2012 - ├─ilsvrc - │ n03676483/ - │ n04067472/ - │ n01622779/ - │ ...... - └─ilsvrc_eval - │ n03018349/ - │ n02504013 - │ n07871810 - │ ...... - -``` -### 配置分布式环境变量 -#### Ascend 910 -Ascend 910 AI处理器的分布式环境变量配置参考[分布式并行训练 (Ascend)](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_ascend.html#id4)。 - -#### GPU -GPU的分布式环境配置参考[分布式并行训练 (GPU)](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_gpu.html#id4)。 - - -## 加载处理数据集 - -分布式训练时,通过并行的方式加载数据集,同时通过MindSpore提供的数据增强接口对数据集进行处理。加载处理数据集的脚本在源码的`src/dataset.py`脚本中。 -```python -import os -import mindspore.common.dtype as mstype -import mindspore.dataset.engine as de -import mindspore.dataset.vision.c_transforms as C -import mindspore.dataset.transforms.c_transforms as C2 -from mindspore.communication.management import init, get_rank, get_group_size - -def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, target="Ascend"): - if target == "Ascend": - device_num, rank_id = _get_rank_info() - else: - init() - rank_id = get_rank() - device_num = get_group_size() - if device_num == 1: - ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True) - else: - ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True, - num_shards=device_num, shard_id=rank_id) - - image_size = 224 - mean = [0.485 * 255, 0.456 * 255, 0.406 * 255] - std = [0.229 * 255, 0.224 * 255, 0.225 * 255] - # define map operations - if do_train: - trans = [ - C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)), - C.RandomHorizontalFlip(prob=0.5), - C.Normalize(mean=mean, std=std), - C.HWC2CHW() - ] - else: - trans = [ - C.Decode(), - C.Resize(256), - C.CenterCrop(image_size), - C.Normalize(mean=mean, std=std), - C.HWC2CHW() - ] - type_cast_op = C2.TypeCast(mstype.int32) - ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=8) - ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) - - # apply batch operations - ds = ds.batch(batch_size, drop_remainder=True) - - # apply dataset repeat operation - ds = ds.repeat(repeat_num) - - return ds -``` - -> MindSpore支持进行多种数据处理和增强的操作,各种操作往往组合使用,具体可以参考[数据处理与数据增强](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/data_processing_and_augmentation.html)章节。 - - -## 定义网络 -本示例中使用的网络模型为ResNet50-v1.5,先定义[ResNet50网络](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py),然后使用二阶优化器自定义的算子替换`Conv2d`和 -和`Dense`算子。定义好的网络模型在在源码`src/resnet_thor.py`脚本中,自定义的算子`Conv2d_thor`和`Dense_thor`在`src/thor_layer.py`脚本中。 - -- 使用`Conv2d_thor`替换原网络模型中的`Conv2d` -- 使用`Dense_thor`替换原网络模型中的`Dense` - -> 使用THOR自定义的算子`Conv2d_thor`和`Dense_thor`是为了保存模型训练中的二阶矩阵信息,新定义的网络与原网络模型的backbone一致。 - -网络构建完成以后,在`__main__`函数中调用定义好的ResNet50: -```python -... -from src.resnet_thor import resnet50 -... -f __name__ == "__main__": - ... - # define the net - net = resnet50(class_num=config.class_num, damping=damping, loss_scale=config.loss_scale, - frequency=config.frequency, batch_size=config.batch_size) - ... -``` - - -## 定义损失函数及THOR优化器 - - -### 定义损失函数 - -MindSpore支持的损失函数有`SoftmaxCrossEntropyWithLogits`、`L1Loss`、`MSELoss`等。THOR优化器需要使用`SoftmaxCrossEntropyWithLogits`损失函数。 - -损失函数的实现步骤在`src/crossentropy.py`脚本中。这里使用了深度网络模型训练中的一个常用trick:label smoothing,通过对真实标签做平滑处理,提高模型对分类错误标签的容忍度,从而可以增加模型的泛化能力。 -```python -class CrossEntropy(_Loss): - """CrossEntropy""" - def __init__(self, smooth_factor=0., num_classes=1000): - super(CrossEntropy, self).__init__() - self.onehot = P.OneHot() - self.on_value = Tensor(1.0 - smooth_factor, mstype.float32) - self.off_value = Tensor(1.0 * smooth_factor / (num_classes - 1), mstype.float32) - self.ce = nn.SoftmaxCrossEntropyWithLogits() - self.mean = P.ReduceMean(False) - - def construct(self, logit, label): - one_hot_label = self.onehot(label, F.shape(logit)[1], self.on_value, self.off_value) - loss = self.ce(logit, one_hot_label) - loss = self.mean(loss, 0) - return loss -``` -在`__main__`函数中调用定义好的损失函数: - -```python -... -from src.crossentropy import CrossEntropy -... -if __name__ == "__main__": - ... - # define the loss function - if not config.use_label_smooth: - config.label_smooth_factor = 0.0 - loss = CrossEntropy(smooth_factor=config.label_smooth_factor, num_classes=config.class_num) - ... -``` - -### 定义优化器 - -THOR优化器的参数更新公式如下: - -$$ \theta^{t+1} = \theta^t + \alpha F^{-1}\nabla E$$ - -参数更新公式中各参数的含义如下: -- $\theta$:网络中的可训参数; -- $t$:迭代次数; -- $\alpha$:学习率值,参数的更新步长; -- $F^{-1}$:FIM矩阵,在网络中计算获得; -- $\nabla E$:一阶梯度值。 - -从参数更新公式中可以看出,THOR优化器需要额外计算的是每一层的FIM矩阵,每一层的FIM矩阵就是之前在自定义的网络模型中计算获得的。FIM矩阵可以对每一层参数更新的步长和方向进行自适应的调整,加速收敛的同时可以降低调参的复杂度。 - -```python -... -if args_opt.device_target == "Ascend": - from src.thor import THOR -else: - from src.thor import THOR_GPU as THOR -... - -if __name__ == "__main__": - ... - # learning rate setting - lr = get_model_lr(0, config.lr_init, config.lr_decay, config.lr_end_epoch, step_size, decay_epochs=39) - # define the optimizer - opt = THOR(filter(lambda x: x.requires_grad, net.get_parameters()), Tensor(lr), config.momentum, - filter(lambda x: 'matrix_A' in x.name, net.get_parameters()), - filter(lambda x: 'matrix_G' in x.name, net.get_parameters()), - filter(lambda x: 'A_inv_max' in x.name, net.get_parameters()), - filter(lambda x: 'G_inv_max' in x.name, net.get_parameters()), - config.weight_decay, config.loss_scale) - ... -``` - -## 训练网络 - -### 配置模型保存 - -MindSpore提供了callback机制,可以在训练过程中执行自定义逻辑,这里使用框架提供的`ModelCheckpoint`函数。 -`ModelCheckpoint`可以保存网络模型和参数,以便进行后续的fine-tuning操作。 -`TimeMonitor`、`LossMonitor`是MindSpore官方提供的callback函数,可以分别用于监控训练过程中单步迭代时间和`loss`值的变化。 - -```python -... -from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, TimeMonitor, LossMonitor -... -if __name__ == "__main__": - ... - # define callbacks - time_cb = TimeMonitor(data_size=step_size) - loss_cb = LossMonitor() - cb = [time_cb, loss_cb] - if config.save_checkpoint: - config_ck = CheckpointConfig(save_checkpoint_steps=config.save_checkpoint_epochs * step_size, - keep_checkpoint_max=config.keep_checkpoint_max) - ckpt_cb = ModelCheckpoint(prefix="resnet", directory=ckpt_save_dir, config=config_ck) - cb += [ckpt_cb] - ... -``` - -### 配置训练网络 - -通过MindSpore提供的`model.train`接口可以方便地进行网络的训练。THOR优化器通过降低二阶矩阵更新频率,来减少计算量,提升计算速度,故重新定义一个Model_Thor类,继承MindSpore提供的Model类。在Model_Thor类中增加二阶矩阵更新频率控制参数,用户可以通过调整该参数,优化整体的性能。 - - -```python -... -from mindspore.train.loss_scale_manager import FixedLossScaleManager -from src.model_thor import Model_Thor as Model -... - -if __name__ == "__main__": - ... - loss_scale = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False) - if target == "Ascend": - model = Model(net, loss_fn=loss, optimizer=opt, amp_level='O2', loss_scale_manager=loss_scale, - keep_batchnorm_fp32=False, metrics={'acc'}, frequency=config.frequency) - else: - model = Model(net, loss_fn=loss, optimizer=opt, loss_scale_manager=loss_scale, metrics={'acc'}, - amp_level="O2", keep_batchnorm_fp32=True, frequency=config.frequency) - ... -``` - -### 运行脚本 -训练脚本定义完成之后,调`scripts`目录下的shell脚本,启动分布式训练进程。 -#### Ascend 910 -目前MindSpore分布式在Ascend上执行采用单卡单进程运行方式,即每张卡上运行1个进程,进程数量与使用的卡的数量一致。其中,0卡在前台执行,其他卡放在后台执行。每个进程创建1个目录,目录名称为`train_parallel`+ `device_id`,用来保存日志信息,算子编译信息以及训练的checkpoint文件。下面以使用8张卡的分布式训练脚本为例,演示如何运行脚本: - -使用以下命令运行脚本: -``` -sh run_distribute_train.sh [RANK_TABLE_FILE] [DATASET_PATH] [DEVICE_NUM] -``` -脚本需要传入变量`RANK_TABLE_FILE`、`DATASET_PATH`和`DEVICE_NUM`,其中: -- `RANK_TABLE_FILE`:组网信息文件的路径。 -- `DATASET_PATH`:训练数据集路径。 -- `DEVICE_NUM`: 实际的运行卡数。 -其余环境变量请参考安装教程中的配置项。 - -训练过程中loss打印示例如下: - -```bash -... -epoch: 1 step: 5004, loss is 4.4182425 -epoch: 2 step: 5004, loss is 3.740064 -epoch: 3 step: 5004, loss is 4.0546017 -epoch: 4 step: 5004, loss is 3.7598825 -epoch: 5 step: 5004, loss is 3.3744206 -...... -epoch: 40 step: 5004, loss is 1.6907625 -epoch: 41 step: 5004, loss is 1.8217756 -epoch: 42 step: 5004, loss is 1.6453942 -... -``` - -训练完后,每张卡训练产生的checkpoint文件保存在各自训练目录下,`device_0`产生的checkpoint文件示例如下: - -```bash -└─train_parallel0 - ├─resnet-1_5004.ckpt - ├─resnet-2_5004.ckpt - │ ...... - ├─resnet-42_5004.ckpt -``` - -其中, -`*.ckpt`:指保存的模型参数文件。checkpoint文件名称具体含义:*网络名称*-*epoch数*_*step数*.ckpt。 - -#### GPU -在GPU硬件平台上,MindSpore采用OpenMPI的`mpirun`进行分布式训练,进程创建1个目录,目录名称为`train_parallel`,用来保存日志信息和训练的checkpoint文件。下面以使用8张卡的分布式训练脚本为例,演示如何运行脚本: -``` -sh run_distribute_train_gpu.sh [DATASET_PATH] [DEVICE_NUM] -``` -脚本需要传入变量`DATASET_PATH`和`DEVICE_NUM`,其中: -- `DATASET_PATH`:训练数据集路径。 -- `DEVICE_NUM`: 实际的运行卡数。 - -在GPU训练时,无需设置`DEVICE_ID`环境变量,因此在主训练脚本中不需要调用`int(os.getenv('DEVICE_ID'))`来获取卡的物理序号,同时`context`中也无需传入`device_id`。我们需要将device_target设置为GPU,并需要调用`init()`来使能NCCL。 - -训练过程中loss打印示例如下: -```bash -... -epoch: 1 step: 5004, loss is 4.2546034 -epoch: 2 step: 5004, loss is 4.0819564 -epoch: 3 step: 5004, loss is 3.7005644 -epoch: 4 step: 5004, loss is 3.2668946 -epoch: 5 step: 5004, loss is 3.023509 -...... -epoch: 36 step: 5004, loss is 1.645802 -... -``` - -训练完后,保存的模型文件示例如下: - -```bash -└─train_parallel - ├─ckpt_0 - ├─resnet-1_5004.ckpt - ├─resnet-2_5004.ckpt - │ ...... - ├─resnet-36_5004.ckpt - ...... - ├─ckpt_7 - ├─resnet-1_5004.ckpt - ├─resnet-2_5004.ckpt - │ ...... - ├─resnet-36_5004.ckpt - -``` - -## 模型推理 - -使用训练过程中保存的checkpoint文件进行推理,验证模型的泛化能力。首先通过`load_checkpoint`接口加载模型文件,然后调用`Model`的`eval`接口对输入图片类别作出预测,再与输入图片的真实类别做比较,得出最终的预测精度值。 - -### 定义推理网络 - -1. 使用`load_checkpoint`接口加载模型文件。 -2. 使用`model.eval`接口读入测试数据集,进行推理。 -3. 计算得出预测精度值。 - -```python -... -from mindspore.train.serialization import load_checkpoint, load_param_into_net -... - -if __name__ == "__main__": - ... - # define net - net = resnet(class_num=config.class_num) - net.add_flags_recursive(thor=False) - - # load checkpoint - param_dict = load_checkpoint(args_opt.checkpoint_path) - keys = list(param_dict.keys()) - for key in keys: - if "damping" in key: - param_dict.pop(key) - load_param_into_net(net, param_dict) - net.set_train(False) - - # define model - model = Model(net, loss_fn=loss, metrics={'top_1_accuracy', 'top_5_accuracy'}) - - # eval model - res = model.eval(dataset) - print("result:", res, "ckpt=", args_opt.checkpoint_path) -``` - -### 执行推理 -推理网络定义完成之后,调用`scripts`目录下的shell脚本,进行推理。 -#### Ascend 910 -在Ascend 910硬件平台上,推理的执行命令如下: -``` -sh run_eval.sh [DATASET_PATH] [CHECKPOINT_PATH] -``` -脚本需要传入变量`DATASET_PATH`和`CHECKPOINT_PATH`,其中: -- `DATASET_PATH`:推理数据集路径。 -- `CHECKPOINT_PATH`: 保存的checkpoint路径。 - -目前推理使用的是单卡(默认device 0)进行推理,推理的结果如下: -``` -result: {'top_5_accuracy': 0.9295574583866837, 'top_1_accuracy': 0.761443661971831} ckpt=train_parallel0/resnet-42_5004.ckpt -``` -- `top_5_accuracy`:对于一个输入图片,如果预测概率排名前五的标签中包含真实标签,即认为分类正确; -- `top_1_accuracy`:对于一个输入图片,如果预测概率最大的标签与真实标签相同,即认为分类正确。 -#### GPU - -在GPU硬件平台上,推理的执行命令如下: -``` -sh run_eval_gpu.sh [DATASET_PATH] [CHECKPOINT_PATH] -``` -脚本需要传入变量`DATASET_PATH`和`CHECKPOINT_PATH`,其中: -- `DATASET_PATH`:推理数据集路径。 -- `CHECKPOINT_PATH`: 保存的checkpoint路径。 - -推理的结果如下: -``` -result: {'top_5_accuracy': 0.9287972151088348, 'top_1_accuracy': 0.7597031049935979} ckpt=train_parallel/resnet-36_5004.ckpt -``` +# ResNet-50二阶优化实践 + +`Linux` `Ascend` `GPU` `模型开发` `模型调优` `高级` + + + +- [ResNet-50二阶优化实践](#resnet-50二阶优化实践) + - [概述](#概述) + - [准备环节](#准备环节) + - [准备数据集](#准备数据集) + - [配置分布式环境变量](#配置分布式环境变量) + - [加载处理数据集](#加载处理数据集) + - [定义网络](#定义网络) + - [定义损失函数及THOR优化器](#定义损失函数及thor优化器) + - [定义损失函数](#定义损失函数) + - [定义优化器](#定义优化器) + - [训练网络](#训练网络) + - [配置模型保存](#配置模型保存) + - [配置训练网络](#配置训练网络) + - [运行脚本](#运行脚本) + - [模型推理](#模型推理) + + +   + +## 概述 + +常见的优化算法可分为一阶优化算法和二阶优化算法。经典的一阶优化算法如SGD等,计算量小、计算速度快,但是收敛的速度慢,所需的迭代次数多。而二阶优化算法使用目标函数的二阶导数来加速收敛,能更快地收敛到模型最优值,所需要的迭代次数少,但由于二阶优化算法过高的计算成本,导致其总体执行时间仍然慢于一阶,故目前在深度神经网络训练中二阶优化算法的应用并不普遍。二阶优化算法的主要计算成本在于二阶信息矩阵(Hessian矩阵、[FIM矩阵](https://arxiv.org/pdf/1808.07172.pdf)等)的求逆运算,时间复杂度约为$O(n^3)$。 + +MindSpore开发团队在现有的自然梯度算法的基础上,对FIM矩阵采用近似、切分等优化加速手段,极大的降低了逆矩阵的计算复杂度,开发出了可用的二阶优化器THOR。使用8块Ascend 910 AI处理器,THOR可以在72min内完成ResNet50-v1.5网络和ImageNet数据集的训练,相比于SGD+Momentum速度提升了近一倍。 + + +本篇教程将主要介绍如何在Ascend 910 以及GPU上,使用MindSpore提供的二阶优化器THOR训练ResNet50-v1.5网络和ImageNet数据集。 +> 你可以在这里下载完整的示例代码: + 。 + +### 示例代码目录结构 + +```shell +├── resnet_thor + ├── README.md + ├── scripts + ├── run_distribute_train.sh # launch distributed training for Ascend 910 + └── run_eval.sh # launch inference for Ascend 910 + ├── run_distribute_train_gpu.sh # launch distributed training for GPU + └── run_eval_gpu.sh # launch inference for GPU + ├── src + ├── crossentropy.py # CrossEntropy loss function + ├── config.py # parameter configuration + ├── dataset_helper.py # dataset helper for minddata dataset + ├── grad_reducer_thor.py # grad reduce for thor + ├── model_thor.py # model for train + ├── resnet_thor.py # resnet50_thor backone + ├── thor.py # thor optimizer + ├── thor_layer.py # thor layer + └── dataset.py # data preprocessing + ├── eval.py # infer script + └── train.py # train script + +``` + +整体执行流程如下: +1. 准备ImageNet数据集,处理需要的数据集; +2. 定义ResNet50网络; +3. 定义损失函数和THOR优化器; +4. 加载数据集并进行训练,训练完成后,查看结果及保存模型文件; +5. 加载保存的模型,进行推理。 + + +## 准备环节 + +实践前,确保已经正确安装MindSpore。如果没有,可以通过[MindSpore安装页面](https://www.mindspore.cn/install)安装MindSpore。 + +### 准备数据集 + +下载完整的ImageNet2012数据集,将数据集解压分别存放到本地工作区的`ImageNet2012/ilsvrc`、`ImageNet2012/ilsvrc_eval`路径下。 + +目录结构如下: + +``` +└─ImageNet2012 + ├─ilsvrc + │ n03676483/ + │ n04067472/ + │ n01622779/ + │ ...... + └─ilsvrc_eval + │ n03018349/ + │ n02504013 + │ n07871810 + │ ...... + +``` +### 配置分布式环境变量 +#### Ascend 910 +Ascend 910 AI处理器的分布式环境变量配置参考[分布式并行训练 (Ascend)](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_ascend.html#id4)。 + +#### GPU +GPU的分布式环境配置参考[分布式并行训练 (GPU)](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_gpu.html#id4)。 + + +## 加载处理数据集 + +分布式训练时,通过并行的方式加载数据集,同时通过MindSpore提供的数据增强接口对数据集进行处理。加载处理数据集的脚本在源码的`src/dataset.py`脚本中。 +```python +import os +import mindspore.common.dtype as mstype +import mindspore.dataset.engine as de +import mindspore.dataset.vision.c_transforms as C +import mindspore.dataset.transforms.c_transforms as C2 +from mindspore.communication.management import init, get_rank, get_group_size + +def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, target="Ascend"): + if target == "Ascend": + device_num, rank_id = _get_rank_info() + else: + init() + rank_id = get_rank() + device_num = get_group_size() + if device_num == 1: + ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True) + else: + ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True, + num_shards=device_num, shard_id=rank_id) + + image_size = 224 + mean = [0.485 * 255, 0.456 * 255, 0.406 * 255] + std = [0.229 * 255, 0.224 * 255, 0.225 * 255] + # define map operations + if do_train: + trans = [ + C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)), + C.RandomHorizontalFlip(prob=0.5), + C.Normalize(mean=mean, std=std), + C.HWC2CHW() + ] + else: + trans = [ + C.Decode(), + C.Resize(256), + C.CenterCrop(image_size), + C.Normalize(mean=mean, std=std), + C.HWC2CHW() + ] + type_cast_op = C2.TypeCast(mstype.int32) + ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=8) + ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) + + # apply batch operations + ds = ds.batch(batch_size, drop_remainder=True) + + # apply dataset repeat operation + ds = ds.repeat(repeat_num) + + return ds +``` + +> MindSpore支持进行多种数据处理和增强的操作,各种操作往往组合使用,具体可以参考[数据处理与数据增强](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/data_processing_and_augmentation.html)章节。 + + +## 定义网络 +本示例中使用的网络模型为ResNet50-v1.5,先定义[ResNet50网络](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py),然后使用二阶优化器自定义的算子替换`Conv2d`和 +和`Dense`算子。定义好的网络模型在在源码`src/resnet_thor.py`脚本中,自定义的算子`Conv2d_thor`和`Dense_thor`在`src/thor_layer.py`脚本中。 + +- 使用`Conv2d_thor`替换原网络模型中的`Conv2d` +- 使用`Dense_thor`替换原网络模型中的`Dense` + +> 使用THOR自定义的算子`Conv2d_thor`和`Dense_thor`是为了保存模型训练中的二阶矩阵信息,新定义的网络与原网络模型的backbone一致。 + +网络构建完成以后,在`__main__`函数中调用定义好的ResNet50: +```python +... +from src.resnet_thor import resnet50 +... +f __name__ == "__main__": + ... + # define the net + net = resnet50(class_num=config.class_num, damping=damping, loss_scale=config.loss_scale, + frequency=config.frequency, batch_size=config.batch_size) + ... +``` + + +## 定义损失函数及THOR优化器 + + +### 定义损失函数 + +MindSpore支持的损失函数有`SoftmaxCrossEntropyWithLogits`、`L1Loss`、`MSELoss`等。THOR优化器需要使用`SoftmaxCrossEntropyWithLogits`损失函数。 + +损失函数的实现步骤在`src/crossentropy.py`脚本中。这里使用了深度网络模型训练中的一个常用trick:label smoothing,通过对真实标签做平滑处理,提高模型对分类错误标签的容忍度,从而可以增加模型的泛化能力。 +```python +class CrossEntropy(_Loss): + """CrossEntropy""" + def __init__(self, smooth_factor=0., num_classes=1000): + super(CrossEntropy, self).__init__() + self.onehot = P.OneHot() + self.on_value = Tensor(1.0 - smooth_factor, mstype.float32) + self.off_value = Tensor(1.0 * smooth_factor / (num_classes - 1), mstype.float32) + self.ce = nn.SoftmaxCrossEntropyWithLogits() + self.mean = P.ReduceMean(False) + + def construct(self, logit, label): + one_hot_label = self.onehot(label, F.shape(logit)[1], self.on_value, self.off_value) + loss = self.ce(logit, one_hot_label) + loss = self.mean(loss, 0) + return loss +``` +在`__main__`函数中调用定义好的损失函数: + +```python +... +from src.crossentropy import CrossEntropy +... +if __name__ == "__main__": + ... + # define the loss function + if not config.use_label_smooth: + config.label_smooth_factor = 0.0 + loss = CrossEntropy(smooth_factor=config.label_smooth_factor, num_classes=config.class_num) + ... +``` + +### 定义优化器 + +THOR优化器的参数更新公式如下: + +$$ \theta^{t+1} = \theta^t + \alpha F^{-1}\nabla E$$ + +参数更新公式中各参数的含义如下: +- $\theta$:网络中的可训参数; +- $t$:迭代次数; +- $\alpha$:学习率值,参数的更新步长; +- $F^{-1}$:FIM矩阵,在网络中计算获得; +- $\nabla E$:一阶梯度值。 + +从参数更新公式中可以看出,THOR优化器需要额外计算的是每一层的FIM矩阵,每一层的FIM矩阵就是之前在自定义的网络模型中计算获得的。FIM矩阵可以对每一层参数更新的步长和方向进行自适应的调整,加速收敛的同时可以降低调参的复杂度。 + +```python +... +if args_opt.device_target == "Ascend": + from src.thor import THOR +else: + from src.thor import THOR_GPU as THOR +... + +if __name__ == "__main__": + ... + # learning rate setting + lr = get_model_lr(0, config.lr_init, config.lr_decay, config.lr_end_epoch, step_size, decay_epochs=39) + # define the optimizer + opt = THOR(filter(lambda x: x.requires_grad, net.get_parameters()), Tensor(lr), config.momentum, + filter(lambda x: 'matrix_A' in x.name, net.get_parameters()), + filter(lambda x: 'matrix_G' in x.name, net.get_parameters()), + filter(lambda x: 'A_inv_max' in x.name, net.get_parameters()), + filter(lambda x: 'G_inv_max' in x.name, net.get_parameters()), + config.weight_decay, config.loss_scale) + ... +``` + +## 训练网络 + +### 配置模型保存 + +MindSpore提供了callback机制,可以在训练过程中执行自定义逻辑,这里使用框架提供的`ModelCheckpoint`函数。 +`ModelCheckpoint`可以保存网络模型和参数,以便进行后续的fine-tuning操作。 +`TimeMonitor`、`LossMonitor`是MindSpore官方提供的callback函数,可以分别用于监控训练过程中单步迭代时间和`loss`值的变化。 + +```python +... +from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, TimeMonitor, LossMonitor +... +if __name__ == "__main__": + ... + # define callbacks + time_cb = TimeMonitor(data_size=step_size) + loss_cb = LossMonitor() + cb = [time_cb, loss_cb] + if config.save_checkpoint: + config_ck = CheckpointConfig(save_checkpoint_steps=config.save_checkpoint_epochs * step_size, + keep_checkpoint_max=config.keep_checkpoint_max) + ckpt_cb = ModelCheckpoint(prefix="resnet", directory=ckpt_save_dir, config=config_ck) + cb += [ckpt_cb] + ... +``` + +### 配置训练网络 + +通过MindSpore提供的`model.train`接口可以方便地进行网络的训练。THOR优化器通过降低二阶矩阵更新频率,来减少计算量,提升计算速度,故重新定义一个Model_Thor类,继承MindSpore提供的Model类。在Model_Thor类中增加二阶矩阵更新频率控制参数,用户可以通过调整该参数,优化整体的性能。 + + +```python +... +from mindspore.train.loss_scale_manager import FixedLossScaleManager +from src.model_thor import Model_Thor as Model +... + +if __name__ == "__main__": + ... + loss_scale = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False) + if target == "Ascend": + model = Model(net, loss_fn=loss, optimizer=opt, amp_level='O2', loss_scale_manager=loss_scale, + keep_batchnorm_fp32=False, metrics={'acc'}, frequency=config.frequency) + else: + model = Model(net, loss_fn=loss, optimizer=opt, loss_scale_manager=loss_scale, metrics={'acc'}, + amp_level="O2", keep_batchnorm_fp32=True, frequency=config.frequency) + ... +``` + +### 运行脚本 +训练脚本定义完成之后,调`scripts`目录下的shell脚本,启动分布式训练进程。 +#### Ascend 910 +目前MindSpore分布式在Ascend上执行采用单卡单进程运行方式,即每张卡上运行1个进程,进程数量与使用的卡的数量一致。其中,0卡在前台执行,其他卡放在后台执行。每个进程创建1个目录,目录名称为`train_parallel`+ `device_id`,用来保存日志信息,算子编译信息以及训练的checkpoint文件。下面以使用8张卡的分布式训练脚本为例,演示如何运行脚本: + +使用以下命令运行脚本: +``` +sh run_distribute_train.sh [RANK_TABLE_FILE] [DATASET_PATH] [DEVICE_NUM] +``` +脚本需要传入变量`RANK_TABLE_FILE`、`DATASET_PATH`和`DEVICE_NUM`,其中: +- `RANK_TABLE_FILE`:组网信息文件的路径。 +- `DATASET_PATH`:训练数据集路径。 +- `DEVICE_NUM`: 实际的运行卡数。 +其余环境变量请参考安装教程中的配置项。 + +训练过程中loss打印示例如下: + +```bash +... +epoch: 1 step: 5004, loss is 4.4182425 +epoch: 2 step: 5004, loss is 3.740064 +epoch: 3 step: 5004, loss is 4.0546017 +epoch: 4 step: 5004, loss is 3.7598825 +epoch: 5 step: 5004, loss is 3.3744206 +...... +epoch: 40 step: 5004, loss is 1.6907625 +epoch: 41 step: 5004, loss is 1.8217756 +epoch: 42 step: 5004, loss is 1.6453942 +... +``` + +训练完后,每张卡训练产生的checkpoint文件保存在各自训练目录下,`device_0`产生的checkpoint文件示例如下: + +```bash +└─train_parallel0 + ├─resnet-1_5004.ckpt + ├─resnet-2_5004.ckpt + │ ...... + ├─resnet-42_5004.ckpt +``` + +其中, +`*.ckpt`:指保存的模型参数文件。checkpoint文件名称具体含义:*网络名称*-*epoch数*_*step数*.ckpt。 + +#### GPU +在GPU硬件平台上,MindSpore采用OpenMPI的`mpirun`进行分布式训练,进程创建1个目录,目录名称为`train_parallel`,用来保存日志信息和训练的checkpoint文件。下面以使用8张卡的分布式训练脚本为例,演示如何运行脚本: +``` +sh run_distribute_train_gpu.sh [DATASET_PATH] [DEVICE_NUM] +``` +脚本需要传入变量`DATASET_PATH`和`DEVICE_NUM`,其中: +- `DATASET_PATH`:训练数据集路径。 +- `DEVICE_NUM`: 实际的运行卡数。 + +在GPU训练时,无需设置`DEVICE_ID`环境变量,因此在主训练脚本中不需要调用`int(os.getenv('DEVICE_ID'))`来获取卡的物理序号,同时`context`中也无需传入`device_id`。我们需要将device_target设置为GPU,并需要调用`init()`来使能NCCL。 + +训练过程中loss打印示例如下: +```bash +... +epoch: 1 step: 5004, loss is 4.2546034 +epoch: 2 step: 5004, loss is 4.0819564 +epoch: 3 step: 5004, loss is 3.7005644 +epoch: 4 step: 5004, loss is 3.2668946 +epoch: 5 step: 5004, loss is 3.023509 +...... +epoch: 36 step: 5004, loss is 1.645802 +... +``` + +训练完后,保存的模型文件示例如下: + +```bash +└─train_parallel + ├─ckpt_0 + ├─resnet-1_5004.ckpt + ├─resnet-2_5004.ckpt + │ ...... + ├─resnet-36_5004.ckpt + ...... + ├─ckpt_7 + ├─resnet-1_5004.ckpt + ├─resnet-2_5004.ckpt + │ ...... + ├─resnet-36_5004.ckpt + +``` + +## 模型推理 + +使用训练过程中保存的checkpoint文件进行推理,验证模型的泛化能力。首先通过`load_checkpoint`接口加载模型文件,然后调用`Model`的`eval`接口对输入图片类别作出预测,再与输入图片的真实类别做比较,得出最终的预测精度值。 + +### 定义推理网络 + +1. 使用`load_checkpoint`接口加载模型文件。 +2. 使用`model.eval`接口读入测试数据集,进行推理。 +3. 计算得出预测精度值。 + +```python +... +from mindspore.train.serialization import load_checkpoint, load_param_into_net +... + +if __name__ == "__main__": + ... + # define net + net = resnet(class_num=config.class_num) + net.add_flags_recursive(thor=False) + + # load checkpoint + param_dict = load_checkpoint(args_opt.checkpoint_path) + keys = list(param_dict.keys()) + for key in keys: + if "damping" in key: + param_dict.pop(key) + load_param_into_net(net, param_dict) + net.set_train(False) + + # define model + model = Model(net, loss_fn=loss, metrics={'top_1_accuracy', 'top_5_accuracy'}) + + # eval model + res = model.eval(dataset) + print("result:", res, "ckpt=", args_opt.checkpoint_path) +``` + +### 执行推理 +推理网络定义完成之后,调用`scripts`目录下的shell脚本,进行推理。 +#### Ascend 910 +在Ascend 910硬件平台上,推理的执行命令如下: +``` +sh run_eval.sh [DATASET_PATH] [CHECKPOINT_PATH] +``` +脚本需要传入变量`DATASET_PATH`和`CHECKPOINT_PATH`,其中: +- `DATASET_PATH`:推理数据集路径。 +- `CHECKPOINT_PATH`: 保存的checkpoint路径。 + +目前推理使用的是单卡(默认device 0)进行推理,推理的结果如下: +``` +result: {'top_5_accuracy': 0.9295574583866837, 'top_1_accuracy': 0.761443661971831} ckpt=train_parallel0/resnet-42_5004.ckpt +``` +- `top_5_accuracy`:对于一个输入图片,如果预测概率排名前五的标签中包含真实标签,即认为分类正确; +- `top_1_accuracy`:对于一个输入图片,如果预测概率最大的标签与真实标签相同,即认为分类正确。 +#### GPU + +在GPU硬件平台上,推理的执行命令如下: +``` +sh run_eval_gpu.sh [DATASET_PATH] [CHECKPOINT_PATH] +``` +脚本需要传入变量`DATASET_PATH`和`CHECKPOINT_PATH`,其中: +- `DATASET_PATH`:推理数据集路径。 +- `CHECKPOINT_PATH`: 保存的checkpoint路径。 + +推理的结果如下: +``` +result: {'top_5_accuracy': 0.9287972151088348, 'top_1_accuracy': 0.7597031049935979} ckpt=train_parallel/resnet-36_5004.ckpt +``` diff --git a/tutorials/source_zh_cn/advanced_use/serving.md b/tutorials/training/source_zh_cn/advanced_use/serving.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/serving.md rename to tutorials/training/source_zh_cn/advanced_use/serving.md diff --git a/tutorials/source_zh_cn/advanced_use/summary_record.md b/tutorials/training/source_zh_cn/advanced_use/summary_record.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/summary_record.md rename to tutorials/training/source_zh_cn/advanced_use/summary_record.md diff --git a/tutorials/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md b/tutorials/training/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md rename to tutorials/training/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md diff --git a/tutorials/source_zh_cn/advanced_use/use_on_the_cloud.md b/tutorials/training/source_zh_cn/advanced_use/use_on_the_cloud.md similarity index 100% rename from tutorials/source_zh_cn/advanced_use/use_on_the_cloud.md rename to tutorials/training/source_zh_cn/advanced_use/use_on_the_cloud.md diff --git a/tutorials/source_zh_cn/advanced_use/visualization_tutorials.rst b/tutorials/training/source_zh_cn/advanced_use/visualization_tutorials.rst similarity index 100% rename from tutorials/source_zh_cn/advanced_use/visualization_tutorials.rst rename to tutorials/training/source_zh_cn/advanced_use/visualization_tutorials.rst diff --git a/tutorials/source_zh_cn/conf.py b/tutorials/training/source_zh_cn/conf.py similarity index 100% rename from tutorials/source_zh_cn/conf.py rename to tutorials/training/source_zh_cn/conf.py diff --git a/tutorials/source_zh_cn/index.rst b/tutorials/training/source_zh_cn/index.rst similarity index 100% rename from tutorials/source_zh_cn/index.rst rename to tutorials/training/source_zh_cn/index.rst diff --git a/tutorials/source_zh_cn/quick_start/images/LeNet_5.jpg b/tutorials/training/source_zh_cn/quick_start/images/LeNet_5.jpg similarity index 100% rename from tutorials/source_zh_cn/quick_start/images/LeNet_5.jpg rename to tutorials/training/source_zh_cn/quick_start/images/LeNet_5.jpg diff --git a/tutorials/source_zh_cn/quick_start/images/linear_regression.gif b/tutorials/training/source_zh_cn/quick_start/images/linear_regression.gif similarity index 100% rename from tutorials/source_zh_cn/quick_start/images/linear_regression.gif rename to tutorials/training/source_zh_cn/quick_start/images/linear_regression.gif diff --git a/tutorials/source_zh_cn/quick_start/images/linear_regression_eval_datasets.png b/tutorials/training/source_zh_cn/quick_start/images/linear_regression_eval_datasets.png similarity index 100% rename from tutorials/source_zh_cn/quick_start/images/linear_regression_eval_datasets.png rename to tutorials/training/source_zh_cn/quick_start/images/linear_regression_eval_datasets.png diff --git a/tutorials/source_zh_cn/quick_start/images/model_net_and_eval_datasets.png b/tutorials/training/source_zh_cn/quick_start/images/model_net_and_eval_datasets.png similarity index 100% rename from tutorials/source_zh_cn/quick_start/images/model_net_and_eval_datasets.png rename to tutorials/training/source_zh_cn/quick_start/images/model_net_and_eval_datasets.png diff --git a/tutorials/source_zh_cn/quick_start/linear_regression.md b/tutorials/training/source_zh_cn/quick_start/linear_regression.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/linear_regression.md rename to tutorials/training/source_zh_cn/quick_start/linear_regression.md diff --git a/tutorials/source_zh_cn/quick_start/quick_start.md b/tutorials/training/source_zh_cn/quick_start/quick_start.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_start.md rename to tutorials/training/source_zh_cn/quick_start/quick_start.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video.md b/tutorials/training/source_zh_cn/quick_start/quick_video.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video.md rename to tutorials/training/source_zh_cn/quick_start/quick_video.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/ascend910.md b/tutorials/training/source_zh_cn/quick_start/quick_video/ascend910.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/ascend910.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/ascend910.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/community.md b/tutorials/training/source_zh_cn/quick_start/quick_video/community.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/community.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/community.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/cpu_operator_development.md b/tutorials/training/source_zh_cn/quick_start/quick_video/cpu_operator_development.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/cpu_operator_development.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/cpu_operator_development.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/cpu_ubuntu.md b/tutorials/training/source_zh_cn/quick_start/quick_video/cpu_ubuntu.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/cpu_ubuntu.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/cpu_ubuntu.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/cpu_windows.md b/tutorials/training/source_zh_cn/quick_start/quick_video/cpu_windows.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/cpu_windows.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/cpu_windows.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/customized_debugging.md b/tutorials/training/source_zh_cn/quick_start/quick_video/customized_debugging.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/customized_debugging.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/customized_debugging.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/gpu.md b/tutorials/training/source_zh_cn/quick_start/quick_video/gpu.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/gpu.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/gpu.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/gpu_operator_development.md b/tutorials/training/source_zh_cn/quick_start/quick_video/gpu_operator_development.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/gpu_operator_development.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/gpu_operator_development.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md b/tutorials/training/source_zh_cn/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/loading_the_dataset_and_converting_data_format.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/mindInsight_dashboard.md b/tutorials/training/source_zh_cn/quick_start/quick_video/mindInsight_dashboard.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/mindInsight_dashboard.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/mindInsight_dashboard.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/mindInsight_installation_and_common_commands.md b/tutorials/training/source_zh_cn/quick_start/quick_video/mindInsight_installation_and_common_commands.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/mindInsight_installation_and_common_commands.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/mindInsight_installation_and_common_commands.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/mindInsight_lineage_and_scalars_comparision.md b/tutorials/training/source_zh_cn/quick_start/quick_video/mindInsight_lineage_and_scalars_comparision.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/mindInsight_lineage_and_scalars_comparision.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/mindInsight_lineage_and_scalars_comparision.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/quick_start_video.md b/tutorials/training/source_zh_cn/quick_start/quick_video/quick_start_video.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/quick_start_video.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/quick_start_video.md diff --git a/tutorials/source_zh_cn/quick_start/quick_video/saving_and_loading_model_parameters.md b/tutorials/training/source_zh_cn/quick_start/quick_video/saving_and_loading_model_parameters.md similarity index 100% rename from tutorials/source_zh_cn/quick_start/quick_video/saving_and_loading_model_parameters.md rename to tutorials/training/source_zh_cn/quick_start/quick_video/saving_and_loading_model_parameters.md diff --git a/tutorials/source_zh_cn/use/custom_operator.md b/tutorials/training/source_zh_cn/use/custom_operator.md similarity index 100% rename from tutorials/source_zh_cn/use/custom_operator.md rename to tutorials/training/source_zh_cn/use/custom_operator.md diff --git a/tutorials/source_zh_cn/use/data_preparation.rst b/tutorials/training/source_zh_cn/use/data_preparation.rst similarity index 100% rename from tutorials/source_zh_cn/use/data_preparation.rst rename to tutorials/training/source_zh_cn/use/data_preparation.rst diff --git a/tutorials/source_zh_cn/use/defining_the_network.rst b/tutorials/training/source_zh_cn/use/defining_the_network.rst similarity index 100% rename from tutorials/source_zh_cn/use/defining_the_network.rst rename to tutorials/training/source_zh_cn/use/defining_the_network.rst diff --git a/tutorials/source_zh_cn/use/image_loading.md b/tutorials/training/source_zh_cn/use/image_loading.md similarity index 100% rename from tutorials/source_zh_cn/use/image_loading.md rename to tutorials/training/source_zh_cn/use/image_loading.md diff --git a/tutorials/source_zh_cn/use/images/dataset_pipeline.eddx b/tutorials/training/source_zh_cn/use/images/dataset_pipeline.eddx similarity index 100% rename from tutorials/source_zh_cn/use/images/dataset_pipeline.eddx rename to tutorials/training/source_zh_cn/use/images/dataset_pipeline.eddx diff --git a/tutorials/source_zh_cn/use/images/map.eddx b/tutorials/training/source_zh_cn/use/images/map.eddx similarity index 100% rename from tutorials/source_zh_cn/use/images/map.eddx rename to tutorials/training/source_zh_cn/use/images/map.eddx diff --git a/tutorials/source_zh_cn/use/images/mnist_5.png b/tutorials/training/source_zh_cn/use/images/mnist_5.png similarity index 100% rename from tutorials/source_zh_cn/use/images/mnist_5.png rename to tutorials/training/source_zh_cn/use/images/mnist_5.png diff --git a/tutorials/source_zh_cn/use/images/mnist_5_resize_crop.png b/tutorials/training/source_zh_cn/use/images/mnist_5_resize_crop.png similarity index 100% rename from tutorials/source_zh_cn/use/images/mnist_5_resize_crop.png rename to tutorials/training/source_zh_cn/use/images/mnist_5_resize_crop.png diff --git a/tutorials/source_zh_cn/use/multi_platform_inference.md b/tutorials/training/source_zh_cn/use/multi_platform_inference.md similarity index 100% rename from tutorials/source_zh_cn/use/multi_platform_inference.md rename to tutorials/training/source_zh_cn/use/multi_platform_inference.md diff --git a/tutorials/source_zh_cn/use/saving_and_loading_model_parameters.md b/tutorials/training/source_zh_cn/use/saving_and_loading_model_parameters.md similarity index 100% rename from tutorials/source_zh_cn/use/saving_and_loading_model_parameters.md rename to tutorials/training/source_zh_cn/use/saving_and_loading_model_parameters.md diff --git a/tutorials/source_zh_cn/use/text_loading.md b/tutorials/training/source_zh_cn/use/text_loading.md similarity index 100% rename from tutorials/source_zh_cn/use/text_loading.md rename to tutorials/training/source_zh_cn/use/text_loading.md -- Gitee From 0da145e5f69818f5e69833c2873ed3b5c6a3c7ae Mon Sep 17 00:00:00 2001 From: caozhou Date: Mon, 14 Sep 2020 11:38:29 +0800 Subject: [PATCH 006/100] delete DepthwiseConv2d in docs r1.0 --- api/source_zh_cn/programming_guide/cell.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/source_zh_cn/programming_guide/cell.md b/api/source_zh_cn/programming_guide/cell.md index 8570e80c0a..698e7f5995 100644 --- a/api/source_zh_cn/programming_guide/cell.md +++ b/api/source_zh_cn/programming_guide/cell.md @@ -127,7 +127,7 @@ MindSpore框架在nn的layer层内置了丰富的接口,主要内容如下: 卷积层提供了一些卷积计算的功能,如普通卷积,深度卷积和卷积转置等。 - 主要接口有Conv2d,Conv1d,Conv2dTranspose,DepthwiseConv2d,Conv1dTranspose等。 + 主要接口有Conv2d,Conv1d,Conv2dTranspose,Conv1dTranspose等。 - 池化层: -- Gitee From 91dab2bbdba359a038e91ab79d81e7a703110073 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 11 Sep 2020 23:53:37 -0400 Subject: [PATCH 007/100] Fix API changes for v1.0 --- .../source_zh_cn/augmentation.md | 34 ++++++------ .../source_zh_cn/auto_augmentation.md | 2 +- .../source_zh_cn/dataset_conversion.md | 8 +-- .../source_zh_cn/pipeline.md | 2 +- .../source_zh_cn/tokenizer.md | 2 +- resource/api_mapping.md | 18 +++---- .../computer_vision_application.ipynb | 6 +-- .../customized_debugging_information.ipynb | 14 ++--- .../data_loading_enhancement.ipynb | 21 ++++---- .../notebook/debugging_in_pynative_mode.ipynb | 14 ++--- .../calculate_and_datagraphic.ipynb | 26 ++++----- ...nsight_image_histogram_scalar_tensor.ipynb | 18 +++---- ...sight_model_lineage_and_data_lineage.ipynb | 16 +++--- tutorials/notebook/mixed_precision.ipynb | 8 +-- tutorials/notebook/model_security.ipynb | 14 ++--- ..._the_performance_of_data_preparation.ipynb | 6 +-- tutorials/notebook/quick_start.ipynb | 10 ++-- ...chronization_training_and_evaluation.ipynb | 8 +-- .../computer_vision_application.md | 4 +- .../source_en/advanced_use/hub_tutorial.md | 54 +++++++++---------- .../source_en/advanced_use/model_security.md | 2 +- .../data_processing_and_augmentation.md | 2 +- .../advanced_use/auto_augmentation.md | 10 ++-- .../source_zh_cn/advanced_use/cache.md | 6 +-- .../computer_vision_application.md | 4 +- .../advanced_use/differential_privacy.md | 21 ++++---- .../source_zh_cn/advanced_use/hub_tutorial.md | 51 +++++++++--------- .../advanced_use/model_security.md | 2 +- .../source_zh_cn/use/image_loading.md | 6 +-- .../training/source_zh_cn/use/text_loading.md | 2 +- .../resnet50_distributed_training.py | 4 +- tutorials/tutorial_code/lenet/lenet.py | 10 ++-- .../tutorial_code/resnet/cifar_resnet50.py | 4 +- .../tutorial_code/sample_for_cloud/dataset.py | 4 +- 34 files changed, 206 insertions(+), 207 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/augmentation.md b/docs/programming_guide/source_zh_cn/augmentation.md index 74fd8b0ba8..35920d2dfb 100644 --- a/docs/programming_guide/source_zh_cn/augmentation.md +++ b/docs/programming_guide/source_zh_cn/augmentation.md @@ -10,7 +10,7 @@ - [Resize](#resize) - [Invert](#invert) - [py_transforms](#py_transforms) - - [ComposeOp](#composeop) + - [Compose](#compose) - [使用说明](#使用说明) @@ -40,7 +40,7 @@ MindSpore目前支持的常用数据增强算子如下表所示,更多数据 | py_transforms | RandomCrop | 在图像随机位置裁剪指定大小子图像。 | | | Resize | 将图像缩放到指定大小。 | | | Invert | 将图像进行反相。 | -| |ComposeOp | 将列表中的数据增强操作依次执行。 | +| |Compose | 将列表中的数据增强操作依次执行。 | ## c_transforms @@ -62,7 +62,7 @@ MindSpore目前支持的常用数据增强算子如下表所示,更多数据 import matplotlib.pyplot as plt import mindspore.dataset as ds -import mindspore.dataset.transforms.vision.c_transforms as c_trans +import mindspore.dataset.vision.c_transforms as c_trans # 下载Cifar10数据集,将其解压到Cifar10Data目录 DATA_DIR = "../data/dataset/testCifar10Data2" @@ -77,7 +77,7 @@ dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) random_crop = c_trans.RandomCrop([10, 10]) # 使用map算子将其作用到数据管道的数据集中 -dataset2 = dataset1.map(input_columns=["image"], operations=random_crop) +dataset2 = dataset1.map(operations=random_crop, input_columns=["image"]) # 启动数据管道,输出3个样本数据 image_list1, label_list1 = [], [] @@ -130,7 +130,7 @@ Cropped image Shape: (10, 10, 3) , Cropped label: 9 import matplotlib.pyplot as plt import mindspore.dataset as ds -import mindspore.dataset.transforms.vision.c_transforms as c_trans +import mindspore.dataset.vision.c_transforms as c_trans # 设置全局随机种子 ds.config.set_seed(6) @@ -148,7 +148,7 @@ dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) random_horizontal_flip = c_trans.RandomHorizontalFlip(prob=0.8) # 使用map算子将其作用到数据管道的数据集中 -dataset2 = dataset1.map(input_columns=["image"], operations=random_horizontal_flip) +dataset2 = dataset1.map(operations=random_horizontal_flip, input_columns=["image"]) # 启动数据管道,输出4个样本数据 image_list1, label_list1 = [], [] @@ -205,7 +205,7 @@ Flipped image Shape: (32, 32, 3) , Flipped label: 9 import matplotlib.pyplot as plt import mindspore.dataset as ds -import mindspore.dataset.transforms.vision.c_transforms as c_trans +import mindspore.dataset.vision.c_transforms as c_trans # 下载MNIST数据集,将其解压到MnistData目录 DATA_DIR = "../data/dataset/testMnistData2" @@ -217,7 +217,7 @@ dataset1 = ds.MnistDataset(DATA_DIR, num_samples=4, shuffle=False) resize = c_trans.Resize(size=[101, 101]) # 使用map算子将其作用到数据管道的数据集中 -dataset2 = dataset1.map(input_columns=["image"], operations=resize) +dataset2 = dataset1.map(operations=resize, input_columns=["image"]) # 启动数据管道 image_list1, label_list1 = [], [] @@ -270,7 +270,7 @@ Flipped image Shape: (101, 101, 1) , Flipped label: 1 import matplotlib.pyplot as plt import mindspore.dataset as ds -import mindspore.dataset.transforms.vision.c_transforms as c_trans +import mindspore.dataset.vision.c_transforms as c_trans # 设置全局随机种子 ds.config.set_seed(8) @@ -288,7 +288,7 @@ resize = c_trans.Resize(size=[101, 101]) invert = c_trans.Invert() # 使用map算子将其作用到数据管道的数据集中(两个算子按顺序起作用) -dataset2 = dataset1.map(input_columns=["image"], operations=[resize, invert]) +dataset2 = dataset1.map(operations=[resize, invert], input_columns=["image"]) # 启动数据管道 image_list1, label_list1 = [], [] @@ -336,23 +336,23 @@ Flipped image Shape: (32, 32, 3) , Flipped label: 5 下面将简要介绍几种常用的py_transforms模块数据增强算子的使用方法,更多的py_transforms模块数据增强算子参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html#module-mindspore.dataset.vision.py_transforms)。 -### ComposeOp +### Compose ```python # 对输入图像进行解码,缩放组合操作 import matplotlib.pyplot as plt import mindspore.dataset as ds -import mindspore.dataset.transforms.vision.py_transforms as py_trans - +import mindspore.dataset.vision.py_transforms as py_trans +from mindspore.dataset.transforms.py_transforms import Compose # 设置全局随机种子 ds.config.set_seed(8) # 图像数据集目录 DATA_DIR = "../data/dataset/testPK/data" -# 使用ImageFolderDatasetV2读取数据集,获取5个样本 -dataset1 = ds.ImageFolderDatasetV2(DATA_DIR, num_samples=5, shuffle=True) +# 使用ImageFolderDataset读取数据集,获取5个样本 +dataset1 = ds.ImageFolderDataset(DATA_DIR, num_samples=5, shuffle=True) # 创建一组数据增强算子的集合 transforms_list = [ @@ -360,10 +360,10 @@ transforms_list = [ py_trans.Resize(size=(200,200)), # 缩放图像到[200, 200]大小 py_trans.ToTensor() # 将PIL图像转换到Numpy ] -compose_trans = py_trans.ComposeOp(transforms_list) +compose_trans = Compose(transforms_list) # 使用map算子将其作用到数据管道的数据集中 -dataset2 = dataset1.map(input_columns=["image"], operations=compose_trans()) +dataset2 = dataset1.map(operations=compose_trans, input_columns=["image"]) # 启动数据管道,输出5个样本数据 image_list, label_list = [], [] diff --git a/docs/programming_guide/source_zh_cn/auto_augmentation.md b/docs/programming_guide/source_zh_cn/auto_augmentation.md index 57ec65060e..ef71980b51 100644 --- a/docs/programming_guide/source_zh_cn/auto_augmentation.md +++ b/docs/programming_guide/source_zh_cn/auto_augmentation.md @@ -67,7 +67,7 @@ Mindspore的`sync_wait`接口支持按batch或epoch粒度来调整数据增强 1. 用户预先定义class`Augment`,其中`preprocess`为`map`操作中的自定义数据增强函数,`update`为更新数据增强策略的回调函数。 ```python - import mindspore.dataset.transforms.vision.py_transforms as transforms + import mindspore.dataset.vision.py_transforms as transforms import mindspore.dataset as de import numpy as np diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index 59e68a061f..255bab0f4d 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -41,7 +41,7 @@ import os import mindspore.dataset as ds from mindspore.mindrecord import FileWriter - import mindspore.dataset.transforms.vision.c_transforms as vision + import mindspore.dataset.vision.c_transforms as vision from PIL import Image ################################ 生成MindRecord文件 ################################ @@ -91,7 +91,7 @@ data_set = ds.MindDataset(dataset_file=mindrecord_filename) # 创建读取对象,默认开启shuffle decode_op = vision.Decode() - data_set = data_set.map(input_columns=["data"], operations=decode_op, num_parallel_workers=2) # 解码data字段 + data_set = data_set.map(operations=decode_op, input_columns=["data"], num_parallel_workers=2) # 解码data字段 count = 0 for item in data_set.create_dict_iterator(): # 循环读取MindRecord中所有数据 print("sample: {}".format(item)) @@ -421,7 +421,7 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 import os import mindspore.dataset as ds from mindspore.mindrecord import TFRecordToMR - import mindspore.dataset.transforms.vision.c_transforms as vision + import mindspore.dataset.vision.c_transforms as vision from PIL import Image import tensorflow as tf # 需要tensorflow >= 2.1.0 @@ -512,7 +512,7 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) # 创建读取对象,默认开启shuffle decode_op = vision.Decode() - data_set = data_set.map(input_columns=["image_bytes"], operations=decode_op, num_parallel_workers=2) # 解码图像字段 + data_set = data_set.map(operations=decode_op, input_columns=["image_bytes"], num_parallel_workers=2) # 解码图像字段 count = 0 for item in data_set.create_dict_iterator(): # 循环读取MindRecord中所有数据 print("sample: {}".format(item)) diff --git a/docs/programming_guide/source_zh_cn/pipeline.md b/docs/programming_guide/source_zh_cn/pipeline.md index bd8af3408a..bb87c70caf 100644 --- a/docs/programming_guide/source_zh_cn/pipeline.md +++ b/docs/programming_guide/source_zh_cn/pipeline.md @@ -111,7 +111,7 @@ print("") # 为数据集创建一个映射操作 # input_columns指定要处理的列,operation指定映射函数 -dataset = dataset.map(input_columns=["data"], operations=pyfunc) +dataset = dataset.map(operations=pyfunc, input_columns=["data"]) # 创建数据管道,输出映射后的数据 for data in dataset.create_dict_iterator(): diff --git a/docs/programming_guide/source_zh_cn/tokenizer.md b/docs/programming_guide/source_zh_cn/tokenizer.md index 8ac94e6a54..225ce08707 100644 --- a/docs/programming_guide/source_zh_cn/tokenizer.md +++ b/docs/programming_guide/source_zh_cn/tokenizer.md @@ -179,7 +179,7 @@ tokenizer_op = text.JiebaTokenizer(HMM_FILE, MP_FILE) #打印分词后的数据输出 print("------------------------after tokenize-----------------------------") -dataset = dataset.map(input_columns=["text"], operations=jieba_op, num_parallel_workers=1) +dataset = dataset.map(operations=jieba_op, input_columns=["text"], num_parallel_workers=1) for i in dataset.create_dict_iterator(num_epochs=1): token = text.to_str(i['text']) diff --git a/resource/api_mapping.md b/resource/api_mapping.md index 0eed65d611..3f4a30cd61 100644 --- a/resource/api_mapping.md +++ b/resource/api_mapping.md @@ -36,7 +36,7 @@ Mapping between PyTorch APIs and MindSpore APIs, which is provided by the commun | torch.expm1 | mindspore.ops.operations.Expm1 | | torch.eye | mindspore.ops.operations.Eye | | torch.flatten | mindspore.ops.operations.Flatten | -| torch.flip | mindspore.ops.operations.ReverseV2 +| torch.flip | mindspore.ops.operations.ReverseV2 | | torch.floor | mindspore.ops.operations.Floor | | torch.fmod | mindspore.ops.operations.Mod | | torch.linspace | mindspore.nn.LinSpace | @@ -167,13 +167,13 @@ Mapping between PyTorch APIs and MindSpore APIs, which is provided by the commun | torch.utils.data.distributed.DistributedSampler | mindspore.dataset.DistributedSampler | | torch.zeros | mindspore.ops.operations.ZerosLike | | torch.zeros_like | mindspore.ops.operations.ZerosLike | -| torchvision.datasets.ImageFolder | mindspore.dataset.ImageFolderDatasetV2 | +| torchvision.datasets.ImageFolder | mindspore.dataset.ImageFolderDataset | | torchvision.ops.nms | mindspore.ops.operations.NMSWithMask | | torchvision.ops.roi_align | mindspore.ops.operations.ROIAlign | -| torchvision.transforms.CenterCrop | mindspore.dataset.vision.py_transforms.CenterCrop | -| torchvision.transforms.ColorJitter | mindspore.dataset.vision.py_transforms.RandomColorAdjust | -| torchvision.transforms.Compose | mindspore.dataset.vision.py_transforms.Compose | -| torchvision.transforms.Normalize | mindspore.dataset.vision.py_transforms.Normalize | -| torchvision.transforms.RandomHorizontalFlip | mindspore.dataset.vision.py_transforms.RandomHorizontalFlip | -| torchvision.transforms.Resize | mindspore.dataset.vision.py_transforms.Resize | -| torchvision.transforms.ToTensor | mindspore.dataset.vision.py_transforms.ToTensor | +| torchvision.transforms.CenterCrop | mindspore.dataset.vision.py_transforms.CenterCrop | +| torchvision.transforms.ColorJitter | mindspore.dataset.vision.py_transforms.RandomColorAdjust | +| torchvision.transforms.Compose | mindspore.dataset.transforms.py_transforms.Compose | +| torchvision.transforms.Normalize | mindspore.dataset.vision.py_transforms.Normalize | +| torchvision.transforms.RandomHorizontalFlip | mindspore.dataset.vision.py_transforms.RandomHorizontalFlip | +| torchvision.transforms.Resize | mindspore.dataset.vision.py_transforms.Resize | +| torchvision.transforms.ToTensor | mindspore.dataset.vision.py_transforms.ToTensor | diff --git a/tutorials/notebook/computer_vision_application.ipynb b/tutorials/notebook/computer_vision_application.ipynb index 6d8dfd2d87..17065fcbb5 100644 --- a/tutorials/notebook/computer_vision_application.ipynb +++ b/tutorials/notebook/computer_vision_application.ipynb @@ -213,7 +213,7 @@ "import mindspore.common.dtype as mstype\n", "import mindspore.ops.functional as F\n", "import mindspore.dataset as ds\n", - "import mindspore.dataset.transforms.vision.c_transforms as C\n", + "import mindspore.dataset.vision.c_transforms as C\n", "import mindspore.dataset.transforms.c_transforms as C2\n", "\n", "\n", @@ -252,8 +252,8 @@ " changeswap_op]\n", "\n", " # Apply map operations on images\n", - " cifar_ds = cifar_ds.map(input_columns=\"label\", operations=type_cast_op)\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=c_trans)\n", + " cifar_ds = cifar_ds.map(operations=type_cast_op, input_columns=\"label\")\n", + " cifar_ds = cifar_ds.map(operations=c_trans, input_columns=\"image\")\n", "\n", " # Apply shuffle operations\n", " cifar_ds = cifar_ds.shuffle(buffer_size=10)\n", diff --git a/tutorials/notebook/customized_debugging_information.ipynb b/tutorials/notebook/customized_debugging_information.ipynb index 44be7bd3a7..b05388f1b4 100644 --- a/tutorials/notebook/customized_debugging_information.ipynb +++ b/tutorials/notebook/customized_debugging_information.ipynb @@ -84,9 +84,9 @@ "outputs": [], "source": [ "import mindspore.dataset as ds\n", - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "from mindspore.dataset.transforms.vision import Inter\n", + "from mindspore.dataset.vision import Inter\n", "from mindspore.common import dtype as mstype\n", "\n", "def create_dataset(data_path, batch_size=32, repeat_size=1,\n", @@ -116,11 +116,11 @@ " type_cast_op = C.TypeCast(mstype.int32)\n", "\n", " # apply map operations on images\n", - " mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\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_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", " buffer_size = 10000\n", diff --git a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb index fb56262084..125d1cc4f1 100644 --- a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb +++ b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb @@ -343,7 +343,7 @@ " print(data[\"data\"])\n", "\n", "func = lambda x:x**2\n", - "ds11 = ds10.map(input_columns=\"data\",operations=func)\n", + "ds11 = ds10.map(operations=func, input_columns=\"data\")\n", "print(\"After map:\")\n", "for data in ds11.create_dict_iterator():\n", " print(data[\"data\"])" @@ -449,7 +449,7 @@ "outputs": [], "source": [ "DATA_DIR = \"./enhance_images\"\n", - "ds1 = ds.ImageFolderDatasetV2(DATA_DIR, decode=True)" + "ds1 = ds.ImageFolderDataset(DATA_DIR, decode=True)" ] }, { @@ -465,8 +465,8 @@ "metadata": {}, "outputs": [], "source": [ - "from mindspore.dataset.transforms.vision import Inter\n", - "import mindspore.dataset.transforms.vision.c_transforms as transforms" + "from mindspore.dataset.vision import Inter\n", + "import mindspore.dataset.vision.c_transforms as transforms" ] }, { @@ -476,7 +476,7 @@ "outputs": [], "source": [ "resize_op = transforms.Resize(size=(800,800), interpolation=Inter.LINEAR)\n", - "ds2 = ds1.map(input_columns=\"image\", operations=resize_op)" + "ds2 = ds1.map(operations=resize_op, input_columns=\"image\")" ] }, { @@ -537,14 +537,15 @@ "metadata": {}, "outputs": [], "source": [ - "import mindspore.dataset.transforms.vision.py_transforms as transforms" + "from mindspore.dataset.transforms.py_transforms import Compose" + "import mindspore.dataset.vision.py_transforms as transforms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "2. 定义数据增强算子,通过`ComposeOp`接口将多个数据增强组合使用。" + "2. 定义数据增强算子,通过`Compose`接口将多个数据增强组合使用。" ] }, { @@ -578,15 +579,15 @@ } ], "source": [ - "ds3 = ds.ImageFolderDatasetV2(DATA_DIR)\n", + "ds3 = ds.ImageFolderDataset(DATA_DIR)\n", "\n", "transforms_list = [\n", " transforms.Decode(), # Decode images to PIL format.\n", " transforms.RandomCrop(size=(800,800)),\n", " transforms.ToTensor() # Convert PIL images to Numpy ndarray.\n", "]\n", - "compose = transforms.ComposeOp(transforms_list)\n", - "ds4 = ds3.map(input_columns=\"image\", operations=compose())\n", + "compose = Compose(transforms_list)\n", + "ds4 = ds3.map(operations=compose, input_columns=\"image\")\n", "for data in ds4.create_dict_iterator():\n", " imgplot_resized = plt.imshow(data[\"image\"].transpose(1, 2, 0))\n", " plt.show()" diff --git a/tutorials/notebook/debugging_in_pynative_mode.ipynb b/tutorials/notebook/debugging_in_pynative_mode.ipynb index ce3d50557b..c5e9993c98 100644 --- a/tutorials/notebook/debugging_in_pynative_mode.ipynb +++ b/tutorials/notebook/debugging_in_pynative_mode.ipynb @@ -92,9 +92,9 @@ "metadata": {}, "outputs": [], "source": [ - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "from mindspore.dataset.transforms.vision import Inter\n", + "from mindspore.dataset.vision import Inter\n", "from mindspore.common import dtype as mstype\n", "import mindspore.dataset as ds\n", "import numpy as np\n", @@ -126,11 +126,11 @@ " type_cast_op = C.TypeCast(mstype.int32)\n", "\n", " # using map method to apply operations to a dataset\n", - " mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\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_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", " # process the generated dataset\n", " buffer_size = 10000\n", diff --git a/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb b/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb index 39bffb88e5..2e9bf71b08 100644 --- a/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb +++ b/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb @@ -142,9 +142,9 @@ "outputs": [], "source": [ "import mindspore.dataset as ds\n", - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "from mindspore.dataset.transforms.vision import Inter\n", + "from mindspore.dataset.vision import Inter\n", "from mindspore.common import dtype as mstype\n", "\n", "\n", @@ -177,11 +177,11 @@ " type_cast_op = C.TypeCast(mstype.int32)\n", "\n", " # using map method to apply operations to a dataset\n", - " mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\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_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", " # process the generated dataset\n", " buffer_size = 10000\n", @@ -368,11 +368,11 @@ "2. 下面代码为上面的 `create_dataset` 函数中作数据预处理与数据增强的相关操作。可以从数据图中清晰地看到数据处理的流程。通过查看数据图,可以帮助分析是否存在不恰当的数据处理流程。\n", "\n", "```\n", - "mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - "mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n", - "mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n", - "mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n", - "mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\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_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", "mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script\n", "mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)\n", @@ -418,4 +418,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb b/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb index 082a64b00e..3b0654081e 100644 --- a/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb +++ b/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb @@ -157,7 +157,7 @@ "source": [ "import mindspore.dataset as ds\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "from mindspore.common import dtype as mstype\n", "\n", "\n", @@ -177,14 +177,14 @@ " random_horizontal_op = CV.RandomHorizontalFlip()\n", " channel_swap_op = CV.HWC2CHW()\n", " typecast_op = C.TypeCast(mstype.int32)\n", - " cifar_ds = cifar_ds.map(input_columns=\"label\", operations=typecast_op)\n", + " cifar_ds = cifar_ds.map(operations=typecast_op, input_columns=\"label\")\n", " if status == \"train\":\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=random_crop_op)\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=random_horizontal_op)\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=resize_op)\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=rescale_op)\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=normalize_op)\n", - " cifar_ds = cifar_ds.map(input_columns=\"image\", operations=channel_swap_op)\n", + " cifar_ds = cifar_ds.map(operations=random_crop_op, input_columns=\"image\")\n", + " cifar_ds = cifar_ds.map(operations=random_horizontal_op, input_columns=\"image\")\n", + " cifar_ds = cifar_ds.map(operations=resize_op, input_columns=\"image\")\n", + " cifar_ds = cifar_ds.map(operations=rescale_op, input_columns=\"image\")\n", + " cifar_ds = cifar_ds.map(operations=normalize_op, input_columns=\"image\")\n", + " cifar_ds = cifar_ds.map(operations=channel_swap_op, input_columns=\"image\")\n", "\n", " cifar_ds = cifar_ds.shuffle(buffer_size=1000)\n", " cifar_ds = cifar_ds.batch(batch_size, drop_remainder=True)\n", @@ -1282,4 +1282,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb b/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb index b76c1500a9..d8a27986e8 100644 --- a/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb +++ b/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb @@ -165,9 +165,9 @@ "metadata": {}, "outputs": [], "source": [ - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "from mindspore.dataset.transforms.vision import Inter\n", + "from mindspore.dataset.vision import Inter\n", "from mindspore.common import dtype as mstype\n", "import mindspore.dataset as ds\n", "\n", @@ -200,11 +200,11 @@ " type_cast_op = C.TypeCast(mstype.int32)\n", "\n", " # using map method to apply operations to a dataset\n", - " mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\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_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", " # process the generated dataset\n", " buffer_size = 10000\n", @@ -493,4 +493,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/tutorials/notebook/mixed_precision.ipynb b/tutorials/notebook/mixed_precision.ipynb index 149d1ebf8a..a595551727 100644 --- a/tutorials/notebook/mixed_precision.ipynb +++ b/tutorials/notebook/mixed_precision.ipynb @@ -196,7 +196,7 @@ "import os\n", "import mindspore.common.dtype as mstype\n", "import mindspore.dataset.engine as de\n", - "import mindspore.dataset.transforms.vision.c_transforms as C\n", + "import mindspore.dataset.vision.c_transforms as C\n", "import mindspore.dataset.transforms.c_transforms as C2\n", "\n", "def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, target=\"GPU\"):\n", @@ -220,8 +220,8 @@ "\n", " type_cast_op = C2.TypeCast(mstype.int32)\n", "\n", - " ds = ds.map(input_columns=\"label\", num_parallel_workers=8, operations=type_cast_op)\n", - " ds = ds.map(input_columns=\"image\", num_parallel_workers=8, operations=trans)\n", + " ds = ds.map(operations=type_cast_op, input_columns=\"label\", num_parallel_workers=8)\n", + " ds = ds.map(operations=trans, input_columns=\"image\", num_parallel_workers=8)\n", "\n", " # apply batch operations\n", " ds = ds.batch(batch_size, drop_remainder=True)\n", @@ -991,4 +991,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/tutorials/notebook/model_security.ipynb b/tutorials/notebook/model_security.ipynb index d958155df7..53f79dfe40 100644 --- a/tutorials/notebook/model_security.ipynb +++ b/tutorials/notebook/model_security.ipynb @@ -184,9 +184,9 @@ "outputs": [], "source": [ "import mindspore.dataset as ds\n", - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "from mindspore.dataset.transforms.vision import Inter\n", + "from mindspore.dataset.vision import Inter\n", "from mindspore.common import dtype as mstype\n", "\n", "\n", @@ -214,16 +214,16 @@ " # apply map operations on images\n", " if not sparse:\n", " one_hot_enco = C.OneHot(10)\n", - " ds1 = ds1.map(input_columns=\"label\", operations=one_hot_enco,\n", + " ds1 = ds1.map(operations=one_hot_enco,\n", input_columns=\"label\", " num_parallel_workers=num_parallel_workers)\n", " type_cast_op = C.TypeCast(mstype.float32)\n", - " ds1 = ds1.map(input_columns=\"label\", operations=type_cast_op,\n", + " ds1 = ds1.map(operations=type_cast_op,\n", input_columns=\"label\", " num_parallel_workers=num_parallel_workers)\n", - " ds1 = ds1.map(input_columns=\"image\", operations=resize_op,\n", + " ds1 = ds1.map(operations=resize_op,\n", input_columns=\"image\", " num_parallel_workers=num_parallel_workers)\n", - " ds1 = ds1.map(input_columns=\"image\", operations=rescale_op,\n", + " ds1 = ds1.map(operations=rescale_op,\n", input_columns=\"image\", " num_parallel_workers=num_parallel_workers)\n", - " ds1 = ds1.map(input_columns=\"image\", operations=hwc2chw_op,\n", + " ds1 = ds1.map(operations=hwc2chw_op,\n", input_columns=\"image\", " num_parallel_workers=num_parallel_workers)\n", "\n", " # apply DatasetOps\n", diff --git a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb index dd9aa3ad20..4e92276777 100644 --- a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb +++ b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb @@ -600,7 +600,7 @@ ], "source": [ "import mindspore.dataset.transforms.c_transforms as c_transforms\n", - "import mindspore.dataset.transforms.vision.c_transforms as C\n", + "import mindspore.dataset.vision.c_transforms as C\n", "import matplotlib.pyplot as plt\n", "cifar10_path = \"./dataset/Cifar10Data/cifar-10-batches-bin/\"\n", "\n", @@ -608,7 +608,7 @@ "cifar10_dataset = ds.Cifar10Dataset(cifar10_path,num_parallel_workers=4)\n", "transforms = C.RandomResizedCrop((800,800))\n", "# apply the transform to the dataset through dataset.map()\n", - "cifar10_dataset = cifar10_dataset.map(input_columns=\"image\",operations=transforms,num_parallel_workers=4)\n", + "cifar10_dataset = cifar10_dataset.map(operations=transforms,input_columns=\"image\",num_parallel_workers=4)\n", "\n", "data = next(cifar10_dataset.create_dict_iterator())\n", "plt.imshow(data[\"image\"])\n", @@ -657,7 +657,7 @@ " print(data[\"data\"])\n", "\n", "func = lambda x:x**2\n", - "ds4 = ds3.map(input_columns=\"data\",operations=func,python_multiprocessing=True,num_parallel_workers=4)\n", + "ds4 = ds3.map(operations=func,input_columns=\"data\",python_multiprocessing=True,num_parallel_workers=4)\n", "print(\"after map:\")\n", "for data in ds4.create_dict_iterator():\n", " print(data[\"data\"])" diff --git a/tutorials/notebook/quick_start.ipynb b/tutorials/notebook/quick_start.ipynb index 80dec971e2..18590d37b5 100644 --- a/tutorials/notebook/quick_start.ipynb +++ b/tutorials/notebook/quick_start.ipynb @@ -336,11 +336,11 @@ " type_cast_op = C.TypeCast(mstype.int32)\n", "\n", " # using map to apply operations to a dataset\n", - " mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\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_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", " # process the generated dataset\n", " buffer_size = 10000\n", diff --git a/tutorials/notebook/synchronization_training_and_evaluation.ipynb b/tutorials/notebook/synchronization_training_and_evaluation.ipynb index 80f8573919..d3670b2382 100644 --- a/tutorials/notebook/synchronization_training_and_evaluation.ipynb +++ b/tutorials/notebook/synchronization_training_and_evaluation.ipynb @@ -94,9 +94,9 @@ "source": [ "import os\n", "import mindspore.dataset as ds\n", - "import mindspore.dataset.transforms.vision.c_transforms as CV\n", + "import mindspore.dataset.vision.c_transforms as CV\n", "import mindspore.dataset.transforms.c_transforms as C\n", - "from mindspore.dataset.transforms.vision import Inter\n", + "from mindspore.dataset.vision import Inter\n", "from mindspore.common import dtype as mstype\n", "\n", "def create_dataset(data_path, batch_size=32, repeat_size=1,\n", @@ -112,8 +112,8 @@ " type_cast_op = C.TypeCast(mstype.int32) \n", "\n", " # apply map operations on images\n", - " mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n", - " mnist_ds = mnist_ds.map(input_columns=\"image\", operations=[resize_op,rescale_op,rescale_nml_op,hwc2chw_op],\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,rescale_op,rescale_nml_op,hwc2chw_op],\n", input_columns=\"image\", " num_parallel_workers=num_parallel_workers)\n", "\n", " # apply DatasetOps\n", diff --git a/tutorials/training/source_en/advanced_use/computer_vision_application.md b/tutorials/training/source_en/advanced_use/computer_vision_application.md index 8ead2a76fd..ac9c06bd00 100644 --- a/tutorials/training/source_en/advanced_use/computer_vision_application.md +++ b/tutorials/training/source_en/advanced_use/computer_vision_application.md @@ -119,8 +119,8 @@ tar -zvxf cifar-10-binary.tar.gz c_trans += [resize_op, rescale_op, normalize_op, changeswap_op] # apply map operations on images - cifar_ds = cifar_ds.map(input_columns="label", operations=type_cast_op) - cifar_ds = cifar_ds.map(input_columns="image", operations=c_trans) + cifar_ds = cifar_ds.map(operations=type_cast_op, input_columns="label") + cifar_ds = cifar_ds.map(operations=c_trans, input_columns="image") ``` 3. Shuffle and batch process the data. diff --git a/tutorials/training/source_en/advanced_use/hub_tutorial.md b/tutorials/training/source_en/advanced_use/hub_tutorial.md index a47f655f0d..a441dd7fdc 100644 --- a/tutorials/training/source_en/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_en/advanced_use/hub_tutorial.md @@ -17,17 +17,17 @@ ### 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. +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. +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. +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). +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: @@ -44,7 +44,7 @@ We accept publishing models to MindSpore Hub via PR in `hub` repo. Here we use G 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). +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 @@ -62,8 +62,9 @@ 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 mindspore.dataset.transforms import Compose from PIL import Image +import mindspore.dataset.vision.py_transforms as py_transforms import cv2 context.set_context(mode=context.GRAPH_MODE, @@ -73,7 +74,7 @@ context.set_context(mode=context.GRAPH_MODE, model = "mindspore/ascend/0.7/googlenet_v1_cifar10" image = Image.open('cifar10/a.jpg') -transforms = py_transforms.ComposeOp([py_transforms.ToTensor()]) +transforms = Compose([py_transforms.ToTensor()]) # Initialize the number of classes based on the pre-trained model. network = mshub.load(model, num_classes=10) @@ -83,11 +84,11 @@ 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.* +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: +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`. +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*. @@ -96,10 +97,10 @@ We use Googlenet as example to illustrate how to load a model trained on ImageNe 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) ``` @@ -109,12 +110,12 @@ We use Googlenet as example to illustrate how to load a model trained on ImageNe ```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]) ``` @@ -122,14 +123,14 @@ We use Googlenet as example to illustrate how to load a model trained on ImageNe ```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) ``` @@ -138,16 +139,16 @@ We use Googlenet as example to illustrate how to load a model trained on ImageNe ```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. @@ -159,23 +160,22 @@ We use Googlenet as example to illustrate how to load a model trained on ImageNe ```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, + + 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/training/source_en/advanced_use/model_security.md b/tutorials/training/source_en/advanced_use/model_security.md index a13cf2a91d..ecfab36032 100644 --- a/tutorials/training/source_en/advanced_use/model_security.md +++ b/tutorials/training/source_en/advanced_use/model_security.md @@ -99,7 +99,7 @@ def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, # apply map operations on images if not sparse: one_hot_enco = C.OneHot(10) - ds1 = ds1.map(input_columns="label", operations=one_hot_enco, + ds1 = ds1.map(operations=one_hot_enco, input_columns="label", num_parallel_workers=num_parallel_workers) type_cast_op = C.TypeCast(mstype.float32) ds1 = ds1.map(operations=type_cast_op, input_columns="label", diff --git a/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md b/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md index 419b1edc55..74a9ad497e 100644 --- a/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md +++ b/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md @@ -286,7 +286,7 @@ Data augmentation requires the `map` function. For details about how to use the ```python # path to imagefolder directory. This directory needs to contain sub-directories which contain the images DATA_DIR = "/path/to/imagefolder_directory" - dataset = ds.ImageFolderDatasetV2(DATA_DIR, decode=True) # Decode images. + dataset = ds.ImageFolderDataset(DATA_DIR, decode=True) # Decode images. resize_op = transforms.Resize(size=(500,500), interpolation=Inter.LINEAR) dataset.map(operations=resize_op, input_columns="image") diff --git a/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md index c8d4fefc22..94250841f2 100644 --- a/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md @@ -159,7 +159,7 @@ imagenet_policy = [ ```python def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, shuffle=True, num_samples=5, target="Ascend"): # create a train or eval imagenet2012 dataset for resnet50 - ds = de.ImageFolderDatasetV2(dataset_path, num_parallel_workers=8, + ds = de.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=shuffle, num_samples=num_samples) image_size = 224 @@ -185,12 +185,12 @@ imagenet_policy = [ c_vision.Normalize(mean=mean, std=std), c_vision.HWC2CHW() ] - ds = ds.map(input_columns="image", num_parallel_workers=8, operations=trans) + ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=8) if do_train: - ds = ds.map(input_columns=["image"], operations=c_vision.RandomSelectSubpolicy(imagenet_policy)) - ds = ds.map(input_columns=["image"], num_parallel_workers=8, operations=post_trans) + ds = ds.map(operations=c_vision.RandomSelectSubpolicy(imagenet_policy), input_columns=["image"]) + ds = ds.map(operations=post_trans, input_columns=["image"], num_parallel_workers=8) type_cast_op = c_transforms.TypeCast(mstype.int32) - ds = ds.map(input_columns="label", num_parallel_workers=8, operations=type_cast_op) + ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) # apply batch operations ds = ds.batch(batch_size, drop_remainder=True) diff --git a/tutorials/training/source_zh_cn/advanced_use/cache.md b/tutorials/training/source_zh_cn/advanced_use/cache.md index 797cac1e85..2039720a55 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cache.md +++ b/tutorials/training/source_zh_cn/advanced_use/cache.md @@ -124,7 +124,7 @@ ```python import mindspore.dataset as ds import mindspore.common.dtype as mstype - import mindspore.dataset.transforms.vision.c_transforms as c_vision + import mindspore.dataset.vision.c_transforms as c_vision test_cache = ds.DatasetCache(session_id=1, size=0, spilling=True) ``` @@ -142,7 +142,7 @@ # apply cache to map rescale_op = c_vision.Rescale(1.0 / 255.0, -1.0) - data = data.map(input_columns=["image"], operations=rescale_op, cache=test_cache) + data = data.map(operations=rescale_op, input_columns=["image"], cache=test_cache) num_iter = 0 for item in data.create_dict_iterator(num_epochs=1): # each data is a dictionary @@ -224,7 +224,7 @@ # use the session id passed in from the outside script when defining the cache test_cache = msds.DatasetCache(session_id = session_id, size = 0, spilling=False) - ds = de.ImageFolderDatasetV2(data_dir, num_samples=num_samples, cache = test_cache) + ds = de.ImageFolderDataset(data_dir, num_samples=num_samples, cache = test_cache) ``` - **Step 5:** diff --git a/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md b/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md index 4bed55f52a..4a54e92841 100644 --- a/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md +++ b/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md @@ -122,8 +122,8 @@ tar -zvxf cifar-10-binary.tar.gz c_trans += [resize_op, rescale_op, normalize_op, changeswap_op] # apply map operations on images - cifar_ds = cifar_ds.map(input_columns="label", operations=type_cast_op) - cifar_ds = cifar_ds.map(input_columns="image", operations=c_trans) + cifar_ds = cifar_ds.map(operations=type_cast_op, input_columns="label") + cifar_ds = cifar_ds.map(operations=c_trans, input_columns="image") ``` 3. 数据混洗和批处理 diff --git a/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md b/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md index 1418b34ae6..d2cd750269 100644 --- a/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md +++ b/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md @@ -67,7 +67,7 @@ from mindspore.train.serialization import load_checkpoint, load_param_into_net import mindspore.dataset as ds import mindspore.dataset.vision.c_transforms as CV import mindspore.dataset.transforms.c_transforms as C -from mindspore.dataset.vision.import Inter +from mindspore.dataset.vision import Inter import mindspore.common.dtype as mstype from mindarmour.diff_privacy import DPModel @@ -86,7 +86,7 @@ TAG = 'Lenet5_train' ### 参数配置 1. 设置运行环境、数据集路径、模型训练参数、checkpoint存储参数、差分隐私参数,`data_path`数据路径替换成你的数据集所在路径。更多配置可以参考。 - + ```python cfg = edict({ 'num_classes': 10, # the number of classes of model's output @@ -151,7 +151,7 @@ def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, # apply map operations on images if not sparse: one_hot_enco = C.OneHot(10) - ds1 = ds1.map(input_columns="label", operations=one_hot_enco, + ds1 = ds1.map(operations=one_hot_enco, input_columns="label", num_parallel_workers=num_parallel_workers) type_cast_op = C.TypeCast(mstype.float32) ds1 = ds1.map(operations=type_cast_op, input_columns="label", @@ -324,17 +324,17 @@ ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), acc = model.eval(ds_eval, dataset_sink_mode=False) LOGGER.info(TAG, "============== Accuracy: %s ==============", acc) ``` - + 4. 运行命令。 - + 运行脚本,可在命令行输入命令: - + ```bash python lenet_dp.py ``` - + 其中`lenet5_dp.py`替换成你的脚本的名字。 - + 5. 结果展示。 不加差分隐私的LeNet模型精度稳定在99%,加了Gaussian噪声,自适应Clip的差分隐私LeNet模型收敛,精度稳定在95%左右。 @@ -345,7 +345,7 @@ ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), ... ============== Accuracy: 0.9698 ============== ``` - + ### 引用 [1] C. Dwork and J. Lei. Differential privacy and robust statistics. In STOC, pages 371–380. ACM, 2009. @@ -353,6 +353,3 @@ ds_train = generate_mnist_dataset(os.path.join(cfg.data_path, "train"), [2] Ilya Mironov. Rényi differential privacy. In IEEE Computer Security Foundations Symposium, 2017. [3] Abadi, M. e. a., 2016. *Deep learning with differential privacy.* s.l.:Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security. - - - diff --git a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md index 3467a32d8a..bc6327d561 100644 --- a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md @@ -27,7 +27,7 @@ 1. 将你的预训练模型托管在我们可以访问的存储位置。 -2. 按照 [模板](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/googlenet/mindspore_hub_conf.py) 在你自己的代码仓中添加模型生成文件 `mindspore_hub_conf.py`。 +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` 处所需的哈希值: @@ -46,7 +46,7 @@ 一旦你的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用于加载预训练模型,可以实现一行代码加载模型。主要的模型加载流程如下: @@ -62,26 +62,27 @@ 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 mindspore.dataset.transforms.py_transforms import Compose from PIL import Image import cv2 - + import mindspore.dataset.vision.py_transforms as py_transforms + 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()]) - + transforms = Compose([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)添加到模型构造中时,可以在模型的详情页中找到这个功能。* @@ -96,10 +97,10 @@ 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) ``` @@ -109,12 +110,12 @@ ```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]) ``` @@ -122,31 +123,31 @@ ```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. @@ -158,22 +159,22 @@ ```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, + + 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/training/source_zh_cn/advanced_use/model_security.md b/tutorials/training/source_zh_cn/advanced_use/model_security.md index c5b97a4bae..52d4a2fd09 100644 --- a/tutorials/training/source_zh_cn/advanced_use/model_security.md +++ b/tutorials/training/source_zh_cn/advanced_use/model_security.md @@ -50,7 +50,7 @@ from mindspore import dataset as ds import mindspore.common.dtype as mstype import mindspore.dataset.vision.c_transforms as CV import mindspore.dataset.transforms.c_transforms as C -from mindspore.dataset.vision.import Inter +from mindspore.dataset.vision import Inter import mindspore.nn as nn from mindspore.nn import SoftmaxCrossEntropyWithLogits from mindspore.common.initializer import TruncatedNormal diff --git a/tutorials/training/source_zh_cn/use/image_loading.md b/tutorials/training/source_zh_cn/use/image_loading.md index 0c51bec4a3..be239acfd1 100644 --- a/tutorials/training/source_zh_cn/use/image_loading.md +++ b/tutorials/training/source_zh_cn/use/image_loading.md @@ -154,8 +154,8 @@ for data in mnist_dataset.create_dict_iterator(): 1. 导入相关模块,重新加载数据集。 ```python - from mindspore.dataset.transforms.vision import Inter - import mindspore.dataset.transforms.vision.c_transforms as transforms + from mindspore.dataset.vision import Inter + import mindspore.dataset.vision.c_transforms as transforms # 重新加载数据集 mnist_dataset = ds.MnistDataset(DATA_DIR, num_samples=6, shuffle=False) @@ -167,7 +167,7 @@ for data in mnist_dataset.create_dict_iterator(): resize_op = transforms.Resize(size=(200,200), interpolation=Inter.LINEAR) crop_op = transforms.RandomCrop(150) transforms_list = [resize_op, crop_op] - ds4 = mnist_dataset.map(input_columns="image", operations=transforms_list) + ds4 = mnist_dataset.map(operations=transforms_list, input_columns="image") ``` 3. 查看数据增强效果。 diff --git a/tutorials/training/source_zh_cn/use/text_loading.md b/tutorials/training/source_zh_cn/use/text_loading.md index 7150cfd67d..76f8109e0e 100644 --- a/tutorials/training/source_zh_cn/use/text_loading.md +++ b/tutorials/training/source_zh_cn/use/text_loading.md @@ -105,7 +105,7 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 3. 执行操作。 ```python - dataset = dataset.map(input_columns=["text"], operations=text.SlidingWindow(2, 0)) + dataset = dataset.map(operations=text.SlidingWindow(2, 0), input_columns=["text"]) ``` 4. 执行之后输出效果。 diff --git a/tutorials/tutorial_code/distributed_training/resnet50_distributed_training.py b/tutorials/tutorial_code/distributed_training/resnet50_distributed_training.py index f7bde7ec41..99ca5892f0 100644 --- a/tutorials/tutorial_code/distributed_training/resnet50_distributed_training.py +++ b/tutorials/tutorial_code/distributed_training/resnet50_distributed_training.py @@ -67,8 +67,8 @@ def create_dataset(data_path, repeat_num=1, batch_size=32, rank_id=0, rank_size= c_trans += [resize_op, rescale_op, normalize_op, changeswap_op] # apply map operations on images - data_set = data_set.map(input_columns="label", operations=type_cast_op) - data_set = data_set.map(input_columns="image", operations=c_trans) + data_set = data_set.map(operations=type_cast_op, input_columns="label") + data_set = data_set.map(operations=c_trans, input_columns="image") # apply shuffle operations data_set = data_set.shuffle(buffer_size=10) diff --git a/tutorials/tutorial_code/lenet/lenet.py b/tutorials/tutorial_code/lenet/lenet.py index 3a25515233..0bfca4e918 100644 --- a/tutorials/tutorial_code/lenet/lenet.py +++ b/tutorials/tutorial_code/lenet/lenet.py @@ -59,11 +59,11 @@ def create_dataset(data_path, batch_size=32, repeat_size=1, type_cast_op = C.TypeCast(mstype.int32) # change data type of label to int32 to fit network # apply map operations on images - mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(operations=resize_op, input_columns="image", num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(operations=rescale_op, input_columns="image", num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(operations=rescale_nml_op, input_columns="image", num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(operations=hwc2chw_op, input_columns="image", num_parallel_workers=num_parallel_workers) # apply DatasetOps buffer_size = 10000 diff --git a/tutorials/tutorial_code/resnet/cifar_resnet50.py b/tutorials/tutorial_code/resnet/cifar_resnet50.py index edf4e34bd8..816b9f6218 100644 --- a/tutorials/tutorial_code/resnet/cifar_resnet50.py +++ b/tutorials/tutorial_code/resnet/cifar_resnet50.py @@ -89,8 +89,8 @@ def create_dataset(repeat_num=1, training=True): changeswap_op] # apply map operations on images - cifar_ds = cifar_ds.map(input_columns="label", operations=type_cast_op) - cifar_ds = cifar_ds.map(input_columns="image", operations=c_trans) + cifar_ds = cifar_ds.map(operations=type_cast_op, input_columns="label") + cifar_ds = cifar_ds.map(operations=c_trans, input_columns="image") # apply shuffle operations cifar_ds = cifar_ds.shuffle(buffer_size=10) diff --git a/tutorials/tutorial_code/sample_for_cloud/dataset.py b/tutorials/tutorial_code/sample_for_cloud/dataset.py index 4f0546724d..7d8dfe9337 100644 --- a/tutorials/tutorial_code/sample_for_cloud/dataset.py +++ b/tutorials/tutorial_code/sample_for_cloud/dataset.py @@ -74,8 +74,8 @@ def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32): type_cast_op = C2.TypeCast(mstype.int32) - ds = ds.map(input_columns="label", num_parallel_workers=8, operations=type_cast_op) - ds = ds.map(input_columns="image", num_parallel_workers=8, operations=trans) + ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) + ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=8) # apply batch operations ds = ds.batch(batch_size, drop_remainder=True) -- Gitee From 7b60ccb49a8f77ec276ac8b5de1edfd5e2b1dd47 Mon Sep 17 00:00:00 2001 From: wandongdong Date: Sun, 13 Sep 2020 20:46:41 -0700 Subject: [PATCH 008/100] up GPU op list --- lite/docs/source_en/operator_list.md | 66 ++++++++++++------------- lite/docs/source_zh_cn/operator_list.md | 66 ++++++++++++------------- 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/lite/docs/source_en/operator_list.md b/lite/docs/source_en/operator_list.md index 6038b5c956..4f347a146e 100644 --- a/lite/docs/source_en/operator_list.md +++ b/lite/docs/source_en/operator_list.md @@ -6,62 +6,62 @@ | Operation | CPU
FP16 | CPU
FP32 | CPU
Int8 | CPU
UInt8 | GPU
FP16 | GPU
FP32 | Tensorflow
Lite op supported | Caffe
Lite op supported | Onnx
Lite op supported | |-----------------------|----------|----------|-----------|----------|----------|------------------|----------|----------|----------| -| Abs | | √ | √ | √ | | | Abs | | Abs | -| Add | √ | √ | √ | √ | | √ | Add | | Add | +| Abs | | √ | √ | √ | √ | √ | Abs | | Abs | +| Add | √ | √ | √ | √ | √ | √ | Add | | Add | | AddN | | √ | | | | | AddN | | | | Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | | Argmin | | √ | √ | √ | | | Argmin | | | -| AvgPool | √ | √ | √ | √ | | √ | MeanPooling| Pooling | AveragePool | -| BatchNorm | √ | √ | √ | √ | | √ | | BatchNorm | BatchNormalization | +| AvgPool | √ | √ | √ | √ | √ | √ | MeanPooling| Pooling | AveragePool | +| BatchNorm | √ | √ | √ | √ | √ | √ | | BatchNorm | BatchNormalization | | BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | -| BiasAdd | | √ | √ | √ | | √ | | | BiasAdd | +| BiasAdd | | √ | √ | √ | √ | √ | | | BiasAdd | | Broadcast | | √ | | | | | BroadcastTo | | Expand | -| Cast | √ | √ | | √ | | | Cast, DEQUANTIZE* | | Cast | -| Ceil | | √ | √ | √ | | | Ceil | | Ceil | +| Cast | √ | √ | | √ | √ | √ | Cast, DEQUANTIZE* | | Cast | +| Ceil | | √ | √ | √ | √ | √ | Ceil | | Ceil | | Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | | Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | | Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | -| Cos | | √ | √ | √ | | | Cos | | Cos | +| Cos | | √ | √ | √ | √ | √ | Cos | | Cos | | Crop | | √ | √ | √ | | | | Crop | | | DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | | DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | | DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | -| Div | √ | √ | √ | √ | | √ | Div, RealDiv | | Div | +| Div | √ | √ | √ | √ | √ | √ | Div, RealDiv | | Div | | Eltwise | √ | √ | | | | | | Eltwise | | | Elu | | √ | | | | | Elu | | Elu | | Equal | √ | √ | √ | √ | | | Equal | | Equal | -| Exp | | √ | | | | | Exp | | Exp | +| Exp | | √ | | | √ | √ | Exp | | Exp | | ExpandDims | | √ | | | | | | | | | Fill | | √ | | | | | Fill | | | | Flatten | | √ | | | | | | Flatten | | -| Floor | | √ | √ | √ | | | flOOR | | Floor | +| Floor | | √ | √ | √ | √ | √ | flOOR | | Floor | | FloorDiv | √ | √ | | | | | FloorDiv | | | | FloorMod | √ | √ | | | | | FloorMod | | | -| FullConnection | | √ | √ | √ | | | FullyConnected | InnerProduct | | +| FullConnection | | √ | √ | √ | √ | √ | FullyConnected | InnerProduct | | | GatherNd | | √ | √ | √ | | | GatherND | | | | GatherV2 | | √ | √ | √ | | | Gather | | Gather | | Greater | √ | √ | √ | √ | | | Greater | | Greater | | GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | | Hswish | √ | √ | √ | √ | | | HardSwish | | | -| LeakyReLU | √ | √ | | | | √ | LeakyRelu | | LeakyRelu | +| LeakyReLU | √ | √ | | | √ | √ | LeakyRelu | | LeakyRelu | | Less | √ | √ | √ | √ | | | Less | | Less | | LessEqual | √ | √ | √ | √ | | | LessEqual | | | | LRN | | √ | | | | | LocalResponseNorm | | Lrn | -| Log | | √ | √ | √ | | | Log | | Log | +| Log | | √ | √ | √ | √ | √ | Log | | Log | | LogicalAnd | √ | √ | | | | | LogicalAnd | | | -| LogicalNot | | √ | √ | √ | | | LogicalNot | | | +| LogicalNot | | √ | √ | √ | √ | √ | LogicalNot | | | | LogicalOr | √ | √ | | | | | LogicalOr | | | | LSTM | | √ | | | | | | | | | MatMul | | √ | √ | √ | √ | √ | | | MatMul | | Maximum | √ | √ | | | | | Maximum | | Max | -| MaxPool | √ | √ | √ | √ | | √ | MaxPooling | Pooling | MaxPool | +| MaxPool | √ | √ | √ | √ | √ | √ | MaxPooling | Pooling | MaxPool | | Minimum | √ | √ | | | | | Minimum | | Min | -| Mul | √ | √ | √ | √ | | √ | Mul | | Mul | +| Mul | √ | √ | √ | √ | √ | √ | Mul | | Mul | | NotEqual | √ | √ | √ | √ | | | NotEqual | | | | OneHot | | √ | | | | | OneHot | | | | Pad | | √ | √ | √ | | | Pad | | Pad | | Pow | | √ | √ | √ | | | Pow | Power | Power | -| PReLU | | √ | | | | √ | | PReLU | | +| PReLU | | √ | | | √ | √ | | PReLU | | | Range | | √ | | | | | Range | | | | Rank | | √ | | | | | Rank | | | | ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | @@ -70,37 +70,37 @@ | ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | | ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | | ReduceSumSquare | √ | √ | √ | √ | | | | | | -| ReLU | √ | √ | √ | √ | | √ | Relu | ReLU | Relu | -| ReLU6 | √ | √ | √ | √ | | √ | Relu6 | ReLU6 | Clip* | -| Reshape | √ | √ | √ | √ | | √ | Reshape | Reshape | Reshape,Flatten | +| ReLU | √ | √ | √ | √ | √ | √ | Relu | ReLU | Relu | +| ReLU6 | √ | √ | √ | √ | √ | √ | Relu6 | ReLU6 | Clip* | +| Reshape | √ | √ | √ | √ | √ | √ | Reshape | Reshape | Reshape,Flatten | | Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | | Reverse | | √ | | | | | reverse | | | | ReverseSequence | | √ | | | | | ReverseSequence | | | -| Round | | √ | √ | √ | | | Round | | | -| Rsqrt | | √ | √ | √ | | | Rsqrt | | | -| Scale | | √ | | | | | | Scale | | +| Round | | √ | √ | √ | √ | √ | Round | | | +| Rsqrt | | √ | √ | √ | √ | √ | Rsqrt | | | +| Scale | | √ | | | √ | √ | | Scale | | | ScatterNd | | √ | | | | | ScatterNd | | | | Shape | | √ | | | | | Shape | | Shape | -| Sigmoid | √ | √ | √ | √ | | √ | Logistic | Sigmoid | Sigmoid | -| Sin | | √ | √ | √ | | | Sin | | Sin | +| Sigmoid | √ | √ | √ | √ | √ | √ | Logistic | Sigmoid | Sigmoid | +| Sin | | √ | √ | √ | √ | √ | Sin | | Sin | | Slice | | √ | √ | √ | √ | √ | Slice | | Slice | -| Softmax | √ | √ | √ | √ | | √ | Softmax | Softmax | Softmax | +| Softmax | √ | √ | √ | √ | √ | √ | Softmax | Softmax | Softmax | | SpaceToBatch | | √ | | | | | | | | | SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | | SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | | SparseToDense | | √ | | | | | SpareToDense | | | | Split | √ | √ | √ | √ | | | Split, SplitV | | | -| Sqrt | | √ | √ | √ | | | Sqrt | | Sqrt | -| Square | | √ | √ | √ | | | Square | | | -| SquaredDifference | | √ | | | | | SquaredDifference | | | +| Sqrt | | √ | √ | √ | √ | √ | Sqrt | | Sqrt | +| Square | | √ | √ | √ | √ | √ | Square | | | +| SquaredDifference | | √ | | | | | SquaredDifference | | | | Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | | StridedSlice | | √ | √ | √ | | | StridedSlice| | | | Stack | | √ | | | | | Stack | | | -| Sub | √ | √ | √ | √ | | √ | Sub | | Sub | -| Tanh | √ | √ | | | | | Tanh | TanH | | +| Sub | √ | √ | √ | √ | √ | √ | Sub | | Sub | +| Tanh | √ | √ | | | √ | √ | Tanh | TanH | | | Tile | | √ | | | | | Tile | | Tile | | TopK | | √ | √ | √ | | | TopKV2 | | | -| Transpose | √ | √ | | | | √ | Transpose | Permute | Transpose | +| Transpose | √ | √ | | | √ | √ | Transpose | Permute | Transpose | | Unique | | √ | | | | | Unique | | | | Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | | Unstack | | √ | | | | | Unstack | | | diff --git a/lite/docs/source_zh_cn/operator_list.md b/lite/docs/source_zh_cn/operator_list.md index 3384d8baf9..333e209f4e 100644 --- a/lite/docs/source_zh_cn/operator_list.md +++ b/lite/docs/source_zh_cn/operator_list.md @@ -6,62 +6,62 @@ | 操作名 | CPU
FP16 | CPU
FP32 | CPU
Int8 | CPU
UInt8 | GPU
FP16 | GPU
FP32 | 支持的Tensorflow
Lite op | 支持的Caffe
Lite op | 支持的Onnx
Lite op | |-----------------------|----------|----------|----------|-----------|----------|-------------------|----------|----------|---------| -| Abs | | √ | √ | √ | | | Abs | | Abs | -| Add | √ | √ | √ | √ | | √ | Add | | Add | +| Abs | | √ | √ | √ | √ | √ | Abs | | Abs | +| Add | √ | √ | √ | √ | √ | √ | Add | | Add | | AddN | | √ | | | | | AddN | | | | Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | | Argmin | | √ | √ | √ | | | Argmin | | | -| AvgPool | √ | √ | √ | √ | | √ | MeanPooling| Pooling | AveragePool | -| BatchNorm | √ | √ | √ | √ | | √ | | BatchNorm | BatchNormalization | +| AvgPool | √ | √ | √ | √ | √ | √ | MeanPooling| Pooling | AveragePool | +| BatchNorm | √ | √ | √ | √ | √ | √ | | BatchNorm | BatchNormalization | | BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | -| BiasAdd | | √ | √ | √ | | √ | | | BiasAdd | +| BiasAdd | | √ | √ | √ | √ | √ | | | BiasAdd | | Broadcast | | √ | | | | | BroadcastTo | | Expand | -| Cast | √ | √ | | √ | | | Cast, DEQUANTIZE* | | Cast | -| Ceil | | √ | √ | √ | | | Ceil | | Ceil | +| Cast | √ | √ | | √ | √ | √ | Cast, DEQUANTIZE* | | Cast | +| Ceil | | √ | √ | √ | √ | √ | Ceil | | Ceil | | Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | | Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | | Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | -| Cos | | √ | √ | √ | | | Cos | | Cos | +| Cos | | √ | √ | √ | √ | √ | Cos | | Cos | | Crop | | √ | √ | √ | | | | Crop | | | DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | | DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | | DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | -| Div | √ | √ | √ | √ | | √ | Div, RealDiv | | Div | +| Div | √ | √ | √ | √ | √ | √ | Div, RealDiv | | Div | | Eltwise | √ | √ | | | | | | Eltwise | | | Elu | | √ | | | | | Elu | | Elu | | Equal | √ | √ | √ | √ | | | Equal | | Equal | -| Exp | | √ | | | | | Exp | | Exp | +| Exp | | √ | | | √ | √ | Exp | | Exp | | ExpandDims | | √ | | | | | | | | | Fill | | √ | | | | | Fill | | | | Flatten | | √ | | | | | | Flatten | | -| Floor | | √ | √ | √ | | | flOOR | | Floor | +| Floor | | √ | √ | √ | √ | √ | flOOR | | Floor | | FloorDiv | √ | √ | | | | | FloorDiv | | | | FloorMod | √ | √ | | | | | FloorMod | | | -| FullConnection | | √ | √ | √ | | | FullyConnected | InnerProduct | | +| FullConnection | | √ | √ | √ | √ | √ | FullyConnected | InnerProduct | | | GatherNd | | √ | √ | √ | | | GatherND | | | | GatherV2 | | √ | √ | √ | | | Gather | | Gather | | Greater | √ | √ | √ | √ | | | Greater | | Greater | | GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | | Hswish | √ | √ | √ | √ | | | HardSwish | | | -| LeakyReLU | √ | √ | | | | √ | LeakyRelu | | LeakyRelu | +| LeakyReLU | √ | √ | | | √ | √ | LeakyRelu | | LeakyRelu | | Less | √ | √ | √ | √ | | | Less | | Less | | LessEqual | √ | √ | √ | √ | | | LessEqual | | | | LRN | | √ | | | | | LocalResponseNorm | | Lrn | -| Log | | √ | √ | √ | | | Log | | Log | +| Log | | √ | √ | √ | √ | √ | Log | | Log | | LogicalAnd | √ | √ | | | | | LogicalAnd | | | -| LogicalNot | | √ | √ | √ | | | LogicalNot | | | +| LogicalNot | | √ | √ | √ | √ | √ | LogicalNot | | | | LogicalOr | √ | √ | | | | | LogicalOr | | | | LSTM | | √ | | | | | | | | | MatMul | | √ | √ | √ | √ | √ | | | MatMul | | Maximum | √ | √ | | | | | Maximum | | Max | -| MaxPool | √ | √ | √ | √ | | √ | MaxPooling | Pooling | MaxPool | +| MaxPool | √ | √ | √ | √ | √ | √ | MaxPooling | Pooling | MaxPool | | Minimum | √ | √ | | | | | Minimum | | Min | -| Mul | √ | √ | √ | √ | | √ | Mul | | Mul | +| Mul | √ | √ | √ | √ | √ | √ | Mul | | Mul | | NotEqual | √ | √ | √ | √ | | | NotEqual | | | | OneHot | | √ | | | | | OneHot | | | | Pad | | √ | √ | √ | | | Pad | | Pad | | Pow | | √ | √ | √ | | | Pow | Power | Power | -| PReLU | | √ | | | | √ | | PReLU | | +| PReLU | | √ | | | √ | √ | | PReLU | | | Range | | √ | | | | | Range | | | | Rank | | √ | | | | | Rank | | | | ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | @@ -70,37 +70,37 @@ | ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | | ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | | ReduceSumSquare | √ | √ | √ | √ | | | | | | -| ReLU | √ | √ | √ | √ | | √ | Relu | ReLU | Relu | -| ReLU6 | √ | √ | √ | √ | | √ | Relu6 | ReLU6 | Clip* | -| Reshape | √ | √ | √ | √ | | √ | Reshape | Reshape | Reshape,Flatten | +| ReLU | √ | √ | √ | √ | √ | √ | Relu | ReLU | Relu | +| ReLU6 | √ | √ | √ | √ | √ | √ | Relu6 | ReLU6 | Clip* | +| Reshape | √ | √ | √ | √ | √ | √ | Reshape | Reshape | Reshape,Flatten | | Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | | Reverse | | √ | | | | | reverse | | | | ReverseSequence | | √ | | | | | ReverseSequence | | | -| Round | | √ | √ | √ | | | Round | | | -| Rsqrt | | √ | √ | √ | | | Rsqrt | | | -| Scale | | √ | | | | | | Scale | | +| Round | | √ | √ | √ | √ | √ | Round | | | +| Rsqrt | | √ | √ | √ | √ | √ | Rsqrt | | | +| Scale | | √ | | | √ | √ | | Scale | | | ScatterNd | | √ | | | | | ScatterNd | | | | Shape | | √ | | | | | Shape | | Shape | -| Sigmoid | √ | √ | √ | √ | | √ | Logistic | Sigmoid | Sigmoid | -| Sin | | √ | √ | √ | | | Sin | | Sin | +| Sigmoid | √ | √ | √ | √ | √ | √ | Logistic | Sigmoid | Sigmoid | +| Sin | | √ | √ | √ | √ | √ | Sin | | Sin | | Slice | | √ | √ | √ | √ | √ | Slice | | Slice | -| Softmax | √ | √ | √ | √ | | √ | Softmax | Softmax | Softmax | +| Softmax | √ | √ | √ | √ | √ | √ | Softmax | Softmax | Softmax | | SpaceToBatch | | √ | | | | | | | | | SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | | SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | | SparseToDense | | √ | | | | | SpareToDense | | | | Split | √ | √ | √ | √ | | | Split, SplitV | | | -| Sqrt | | √ | √ | √ | | | Sqrt | | Sqrt | -| Square | | √ | √ | √ | | | Square | | | -| SquaredDifference | | √ | | | | | SquaredDifference | | | +| Sqrt | | √ | √ | √ | √ | √ | Sqrt | | Sqrt | +| Square | | √ | √ | √ | √ | √ | Square | | | +| SquaredDifference | | √ | | | | | SquaredDifference | | | | Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | | StridedSlice | | √ | √ | √ | | | StridedSlice| | | | Stack | | √ | | | | | Stack | | | -| Sub | √ | √ | √ | √ | | √ | Sub | | Sub | -| Tanh | √ | √ | | | | | Tanh | TanH | | +| Sub | √ | √ | √ | √ | √ | √ | Sub | | Sub | +| Tanh | √ | √ | | | √ | √ | Tanh | TanH | | | Tile | | √ | | | | | Tile | | Tile | | TopK | | √ | √ | √ | | | TopKV2 | | | -| Transpose | √ | √ | | | | √ | Transpose | Permute | Transpose | +| Transpose | √ | √ | | | √ | √ | Transpose | Permute | Transpose | | Unique | | √ | | | | | Unique | | | | Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | | Unstack | | √ | | | | | Unstack | | | -- Gitee From 22a046040d71bac30ddd9774bacfe7c3a53ad732 Mon Sep 17 00:00:00 2001 From: "wangnan39@huawei.com" Date: Mon, 14 Sep 2020 11:56:53 +0800 Subject: [PATCH 009/100] delete DataWrapper for r0.1 --- docs/source_en/operator_list.md | 1 - docs/source_zh_cn/operator_list.md | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/source_en/operator_list.md b/docs/source_en/operator_list.md index 672de46b5a..bf38c07967 100644 --- a/docs/source_en/operator_list.md +++ b/docs/source_en/operator_list.md @@ -84,7 +84,6 @@ | [mindspore.nn.WithLossCell](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.WithLossCell) | Supported | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.WithGradCell](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.WithGradCell) | Supported | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.TrainOneStepCell](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.TrainOneStepCell) | Supported | Supported | Doing |wrap/cell_wrapper -| [mindspore.nn.DataWrapper](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DataWrapper) |Doing | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.GetNextSingleOp](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.GetNextSingleOp) |Doing | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.WithEvalCell](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.WithEvalCell) | Supported | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.ParameterUpdate](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.ParameterUpdate) | Supported |Doing | Doing |wrap/cell_wrapper diff --git a/docs/source_zh_cn/operator_list.md b/docs/source_zh_cn/operator_list.md index 016d4b5f80..f3adc9459f 100644 --- a/docs/source_zh_cn/operator_list.md +++ b/docs/source_zh_cn/operator_list.md @@ -84,7 +84,6 @@ | [mindspore.nn.WithLossCell](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.WithLossCell) | Supported | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.WithGradCell](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.WithGradCell) | Supported | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.TrainOneStepCell](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.TrainOneStepCell) | Supported | Supported | Doing |wrap/cell_wrapper -| [mindspore.nn.DataWrapper](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DataWrapper) |Doing | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.GetNextSingleOp](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.GetNextSingleOp) |Doing | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.WithEvalCell](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.WithEvalCell) | Supported | Supported | Doing |wrap/cell_wrapper | [mindspore.nn.ParameterUpdate](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.ParameterUpdate) | Supported |Doing | Doing |wrap/cell_wrapper -- Gitee From d2b66ddd4033d8df0bc9c71ea044ba1e8acaa38b Mon Sep 17 00:00:00 2001 From: leiyuning Date: Mon, 14 Sep 2020 12:08:35 +0800 Subject: [PATCH 010/100] del lite doc --- .../mindarmour.adv_robustness.attacks.rst | 0 .../mindarmour.adv_robustness.defenses.rst | 0 .../mindarmour.adv_robustness.detectors.rst | 0 .../mindarmour.adv_robustness.evaluations.rst | 0 .../mindarmour/mindarmour.fuzz_testing.rst | 0 .../mindarmour.privacy.diff_privacy.rst | 0 .../mindarmour.privacy.evaluation.rst | 0 .../python => }/mindarmour/mindarmour.rst | 0 .../mindarmour/mindarmour.utils.rst | 0 .../mindspore.common.initializer.rst | 0 .../mindspore/mindspore.communication.rst | 0 .../mindspore/mindspore.context.rst | 0 .../mindspore/mindspore.dataset.config.rst | 0 .../mindspore/mindspore.dataset.rst | 0 .../mindspore/mindspore.dataset.text.rst | 0 .../mindspore.dataset.transforms.rst | 0 .../mindspore/mindspore.dataset.vision.rst | 0 .../python => }/mindspore/mindspore.dtype.rst | 0 .../python => }/mindspore/mindspore.hub.rst | 0 .../mindspore/mindspore.mindrecord.rst | 0 .../mindspore/mindspore.nn.dynamic_lr.rst | 0 .../mindspore.nn.learning_rate_schedule.rst | 0 .../mindspore/mindspore.nn.probability.rst | 0 .../python => }/mindspore/mindspore.nn.rst | 0 .../mindspore/mindspore.ops.composite.rst | 0 .../mindspore/mindspore.ops.operations.rst | 0 .../python => }/mindspore/mindspore.ops.rst | 0 .../mindspore/mindspore.profiler.rst | 0 .../{api/python => }/mindspore/mindspore.rst | 0 .../python => }/mindspore/mindspore.train.rst | 0 .../mindspore_hub/mindspore_hub.rst | 0 .../mindarmour.adv_robustness.attacks.rst | 0 .../mindarmour.adv_robustness.defenses.rst | 0 .../mindarmour.adv_robustness.detectors.rst | 0 .../mindarmour.adv_robustness.evaluations.rst | 0 .../mindarmour/mindarmour.fuzz_testing.rst | 0 .../mindarmour.privacy.diff_privacy.rst | 0 .../mindarmour.privacy.evaluation.rst | 0 .../python => }/mindarmour/mindarmour.rst | 0 .../mindarmour/mindarmour.utils.rst | 0 .../mindspore.common.initializer.rst | 0 .../mindspore/mindspore.communication.rst | 0 .../mindspore/mindspore.context.rst | 0 .../mindspore/mindspore.dataset.config.rst | 0 .../mindspore/mindspore.dataset.rst | 0 .../mindspore/mindspore.dataset.text.rst | 0 .../mindspore.dataset.transforms.rst | 0 .../mindspore/mindspore.dataset.vision.rst | 0 .../python => }/mindspore/mindspore.dtype.rst | 0 .../python => }/mindspore/mindspore.hub.rst | 0 .../mindspore/mindspore.mindrecord.rst | 0 .../mindspore/mindspore.nn.dynamic_lr.rst | 0 .../mindspore.nn.learning_rate_schedule.rst | 0 .../mindspore/mindspore.nn.probability.rst | 0 .../python => }/mindspore/mindspore.nn.rst | 0 .../mindspore/mindspore.ops.composite.rst | 0 .../mindspore/mindspore.ops.operations.rst | 0 .../python => }/mindspore/mindspore.ops.rst | 0 .../mindspore/mindspore.profiler.rst | 0 .../{api/python => }/mindspore/mindspore.rst | 0 .../python => }/mindspore/mindspore.train.rst | 0 .../mindspore_hub/mindspore_hub.rst | 0 lite/docs/Makefile | 20 -- lite/docs/requirements.txt | 5 - lite/docs/source_en/_static/logo_source.png | Bin 2009 -> 0 bytes lite/docs/source_en/architecture_lite.md | 19 -- lite/docs/source_en/conf.py | 60 ---- lite/docs/source_en/glossary_lite.md | 12 - .../images/MindSpore-Lite-architecture.png | Bin 55828 -> 0 bytes lite/docs/source_en/index_lite.rst | 16 - lite/docs/source_en/operator_list_lite.md | 111 ------- .../docs/source_zh_cn/_static/logo_source.png | Bin 2009 -> 0 bytes lite/docs/source_zh_cn/apicc/apicc.rst | 12 - lite/docs/source_zh_cn/apicc/class_list.md | 15 - lite/docs/source_zh_cn/apicc/dataset.md | 282 ------------------ .../apicc/errorcode_and_metatype.md | 51 ---- lite/docs/source_zh_cn/apicc/lite.md | 197 ------------ lite/docs/source_zh_cn/apicc/session.md | 177 ----------- lite/docs/source_zh_cn/apicc/tensor.md | 142 --------- lite/docs/source_zh_cn/architecture_lite.md | 20 -- lite/docs/source_zh_cn/conf.py | 62 ---- lite/docs/source_zh_cn/glossary_lite.md | 12 - .../images/MindSpore-Lite-architecture.png | Bin 55828 -> 0 bytes lite/docs/source_zh_cn/index_lite.rst | 16 - lite/docs/source_zh_cn/operator_list_lite.md | 111 ------- lite/lite.md | 0 lite/lite_en.md | 0 87 files changed, 1340 deletions(-) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.adv_robustness.attacks.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.adv_robustness.defenses.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.adv_robustness.detectors.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.adv_robustness.evaluations.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.fuzz_testing.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.privacy.diff_privacy.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.privacy.evaluation.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.rst (100%) rename docs/api_python/source_en/{api/python => }/mindarmour/mindarmour.utils.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.common.initializer.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.communication.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.context.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.dataset.config.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.dataset.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.dataset.text.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.dataset.transforms.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.dataset.vision.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.dtype.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.hub.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.mindrecord.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.nn.dynamic_lr.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.nn.learning_rate_schedule.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.nn.probability.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.nn.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.ops.composite.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.ops.operations.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.ops.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.profiler.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore/mindspore.train.rst (100%) rename docs/api_python/source_en/{api/python => }/mindspore_hub/mindspore_hub.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.adv_robustness.attacks.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.adv_robustness.defenses.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.adv_robustness.detectors.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.adv_robustness.evaluations.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.fuzz_testing.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.privacy.diff_privacy.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.privacy.evaluation.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindarmour/mindarmour.utils.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.common.initializer.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.communication.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.context.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.dataset.config.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.dataset.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.dataset.text.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.dataset.transforms.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.dataset.vision.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.dtype.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.hub.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.mindrecord.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.nn.dynamic_lr.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.nn.learning_rate_schedule.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.nn.probability.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.nn.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.ops.composite.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.ops.operations.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.ops.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.profiler.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore/mindspore.train.rst (100%) rename docs/api_python/source_zh_cn/{api/python => }/mindspore_hub/mindspore_hub.rst (100%) delete mode 100644 lite/docs/Makefile delete mode 100644 lite/docs/requirements.txt delete mode 100644 lite/docs/source_en/_static/logo_source.png delete mode 100644 lite/docs/source_en/architecture_lite.md delete mode 100644 lite/docs/source_en/conf.py delete mode 100644 lite/docs/source_en/glossary_lite.md delete mode 100644 lite/docs/source_en/images/MindSpore-Lite-architecture.png delete mode 100644 lite/docs/source_en/index_lite.rst delete mode 100644 lite/docs/source_en/operator_list_lite.md delete mode 100644 lite/docs/source_zh_cn/_static/logo_source.png delete mode 100644 lite/docs/source_zh_cn/apicc/apicc.rst delete mode 100644 lite/docs/source_zh_cn/apicc/class_list.md delete mode 100644 lite/docs/source_zh_cn/apicc/dataset.md delete mode 100644 lite/docs/source_zh_cn/apicc/errorcode_and_metatype.md delete mode 100644 lite/docs/source_zh_cn/apicc/lite.md delete mode 100644 lite/docs/source_zh_cn/apicc/session.md delete mode 100644 lite/docs/source_zh_cn/apicc/tensor.md delete mode 100644 lite/docs/source_zh_cn/architecture_lite.md delete mode 100644 lite/docs/source_zh_cn/conf.py delete mode 100644 lite/docs/source_zh_cn/glossary_lite.md delete mode 100644 lite/docs/source_zh_cn/images/MindSpore-Lite-architecture.png delete mode 100644 lite/docs/source_zh_cn/index_lite.rst delete mode 100644 lite/docs/source_zh_cn/operator_list_lite.md create mode 100644 lite/lite.md create mode 100644 lite/lite_en.md diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.attacks.rst b/docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.attacks.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.attacks.rst rename to docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.attacks.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.defenses.rst b/docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.defenses.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.defenses.rst rename to docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.defenses.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.detectors.rst b/docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.detectors.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.detectors.rst rename to docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.detectors.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.evaluations.rst b/docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.evaluations.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.adv_robustness.evaluations.rst rename to docs/api_python/source_en/mindarmour/mindarmour.adv_robustness.evaluations.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.fuzz_testing.rst b/docs/api_python/source_en/mindarmour/mindarmour.fuzz_testing.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.fuzz_testing.rst rename to docs/api_python/source_en/mindarmour/mindarmour.fuzz_testing.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.privacy.diff_privacy.rst b/docs/api_python/source_en/mindarmour/mindarmour.privacy.diff_privacy.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.privacy.diff_privacy.rst rename to docs/api_python/source_en/mindarmour/mindarmour.privacy.diff_privacy.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.privacy.evaluation.rst b/docs/api_python/source_en/mindarmour/mindarmour.privacy.evaluation.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.privacy.evaluation.rst rename to docs/api_python/source_en/mindarmour/mindarmour.privacy.evaluation.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.rst b/docs/api_python/source_en/mindarmour/mindarmour.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.rst rename to docs/api_python/source_en/mindarmour/mindarmour.rst diff --git a/docs/api_python/source_en/api/python/mindarmour/mindarmour.utils.rst b/docs/api_python/source_en/mindarmour/mindarmour.utils.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindarmour/mindarmour.utils.rst rename to docs/api_python/source_en/mindarmour/mindarmour.utils.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.common.initializer.rst b/docs/api_python/source_en/mindspore/mindspore.common.initializer.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.common.initializer.rst rename to docs/api_python/source_en/mindspore/mindspore.common.initializer.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.communication.rst b/docs/api_python/source_en/mindspore/mindspore.communication.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.communication.rst rename to docs/api_python/source_en/mindspore/mindspore.communication.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.context.rst b/docs/api_python/source_en/mindspore/mindspore.context.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.context.rst rename to docs/api_python/source_en/mindspore/mindspore.context.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.dataset.config.rst b/docs/api_python/source_en/mindspore/mindspore.dataset.config.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.dataset.config.rst rename to docs/api_python/source_en/mindspore/mindspore.dataset.config.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.dataset.rst b/docs/api_python/source_en/mindspore/mindspore.dataset.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.dataset.rst rename to docs/api_python/source_en/mindspore/mindspore.dataset.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.dataset.text.rst b/docs/api_python/source_en/mindspore/mindspore.dataset.text.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.dataset.text.rst rename to docs/api_python/source_en/mindspore/mindspore.dataset.text.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.dataset.transforms.rst b/docs/api_python/source_en/mindspore/mindspore.dataset.transforms.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.dataset.transforms.rst rename to docs/api_python/source_en/mindspore/mindspore.dataset.transforms.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.dataset.vision.rst b/docs/api_python/source_en/mindspore/mindspore.dataset.vision.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.dataset.vision.rst rename to docs/api_python/source_en/mindspore/mindspore.dataset.vision.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.dtype.rst b/docs/api_python/source_en/mindspore/mindspore.dtype.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.dtype.rst rename to docs/api_python/source_en/mindspore/mindspore.dtype.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.hub.rst b/docs/api_python/source_en/mindspore/mindspore.hub.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.hub.rst rename to docs/api_python/source_en/mindspore/mindspore.hub.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.mindrecord.rst b/docs/api_python/source_en/mindspore/mindspore.mindrecord.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.mindrecord.rst rename to docs/api_python/source_en/mindspore/mindspore.mindrecord.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.nn.dynamic_lr.rst b/docs/api_python/source_en/mindspore/mindspore.nn.dynamic_lr.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.nn.dynamic_lr.rst rename to docs/api_python/source_en/mindspore/mindspore.nn.dynamic_lr.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.nn.learning_rate_schedule.rst b/docs/api_python/source_en/mindspore/mindspore.nn.learning_rate_schedule.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.nn.learning_rate_schedule.rst rename to docs/api_python/source_en/mindspore/mindspore.nn.learning_rate_schedule.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.nn.probability.rst b/docs/api_python/source_en/mindspore/mindspore.nn.probability.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.nn.probability.rst rename to docs/api_python/source_en/mindspore/mindspore.nn.probability.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.nn.rst b/docs/api_python/source_en/mindspore/mindspore.nn.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.nn.rst rename to docs/api_python/source_en/mindspore/mindspore.nn.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.ops.composite.rst b/docs/api_python/source_en/mindspore/mindspore.ops.composite.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.ops.composite.rst rename to docs/api_python/source_en/mindspore/mindspore.ops.composite.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.ops.operations.rst b/docs/api_python/source_en/mindspore/mindspore.ops.operations.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.ops.operations.rst rename to docs/api_python/source_en/mindspore/mindspore.ops.operations.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.ops.rst b/docs/api_python/source_en/mindspore/mindspore.ops.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.ops.rst rename to docs/api_python/source_en/mindspore/mindspore.ops.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.profiler.rst b/docs/api_python/source_en/mindspore/mindspore.profiler.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.profiler.rst rename to docs/api_python/source_en/mindspore/mindspore.profiler.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.rst b/docs/api_python/source_en/mindspore/mindspore.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.rst rename to docs/api_python/source_en/mindspore/mindspore.rst diff --git a/docs/api_python/source_en/api/python/mindspore/mindspore.train.rst b/docs/api_python/source_en/mindspore/mindspore.train.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore/mindspore.train.rst rename to docs/api_python/source_en/mindspore/mindspore.train.rst diff --git a/docs/api_python/source_en/api/python/mindspore_hub/mindspore_hub.rst b/docs/api_python/source_en/mindspore_hub/mindspore_hub.rst similarity index 100% rename from docs/api_python/source_en/api/python/mindspore_hub/mindspore_hub.rst rename to docs/api_python/source_en/mindspore_hub/mindspore_hub.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.attacks.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.attacks.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.attacks.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.attacks.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.defenses.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.defenses.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.defenses.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.defenses.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.detectors.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.detectors.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.detectors.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.detectors.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.evaluations.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.evaluations.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.adv_robustness.evaluations.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.adv_robustness.evaluations.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.fuzz_testing.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.fuzz_testing.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.fuzz_testing.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.fuzz_testing.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.privacy.diff_privacy.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.privacy.diff_privacy.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.privacy.diff_privacy.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.privacy.diff_privacy.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.privacy.evaluation.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.privacy.evaluation.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.privacy.evaluation.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.privacy.evaluation.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.utils.rst b/docs/api_python/source_zh_cn/mindarmour/mindarmour.utils.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindarmour/mindarmour.utils.rst rename to docs/api_python/source_zh_cn/mindarmour/mindarmour.utils.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.common.initializer.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.common.initializer.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.common.initializer.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.common.initializer.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.communication.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.communication.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.communication.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.communication.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.context.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.context.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.context.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.context.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.config.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dataset.config.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.config.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.dataset.config.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dataset.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.dataset.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.text.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dataset.text.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.text.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.dataset.text.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.transforms.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dataset.transforms.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.transforms.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.dataset.transforms.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.vision.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dataset.vision.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dataset.vision.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.dataset.vision.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dtype.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dtype.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.dtype.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.dtype.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.hub.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.hub.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.hub.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.hub.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.mindrecord.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.mindrecord.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.mindrecord.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.mindrecord.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.dynamic_lr.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.nn.dynamic_lr.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.dynamic_lr.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.nn.dynamic_lr.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.learning_rate_schedule.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.nn.learning_rate_schedule.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.learning_rate_schedule.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.nn.learning_rate_schedule.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.probability.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.nn.probability.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.probability.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.nn.probability.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.nn.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.nn.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.nn.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.ops.composite.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.ops.composite.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.ops.composite.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.ops.composite.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.ops.operations.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.ops.operations.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.ops.operations.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.ops.operations.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.ops.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.ops.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.ops.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.ops.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.profiler.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.profiler.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.profiler.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.profiler.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore/mindspore.train.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.train.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore/mindspore.train.rst rename to docs/api_python/source_zh_cn/mindspore/mindspore.train.rst diff --git a/docs/api_python/source_zh_cn/api/python/mindspore_hub/mindspore_hub.rst b/docs/api_python/source_zh_cn/mindspore_hub/mindspore_hub.rst similarity index 100% rename from docs/api_python/source_zh_cn/api/python/mindspore_hub/mindspore_hub.rst rename to docs/api_python/source_zh_cn/mindspore_hub/mindspore_hub.rst diff --git a/lite/docs/Makefile b/lite/docs/Makefile deleted file mode 100644 index 1eff895270..0000000000 --- a/lite/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source_zh_cn -BUILDDIR = build_zh_cn - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/lite/docs/requirements.txt b/lite/docs/requirements.txt deleted file mode 100644 index 8788e57530..0000000000 --- a/lite/docs/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -sphinx -recommonmark -sphinx-markdown-tables -sphinx_rtd_theme -numpy \ No newline at end of file diff --git a/lite/docs/source_en/_static/logo_source.png b/lite/docs/source_en/_static/logo_source.png deleted file mode 100644 index fc347d271abe082ae8d16242328551648766b6fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2009 zcmV;~2PXK5P)H00009a7bBm000XT z000XT0n*)m`~Uz4i%CR5RA_?=5PgUQtqqg1R-3H5BGlMp(8P#c(+ z(rpe+v7x0p?9ipaARp76>|1lRZz+1RfVD1)AZUbQX_|xMsIJ;bMPf&-oB%S~P*gy< z6J>X#gVK=o8G#1#CEsXSQ>`A>r1paj zA=*PxRA*aTJNm_>mOmpMd?WoOlq1~MH6*dLwA0=8D9~d&-2p#e+5qGi_U$|R#Ba85 z;14@Cn0;n_Kv=M}-%y!f-{-n@CM+6=vU^A>gXT!RhD)ujB%jC;kbRM^;u6Svje z_uo(4R+~ER=Ss@er1;Ut6Sq~fQZXx)D@8;6=wsz-63hi(RjXCt`4K+YQ#aff78h6W zI?Pim7*A^XH-6i_{cMQ@0^wxJ4JlDI$08I7_|vADHcbor0GVTYL9=ZZAw}>>90#`} zy**I;ia?Ng53I<%N8&ibAoCuPVMa6a zk$@kBjD>VLg3tbtECql?NiR;izLSz_; zAe>Ca^aAW1nn}cs5}Z4l znHL#GWSF>Ngp;WnAGjIDvkSnGHm&jO!tm@IixA|H8+bu~$Vm61$S}~VKsUF}K*Tzb z3D(v1Of z@7>!}TtPo@w9I>AdO_mYnz<>a7g&UbXXl8in!O6Xj_JB0_~J%sEEEKWxKXMZAZ6YY zRdan)(-OzZJP+~HY+L3%giR5AqnUZDA>NQ6#SH^0jQEsvftaqxbe(K*@Q{So5*daF zkvL9d7ywKbA)*OeuP}&WEJE&PA#ofL=qAw6odg!f4qVswW$vmGnE$4jzL!8p4xmAM5FgK1rKNbp#3=>t=zNu;A z&}Q{)ieC|Y&2FhnfVw2Qk$@k5O$n*XPdvG)YR~mQ8=0Lu@!97I`B;c$2^x2{H62>; z!q7|tpmOW%E^!<3Vb+Jb1nh-`jjB0dkaG{lXPyH;f0qX@om@(YMiOxIzhW@y?h4wqAKlveT32VWy!L)RUo4kj z>*@lT105Y}_wHry-Yu5P5bS}DC%iOmVSHl$e$Wl}T6jHs_pVzXU`U&0v0P>mdP_Q3 zGc+iIK)1GD`u5w@^724O$6F6RygR3Kz;&^_=A~&;`amMXL;`*buWPnlESDX42#ke- zppT=Q*GtnP!#Jm}4RmxUg0EO!14AT^gR>xa>v^)?CyTsoe`=Jf)v8sg{IgJ~dHRE& zEOzN(p!%OII@{WyzqTW^`>*>WN_#e5VYPgs)WrXEcUD(}Z2M04+(S<-R;6 - -The overall architecture of MindSpore Lite is as follows: - -![architecture](./images/MindSpore-Lite-architecture.png) - -- **Frontend:** generates models. You can use the model building API to build models and convert third-party models and models trained by MindSpore to MindSpore Lite models. Third-party models include TensorFlow Lite, Caffe 1.0, and ONNX models. - -- **IR:** defines the tensors, operators, and graphs of MindSpore. - -- **Backend:** optimizes graphs based on IR, including graph high level optimization (GHLO), graph low level optimization (GLLO), and quantization. GHLO is responsible for hardware-independent optimization, such as operator fusion and constant folding. GLLO is responsible for hardware-related optimization. Quantizer supports quantization methods after training, such as weight quantization and activation value quantization. - -- **Runtime:** inference runtime of intelligent devices. Sessions are responsible for session management and provide external APIs. The thread pool and parallel primitives are responsible for managing the thread pool used for graph execution. Memory allocation is responsible for memory overcommitment of each operator during graph execution. The operator library provides the CPU and GPU operators. - -- **Micro:** runtime of IoT devices, including the model generation .c file, thread pool, memory overcommitment, and operator library. - -Runtime and Micro share the underlying infrastructure layers, such as the operator library, memory allocation, thread pool, and parallel primitives. diff --git a/lite/docs/source_en/conf.py b/lite/docs/source_en/conf.py deleted file mode 100644 index fd89055b9b..0000000000 --- a/lite/docs/source_en/conf.py +++ /dev/null @@ -1,60 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os - - -# -- Project information ----------------------------------------------------- - -project = 'MindSpore Lite' -copyright = '2020, MindSpore Lite' -author = 'MindSpore Lite' - -# The full version, including alpha/beta/rc tags -release = 'master' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx_markdown_tables', - 'recommonmark', -] - -source_suffix = { - '.rst': 'restructuredtext', - '.md': 'markdown', -} - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] - -pygments_style = 'sphinx' - -autodoc_inherit_docstrings = False - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' - -html_static_path = ['_static'] \ No newline at end of file diff --git a/lite/docs/source_en/glossary_lite.md b/lite/docs/source_en/glossary_lite.md deleted file mode 100644 index 8b59622929..0000000000 --- a/lite/docs/source_en/glossary_lite.md +++ /dev/null @@ -1,12 +0,0 @@ -# Glossary - - - -| Acronym and Abbreviation | Description | -| ----- | ----- | -| MindSpore Lite | MindSpore AI engine is applied to the intelligent terminal and resource constrained scenes on the edge side. | -| MindSpore Micro | MindSpore AI engine with smaller package size for IOT devices. | -| GHLO | Graph high-level optimization. | -| GLLO | Graph low-level optimization. | -| RT | Runtime. | - diff --git a/lite/docs/source_en/images/MindSpore-Lite-architecture.png b/lite/docs/source_en/images/MindSpore-Lite-architecture.png deleted file mode 100644 index abf28796690f5649f8bc92382dfd4c2c83187620..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55828 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 diff --git a/lite/docs/source_en/index_lite.rst b/lite/docs/source_en/index_lite.rst deleted file mode 100644 index abecfe957e..0000000000 --- a/lite/docs/source_en/index_lite.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. MindSpore documentation master file, created by - sphinx-quickstart on Thu Aug 17 10:00:00 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -MindSpore Lite Documentation -============================ - -.. toctree:: - :glob: - :maxdepth: 1 - - architecture - apicc/apicc - operator_list - glossary diff --git a/lite/docs/source_en/operator_list_lite.md b/lite/docs/source_en/operator_list_lite.md deleted file mode 100644 index 6038b5c956..0000000000 --- a/lite/docs/source_en/operator_list_lite.md +++ /dev/null @@ -1,111 +0,0 @@ -# Operator List - - - -> √ The checked items are the operators supported by MindSpore Lite。 - -| Operation | CPU
FP16 | CPU
FP32 | CPU
Int8 | CPU
UInt8 | GPU
FP16 | GPU
FP32 | Tensorflow
Lite op supported | Caffe
Lite op supported | Onnx
Lite op supported | -|-----------------------|----------|----------|-----------|----------|----------|------------------|----------|----------|----------| -| Abs | | √ | √ | √ | | | Abs | | Abs | -| Add | √ | √ | √ | √ | | √ | Add | | Add | -| AddN | | √ | | | | | AddN | | | -| Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | -| Argmin | | √ | √ | √ | | | Argmin | | | -| AvgPool | √ | √ | √ | √ | | √ | MeanPooling| Pooling | AveragePool | -| BatchNorm | √ | √ | √ | √ | | √ | | BatchNorm | BatchNormalization | -| BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | -| BiasAdd | | √ | √ | √ | | √ | | | BiasAdd | -| Broadcast | | √ | | | | | BroadcastTo | | Expand | -| Cast | √ | √ | | √ | | | Cast, DEQUANTIZE* | | Cast | -| Ceil | | √ | √ | √ | | | Ceil | | Ceil | -| Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | -| Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | -| Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | -| Cos | | √ | √ | √ | | | Cos | | Cos | -| Crop | | √ | √ | √ | | | | Crop | | -| DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | -| DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | -| DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | -| Div | √ | √ | √ | √ | | √ | Div, RealDiv | | Div | -| Eltwise | √ | √ | | | | | | Eltwise | | -| Elu | | √ | | | | | Elu | | Elu | -| Equal | √ | √ | √ | √ | | | Equal | | Equal | -| Exp | | √ | | | | | Exp | | Exp | -| ExpandDims | | √ | | | | | | | | -| Fill | | √ | | | | | Fill | | | -| Flatten | | √ | | | | | | Flatten | | -| Floor | | √ | √ | √ | | | flOOR | | Floor | -| FloorDiv | √ | √ | | | | | FloorDiv | | | -| FloorMod | √ | √ | | | | | FloorMod | | | -| FullConnection | | √ | √ | √ | | | FullyConnected | InnerProduct | | -| GatherNd | | √ | √ | √ | | | GatherND | | | -| GatherV2 | | √ | √ | √ | | | Gather | | Gather | -| Greater | √ | √ | √ | √ | | | Greater | | Greater | -| GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | -| Hswish | √ | √ | √ | √ | | | HardSwish | | | -| LeakyReLU | √ | √ | | | | √ | LeakyRelu | | LeakyRelu | -| Less | √ | √ | √ | √ | | | Less | | Less | -| LessEqual | √ | √ | √ | √ | | | LessEqual | | | -| LRN | | √ | | | | | LocalResponseNorm | | Lrn | -| Log | | √ | √ | √ | | | Log | | Log | -| LogicalAnd | √ | √ | | | | | LogicalAnd | | | -| LogicalNot | | √ | √ | √ | | | LogicalNot | | | -| LogicalOr | √ | √ | | | | | LogicalOr | | | -| LSTM | | √ | | | | | | | | -| MatMul | | √ | √ | √ | √ | √ | | | MatMul | -| Maximum | √ | √ | | | | | Maximum | | Max | -| MaxPool | √ | √ | √ | √ | | √ | MaxPooling | Pooling | MaxPool | -| Minimum | √ | √ | | | | | Minimum | | Min | -| Mul | √ | √ | √ | √ | | √ | Mul | | Mul | -| NotEqual | √ | √ | √ | √ | | | NotEqual | | | -| OneHot | | √ | | | | | OneHot | | | -| Pad | | √ | √ | √ | | | Pad | | Pad | -| Pow | | √ | √ | √ | | | Pow | Power | Power | -| PReLU | | √ | | | | √ | | PReLU | | -| Range | | √ | | | | | Range | | | -| Rank | | √ | | | | | Rank | | | -| ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | -| ReduceMean | √ | √ | √ | √ | | | Mean | | ReduceMean | -| ReduceMin | √ | √ | √ | √ | | | ReduceMin | | ReduceMin | -| ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | -| ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | -| ReduceSumSquare | √ | √ | √ | √ | | | | | | -| ReLU | √ | √ | √ | √ | | √ | Relu | ReLU | Relu | -| ReLU6 | √ | √ | √ | √ | | √ | Relu6 | ReLU6 | Clip* | -| Reshape | √ | √ | √ | √ | | √ | Reshape | Reshape | Reshape,Flatten | -| Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | -| Reverse | | √ | | | | | reverse | | | -| ReverseSequence | | √ | | | | | ReverseSequence | | | -| Round | | √ | √ | √ | | | Round | | | -| Rsqrt | | √ | √ | √ | | | Rsqrt | | | -| Scale | | √ | | | | | | Scale | | -| ScatterNd | | √ | | | | | ScatterNd | | | -| Shape | | √ | | | | | Shape | | Shape | -| Sigmoid | √ | √ | √ | √ | | √ | Logistic | Sigmoid | Sigmoid | -| Sin | | √ | √ | √ | | | Sin | | Sin | -| Slice | | √ | √ | √ | √ | √ | Slice | | Slice | -| Softmax | √ | √ | √ | √ | | √ | Softmax | Softmax | Softmax | -| SpaceToBatch | | √ | | | | | | | | -| SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | -| SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | -| SparseToDense | | √ | | | | | SpareToDense | | | -| Split | √ | √ | √ | √ | | | Split, SplitV | | | -| Sqrt | | √ | √ | √ | | | Sqrt | | Sqrt | -| Square | | √ | √ | √ | | | Square | | | -| SquaredDifference | | √ | | | | | SquaredDifference | | | -| Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | -| StridedSlice | | √ | √ | √ | | | StridedSlice| | | -| Stack | | √ | | | | | Stack | | | -| Sub | √ | √ | √ | √ | | √ | Sub | | Sub | -| Tanh | √ | √ | | | | | Tanh | TanH | | -| Tile | | √ | | | | | Tile | | Tile | -| TopK | | √ | √ | √ | | | TopKV2 | | | -| Transpose | √ | √ | | | | √ | Transpose | Permute | Transpose | -| Unique | | √ | | | | | Unique | | | -| Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | -| Unstack | | √ | | | | | Unstack | | | -| Where | | √ | | | | | Where | | | -| ZerosLike | | √ | | | | | ZerosLike | | | - -* Clip: only support convert clip(0, 6) to Relu6. -* DEQUANTIZE: only support to convert fp16 to fp32. diff --git a/lite/docs/source_zh_cn/_static/logo_source.png b/lite/docs/source_zh_cn/_static/logo_source.png deleted file mode 100644 index fc347d271abe082ae8d16242328551648766b6fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2009 zcmV;~2PXK5P)H00009a7bBm000XT z000XT0n*)m`~Uz4i%CR5RA_?=5PgUQtqqg1R-3H5BGlMp(8P#c(+ z(rpe+v7x0p?9ipaARp76>|1lRZz+1RfVD1)AZUbQX_|xMsIJ;bMPf&-oB%S~P*gy< z6J>X#gVK=o8G#1#CEsXSQ>`A>r1paj zA=*PxRA*aTJNm_>mOmpMd?WoOlq1~MH6*dLwA0=8D9~d&-2p#e+5qGi_U$|R#Ba85 z;14@Cn0;n_Kv=M}-%y!f-{-n@CM+6=vU^A>gXT!RhD)ujB%jC;kbRM^;u6Svje z_uo(4R+~ER=Ss@er1;Ut6Sq~fQZXx)D@8;6=wsz-63hi(RjXCt`4K+YQ#aff78h6W zI?Pim7*A^XH-6i_{cMQ@0^wxJ4JlDI$08I7_|vADHcbor0GVTYL9=ZZAw}>>90#`} zy**I;ia?Ng53I<%N8&ibAoCuPVMa6a zk$@kBjD>VLg3tbtECql?NiR;izLSz_; zAe>Ca^aAW1nn}cs5}Z4l znHL#GWSF>Ngp;WnAGjIDvkSnGHm&jO!tm@IixA|H8+bu~$Vm61$S}~VKsUF}K*Tzb z3D(v1Of z@7>!}TtPo@w9I>AdO_mYnz<>a7g&UbXXl8in!O6Xj_JB0_~J%sEEEKWxKXMZAZ6YY zRdan)(-OzZJP+~HY+L3%giR5AqnUZDA>NQ6#SH^0jQEsvftaqxbe(K*@Q{So5*daF zkvL9d7ywKbA)*OeuP}&WEJE&PA#ofL=qAw6odg!f4qVswW$vmGnE$4jzL!8p4xmAM5FgK1rKNbp#3=>t=zNu;A z&}Q{)ieC|Y&2FhnfVw2Qk$@k5O$n*XPdvG)YR~mQ8=0Lu@!97I`B;c$2^x2{H62>; z!q7|tpmOW%E^!<3Vb+Jb1nh-`jjB0dkaG{lXPyH;f0qX@om@(YMiOxIzhW@y?h4wqAKlveT32VWy!L)RUo4kj z>*@lT105Y}_wHry-Yu5P5bS}DC%iOmVSHl$e$Wl}T6jHs_pVzXU`U&0v0P>mdP_Q3 zGc+iIK)1GD`u5w@^724O$6F6RygR3Kz;&^_=A~&;`amMXL;`*buWPnlESDX42#ke- zppT=Q*GtnP!#Jm}4RmxUg0EO!14AT^gR>xa>v^)?CyTsoe`=Jf)v8sg{IgJ~dHRE& zEOzN(p!%OII@{WyzqTW^`>*>WN_#e5VYPgs)WrXEcUD(}Z2M04+(S<-R;6 dsize, UINT8_C1 borderValue) -``` - -对1通道图像应用仿射变换。 - -- 参数 - - - `src`: 输入图片数据。 - - `out_img`: 输出图片数据。 - - `M[6]`: 仿射变换矩阵。 - - `dsize`: 输出图像的大小。 - - `borderValue`: 采图之后用于填充的像素值。 - -``` -void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector dsize, UINT8_C3 borderValue) -``` - -对3通道图像应用仿射变换。 - -- 参数 - - - `src`: 输入图片数据。 - - `out_img`: 输出图片数据。 - - `M[6]`: 仿射变换矩阵。 - - `dsize`: 输出图像的大小。 - - `borderValue`: 采图之后用于填充的像素值。 - -``` -std::vector> GetDefaultBoxes(BoxesConfig config) -``` - -获取Faster R-CNN,SSD,YOLO等的默认框。 - -- 参数 - - - `config`: BoxesConfig结构体对象。 - -- 返回值 - - 返回默认框。 - -``` -void ConvertBoxes(std::vector> &boxes, std::vector> &default_boxes, BoxesConfig config) -``` - -将预测框转换为(y,x,h,w)的实际框。 - -- 参数 - - - `boxes`: 实际框的大小。 - - `default_boxes`: 默认框。 - - `config`: BoxesConfig结构体对象。 - -``` -std::vector ApplyNms(std::vector> &all_boxes, std::vector &all_scores, float thres, int max_boxes) -``` - -对实际框的非极大值抑制。 - -- 参数 - - - `all_boxes`: 所有输入的框。 - - `all_scores`: 通过网络执行后所有框的得分。 - - `thres`: IOU的预值。 - - `max_boxes`: 输出框的最大值。 -- 返回值 - - 返回框的id。 - -  - -## LiteMat - -LiteMat是一个处理图像的类。 - -**构造函数和析构函数** - - -``` -LiteMat() - -LiteMat(int width, LDataType data_type = LDataType::UINT8) - -LiteMat(int width, int height, LDataType data_type = LDataType::UINT8) - -LiteMat(int width, int height, int channel, LDataType data_type = LDataType::UINT8) -``` - -MindSpore中dataset模块下LiteMat的构造方法,使用参数的默认值。 - -``` -~LiteMat(); -``` - -MindSpore dataset LiteMat的析构函数。 - -**公有成员函数** - - -``` -void Init(int width, LDataType data_type = LDataType::UINT8) - -void Init(int width, int height, LDataType data_type = LDataType::UINT8) - -void Init(int width, int height, int channel, LDataType data_type = LDataType::UINT8) -``` - -该函数用于初始化图像的通道,宽度和高度,参数不同。 - -``` -bool IsEmpty() const -``` - -确定对象是否为空的函数。 - -- 返回值 - - 返回True或者False。 - -``` -void Release() -``` - -释放内存的函数。 - -**私有成员函数** - -``` -void *AlignMalloc(unsigned int size) -``` - -申请内存对齐的函数。 - -- 参数 - - - `size`: 内存大小。 - -- 返回值 - - 返回指针的大小。 - -``` -void AlignFree(void *ptr) -``` - -释放指针内存大小的方法。 - -``` -void InitElemSize(LDataType data_type) -``` - -通过data_type初始化元素字节数的值。 - -- 参数 - - - `data_type`: 数据的类型。 - -``` - int addRef(int *p, int value) -``` - -用于计算引用该函数次数的函数。 - -- 参数 - - - `p`: 指向引用的对象。 - - `value`: 引用时所加的值。 \ No newline at end of file diff --git a/lite/docs/source_zh_cn/apicc/errorcode_and_metatype.md b/lite/docs/source_zh_cn/apicc/errorcode_and_metatype.md deleted file mode 100644 index 4195eaedcf..0000000000 --- a/lite/docs/source_zh_cn/apicc/errorcode_and_metatype.md +++ /dev/null @@ -1,51 +0,0 @@ -# 错误码及元类型 - -以下表格描述了MindSpore Lite中支持的错误码和元类型。 - -## ErrorCode - -| 定义 | 值 | 描述 | -| --- | --- | --- | -| RET_OK | 0 | 执行成功。 | -| RET_ERROR | -1 | 通用错误码。 | -| RET_NULL_PTR | -2 | 返回空指针。 | -| RET_PARAM_INVALID | -3 | 无效参数。 | -| RET_NO_CHANGE | -4 | 无改变。 | -| RET_SUCCESS_EXIT | -5 | 无错误退出。 | -| RET_MEMORY_FAILED | -6 | 创建内存失败。 | -| RET_OUT_OF_TENSOR_RANGE | -101 | 输出检查越界。 | -| RET_INPUT_TENSOR_ERROR | -102 | 输入检查越界。 | -| RET_REENTRANT_ERROR | -103 | 存在运行中的执行器。 | -| RET_GRAPH_FILE_ERR | -201 | 图文件识别失败。 | -| RET_NOT_FIND_OP | -301 | 无法找到算子。 | -| RET_INVALID_OP_NAME | -302 | 无效算子名。 | -| RET_INVALID_OP_ATTR | -303 | 无效算子属性。 | -| RET_OP_EXECUTE_FAILURE | -304 | 算子执行失败。 | -| RET_FORMAT_ERR | -401 | 张量格式检查失败。 | -| RET_INFER_ERR | -501 | 维度推理失败。 | -| RET_INFER_INVALID | -502 | 无效的维度推理。 | - -## MetaType - - **enum**类型变量。 - -| 类型定义 | 值 | 描述 | -| --- | --- | --- | -|kNumberTypeBegin| 29 | 表示Number类型的起始。 | -|kNumberTypeBool| 30 | 表示Bool数据类型。 | -|kNumberTypeInt| 31 | 表示Int数据类型。 | -|kNumberTypeInt8| 32 | 表示Int8数据类型。 | -|kNumberTypeInt16| 33 | 表示Int16数据类型。 | -|kNumberTypeInt32| 34 | 表示Int32数据类型。 | -|kNumberTypeInt64| 35 | 表示Int64数据类型。 | -|kNumberTypeUInt| 36 | 表示UInt数据类型。 | -|kNumberTypeUInt8| 37 | 表示UInt8数据类型。 | -|kNumberTypeUInt16| 38 | 表示UInt16数据类型。 | -|kNumberTypeUInt32| 39 | 表示UInt32数据类型。 | -|kNumberTypeUInt64| 40 | 表示UInt64数据类型。 | -|kNumberTypeFloat| 41 | 表示Float数据类型。 | -|kNumberTypeFloat16| 42 | 表示Float16数据类型。 | -|kNumberTypeFloat32| 43 | 表示Float32数据类型。 | -|kNumberTypeFloat64| 44 | 表示Float64数据类型。| -|kNumberTypeEnd| 45 | 表示Number类型的结尾。 | - diff --git a/lite/docs/source_zh_cn/apicc/lite.md b/lite/docs/source_zh_cn/apicc/lite.md deleted file mode 100644 index 2673487a86..0000000000 --- a/lite/docs/source_zh_cn/apicc/lite.md +++ /dev/null @@ -1,197 +0,0 @@ -# mindspore::lite - -#include <[context.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/context.h)> - -#include <[model.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/model.h)> - -#include <[version.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/version.h)> - - -## Allocator - -Allocator类定义了一个内存池,用于动态地分配和释放内存。 - -## Context - -Context类用于保存执行中的环境变量。 - -**构造函数和析构函数** - -``` -Context() -``` - -用默认参数构造MindSpore Lite Context 对象。 - -``` -Context(int thread_num, std::shared_ptr allocator, DeviceContext device_ctx) -``` - -根据输入参数构造MindSpore Lite Context 对象。 - -- 参数 - - - `thread_num`: 定义了执行线程数。 - - - `allocator`: 定义了内存分配器。 - - - `device_ctx`: 定义了设备信息。 - -- 返回值 - - MindSpore Lite Context 指针。 - -``` -~Context() -``` - -MindSpore Lite Context 的析构函数。 - -**公有属性** - -``` -float16_priority -``` - -**bool** 值,默认为**false**,用于使能float16 推理。 - -``` -device_ctx_{DT_CPU} -``` - -[**DeviceContext**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#devicecontext)结构体。用于设置设备信息。 - -``` -thread_num_ -``` - -**int** 值,默认为**2**,设置线程数。 - -``` -allocator -``` - -指针类型,指向内存分配器[**Allocator**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#allocator)的指针。 - -``` -cpu_bind_mode_ -``` - -[**CpuBindMode**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#cpubindmode)枚举类型,默认为**MID_CPU**。 - -## PrimitiveC - -PrimitiveC定义为算子的原型。 - -## Model - -Model定义了MindSpore Lite中的模型,便于计算图管理。 - -**析构函数** - -``` -~Model() -``` - -MindSpore Lite Model的析构函数。 - -**公有成员函数** - -``` -void Destroy() -``` - -释放Model内的所有过程中动态分配的内存。 - -``` -void Free() -``` - -释放MindSpore Lite Model中的MetaGraph。 - -**静态公有成员函数** - -``` -static Model *Import(const char *model_buf, size_t size) -``` - -创建Model指针的静态方法。 - -- 参数 - - - `model_buf`: 定义了读取模型文件的缓存区。 - - - `size`: 定义了模型缓存区的字节数。 - -- 返回值 - - 指向MindSpore Lite的Model的指针。 - -## CpuBindMode -枚举类型,设置cpu绑定策略。 - -**属性** - -``` -MID_CPU = -1 -``` - -优先中等CPU绑定策略。 - -``` -HIGHER_CPU = 1 -``` - -优先高级CPU绑定策略。 - -``` -NO_BIND = 0 -``` - -不绑定。 - -## DeviceType -枚举类型,设置设备类型。 - -**属性** - -``` -DT_CPU = -1 -``` - -设备为CPU。 - -``` -DT_GPU = 1 -``` - -设备为GPU。 - -``` -DT_NPU = 0 -``` - -设备为NPU,暂不支持。 - -## DeviceContext - -定义设备类型的结构体。 - -**属性** - -``` -type -``` - -[**DeviceType**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#devicetype) 变量。设备类型。 - -## Version - -``` -std::string Version() -``` -全局方法,用于获取版本的字符串。 - -- 返回值 - - MindSpore Lite版本的字符串。 \ No newline at end of file diff --git a/lite/docs/source_zh_cn/apicc/session.md b/lite/docs/source_zh_cn/apicc/session.md deleted file mode 100644 index 86556e1351..0000000000 --- a/lite/docs/source_zh_cn/apicc/session.md +++ /dev/null @@ -1,177 +0,0 @@ -# mindspore::session - -#include <[lite_session.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/lite_session.h)> - - -## LiteSession - -LiteSession定义了MindSpore Lite中的会话,用于进行Model的编译和前向推理。 - -**构造函数和析构函数** - -``` -LiteSession() -``` -MindSpore Lite LiteSession的构造函数,使用默认参数。 -``` -~LiteSession() -``` -MindSpore Lite LiteSession的析构函数。 - -**公有成员函数** -``` -virtual void BindThread(bool if_bind) -``` -尝试将线程池中的线程绑定到指定的cpu内核,或从指定的cpu内核进行解绑。 - -- 参数 - - - `if_bind`: 定义了对线程进行绑定或解绑。 - -``` -virtual int CompileGraph(lite::Model *model) -``` -编译MindSpore Lite模型。 - -> 注意: CompileGraph必须在RunGraph方法之后调用。 - -- 参数 - - - `model`: 定义了需要被编译的模型。 - -- 返回值 - - STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h)中定义。 - -``` -virtual std::vector GetInputs() const -``` -获取MindSpore Lite模型的MSTensors输入。 - -- 返回值 - - MindSpore Lite MSTensor向量。 - -``` -std::vector GetInputsByName(const std::string &node_name) const -``` -通过节点名获取MindSpore Lite模型的MSTensors输入。 - -- 参数 - - - `node_name`: 定义了节点名。 - -- 返回值 - - MindSpore Lite MSTensor向量。 - -``` -virtual int RunGraph(const KernelCallBack &before = nullptr, const KernelCallBack &after = nullptr) -``` -运行带有回调函数的会话。 -> 注意: RunGraph必须在CompileGraph方法之后调用。 - -- 参数 - - - `before`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之前调用的回调函数。 - - - `after`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之后调用的回调函数。 - -- 返回值 - - STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h)中定义。 - -``` -virtual std::vector GetOutputsByNodeName(const std::string &node_name) const -``` -通过节点名获取MindSpore Lite模型的MSTensors输出。 - -- 参数 - - - `node_name`: 定义了节点名。 - -- 返回值 - - MindSpore Lite MSTensor向量。 - -``` -virtual std::unordered_map GetOutputs() const -``` -获取与张量名相关联的MindSpore Lite模型的MSTensors输出。 - -- 返回值 - - 包含输出张量名和MindSpore Lite MSTensor的容器类型变量。 - -``` -virtual std::vector GetOutputTensorNames() const -``` -获取由当前会话所编译的模型的输出张量名。 - -- 返回值 - - 字符串向量,其中包含了按顺序排列的输出张量名。 - -``` -virtual mindspore::tensor::MSTensor *GetOutputByTensorName(const std::string &tensor_name) const -``` -通过张量名获取MindSpore Lite模型的MSTensors输出。 - -- 参数 - - - `tensor_name`: 定义了张量名。 - -- 返回值 - - 指向MindSpore Lite MSTensor的指针。 - -``` -virtual int Resize(const std::vector &inputs, const std::vector> &dims) -``` -调整输入的形状。 - -- 参数 - - - `inputs`: 模型对应的所有输入。 - - `dims`: 输入对应的新的shape,顺序注意要与inputs一致。 - -- 返回值 - - STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h)中定义。 - -**静态公有成员函数** - -``` -static LiteSession *CreateSession(lite::Context *context) -``` -用于创建一个LiteSession指针的静态方法。 - -- 参数 - - - `context`: 定义了所要创建的session的上下文。 - -- 返回值 - - 指向MindSpore Lite LiteSession的指针。 -## KernelCallBack - -``` -using KernelCallBack = std::function inputs, std::vector outputs, const CallBackParam &opInfo)> -``` - -一个函数包装器。KernelCallBack 定义了指向回调函数的指针。 - -## CallBackParam - -一个结构体。CallBackParam定义了回调函数的输入参数。 -**属性** - -``` -name_callback_param -``` -**string** 类型变量。节点名参数。 - -``` -type_callback_param -``` -**string** 类型变量。节点类型参数。 \ No newline at end of file diff --git a/lite/docs/source_zh_cn/apicc/tensor.md b/lite/docs/source_zh_cn/apicc/tensor.md deleted file mode 100644 index e9eae1f0fd..0000000000 --- a/lite/docs/source_zh_cn/apicc/tensor.md +++ /dev/null @@ -1,142 +0,0 @@ -# mindspore::tensor - -#include <[ms_tensor.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/ms_tensor.h)> - - -## MSTensor - -MSTensor定义了MindSpore Lite中的张量。 - -**构造函数和析构函数** -``` -MSTensor() -``` -MindSpore Lite MSTensor的构造函数。 - -- 返回值 - - MindSpore Lite MSTensor 的实例。 - -``` -virtual ~MSTensor() -``` -MindSpore Lite Model的析构函数。 - -**公有成员函数** - -``` -virtual TypeId data_type() const -``` -获取MindSpore Lite MSTensor的数据类型。 - -> 注意:TypeId在[mindspore/mindspore/core/ir/dtype/type_id\.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/core/ir/dtype/type_id.h)中定义。只有TypeId枚举中的数字类型可用于MSTensor。 - -- 返回值 - - MindSpore Lite MSTensor类的MindSpore Lite TypeId。 - -``` -virtual TypeId set_data_type(TypeId data_type) -``` -设置MindSpore Lite MSTensor的数据类型。 - -- 参数 - - - `data_type`: 定义了MindSpore Lite MSTensor所需设置的MindSpore Lite TypeId。 - -- 返回值 - - 设置后的MindSpore Lite MSTensor的MindSpore Lite TypeI。 - -``` -virtual std::vector shape() const -``` -获取MindSpore Lite MSTensor的形状。 - -- 返回值 - - 一个包含MindSpore Lite MSTensor形状数值的整型向量。 - -``` -virtual size_t set_shape(const std::vector &shape) -``` -设置MindSpore Lite MSTensor的形状. - -- 参数 - - - `shape`: 定义了一个整型向量,包含了所需设置的MindSpore Lite MSTensor形状数值。 - -- 返回值 - - 设置形状后的MindSpore Lite MSTensor的大小。 - -``` -virtual int DimensionSize(size_t index) const -``` -Get size of the dimension of the MindSpore Lite MSTensor index by the parameter index. - -- 参数 - - - `index`: 定义了返回的维度的索引。 - -- 返回值 - - MindSpore Lite MSTensor的维度的大小。 - -``` -virtual int ElementsNum() const -``` -获取MSTensor中的元素个数。 - -- 返回值 - - MSTensor中的元素个数 - -``` -virtual std::size_t hash() const -``` -获取MindSpore Lite MSTensor的哈希码。 - -- 返回值 - - MindSpore Lite MSTensor的哈希码。 - -``` -virtual size_t Size() const -``` -获取MSTensor中的数据的字节数大小。 - -- 返回值 - - MSTensor中的数据的字节数大小。 - - -``` -virtual void *MutableData() const -``` -获取MSTensor中的数据的指针。 - -> 注意:该数据指针可用于对MSTensor中的数据进行读取和写入。 - -- 返回值 - - 指向MSTensor中的数据的指针。 - -**静态公有成员函数** - -``` -static MSTensor *CreateTensor(TypeId data_type, const std::vector &shape) -``` -创建MSTensor指针的静态方法。 - -> 注意:TypeId在[mindspore/mindspore/core/ir/dtype/type_id\.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/core/ir/dtype/type_id.h)中定义。只有TypeId枚举中的数字类型可用于MSTensor。 - -- 参数 - - - `data_type`: 定义了所要创建的张量的数据类型。 - - - `shape`: 定义了所要创建的张量的形状。 - -- 返回值 - - 指向MSTensor的指针。 \ No newline at end of file diff --git a/lite/docs/source_zh_cn/architecture_lite.md b/lite/docs/source_zh_cn/architecture_lite.md deleted file mode 100644 index ce86fa9829..0000000000 --- a/lite/docs/source_zh_cn/architecture_lite.md +++ /dev/null @@ -1,20 +0,0 @@ -# 总体架构 - - - -MindSpore Lite框架的总体架构如下所示: - -![architecture](images/MindSpore-Lite-architecture.png) - -- **前端(Frontend):** 负责模型生成,用户可以通过模型构建接口构建模型,将第三方模型和MindSpore训练的模型转换为MindSpore Lite模型,其中第三方模型包括TensorFlow Lite、Caffe 1.0和ONNX模型。 - -- **IR:** 负责MindSpore的Tensor定义、算子定义和图定义。 - -- **Backend:** 基于IR进行图优化,包括GHLO、GLLO和量化三部分。其中,GHLO负责和硬件无关的优化,如算子融合、常量折叠等;GLLO负责与硬件相关的优化;量化Quantizer支持权重量化、激活值量化等训练后量化手段。 - -- **Runtime:** 智能终端的推理运行时,其中session负责会话管理,提供对外接口;线程池和并行原语负责图执行使用的线程池管理,内存分配负责图执行中各个算子的内存复用,算子库提供CPU和GPU算子。 - -- **Micro:** IoT设备的运行时,包括模型生成.c文件、线程池、内存复用和算子库。 - -其中,Runtime和Micro共享底层的算子库、内存分配、线程池、并行原语等基础设施层。 - diff --git a/lite/docs/source_zh_cn/conf.py b/lite/docs/source_zh_cn/conf.py deleted file mode 100644 index dd8e0482bb..0000000000 --- a/lite/docs/source_zh_cn/conf.py +++ /dev/null @@ -1,62 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os - - -# -- Project information ----------------------------------------------------- - -project = 'MindSpore Lite' -copyright = '2020, MindSpore Lite' -author = 'MindSpore Lite' - -# The full version, including alpha/beta/rc tags -release = 'master' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx_markdown_tables', - 'recommonmark', -] - -source_suffix = { - '.rst': 'restructuredtext', - '.md': 'markdown', -} - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] - -pygments_style = 'sphinx' - -autodoc_inherit_docstrings = False - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' - -html_search_language = 'zh' - -html_static_path = ['_static'] \ No newline at end of file diff --git a/lite/docs/source_zh_cn/glossary_lite.md b/lite/docs/source_zh_cn/glossary_lite.md deleted file mode 100644 index b9cf41a4c6..0000000000 --- a/lite/docs/source_zh_cn/glossary_lite.md +++ /dev/null @@ -1,12 +0,0 @@ -# 术语 - - - -| 术语/缩略语 | 说明 | -| ----- | ----- | -| MindSpore Lite | 应用在智能终端,边缘册资源受限场景的MindSpore AI 引擎。 | -| MindSpore Micro | 应用在IoT设备的,包大小更小的MindSpore AI引擎。 | -| GHLO | Graph high-level optimization,图高层优化。 | -| GLLO | Graph low-level optimization,图底层优化。 | -| RT | Runtime运行时。 | - diff --git a/lite/docs/source_zh_cn/images/MindSpore-Lite-architecture.png b/lite/docs/source_zh_cn/images/MindSpore-Lite-architecture.png deleted file mode 100644 index abf28796690f5649f8bc92382dfd4c2c83187620..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55828 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 diff --git a/lite/docs/source_zh_cn/index_lite.rst b/lite/docs/source_zh_cn/index_lite.rst deleted file mode 100644 index 20ecdbb72c..0000000000 --- a/lite/docs/source_zh_cn/index_lite.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. MindSpore documentation master file, created by - sphinx-quickstart on Thu Aug 17 10:00:00 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -MindSpore端侧文档 -================== - -.. toctree:: - :glob: - :maxdepth: 1 - - architecture - apicc/apicc - operator_list - glossary diff --git a/lite/docs/source_zh_cn/operator_list_lite.md b/lite/docs/source_zh_cn/operator_list_lite.md deleted file mode 100644 index 3384d8baf9..0000000000 --- a/lite/docs/source_zh_cn/operator_list_lite.md +++ /dev/null @@ -1,111 +0,0 @@ -# 算子支持 - - - -> √勾选的项为MindSpore Lite所支持的算子。 - -| 操作名 | CPU
FP16 | CPU
FP32 | CPU
Int8 | CPU
UInt8 | GPU
FP16 | GPU
FP32 | 支持的Tensorflow
Lite op | 支持的Caffe
Lite op | 支持的Onnx
Lite op | -|-----------------------|----------|----------|----------|-----------|----------|-------------------|----------|----------|---------| -| Abs | | √ | √ | √ | | | Abs | | Abs | -| Add | √ | √ | √ | √ | | √ | Add | | Add | -| AddN | | √ | | | | | AddN | | | -| Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | -| Argmin | | √ | √ | √ | | | Argmin | | | -| AvgPool | √ | √ | √ | √ | | √ | MeanPooling| Pooling | AveragePool | -| BatchNorm | √ | √ | √ | √ | | √ | | BatchNorm | BatchNormalization | -| BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | -| BiasAdd | | √ | √ | √ | | √ | | | BiasAdd | -| Broadcast | | √ | | | | | BroadcastTo | | Expand | -| Cast | √ | √ | | √ | | | Cast, DEQUANTIZE* | | Cast | -| Ceil | | √ | √ | √ | | | Ceil | | Ceil | -| Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | -| Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | -| Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | -| Cos | | √ | √ | √ | | | Cos | | Cos | -| Crop | | √ | √ | √ | | | | Crop | | -| DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | -| DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | -| DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | -| Div | √ | √ | √ | √ | | √ | Div, RealDiv | | Div | -| Eltwise | √ | √ | | | | | | Eltwise | | -| Elu | | √ | | | | | Elu | | Elu | -| Equal | √ | √ | √ | √ | | | Equal | | Equal | -| Exp | | √ | | | | | Exp | | Exp | -| ExpandDims | | √ | | | | | | | | -| Fill | | √ | | | | | Fill | | | -| Flatten | | √ | | | | | | Flatten | | -| Floor | | √ | √ | √ | | | flOOR | | Floor | -| FloorDiv | √ | √ | | | | | FloorDiv | | | -| FloorMod | √ | √ | | | | | FloorMod | | | -| FullConnection | | √ | √ | √ | | | FullyConnected | InnerProduct | | -| GatherNd | | √ | √ | √ | | | GatherND | | | -| GatherV2 | | √ | √ | √ | | | Gather | | Gather | -| Greater | √ | √ | √ | √ | | | Greater | | Greater | -| GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | -| Hswish | √ | √ | √ | √ | | | HardSwish | | | -| LeakyReLU | √ | √ | | | | √ | LeakyRelu | | LeakyRelu | -| Less | √ | √ | √ | √ | | | Less | | Less | -| LessEqual | √ | √ | √ | √ | | | LessEqual | | | -| LRN | | √ | | | | | LocalResponseNorm | | Lrn | -| Log | | √ | √ | √ | | | Log | | Log | -| LogicalAnd | √ | √ | | | | | LogicalAnd | | | -| LogicalNot | | √ | √ | √ | | | LogicalNot | | | -| LogicalOr | √ | √ | | | | | LogicalOr | | | -| LSTM | | √ | | | | | | | | -| MatMul | | √ | √ | √ | √ | √ | | | MatMul | -| Maximum | √ | √ | | | | | Maximum | | Max | -| MaxPool | √ | √ | √ | √ | | √ | MaxPooling | Pooling | MaxPool | -| Minimum | √ | √ | | | | | Minimum | | Min | -| Mul | √ | √ | √ | √ | | √ | Mul | | Mul | -| NotEqual | √ | √ | √ | √ | | | NotEqual | | | -| OneHot | | √ | | | | | OneHot | | | -| Pad | | √ | √ | √ | | | Pad | | Pad | -| Pow | | √ | √ | √ | | | Pow | Power | Power | -| PReLU | | √ | | | | √ | | PReLU | | -| Range | | √ | | | | | Range | | | -| Rank | | √ | | | | | Rank | | | -| ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | -| ReduceMean | √ | √ | √ | √ | | | Mean | | ReduceMean | -| ReduceMin | √ | √ | √ | √ | | | ReduceMin | | ReduceMin | -| ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | -| ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | -| ReduceSumSquare | √ | √ | √ | √ | | | | | | -| ReLU | √ | √ | √ | √ | | √ | Relu | ReLU | Relu | -| ReLU6 | √ | √ | √ | √ | | √ | Relu6 | ReLU6 | Clip* | -| Reshape | √ | √ | √ | √ | | √ | Reshape | Reshape | Reshape,Flatten | -| Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | -| Reverse | | √ | | | | | reverse | | | -| ReverseSequence | | √ | | | | | ReverseSequence | | | -| Round | | √ | √ | √ | | | Round | | | -| Rsqrt | | √ | √ | √ | | | Rsqrt | | | -| Scale | | √ | | | | | | Scale | | -| ScatterNd | | √ | | | | | ScatterNd | | | -| Shape | | √ | | | | | Shape | | Shape | -| Sigmoid | √ | √ | √ | √ | | √ | Logistic | Sigmoid | Sigmoid | -| Sin | | √ | √ | √ | | | Sin | | Sin | -| Slice | | √ | √ | √ | √ | √ | Slice | | Slice | -| Softmax | √ | √ | √ | √ | | √ | Softmax | Softmax | Softmax | -| SpaceToBatch | | √ | | | | | | | | -| SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | -| SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | -| SparseToDense | | √ | | | | | SpareToDense | | | -| Split | √ | √ | √ | √ | | | Split, SplitV | | | -| Sqrt | | √ | √ | √ | | | Sqrt | | Sqrt | -| Square | | √ | √ | √ | | | Square | | | -| SquaredDifference | | √ | | | | | SquaredDifference | | | -| Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | -| StridedSlice | | √ | √ | √ | | | StridedSlice| | | -| Stack | | √ | | | | | Stack | | | -| Sub | √ | √ | √ | √ | | √ | Sub | | Sub | -| Tanh | √ | √ | | | | | Tanh | TanH | | -| Tile | | √ | | | | | Tile | | Tile | -| TopK | | √ | √ | √ | | | TopKV2 | | | -| Transpose | √ | √ | | | | √ | Transpose | Permute | Transpose | -| Unique | | √ | | | | | Unique | | | -| Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | -| Unstack | | √ | | | | | Unstack | | | -| Where | | √ | | | | | Where | | | -| ZerosLike | | √ | | | | | ZerosLike | | | - -* Clip: 仅支持将clip(0, 6)转换为Relu6. -* DEQUANTIZE: 仅支持将fp16转换为fp32. diff --git a/lite/lite.md b/lite/lite.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lite/lite_en.md b/lite/lite_en.md new file mode 100644 index 0000000000..e69de29bb2 -- Gitee From e62139712df42360716fde5732ad9f86640d395d Mon Sep 17 00:00:00 2001 From: Ting Wang Date: Mon, 14 Sep 2020 13:04:52 +0800 Subject: [PATCH 011/100] update index Signed-off-by: Ting Wang --- docs/api_python/source_en/index.rst | 62 ++++++++--------- docs/api_python/source_zh_cn/index.rst | 62 ++++++++--------- docs/note/source_en/index_lite.rst | 7 +- docs/note/source_zh_cn/index_lite.rst | 7 +- .../source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_en/_static/logo_source.png | Bin 0 -> 2009 bytes .../source_en/advanced_use/serving.md | 0 tutorials/inference/source_en/conf.py | 59 ++++++++++++++++ tutorials/inference/source_en/index.rst | 21 ++++++ .../source_en/use/multi_platform_inference.md | 0 .../source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_zh_cn/_static/logo_source.png | Bin 0 -> 2009 bytes .../source_zh_cn/advanced_use/serving.md | 0 tutorials/inference/source_zh_cn/conf.py | 63 ++++++++++++++++++ tutorials/inference/source_zh_cn/index.rst | 21 ++++++ .../use/multi_platform_inference.md | 0 tutorials/training/source_en/index.rst | 8 --- tutorials/training/source_zh_cn/index.rst | 8 --- 18 files changed, 232 insertions(+), 86 deletions(-) create mode 100644 tutorials/inference/source_en/_static/logo_notebook.png create mode 100644 tutorials/inference/source_en/_static/logo_source.png rename tutorials/{training => inference}/source_en/advanced_use/serving.md (100%) create mode 100644 tutorials/inference/source_en/conf.py create mode 100644 tutorials/inference/source_en/index.rst rename tutorials/{training => inference}/source_en/use/multi_platform_inference.md (100%) create mode 100644 tutorials/inference/source_zh_cn/_static/logo_notebook.png create mode 100644 tutorials/inference/source_zh_cn/_static/logo_source.png rename tutorials/{training => inference}/source_zh_cn/advanced_use/serving.md (100%) create mode 100644 tutorials/inference/source_zh_cn/conf.py create mode 100644 tutorials/inference/source_zh_cn/index.rst rename tutorials/{training => inference}/source_zh_cn/use/multi_platform_inference.md (100%) diff --git a/docs/api_python/source_en/index.rst b/docs/api_python/source_en/index.rst index 12f19eaff2..8ead7c54c1 100644 --- a/docs/api_python/source_en/index.rst +++ b/docs/api_python/source_en/index.rst @@ -10,44 +10,44 @@ MindSpore API :maxdepth: 1 :caption: MindSpore Python API - api/python/mindspore/mindspore - api/python/mindspore/mindspore.dtype - api/python/mindspore/mindspore.common.initializer - api/python/mindspore/mindspore.communication - api/python/mindspore/mindspore.context - api/python/mindspore/mindspore.hub - api/python/mindspore/mindspore.nn - api/python/mindspore/mindspore.nn.dynamic_lr - api/python/mindspore/mindspore.nn.learning_rate_schedule - api/python/mindspore/mindspore.nn.probability - api/python/mindspore/mindspore.ops - api/python/mindspore/mindspore.ops.composite - api/python/mindspore/mindspore.ops.operations - api/python/mindspore/mindspore.train - api/python/mindspore/mindspore.dataset - api/python/mindspore/mindspore.dataset.config - api/python/mindspore/mindspore.dataset.text - api/python/mindspore/mindspore.dataset.transforms - api/python/mindspore/mindspore.dataset.vision - api/python/mindspore/mindspore.mindrecord - api/python/mindspore/mindspore.profiler + mindspore/mindspore + mindspore/mindspore.dtype + mindspore/mindspore.common.initializer + mindspore/mindspore.communication + mindspore/mindspore.context + mindspore/mindspore.hub + mindspore/mindspore.nn + mindspore/mindspore.nn.dynamic_lr + mindspore/mindspore.nn.learning_rate_schedule + mindspore/mindspore.nn.probability + mindspore/mindspore.ops + mindspore/mindspore.ops.composite + mindspore/mindspore.ops.operations + mindspore/mindspore.train + mindspore/mindspore.dataset + mindspore/mindspore.dataset.config + mindspore/mindspore.dataset.text + mindspore/mindspore.dataset.transforms + mindspore/mindspore.dataset.vision + mindspore/mindspore.mindrecord + mindspore/mindspore.profiler .. toctree:: :maxdepth: 1 :caption: MindArmour Python API - api/python/mindarmour/mindarmour - api/python/mindarmour/mindarmour.adv_robustness.attacks - api/python/mindarmour/mindarmour.adv_robustness.defenses - api/python/mindarmour/mindarmour.adv_robustness.detectors - api/python/mindarmour/mindarmour.adv_robustness.evaluations - api/python/mindarmour/mindarmour.fuzz_testing - api/python/mindarmour/mindarmour.privacy.diff_privacy - api/python/mindarmour/mindarmour.privacy.evaluation - api/python/mindarmour/mindarmour.utils + mindarmour/mindarmour + mindarmour/mindarmour.adv_robustness.attacks + mindarmour/mindarmour.adv_robustness.defenses + mindarmour/mindarmour.adv_robustness.detectors + mindarmour/mindarmour.adv_robustness.evaluations + mindarmour/mindarmour.fuzz_testing + mindarmour/mindarmour.privacy.diff_privacy + mindarmour/mindarmour.privacy.evaluation + mindarmour/mindarmour.utils .. toctree:: :maxdepth: 1 :caption: MindSpore Hub Python API - api/python/mindspore_hub/mindspore_hub + mindspore_hub/mindspore_hub diff --git a/docs/api_python/source_zh_cn/index.rst b/docs/api_python/source_zh_cn/index.rst index 502e8495e2..647dcdffda 100644 --- a/docs/api_python/source_zh_cn/index.rst +++ b/docs/api_python/source_zh_cn/index.rst @@ -16,44 +16,44 @@ MindSpore API :maxdepth: 1 :caption: MindSpore Python API - api/python/mindspore/mindspore - api/python/mindspore/mindspore.dtype - api/python/mindspore/mindspore.common.initializer - api/python/mindspore/mindspore.communication - api/python/mindspore/mindspore.context - api/python/mindspore/mindspore.hub - api/python/mindspore/mindspore.nn - api/python/mindspore/mindspore.nn.dynamic_lr - api/python/mindspore/mindspore.nn.learning_rate_schedule - api/python/mindspore/mindspore.nn.probability - api/python/mindspore/mindspore.ops - api/python/mindspore/mindspore.ops.composite - api/python/mindspore/mindspore.ops.operations - api/python/mindspore/mindspore.train - api/python/mindspore/mindspore.dataset - api/python/mindspore/mindspore.dataset.config - api/python/mindspore/mindspore.dataset.text - api/python/mindspore/mindspore.dataset.transforms - api/python/mindspore/mindspore.dataset.vision - api/python/mindspore/mindspore.mindrecord - api/python/mindspore/mindspore.profiler + mindspore/mindspore + mindspore/mindspore.dtype + mindspore/mindspore.common.initializer + mindspore/mindspore.communication + mindspore/mindspore.context + mindspore/mindspore.hub + mindspore/mindspore.nn + mindspore/mindspore.nn.dynamic_lr + mindspore/mindspore.nn.learning_rate_schedule + mindspore/mindspore.nn.probability + mindspore/mindspore.ops + mindspore/mindspore.ops.composite + mindspore/mindspore.ops.operations + mindspore/mindspore.train + mindspore/mindspore.dataset + mindspore/mindspore.dataset.config + mindspore/mindspore.dataset.text + mindspore/mindspore.dataset.transforms + mindspore/mindspore.dataset.vision + mindspore/mindspore.mindrecord + mindspore/mindspore.profiler .. toctree:: :maxdepth: 1 :caption: MindArmour Python API - api/python/mindarmour/mindarmour - api/python/mindarmour/mindarmour.adv_robustness.attacks - api/python/mindarmour/mindarmour.adv_robustness.defenses - api/python/mindarmour/mindarmour.adv_robustness.detectors - api/python/mindarmour/mindarmour.adv_robustness.evaluations - api/python/mindarmour/mindarmour.fuzz_testing - api/python/mindarmour/mindarmour.privacy.diff_privacy - api/python/mindarmour/mindarmour.privacy.evaluation - api/python/mindarmour/mindarmour.utils + mindarmour/mindarmour + mindarmour/mindarmour.adv_robustness.attacks + mindarmour/mindarmour.adv_robustness.defenses + mindarmour/mindarmour.adv_robustness.detectors + mindarmour/mindarmour.adv_robustness.evaluations + mindarmour/mindarmour.fuzz_testing + mindarmour/mindarmour.privacy.diff_privacy + mindarmour/mindarmour.privacy.evaluation + mindarmour/mindarmour.utils .. toctree:: :maxdepth: 1 :caption: MindSpore Hub Python API - api/python/mindspore_hub/mindspore_hub + mindspore_hub/mindspore_hub diff --git a/docs/note/source_en/index_lite.rst b/docs/note/source_en/index_lite.rst index abecfe957e..c333a1965a 100644 --- a/docs/note/source_en/index_lite.rst +++ b/docs/note/source_en/index_lite.rst @@ -10,7 +10,6 @@ MindSpore Lite Documentation :glob: :maxdepth: 1 - architecture - apicc/apicc - operator_list - glossary + architecture_lite + operator_list_lite + glossary_lite diff --git a/docs/note/source_zh_cn/index_lite.rst b/docs/note/source_zh_cn/index_lite.rst index 20ecdbb72c..715f7b1b5c 100644 --- a/docs/note/source_zh_cn/index_lite.rst +++ b/docs/note/source_zh_cn/index_lite.rst @@ -10,7 +10,6 @@ MindSpore端侧文档 :glob: :maxdepth: 1 - architecture - apicc/apicc - operator_list - glossary + architecture_lite + operator_list_lite + glossary_lite diff --git a/tutorials/inference/source_en/_static/logo_notebook.png b/tutorials/inference/source_en/_static/logo_notebook.png new file mode 100644 index 0000000000000000000000000000000000000000..8b60a39049880c74956d5e37c985ebfd7f401d5d GIT binary patch literal 1832 zcmV+@2iN$CP)-K$iVR#(6O=)=A4x!r~RH%m{3jvu>v{MdSO z`0*z)hD)QZYhQhd5V|@ye{F8Q5eK^r@9cF4G@xTg;-I9e)su>*DVkR6?thMws>Tb& zZLUI)<%GDfqo$NpH6bpTe7Jp={_}C5Xj;$2WVKHRXJ!YcrsIVoH#Yw7he9lukLB`p z1d>vDaAtO!3yT+u(M)zb4E4#mvGJaX$!I3ajg9xG?!szIs>+RxgTn`BX5TCjH;99b zqMS;m(t3xuNzfPvosNVk8pRb&OG@RC+Z}W|M*4bLih6^!ZU-e*eLM5eCK1c!qnT{j z!xcX}Tm0OxQzI`5IWIJHsbRF3B-HY!vP_= z3o0x{ffh;5il(s?74~p6#_>W?kQLZ2!~Sj>z;|plB$}5z*4K0Ed+wBD4J%XLI~YCb2{wd zKpg^oLo+SizCk`%3SEG~l_OnOj&#+LtVYP~iWiCygMutqdn8^cvQ*1x;3Qnq7)LYN zJ7-SQ80#_af*6NY>M2C4-g6P35Aq>N7=tsj5uX>H8}WIea7KJy;2G)bg}pTzI0=ej z566v-C#5ow4EwtYA#6cQ!l2Uus|Dep)6p|ANl3ugJVO)f0D>%AYOz#{r7Z-ocS&-M zB0g`tPz<@<5FD0fCMC(z?HkmEH%8dQ#d7(iRMvZi1)iZzJwZZTpfM(a zuh;Ko2%v;0hTN{CR37$slU>d;G)c$=;6bp5Gy%jf;A>M`00|}`ipCCx$PmJi+ZD}Z zA#YU^3iA4|LgsmfVJV7`^rzB_rVabMO{*1T#Zn6%YO=)yIBmf#mZD$)CK#8up_#SZ zzEkfHpc{x63a^WTr@lN(QIIf#PNyI%B~?{4E$DR67(;p9kiq!qEiEP?_Ah91z+Gb$!Uo}r<{K!JpwfTdalS%Yl{lO=T-*enTQACoF; z+N=?u7Y@&{T;AC6)zPXCXg1@8g2|0_)N7ep%k4WD2Ry^@3=N%d_1$5AHynjoih@pu zlz(Gy!81%WleH`g)u1ts_`J~H@eGrcB+^wtUV+~r?BNEc?vvgnDV52iW4V0L>4X7n zAWK5nMgvp#A^9gnG3a#YwM+sY8e=GG#`+C1)moc5&<^{%2d3`#OiaS6^mDjWQkO>q z9~;Hs6joBzT4vUAdlS0w#VN-j@-c~wYav~!+^bZ`H;DRZv%L%bi>;~2D0r^Dz0GFR zo55ElAmnym?&>7QymTI*wOpj7D?Oc01VWu$-*zEzkooATo#l;_< zJY^~B27dyQCreSeKmQVBC1AIQ+-_S_lOW5_S5|0@i3~#Ma#!d0vp=4%tOT7-__b;g z0?GKZXVZ&|0lWQ%{tfo|%8R3|tpU3oA#}90Ri9ab%hw@pp;gNk(+>TBEmsVFdY1e_~=B>VCZs08kLg;Vc W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT z000XT0n*)m`~Uz4i%CR5RA_?=5PgUQtqqg1R-3H5BGlMp(8P#c(+ z(rpe+v7x0p?9ipaARp76>|1lRZz+1RfVD1)AZUbQX_|xMsIJ;bMPf&-oB%S~P*gy< z6J>X#gVK=o8G#1#CEsXSQ>`A>r1paj zA=*PxRA*aTJNm_>mOmpMd?WoOlq1~MH6*dLwA0=8D9~d&-2p#e+5qGi_U$|R#Ba85 z;14@Cn0;n_Kv=M}-%y!f-{-n@CM+6=vU^A>gXT!RhD)ujB%jC;kbRM^;u6Svje z_uo(4R+~ER=Ss@er1;Ut6Sq~fQZXx)D@8;6=wsz-63hi(RjXCt`4K+YQ#aff78h6W zI?Pim7*A^XH-6i_{cMQ@0^wxJ4JlDI$08I7_|vADHcbor0GVTYL9=ZZAw}>>90#`} zy**I;ia?Ng53I<%N8&ibAoCuPVMa6a zk$@kBjD>VLg3tbtECql?NiR;izLSz_; zAe>Ca^aAW1nn}cs5}Z4l znHL#GWSF>Ngp;WnAGjIDvkSnGHm&jO!tm@IixA|H8+bu~$Vm61$S}~VKsUF}K*Tzb z3D(v1Of z@7>!}TtPo@w9I>AdO_mYnz<>a7g&UbXXl8in!O6Xj_JB0_~J%sEEEKWxKXMZAZ6YY zRdan)(-OzZJP+~HY+L3%giR5AqnUZDA>NQ6#SH^0jQEsvftaqxbe(K*@Q{So5*daF zkvL9d7ywKbA)*OeuP}&WEJE&PA#ofL=qAw6odg!f4qVswW$vmGnE$4jzL!8p4xmAM5FgK1rKNbp#3=>t=zNu;A z&}Q{)ieC|Y&2FhnfVw2Qk$@k5O$n*XPdvG)YR~mQ8=0Lu@!97I`B;c$2^x2{H62>; z!q7|tpmOW%E^!<3Vb+Jb1nh-`jjB0dkaG{lXPyH;f0qX@om@(YMiOxIzhW@y?h4wqAKlveT32VWy!L)RUo4kj z>*@lT105Y}_wHry-Yu5P5bS}DC%iOmVSHl$e$Wl}T6jHs_pVzXU`U&0v0P>mdP_Q3 zGc+iIK)1GD`u5w@^724O$6F6RygR3Kz;&^_=A~&;`amMXL;`*buWPnlESDX42#ke- zppT=Q*GtnP!#Jm}4RmxUg0EO!14AT^gR>xa>v^)?CyTsoe`=Jf)v8sg{IgJ~dHRE& zEOzN(p!%OII@{WyzqTW^`>*>WN_#e5VYPgs)WrXEcUD(}Z2M04+(S<-R;6 Date: Mon, 14 Sep 2020 16:04:32 +0800 Subject: [PATCH 012/100] remove mindspore.hub and add mindspore_hub.load --- docs/api_python/source_en/index.rst | 1 - docs/api_python/source_en/mindspore/mindspore.hub.rst | 4 ---- docs/api_python/source_zh_cn/index.rst | 1 - .../source_zh_cn/mindspore/mindspore.hub.rst | 4 ---- .../source_en/use/multi_platform_inference.md | 9 ++++----- .../source_zh_cn/use/multi_platform_inference.md | 11 +++++------ 6 files changed, 9 insertions(+), 21 deletions(-) delete mode 100644 docs/api_python/source_en/mindspore/mindspore.hub.rst delete mode 100644 docs/api_python/source_zh_cn/mindspore/mindspore.hub.rst diff --git a/docs/api_python/source_en/index.rst b/docs/api_python/source_en/index.rst index 8ead7c54c1..5e24b2f5ab 100644 --- a/docs/api_python/source_en/index.rst +++ b/docs/api_python/source_en/index.rst @@ -15,7 +15,6 @@ MindSpore API mindspore/mindspore.common.initializer mindspore/mindspore.communication mindspore/mindspore.context - mindspore/mindspore.hub mindspore/mindspore.nn mindspore/mindspore.nn.dynamic_lr mindspore/mindspore.nn.learning_rate_schedule diff --git a/docs/api_python/source_en/mindspore/mindspore.hub.rst b/docs/api_python/source_en/mindspore/mindspore.hub.rst deleted file mode 100644 index 458c704fc3..0000000000 --- a/docs/api_python/source_en/mindspore/mindspore.hub.rst +++ /dev/null @@ -1,4 +0,0 @@ -mindspore.hub -============= - -.. autofunction:: mindspore.hub.load_weights diff --git a/docs/api_python/source_zh_cn/index.rst b/docs/api_python/source_zh_cn/index.rst index 647dcdffda..13bd141b9f 100644 --- a/docs/api_python/source_zh_cn/index.rst +++ b/docs/api_python/source_zh_cn/index.rst @@ -21,7 +21,6 @@ MindSpore API mindspore/mindspore.common.initializer mindspore/mindspore.communication mindspore/mindspore.context - mindspore/mindspore.hub mindspore/mindspore.nn mindspore/mindspore.nn.dynamic_lr mindspore/mindspore.nn.learning_rate_schedule diff --git a/docs/api_python/source_zh_cn/mindspore/mindspore.hub.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.hub.rst deleted file mode 100644 index 458c704fc3..0000000000 --- a/docs/api_python/source_zh_cn/mindspore/mindspore.hub.rst +++ /dev/null @@ -1,4 +0,0 @@ -mindspore.hub -============= - -.. autofunction:: mindspore.hub.load_weights diff --git a/tutorials/inference/source_en/use/multi_platform_inference.md b/tutorials/inference/source_en/use/multi_platform_inference.md index 15b2ce276e..161eb2e41b 100644 --- a/tutorials/inference/source_en/use/multi_platform_inference.md +++ b/tutorials/inference/source_en/use/multi_platform_inference.md @@ -82,17 +82,16 @@ MindSpore supports the following inference scenarios based on the hardware platf 1.2 Remote Storage - When the pre-trained models are saved remotely, the steps of performing inference on validation dataset are as follows: firstly creating a model, then loading model and parameters using `hub.load_weights`, and finally performing inference on validation dataset once created. The processing method of the validation dataset is the same as that of the training dataset. + When the pre-trained models are saved remotely, the steps of performing inference on validation dataset are as follows: firstly determine which model to be used, then loading model and parameters using `mindspore_hub.load`, and finally performing inference on validation dataset once created. The processing method of the validation dataset is the same as that of the training dataset. ```python - network = LeNet5(cfg.num_classes) + model_uid = "mindspore/ascend/0.7/googlenet_v1_cifar10" # using GoogleNet as an example. + network = mindspore_hub.load(model_uid, num_classes=10) net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") net_opt = nn.Momentum(network.trainable_params(), cfg.lr, cfg.momentum) model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy()}) print("============== Starting Testing ==============") - hub.load_weights(network, network_name="lenet", **{"device_target": - "ascend", "dataset":"mnist", "version": "0.5.0"}) dataset = create_dataset(os.path.join(args.data_path, "test"), cfg.batch_size, 1) @@ -101,7 +100,7 @@ MindSpore supports the following inference scenarios based on the hardware platf ``` In the preceding information: - `hub.load_weights` is an API for loading model parameters. PLease check the details in . + `mindpsore_hub.load` is an API for loading model parameters. PLease check the details in . 2. Use the `model.predict` API to perform inference. ```python diff --git a/tutorials/inference/source_zh_cn/use/multi_platform_inference.md b/tutorials/inference/source_zh_cn/use/multi_platform_inference.md index 5628bdc5c1..39c0870168 100644 --- a/tutorials/inference/source_zh_cn/use/multi_platform_inference.md +++ b/tutorials/inference/source_zh_cn/use/multi_platform_inference.md @@ -79,18 +79,17 @@ CPU | ONNX格式 | 支持ONNX推理的runtime/SDK,如TensorRT。 `model.eval`为模型验证接口,对应接口说明:。 > 推理样例代码:。 - 1.2 模型保存在华为云 + 1.2 使用MindSpore Hub从华为云加载模型 - 首先构建模型,然后使用`hub.load_weights`从云端加载模型参数,传入验证数据集后即可进行推理,验证数据集的处理方式与训练数据集相同。 + 首先构建模型,然后使用`mindspore_hub.load`从云端加载模型参数,传入验证数据集后即可进行推理,验证数据集的处理方式与训练数据集相同。 ```python - network = LeNet5(cfg.num_classes) + model_uid = "mindspore/ascend/0.7/googlenet_v1_cifar10" # using GoogleNet as an example. + network = mindspore_hub.load(model_uid, num_classes=10) net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") net_opt = nn.Momentum(network.trainable_params(), cfg.lr, cfg.momentum) model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy()}) print("============== Starting Testing ==============") - hub.load_weights(network, network_name="lenet", **{"device_target": - "ascend", "dataset":"mnist", "version": "0.5.0"}) dataset = create_dataset(os.path.join(args.data_path, "test"), cfg.batch_size, 1) @@ -98,7 +97,7 @@ CPU | ONNX格式 | 支持ONNX推理的runtime/SDK,如TensorRT。 print("============== {} ==============".format(acc)) ``` 其中, - `hub.load_weights`为加载模型参数接口,对应接口说明:。 + `mindspore_hub.load`为加载模型参数接口,对应接口说明:。 2. 使用`model.predict`接口来进行推理操作。 ```python -- Gitee From 59efb1798e69c7a89183ee19ed31bcb85db04f52 Mon Sep 17 00:00:00 2001 From: yingchen Date: Mon, 14 Sep 2020 11:51:49 +0800 Subject: [PATCH 013/100] update computer vision application --- .../advanced_use/computer_vision_application.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/computer_vision_application.md b/tutorials/training/source_en/advanced_use/computer_vision_application.md index 8ead2a76fd..b15b0539b6 100644 --- a/tutorials/training/source_en/advanced_use/computer_vision_application.md +++ b/tutorials/training/source_en/advanced_use/computer_vision_application.md @@ -22,13 +22,13 @@ ## Overview -Computer vision is the most widely researched and mature technology field of deep learning, and is widely used in scenarios such as mobile phone photographing, intelligent security protection, and automated driving. Since AlexNet won the ImageNet competition in 2012, deep learning has greatly promoted the development of the computer vision field. Almost all the most advanced computer vision algorithms are related to deep learning. Deep neural network can extract image features layer by layer and retain local invariance. It is widely used in visual tasks such as classification, detection, segmentation, tracking, retrieval, recognition, promotion, and reconstruction. +Computer vision is one of the most widely researched and mature technology fields of deep learning, and is widely applied to scenarios such as mobile phone photographing, intelligent security protection, and automated driving. Since AlexNet won the ImageNet competition in 2012, deep learning has greatly promoted the development of the computer vision field. Almost all the most advanced computer vision algorithms are related to deep learning. Deep neural network can extract image features layer by layer and retain local invariance. It is widely used in visual tasks such as classification, detection, segmentation, tracking, retrieval, recognition, promotion, and reconstruction. This chapter describes how to apply MindSpore to computer vision scenarios based on image classification tasks. ## Image Classification -Image classification is the most basic computer vision application and belongs to the supervised learning category. For example, determine the class of a digital image, such as cat, dog, airplane, or car. The function is as follows: +Image classification is one of the most basic computer vision applications and belongs to the supervised learning category. For example, determine the class of a digital image, such as cat, dog, airplane, or car. The function is as follows: ```python def classify(image): @@ -49,9 +49,9 @@ MindSpore supports the following image classification networks: LeNet, AlexNet, Figure 1: CIFAR-10 dataset [1] -Figure 1 shows that the CIFAR-10 dataset contains 10 classes of 60,000 images. Each class contains 6000 images. 50,000 images are for training and 10,000 images are for testing. The size of each image is 32 x 32 pixels. +The CIFAR-10 dataset contains 10 classes of 60,000 images. Each class contains 6000 images. 50,000 images are for training and 10,000 images are for testing. The size of each image is 32 x 32 pixels. -Generally, a training indicator of image classification is accuracy, that is, a ratio of a quantity of accurately predicted examples to a total quantity of predicted examples. +Generally, a training indicator of image classification is accuracy, that is, a ratio of the quantity of accurately predicted examples to the total quantity of predicted examples. Next, let's use MindSpore to solve the image classification task. The overall process is as follows: 1. Download the CIFAR-10 dataset. @@ -61,12 +61,12 @@ Next, let's use MindSpore to solve the image classification task. The overall pr 5. Call the high-level `Model` API to train and save the model file. 6. Load the saved model for inference. -> This example is for the hardware platform of the Ascend 910 AI processor. You can find the complete executable sample code at: . +> This example uses the hardware platform of the Ascend 910 AI processor. You can find the complete executable sample code at: . The key parts of the task process code are explained below. ### Downloading the CIFAR-10 Dataset -CIFAR-10 dataset download address: [the website of Cifar-10 Dataset](https://www.cs.toronto.edu/~kriz/cifar.html) In this example, the data is in binary format. In the Linux environment, run the following command to download the dataset: +CIFAR-10 dataset download address: [the website of Cifar-10 Dataset](https://www.cs.toronto.edu/~kriz/cifar.html). In this example, the data is in binary format. In the Linux environment, run the following command to download the dataset: ```shell wget https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz -- Gitee From a487b1f047fde52d56fd34b25a369509c1b1829a Mon Sep 17 00:00:00 2001 From: Ziyan Date: Fri, 11 Sep 2020 09:37:56 +0800 Subject: [PATCH 014/100] optimizer distributed training design --- .../mindspore/distributed_training_design.md | 144 ++++++++++++++++++ .../design/mindspore/images/auto_parallel.png | Bin 0 -> 56566 bytes .../design/mindspore/images/data_parallel.png | Bin 0 -> 57944 bytes .../mindspore/images/operator_split.png | Bin 0 -> 31956 bytes .../images/tensor_redistribution.png | Bin .../images/tensor_redistribution1.png | Bin 0 -> 54984 bytes .../images/tensor_redistribution2.png | Bin 0 -> 59677 bytes .../images/tensor_redistribution3.png | Bin 0 -> 54617 bytes .../mindspore/distributed_training_design.md | 10 +- .../design/mindspore/images/data_parallel.png | Bin 14300 -> 57944 bytes .../images/tensor_redistribution1.png | Bin 62482 -> 54984 bytes .../images/tensor_redistribution2.png | Bin 65607 -> 59677 bytes .../images/tensor_redistribution3.png | Bin 53765 -> 54617 bytes 13 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 docs/note/source_en/design/mindspore/distributed_training_design.md create mode 100644 docs/note/source_en/design/mindspore/images/auto_parallel.png create mode 100644 docs/note/source_en/design/mindspore/images/data_parallel.png create mode 100644 docs/note/source_en/design/mindspore/images/operator_split.png rename docs/note/{source_zh_cn => source_en}/design/mindspore/images/tensor_redistribution.png (100%) create mode 100644 docs/note/source_en/design/mindspore/images/tensor_redistribution1.png create mode 100644 docs/note/source_en/design/mindspore/images/tensor_redistribution2.png create mode 100644 docs/note/source_en/design/mindspore/images/tensor_redistribution3.png diff --git a/docs/note/source_en/design/mindspore/distributed_training_design.md b/docs/note/source_en/design/mindspore/distributed_training_design.md new file mode 100644 index 0000000000..b943ae1f4f --- /dev/null +++ b/docs/note/source_en/design/mindspore/distributed_training_design.md @@ -0,0 +1,144 @@ +# Distributed Training Design + +`Ascend` `GPU` `Model Development` `Model Optimization` `Framework Development` `Intermediate` `Expert` `Contributor` + + + +- [Distributed Training Design](#distributed-training-design) + - [Background](#background) + - [Concepts](#concepts) + - [Collective Communication](#collective-communication) + - [Synchronization Mode](#synchronization-mode) + - [Data Parallelism](#data-parallelism) + - [Principle of Data Parallelism](#principle-of-data-parallelism) + - [Data Parallel Code](#data-parallel-code) + - [Automatic Parallelism](#automatic-parallelism) + - [Principle of Automatic Parallelism](#principle-of-automatic-parallelism) + - [Automatic Parallel Code](#automatic-parallel-code) + + + + + +## Background + +With the rapid development of deep learning, the number of datasets and parameters are growing exponentially to improve the accuracy and generalization capability of neural networks. Parallel distributed training has become a development trend to resolve the performance bottleneck of ultra-large scale networks. MindSpore supports the mainstream distributed training paradigm and develops an automatic hybrid parallel solution. The following describes the design principles of several parallel training modes and provides guidance for users to perform custom development. + + +## Concepts + +### Collective Communication + +Collective communication is defined as communication that involves a group of processes. All processes in the group send and receive data after meeting certain conditions. MindSpore implements data transmission during parallel training through collective communication. On Ascend chips, MindSpore depends on the Huawei Collective Communication Library (`HCCL`) to implement the task. On GPU, MindSpore depends on the NVIDIA Collective Communication Library (`NCCL`) to implement the task. + +### Synchronization Mode + +In synchronous mode, all devices strart training at the same time and update parameter values synchronously after the backward propagation algorithm is executed. Currently, MindSpore uses the synchronous training mode. + +## Data Parallelism + +This section describes how the data parallel mode `ParallelMode.DATA_PARALLEL` works in MindSpore. + +### Principle of Data Parallelism + +![Data Parallel Description](./images/data_parallel.png) + +1. Environment dependencies + + Each time before parallel training starts, the `mindspore.communication.init` API is called to initialize communication resources and the global communication group `WORLD_COMM_GROUP` is automatically created. + +2. Data distribution + + The key of data parallelism is to split datasets based on the sample dimension and deliver the split datasets to different devices. Each dataset loading API provided by the `mindspore.dataset` module has the `num_shards` and `shard_id` parameters. The parameters are used to split a dataset into multiple datasets, perform cyclic sampling, and collect data of the `batch` size to each device. When the data volume is insufficient, the sampling restarts from the beginning. + +3. Network structure + + The scripting method of data parallel network is the same as that of standalone network. This is because, although models of each device are executed independently during the forward and backward propagation processes, the same network structure is maintained. To ensure the synchronous training between devices, the initial values of corresponding network parameters must be the same. You are advised to set the same random number seed on each device by using `numpy.random.seed` to broadcast models. + +4. Gradient aggregation + + Theoretically, the training effect of data parallel network should be the same as that of the standalone network. To ensure the consistency of the calculation logic, the `AllReduce` operator is inserted after gradient calculation to implement the gradient aggregation operation between devices. You can enable `mean` to average the sum of gradient values, or regard `mean` as a hyperparameter. Enabling `mean` is equivalent to reducing the learning rate by multiple times. + +5. Parameter update + + Because the gradient aggregation operation is introduced, the models of each device perform parameter update with the same gradient value. Therefore, MindSpore implements a synchronous data parallel training mode. Theoretically, models trained by each device are the same. If the reduce operation on samples is involved on the network, the network output may be different. This is determined by the sharding attribute of data parallelism. + +### Data Parallel Code + +1. Collective communication + + - [management.py](https://gitee.com/mindspore/mindspore/blob/master/mindspore/communication/management.py): This file covers the `helper` function APIs commonly used during the collective communication process, for example, the APIs for obtaining the number of clusters and device ID. When collective communication is executed on the Ascend chip, the framework loads the `libhccl.so` library file in the environment and uses it to call the communication APIs from the Python layer to the underlying layer. + - [comm_ops.py](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ops/operations/comm_ops.py): MindSpore encapsulates supported collective communication operations as operators and stores the operators in this file. The operators include `AllReduce`, `AllGather`, `ReduceScatter`, and `Broadcast`. `PrimitiveWithInfer` defines the attributes required by the operators, as well as the `shape` and `dtype` inference methods from the input to the output during graph composition. + +2. Gradient aggregation + + - [grad_reducer.py](https://gitee.com/mindspore/mindspore/blob/master/mindspore/nn/wrap/grad_reducer.py): This file implements the gradient aggregation process. After the input parameter `grads` is expanded by using `HyperMap`, the `AllReduce` operator is inserted. The global communication group is used. You can also perform custom development by referring to this section based on your network requirements. In MindSpore, standalone and distributed execution shares a set of network encapsulation APIs. In the `Cell`, `ParallelMode` is used to determine whether to perform gradient aggregation. For details about the network encapsulation APIs, see the `TrainOneStepCell` code implementation. + + +## Automatic Parallelism + +As a key feature of MindSpore, automatic parallelism is used to implement hybrid parallel training that combines automatic data parallelism and model parallelism. It aims to help users express the parallel algorithm logic using standalone scripts, reduce the difficulty of distributed training, improve the algorithm R&D efficiency, and maintain the high performance of training. This section describes how the automatic parallel mode `ParallelMode.AUTO_PARALLEL` and semi-automatic parallel mode `ParallelMode.SEMI_AUTO_PARALLEL` work in MindSpore. + +### Principle of Automatic Parallelism + +![Automatic Parallel Description](./images/auto_parallel.png) + +1. Distributed operator and tensor layout + + As shown in the preceding figure, the automatic parallel process traverses the standalone forward ANF graphs and performs shard modeling on tensors in the unit of distributed operator, indicating how the input and output tensors of an operator are distributed to each device of the cluster, that is, the tensor layout. Users do not need to know which device runs which slice of a model. The framework automatically schedules and allocates model slices. + + To obtain the tensor layout model, each operator has a shard strategy, which indicates the shard status of each input of the operator in the corresponding dimension. Generally, tensors can be sharded in any dimension as long as the value is a multiple of 2, and the even distribution principle is met. The following figure shows an example of the three-dimensional `BatchMatmul` operation. The parallel strategy consists of two tuples, indicating the sharding of `input` and `weight`, respectively. Elements in a tuple correspond to tensor dimensions one by one. `2^N` indicates the shard unit, and `1` indicates that the tuple is not sharded. If you want to express a parallel data shard strategy, that is, only data in the `batch` dimension of `input` is sharded, and data in other dimensions are not sharded, you can use `strategy=((2^N, 1, 1),(1, 1, 1))`. If you want to express a parallel model shard strategy, that is, only model in the non-`batch` dimension of `weight` is sharded, for example, only the `channel` dimension is sharded, you can use `strategy=((1, 1, 1),(1, 1, 2^N))`. If you want to express a hybrid parallel shard strategy, one of which is `strategy=((2^N, 1, 1),(1, 1, 2^N))`. + + ![Operator Sharding Definition](./images/operator_split.png) + + Based on the shard strategy of an operator, the framework automatically derives the distribution model of input tensors and output tensors of the operator. This distribution model consists of `device_matrix`, `tensor_shape`, and `tensor map`, which indicate the device matrix shape, tensor shape, and mapping between devices and tensor dimensions, respectively. Based on the tensor layout model, distributed operator determines whether to insert extra computation and communication operations in the graph to ensure that the operator computing logic is correct. + +2. Tensor Redistribution + + When the output tensor model of an operator is inconsistent with the input tensor model of the next operator, computation and communication operations need to be introduced to implement the change between tensor layouts. The automatic parallel process introduces the tensor redistribution algorithm, which can be used to derive the communication conversion operations between random tensor layouts. The following three examples represent a parallel computing process of the formula `Z=(X×W)×V`, that is, a `MatMul` operation of two two-dimensional matrices, and show how to perform conversion between different parallel modes. + + In example 1, the output of the first data parallel matrix multiplication is sharded in the row rection, and the input of the second model parallel matrix multiplication requires full tensors. The framework automatically inserts the `AllGather` operator to implement redistribution. + + ![Tensor Redistribution](./images/tensor_redistribution1.png) + + In example 2, the output of parallel matrix multiplication of the first model is sharded in the column direction, and the input of parallel matrix multiplication of the second model is sharded in the row direction. The framework automatically inserts a communication operator equivalent to the `AlltoAll` operation in collective communication to implement redistribution. + + ![Tensor Redistribution](./images/tensor_redistribution2.png) + + In example 3, an output shard mode of the first hybrid parallel matrix multiplication is the same as an input shard mode of the second hybrid parallel matrix multiplication. Therefore, redistribution does not need to be introduced. In the second matrix multiplication operation, the related dimensions of the two inputs are sharded. Therefore, the `AllReduce` operator needs to be inserted to ensure the operation correctness. + + ![Tensor Redistribution](./images/tensor_redistribution3.png) + + In general, this distributed representation breaks the boundary between data parallelism and model parallelism, making it easy to implement hybrid parallelism. From the perspective of scripts, users only need to construct a standalone network to express the parallel algorithm logic. Framework automatically shards the entire graph. + +3. Efficient parallel strategy search algorithm + + The `SEMI_AUTO_PARALLEL` semi-automatic parallel mode indicates that you manually configure the parallel strategy for operators when you are familiar with the operator sharding representation. This mode is helpful for manual optimization, with certain commissioning difficulty. You need to master the parallel principle and obtain a high-performance parallel solution based on the network structure and cluster topology. To further help users accelerate the parallel network training process, the automatic parallel mode `AUTO_PARALLEL` introduces the automatic search feature of the parallel strategy on the basis of the semi-automatic parallel mode. Automatic parallelism builds cost models based on the hardware platform, and calculates the computation cost, memory cost, and communication cost of a certain amount of data and specific operators based on different parallel strategies Then, by using the dynamic programming algorithm or recursive programming algorithm and taking the memory upper limit of a single device as a constraint condition, a parallel strategy with optimal performance is efficiently searched out. + + Strategy search replaces manual model sharding and provides a high-performance sharding solution within a short period of time, greatly reducing the threshold for parallel training. + + +4. Convenient distributed automatic differentiation + + In addition to forward network communication, the traditional manual model sharding needs to consider backward parallel computing. MindSpore encapsulates communication operations into operators and automatically generates backward propagation of communication operators based on the original automatic differentiation operations of the framework. Therefore, even during distributed training, users only need to pay attention to the forward propagation of the network to implement actual automatic parallel training. + +### Automatic Parallel Code + +1. Tensor layout model + - [tensor_layout](https://gitee.com/mindspore/mindspore/tree/master/mindspore/ccsrc/frontend/parallel/tensor_layout): This directory contains the definitions and implementation of functions related to the tensor distribution model. `tensor_layout.h` declares the member variables `tensor_map_origin_`, `tensor_shape_`, and `device_arrangement_` required by a tensor distribution model. In `tensor_redistribution.h`, the related methods for implementing the `from_origin_` and `to_origin_` transformation between tensor distributions are declared. The deduced redistribution operation is stored in `operator_list_` and returned, in addition, the communication cost `comm_cost_`,, memory cost `memory_cost_`, and calculation cost `computation_cost_` required for redistribution are calculated. + +2. Distributed operators + - [ops_info](https://gitee.com/mindspore/mindspore/tree/master/mindspore/ccsrc/frontend/parallel/ops_info): This directory contains the implementation of distributed operators. In `operator_info.h`, the base class `OperatorInfo` of distributed operator implementation is defined. A distributed operator to be developed shall inherit the base class and explicitly implement related imaginary functions. The `InferTensorInfo`, `InferTensorMap`, and `InferDevMatrixShape` functions define the algorithms for deriving the input and output tensor distribution model of the operator. The `InferForwardCommunication` and `InferMirrorOps` functions define the extra calculation and communication operations to be inserted for operator sharding. The `CheckStrategy` and `GenerateStrategies` functions define the parallel strategy validation and generation for the operator. According to the parallel strategy `SetCostUnderStrategy`, the parallel cost `operator_cost_` of the distributed operator is generated. + +3. Strategy search algorithm + - [auto_parallel](https://gitee.com/mindspore/mindspore/tree/master/mindspore/ccsrc/frontend/parallel/auto_parallel): The shard strategy search algorithm is implemented in this directory. `graph_costmodel.h` defines the graph composition information. Each point indicates an operator `OperatorInfo`. The directed edge `edge_costmodel.h` indicates the input and output relationship of operators and the redistribution cost. `operator_costmodel.h` defines the cost model of each operator, including the calculation cost, communication cost, and memory cost. `dp_algorithm_costmodel.h` describes the main process of the dynamic planning algorithm, which consists of a series of graph operations. `costmodel.h` defines the data structures of cost and graph operations. + +4. Device management + - [device_manager.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/frontend/parallel/device_manager.h): This file is used to create and manage cluster device communication groups. The device matrix model is defined by `device_matrix.h`, and the communication domain is managed by `group_manager.h`. + +5. Entire graph sharding + - [step_auto_parallel.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/frontend/parallel/step_auto_parallel.h), and [step_parallel.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/frontend/parallel/step_parallel.h): The two files contain the core implementation of the automatic parallel process. `step_auto_parallel.h` calls the strategy search process and generates the `OperatorInfo` of the distributed operator. Then in `step_parallel.h`, processes such as operator sharding and tensor redistribution are processed to reconstruct the standalone computing graph in distributed mode. + + +6. Backward propagation of communication operators + - [grad_comm_ops.py](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ops/_grad/grad_comm_ops.py): This file defines the backward propagation of communication operators, such as `AllReduce` and `AllGather`. diff --git a/docs/note/source_en/design/mindspore/images/auto_parallel.png b/docs/note/source_en/design/mindspore/images/auto_parallel.png new file mode 100644 index 0000000000000000000000000000000000000000..800b3b2536c739dcc48a1e46b5f65fc327e4ce8d GIT binary patch literal 56566 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 Xjl>=rOhaavfXm>Hu}+zmW5mA!R)z9; literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindspore/images/data_parallel.png b/docs/note/source_en/design/mindspore/images/data_parallel.png new file mode 100644 index 0000000000000000000000000000000000000000..a92c82aa64615b398e83b9bc2cf0aa2c5db9f904 GIT binary patch literal 57944 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 jdZqteSiw9fINb#c!%JkGhRT!TqOvh;I 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 - + ## 背景 @@ -47,19 +47,19 @@ 每次开始进行并行训练前,通过调用`mindspore.communication.init`接口初始化通信资源,并自动创建全局通信组`WORLD_COMM_GROUP`。 -2. 数据分发 +2. 数据分发(Data distribution) 数据并行的核心在于将数据集在样本维度拆分并下发到不同的卡上。在`mindspore.dataset`模块提供的所有数据集加载接口中都有`num_shards`和`shard_id`两个参数,它们用于将数据集拆分为多份并循环采样的方式,采集`batch`大小的数据到各自的卡上,当出现数据量不足的情况时将会从头开始采样。 3. 网络构图 - 数据并行网络的书写方式与单机网络没有差别,这是因为在正反向传播过程中各卡的模型间是独立执行的,只是保持了相同的网络结构。唯一需要特别注意的是为了保证各卡间训练同步,相应的网络参数初始化值应当是一致的,这里建议通过`numpy.random.seed`在每张卡上设置相同的随机数种子达到模型广播的目的。 + 数据并行网络的书写方式与单机网络没有差别,这是因为在正反向传播(Forward propogation & Backword Propogation)过程中各卡的模型间是独立执行的,只是保持了相同的网络结构。唯一需要特别注意的是为了保证各卡间训练同步,相应的网络参数初始化值应当是一致的,这里建议通过`numpy.random.seed`在每张卡上设置相同的随机数种子达到模型广播的目的。 -4. 梯度聚合 +4. 梯度聚合(Gradient aggregation) 数据并行理论上应该实现和单机一致的训练效果,为了保证计算逻辑的一致性,在梯度计算完成后插入`AllReduce`算子实现各卡间的梯度聚合操作。这里我们设置了`mean`开关,用户可以选择是否要对求和后的梯度值进行求平均操作,也可以将其视为超参项,打开开关等价于学习率倍数缩小。 -5. 参数更新 +5. 参数更新(Parameter update) 因为引入了梯度聚合操作,所以各卡的模型会以相同的梯度值一起进入参数更新步骤。因此MindSpore实现的是一种同步数据并行训练方式。理论上最终每卡训练出来的模型是相同的,如果网络中含有在样本维度的归约类型操作,网络的输出可能会有所差别,这是由数据并行的切分性质决定的。 diff --git a/docs/note/source_zh_cn/design/mindspore/images/data_parallel.png b/docs/note/source_zh_cn/design/mindspore/images/data_parallel.png index a926948143fbdfbe323fe661672c0aad824459a0..a92c82aa64615b398e83b9bc2cf0aa2c5db9f904 100644 GIT binary patch literal 57944 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 jdZqteM7nh8JqV$Qlz{YJ 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 diff --git a/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution1.png b/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution1.png index 2220231387851241c5fa8d514aff00c0f4e3cc49..ed4d79416a0a07f8d75e738aa544d214834ae778 100644 GIT binary patch literal 54984 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 kbG4>i$C6AE}qh{}qT3F-g*FC~6K9RL6T diff --git a/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution2.png b/docs/note/source_zh_cn/design/mindspore/images/tensor_redistribution2.png index 1261cdc28b2f8c3a6f0ccba9adb96e9d0fb5bcfa..114f984c66ae578722dbcdbb59ab03c44dbcb097 100644 GIT binary patch literal 59677 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

    5KhMj{t9t)BG#Edb&36Y(a$xhiFeFVN2OBe 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 -- Gitee From a4b78e7627422af2e85a21166ae4e94d460868ba Mon Sep 17 00:00:00 2001 From: lihongkang <[lihongkang1@huawei.com]> Date: Mon, 14 Sep 2020 17:24:40 +0800 Subject: [PATCH 015/100] update op list --- docs/note/source_en/operator_list.md | 2 +- docs/note/source_zh_cn/operator_list.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/note/source_en/operator_list.md b/docs/note/source_en/operator_list.md index bf38c07967..5f8f57179a 100644 --- a/docs/note/source_en/operator_list.md +++ b/docs/note/source_en/operator_list.md @@ -37,7 +37,7 @@ | [mindspore.nn.Flatten](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Flatten) |Supported | Supported | Supported |layer/basic | [mindspore.nn.Dense](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Dense) |Supported | Supported | Supported |layer/basic | [mindspore.nn.ClipByNorm](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.ClipByNorm) |Supported | Supported | Doing |layer/basic -| [mindspore.nn.Norm](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Norm) |Doing | Supported | Doing |layer/basic +| [mindspore.nn.Norm](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Norm) |Supported | Supported | Doing |layer/basic | [mindspore.nn.OneHot](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.OneHot) | Supported | Supported | Supported |layer/basic | [mindspore.nn.Range](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Range) | Supported | Doing | Doing |layer/basic | [mindspore.nn.SequentialCell](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.SequentialCell) |Supported | Supported | Doing |layer/container diff --git a/docs/note/source_zh_cn/operator_list.md b/docs/note/source_zh_cn/operator_list.md index f3adc9459f..f29cc3fd7e 100644 --- a/docs/note/source_zh_cn/operator_list.md +++ b/docs/note/source_zh_cn/operator_list.md @@ -37,7 +37,7 @@ | [mindspore.nn.Flatten](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Flatten) |Supported | Supported | Supported |layer/basic | [mindspore.nn.Dense](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Dense) |Supported | Supported | Supported |layer/basic | [mindspore.nn.ClipByNorm](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.ClipByNorm) |Supported | Supported | Doing |layer/basic -| [mindspore.nn.Norm](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Norm) |Doing | Supported | Doing |layer/basic +| [mindspore.nn.Norm](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Norm) |Supported | Supported | Doing |layer/basic | [mindspore.nn.OneHot](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.OneHot) | Supported | Supported | Supported |layer/basic | [mindspore.nn.Range](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Range) | Supported | Doing | Doing |layer/basic | [mindspore.nn.SequentialCell](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.SequentialCell) |Supported | Supported | Doing |layer/container -- Gitee From 9fbfb02293212c387ba88508d739acb28ec675f9 Mon Sep 17 00:00:00 2001 From: leiyuning Date: Mon, 14 Sep 2020 19:41:53 +0800 Subject: [PATCH 016/100] add _static dir --- docs/api_cpp/source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes docs/api_cpp/source_en/_static/logo_source.png | Bin 0 -> 2009 bytes .../source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../api_cpp/source_zh_cn/_static/logo_source.png | Bin 0 -> 2009 bytes .../api_java/source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes docs/api_java/source_en/_static/logo_source.png | Bin 0 -> 2009 bytes .../source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_zh_cn/_static/logo_source.png | Bin 0 -> 2009 bytes .../source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes docs/faq/source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes docs/faq/source_en/_static/logo_source.png | Bin 0 -> 2009 bytes docs/faq/source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes docs/faq/source_zh_cn/_static/logo_source.png | Bin 0 -> 2009 bytes docs/note/source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes docs/note/source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_en/_static/logo_source.png | Bin 0 -> 2009 bytes .../programming_guide/source_en/api_structure.md | 3 +++ .../source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../source_zh_cn/_static/logo_source.png | Bin 0 -> 2009 bytes .../source_zh_cn/api_structure.md | 2 +- .../lite/source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../lite/source_zh_cn/_static/logo_notebook.png | Bin 0 -> 1832 bytes .../training/source_en/_static/logo_notebook.png | Bin 0 -> 1832 bytes 25 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 docs/api_cpp/source_en/_static/logo_notebook.png create mode 100644 docs/api_cpp/source_en/_static/logo_source.png create mode 100644 docs/api_cpp/source_zh_cn/_static/logo_notebook.png create mode 100644 docs/api_cpp/source_zh_cn/_static/logo_source.png create mode 100644 docs/api_java/source_en/_static/logo_notebook.png create mode 100644 docs/api_java/source_en/_static/logo_source.png create mode 100644 docs/api_java/source_zh_cn/_static/logo_notebook.png create mode 100644 docs/api_java/source_zh_cn/_static/logo_source.png create mode 100644 docs/api_python/source_en/_static/logo_notebook.png create mode 100644 docs/api_python/source_zh_cn/_static/logo_notebook.png create mode 100644 docs/faq/source_en/_static/logo_notebook.png create mode 100644 docs/faq/source_en/_static/logo_source.png create mode 100644 docs/faq/source_zh_cn/_static/logo_notebook.png create mode 100644 docs/faq/source_zh_cn/_static/logo_source.png create mode 100644 docs/note/source_en/_static/logo_notebook.png create mode 100644 docs/note/source_zh_cn/_static/logo_notebook.png create mode 100644 docs/programming_guide/source_en/_static/logo_notebook.png create mode 100644 docs/programming_guide/source_en/_static/logo_source.png create mode 100644 docs/programming_guide/source_en/api_structure.md create mode 100644 docs/programming_guide/source_zh_cn/_static/logo_notebook.png create mode 100644 docs/programming_guide/source_zh_cn/_static/logo_source.png create mode 100644 tutorials/lite/source_en/_static/logo_notebook.png create mode 100644 tutorials/lite/source_zh_cn/_static/logo_notebook.png create mode 100644 tutorials/training/source_en/_static/logo_notebook.png diff --git a/docs/api_cpp/source_en/_static/logo_notebook.png b/docs/api_cpp/source_en/_static/logo_notebook.png new file mode 100644 index 0000000000000000000000000000000000000000..8b60a39049880c74956d5e37c985ebfd7f401d5d GIT binary patch literal 1832 zcmV+@2iN$CP)-K$iVR#(6O=)=A4x!r~RH%m{3jvu>v{MdSO z`0*z)hD)QZYhQhd5V|@ye{F8Q5eK^r@9cF4G@xTg;-I9e)su>*DVkR6?thMws>Tb& zZLUI)<%GDfqo$NpH6bpTe7Jp={_}C5Xj;$2WVKHRXJ!YcrsIVoH#Yw7he9lukLB`p z1d>vDaAtO!3yT+u(M)zb4E4#mvGJaX$!I3ajg9xG?!szIs>+RxgTn`BX5TCjH;99b zqMS;m(t3xuNzfPvosNVk8pRb&OG@RC+Z}W|M*4bLih6^!ZU-e*eLM5eCK1c!qnT{j z!xcX}Tm0OxQzI`5IWIJHsbRF3B-HY!vP_= z3o0x{ffh;5il(s?74~p6#_>W?kQLZ2!~Sj>z;|plB$}5z*4K0Ed+wBD4J%XLI~YCb2{wd zKpg^oLo+SizCk`%3SEG~l_OnOj&#+LtVYP~iWiCygMutqdn8^cvQ*1x;3Qnq7)LYN zJ7-SQ80#_af*6NY>M2C4-g6P35Aq>N7=tsj5uX>H8}WIea7KJy;2G)bg}pTzI0=ej z566v-C#5ow4EwtYA#6cQ!l2Uus|Dep)6p|ANl3ugJVO)f0D>%AYOz#{r7Z-ocS&-M zB0g`tPz<@<5FD0fCMC(z?HkmEH%8dQ#d7(iRMvZi1)iZzJwZZTpfM(a zuh;Ko2%v;0hTN{CR37$slU>d;G)c$=;6bp5Gy%jf;A>M`00|}`ipCCx$PmJi+ZD}Z zA#YU^3iA4|LgsmfVJV7`^rzB_rVabMO{*1T#Zn6%YO=)yIBmf#mZD$)CK#8up_#SZ zzEkfHpc{x63a^WTr@lN(QIIf#PNyI%B~?{4E$DR67(;p9kiq!qEiEP?_Ah91z+Gb$!Uo}r<{K!JpwfTdalS%Yl{lO=T-*enTQACoF; z+N=?u7Y@&{T;AC6)zPXCXg1@8g2|0_)N7ep%k4WD2Ry^@3=N%d_1$5AHynjoih@pu zlz(Gy!81%WleH`g)u1ts_`J~H@eGrcB+^wtUV+~r?BNEc?vvgnDV52iW4V0L>4X7n zAWK5nMgvp#A^9gnG3a#YwM+sY8e=GG#`+C1)moc5&<^{%2d3`#OiaS6^mDjWQkO>q z9~;Hs6joBzT4vUAdlS0w#VN-j@-c~wYav~!+^bZ`H;DRZv%L%bi>;~2D0r^Dz0GFR zo55ElAmnym?&>7QymTI*wOpj7D?Oc01VWu$-*zEzkooATo#l;_< zJY^~B27dyQCreSeKmQVBC1AIQ+-_S_lOW5_S5|0@i3~#Ma#!d0vp=4%tOT7-__b;g z0?GKZXVZ&|0lWQ%{tfo|%8R3|tpU3oA#}90Ri9ab%hw@pp;gNk(+>TBEmsVFdY1e_~=B>VCZs08kLg;Vc W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT 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 W4XI#LEpO2P0000H00009a7bBm000XT z000XT0n*)m`~Uz4i%CR5RA_?=5PgUQtqqg1R-3H5BGlMp(8P#c(+ z(rpe+v7x0p?9ipaARp76>|1lRZz+1RfVD1)AZUbQX_|xMsIJ;bMPf&-oB%S~P*gy< z6J>X#gVK=o8G#1#CEsXSQ>`A>r1paj zA=*PxRA*aTJNm_>mOmpMd?WoOlq1~MH6*dLwA0=8D9~d&-2p#e+5qGi_U$|R#Ba85 z;14@Cn0;n_Kv=M}-%y!f-{-n@CM+6=vU^A>gXT!RhD)ujB%jC;kbRM^;u6Svje z_uo(4R+~ER=Ss@er1;Ut6Sq~fQZXx)D@8;6=wsz-63hi(RjXCt`4K+YQ#aff78h6W zI?Pim7*A^XH-6i_{cMQ@0^wxJ4JlDI$08I7_|vADHcbor0GVTYL9=ZZAw}>>90#`} zy**I;ia?Ng53I<%N8&ibAoCuPVMa6a zk$@kBjD>VLg3tbtECql?NiR;izLSz_; zAe>Ca^aAW1nn}cs5}Z4l znHL#GWSF>Ngp;WnAGjIDvkSnGHm&jO!tm@IixA|H8+bu~$Vm61$S}~VKsUF}K*Tzb z3D(v1Of z@7>!}TtPo@w9I>AdO_mYnz<>a7g&UbXXl8in!O6Xj_JB0_~J%sEEEKWxKXMZAZ6YY zRdan)(-OzZJP+~HY+L3%giR5AqnUZDA>NQ6#SH^0jQEsvftaqxbe(K*@Q{So5*daF zkvL9d7ywKbA)*OeuP}&WEJE&PA#ofL=qAw6odg!f4qVswW$vmGnE$4jzL!8p4xmAM5FgK1rKNbp#3=>t=zNu;A z&}Q{)ieC|Y&2FhnfVw2Qk$@k5O$n*XPdvG)YR~mQ8=0Lu@!97I`B;c$2^x2{H62>; z!q7|tpmOW%E^!<3Vb+Jb1nh-`jjB0dkaG{lXPyH;f0qX@om@(YMiOxIzhW@y?h4wqAKlveT32VWy!L)RUo4kj z>*@lT105Y}_wHry-Yu5P5bS}DC%iOmVSHl$e$Wl}T6jHs_pVzXU`U&0v0P>mdP_Q3 zGc+iIK)1GD`u5w@^724O$6F6RygR3Kz;&^_=A~&;`amMXL;`*buWPnlESDX42#ke- zppT=Q*GtnP!#Jm}4RmxUg0EO!14AT^gR>xa>v^)?CyTsoe`=Jf)v8sg{IgJ~dHRE& zEOzN(p!%OII@{WyzqTW^`>*>WN_#e5VYPgs)WrXEcUD(}Z2M04+(S<-R;6 - + ## 设计理念 diff --git a/tutorials/lite/source_en/_static/logo_notebook.png b/tutorials/lite/source_en/_static/logo_notebook.png new file mode 100644 index 0000000000000000000000000000000000000000..8b60a39049880c74956d5e37c985ebfd7f401d5d GIT binary patch literal 1832 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 W4XI#LEpO2P0000 Date: Tue, 15 Sep 2020 10:03:06 +0800 Subject: [PATCH 017/100] Add Convertor tool docs for windows enviroment --- tutorials/lite/source_en/build.md | 55 +----------------- .../lite/source_en/use/converter_tool.md | 13 +---- tutorials/lite/source_zh_cn/build.md | 56 +------------------ .../lite/source_zh_cn/use/converter_tool.md | 11 +--- 4 files changed, 9 insertions(+), 126 deletions(-) diff --git a/tutorials/lite/source_en/build.md b/tutorials/lite/source_en/build.md index ef1282a257..b33d449665 100644 --- a/tutorials/lite/source_en/build.md +++ b/tutorials/lite/source_en/build.md @@ -9,12 +9,7 @@ - [Compilation Example](#compilation-example) - [Output Description](#output-description) - [Description of Converter's Directory Structure](#description-of-converters-directory-structure) - - [Description of Runtime and Other tools' Directory Structure](#description-of-runtime-and-other-tools-directory-structure) - - [Windows Environment Compilation](#windows-environment-compilation) - - [Environment Requirements](#environment-requirements-1) - - [Compilation Options](#compilation-options-1) - - [Compilation Example](#compilation-example-1) - - [Output Description](#output-description-1) + - [Description of Runtime and Other tools' Directory Structure](#description-of-runtime-and-other-tools-directory-structure) @@ -24,7 +19,7 @@ This chapter introduces how to quickly compile MindSpore Lite, which includes th | Module | Support Platform | Description | | --- | ---- | ---- | -| converter | Linux、Windows | Model Conversion Tool | +| converter | Linux | Model Conversion Tool | | runtime | Linux、Android | Model Inference Framework | | benchmark | Linux、Android | Benchmarking Tool | | time_profiler | Linux、Android | Performance Analysis Tool | @@ -183,49 +178,3 @@ The inference framework can be obtained under `-I x86_64`, `-I arm64` and `-I ar > 1. `liboptimize.so` only exists in the output package of runtime-arm64 and is only used on ARMv8.2 and CPUs that support fp16. > 2. Compile ARM64 to get the inference framework output of arm64-cpu by default, if you add `-e gpu`, you will get the inference framework output of arm64-gpu, and the package name is `mindspore-lite-{version}-runtime-arm64-gpu.tar.gz`, compiling ARM32 is in the same way. > 3. Before running the tools in the converter, benchmark or time_profile directory, you need to configure environment variables, and configure the path where the dynamic libraries of MindSpore Lite and Protobuf are located to the path where the system searches for dynamic libraries. Take the compiled under version 0.7.0-beta as an example: configure converter: `export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`; configure benchmark and timeprofiler: `export LD_LIBRARY_PATH= ./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`. - -## Windows Environment Compilation - -### Environment Requirements - -- The supported compilation environment is: Windows 10, 64-bit. - -- Compilation dependencies are: - - [CMake](https://cmake.org/download/) >= 3.14.1 - - [MinGW GCC](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/7.3.0/threads-posix/seh/x86_64-7.3.0-release-posix-seh-rt_v5-rev0.7z/download) = 7.3.0 - - [Python](https://www.python.org/) >= 3.7.5 - -> The compilation script will execute `git clone` to obtain the code of the third-party dependent libraries. Please make sure that the git network settings are correct and available in advance. - -### Compilation Options - -The compilation options of MindSpore Lite are as follows: - -| Parameter | Parameter Description | Mandatory or Not | -| -------- | ----- | ---- | -| **lite** | **Set this parameter to compile the Mindspore Lite project.** | **Yes** | -| [n] | Set the number of threads used during compilation, otherwise the default is set to 6 threads. | No | - -### Compilation Example - -First, use the git tool to download the source code from the MindSpore code repository. -```bash -git clone https://gitee.com/mindspore/mindspore.git -``` - -Then, use the cmd tool to compile MindSpore Lite in the root directory of the source code and execute the following commands. - -- Compile the Windows version with the default number of threads (6 threads). - ```bash - call build.bat lite - ``` -- Compile the Windows version with the specified number of threads 8. - ```bash - call build.bat lite 8 - ``` - -### Output Description - -After the compilation is complete, enter the `mindspore/output/` directory, unzip the output file `mindspore-lite-{version}-converter-win-cpu.zip`, which contains the conversion tool executable file. - -> version: version of the output, consistent with that of the MindSpore. diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index 38cd115fb1..de9a3020e2 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -11,7 +11,7 @@ - [Windows Environment Instructions](#windows-environment-instructions) - [Environment Preparation](#environment-preparation-1) - [Parameter Description](#parameter-description-1) - - [Example](#example-1) + - [Example](#example-1) @@ -119,9 +119,7 @@ The following describes the parameters in detail. To use the MindSpore Lite model conversion tool, the following environment preparations are required. -- Compile: The model conversion tool code is in the `mindspore/lite/tools/converter` directory of the MindSpore source code, refer to the [Environment Requirements](https://www.mindspore.cn/lite/tutorial/en/master/build.html#environment-requirements-1) and [Compilation Example](https://www.mindspore.cn/lite/tutorial/en/master/build.html#compilation-example-1) in the build document. - -- Run: Refer to [Output Description](https://www.mindspore.cn/lite/tutorial/en/master/build.html#output-description-1) in the deployment document to obtain the `converter` tool, and set the environment variable of MinGW(Add the bin directory of MinGW in the system variable Path). +- Get the toolkit: To obtain the 'Converter' tool, download the zip package of windows conversion tool and unzip it to the local directory. ### Parameter Description @@ -129,12 +127,7 @@ Reference description Linux environment model conversion tool [parameter descrip ### Example -First, use the cmd tool to enter the command to compile in the root directory of the source code, refer to `build.md`. -```bash -call build.bat lite -``` - -Then, set the log printing level to INFO. +Set the log printing level to INFO. ```bash set MSLOG=INFO ``` diff --git a/tutorials/lite/source_zh_cn/build.md b/tutorials/lite/source_zh_cn/build.md index a3e60383d3..0ef2ee0312 100644 --- a/tutorials/lite/source_zh_cn/build.md +++ b/tutorials/lite/source_zh_cn/build.md @@ -9,12 +9,7 @@ - [编译示例](#编译示例) - [编译输出](#编译输出) - [模型转换工具converter目录结构说明](#模型转换工具converter目录结构说明) - - [模型推理框架runtime及其他工具目录结构说明](#模型推理框架runtime及其他工具目录结构说明) - - [Windows环境编译](#windows环境编译) - - [环境要求](#环境要求-1) - - [编译选项](#编译选项-1) - - [编译示例](#编译示例-1) - - [编译输出](#编译输出-1) + - [模型推理框架runtime及其他工具目录结构说明](#模型推理框架runtime及其他工具目录结构说明) @@ -24,7 +19,7 @@ | 模块 | 支持平台 | 说明 | | --- | ---- | ---- | -| converter | Linux、Windows | 模型转换工具 | +| converter | Linux | 模型转换工具 | | runtime | Linux、Android | 模型推理框架 | | benchmark | Linux、Android | 基准测试工具 | | time_profiler | Linux、Android | 性能分析工具 | @@ -184,50 +179,3 @@ tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz > 1. `liboptimize.so`仅在runtime-arm64的输出包中存在,仅在ARMv8.2和支持fp16特性的CPU上使用。 > 2. 编译ARM64默认可获得arm64-cpu的推理框架输出件,若添加`-e gpu`则获得arm64-gpu的推理框架输出件,此时包名为`mindspore-lite-{version}-runtime-arm64-gpu.tar.gz`,编译ARM32同理。 > 3. 运行converter、benchmark或time_profile目录下的工具前,都需配置环境变量,将MindSpore Lite和Protobuf的动态库所在的路径配置到系统搜索动态库的路径中。以0.7.0-beta版本下编译为例:配置converter:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`;配置benchmark和timeprofiler:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`。 - -## Windows环境编译 - -### 环境要求 - -- 支持的编译环境为:Windows 10,64位。 - -- 编译依赖 - - [CMake](https://cmake.org/download/) >= 3.14.1 - - [MinGW GCC](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/7.3.0/threads-posix/seh/x86_64-7.3.0-release-posix-seh-rt_v5-rev0.7z/download) = 7.3.0 - - [Python](https://www.python.org/) >= 3.7.5 - -> 编译脚本中会执行`git clone`获取第三方依赖库的代码,请提前确保git的网络设置正确可用。 - -### 编译选项 - -MindSpore Lite的编译选项如下。 - -| 参数 | 参数说明 | 是否必选 | -| -------- | ----- | ---- | -| **lite** | **设置该参数,则对Mindspore Lite工程进行编译** | **是** | -| [n] | 设定编译时所用的线程数,否则默认设定为6线程 | 否 | - -### 编译示例 - -首先,使用git工具从MindSpore代码仓下载源码。 - -```bash -git clone https://gitee.com/mindspore/mindspore.git -``` - -然后,使用cmd工具在源码根目录下,执行如下命令即可编译MindSpore Lite。 - -- 以默认线程数(6线程)编译Windows版本。 - ```bash - call build.bat lite - ``` -- 以指定线程数8编译Windows版本。 - ```bash - call build.bat lite 8 - ``` - -### 编译输出 - -编译完成之后,进入`mindspore/output/`目录,解压后即可获取输出件`mindspore-lite-{version}-converter-win-cpu.zip`,其中含有转换工具可执行文件。 - -> version:输出件版本号,与所编译的分支代码对应的版本一致。 diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index 1b9ad944df..d63fefb842 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -120,9 +120,7 @@ MindSpore Lite模型转换工具提供了多种参数设置,用户可根据需 使用MindSpore Lite模型转换工具,需要进行如下环境准备工作。 -- 编译:模型转换工具代码在MindSpore源码的`mindspore/lite/tools/converter`目录中,参考部署文档中的[环境要求](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id5)和[编译示例](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id7)编译Windows版本。 - -- 运行:参考部署文档中的[编译输出](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id8),获得`converter`工具,,并配置MinGW环境变量(在系统变量Path里添加MinGW的bin目录)。 +- 获取工具包:下载Windows转换工具的Zip包并解压至本地目录,获得`converter`工具。 ### 参数说明 @@ -130,12 +128,7 @@ MindSpore Lite模型转换工具提供了多种参数设置,用户可根据需 ### 使用示例 -首先,使用cmd工具在源码根目录下,输入命令进行编译,可参考`build.md`。 -```bash -call build.bat lite -``` - -然后,设置日志打印级别为INFO。 +设置日志打印级别为INFO。 ```bash set MSLOG=INFO ``` -- Gitee From 34b33db19f28b8c80c135fdd2cddfaebb646a5b1 Mon Sep 17 00:00:00 2001 From: lvmingfu <630944715@qq.com> Date: Tue, 15 Sep 2020 11:01:04 +0800 Subject: [PATCH 018/100] fix notebook files in tutorials --- .../data_loading_enhancement.ipynb | 2 +- tutorials/notebook/model_security.ipynb | 10 +++++----- .../synchronization_training_and_evaluation.ipynb | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb index 125d1cc4f1..60aaa92e94 100644 --- a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb +++ b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb @@ -537,7 +537,7 @@ "metadata": {}, "outputs": [], "source": [ - "from mindspore.dataset.transforms.py_transforms import Compose" + "from mindspore.dataset.transforms.py_transforms import Compose\n", "import mindspore.dataset.vision.py_transforms as transforms" ] }, diff --git a/tutorials/notebook/model_security.ipynb b/tutorials/notebook/model_security.ipynb index 53f79dfe40..79c458f78c 100644 --- a/tutorials/notebook/model_security.ipynb +++ b/tutorials/notebook/model_security.ipynb @@ -214,16 +214,16 @@ " # apply map operations on images\n", " if not sparse:\n", " one_hot_enco = C.OneHot(10)\n", - " ds1 = ds1.map(operations=one_hot_enco,\n", input_columns=\"label\", + " ds1 = ds1.map(operations=one_hot_enco, input_columns=\"label\",\n", " num_parallel_workers=num_parallel_workers)\n", " type_cast_op = C.TypeCast(mstype.float32)\n", - " ds1 = ds1.map(operations=type_cast_op,\n", input_columns=\"label\", + " ds1 = ds1.map(operations=type_cast_op, input_columns=\"label\",\n", " num_parallel_workers=num_parallel_workers)\n", - " ds1 = ds1.map(operations=resize_op,\n", input_columns=\"image\", + " ds1 = ds1.map(operations=resize_op, input_columns=\"image\",\n", " num_parallel_workers=num_parallel_workers)\n", - " ds1 = ds1.map(operations=rescale_op,\n", input_columns=\"image\", + " ds1 = ds1.map(operations=rescale_op,input_columns=\"image\",\n", " num_parallel_workers=num_parallel_workers)\n", - " ds1 = ds1.map(operations=hwc2chw_op,\n", input_columns=\"image\", + " ds1 = ds1.map(operations=hwc2chw_op, input_columns=\"image\",\n", " num_parallel_workers=num_parallel_workers)\n", "\n", " # apply DatasetOps\n", diff --git a/tutorials/notebook/synchronization_training_and_evaluation.ipynb b/tutorials/notebook/synchronization_training_and_evaluation.ipynb index d3670b2382..8c22d397b8 100644 --- a/tutorials/notebook/synchronization_training_and_evaluation.ipynb +++ b/tutorials/notebook/synchronization_training_and_evaluation.ipynb @@ -113,8 +113,8 @@ "\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,rescale_op,rescale_nml_op,hwc2chw_op],\n", input_columns=\"image\", - " num_parallel_workers=num_parallel_workers)\n", + " mnist_ds = mnist_ds.map(operations=[resize_op,rescale_op,rescale_nml_op,hwc2chw_op],\n", + " input_columns=\"image\", num_parallel_workers=num_parallel_workers)\n", "\n", " # apply DatasetOps\n", " buffer_size = 10000\n", -- Gitee From 7e7ba2286003d520b75f22bf596dd328637479e7 Mon Sep 17 00:00:00 2001 From: SebastianHan Date: Tue, 15 Sep 2020 11:23:17 +0800 Subject: [PATCH 019/100] add 910 video --- .../source_zh_cn/quick_start/quick_video.md | 24 +++++++++++++++++++ .../ascend910_operator_development.md | 7 ++++++ 2 files changed, 31 insertions(+) create mode 100644 tutorials/training/source_zh_cn/quick_start/quick_video/ascend910_operator_development.md diff --git a/tutorials/training/source_zh_cn/quick_start/quick_video.md b/tutorials/training/source_zh_cn/quick_start/quick_video.md index 115ef7d67e..cd6af62eb4 100644 --- a/tutorials/training/source_zh_cn/quick_start/quick_video.md +++ b/tutorials/training/source_zh_cn/quick_start/quick_video.md @@ -337,6 +337,30 @@ +

    diff --git a/tutorials/training/source_zh_cn/quick_start/quick_video/ascend910_operator_development.md b/tutorials/training/source_zh_cn/quick_start/quick_video/ascend910_operator_development.md new file mode 100644 index 0000000000..8b72f11c5e --- /dev/null +++ b/tutorials/training/source_zh_cn/quick_start/quick_video/ascend910_operator_development.md @@ -0,0 +1,7 @@ +# Ascend 910算子开发 + +[comment]: <> (本文档中包含手把手系列视频,码云Gitee不支持展示,请于官方网站对应教程中查看) + + \ No newline at end of file -- Gitee From 9fa6369b432df03fca90e072b2df546b475cdc09 Mon Sep 17 00:00:00 2001 From: chenjianping Date: Tue, 15 Sep 2020 15:21:48 +0800 Subject: [PATCH 020/100] refresh resize interface --- tutorials/lite/source_en/use/runtime.md | 10 ++++++---- tutorials/lite/source_zh_cn/use/runtime.md | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tutorials/lite/source_en/use/runtime.md b/tutorials/lite/source_en/use/runtime.md index 748ef39812..eca4461031 100644 --- a/tutorials/lite/source_en/use/runtime.md +++ b/tutorials/lite/source_en/use/runtime.md @@ -187,10 +187,11 @@ virtual std::vector GetInputs() const = 0; /// \brief Resize inputs shape. /// -/// \param[in] inputs Define the new inputs shape. +/// \param[in] inputs Define Model inputs. +/// \param[in] dims Define All inputs new shape. /// /// \return STATUS as an error code of resize inputs, STATUS is defined in errorcode.h. -virtual int Resize(const std::vector &inputs) = 0; +virtual int Resize(const std::vector &inputs, const std::vector> &dims) = 0; ``` ### Example @@ -202,8 +203,9 @@ The following code demonstrates how to resize the input of MindSpore Lite: auto inputs = session->GetInputs(); std::vector resize_shape = {1, 128, 128, 3}; // Assume the model has only one input,resize input shape to [1, 128, 128, 3] -inputs[0]->set_shape(resize_shape); -session->Resize(inputs); +std::vector> new_shapes; +new_shapes.push_back(resize_shape); +session->Resize(inputs, new_shapes); ``` ### Compiling Graphs diff --git a/tutorials/lite/source_zh_cn/use/runtime.md b/tutorials/lite/source_zh_cn/use/runtime.md index 2ba5ab7bad..285c6719ce 100644 --- a/tutorials/lite/source_zh_cn/use/runtime.md +++ b/tutorials/lite/source_zh_cn/use/runtime.md @@ -186,10 +186,11 @@ virtual std::vector GetInputs() const = 0; /// \brief Resize inputs shape. /// -/// \param[in] inputs Define the new inputs shape. +/// \param[in] inputs Define Model inputs. +/// \param[in] dims Define All inputs new shape. /// /// \return STATUS as an error code of resize inputs, STATUS is defined in errorcode.h. -virtual int Resize(const std::vector &inputs) = 0; +virtual int Resize(const std::vector &inputs, const std::vector> &dims) = 0; ``` ### 使用示例 @@ -200,8 +201,9 @@ virtual int Resize(const std::vector &inputs) = 0; auto inputs = session->GetInputs(); std::vector resize_shape = {1, 128, 128, 3}; // Assume the model has only one input,resize input shape to [1, 128, 128, 3] -inputs[0]->set_shape(resize_shape); -session->Resize(inputs); +std::vector> new_shapes; +new_shapes.push_back(resize_shape); +session->Resize(inputs, new_shapes); ``` ### 图编译 -- Gitee From cf3bb2aa307ab0bc1e56c4dad6e7cc6f206c6b9b Mon Sep 17 00:00:00 2001 From: AGroupofProbiotocs Date: Tue, 15 Sep 2020 15:26:54 +0800 Subject: [PATCH 021/100] Update the MindSpore Lite docs, remove some attributes and methods not supported anymore --- docs/api_cpp/source_en/lite.md | 42 ++++--------------- docs/api_cpp/source_en/session.md | 12 +++--- docs/api_cpp/source_en/tensor.md | 60 +-------------------------- docs/api_cpp/source_zh_cn/lite.md | 46 ++++----------------- docs/api_cpp/source_zh_cn/session.md | 12 +++--- docs/api_cpp/source_zh_cn/tensor.md | 62 ++-------------------------- 6 files changed, 34 insertions(+), 200 deletions(-) diff --git a/docs/api_cpp/source_en/lite.md b/docs/api_cpp/source_en/lite.md index 93bc93edf0..19b6a2cc8e 100644 --- a/docs/api_cpp/source_en/lite.md +++ b/docs/api_cpp/source_en/lite.md @@ -1,10 +1,10 @@ # mindspore::lite -#include <[context.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/context.h)> +#include <[context.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/context.h)> -#include <[model.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/model.h)> +#include <[model.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/model.h)> -#include <[version.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/version.h)> +#include <[version.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/version.h)> ## Allocator @@ -23,23 +23,6 @@ Context() Constructor of MindSpore Lite Context using default value for parameters. -``` -Context(int thread_num, std::shared_ptr allocator, DeviceContext device_ctx) -``` -Constructor of MindSpore Lite Context using input value for parameters. - -- Parameters - - - `thread_num`: Define the work thread number during the runtime. - - - `allocator`: Define the allocator for malloc. - - - `device_ctx`: Define device information during the runtime. - -- Returns - - The instance of MindSpore Lite Context. - ``` ~Context() ``` @@ -53,9 +36,9 @@ float16_priority A **bool** value. Defaults to **false**. Prior enable float16 inference. ``` -device_ctx_{DT_CPU} +device_type ``` -A [**DeviceContext**](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#devicecontext) struct defined at the bottom of the text. Using to specify the device. +A [**DeviceType**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/lite.html#devicetype) **enum** type. Defaults to **DT_CPU**. Using to specify the device. ``` thread_num_ @@ -67,13 +50,13 @@ An **int** value. Defaults to **2**. Thread number config for thread pool. allocator ``` -A **pointer** pointing to [**Allocator**](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#allocator). +A **pointer** pointing to [**Allocator**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/lite.html#allocator). ``` cpu_bind_mode_ ``` -A [**CpuBindMode**](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#cpubindmode) enum variable. Defaults to **MID_CPU**. +A [**CpuBindMode**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/lite.html#cpubindmode) **enum** variable. Defaults to **MID_CPU**. ## PrimitiveC Primitive is defined as prototype of operator. @@ -121,6 +104,7 @@ Static method to create a Model pointer. An **enum** type. CpuBindMode defined for holding bind cpu strategy argument. **Attributes** + ``` MID_CPU = -1 ``` @@ -153,16 +137,6 @@ GPU device type. DT_NPU = 0 ``` NPU device type, not supported yet. -## DeviceContext - -A **struct**. DeviceContext defined for holding DeviceType. - -**Attributes** -``` -type -``` -A [**DeviceType**](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#devicetype) variable. The device type. - ## Version ``` diff --git a/docs/api_cpp/source_en/session.md b/docs/api_cpp/source_en/session.md index 3ecee43e21..1dc5700146 100644 --- a/docs/api_cpp/source_en/session.md +++ b/docs/api_cpp/source_en/session.md @@ -1,6 +1,6 @@ # mindspore::session -#include <[lite_session.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/lite_session.h)> +#include <[lite_session.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/lite_session.h)> ## LiteSession @@ -41,7 +41,7 @@ Compile MindSpore Lite model. - Returns - STATUS as an error code of compiling graph, STATUS is defined in [errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h). + STATUS as an error code of compiling graph, STATUS is defined in [errorcode.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/errorcode.h). ``` virtual std::vector GetInputs() const @@ -73,13 +73,13 @@ Run session with callback. - Parameters - - `before`: A [**KernelCallBack**](https://www.mindspore.cn/lite/docs/en/master/apicc/session.html#kernelcallback) function. Define a callback function to be called before running each node. + - `before`: A [**KernelCallBack**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/session.html#kernelcallback) function. Define a callback function to be called before running each node. - - `after`: A [**KernelCallBack**](https://www.mindspore.cn/lite/docs/en/master/apicc/session.html#kernelcallback) function. Define a callback function to be called after running each node. + - `after`: A [**KernelCallBack**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/session.html#kernelcallback) function. Define a callback function to be called after running each node. - Returns - STATUS as an error code of running graph, STATUS is defined in [errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h). + STATUS as an error code of running graph, STATUS is defined in [errorcode.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/errorcode.h). ``` virtual std::vector GetOutputsByNodeName(const std::string &node_name) const @@ -151,7 +151,7 @@ Resize inputs shape. - Returns - STATUS as an error code of resize inputs, STATUS is defined in [errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h). + STATUS as an error code of resize inputs, STATUS is defined in [errorcode.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/errorcode.h). **Static Public Member Functions** diff --git a/docs/api_cpp/source_en/tensor.md b/docs/api_cpp/source_en/tensor.md index 014929ba12..f74d7a33ec 100644 --- a/docs/api_cpp/source_en/tensor.md +++ b/docs/api_cpp/source_en/tensor.md @@ -1,6 +1,6 @@ # mindspore::tensor -#include <[ms_tensor.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/ms_tensor.h)> +#include <[ms_tensor.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/ms_tensor.h)> ## MSTensor @@ -30,25 +30,12 @@ virtual TypeId data_type() const ``` Get data type of the MindSpore Lite MSTensor. -> Note: TypeId is defined in [mindspore/mindspore/core/ir/dtype/type_id.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/core/ir/dtype/type_id.h). Only number types in TypeId enum are suitable for MSTensor. +> Note: TypeId is defined in [mindspore/mindspore/core/ir/dtype/type_id.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/core/ir/dtype/type_id.h). Only number types in TypeId enum are suitable for MSTensor. - Returns MindSpore Lite TypeId of the MindSpore Lite MSTensor. -``` -virtual TypeId set_data_type(TypeId data_type) -``` -Set data type for the MindSpore Lite MSTensor. - -- Parameters - - - `data_type`: Define MindSpore Lite TypeId to be set in the MindSpore Lite MSTensor. - -- Returns - - MindSpore Lite TypeId of the MindSpore Lite MSTensor after set. - ``` virtual std::vector shape() const ``` @@ -59,19 +46,6 @@ Get shape of the MindSpore Lite MSTensor. A vector of int as the shape of the MindSpore Lite MSTensor. -``` -virtual size_t set_shape(const std::vector &shape) -``` -Set shape for the MindSpore Lite MSTensor. - -- Parameters - - - `shape`: Define a vector of int as shape to be set into the MindSpore Lite MSTensor. - -- Returns - - Size of shape of the MindSpore Lite MSTensor after set. - ``` virtual int DimensionSize(size_t index) const ``` @@ -96,16 +70,6 @@ Get number of element in MSTensor. Number of element in MSTensor. -``` -virtual std::size_t hash() const -``` - -Get hash of the MindSpore Lite MSTensor. - -- Returns - - Hash of the MindSpore Lite MSTensor. - ``` virtual size_t Size() const ``` @@ -129,23 +93,3 @@ Get the pointer of data in MSTensor. - Returns The pointer points to data in MSTensor. - -**Static Public Member Functions** - -``` -static MSTensor *CreateTensor(TypeId data_type, const std::vector &shape) -``` - -Static method to create a MSTensor pointer. - -> Note: TypeId is defined in [mindspore/mindspore/core/ir/dtype/type_id.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/core/ir/dtype/type_id.h). Only number types in TypeId enum are suitable for MSTensor. - -- Parameters - - - `data_type`: Define the data type of tensor to be created. - - - `shape`: Define the shape of tensor to be created. - -- Returns - - The pointer of MSTensor. \ No newline at end of file diff --git a/docs/api_cpp/source_zh_cn/lite.md b/docs/api_cpp/source_zh_cn/lite.md index 8c321676b4..13931a5cc0 100644 --- a/docs/api_cpp/source_zh_cn/lite.md +++ b/docs/api_cpp/source_zh_cn/lite.md @@ -1,10 +1,10 @@ # mindspore::lite -#include <[context.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/context.h)> +#include <[context.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/context.h)> -#include <[model.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/model.h)> +#include <[model.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/model.h)> -#include <[version.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/version.h)> +#include <[version.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/version.h)> ## Allocator @@ -23,24 +23,6 @@ Context() 用默认参数构造MindSpore Lite Context 对象。 -``` -Context(int thread_num, std::shared_ptr allocator, DeviceContext device_ctx) -``` - -根据输入参数构造MindSpore Lite Context 对象。 - -- 参数 - - - `thread_num`: 定义了执行线程数。 - - - `allocator`: 定义了内存分配器。 - - - `device_ctx`: 定义了设备信息。 - -- 返回值 - - MindSpore Lite Context 指针。 - ``` ~Context() ``` @@ -53,13 +35,13 @@ MindSpore Lite Context 的析构函数。 float16_priority ``` -**bool** 值,默认为**false**,用于使能float16 推理。 +**bool**值,默认为**false**,用于使能float16 推理。 ``` -device_ctx_{DT_CPU} +device_type ``` -[**DeviceContext**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#devicecontext)结构体。用于设置设备信息。 +[**DeviceType**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/lite.html#devicetype)枚举类型。默认为**DT_CPU**,用于设置设备信息。 ``` thread_num_ @@ -71,13 +53,13 @@ thread_num_ allocator ``` -指针类型,指向内存分配器[**Allocator**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#allocator)的指针。 +指针类型,指向内存分配器[**Allocator**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/lite.html#allocator)的指针。 ``` cpu_bind_mode_ ``` -[**CpuBindMode**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#cpubindmode)枚举类型,默认为**MID_CPU**。 +[**CpuBindMode**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/lite.html#cpubindmode)枚举类型,默认为**MID_CPU**。 ## PrimitiveC @@ -173,18 +155,6 @@ DT_NPU = 0 设备为NPU,暂不支持。 -## DeviceContext - -定义设备类型的结构体。 - -**属性** - -``` -type -``` - -[**DeviceType**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#devicetype) 变量。设备类型。 - ## Version ``` diff --git a/docs/api_cpp/source_zh_cn/session.md b/docs/api_cpp/source_zh_cn/session.md index 37a7bcb8d7..31f231714f 100644 --- a/docs/api_cpp/source_zh_cn/session.md +++ b/docs/api_cpp/source_zh_cn/session.md @@ -1,6 +1,6 @@ # mindspore::session -#include <[lite_session.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/lite_session.h)> +#include <[lite_session.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/lite_session.h)> ## LiteSession @@ -41,7 +41,7 @@ virtual int CompileGraph(lite::Model *model) - 返回值 - STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h)中定义。 + STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/errorcode.h)中定义。 ``` virtual std::vector GetInputs() const @@ -73,13 +73,13 @@ virtual int RunGraph(const KernelCallBack &before = nullptr, const KernelCallBac - 参数 - - `before`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之前调用的回调函数。 + - `before`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之前调用的回调函数。 - - `after`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之后调用的回调函数。 + - `after`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之后调用的回调函数。 - 返回值 - STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h)中定义。 + STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/errorcode.h)中定义。 ``` virtual std::vector GetOutputsByNodeName(const std::string &node_name) const @@ -137,7 +137,7 @@ virtual int Resize(const std::vector &inputs, const std::ve - 返回值 - STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/errorcode.h)中定义。 + STATUS ,即编译图的错误码。STATUS在[errorcode.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/errorcode.h)中定义。 **静态公有成员函数** diff --git a/docs/api_cpp/source_zh_cn/tensor.md b/docs/api_cpp/source_zh_cn/tensor.md index e9eae1f0fd..269d54d742 100644 --- a/docs/api_cpp/source_zh_cn/tensor.md +++ b/docs/api_cpp/source_zh_cn/tensor.md @@ -1,6 +1,6 @@ # mindspore::tensor -#include <[ms_tensor.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/lite/include/ms_tensor.h)> +#include <[ms_tensor.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/lite/include/ms_tensor.h)> ## MSTensor @@ -15,7 +15,7 @@ MindSpore Lite MSTensor的构造函数。 - 返回值 - MindSpore Lite MSTensor 的实例。 + MindSpore Lite MSTensor的实例。 ``` virtual ~MSTensor() @@ -29,25 +29,12 @@ virtual TypeId data_type() const ``` 获取MindSpore Lite MSTensor的数据类型。 -> 注意:TypeId在[mindspore/mindspore/core/ir/dtype/type_id\.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/core/ir/dtype/type_id.h)中定义。只有TypeId枚举中的数字类型可用于MSTensor。 +> 注意:TypeId在[mindspore/mindspore/core/ir/dtype/type_id\.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/core/ir/dtype/type_id.h)中定义。只有TypeId枚举中的数字类型可用于MSTensor。 - 返回值 MindSpore Lite MSTensor类的MindSpore Lite TypeId。 -``` -virtual TypeId set_data_type(TypeId data_type) -``` -设置MindSpore Lite MSTensor的数据类型。 - -- 参数 - - - `data_type`: 定义了MindSpore Lite MSTensor所需设置的MindSpore Lite TypeId。 - -- 返回值 - - 设置后的MindSpore Lite MSTensor的MindSpore Lite TypeI。 - ``` virtual std::vector shape() const ``` @@ -57,23 +44,10 @@ virtual std::vector shape() const 一个包含MindSpore Lite MSTensor形状数值的整型向量。 -``` -virtual size_t set_shape(const std::vector &shape) -``` -设置MindSpore Lite MSTensor的形状. - -- 参数 - - - `shape`: 定义了一个整型向量,包含了所需设置的MindSpore Lite MSTensor形状数值。 - -- 返回值 - - 设置形状后的MindSpore Lite MSTensor的大小。 - ``` virtual int DimensionSize(size_t index) const ``` -Get size of the dimension of the MindSpore Lite MSTensor index by the parameter index. +通过参数索引获取MindSpore Lite MSTensor的维度的大小。 - 参数 @@ -92,15 +66,6 @@ virtual int ElementsNum() const MSTensor中的元素个数 -``` -virtual std::size_t hash() const -``` -获取MindSpore Lite MSTensor的哈希码。 - -- 返回值 - - MindSpore Lite MSTensor的哈希码。 - ``` virtual size_t Size() const ``` @@ -121,22 +86,3 @@ virtual void *MutableData() const - 返回值 指向MSTensor中的数据的指针。 - -**静态公有成员函数** - -``` -static MSTensor *CreateTensor(TypeId data_type, const std::vector &shape) -``` -创建MSTensor指针的静态方法。 - -> 注意:TypeId在[mindspore/mindspore/core/ir/dtype/type_id\.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/core/ir/dtype/type_id.h)中定义。只有TypeId枚举中的数字类型可用于MSTensor。 - -- 参数 - - - `data_type`: 定义了所要创建的张量的数据类型。 - - - `shape`: 定义了所要创建的张量的形状。 - -- 返回值 - - 指向MSTensor的指针。 \ No newline at end of file -- Gitee From 5226e2179d513a3b496790b686283564b9bf6700 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Tue, 15 Sep 2020 15:38:47 +0800 Subject: [PATCH 022/100] Add markdown and modify markdown format --- docs/note/source_en/architecture_lite.md | 2 + docs/note/source_en/design/mindspore/ir.md | 2 +- docs/note/source_en/glossary_lite.md | 2 + docs/note/source_en/operator_list_lite.md | 2 + docs/note/source_zh_cn/architecture_lite.md | 3 + docs/note/source_zh_cn/design/mindspore/ir.md | 2 +- docs/note/source_zh_cn/glossary_lite.md | 2 + docs/note/source_zh_cn/operator_list_lite.md | 2 + .../source_en/advanced_use/hub_tutorial.md | 2 +- .../images/cifar10_c_transforms.png | Bin 0 -> 46693 bytes .../source_en/advanced_use/images/compose.png | Bin 0 -> 18941 bytes .../data_enhancement_performance_scheme.png | Bin 0 -> 54529 bytes .../data_loading_performance_scheme.png | Bin 0 -> 48509 bytes .../advanced_use/images/operator_fusion.png | Bin 0 -> 13533 bytes .../advanced_use/images/pipeline.png | Bin 0 -> 5954 bytes .../images/shuffle_performance_scheme.png | Bin 0 -> 22805 bytes ...ize_the_performance_of_data_preparation.md | 387 ++++++++++++++++++ ...synchronization_training_and_evaluation.md | 2 +- tutorials/training/source_en/index.rst | 1 + .../advanced_use/auto_augmentation.md | 2 +- .../source_zh_cn/advanced_use/cache.md | 2 +- .../computer_vision_application.md | 10 +- .../data_processing_acceleration.md | 2 +- .../advanced_use/dataset_conversion.md | 2 +- .../advanced_use/deep_probability_program.md | 14 +- .../source_zh_cn/advanced_use/hub_tutorial.md | 2 +- .../advanced_use/membership_inference.md | 2 + .../mobilenetv2_incremental_learning.md | 3 +- .../model_scripts_transformation.md | 2 +- ...ize_the_performance_of_data_preparation.md | 26 +- .../source_zh_cn/use/image_loading.md | 2 +- .../training/source_zh_cn/use/text_loading.md | 2 +- 32 files changed, 442 insertions(+), 38 deletions(-) create mode 100644 tutorials/training/source_en/advanced_use/images/cifar10_c_transforms.png create mode 100644 tutorials/training/source_en/advanced_use/images/compose.png create mode 100644 tutorials/training/source_en/advanced_use/images/data_enhancement_performance_scheme.png create mode 100644 tutorials/training/source_en/advanced_use/images/data_loading_performance_scheme.png create mode 100644 tutorials/training/source_en/advanced_use/images/operator_fusion.png create mode 100644 tutorials/training/source_en/advanced_use/images/pipeline.png create mode 100644 tutorials/training/source_en/advanced_use/images/shuffle_performance_scheme.png create mode 100644 tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md diff --git a/docs/note/source_en/architecture_lite.md b/docs/note/source_en/architecture_lite.md index 6458577572..c0bd5c1234 100644 --- a/docs/note/source_en/architecture_lite.md +++ b/docs/note/source_en/architecture_lite.md @@ -1,5 +1,7 @@ # Overall Architecture +`Linux` `Windows` `On Device` `Inference Application` `Intermediate` `Expert` `Contributor` + The overall architecture of MindSpore Lite is as follows: diff --git a/docs/note/source_en/design/mindspore/ir.md b/docs/note/source_en/design/mindspore/ir.md index 4837ba94ba..9874351845 100644 --- a/docs/note/source_en/design/mindspore/ir.md +++ b/docs/note/source_en/design/mindspore/ir.md @@ -1,7 +1,7 @@ # MindSpore IR (MindIR) -`Framework Development` `Intermediate` `Expert` `Contributor` +`Linux` `Windows` `Framework Development` `Intermediate` `Expert` `Contributor` diff --git a/docs/note/source_en/glossary_lite.md b/docs/note/source_en/glossary_lite.md index 8b59622929..fedf2cf2c9 100644 --- a/docs/note/source_en/glossary_lite.md +++ b/docs/note/source_en/glossary_lite.md @@ -1,5 +1,7 @@ # Glossary +`Linux` `Windows` `On Device` `Whole Process` `Beginner` `Intermediate` `Expert` + | Acronym and Abbreviation | Description | diff --git a/docs/note/source_en/operator_list_lite.md b/docs/note/source_en/operator_list_lite.md index 4f347a146e..63bfd34990 100644 --- a/docs/note/source_en/operator_list_lite.md +++ b/docs/note/source_en/operator_list_lite.md @@ -1,5 +1,7 @@ # Operator List +`Linux` `On Device` `Inference Application` `Beginner` `Intermediate` `Expert` + > √ The checked items are the operators supported by MindSpore Lite。 diff --git a/docs/note/source_zh_cn/architecture_lite.md b/docs/note/source_zh_cn/architecture_lite.md index ce86fa9829..86697a237b 100644 --- a/docs/note/source_zh_cn/architecture_lite.md +++ b/docs/note/source_zh_cn/architecture_lite.md @@ -1,5 +1,8 @@ # 总体架构 +`Linux` `Windows` `端侧` `推理应用` `中级` `高级` `贡献者` + + MindSpore Lite框架的总体架构如下所示: diff --git a/docs/note/source_zh_cn/design/mindspore/ir.md b/docs/note/source_zh_cn/design/mindspore/ir.md index 77bc45014d..362544c7f1 100644 --- a/docs/note/source_zh_cn/design/mindspore/ir.md +++ b/docs/note/source_zh_cn/design/mindspore/ir.md @@ -1,6 +1,6 @@ # MindSpore IR(MindIR) -`Linux` `框架开发` `中级` `高级` `贡献者` +`Linux` `Windows` `框架开发` `中级` `高级` `贡献者` diff --git a/docs/note/source_zh_cn/glossary_lite.md b/docs/note/source_zh_cn/glossary_lite.md index b9cf41a4c6..947bea9a25 100644 --- a/docs/note/source_zh_cn/glossary_lite.md +++ b/docs/note/source_zh_cn/glossary_lite.md @@ -1,5 +1,7 @@ # 术语 +`Linux` `Windows` `端侧` `全流程` `初级` `中级` `高级` + | 术语/缩略语 | 说明 | diff --git a/docs/note/source_zh_cn/operator_list_lite.md b/docs/note/source_zh_cn/operator_list_lite.md index 333e209f4e..9360f8f626 100644 --- a/docs/note/source_zh_cn/operator_list_lite.md +++ b/docs/note/source_zh_cn/operator_list_lite.md @@ -1,5 +1,7 @@ # 算子支持 +`Linux` `Ascend` `端侧` `推理应用` `初级` `中级` `高级` + > √勾选的项为MindSpore Lite所支持的算子。 diff --git a/tutorials/training/source_en/advanced_use/hub_tutorial.md b/tutorials/training/source_en/advanced_use/hub_tutorial.md index a441dd7fdc..26f6e5398f 100644 --- a/tutorials/training/source_en/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_en/advanced_use/hub_tutorial.md @@ -1,6 +1,6 @@ ## Submitting, Loading and Fine-tuning Models using MindSpore Hub -`Ascend` `GPU` `MindSpore Hub` `Model Submission` `Model Loading` `Model Fine-tuning` `Beginner` `Intermediate` `Expert` +`Linux` `Ascend` `GPU` `MindSpore Hub` `Model Submission` `Model Loading` `Model Fine-tuning` `Beginner` `Intermediate` `Expert` diff --git a/tutorials/training/source_en/advanced_use/images/cifar10_c_transforms.png b/tutorials/training/source_en/advanced_use/images/cifar10_c_transforms.png new file mode 100644 index 0000000000000000000000000000000000000000..10dc267dc650764566f6d20b7f090e20c12f8e11 GIT binary patch literal 46693 zcmYJ41ymJZ)ad61aES|-M)CrRAl)fkkd~6}?k)uc;a*y$6{Jf_knT$bD@uk3bk}Qq>C>7xuhWtgT7T0`%zP6P9VyUIRjgj%s<<$O& z{-)idUt$>_8A+`yozFu44f_#X=X0lqONm_7@}{YmFV9^W?@UwH`JCBL)vV$3k=87q z+eN2g!TVmpGTx1>q9>AJ>Z@888}PMqAMpRicW5Lr9fgN%0UsjNk^cg`<=?BMumHTQ zE@8h5C^)OD@KBZh|5f3}g3A6rAdSCQk`0uX4ZIk<=>6|rJch^pee{o!Of=~G2OZ1! zE1STL0nl!ubAO|7JNCad9tAv5SrG%+guRUavGPCWWB0=Qn z`{=SD!VWh>29o$?_=*pt191rt>TWLV;~m(7#x*2Ns59X0wR&|WnT5Fy9u@s&kVPV9 zznBeX?}#wOF;aQZLYN>{qU~ay)W7k6`wWW$62F2NVsyb`lSiHEU zj+2+m+5e0iKeY&=@+Va)v@;7kx zgUrL)(cPP+W}pAcc2f!;2b|5#9M+c4UDmlk#oWh4H*cR@H)%(k)+Rj1Os=0dacNai z*F8eDGWtWNQ_izfk!X z`vDpHUgYH;+57AEdxk4BwYOcLtO##tfdu;-N8rBi(;*!ZW$7JpdXUHX;kRe+Z{(gD zv~Pba(fiTL)S@hH0z$V3v|Tg0Pfe)5H0{a*WOwccJxl|0r2<|aywJzG3|aO+$$0P9 zD*J^#P)&_{oAT>c?AG^dKGe!6_~Iqg(Gt@UbOi^v`NB={Z4j$U^OS;qQs=H$YS8lr z?BL5tC)aGj5R5-n7=Gn!;e;hv!P>hFC2sBKS4u)LvZinyP9 zAZ|R-uYfOfOe(qD`h>B;0U-A#7{d~+##D3U4LxwrhK6@AXieS!#qR~9#sjsvYO>!M zR9aFx6@2offK6t-$7Xv%MBV#j*u-a0TLmOb=JiCDWkY+&N(PzShiP<4?gKr5c&QDE zGJ45y-w&{)7hYHIM_bsC6eQSyl>?&^&&(2?N0$?3bU&)Vb)k=PlpT$0^fzm2CK^Xl zrbu3k)_7@nRQPR3LFKrc>*vE;zv}H?lT8~R^NyGe_Nw`g7W^oIR!Dh2>f;VOdy|NL z_rkRtZWgW%6kn|Yfj6hz#;F>aS|!eZH$H2X)CKpc7|(pc26V_;UMT3`$ddh3<6IFJh79X zSfeZqI2U!h)lt`GhQo-1gO}>UftHm5T}NrPq<>yi^kyWCfl` z>F`+ep!FHL{wZ+R!Z3D?N%?AS`ICrNUx4+LWRjQaJ64$M%(rrx_aziSg>4Y)#iw?o znQ4zjI_N%jfY&dP{b<~WR06|NJT1GjU)jmMzXrru^7q8h-X6_4>gG?SO~sfi*OWyPO<*gfx>3lfzDscd6((Pys%}7twOAoy0+F4p~5y04h*zxnmsUlg-bC#s` zeC=NX0}SZ;)Rq*gp&Ev6rT!YOB$YvqiVk%DYL-}$d~whW^-J74N5Y{cRrFfXnuj_4 zt3Uy*l^8!~HlD~eFu?xOR*Y`0Tz6>CajS#{#aef$f2bFyk&zOy#`9q_87HPW1@^cz z!d#ZVH~TLMWZR@;`)l@5;jN+hs67A{#3EL<`V_-K;$}4cQDBhc8H`^czmrcfOmHvo z9gzP$ab)LQ=ar49Tim3gG}^H8Yk8e$_Wtg#*PjCoCd{3rv-ksY-8xw}uCnXw2Jj5p z;*kOwsts<)c9t)QULMjFs$dUVs&j}IHtzLTsltI{SVVRT$U(jNlIO;#OTiKtkWm+^ z5si^|a{D1Evoo{oJaa;pAqB<~#$l4;M|X6r1h$LA;toGkO(QTvpqEGsK8w+uW*Hkb9?Mvqc+iV`8C|*)B znH4!QKI3IMgFZLrj*%2&0q~SHf`dbktR+>YhRxwTTBYjDPI|Md0Y=n^lnBS1-H_B4 z-G}{B)}3Ws%|En7nZpfqP2Gkdsj(-7igzb#5GfVnU; zGXE7O=VS4<7gFpn=q!?_4-N`#4e*}NGOsuxqfMC>!$$UdBaVr!g)9lEB3rCk&=xTx z*&i&rWPRvk&)8SZ?46V7BbDadEbbY6ChpGtqoVxXO!9dEMIIEUYgXt_x-A|7Rvl;x zG&TH&pKx+prhL1ju$P{N7Aap#dU~Xp@5x+w{JM65?qSoDCp=@$dE7i0`SbYp>SsKv z#N6VbEg|x+G7JY&!6^fMdSkS{ks0x;_&I8zRv;?iCRI2C6E?_xoh>-`u;2P{E`{Pte8S#4X$E2yK=MIOc z(W41MwMtd6k2f}{u&B%3b)WupeyCN-tYK5Xn4fI2fhkt8k;KtCWt#EqX~uU!Nuzw`sTN zDjZemcb7Mmo;Ug9;w?44|I}?VlBbJ{2Z6Sg3Iz11;hO7?M`YXNdk>z+fclS*`D51R zdcXBiU5bYQ1KcRJE*F9*7k*Ml8aPzMERN7SE)|`K>@bhy36sZF`uJ$d%LeMi{5=Vb z0BVjELXrfCrnD?$#wDZ(7nhtwUK|*T?+W(9!N2?ANp` zQGJ-}d6vqL%rsbJM%VQ}Nvr+@aC1`=t8Qht}D zVRY1{s$~cq93sZtQ=dd*r4T})1QF~6Zt5{p))ftG3IqlEBlhNpssFyQY;-q6Oh{iP zg9D%Q!hZ0|vfvj7Bzk&w?X?8}0#{sbOzfJ3cw}~o89U(z7*>B2l?#Xlfb(WxS_DzR+nR5aSJfvK+FZjP0E;!vB8Db+pP5lz!j`@B zKG5h(#m?q$62q?@yFFus)x4mmLv2#~KD1WdZwMlpo~|DUuFM|HW@S~n&}6=8@|^u{ z$FkCw*T8u3gVlIe>jDn^G7kBMMs?75!`|F{M>vbx)S}VK31JLk=f z(LrVY@Q;o_QGUCd4^IU8?XiMI7XNEG^khJ`tL3F$d3V61JO-5`G6~<)R2(7J(j3ko05|{GF4nCD!iorvk z#d~1st8Cdzb+d^CP#uPg64IXAEkOFYT?mcp0|HG1n1g#G0UXUoFk( z9ERX#Q(JlC_O_DTU|jGIS~K`*`n~FTvW5$nriD(W&n%#KB*xQ$UWLZ^F-o)wFU9N^G3$xdd_{E zKh5RP{&Z{^5b%cNsjH;yl+i&Lzv3~DW2%E`^Uus@NAK~pU!;Rp*lh>_laGTCZZ2A7rJ^kYlbAlhVrP-2bn;i*>E z!$~@SJAVe&cm3!NbB!5AjNK|XLSNoYd7U{)V!_9Xd4Z+QbDX}0+L{6ii{u57+-yQa z#Wy6XVm{o*ujIuQoRzt@lLZW9nVe zfrpw>ihr8@(2>Gx3cc|rYIDAggM_D_G7x|7&{1$cmO9>2iF*5fCG?&_>9}3afl1&H z<-@0IiEbh<&v~YB;yWFcEp|`@->B-aL;I18Tu4REuZDPQ-XlT%rio=i{r#sOI0r_X zL%VP0>Nt-zCj&K>a-+3ywK`HkX$oc%|NbtK6dS?;2w72_qq{XKceayOO;LgNv;o-3KS-4(h#86aW2pCw{2@X{%Rt~pY2#M7O&ra&cJ;^IFm;egl2uqLUgUie={769w zHCZ@4oYjX;h_N_YNb!@-Et4)WZeCBg>(W(4)j#NOKck4eIp==Jb+ud(7;|rs*MMvYBKhd-xOkR14v6 z#CHSSFI}fes}nQh`yVR`zlMC$eNY-FN%a#313nCEf&p0n97zo~p|QYU{=W~&T#EZE z1t>aSD_g2ULI!eXU1D7QpnoELE+c{Cio}R2N}$5y?>>LBSKe}V=xZ!+UU;o@*)z)@ z`alR^uH~VQT1mBAa4E=qO=~6V@cfOI5W(Bt#%FcKS!7CwjBV=yhcJ*1lP3CTnNrme%Afxun!1&Zs6ofB)m%N@yPWsEf@)S%G+^Zn?rm z+_jSFw9aB**hs+EdDiD!o!@2Tq`*0co~zrP8~4|V|6Ke81Ix-bRWvx|cwmam0? zdoJ_=_>dBG^SSuy(>KlIf7It+CIfmozgX%tHB>;@1dJ8|iimm*4zsAU6*NaPy@Eg5 z`&BfJiM|lzDe^5^*zdGuKzF8(F(#7=h54qco6`q(&mcvZHk%lmJ{jsUxLZO^Q1bUn zS>>T5Bm*dK{8W$|OD9#1qYz}7`0H16cGJp31B`_>lb9a^8Hv67CyQ4$#XXeM-18 z+u*ZCaHy&EiYGP%!Va>(?Sy#RrvMr>{Mn>lu2gFs=`oHP#RKC5buEvevDEW*<7 zm;DXFxMMA#2UOjCSk8BC;x{BKc`Cuy;Ds38T)mt-N1HHQ;n(x+k^CAsjZz z-yb2Y3qD(TaR!eh#n*3;0y9>QzUCZnyiXaL`7vDJ$UzV+( zor5murS4walZ_oNnw%RH=#}<-CVT!_Wg|t4 zAns3(;soK?2~oVWs9ZdUTWoC))358v>oD;f(BCy$uudAcl%?D+4{ww*;?Vn%V7b*X zyhh#~4&GU=bCBc@k98i(%%_f!wDuZ(a|u-;P&%G_MTJP#swltxgUqhU9Sr+i&*}p5 zxeBiOZBku_k+218&(Liv&WrGL0y3T6ZM`Q8GGBI}SxpM~Z4Y6zBAyLy6>OdqO&J#f z?Q2`Fs^@}_JNC{#`oUO4!d0{R%w9MI^0S3fS=D}Vf7m`b%@F1``S`Ft)VySS^nL&G z?s<6~@>&OwBmnQou`U+X+LDsU{rVY#kMyOozI16MSZHhVYdUYNdE`OJwvsHyTY%!_ zwQ%xRF)JV|rrI7%4twT6z&cFgT$7nBou;)M-p;qc$VojTXvWIhnM-Spe-3sCalHtT zZLd=orofs^vaOaEcR6LCQlw#qA@p~we{8@b^2tMz92K^@5OsNura>U+qeDNbAiYED z%$J^{9?9l2+RKo0{pHS-E)Q_1mzy*ov*GKQRE}{Q`b0Hr34iM%-m0fuIBzsf+V=Ob zk}gEgq4D=a8GquRU8Li=f0dKAGuL*m4Cl^e>`on;W;6@Ql_u^gd$ftUuJ^luBX*e* zYNcLcHeIR@hXscBFCZz>F9X6pEAxS}LSIFZd)HATs)s7@H6o|NS4Kmb5&M5aE_5C1 z>HI}XGKUPvHy7G0c7?AOgs#h+1&A00{2v-}2GVXM#-375U2nWJS=bAPqmSqdsR5O) zVQPkV@#mAODvwAp1}IS1Dq(BL-t8BW4GYp_!sE35+ZZca^rDO3WjCdxC`V8*v-E2< zBTG81oJh{u-8C;zgi;XqD>*K#heh(qV!=k0*gQcZ0iThFLD<8T@dwaD{J{Guqd2xb zxr@QfpQlNPIzeU92#9P7RyLG`t3j98@VQ%|emU|3oAfu^_NkezYke9!5t}Rj{#k)z zV(&)k&#DXXoVUH=ORKX5N?us+oqWv9Ay(C4Lg~2*?XTfg5AZddagnP=vqBKe?6bdh z2eW6xO%<-#;Dt6TXL0KV6w$dMUTBqijff;oHg6HeM>N@BSj zw;K--yUBxXI?;X$gF=zRSg(wzI$xi1QhV`%V1*eYa`jl#CshR(-9!3XuWPuMufV*sld*-Hlf7#!C=7gQ? zSJXj(`v&N%lM{JXZUh|=OhMrsI>w4S#`g7GlX+qVIj+dgY+(foNNR7qqs)I7y5Mcc z!Xt206eTw8+rx2UXzcY6P_+MJTOHdX8Pe&FjI`(wc3!Z5Gqd2*H|vwtQZpmmgYFx! zk&Thq5!AItuZ0B*{GJK~_5K8vLgDaa1f&EqzdVG>buq(^u@pB;eojv0Zz z>lb#6_2rTzsVqGIf+tQa=u!@5I`t7FE#gnC(Je_>4bke^pdhFW=M8SUqWLb8yx-X& z_bq9)*FDD@M7QAD)$Y3Ay%+Fs|->Ztd@jkk_Vz;_*_f^~4Wt&p~CtkiwL+oBC@;(n#FaQ2X#mWke zInO4B*#P5|rb>dCjNnvgj$}$^Cr!r3*N`)seT0=dC_GTG00KE9ItLm|@yfU8F7}85 zubR0tb%6WdCG8`tHHzrIw^a9><_zXT(^l2lKRsOL-v+#A&xA&*oi2(XUUnmAX8hmc zB7M=*jTFq0ju~aQk5`Hx0K z#F2N-=^xR!F_nXTrwz2)GOuGEuKC_d43#biP8xPXe5#IhiCTmxnHRMuE%*}R_A;VX ze#fs5kNjSD^dYIw5;eFxM%k4H#Z2hST1&*dN3- zhb1d%6QbB~ZKvZeZhxh&ju2DbiLpptNW#{rj`9!pJ`aPldb#?ep z>`a2*d}-C9F~o@(_M2SEwk2FFy=g6!Gg;W(Cso`l7eEa*OW~+uDw>#Z*I(Cv^Or9QJ2@~tUs`!;)3DrW z$uvyi>Ds6BN6^Upe)SFX(AfML<=TDUEAyePySUO3qKS(pHtqT$6KlVwSc{@7^9sl_ zoB~(IWJnY|25<1roFnQ ztK)yu*!l(1vn7=Ig4@sa`s>qiBc#dU0$wXKUL&Q@@SBq=a4L?WKW~fdXf&@#_f~-` zdwZ?ElmsmcD%}nDmSnMlA9I?KeZl|bqPD!#vP#;>Y8K5-u)ys(^44YlZog;pX?vpr zaPZ^1fuZ3rN&nZyG$m(`<;SXO?MeJ)BZ(DF z`bZ~%;?)f1@iPL4U1-cFeBTR+H`g>TX{UWT*ao550LFWx5t~}vnqcCv{_*bhKNZor zs;d)%5AbMdVO_Md=S#mVC`io5lHYE+X_&%}Nw)v*T7Yk#Y7MIfo@sm(NF;euaadmG zAR_(%AnX5GQ{`bc5jkU*S3Fnl*L+4s0lpVlBBKM2^n+6P*tC>D<|SvsIvx`|G@R!w zi|4fOiCekn@Vh(GIi@kg_=SmmhPo+i{&%fZN+rG^6%Q)qI*So0|m8z znh&yKad!fMw;4fV6mXZe#aqjuyCr2uRud<5D%jq7xr+MoMiVyc)?ga`@< z9)4wdfy6m|2%uy3-s{Hjg^$K?teZdkb_*X+IQhCrn_O=Ml1`=R#HL<|0#h6&L;A&% z^3%w1xBt|EBqH+V z)Kwn4ze)xC+aejwHyq;r7aJ(bJ3d_BtVpK^EZWZRN&}R?7`G`SkyggZ5c?=pmB%>0 zw<+H?{3%`~FNU20X#S%tP8RBD zdfV3i6aIIs`z^Z6%prn?r>)0j9rnilYL`nw42HXx3DX^UiB5Mr?O~d>(RA~V0dz*- zkLMbjWw(N(#jmIKzjC+;;_IK#=o+KLkQDN7OXRMzwks@$Fvj!E2QUaL9Q-!y&V1() z)i_L`z+B$wfiQJkE$1ED(#0T2G(+%6Z$tWHPh^vK(orH9Q<(~>Ojg!T z=h!4x>!LACtNDow$SnL2oxT=XK0m2(<2H;dUvddWZ4sw3Gijk}&l%rem5KWo9ydce z_r4Ef7U1f8H~e<^f|@+B3%aQwW5VZwNg6#`Bku~=jTq1%h_pl!6B(3yja<>}z)BFm zYOK7g@r5x69o{R8F=FU@0gT;`%?8Vfp>t{vaeyC&4FV`6ZJ8DA?8b{@fis?^Nb)={ zcN>shfkWaiRL?-{D+@=HM()sm-q*sP7@V%rfop04ot)mzAT@ZGBzK zv#xa^cV>&A7sFf8QUV%hOU?2`$cp`TSG>hc*I6HN*M;HbC3|y?6AoiR>=7*+^zjct zw`A^{p`)LW9Jg-&2NKPEl7()fb^#4nrNf+}bN9c45TffJIvZwDOFIlNSrAS7u%E4N zLC4oZb=|$>v|8yImw$$cyQ}=zPV!spDuO#TEuFXFc94Jl9tWB^`?w>RK{3K{h>`#q zvzX`u4r4F9OZDCIGdZ|c{dP%@AIQ1LR$2+qvXhuPlMyU$`*G)jZxIyXvh2~^+C9xr!4rH{KmXV3O8+n-vD(ql*hn%!c$Tzuw(c;8%TmS_}U{ee$= zRfrvxog^e`ez^~zM5ZwmO?jjX750L8x;(bczHcXpfgjDLhY50X5(Y;P-CN>)*-%EU z$9?X&4c=$mH3_4BTiW6f&==L2{6?a;V-mB}=RyT@mNXbdna7rO&4zfyF^kT#rh(H5 zMme~RB<+Ep&sU?-Xg}2*>c=iGoPj?w!+kmzGyW&8cdy7t!+J-Rfp^_yM5l^iK;}Yv z28}QIMn%USso`)*laXe%rTZbIKlAsC@YX>$r8QhKCa+F>-Lw<2LS3@mDE4>G4J2s9 z-zVc1gI(Oe{27q7W^}C_TWcw=b4u15tGWNA`{>jjrEU+0?AY>>Qsb{k4`v94b*b4^ zh}-CtE{NFLCY^1H(k#kRnLgaYI)E9W*i$l3Y89jJ0#tqZkz*+U34lB#_tc1q!6Nvj zZLsn**AS$jc3@-8R=++e8iLkw8*<2IFf=yNgIj^vfs0BX;`!T3O43ME^unIW6~wdX zFwn^gVm(VJ^hU(7jBy&8pFn$`bXYBq^YmD=Xy3`?r)ENY!p9neIkLzXo`0J&jM2bm z{{1vGJoF9uLu`z`RJOjB#Ja-_4^C5cg{7Fk8k1@#w!n-DI(CKD?#rqcw2Kz57-N1 zHT;zmlepa{mI0(eDAgxQ+1Wds(kmvIj)@PWxQF{)=_~<*KSQO#qkYq=FTc>0{C!P9 znRCknbGHX_e+W_P(c`wNet<<#O?kn_b>x1{lj@wVcUyL;qrG@A+V_ti zui`m75MD?T>+NT5Tn>JjUr;PW#!^WT(U}H7?l@mnd6qwqQjUgOo00w`fbCvSmzAcC zb(-_y-{c%$LV&U22Uo0r4D#Y;M4P5RwP=kdl+FQ2DFncye7%DjS9^O51X~~vd)7di z)UZP;^dH>WUe>kh&sG>vG3|3j)_X}%(X_K~*rAlSt{o_NI-sta%o`hQ31&MqRoGV{4>Hm6TcfICBMV0&YOSXx%VLF64qWUVS<;sCdHeEdmELnFMjjLF;z@z#8Iee!L zK+l2(@njdy-y6*NnEu!5Mf;v?g5n#pz<-bRV!TmgoP>fUr>jj4_53LcWv15K>g<$~ zD+DYleX&8O$HuV9b07{1gR>f-xMC?R{rP^j(EThx;QfeGrm>-@mxvg#72RWtgI$e?yx z-rkz^C*9x@9AuoQbi3S1)o%>SeDx^V5-bu!2)u|}r?vjD;+QFkVSBRI&31{DLOI@G zK`lRRVmyNP(rL#(ToVJuJc z9a7ud^NOpm_osi{Y@|ACJXF@ksHr2Omq-_}B+_*}Xti|dezO;SG&64AOC1+oNAl$a zCp3Izx%F%C23PS9>iOri=&Zah+*LE9CtUQ$dR7%_l}7npEUEs=%6?r7)Cni%)}jY> z7VquB&M}?u4MHwcH8DvjY;;*r%3$r1Z|Igj+14_?`HSzb{I|&?!ISiRSI5F6rqyGA z$}uj|XLJ>Bb)|BPgJdOt1%~2XylehDZ2BW1(Ja3sH3G|E3wQjW@W93@@7VO~?|?>* zB}3qf%xM9~R(?!$M2j`$DsqD2WZ4L6q~3E{OsmMpp_9+&G-Ww97=Vq~)}y$xDxZI~2j6MMlec>QvELZ;5%1B_&k6eDLLlCauKC zPiAiW`MV$Cx%{sotjwtCQeSFauiNdPO0#dc!CKl7udDaTR72*1>0``V*?Yg!+h;n? zb$sEZ4Uh{v?bAZp-#b8{rtBR*(2mdGB_%Twd~tEPU?NQsL*j*HKh@^v76NGC7U=PlNgfxk8tZ zo^!C0(4~BQ&Goo7VI_zdS+QCV#U4U5OeyDwu2=5;eRcJ*JCM}(`3Kw_{I}(Ov&p|( zNFtAgKYpSbB@cRTf6cDRfqbRM6ecS>R#qb)PK_TodBI=QtIhmUON)2_4f+=6ToRj} zHsez}eygnQJM7pkMYJrhqH}LXeCaSdZOQObN~Yjv&Z*Aq3!Q)tWIbMCyV2tx>?qfq zI~C*5^ok_wmBTTX29E5NZgXX$yh9>bKx?2g!kO)caiwzUJTkvsmz8wQ^K*hL0Q%Lr^1iH%Kt)({$`@_eSJ2YtcB z*v%c@6m*UUa`6;dWv$o4DbHR=qFol2 zQnYPRA|S1E0nxJ-t?v5!_iX*^e!o)y)O)&?eyCdM(snj93rkB;zcq;@oBvW#0n@A1 zT5q{Z?H$|kM!Hvyt4SUCiirh2Typ#BLBf?=>4CH4&I~K{=}r9+TqYZ>)=xX8`fs}X zyyT(M^x#`u_s*6i>=k@8Ix+ws9mLQfRa$&M+IWBTk&LjAjP2jc)Ccy}?`)G+ozxEHC4JfM(T+uXDLHD_3I=aHsA{2g&Xxwh+~uK)f-{MSU%Uo&7h)d> z0rozmND7MKIqQW#1!yP4!rri`x}d2)24QiuqF@u!M_sh5j>2)Lm$B<2K=WA%VkgwYsUp~YoZ@s zJs%0((|L+*%@ia6D$ESN;``JuXZz=d1_&i0Wb<^pZwIXu>YSPtWLZkdth6w!9+2U; zKPX>})wmoDTeO|K3i2RoE2OyR|EM2tu6WB~DBMfVw`I zX$3fxcj$vyXCN(?0cb<#;2CWDl3@S3@VlkalaDHPaD^!Zs=)_hQGZoRcku? zo?tru^MM2G@A2w(O!jrUrM#Nx>mrBVkbgRu8U6+*%OhA_dh$b}>bYpJJ z%UsvU-FEOo5eAV4&$LL9M zYL=;)2MdDco3{dYAL|}}cYJ8doQ_qXI& z;|h|k!?m32)qiL$3vFLV)W6NKWG7Sq`x38IqW5T+Fgy`!e|pbhl5%@btfjzbWi)$6 zBqFwoA*V~Cmb}Mab2jzE0KM89t)I2JMWsox+i`{{q!E0{t$f^zQ3U)4vzszlLvXtP zoL8BgnR;S_e6qr#e#@(N6|~{mLNGb zL)peN>fnylG`O8Vit3}hZ1g@cxY`;RK&-JjHaRs6ispMi_uY1QsEBW7L~1^pC^0SH z_)ryY)hYvmp6>Z7#VbNjvFuCfRC-`aQ>!K+dR^*%U05*0X341O?^|hKerD{)j~XV5 zks|q`Ys;{wC5yY$%vB@{O}cnJ+tq_lKIQyGEV$HiU43!Y@LO$O!eQIv+QZ6${aTQ4 zg2SFTzHo9JPP`Tz8#~WNvy?a z%(L@&nLy5jq2Vvmm77a^zDH>LA?mF|c4dc;6V%AwNXTA)tTuH^iDJc9=*0$KD(OPc zhHmLqIy#Ul7yvpnPg>#09{pA(<$>&?PTjl6?q@2o5v7Vxze~Tt1>fLI|wN9zChAp8Y-k;2C)cD7Whtc=Um7x+I(#zT#%hq~(u(dQ8Ony7!Cs z4T=@_Yj6%l(Tmr~D#r?`2Z2S>AX8tJtFvmP z@dwMJZXT$oC!Nip4r>`p(r0VW^t?hTkW z0Q~4e!qhzXBPpY2VB&xfY1iK91b=)hW${GDzy$4p7^pT(t(-2H!1?Xvr}gziO{GbN zbsxfi#E(o*5ka$0x})P?`<$`U%hx~!Gofj1Na6jDG`Ew#;h?u!2;am~ z@wz^-U=xZXlp!PS$IE*6U}x^LZQ9ghe0ODs>dj~N*bCZ-LcS8sX9v!I{Uhg&~YE+?%I0frP?9#&q?4Js&s%QW>M)&zu z+B4*A+6cd>9d*fNkGN{BHU0kXy}U8RIW#a=OUD`-k{VK?hBp9^W0O)zQ*1CCL_j z3WhBNqU8ht$P)B~SPEB6Twqf>3qrin7ty@{fcB8)?|=K|sPRG!hF#yCHM9kN8*5^z zDoMQ9^coz7!crT$xZj6&5G`A|54JN3nuzE|3znKvTh7yJ7B$WMOwOqUQj)E@4_(R& z511Cmi(i^5eae*2-Vnd&=5Y2KZC!N%#?l`~?Uhml86`c>gFIV2X8s$g^8C)jruNFj z34gB>oAsf@H^&>J?@5Z)1$Cx^Jljj=ps(s8FRA6q=9Ic@dM(Swc1dbPVQp6$1gvX1 zxer9_Ja&(&UKzjcoIP$yIngN7VrxF#sy(Z=yQ z4L9m5r&GVFOohq7VO()bv;eM5l006^G?1bc!!c8aO9f@w%m=<)%X% zD#a3gH^@U}%7_7@&pnS=IW7obqE2zmP`gANvMoh9*ku<%75NKM;<*Mix09Y#PZqZ* zJv#wE5ZV>D^^(MV7!65*iK$^zeASgnNEI;V!83;?X$p9y0Eco(g6{jHFULC>ai2X6 zlC}eQ*>7mD2=5GVP+_*UnRJfvY9v=!2#!%hRD}u?UJm7xdUgs#LAd*z?84{4qR)o1 zA0s|Yq`t?6I_~mLiybzJ+JershsmQ3u4DE@cousu9Wj9WuaH!T2h_5dbPLn`>ja)@ zFu{4Q%y_b+P#HOo*toE+Q@kEz>#7vf;G(GmK>-R(O|QX<)n%xP(fK|Yiakn)5-jqa zNrnO{McngqPhH-BjuNyjD_X0|KZ5^S5Bq5Znb3J8w&PNdEjF6rtuaS zUYci{LxSUj+m$$|s>ET={h8>)Jax~|u<6|2n-rQ{61D8Alm*!{jNW3C@m{)W9Js(L3*2z;0uTCamvPe*R zag2Nk>d)I^SUAUrNdWbSe+oq_1YoY*-yLcUjd|4rN9W6Bx#O$R&dRV86SO3J#V z14=8}dvV{Vf3|{7ffvMZbCP-}ghGL6b=;|+AIB&3#O>1c3sn=Y5BE1P35=!;CAu{K z+%ZQW%~6QABt5AZ3&Kz>_YZVwyB)KLV~Bu1P5>T{L;B13K}3>q!Mq-2Oqe{5U@jto zky&pJB(%VnhMgK|=jd_+Tg_Y)+%W8+A@=cF_fRYRvvl9FnPLhSSd!OGx~kTBUh-fS zot(%1gqrYL(c`1Jh{Q@kkRc8-8VDiwY#&*bCyrF34>qhzd&e-;l6?HW#+VKZOM&{TW;npZJT z7?Dr)Y*1X*=k#avU^YpcTykC=-sqldjFc(1v$N2BQ1d0ak}0ygI87` zL_m4rP>sMDf*6-cxj@S|Md9|)b?nKnW;VYm72IDog2mQGTI9M6VrnuY8y%_Yfdx*7SHhbH zoq8ZVHXp=GWrb|MFV9D3EcAUr)yd8uI`wliHJ(Llb&o>MyYC8?n;Cri-Ad$dbg zIsdmK#ie;oaMcBkhPl%0$%*v8`nC7P_nD?-omcLC<5h+38oo<<;Y07rEC$u1w^-8k zx4N4(i2gPyi*uVUtMZQ9R}gEIju;}F1#e1`Z~Mvv&rp1#x0iM@OQirXn>o|@Eo?ra z^!e)#YO~{}2(X%%D^Z`HeF<(({P*WXpuPuxb*8dy9W;Y$STml=kj2`)d~Fim78O(? zqqL%9bZ%-tLCW)xHR%vHSa4R@_Sc@J-FrNhJ#jQvB#6XobfP|2U4 z{Y-v_~+c)`DBJasLo^Ew(yU6vA*D@0(` z&Uv`p(rKFpG#9*P@Ktq8!ExTDsQr`Vgn}AMK>Ly_@4=%;u;QiVBvz*0BQ;DC^(bSe z2By$N_e>AGM4?3p&kA~PhQ7gCjHwcgpO&hOtW*9QN-w#IUSmX3Oyc!b7QZ;_wdW9| z^{~&FkS#of@bDMy_=~qMxBtWXn=bu|*Ww5?H3PmRfAMqdv6w|MKY0E2#&aMNOQvt5 z%VYt4a9tYGQD@csS9ev|t)mmr_zJjpM&Jj*p(%#+K6UjI5_p){>mtuBbLoRhosO<{ z9x(T-@hd=LnE2oXWK@SJkYhUWWVSb$WPDQ?IyR9v^X81Df+zT^(&z`r_qEO-oO_)K z{&gbE#+Qkdx|R2G!~9%7)2-Ep)_$hHJgzXMuq|)NS~;XoJ3R4`ch6(XIkpF~#XO`4 ztpG1Eb{LSHe|zBLd~Uapc;PxY(aO>SN1)9a?7YmeLROO4CZjH*kL*tU*xw508t|#h z;|5*7Hwk{VTVHW|zDQ-=Y9-tB@c09qLvx^=5TgbEQQ^@L z|IGHn4R-T0kWP9jmvjaa0bR|{Ii7OOLadxsq@X0@K1RGce__qFllQWS@9uEIpfxRr z3iHFo=0+Y@q~*-F-Z};L5`!&^t@$n!T23U=Aslju~D(B!j`tTDUa0+(VkJ}7VrCb@6XCi zOl&_y0(z*gby^Y5`TW*O_O~SH&9fh3B^E$nMU0`6paQ4-C=!^uK`MhD_(RsaO zD#@ry&^pgT-n0p{=NfoRbm*Omg$qW~^8_<1Ju3fGuN*@2UQah#051i*r}^JoFzI8M zX+K<_T2i^%hQmSGP`R{DFr3i2i#z~nxM$6Bm6OckEb zovuCy_g7_%gzvS>gjAs%TGIc%_wSQ$@ZqtmHuGK)-+Q41P@;xYh2PS~D zkBop;)WGL?jEvv0K*sb_4bbKJY(uq&)f3D6FTA%_qBb5pY_K14~b9n}}y4QDLWE%+Tdgchzi z8)T-(N|6ZCM6^HU;whwHg^?VGYT+~g4Msk3WUFyuX$HKNd8gPPENWSU2t}?+;wPO{ zX2=7i0%d;}ico(;3$es_tM$(x-^_kk?nD5qGoB0o!W|rmEXbVpd=zDBzp<#B3(!Df zu-uk3cb2<}y^6THL|p9Gp~8YYjQo~+)IVDpTRo2B@9zolc^z=81q6UF#u`)3l6~6d zfP+k7i6`+zDd7JE)lu7%Iv;lvZG0zMFE#nr6v&aM^{COX<~HCgOCEY<+qMcnXQse? zCea)%gp<^~bhg+GTI8>k4k@xpt`vNCp1XR;p;!>i7~W8pKWo-ga+rJRoj87MU8nsL=#f7AZ{ z5?crB63^ki3KfF|?W+;H;^4)I@WynzX3DgDq6;-hh;sI!d{47u+{gEgNAlkSNb5Op zoyqvO47im608H>W((!Bc&< ze7`Xk$RYEpF*HUgH}*fUa@XNtky^%gJm>r(cC)N`+@Nrfn@%bvBAK)+f_lM?( z7u~}mygg)pgvY&V^d>0%lfbCYfA--Se<%n*3l<1*38ENI0JxTQ;}Ip}~KKIncA^N0IUSJOid zjV})FdX;X05u*myvHFn*)2>^kvnHElNSoy{SimUR7n$ly|D!GT#gZCeNVt-ZQn|)e^^) z_tM(17UX8MIq8IBx=HJN?&JvI2}C$oX-nqLQTEOC3p(!-9zCxAe5h6Qt`SS1Ftz`? z=3AnHYei+G)}0T~ar^6b1biM%eilGn$Gut_2)h*CfR|tsfFXrg?aGqmjmd7gEV%?o zm{U99-!CeX_z=N^^}!CzjWA z2OLx+8^YRsM?m&ZCS!}@E$*lIB6m&R>T8c9IP;ybxK?D3tLWBJvEg3F8dFm1fC~wI zrcnQC|9L$Y%9A8Sa)tk$5KT}hAsLlhiZSN-9U)}=`W1EfeYjnplc$<+e(hoRdz(ga zM16548;KpXYDrdmr54vlSmL!0+0tNG=Q>3z{PsFe^=vY5wovJi1TYYr-|a|$aODoo z&Q2FWt_R{@37XkD1A!KvX2N8AZJ3KWYD;wBzkY;C6LCUuxfGk=4FKoowEj%;l0U?7 z!ykXo`}Z5wG=CNH0{u~Hs-kmye#l!w95_i`2DU+U*m=>1%-KOaFhSyx@<|_S$b_3` z44!=$7tT5jMf&VtQ9G5Oh>y+3G26r`A4jbCpzDbl>^#@jnef%nqon+GOv z9LujH@wX3)ycxsfUfQ$W{!M3kJn&TiZ{iFzNUdQg~@u(~Z? zoO)i97Luv+Kn8ttja3#q=hR!0AJwKqZ|uLhX!YKBsd?%gMvj}Gvx@&=Ynnu)SN{A( z_l#+)WA=n=ms;~St(tndF!d^4y$3>e^sZ+1E249-!?J1pqQq2lQz>iP`2ANAxwW|o zZGafLV*G>ONFd_4t#JaAc4vnd z8jyLy6B|+(-6W%z%D&iUZZBi6Gk-`Xenw-t=Rws6$=xPSB z{!d!+J4@?$Yxp8B{=2nBRy&`PDZJQ<+g*K-I_DWz=>oK!f30Xc*Y1jS=#f!zl#;6S z7iKU12h!lqc%-vh?%5dXjDo~@gbqYEfYtB^oBH*n$~R}O5VKtHFjnXNOVvA2^TXqR z>D6%r3A$2N3GTO#z-ST@M5i%!?e2io29jTg(u~Rohe`b6m7&i(-M#$g+zj;~^}%Ub zp>Qj2{Lt5eqZajtZ=DEZf*(HE4tx6Qlhv;qc3|{2(~cSV8hG3p7Z_`AkB#>(D;8fB zdpi4Y;Qe&&RJMh0{Y#D5;`zJj3z)U;b6SlokpQ;TL_Ty&^j*N+b=1b$!O_J=HVFxj zpoxjeb8uG9V9iAsN8453ZNZFK;0JLVzogJ_d=)<^o@^6ch^CjLvJ^z>o^sb9Zcp!JP&#;vY+98Upwgb{kA?rm4NsxZF9IT%p3Rz_S_ zJN9k2RkdhxHzGs%z6DNM@0$N zub&rOue_o*>(g(X>j{m;@i-jjT7+ya`aLT_>K@8@?RtI0lk{{t4z^TXRU^wWY02y~ zezQ!0#mE% zs({BUK=tFj_$h1S%Iy-=1$A~B?&#(hY*nLAm<$Me2k5Lze9dPi2(%3(j#ZNz{rFs7EF~?XilPnTwTruc zFvM*l(6?zTxA#6=3K@P|Y6Qpv(mkC=Q*UbhoK2@bQTYo%H?Jpe`Y#$`~0713cm=Aw8{u=EJo&LAb4+ZYviT zlm`LSvTJ_WH zmssHqk^8Ms)Nn5gTp7WBMNK;~2zqW(O4_(D$D85IGO@at$9-|6^cwBV zC%p3s&>kKblb_=tuo5m)oqw6}(=2?Bofye^?M(yCI`F)|elpfE$38o3Uj9y9PRNx= zpDsa<*?ht9Sr2;shhq3+wrb+>CFT|=vs~GKI-D{;p`6-gd(&CbxEif*atWO;@z5x+ zFf(TaMJ+waXysWn2#FJdXQ4{Xo5YKG+c2*Lf<=wiy&ru!^);bf;O=ux_+?S$$2dN! z3iBg188@`Y!E0fcm$lsfVjw9xx^%Fv&hz>=I5vUIDx1^GYpp?2qXA2H5;{wd9gXYY zyp)F@gKmS7MDyA#yx#p^{HxK9L_IG%e)2h=g)6*5?d+8^7rsctwWD_X8(>41BCv80 zZGs&s(!#l>TW?yOvz=$-pmZwYw>tjjzxoN|+-8u~$eWMdFMJ$sx%Wc7NJ>8-9$5-@ z1IOWJr-6D+y9I|>%ee7NnlAjFc)PZ_f>DFrxWKk3D{Cd}9Um=SIB45jZD8%#qxyqf zsgY6H$X{9qH(I(>u;F=XLa6!-+z822WESfhg=A#p zC;s7m5n4Mw^S{0(KR&qi^$g9u!tpX4Gp)fg_X`0h#b0+{YirBnn1L11``gdM>!}cr zc2rfDv!xZBB4enEPnVd@O46cmQ|Vna;AnU}8##U9zCI3A*34h)yk1+GC>-+q; zs<>zM48_Z0u{mx_hCph?L?S^_cw!iPU@xm<>>5H2!0A8de>FOPcbVJahJ*6@dc>qC zs7AE7ATm98dGfhg?}hI5Amr(di=nEN-2x8Gjq4U51uDOcj=O_!HmqFqBE*oZ7dLKb zBp7L^poS8G+GU}JC74o*Smv$!#((M*N$-RN+^nA7{h(2xtorf@0MxqA@lvsJ zpYvHXsJ$a+;4_SQlGUege(gOThx;^bw3L9gaEL0lY8KNZgxI&K$aln(Z8mqn`h4-_ z<_)t6@eG=Pfbcu@i71sDZPLThNQCPxY(PKK9{1$tigP3Euj; zch$xEsXLK+^D7cb_pjFiS1PND40E5JrJKET3OLx>Ttt^&V2Rt>IR6goJmuC?y5!Kz z)nKqx55!i%p16LYGFJKQ?>TE;f(s$c$O;c|!iL0sALCvLgbTj$detVCPYDn5`%W_u z{=DmlFMD5xa3AX2jLPk4Ts>Q!9n)$AF2}};MI;ryi3jE@z`Bg;l_N$=Au`O8&fp)0 zsmd`XoI34sk;l`>?pgo6Cnx8bQyOoiON3{C6uJ3B^OdQYHaxXA%s%KqN68@J?YAwl zSm!hcLR#KioipCS`nqnfy8@Z%kGx; zGWlytj@q1mj$i$Uhx>xFYzoD-O_t079F)ub28!8B)bR(fg1tv7>)Jmm^3-&!VTo66 zALE`p#nQ6L{X?z^Y?_SLb{J1jRbME2MSi5?qtLR|HvYxNk=B&me=4W5b%v{MOWW^8 zFzr$fHV$mZyTOLl%0ft3<<$*icjG4YU?+`MLd!S)D>qlY^oL6~pbqOC^&O&~-;eV) z;7mZ`A<5&g#p)pJ;>*9T@pJy@Z(awj_6kns?EV@n{S*xX=zm_a!%u|C5!h*mZmp<;wT*7Sp(|se zj*X2oFMs3yGYdKS+mceuE{P- z(*-Kx|B(y{%syeyubF;S%wTLj<*ZZuHthu$t9KS`W?_rP;!_ylNoM-|*3|_OT+DyI zaWA7VRJA)Cr1&`eWQfdyYx|T4O03Pmy|+yJft}s!BW9sE`UIvUFOnpk$ zb6d4lm6LeWd($L-ZF;;MdzFf-K7!fE4p7xydtZG-*h@s#kH8aV(gnUGPRJ=%HK){mO#P9TI1qn__c|RD*4&&?MulWuSe5sKR@p7 zenJuFUdZT+`V0$CJDuz>4VHb~OC@rgIMz)QC4&&g2H0P^WPI_ncC}3vST`5z&*uQSG&dTSid8y$xCG{{yX4t7I7$-f|0~tDFR))cHGLG zE6&GNp+H1n+jNtc0Ax9x2!Kw|(>pLPsl9xThq1;oAl(tMxjpIPV~sDDKnG?8;9mu3 z2Uo2(TEK|lyh)SVVh;%xE5DQpyU}6A${CGx;NO(O@-)bhE7b>2dL}cDy)K8zE9pvF zoK?OE@(6d3yGK85A#o1pEBcG8{P40}4f7mIG$g-cj%{YA_ASrgyqo{+HoYZ!VC?1V z6%L^dd7V~~2lA$PwlA;z_o8!bJT_ksO0|$j>y>1HFiJa9r$=+NVg3TB007egSviYH z+E}goeu#`pN<48 zVN432#U`x{pM^m_fT6_c!GcqtzEI(vXL;V4G8Ut0chv(IqkfBJGAV>95b{ z)~tQS(m*#NaB%v%>1D0cQ}3*M6jNUS<-iy6@k02l$V%{;A&6p3fZUuB%t(hN1+z}J zZZTTUQ+Z9M-iTMaVtj%1wER-uCScnCrL2w;lCQ$ZrqxHC1CPouq{`L#0=w8h;gZ}Q zhX|i$lh}Rp3ja5?ZO~jbKUjFNC%X12TnulB`MTytYc5&pWz}aMKEn=wPMX#b+-ox6 zE+_0>)RW!m3l5;5ccHHS>=PgF3>bZ7D<1f!!JyN7|v)Fj?!2P)tBn7PC7ax->&$+klj5DCEj>qx$ z)}1qboZmjcbxp}-Y~(;k=zq1&FEj-SApaec!TFFUx_vP%3pHe6u>jWJmnK(>L9>b>J_BN?^4juI# zDp9f=UL97|GsqNiHE|}vT>B6Xtaw?Rn|wH_5HV`cLUru7Is4KOep^}sgfa>O&2i8y zQ%Q-CGYKELbjO{w+EW>^N1@GBd+Sr7BEd@y-yQRI#8t$H>I)^^7W>5xpMlK=vH3FD zPcOCy&3-j1A zT?S)LeNDoC?Xk#Bd&3uHv`D$%=?B1RS(eGCirMwkp>2IoB(m8Xn);9D5=dHH6x1O(AtvDtPbw zA+<6q%6YV)OldQ6Z<5Smw!WOB0IOSfyz5ZY8M18$yCt!v>tz*avk(5FT4zhje;;&~9 z`ps3l#Wkq|Fu~i}fBbt_bPd7Dcm4S&qGuv&I77rn{ks9bs&_#UEz&;n@JqeGBh8*U zi9s9gSjW%O;y+x_B-W7iMQ3i2SMsj>f??b6m$Q+v}IIEtT!@S^qZl8jhDHY?0S~21AtqPSP(oC7)@0N9t zpiFGlaKHPS0OzI103m7vfTZ8x_`=?)qRi$M`dYtJmwXQ$AHu??f-^7c+g*!&_6W9JJnF_z6Z@BTn_wSs)XI5>UTYS`T{OEU3Lso{7t zK6vrbKmUb_aEcj0h&Aze2$JOKE5b)4`L}H22>vP5ZSj*p6B6uzbN1V+Xhgv)HnNg3 z`Mf8Jw&6GPGY^z{3;US`(#*&6%Xo2omNu4rhE`*b-0ue`v>#mgjrjas7!euqZOpFw zH)mHN(DA=R4l>LODb?LsBL6-nOuNHH{P_^!bq94rNikvLve};wJlhVILVQSNW8-B5 zrGwteC*tItS*E`u8y$AxC!tbuX7(s>2TkvAf)I~!hNh&76QKbg)l}0ptErVK>&G@p zqW~}u46|`H|C|C-iAzwg=qMlH8XF+W1+{<{!aSyLlezU-i<(V`3C-zK^!HRJ*Lk8m z2_QslLm(?GO3{Vd08waXOxI8bFHg(+2*!0g{6RGUQztWaytwBf=ip7ZvC6HepEklU zn(}QUTH;>8yiU0`gHMor?qM0tL!r|yyJG$`-67!%IikO}EvRTc_OJGwIu$B=&=$p9G!MHn$n_ z_esQ`3S9AQZE1hSUws_oXL0UIOAXWw!7Y^Fl^5F$G_hRpQTgXGBmias zy1rmf^+go1xvMAn{tNr1mZC1IOnw6d`<4C(80YwG^^-mU*CLeUHS}bMZ9(OHmWCD1 zTJw2#XF!3P?Btpu=Hc6uf95Kx>qc@!?e$3?2w;ms@E8lLz(aJKj)h zb=UD$5(<+5{x-wr6+Q+Uzhz}%u;9}~)P5+=tsM~>xP(EK?fLv#65Jf47wMilsTY+U zS2@hkBsC0)l{-}#NuVV}{?sq4rl9O_$#?x6U*KO2@^bfZl*F(;8~yNFqf4JOGnFt_ zgFM~ZB=8ZS!!!0F9gV8oeDYk9?fUh(g=YTP58RfIhs()sX4psi zMkjJfc1m+o!Nx-wvAyDqVU=du%SaAuO;2WNCKWJlX9KTH_A8p(pv9f3#MC4wlPFsA z<~(1bUGq2*y}5vaN^hRm(<23Mz+l;nzcsWwEpW$t6*BDTy%Z0E>1&Aqq=LORp{QOXV&C(Pnpvpl3@KF!?Dr%I%Xikt`9&fbLl zq!MF_pA8ocCQT*6czMi?yJilYXY&qeu|TNz)k3nu-Pa?MN^n+CAK7rzj4Fq8jPgJ^ z-RpPVq(k4xv^lx#t5!dFewa6kY4KZjNvFZTgF#vgbW=E7RC0;9>U5rn+NMr1VanTz zURFbiJNL-I%2FCH5ZXYo+O_eYrW9pRm){lbFdbtgKE>6VfC_h`&EG^DxI4uT;b;E? z-q#aO5l`#arw?2XY|YOZ0}3i+RO!KFkROpr+RlNdXCR=o=bhyL%p2~p#ZMNIwQhD z^oO1;Qk}fV|8CSNFWpW5<*)A3%jeZJtymM!MnKpEV^l7?d=p~urY{DC&G_{w?KZru~6L2w5@ui&(&V+38*TMtk5>vjjXhaEq?1^wv2W%yQ}!#=HSwr*k|QHbs7Ja<;QG&*-Wl@Zq`Q( z$~4ttC-il=bKapru_pG7 z!I{2%7U%D>a49xqy3LKn{dkQT-`)E7H)U!=4DxfMh1A`mMew~Ty#j3)Ts+bro}k2= z2cjXEH@Be`EfnTDzdx^viJ70{Z)XKw|`^m!_K9uR=x2=nlr$|i8Ge3_Lg|9dkcPKtIF@ndri9p;y za2FR$yfGw&tk;2eC%!}nrN=SMnbM*V7_4W2ltw&MXM9ZQ(#m|^`Ui?#X`t6y2$X(dkf&<2c zi=ehweCgs$l@Y$+z`b8r4~9XT>s@^I8QP%-B=phwb*=m%`)20@vzWEDywFT$5FRI0 zOqxS?{a!ogX;xupV^6&`iWfIO89rUjd_t_LKKKr;!jcTjmNzg{#;Si2*nwx17YNU8 z)A5dRm0fv7E&U|jcxAp;qhIrqYqJEi(f!e(JQ4@nyCYMnh%!z=7|EfGkavW^T^ZH> zCB1($*wMHra6PE;bT`9k0 zJ+L~w0Dcn?yghS7-!CtY84$sl@`E_;D*_ln=O+90#&I5yZ?Q8G(EiCs*yU#vc$(d@ zLBSmCw6t<`L`>iA9rQr5cILQFh2J3{S>k@8iMc75*FT*qAWpaH;um81nPD^*U~a<7 zQ7Waz^2&9?4mrA>8 znYnxoCthI?SD)scrU9K}qr|?Kms@vtHx?Zo-O*vExoD`zvajp%&b1r8KT)>NF~gF0 zJMa9RN4J3G(U;KN!YPX*C?-gX)k1aR_XMg_J8suxhl}5R(4!XnaYVe4QC*w)qDG+% zgN%c}NILB>6Ao_e6d?$yY=2Z%WxLel!fGP`{dHXL;MFKT!&DRsb;2EbGRa6b@7z;^ z@pd_A`wZ<26O2}UvBAdUo3&RFjq8j^*8KOeFyV@CJ*H{CWGp=>ku6wzVDwPfQg0p$w1fLtDeTa#_xoh4%$B#&_5jRQMLs~lIebGt_NatbWRSwIuk!z zOowTmmc)PY)~EjZ#z?uDH$q_%ot#F51H-~QSLW3ZW+(KbB{Jd z#PaSYoF41oaR2U2Iedylzy%YYRvv6eT0t7p=dyyT&FzI6I=E;0o{aQ+u%(v>e9i3e zK4y?OTMb=5bZa@H()4!I&Ytt0naiCrC7o4pVsJ~tQYoAcu$G>o3v}zAv6nS#JXUEi zgR<31;L3U!hyChyt)5gdQXY~{%Nr1abC_h{-b&lh>a6?oTINNlK&~ieAedSWtWJy| zD%7F-k83CN!GrUa)lSy34&ir{&Jf@&0MGksvy{-m{$mOf@D}@qVj~@vBjz}bPgjpl zm+gU&e||9+;30`jk5?>aI^n({%V}0Z91CWWw1gdykE)~yPD^nbeE=1wg8N{BkLR2| ztM%ra9jB%&X1hFIY)T_a`st=R)17%TKBVA}gQ>s>AE;<`XvwzYVX{Gor@;Mx9r-04 zOqRPh@c+c(4}fcbt((%3_Po@4LVm$>=64RRNk4^{1qD2+%5)%kBlpSd>cg^x5!cq>y#L|e=ZwE?3 z$~f?BvfZ+zs!?v8P!NzY?xcEp=Fq*soicy;C|dic3S=HGZjVK8An1E|h;oQ}xUC-X zWwRhzOi2Vv33;_i2~W|>Mq?y81^qJcNv|A%%BB~OS>2FpiXAU3k%1LkBqk0@mcW$h zpV`z>TUpB7CY;~Xu)rXNWL7H5;fCOm-qOxalX*fU!NAP5xHg&SC5vXs z@y;o6?ENFUKQ#~}ZGI(Fg_Fux$VrVw;dtkeE}#Z^ zD5#LdhqfNgzg3h{gO6WNimA}GsO6~9bM_nPt*$1Lq^Hz2t+z&@{pNGhksCy*Bv{)( zeUSSr@M%6?U;+bd;z3t;TwAt|X7YOdI^ZP0QE2BhO31|sWnAC!i zJm|XiHQWbcToM8ot7gh39fX_h)br?6+)i-&ZV>c3P0bJQ(+_N;)qng}I3hyx*v8Yx za_3F0yB7HR60Lulr^oHnw+-=wArUtoouQuyKktRj#cvWR19z)*211ilY?t>ofRC)@t+B2V<2h!f-!Xdu_9?s9U>gV&={ARxyB>W z5-M1J5;lo{*trByw|<2AEWY5rc#$D0FHj=0S~%bc3XatCR3#=a;yX3OG1i z^C6)>?tf3PCDtWPVCefvbX@j`6eM1&=2i+_Mpp&iA}zt|Tyryea3)!R6Un!&sbi1s zw|u~iuf%}MI}`?`jD=tO%Yh1+6FyWbrH;pH*P$F{owt^3HLUkeTYncKZe!}Dj|20f z+!Z^P3HF7(cu!ICylsKsiw$;7q;(@gej>@u7;qf!GqU7+_=@%ZL*_ADP*XB>Dfbf9$?UZR{*;x&Ox0!vT|h z5QNN8c~_oi%qTIpcS<=+{Oc^<^5&XJYd27rovk4y#HZV#W%b_*Nl86nLqEIYr_vxt zmB20v2^u{l9DzZ>PceZ`Qg6uNFiphBnQH0U?Jlgp`iWRzbo*d#ySCX6(U+hHK#|}B zvbR(}=et5f;#Z8pl!3nW2c~l3uar|M%#JDTQ$z+8pDNl?yRRE}8q3;>yh(dfJfNV) z;UcWU4F=t>TJrXD*fq?)18odT<7UjhXC(Z6>}ANp8(3S?DZWL$C9;-vCJrX*EEFvB z7=B0;JtC?Z@~Rv{{OGIpM>zttf%-!vJPI-7{CO<%DGtNNd!sk0!EZmc!1Ls3x*o*E zMp6m$(@;NlAqT?$J{Ab!ef%)&d`pK;fdx-^hzJpetF14$-1I(w37Q?@!|M#h9nljK zkXFy~usVH3OBEsqqmcyI_u$?7bOy#~j!G;Qi=R=QNHT}UHn*v?H|m2hA8Gah^319X zkEp|7o(~AMe780*s2-#A2DqQwH%QK}@ZoWG`$*w)SL-?_cS2~Zwbl4_G`6AvsLSv? z;Ut0ZMF$w8K4pA#96*HWh@ErXg}N++>@LIOB?;YNw|^(@iTmev{k}p`!!fw?LHx{< z6weyMpVHMx(!;4W&hc9OmR$3~^=KwXY+=?EGI3D}^|a4bzc=VKK}Qc?x>UKs09#GR=v(3O)JN_=cOlkXxw9JW;v*hgJ^61sFNsGvlK6DPA(eWN< z;?Rlxf>SXaXH(M>Xxnej#P6?NpYfB{ptv-;n;&=Y;Cpdu>MC?| zeH3O)yb$~tIYji;lkbj|H4MdaK6Bp%0&L!#;FOj%?+MGxjlX~ld(T(lIiLAq{fpWo z?{d;WDV?8jeD6kyO&}hk%Or3`2|2yY6Okfe_U4dS(*Y(}z)x6RB ziMJDm3mF&Xoi7cYbwSmj!u=9+mL0JgT)OvM-P|xksH)ZXY|JJ&$f-93(3szI!}-2# zJ}_D*%$(rcQw>!0T{qKcnwZHyW1L?GDuK3?UqlI+fxlQ`A#$nqW|miq&wajB2!;m5 z?0C=K{_a4Dwj^alGQPS6VN_5*J**GPh(GKjewSXXbG4u`ry)Bt&VH?{E-hvQn78(g1oM^-^Pct(TFTKr*VR&I}cpMf4iN=S4>3`tmOB8jnjDswIXvs&rb44RdZPV|EE zf8;nz#xvH{((s_T4gy19Khj&+ljSFfF4p~KQPbQ=!EO>0{!zSTFwL=mc87Yr9 zE2CFcPtAdk4e}MQz~IB42Sr^aDectHWOJXn+43gQ*e|DE@Rc0Le8fiXIJr@+xkbgb zRL`fvoTc%kqsVq!f=%ul4pVEVw#=BB%4outAk2(YJ^sX>kUdL~Hd9w=bi7Ou2x3Xp zQ;h7vFV+Z5VNu`k;6Q#I3)}p?`a9DHMyk9SitSxB{J6a-vN4bXUN`Ed`RL*B3%J}_ z9SxhKJ=yCa24B$Fr<%USBGMk#@-jYnJo7=7l`OByVOg8GL@tCC@z+6&Uh2I>mQuxi zz^5eiZ}n>vZq+e7*m`;JrI86`V6Nb?(ser!LV48^9iN!30JilS6#KJ2U2n#soBcI~ zq>z%}dT?tgWooR5yRA%4dLx?Y)zKgJlzw3l+Dm>0B>WlhBO)~47|Y!){5o&LOXFB= zPAyhGO&vneN*TMJ4O>nEf7-!btNtTs@4}VtFqGVNkO%gLXdE1Z4vk-7L@UOUo?*t{ z;HAUJG(MXXh0orSUA&Nw>W7X_Wkma_Mtzxi+h@yTQnE){95{)!`%Yy@?S^sI(kXJA zmZ&ukt2rZ3h}h?jJDDULC(K)9s(r0;Jq1Ja{_n!^eM=MR{_7}S3c;+V7>K?+r3&JF z`NWJm-WrUaV5)2E*37(Zau_PbApyqapCAWJSqp=NQ(y#u3ymnJ$8}{vf0ds*zrRPa zV_u`pc;4MtTBrpfT`tq>5zRDI0Q+pXTNa7}ZqQH2JFjXoNy*hp{MOsR*Y0Z>660ax z(W%CR;!c)wHzUhR0R$ue*}Ovf95~yGFB~Ai1Yr(5t}RWjFe=U_=m!u6!IHriSNUxt zCC;!ik^=5EG>AKS83%xkw!S6O@1=khNuGDfR_P`W>~&`){OnsKUGI69F6oOOB)WOx z`M|H_#^=84GdhIU;hh;Kfo*a(SNRl7J>RscLGQ9BMf~FnvDvaDCxfvDp|$C1%CQ2T z(cWN-MlX%%Mn->~c;S(eaF>(1eY_N#$V)~MyiO*B#S}p8^dL^xmvGY_<(BEORg10P zjW+4nYcyREjUxVFgN*@yb;NR=cU?EJpNMhb2L^2FWlFF@nV;}fzGpuWnLvW7jq1NX z)&dZ5bd;0e1rdt?`3t}o2l3Tum$mIqri3RaX`?*J<-oy2mXNp<}QYRj;&-iJ|E4?mMS2eYXh;o3;O z=JzcVQh#_q*>AhvaL7Wa>Zs^@MY1I3pVn^{#hb&ip?M;FerOIwynDqv2b!YllycpRZ0TOzpr;~E)0U)E@fUvgjKZ8xHOmXvEVUWZ_BgcbCy z+CPPx0M60m5}*esW2vAi-N~f?DeEkwqWZ!$er6b8=5a~uzrMnsW&VQ}D?w5Pk`EWk$(|hl8_I`iw^OW)NbHAyyO(gXoc}At^ zM1f_!(ri~Sy5H2rh3P}q^?EjTVcH0e;-QDYD{vgwEi%b;qr7z#bV3{gnT^E>4fVDK zA*priS7J^KT~&B#^Kv9w(--gQ=QqNxd!}#}AuRqCx}{fTA2#Jv2|e~zDPCRgo8@)K~+RSx+RefzFQmOtdL##KMN+WbCv(NwojGi~ChO)dw6e2!` z4QV^& zP)Z(!KM}{Nl}Hf5RIaaF!W-LmG=27Rm7yH}gN3q~HEFH$FO|!ea@ksX%+roMdorXL zTpYCs_^6p~PeQ*1lFiMA6CDD*qInXd z7S4^vFR$=STt#4|+~17|s|ZthL!TS0=aW7Pfe)EzS!ue0<+YFDXdkH}Sbf?t1oZIEyC_;R%b9&hh@tj!qjwgW&_6Zsp&9busZt?Fk zi|2*S)4S=ve7pihzk5MZ`&4-3NW)&4WQI1V?abeg0!FMSEPvB@S zR)ZAl=cgH2SiZ8l@8;ZexX08mt2XsG$(5ly1JbFiu}YSfg;Ssy+v29F`T}m#`S>wu zb+Q1a9i1lyL;bzjjj=cu#tfdhNLbv*yywgMkq~~k4#G@|^vS`r-Fx|$Pr8@G10^?a zo^_I9@g8bjKLd486uo4~#y!Z(Ot8MXN>gv6ut?csnvB#cIr3ko7)kNL97MHxI)y`DFlyRx~&qDw{6uYoypM0tBeNvySw%^ z{UyV%_ZqT_(D6W zbzGShh{#syTUv+IyII|e=)*6Zhl!4x*ld{k$Tz(caNy2TZiP#or*+a}8q3#XPZeJL z3m{f;PIOEeTZkT-E@Szbm-r*Fj0dT?<-^L(g?KqH9CR|+E( z$fE%2BbJ1uWW1+m{t!ishge{#DbC%skY-Zui2|!^kbn&)V^+~5R2%p1YCVdf&F}1A zkpT#d>yfWA2&0mVnf_5i(Q@{jXkad~_yjBW*OOcbZk9vbOrBwZ4O0qfHvp#dawlfd zn5Bp=Jeu{EaYxKNBefw6?M|SurGNm&BR@(8&JIEeW74wcYHMusDGA3<@t6tMh+H7Tw^Y?Amy%i%EB1%&hNjPQ`RvH?C zG9$G-X>(>sY)o1x-Q3>#SNoCj3*rL?)oRH^HprR~gEMHxwOs9YH5dN(+4#E6|NXkP zt3sA9BX`d~RA4u?nz;@WjWy$Q!dCxTjO8-d?oC<4#PGKf#AN&(IP_XS=G@v)DQm1$ zCH(z2n=>@HU)<|Hhf&Qwm(Rz$`zg316!gPlEVHsf?zA>!Y}cx^I=leLldAXZtyMW! zew3~Ev`n@v*6>K%sS-!dF~IWJt%sh1nHfs%fSXhJ10J;6#W zm-9QFoHi)|uN!m*E@P6Ah!l}1pJgQuq{Ch6wDT7vw5I=^p2&Repc(9^idlT(%WL?$ z?kjB#P02$LFEpJX2Wz4C_BucJP1Fw|*x>o6wC8KKN~2TGp|+g6k=70_KkryyLx0GS z?F_swIX2?OirFK>^tse~ztm7GFH$KLXfE7064{ryU8J^(cA@)He$Pm91t3!~P~Jz+ zoRv82VYOFlIe9x7k?6plUg8E#+>w6s*XNFP5o$xelO{);%YWzcjcziyz>!(pX?T z0Ok5Ovnr7gyuQMPMY_V|Jlo*%%JMH4I(@yY%U!V%le2L=U+`^4(-dtv4czOJK#!L^ z-PvGt@AdagJWyJ27wv2OXdEt%cRu(?5kY4oKOFCMT`flz;N5A6Ew*vnpTOEAV@{>B z+{(B$i7mpP(^@E>ZFc7VU|9rOH0cl<&<}(hak1pgiP?ZH7M{BmyHIzbe%u$U&qjdjq%1Vj~SvY;lOO;-}Yhn%l#EhlD`d`-C!qYW;=-t~`zaFH_ zE-qpKY__`tBXmzMa29e4F5K`P81p7v8BN(jqp6`sTUeQ%xV#8Qs8%f)BgiD0@>}>g zl~vehn?k*(_j6w`pc1qhub;5#VQ-2WB<4w@^s<;2WYc=^-u_`%TcrbTUjf02%3U-_ zbI?&BN~VR`@tISfL7`w38m^j@WT!II!;bP@tzL&AJ}$?y=YKc}^fJlso~mmIAtXku z{&81w3b34iObq4x8#UbS3|o)5p)Lw~I^kAi-OD>h|aYD_4= zApR@ZPMkht!cxFq_4dUbR*P;#^(X&gBlhs4{vn})b^2Vk1HNe34gK*#3Fa%!>IRq8 zog#I&LHF`E<5H0XP4V&RVzM3|^E;i5X?yI{MFIrllMdNea7c&nr#YMxw1z1ny2$b0 zJ5~?QHgOtCE7!X? zj_CMOu}%4ie0+S6=wR%(Z(+&*G`_P?zPzBto*QmkXtW=-u5_xDC0pF^y#58#Vuc+{ z(Jua?M{RjvHt|Y#UOK<`17-v;IX+iVD|ElvZx=&7Gad#Mn)pW>GshOkbnU#Ojh7DE zWYZ4n?EaXMjSX}_?F^PcOdY<21}CF-O@lGj6g*djnx4^12q3|sSnHl zZNMyy)c2b|Z0*EypyCFcU0hA25I{oK<6(HWWzAsS!S`J`!vU#4iR`}1Zek2G8L1;| z&@DF;4Qipbst-%9&UxUP*zy{%uY0cEK9xC?&-MIE1>v`GQC~*MFd(?uQSH#qWz#wK zCtV#Pg8MT#CGq1RJ^IDEalq!p@B-e%4ok%eF*Uu%SxEs&%RGFo59u;r-G2!a_<4@taTA7oTo?IMsZMtwhnpyCr9IbjmJ2d?rH zi*uV+6cCfoeqLks1BRBYDn?Ix%@yx^dcWQLq87El>96uh^zkRtKzrC{x@q8P=Ex;i zq3w^XwX*Q;@X!7GX)letR53vDA!U=Q(p-LTZ@>3f(h%!Wq|!U=@lbeh78zxHTy_!1 z8_358zyAGQn3h4MBNYip8QXF45O)-YEn$ZOIpfRvurYPCNE=VfhRa0p_T`=Ju0}_X zFrQ^-HKZ$xjBcF0```v7AC*IM&lL{)D9>&-w}QjBnFzqUp6~&ZbT3eM^a;ltR#E{5 z0;479;rNnVd2DJloZ>6NBE+p9UU0{JW=k81C&^hbb;hk_DtqADBKIY84xvNm!<}Khhztya6=p7aUu?7m@kdXO+&7ju@V%@O$NTb<(~+jBl|(TG&n*jfW}FV$ zfGN)yV1JuwtAUf}UIgzIedA0~#{=^SO7Xm-=E~jnKf@<-RdR8&95Y zEv!epOcNe-aLB%`kARbN$rJTxWwbT=o82lniPhyVPi%0oIJUr!Wz7-1*rAz zow^_zHk~5DC1(eo{>FM_OQ^I}2QOBGD;S{e=gd~%zjvtKF7!F_-zR-HgBlJ6(k5WG#c& z1j;j4S@AV{zk~lvIl)tFaEkh=ZOBl|hgH>!q9lbiU1P5(OlpZE@x|AXw;m=NFSI?s zTngB`O^+Ssmuny^ajs6TBwzZcm|;T^6%%R5`Ygo}>cvYN@aImJr2|TFd0Xi34{Ere z8o6E3e}ra=wvvk&wix7`wUn0#+WarbW@qdkb5V6%+MTA5lrfF79FFs9PLXk zt!6cZV9`AGG&nA*O+b8DC2I$jF(6#l(C+M;VBA)gjkC4aeA3kD(L_=3)S~o`4zfci zi2374^jup``TMmDKZnIw;zk}{+G{dq`uA^#o=kH5G?MRul6JqrP+9O)$_VZ2&X1^6?ygw+ zY|Pca9oUqPmwPwe4K3iLEqjV*~h%`=)k?$2NoQqfou zkZ$ez392-O24nra?aeJc&Ax{UZ)w{Q5jKgaojgPVUxj-8T}xaB1PGo+X&=SCx^Iv7*CZGDCBGPWA%5 z?;5b2S>k7TT(z^&;8Dx2D9CmtFd=$|qg>FWUOTEt$LhN)4gjv5uxT*@U<3(^g$NmGJoQ(#4{^xQ0i!cYFu+wxABs1S&gudxzR!I%uS(r$cnPjv_H)MVW11v2UwM?brqS&MsWtIV03PIW<5nRDw1?-f~iCrK>h2=B}Hy#eqhx5>yV+%~B1QW8F}-bXldLs} z;HA6=4;0Mn-F*aBHS9|3s{>?%3L;*45h_)DpWcf3xXGsVm`HPG+-z<;SblcWT{+nP zw+@8nYs@Ve`$MV+iGvj>zuqHC;*1|#6XH2oKEV2SrFFre6&mm~X&6#rKw-4(aO}4< zaLr%^RxSB8et-c5;EpGO)s6eFB$%ZFw7(damI~%c1^hcXp{LHwyb>yz&9I&6)h zYu=@ZBkg4zM+BHSX0`hIR5-WmY3Y*S1}}^1nly2R_U~E?g)E#4TCbx$rYwq;8H6&- zTDvrMF2k!0mUPcs*P@bg-V26dULk>*5{ESddUKg>h0|KxAo;`fDyrmX?4q82QLN6V ze3&*fjenq(hLF5F&0!E@EL%u;Znmc4iUIb>_Wg0S1>dXcf-CyvRkWD7I8jG7RqdLSo4io&-`OAY8mwpb1+zSX_!=*NkwlX@0NgY7 z1lP3Fa^fjm0AXDJ>Q{2RB)piL8Zn00*y^lt%-ZlUl88$fECUK0?+Newy%`+uWjaZT zkwQ|d+-oz}R(X7-$TMI3FNs>d?+}k3_Bu=LKFabw_l5T7E<{={!VExqJdXrp&QDc(CvJWF#swJTB#z@c@0TM!eUbq5n0YIPM=aIncFc*qQ4f53b!%Tj z-SmFGNaP23XsU&FB*t=HnQVF2i*9cyC(=c#zbv8#GSG)uyh{6q5Fu-{l00at+Y3o0 zCzHUvGg>j3M@m8)%X2mS$phrP@=_5c-cdNbZ?xYoek9t2fb9vDB>I|<|A{7f6bg`8 zJ;fJ1s9Y$MG=`@buw6GV@M={|)fr#liN^nw?~nOPe8W*u-Igc$uij<+o8}C8F*U~XIvi%Q zLJWm9VM@WbnX(^py(n>6hViMavM5CjDM&StP>uXLy|%ydXI0B?#9LvmkDf3`ROd)y zjjBS*WvXz}dcs|wNQb{9I@-)0|1Q1l848~?t#B!=sQ6%_Aaegf9KLWV@uA4wryN6J zBMbpAnSXfFLUBX9=mG){6jh;#uE3awLC6pUD&Iqm(Q@~pAN@%|cTv0hw#5n(cr^yJ z+;eY)UaU1dQV#iM!}cF$PIw(y7dCeMm*J5t>Hy`$ihs3B`t9bG+Z~6L*Shq{pmSB| zTtKf~q~9dLm_!#|)gj&3j6c#gZi6iA=l*UXk64=ol}^!%onTZ&-avA`HzjfJK>aMcYcZVg0baYS!zohyH{_X08UNOf{0mNalXeI^702 zn-C1}ZIiW2m^Ixd2F!Tb{@j)T17%~0+HnYU^TUU*Yy;HYIc1!p?%ShXy2fk);+ zE5Z+T1%z43FFZqW#!yy%3wfFs8}}#Nro=`ZBXp;x3uODCwq2o42|HvjX+D?Z85vdX zklxL6Mh}F@AtUc1!Se!3!2zvVTH=%>3ZFAR4UeIC`Rt-$jI_p<*SDUtv5a_Mex&iY zI@9sByuj(Kwf>xim{7&FUqN?HpDJpIJN$Ti=+yPIMeGpLjuQ7HqHn3rY#?JLApllx zx@r?;pKtihkP29rVX3vNV zAaiQ3d%6Owu3#K-9^*JGZSa?$zI2d1%XR4wbx^|#BvF#2=gH=BnN0OYSooGzX}lvQ zZJ^MnxS6XPCb+5XB&}I^>CcvcsM(}h&TNd-IKKkPsJEek_|BQcM+#eN3)8|1c0fc; z+o|ujvBdo1uZH4)M4Cr!I^mSPr>OKpJdu6lFrfAsb3l~+DS&w3#tcl;Wf0*VY>>(= zQ?=Z%L>lHV?oOK}R0>@aH?&G`z%f7q(pxH{Qcj;Zf2$Jx9ozXyQXd9f8JT@HBXvdz z13?v3Rv1UYAQXw=+_9!DozSC2U30Ph(a6QC$a)*^$P;|gSpUN;o>FoQ!f^-3X!Oro zR`?G>-h{Z3r3LLzq{ zXujN*81^rG{;o!4`>e`(yG(7~uO#Gz_l_dWDJpKx-AaQ$p4g5Dz=#CpLq`dKt6Lx0HM%?VXe>@EzX zX2s3}bIz)m4YJoXc93a){@lm8iliT)5@|{c>)Q+nw0tTl44(3R7f_?;|K6`u;6|g^ zHT`+;50NLk^v|qQ{YUSghmG&_WU`4&{wx~iCpLG9mgVye!Ipgf2Vn0f6G;Gi3!mrK6=EOu_-5 zx+uX#S&p&DAx>~ja4l5qSv$P-RFIBN`Wqyqq2Uk7bdFb#d>zXWDc#(oFvyxW|rR}>)zONHl7k3FzhnNsy#orL!iG!BSNXq?TfvMZ^$9;@CMsE|z;**32&Omt8r zaK40*P!ozIORYng>UeL!MgR;xZ_U>47GQaE@!g}0M=Y=V=8kiuvW5fR zoe2R@_G+urpj&>7qnzxpO+eZ_;5M@M!U^z--S@#k?ZHKiyy1O<$DW! zQ8TCtKIQgmknT70^a{fLm{+b@18eDQeouX!SWn$0IMqiEk5gPT!|#|tE}D%JY0dYU zqLZpw)wwdw0gwA`I&@e%gTG$Jl7{uf&QQK8xdv_z1d5a^AA3X?CQi+DuEn>gqGp`N z<8%^do66(e2D0=bl;f&)`@fE=RZ`W0!M{Yq6!rg{ypwfoIu*(8W}oyfPy->G>24V1 z9~jS^2ZC}8uf;mt=<03hl&&|=`L|5Rgh+^BZSU}RxW2jcP+u6l8!4vC$TG;tbIIUW zS%O%TIgw8W`T))!COK>FFbu-Q@DePnAecHZmcYpOxn3u3sPl-=b;f9w7Z5?Jy5_5m>je0Y$ z%eMRsNq%<_0a@(2T=5v3tFK9-(KScVQ7Sq=OI_GMj;3mnH0vUmmj{lfe>HW-X}Z(Z zzl_TQJYx)J+32F19)Ws@2Y6M@d8L^ZG1pv|o{TP!UL0Rb;`*yPH5APSyX|q+XEWuj zx&LJ7{q+ZIf}|YvZ&Mh^D(CadTHaORhHh@RjkJW?b|oB0SaAr;C=k~0?LA`5V#R2? zv_>j%hYa!KWhtLWhVkM^ffOv6&ie+W7ideI^ZIp%L)86tw0{=9DJi6G!^ex22@6g$ z8;|ZOubg99_^?*0(_xwKE(J@1a}pynLzS#Vew!F|#y1)0VXsf{TouU|)O48y*ANn_ ztop6d@0i}s%vk#E7Ik1iw@vM2Fa4(0=kV$ru2JR7d_E&)-Klc8f}ii1K$5|HPrT-S zbf#g;CUk3nzT zc=v%Luxj0prIVKU^RnXnGY>LTqpvLvAjNE+yygwLFi8^V)1NqmJ>gOwaLz@yDEj;- zG;j1?vWM{WlV|IU^qSXQnD3T|C=`TOr`^=ju6XW2GqW&YY}7KWBTOp459JE*y0d;M zpmu#O?1%T{)1(Y|fas2CX=24-V;^7NEVol$-&X$$aW8Av7?57ckU|2L zP6#^oFY_dOHsy5c9$w%u!x1}0%Zscbco=4Lt{9L61!~-8rIu`PqKzbSXuHDRhv>e! zcPL3cPqM{obY#CpO!-J+%nHYJZ{!}wan^euR#4TC_>Cm~?#2rqZbIS!;hGlQ*aQSW z_C^NF1T^#x{$-W&zxegyQJ(0^6i*rAmia30aw!>P-|g*u8svSGo~()+$e4rC{Tz*K z0#oPxB1Jsc_qDV>bWSQaeKJli=sf?^Mwal>O7PtC0d481VsBSRw&MI)0&x46Gl_{V@>L?Qpacad5j}%;lMY~WFqa4ZWX<=vZ$tcI~B!1VS^;cvwI)7 zW(^jEmW&v-~+nlgz5Pi8itY0E;Si)_HTb|_yQ zxs=_6S!;JPbN|SJz6KWEb0fk-$zexX_FsM$`N!{^y)O?>*6g{q<^wIMM|lY@&n?eyMDuTI3Wn&O!a&i>D{#Stq|l*nzU;C~ z>$lGQGbqFG``goFn*P%gL)GNxnuESArO-FiGfzQd=>_<2z(?Osmwtzco@CiSzM3QU zfv|q5K4!J}#Pbv%Zk@N@4gmui@LVJS0bfaCuE<3dyao`hx?G5S;Sl}Yl;)IkTns=s zWL@%@=E>#=kh^wVYM!3m%DPt)su>-gL;1STFL)QJSG-kWH|2TU)4`i{8t(5E6yQyM za_VtEq)K@|;KKCQFhOF9UCTa`I+`hntc%Tgwo>EGeBA=R$aZpL$6DK%@ z2K;Dp)K=P%DFwI3??S_46?gup=!ytofbed8^aD&yaO^R?u4}|@c+?TKQN>@?DPx&c z2jE&q@!A3JgLn4uIuE|dEE6AR$@AX|ZxcP8{3i!J618O*b$k#GDZZ_jtjnZI_Ec}x zS}4b+Oo;nSC9&+gGID8`gFs#f-Zh&?d3!0?QM$RuxzW5WiMF%&ymS2>Gz(H(^`tK# ztYfq#@v_AjVsoNsdPnS5RICf4VKiRZ=>=~OG`whMMHAjgE5dNr+W8~&$VeFUtkCMM%!5g~`Ahgy%wT~Ar>akQ7NL3} zDsK_gqC39v7OL7*XGY(s0C7z8a|1YJW(aa?tF~n;Z(g9Mq(Feu0R3kU6-=-h2n5+? z`V57FqS&b_ps!Q75wv1fF~e{6S2y)b_xDQgI`iz;@DPsbj2YrSWc1I;0F*zT`WsksNElU^PwW-0;ew%~OQPgllr(8Vey92`8 zgdc}}lj{f8cd0Z@G7BMLr(_xJ+02@t5Kuo1F2J$+XT11JZAEdKMW7NfU3)28o4*+P zT}xB#yO}A1v!DK+B%a^0)DNPH zz3%#DLgm073>N}*=iziQjz;A-V9j#I$yPKG(xw(XlmrY{W4(FU&@C9m}(Zlld1~j=H+nZwpZw<^h#mwB3|8qj0qQLJ-mlk!p zqn(~3dRV5&;Jw3Gav$Gt_FN%1fxdUTyW9pj zWh?OXOMCD5i_46^9hzEJA*yDh?l7nG*H*-7n4&mkQfujPK1vX^aSNgYJc|Z+)a=Zm zfwKzjRpWh%shehHU*n!cJ2vF3tN5`d&|_ZN)>}{RA$nW)l8_gM*@8suerC!agENNz z<73MBEx!{7#KflMmFfWZle4pp78$*dQWXS6>o?z>l zaMSBBToXd+rChVmHgm?WDIoCBmG@_B^r8x?%+;UYKnmBBHw?w{%tN-d64pHg06YCM z`ghzfuqzu7T<^uFqU~=#Q0vmZB-ab zobhM|JXn!K^u}{=?~z9{f|7cuUMS{3BL3)^QV)F$ zHa7pb^;%A3oSA|m?uq0ONy&yE|*}2k3@jdjH6qE0d^rBI|wKVU`a5l`85CljeKC5&~veVqZ z`alRF<2v13IB|PiJ!aMqa6gmA-DB%m@`kUjWtmdiQZeTe*i(*K>LO0ZFq<(Hr!{4& z!WKGjv$eN8Ks%L#CPXCdqvcanH6(b@KF`^!v|MDZ&*qXM#qLrw0*~15(npfSrw9g! zRONtqs*|LULSU&k->+!)+y@sxZ7GR!T%7`mgYJ6pw(5HLHMur>g%CJw9 z{bM^Z*}7Ny@rR=UYi+M2-WlJ^0&3WOkWil|o!+mdwdGamQuGMB6ZonU?N4qE!#JJE zLy7!W1o@9gZg`Kr%sAzw)W|lR(B@Q)6wj{IdTh5)q7xi6xtiXye}6`j>i_z9)Egg`Rgy}1c6Am&Q5pL1UDiElWm7-w>YqPN(JnUp#-}Er31+eVJ^Mx2 zwb?bBR9$xFlJ7Jb;%?8xY^z4&G zRB;CetdRpX0BUGqq@RlGjspljbhi78_jx&Wcj?7LMESkaZr|)*>f7k@pxuR$?^G<2 z1LpTuybCw(fyadgE`%MLhm$vF?==n;Rs;QVy1q|3fy67@BXWQ17 zz*;G}+z#~f-)<5J`EMgcMjTMj5Pi*c;V`b>zQ&;L&Pm6 z$rW1R*IZ@o=Jwhkav+B)zI(lYWouSN`JR=3*PJTe)wiA9M=ElFgXIBTyfpY;Rb`E{ z!!-DbvfR;b&dI3!`bzNK!qBD1v;SlVf((`Ki(8gjg6kUR`=7Z|K$LATj+ih|8bCKD z(mQIv)i=ZUI$|4Zbwy_yEq~eqLSbY-9AY2+E5D8bf)?d5UXHk)bq5n5neL`XPgI|; zV6Sp+p9TY~ME-3-ILOQE^Fz#|7ie)?5b9gdilc@+WVK)KoC*7AxK=0#eNI(PdW*jX zH$=!543x*&6*hntT_2j`6?2i-QB--tK~kps7az>50iW?;=e5puRC{7(+% zQ9w}I@%CZ4S@MVo17&o5Yt(%) z!d`;xMjQD7C}aIQU*PE9EXw&%$M*q>2&QXl+c&^K1?!z}j2F zFpoGFr>_37oKT?t+Bd`{FN;AlAN%@j{@_(vn+2n4K(`s?*AH@@yFZ%@49rNbsDRu2 z@_UM|0QX%%`)|kXvnhN)7bcQPe|iOL^+8Gdq2Y`#dEdIIg#e7cjg0NnSrDqNB`Gy7 zS$PeF1q46Wf1vBW#bY^n^Kd^21dZ2p^Q_-706{GgxA+Ko0%4qcD58cu-q5wzchvpr zvKxeaxT{F}6ZcsTZxt;hOm=_u(K7d_x@Ep!!<7zlPl|ATS96LD1o0!}Z&FUr{<2X9 zZOCIDC8B-ICJcfpk(a2eOJo4%+q=uQ{;LJx)?I6CHc9UsTkm`qy;?e-$d~VQo932y*J=hMHiclz9Qfg7~i4&1r|LA1#3o95F~ zlGA(5p3*<&*hjOshwT;@M`)h|lc3v2-R2er%<=@Q!Jwlm*LHkJK$>58-ME5ofAANJ-INBSwS>CSjV;y3Z(##@ zb0*iR=_=WY{ao{ zez)e%)XdyJrlzK=sXlGH_g-u5rN2$MvZ6F95)l#z1VWXSk@x@tK~I4|P?4|Tfh&73 zF0X(CqJxaqXAlS(>*Wt>YRUHj1fl@RO1x8Z&pcT2a?riZqJ1d7zj!RNlTH4aU^6;1 z&}3|5;t*y;AoJ(Fen$~>dm3!&!Hl8|yJGzNQ;sCH_X%?Y!}sP1%q1rrIz}6guN8`% zPT6up)&@+l>*NV)qS*&Eypv3a6WUxHSB_IYPuxq(cNytSsg(QqXipYL^i|qroy!>P zUgS@2XY!Pkd5ZYozms^`>dnPUB}Axs5io%*zKTE+fr1Lyrl|3(UXE0#ng!uuz{X`5 zPy2E{87iYITN;vxaa^=ZH{@6$_Oq?{k`0g?a*lz*BYxL)Mt?FN%Rxcrim8?LJ=AEVvt~) zk(Nm0hs8R$D})?TPq5-p?>VT-d*X7x&h9s~JhGj8_wX|tld6{a2+{?m-+}k;yIzfW zWayLYzBVJqg3~1#KX)WiRt4hbzOF9${tb%}zh7q#XsyJ)zT}%G8q5oRPJfPH1D%3U zsRV;%jwRL$h2D0)eNMoH9NSCs|3EG$k26?^*ttG_xBmNKh5n!=e(zyK33DE(DL&+G%XOu#Zq0{)BHwuPMy zAPnB{hn;{AA?*0F?3j1DHo*U>toAY+H zne4Hpr~(p%cza?u^rR{in=HKYm{d%$_D1vJnqq|GJun#9Z)FkA;bx=facD^+`cJ*q z$L$@nEsfhF>_7I&L*NAB$%VK>%VljsHvI@bK9?8v^MN#*vV!jS#HnJsygfY5YK3N5 zye`a4S0r~$GRV4|2uAKmPZX2fJdU3^#b=hM!1JEf0@+@i3gffh-<(^9;m3AQIqb4T z{C4G4-_Gds;S{zu*br)T%}$Z(uvRObRm1gA{natGja*V@rQXNe@j`5Lw}Xx~aT>pC zRAEo7v)>0ACi69L$(I7FOINTUitdd$VuSGwA|VHx1=Q=N?vOd|_RB@C{lYm5<{ZXb z=4h%JC19v(0%g@QFmYrza3r>GZ(97AL0{2?QlD0Tx0d=#s_UvAXK-BI2_3(n=D{>PKEuDX9aPZ>8(-;s6Ng4`tEMZ zD?Db<5n}-|`@VdH3e~yy>DRW1FJk-U3Ipx|q&VK)3Vris)*V<4feI%5_U9RWVDHU4 zn??tGF03Sqm7E`bx822gSOJq#DB2k#uB!DJZZo#i|NDNS&`xr+lAhZ$iWYvK!mY)_ zL#g;jG+Rkydtk0C#I2q}UgR=`P)&UaZI#dw6KG{u3kQO{pIltk*|4~5D}$iYX0r&R zQ#7*jE5#JXUthD?Cb-aS@8%ECAzh!=*3lfdeHT3+KHk#Xk=F;CCae_CYo()fwCOy) z`?M*c?eCIxmPIFq{Vy(Hu!kEt13-F3cJKC@fLhmHF? z;=afAh4P0`Y_{Gl7cJ$XMn8h2kbnsv1mzDU zl@FCb(`&=iZ(iTOR@48fvCoDl^2rG=csFgUju3}a7U#@ks18L^J-5Wag2+&PYKV|D z4uv5KzQ-~(J#7FbaS64294%uUJ~6zzDXAxIS1DJSew-=s9eai-rGbAQeWn)f#@L00 zr+Jz}X%G(5?bH|!ZVxJdSTAVU@(YB%*Sx-WjedL-_^{>A=O^8#pSz+w8Ipoz(oA^b zwe;f2W;Ci+x=6to;k4iAks>4sgTyR+cjg;4#Vb~N@RgyV!<$>{gij3m56gTc%|+*rJAsOS^@7^deYPVUoWETc*F7( zzLK5j)g0xvQ;uZAG(lkn#IhU_MCa9t(XG(maWvEQya*LuLI zMHh{iM3IZ@XaAN{lC4nWyBDH5A%<(>4C+E>_qrL%D)l715@jeDZ6cdH5S`ePhRl7@ z1e1%`wymAstzPk*gqy_haz4t^Cdz!Fi<2=kl2_{CzCmM}!(a-hh;pj3*n~8>I!&g%Axgr9T6weX>Ml2`S+SDA7uHD^k-F=F+5}hu9 zb2y9n$Nk*CBt;4>#`~=E`|+0gp{5ITMooOHr*1u}+m*lXF2gvd@g-F-h|sAB)4sgn zLz^ACcTn_&HDTAOMai67bTGfmr$-tb1Y;sfV<^$GJ3Hd^*2>~U4n&w~PHDz&$uIm^ z{0R!}51;uc!h|P3FjEZ|>6{b>-gpHIotlcWb|Y;OKdfeF@|hE0kWd!s&e5Jfcq3rt zcy`<%EGaGw%uYxU!tG3UX`vs?M~q8~2$zAr#*I#`u@e5ea&+~|T|&ByAv3LuJ|a-Q zS49FF@dn-(ePxv#q>f1%$=MD!q2Pxj`Hqc1LNLCk^)n2w2pg=rx+GYvyqj=;rYdk@ zOG-z_`d9Y!02Q;Qa1OYq2kuKBCW(j#{IJ@sz9LKUQ5D*SbERnKWN30S9>np>$oA(~ z`n(8loG?*~4TAZE-tbR>aWdb(s`PzT=SKLz=w(=|DJhK=0kHApH$97FUJ3b)P)Cq` zc+6+<%(+H@|AfTE;=EYBt>-YjDiB!p}5;5R#De-F88BJRaQ-ZI8O0t%@N_8^4NC>al9>Gv(;F zGZ3V6fDOHiBj^1x6Xb{draD%{yTBXCMf^FWWH_|IIAlSGmH&gJqxl_HYzR9CuYYoo zNWkayf*s!a!8Av6PpohWMH!JRjc#Y4xZ`wBWNdTP2$eA zzN09%5T#3kOJ7YW7+@t*hh38PPCZWceN~Ex$wvfKOr)*(26iIv%53cOW$5G3);U0A zty=ngd&5_*<+$ech<434<&m{A8ozJ5gh`%GU_(M+^76+P2G&4h=7@@+okgP;4l7o? zN)LG15OLs6BsUK%AFkxkJhW1D_t)XHU3qsZ|AV&@4xJoC9yv)6=_5;aOJTOP%%47akCm0<*-Pojs6~H0LX$@mNULN=`sYMa%oC172G9AQe$1fu0gKK8m)6cyzz#0PY zuVy`xhXL2_mj$8%o}g$F*U^}bdqA9#ll=?o`f!k)QLj6-VD zo5epJ8Xmsat$1wn#TfC1<$)E#j`!96#E%*$IxbnB8DXKs-h6)PL zhVlA_5K9}C2Mnc1x`Z(BrFwyMY*)13-MmnWy@j!n%x+DOM3RX@aD2411UQuwm=m1s zzWQ?#uptt*q@kXFwc9tgehRye=%c@)6Dh$F?%r`$O;aPoTBAT4v`NJ&X`SFf6TH%w*ZS}0$DK`s81QlzU(A2ORQ3O+DOzvD2`0aY)${ie2+AR4kpB)YzV^vvKN&s>{9_YE$Rw!E+m-ouAK4phBH`?S{(P!H|CV=@V82P z2BZ~C=~&L566H0 zqV+ZGk`bWkr(S2L1m`1K(JRbwi6g4UnD`8r&{D03hDTfd2H8-B!)9IZS4<0 z_9}Jmml0IxiPUF{JW~c9ljw4VrnKoQ5=1A77^g{k1`wja^Jc{is1{_Qy;!>tT6lt! zp-D88n*&Fj%xE)uv(K8>$vHhc8C}2NVWdXS&Nda!uB0@by^CN04K;mE#OFogVWFBP zH%G$xDwWuRC-(CE+Ge82!u8LXR*UWg(DL7t@{a@msx!a;@O-x^2B<|(u|-!A!v5#G zjhnbSj^NpOKL`}rA060<*)ul+yYs|DvjR2L{j~KH`@2tE*Hd9cMcb<7mx0}?p|+9m zzePXg*OufmBrL-I4eWR{=X6-N#b>9-u|+$4UB&iQwIu2?znzO?=EstA_f==6Y;x0- z1;kh|HUD5{Lsd7v!NYEQiv5D1@Q`bDjbO-8yS?Kv62aRgxJEw%t*a4wG;$lVl`-@R z4nXOcyFPYQ*s^sFivmoXrcUDWk91RLoj+jqebyfhpY9#_!Bz z-CxS-ql_czoC#-EuLYTzf^F6@@Eb6wu9}FfKfLaly@p4TgIku_eqf=`$PT@@99O0W z-JydlyZ4}M*@W*HP~uexylo3Pr$-$)qK&zz=er1nvfDgZ<+%WTB1nc#t8FK(_ng7D z#o!)Zt1}VJ*^W#3(x(o0L9&KMo{h0qU(Q7p>GAdSNk|H%G+UZ)G1 ziOZyIh4oL3Yfapm%}3alcAu~S3rQP_;GfvOMqIL~qgV}cc$}2kEmUxsoy|3b!(dpM zRCXW8>1jE7$JJC#zrZ264(LmMOo_YAV~Fz|E|hh*uU+PxO;`q@-(&+(PHIo>2A$)< zcS48?-p{**k0y_{){sTr+oxV}0fuj#m8eTuq;yjVO#p`&V*T(GR7GD&K`e#+_#}v-NFK@eio;@62Y;whYc*29Qj|^IJ<@N4M+H6@! zNJCLkn;DqeY~_6G-Ntn){TBQZ@O+jhrm`l(BF+E8nSl%VwA$L*HFk$YfGrwpQ>u{q z{JFm7QhuS?zMH(~u@8$0%dVMNDhMjxvf|J3t^?p)3fG!*r>7?a=J_L9GXiB0!Ur3i zKXo1XDR|<_N*&0JQ5s4Lthve<7>_m<(|Bt1m;P=F{zkbRyjn3=TmbGJ7R{8?e z{ytU3OsvPve7evTRjAk4?gluiDT6bG^v=tXru$idhk^QHFof%8W=UrMc!fUX)T8|AVdXOvT>!yGHApPwKHd^dQZG zU^b#?OB zKbA6GGTG673{PKPa1sIpM({FvXf6ZetSZoA(|?EebKi>tu3}(-UOXK$c*n0xFg59l z2|AkdM)-K?Y$Pcixlo;rEx+O1L+nriGa8=rFi! zq-HQgQo8N+L=@*Vb;>AQEI4`)o)rkwXtb9EF0^&h9cGJAcXszARFm|~Q|yO6z^$M1 zLI;3Cq`?jc->pj2T@@^JtT|_@^-!A^f(qpqjDYw~8jA%p)`W@;#p2`@ky3YH8UN~% z;rGq-Xa9z0SFUE};L*zJW*Y-~Kz9PMVmO4dV4eMEjxX-fX?`BHUL@x|!C#?b@6Zta zdN^-P4sQ@-wPie(1?4nSa-q6YU)tu%lR3OwnpR&sJ;H?Lkbf-#>!^Xi8p(z-HO`g^J zyXE&rG4Wof=Ja%UNQftsP7@AK#(T?b9i#Xvv5k!lfLmd79|&3;FsTD-BP!cVYoSO< z4=welKp9JDe)7l_AFY8HTx0E<rt#VwhqP|GHPmwZM2^@y1@-c#fQM+vZ*8WMl|l zZ3^@hGN9v}T1lu(`ooHlPrfMjbDxos;C95YTkyC6(`M6&4>rhT$aE^T1!r(|^%X6P z`k(n}#bTJzlqTcbIv&k2yqia6hxR30t!wWZ8I4*shT!30S<`y0sHhl9l4wezNa~M+ zqciS{EI)s>t~s{;sO=y%k0g9ApZu+=3do0ODtsu#F;0BdHdP)baobiXAz?#?BWmCLG(FtMWZj_Pa6SckJOhrWG5WUJZ><{%YdUg$2WAotN2> zGg(}&(W6!1LKQDVK@?4yr6{hBYs$d~BncEk`jm0tg2iet3~Ix?g=58XU)9gSM$Vzs zzwEHUK1`pR+Z!3;NlxNQ41zg86XR|ad%gJSKB zarMJPG>Hqw@%Awn>LphUS$OyN zTux`(vH_(=HOi4N3_Df(sxFP|tPFET;nmCz-0wboLm+9UI9U-FVzjrCnZ^q+?W=jR z1Q(t-Z5Grws;r6i54?fOywH*=D)cx-o-$CkrG5rW@0jp7nanw9WCK@LV5`BXiNI)v zVS%(C;90aUvE0f3`XZ@a{C6UBYL^T6fiyscqZLvH4dienwL)YQzLhbc!1vJ0vZX21 zXjeM$lhn-F0K1@LO`sg-=(jk7NTvke2xy|Z&tomSt}zMJ39-~<5-<~n zQ6iV15|`jI#`S-J!+%i$a;T=>DOhjJAMVWqBl%~nj1Vvs8s=?i~(=jh0C z;`P00yXXL8G6{E~V&iGC4j?&x?pq-NN;sZC9{Znnu4S;7B%aCj-?co`Q;AzpXjP<= z@V@4s>R{HIL*~l~vcLWG)6GtF`_TY{w6p@q0<4W)gmO~11xlvx@CQ)a8$HJy8}6o~ zo^ao;*?tPDZdG@#s0)umz{nzyG^Gk#o0fJ2$~N!z4|DKHt@Z!y{X1SftGsfO$6v7+ z#DW1zLN^3aKx{D)sA@`h-1$WO(`7LP)!>N{;>h*a_W(hO+8G3@;6*R5P=JFp-Hw3_ zklNy@+m+bajm!0y-WL-JIA^i?7E($5iKyYqp2HkG?#3#@DxjV=FLF_v6If{JWx$P{ znUA!(`6m{D7YM)YfnGs2#!Bjd_CW_Lr=;F{yBOCJVHjtO3pM3tRRU@GwE%3d)_zcI+SUZKr9@_*$#MdFSF`` zgR@K!&r18^)0$rEh%EXFx{zrFjgYsma)?|1Bf|o*WIxi~=O- zjFz6U+bSu6klVU;Or%a0$rYb1aU+q7PEK(itAqKx6dS+)%s$0xCwVrGE)kkX2p88b z*sKxvgt}cs4m`7tor$lWDeDZPN{D1zZ)1IkElw>Tv%L3=j>*y1?T zQL|Q7fB*+8|Di)Zx5x=16kU7oXz;-nnc}+LLV0H% zaWb(|bQ8wZ_Z*g^YpJFh7GpkA?D=}t-Sq9jD~jt_B?_OGixGdP8}QJYihFhkHt3s# zox_;!CI(V2f}x(rBWb}B3MY&m|62s}R4srRpKj0e1dO)HMa=3jIPXDe;{KQM0s;N) zus(VXsiy>1d370{btTX8?%9i|lP0myK;hnewJh|@Ro;&k_OoHA4+Og_hk;Sti`06G z$ZYj}8SVb>S5}Yl5c{_+^PF^Q=-jpG$T{zlVR9qmEbcawR{Zw^w&)Lhpil9; zJr2ng07>!1=JSpPH>S+>jaT5#ObR2+Qcw0?4jJ_QzWxq2mz)3UW3C$N{QFi89T6}X zYUapVBbG)4KBM;D(*1Q>hw)rh5AeE5N7?C1&n@00UZoN#Xp^~T+9hdv<+y{M-+oLo zzWXZfVR5w*FWi7Xa%+L%=g7GJBF3v$s}G!E-R|`sSV`oOTq|1+%Swa!Bkih03a@cD=`u_7?cVD|a9CWZ#L2ymQl+(W5#@Z@B97SI za_=>Gmo74kQ&8)mqc?G2K#qoX5%J!{FJRNYiE6n9e(;AC@UCj;HY_Mp>gcVGilrvZ zYv(p+r=6d?JRrGOY%7;3Z0H?~{|j>gBsnWP*zVdbG{ya}C6k zhasFWpeQlE3zT)Q>P3r#KSq38^%$JgSdo(HB?mXAx$<41tDa|+Un9;h2dq#lVucVG zq5Y5N@1xuV5hh7zSr3R$1aG5*N9A5OXA(M0w=OxD7jDgwd%SX0(8CSfrvGZtYT=5z zK|0y1I#?o64@}+$47{D;zK6LbrWxcTJTG#eMNX|O^VG;YHhO@~i8CbG5>4tAN zrYhJ(c20`|>Tf6B13tnO;SpfN0+jIho#+l?Pg=|$*A`z4(W6m(k)-|b$TCuOZCef# z!}DXRz<;9YLS294(QSVYi$XB>U8TYxL>Fb*1QM{A7OrqFW-{$*$IM*KgK4T^=Qg=o z%GnrD&1HZY3$~y81YtM-o~HK?gX)q8JlPaqSCX<^B73bw=IEV_+XwpA4fA-&+A9nS~ z)-UK<|2cYxK&_=lv4Cdu9@<<3(~ozP?yf88VTp=TTPtarrc$7th@fSP9_Rzs>BQsF!Ng zi$~Tu8N~qpJLejPCZ@&=7|p&X(v{vRZeqY<^)LK{H~4(m0b^t;=)d!w9vC=Ej&MYK z^JDbUb<^KtLAQ{)a0FbYw-CTKVjPJ?3=MF`jeS%=%fuqJT28Jw2-Y3yZMNaw6L|Y` zahUU;J`biIARaGHV8M&K@_#qXt@P87iBFtl=nKp*{WSm(YcxT}QnHhLl5%Ub4cUq@ z=y?>?C=}lX*V=|1{YJEzj}ED}!ORK)a21wPOjBmfgfY)e=vT?5875wFw{ss04EEpQ zY_FQ7z0j=;k!cFK(hT_kT{z$(CMzyz8|rIBgJ2WFtx$E|E6`J@(Gq~LNwyZb+ykdR zp!e4qAr~aat{^=3JLq;*qu-ir%cCQ8Md)JqcjM2X>QF`>OWpOWf;^4pTX3%~^@zy) zHZBb^p3BVENu1v5O8tfDTJdwrUaOH0m3b>301Fo%lji2J)kLmUft-!?}<1s>q;##GzO+Pz_-WvyOi) zew;Auw?hy2?t2^>P_jA2-D7dQ-y_`6K7h-6BoKtU2C!Xl{sZU|1|s2$*?tJOcazsJ zxugQ}InTd#aYdlO8rgwxIsyGcGO^If2-m$`WN{+T9B0*}{v-!5>DzZVOPt%?51qeJ zz#47}q<@@{fOjd$mr>{Zkai(c9E%1XNLbl{1AgdvOw%vYP7T;f*9^*A@(>ql3i5dX zJ_ZHAu*CZ#3pa|k@>vbKID)+aL=O0hLPYp70Fn|<-oD44K^9`>S-bDnbHC){aBot$ zP${H=w0~C$j?Qj#`W4xCZ+T?9bJL+6Gt<6lJ*(bnw2~v@DJl?&ayb`Qtjm# znC4mg1);c$2&AP!(;>_?4K@L03qP~hNhhhE*JBt9Z%jN_e>V|>s&FO=WuA_Ry)S4s z-@msq`XbRct5zSqso3KZb#`gr;RJVOwUAr3qap@Rpp%3+bjtf#H z&+%1QT}%=h12<7#6ktMB3p38vmNbrtGkh1dWulSqUysv1+oU*NlAZ3yQq#Riu`3|O z3ZAR@4h>KQK17g|E6{$o%dIN_7K{V`3zn)-oV3bg40(v$3o3lp4I0GccNV!X?1#=F z;?<@$CGuRUb8yL$IJcSONT?c`M=~GreOY)2=tb{FK7gr}u|WAJ_T+9hbWDCSFAM-s z3A!v59#rX~DSl$nD^e7`f<7b9Zu9<-XSLB>)!MPxm=gL=oK>Oq;Jw`bUWnPJ7r0zu zUZ<~o=}ydh(%HpDRC(k-H#fWBMTX}jl&QO_QYRmuD&fs*VV$-`GSKv3sC;buC(;*% z_bck3PB_{8Ux48M0;p5~;C1K8y}^qdGOvHxO*w|Pk>j?gaMa<{aLdZ_=ox`xHvtMf z2%aDsUM2y^kf3CYqlNaPmH$GjpJTckrA$v0%k>A~IJ&e!#ykOHT_8!7ZzT*kxN+(* z6>>y;`7jCZf*~LRR8^5@JWd7Iw-r1BHax@%w8AcNzCcn>mn9T<*_l7uh6h11o{|x% z`H{uT1|^_f-d83BOi}S((BQLo|6Z113Xn z{ME+#Uhq#GATMtmw8mE^>gODFjqFiz*IWttJY@5~WoaudEEn(oo=p z8=ZY1h@hg*Va?NIQnbB~q{nGFq_h1uNs`!#8#l*9lg5Y~h#TMfA;R`Wf+N^nFx)#= zx#==h0c%gt?)M>&bEPI)$|w|o#sN}?ExJ{8m7$g_3Bxp4Ylt)-w0=)vJD_&K$n(I; zQ@zU1WL)qxt%u=DA(ynkHYW8$8Q2Q}?*}a`^n7?P1`yF*Fb1ff19`90a11GE6B(KW znLSxkAjO#f`bE5)rq7k{(3F*;nkpVlQCh$l_yR5EalvlY^p7q`vd98PY=c> zU+s>wTS4dm3XU|cz>UNfUXq^8LWhBwNn4RxnZ&Ar4M$jLC?HSo@Q@EkA%g~)-Jl`c zx8i!3B|Xv;cfphUM>Zl4eb%IuJo*+K5=pLjfBV(z6VxXtWn4(Da?LG<{yCe|WtQet z8;V`5v@=cFI{+e=pPvtmk=JpLNeX5okJ@peTL$DaSWhl8-&dYoy-t&Y8pvycrnUj~J%M95)(QJ;t>WF%sOyrlvUYmaybm z{IP40Z#%qizuP{q1O7=H_J1D>gtq&YX_Vkd1o`^*t@7KOCIDUY;XiN5SowpPfiXm!G=XYu7}mmt2V-NcHllmX~GY)Ct!M}oSl#}EN zKM?G6`#&N8smsCxpgCryDYajNbhIbE@z_A2GBqeP#@N9@#u=qdEFjmHiSG{mHRmm`m$_Pf{KzKNj*S<3hMehV(L_5cd^{R17UE=0Hh3bZ!J*FA{L5X zc$x>`z3Oj(Y`l7*{e36KdN|Fxqn!eNJ|y3MBd5!Ca%zZ%IFxV4k5gt@Fd z;3h<_*2GvXUhM-(1NFkZ3Z@8?&7#){Z=w$GnPWt*C-d^-K(yr>XWdFqj|L`lbsU|V zJMGAW&z}j-hz$TN3KGHdfrpI23d)w-WNyngG>VRX@Wt@`w*!y%i<_=(3i6JBz*O>A zLhceD{f}7)+OEWJFZ-2Mv|~=IB2&l($p2ithFyMSUiP~Zne@^sP||pQ$hjYAj<>nZ z?BPmEk}3K|AF)Hgh5kZpg#_5*{w~XrhS4pFQK6hci|m`~ynN+g)XwW_-V1aQh9x$F znyX1a|2{82*wx&KO1SuX`L$`Z})V@JXUAAAjbo$7bIw3#LeTIs+`6%z4J> zbwguG7r)nKp^K6tGb^`v=^qL_Or|1u{mqmj0*x#dX%H+&kH569D*?4dEcLMsgKB)X zNeHt@0OYMtIVyZq^43YT&hP@Ukx{JXMUmgrWF{YS%4n;51XuH88<0;`A6|3r*>wgb zHu@p5fgIX10U%$VNgT+$owzJ-H9m(N9;B(KzeyTha-$@E-As9lCi-;AT0C<87qSG- zz_u6iDssAWbw76x=ydnOVc@70{y*gI2;p0q+V*MBuBITd>OT-9@Q6R!p7gy>i;wlY zY+bx^d5Pg@8Q7gyd=kAr_O$G>lsw*#)HQ26-WZ4# z$OgIb=lP$-aVC{kT0mQ~=;FOdAl2^A2!4pG!ZHNGb^H5;_hMW3K2a>sCO_NpCK;8u z1THTxHJ7HtP3ROOW9q&Est{GMA*k%5mkx28fPe&8Q~6^goNXoZUzn5Nvasgi*sss7 zL*|%Z#pOJp3@!m9>O4@aveMR3F-r4jZD%())r6Ni-q>Cp3ycCV(dwg?Tz%W;#_HEd z0NP>9)>@h$|#B8Zeo$l zJ=dqvIR*@jjcFwEMzas0eEUpTjF@^=XD4d8SKE(0dpzLYi!E#P0%867nw@R8i46Df zROyyWkNk*-iChk#FJ`I_2S$<_y@rsIlom$RUybC18h>3S^eYZD zLnbDY096)q(>`nT-BPl5DI#S0nTbD!wzbWSpmoD~XKy!v=Cm}_-2QS;olQ32KKqz=@&TqASqifd%$B_iAE9p5oVKc6U6&7^GT9Z+5F0gi3=x(WzNj!S5s7Qr_ zwD!I9^DB6|xY0--ow@%8yg?0c`=Dv1L*t@@e>nV6=VcA|q2rxf7b`OpqHQCSI8T7T zA-XlkZg2n$EdXwI*!@6IJb6V;5{@+94>-3#9-Z67+nZ#~f#6gE2?n3Vn1=0Rt;<_( zo^Sd2q~r2LhV=_;_ErJEJ^>36tQ3ymM%WaAQy&}0gb zVG0q;)l7DASWucZ0eX=vLxT}L7^hgATZY7uMk2QMidNhR2w{PT?y5B+Pr@)!QkXcE_ z6NHj64QHVzv}o77!@mb?5<>Cz;ou zZemW6s;d|KK5^0)B@S6|DsMuYY6YOc-~_?Svq$#^c|m-y#pAw-B}Bz3m}?%Or5>>S zwsHM!!viruf@I<%!I^Rp0t;gbrr+Qo!3{+~D`e$Q*os&UyySCJ4gm*_?C~}<&jbT= zH&6vA2EJ@U#{YNccop(sFfija^QBj$*fZL^y>>eN;6SN|b^x?gLyd_lugpSO-9^CP zLIQ!3ii-Vd*ZR80@T=TgH8?hc;-}KpND&_mLk_CEy+Lt-urRz<)+cB3h&j{UZe5}Q z8!RWD0j&2DTz{?p?#mZ>J{ds`f{J~3sA*x7kl^n%DG0ahy?9>3{c;~m#o-K}Fc2{u zpqfVwu_<8yJYp4Rq_*JKj9!%6pHG+#qVFb9cRHSt^QbYI^!vp;dx&y38vCk14`#56){hH(qX9C zJ;h|+C{lpe7HX*ih~NLeo*#yXN=E%&!tC>fhDaa@`ub7m6SX{-3LN2UL^qKOa!POz z?_D`Lpn@ALf#rcJTCg!4!M|4#E84H2ASz*al`hx9{=hkK`87WhB=2Qyp;@gT*zKeg zfgGDO$P#k@Gbr{2lmNsT4fH@0kd8}$62MpjLO)}uL*>&L0ceGt=YGb#e2ia$C(()k z7638j<^KWz7>e{}hi8?W^anszAvgw!LI_Z||rOs<0f)I^|_m8_BZEoz!MB({9JcQ1Z>utxsX+sy~AUof!@rUL(!?Uxt^%Nx@P4nlFll^qAUp+$>HR{7(6&*_3HMb+TWnjP7{{7nalBBVbUd7}m6SAMzPDJqO7YDn{5k=m24Nqkxr9yTF?xLa zB>@fa`_}3Dv-wbHuSuv(k_aw;hJ^TbHWs(nuS?ZG&enWdz)nc~nvpr@D>%hnq3I=d zTb~zes@KVc`?UP2wKV-maSLy-u{9xKT_{4IlmVxr?_7X*llA?`sNBcVl22^{XXGnM z<8Rn?MlT=sGYfdgqlQL5X?zquUXm-PdK+O!>i(naYeuDlZ-JKrrtESbC7OL^NMdtrV>Tmil|L*~hw3lFzSAaV>u1t6#aPGe{M!M zoLux=f^H9QVocwZj_+cYTFAM)M||U>VLk0;hKe^KRYX1<=~t=UZb^>*J7uc=^~fgq z=?#3^A=B{a75%*P_eG!OL?Y6-ebY_+rkwrs4>pr?I}~+^^STLnkEBy)3d7VsRbA>& z8BsJ5T*`-<)TrP13oN$Gy>OODRS|;4(Aug>hZW*z4ozfo95Nz%ywxU-Ghq&iwQe{6u5S-pVm@I!)hRR^QH%4M(p0 z^w2rWit@g%qdK(^VD&BUzF9*!rMxQKwAng~_4I}rn_x9+ZF1x54`|)0Z?w0QvUAcU zMmPVeYQ4)j1!d}m%=uyaX_SYl-Ep>?5A-X73iTVq%>?J0<(guQ+lhLi$;JbzH}|@& za@)r#(_97f*-{?oFxnX{mE+E9+;fth@)INPfn7LZk9gGXT=V_|Rd?RKTa=CcT9a<{ zpOm#sO*=8j5&N&J*wQ9H&6#Q#uRmq(u12!bHj`RzpkiD}B2o34gF$K`{W52Sc!Nw6 zZq!oO6W?6JCG`oruj>Yk^Fjrhkl7ic-6ad!*mlFrhYptnRV7WOs8#F@;Y-hvO{wdRHoW1r=ZRUvbe)Q9pA zfTrlRe#>W>f^=aAW3J&&=oEa`M9QV5sC^xgVlI2)E2>RNhitJx@3Aw*M_KV}fx}pG;&5n`# zR$KS`p?RTfA+IETmm8@djAB->j*j=TIy(%SnVTfgBqb=m#Mc|x+vWMYNj zuUZgjaeKx5o|ex{9}qoFpYYd=_hxE&67px$k%h+vm<~-URYq4w0%4h^SNgK8vBbCn z0a&Q3rZo*PpooD{U4Oi9GS{gSdf#>}BncE>k@D6(_1yCdzOE;~{Rb41vC?Gg{4TBN88^Hs1f7Mtj)Yad684H^g zT}UstCiWPAy=@Nu=UY1GZ)Y#4E+u?f+)fgqU`HmmUe3l>bdkMqR)6Npz?6hBHXrS5 z=M?pm!SJ5@K3QpN*exM?p{y!=d%5{tV`Xn+vg;>n+>_*wGV1^?&O(zQ`6OeP_Dr{D7vf-JQWI`rzr z(8K<*=gq9ho?E4Dok-`m6>m?KD|^P9{dTA!k1WW-uN0?`2D_4b;Z=)m{b`n~Ux4Am z{@E2Vzx=a{%{Td+|2e+oDdWlQH#JmoAKiNc`t8;_Vqp!R&&2q6(3H6{Fu;E#f(H~M za3BB%@p1-q69n>yir@kchW>!P{eQRq12t|$e94ZnL#I5#0os6MB^4#A#0&%fKdfth Aa{vGU literal 0 HcmV?d00001 diff --git a/tutorials/training/source_en/advanced_use/images/data_enhancement_performance_scheme.png b/tutorials/training/source_en/advanced_use/images/data_enhancement_performance_scheme.png new file mode 100644 index 0000000000000000000000000000000000000000..6417031a63dd2bade4902a83934c05aeee6be195 GIT binary patch literal 54529 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 pzKPt;fIFnd3V!7C&)W!=shU6uUSe{iBeX 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 literal 0 HcmV?d00001 diff --git a/tutorials/training/source_en/advanced_use/images/data_loading_performance_scheme.png b/tutorials/training/source_en/advanced_use/images/data_loading_performance_scheme.png new file mode 100644 index 0000000000000000000000000000000000000000..44c84c1f14dee40cdd76926994ab670494abc006 GIT binary patch literal 48509 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 Iy4}nF0uV`T!vFvP literal 0 HcmV?d00001 diff --git a/tutorials/training/source_en/advanced_use/images/shuffle_performance_scheme.png b/tutorials/training/source_en/advanced_use/images/shuffle_performance_scheme.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c72a99fbade41067f9e6dfe6383634d06433a8 GIT binary patch literal 22805 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 literal 0 HcmV?d00001 diff --git a/tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md b/tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md new file mode 100644 index 0000000000..9844a4d539 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md @@ -0,0 +1,387 @@ +# Optimizing the Data Preparation Performance + +`Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Beginner` `Intermediate` `Expert` + + + +- [Optimizing the Data Preparation Performance](#optimizing-the-data-preparation-performance) + - [Overview](#overview) + - [Overall Process](#overall-process) + - [Preparations](#preparations) + - [Importing Modules](#importing-modules) + - [Downloading the Required Dataset](#downloading-the-required-dataset) + - [Optimizing the Data Loading Performance](#optimizing-the-data-loading-performance) + - [Performance Optimization Solution](#performance-optimization-solution) + - [Code Example](#code-example) + - [Optimizing the Shuffle Performance](#optimizing-the-shuffle-performance) + - [Performance Optimization Solution](#performance-optimization-solution-1) + - [Code Example](#code-example-1) + - [Optimizing the Data Augmentation Performance](#optimizing-the-data-augmentation-performance) + - [Performance Optimization Solution](#performance-optimization-solution-2) + - [Code Example](#code-example-2) + - [Performance Optimization Solution Summary](#performance-optimization-solution-summary) + - [Multi-thread Optimization Solution](#multi-thread-optimization-solution) + - [Multi-process Optimization Solution](#multi-process-optimization-solution) + - [Compose Optimization Solution](#compose-optimization-solution) + - [Operator Fusion Optimization Solution](#operator-fusion-optimization-solution) + + + + + +## Overview + +Data is the most important factor of deep learning. Data quality determines the upper limit of deep learning result, whereas model quality enables the result to approach the upper limit.Therefore, high-quality data input is beneficial to the entire deep neural network. During the entire data processing and data augmentation process, data continuously flows through a "pipeline" to the training system, as shown in the following figure: + +![title](./images/pipeline.png) + +MindSpore provides data processing and data augmentation functions for users. In the pipeline process, if each step can be properly used, the data performance will be greatly improved. This section describes how to optimize performance during data loading, data processing, and data augmentation based on the CIFAR-10 dataset. + +## Overall Process +- Prepare data. +- Optimize the data loading performance. +- Optimize the shuffle performance. +- Optimize the data augmentation performance. +- Summarize the performance optimization solution. + +## Preparations + +### Importing Modules + +The `dataset` module provides APIs for loading and processing datasets. + + +```python +import mindspore.dataset as ds +``` + +The `numpy` module is used to generate ndarrays. + + +```python +import numpy as np +``` + +### Downloading the Required Dataset + +1. Create the `./dataset/Cifar10Data` directory in the current working directory. The dataset used for this practice is stored in this directory. +2. Create the `./transform` directory in the current working directory. The dataset generated during the practice is stored in this directory. +3. Download [the CIFAR-10 dataset in binary format](https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz) and decompress the dataset file to the `./dataset/Cifar10Data/cifar-10-batches-bin` directory. The dataset will be used during data loading. +4. Download [the CIFAR-10 Python dataset in file-format](https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz) and decompress the dataset file to the `./dataset/Cifar10Data/cifar-10-batches-py` directory. The dataset will be used for data conversion. + +The directory structure is as follows: + + + dataset/Cifar10Data + ├── cifar-10-batches-bin + │   ├── batches.meta.txt + │   ├── data_batch_1.bin + │   ├── data_batch_2.bin + │   ├── data_batch_3.bin + │   ├── data_batch_4.bin + │   ├── data_batch_5.bin + │   ├── readme.html + │   └── test_batch.bin + └── cifar-10-batches-py + ├── batches.meta + ├── data_batch_1 + ├── data_batch_2 + ├── data_batch_3 + ├── data_batch_4 + ├── data_batch_5 + ├── readme.html + └── test_batch + +In the preceding information: +- The `cifar-10-batches-bin` directory is the directory for storing the CIFAR-10 dataset in binary format. +- The `cifar-10-batches-py` directory is the directory for storing the CIFAR-10 dataset in Python file format. + +## Optimizing the Data Loading Performance + +MindSpore provides multiple data loading methods, including common dataset loading, user-defined dataset loading, and MindSpore data format loading. For details, see [Loading Datasets](https://www.mindspore.cn/tutorial/en/master/use/data_preparation/loading_the_datasets.html). The dataset loading performance varies depending on the underlying implementation method. + +| | Common Dataset | User-defined Dataset | MindRecord Dataset | +| :----: | :----: | :----: | :----: | +| Underlying implementation | C++ | Python | C++ | +| Performance | High | Medium | High | + +### Performance Optimization Solution + +![title](./images/data_loading_performance_scheme.png) + +Suggestions on data loading performance optimization are as follows: +- Built-in loading operators are preferred for supported dataset formats. For details, see [Built-in Loading Operators](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.dataset.html). If the performance cannot meet the requirements, use the multi-thread concurrency solution. For details, see [Multi-thread Optimization Solution](#multi-thread-optimization-solution). +- For a dataset format that is not supported, convert the format to MindSpore data format and then use the `MindDataset` class to load the dataset. For details, see [Converting Datasets into MindSpore Data Format](https://www.mindspore.cn/tutorial/en/master/use/data_preparation/converting_datasets.html). If the performance cannot meet the requirements, use the multi-thread concurrency solution, for details, see [Multi-thread Optimization Solution](#multi-thread-optimization-solution). +- For dataset formats that are not supported, the user-defined `GeneratorDataset` class is preferred for implementing fast algorithm verification. If the performance cannot meet the requirements, the multi-process concurrency solution can be used. For details, see [Multi-process Optimization Solution](#multi-process-optimization-solution). + +### Code Example + +Based on the preceding suggestions of data loading performance optimization, the `Cifar10Dataset` class of built-in loading operators, the `MindDataset` class after data conversion, and the `GeneratorDataset` class are used to load data. The sample code is displayed as follows: + +1. Use the `Cifar10Dataset` class of built-in operators to load the CIFAR-10 dataset in binary format. The multi-thread optimization solution is used for data loading. Four threads are enabled to concurrently complete the task. Finally, a dictionary iterator is created for the data and a data record is read through the iterator. + + + ```python + cifar10_path = "./dataset/Cifar10Data/cifar-10-batches-bin/" + + # create Cifar10Dataset for reading data + cifar10_dataset = ds.Cifar10Dataset(cifar10_path, num_parallel_workers=4) + # create a dictionary iterator and read a data record through the iterator + print(next(cifar10_dataset.create_dict_iterator())) + ``` + + The output is as follows: + ``` + {'image': array([[[235, 235, 235], + [230, 230, 230], + [234, 234, 234], + ..., + [248, 248, 248], + [248, 248, 248], + [249, 249, 249]], + ..., + [120, 120, 119], + [146, 146, 146], + [177, 174, 190]]], dtype=uint8), 'label': array(9, dtype=uint32)} + ``` + +2. Use the `Cifar10ToMR` class to convert the CIFAR-10 dataset into MindSpore data format. In this example, the CIFAR-10 dataset in Python file format is used. Then use the `MindDataset` class to load the dataset in MindSpore data format. The multi-thread optimization solution is used for data loading. Four threads are enabled to concurrently complete the task. Finally, a dictionary iterator is created for data and a data record is read through the iterator. + + + ```python + from mindspore.mindrecord import Cifar10ToMR + + cifar10_path = './dataset/Cifar10Data/cifar-10-batches-py/' + cifar10_mindrecord_path = './transform/cifar10.record' + + cifar10_transformer = Cifar10ToMR(cifar10_path, cifar10_mindrecord_path) + # executes transformation from Cifar10 to MindRecord + cifar10_transformer.transform(['label']) + + # create MindDataset for reading data + cifar10_mind_dataset = ds.MindDataset(dataset_file=cifar10_mindrecord_path, num_parallel_workers=4) + # create a dictionary iterator and read a data record through the iterator + print(next(cifar10_mind_dataset.create_dict_iterator())) + ``` + + The output is as follows: + ``` + {'data': array([255, 216, 255, ..., 63, 255, 217], dtype=uint8), 'id': array(30474, dtype=int64), 'label': array(2, dtype=int64)} + ``` + +3. The `GeneratorDataset` class is used to load the user-defined dataset, and the multi-process optimization solution is used. Four processes are enabled to concurrently complete the task. Finally, a dictionary iterator is created for the data, and a data record is read through the iterator. + + + ```python + def generator_func(num): + for i in range(num): + yield (np.array([i]),) + + # create GeneratorDataset for reading data + dataset = ds.GeneratorDataset(source=generator_func(5), column_names=["data"], num_parallel_workers=4) + # create a dictionary iterator and read a data record through the iterator + print(next(dataset.create_dict_iterator())) + ``` + + The output is as follows: + ``` + {'data': array([0], dtype=int64)} + ``` + +## Optimizing the Shuffle Performance + +The shuffle operation is used to shuffle ordered datasets or repeated datasets. MindSpore provides the `shuffle` function for users. A larger value of `buffer_size` indicates a higher shuffling degree, consuming more time and computing resources. This API allows users to shuffle the data at any time during the entire pipeline process. For details, see [Shuffle Processing](https://www.mindspore.cn/tutorial/en/master/use/data_preparation/data_processing_and_augmentation.html#shuffle). However, because the underlying implementation methods are different, the performance of this method is not as good as that of setting the `shuffle` parameter to directly shuffle data by referring to the [Built-in Loading Operators](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.dataset.html). + +### Performance Optimization Solution + +![title](./images/shuffle_performance_scheme.png) + +Suggestions on shuffle performance optimization are as follows: +- Use the `shuffle` parameter of built-in loading operators to shuffle data. +- If the `shuffle` function is used and the performance still cannot meet the requirements, increase the value of the `buffer_size` parameter to improve the performance. + +### Code Example + +Based on the preceding shuffle performance optimization suggestions, the `shuffle` parameter of the `Cifar10Dataset` class of built-in loading operators and the `Shuffle` function are used to shuffle data. The sample code is displayed as follows: + +1. Use the built-in operator in `Cifar10Dataset` class to load the CIFAR-10 dataset. In this example, the CIFAR-10 dataset in binary format is used, and the `shuffle` parameter is set to True to perform data shuffle. Finally, a dictionary iterator is created for the data and a data record is read through the iterator. + + + ```python + cifar10_path = "./dataset/Cifar10Data/cifar-10-batches-bin/" + + # create Cifar10Dataset for reading data + cifar10_dataset = ds.Cifar10Dataset(cifar10_path, shuffle=True) + # create a dictionary iterator and read a data record through the iterator + print(next(cifar10_dataset.create_dict_iterator())) + ``` + + The output is as follows: + ``` + {'image': array([[[254, 254, 254], + [255, 255, 254], + [255, 255, 254], + ..., + [232, 234, 244], + [226, 230, 242], + [228, 232, 243]], + ..., + [ 64, 61, 63], + [ 63, 58, 60], + [ 61, 56, 58]]], dtype=uint8), 'label': array(9, dtype=uint32)} + ``` + +2. Use the `shuffle` function to shuffle data. Set `buffer_size` to 3 and use the `GeneratorDataset` class to generate data. + + + ```python + def generator_func(): + for i in range(5): + yield (np.array([i, i+1, i+2, i+3, i+4]),) + + ds1 = ds.GeneratorDataset(source=generator_func, column_names=["data"]) + print("before shuffle:") + for data in ds1.create_dict_iterator(): + print(data["data"]) + + ds2 = ds1.shuffle(buffer_size=3) + print("after shuffle:") + for data in ds2.create_dict_iterator(): + print(data["data"]) + ``` + ``` + The output is as follows: + + before shuffle: + [0 1 2 3 4] + [1 2 3 4 5] + [2 3 4 5 6] + [3 4 5 6 7] + [4 5 6 7 8] + after shuffle: + [2 3 4 5 6] + [0 1 2 3 4] + [4 5 6 7 8] + [1 2 3 4 5] + [3 4 5 6 7] + ``` + +## Optimizing the Data Augmentation Performance + +During image classification training, especially when the dataset is small, users can use data augmentation to preprocess images to enrich the dataset. MindSpore provides multiple data augmentation methods, including: +- Use the built-in C operator (`c_transforms` module) to perform data augmentation. +- Use the built-in Python operator (`py_transforms` module) to perform data augmentation. +- Users can define Python functions as needed to perform data augmentation. + +For details, see [Data Augmentation](https://www.mindspore.cn/tutorial/en/master/use/data_preparation/data_processing_and_augmentation.html#id3). The performance varies according to the underlying implementation methods. + +| Module | Underlying API | Description | +| :----: | :----: | :----: | +| c_transforms | C++ (based on OpenCV) | High performance | +| py_transforms | Python (based on PIL) | This module provides multiple image augmentation functions and the method for converting PIL images into NumPy arrays. | + + +### Performance Optimization Solution + +![title](./images/data_enhancement_performance_scheme.png) + + +Suggestions on data augmentation performance optimization are as follows: +- The `c_transforms` module is preferentially used to perform data augmentation for its highest performance. If the performance cannot meet the requirements, refer to [Multi-thread Optimization Solution](#multi-thread-optimization-solution), [Compose Optimization Solution](#compose-optimization-solution), or [Operator Fusion Optimization Solution](#operator-fusion-optimization-solution). +- If the `py_transforms` module is used to perform data augmentation and the performance still cannot meet the requirements, refer to [Multi-thread Optimization Solution](#multi-thread-optimization-solution), [Multi-process Optimization Solution](#multi-process-optimization-solution), [Compose Optimization Solution](#compose-optimization-solution), or [Operator Fusion Optimization Solution](#operator-fusion-optimization-solution). +- The `c_transforms` module maintains buffer management in C++, and the `py_transforms` module maintains buffer management in Python. Because of the performance cost of switching between Python and C++, it is advised not to use different operator types together. +- If the user-defined Python functions are used to perform data augmentation and the performance still cannot meet the requirements, use the [Multi-thread Optimization Solution](#multi-thread-optimization-solution) or [Multi-process Optimization Solution](#multi-process-optimization-solution). If the performance still cannot be improved, in this case, optimize the user-defined Python code. + +### Code Example + +Based on the preceding suggestions of data augmentation performance optimization, the `c_transforms` module and user-defined Python function are used to perform data augmentation. The code is displayed as follows: + +1. The `c_transforms` module is used to perform data augmentation. During data augmentation, the multi-thread optimization solution is used. Four threads are enabled to concurrently complete the task. The operator fusion optimization solution is used and the `RandomResizedCrop` fusion class is used to replace the `RandomResize` and `RandomCrop` classes. + + + ```python + import mindspore.dataset.transforms.c_transforms as c_transforms + import mindspore.dataset.vision.c_transforms as C + import matplotlib.pyplot as plt + cifar10_path = "./dataset/Cifar10Data/cifar-10-batches-bin/" + + # create Cifar10Dataset for reading data + cifar10_dataset = ds.Cifar10Dataset(cifar10_path, num_parallel_workers=4) + transforms = C.RandomResizedCrop((800, 800)) + # apply the transform to the dataset through dataset.map() + cifar10_dataset = cifar10_dataset.map(operations=transforms, input_columns="image", num_parallel_workers=4) + + data = next(cifar10_dataset.create_dict_iterator()) + plt.imshow(data["image"]) + plt.show() + ``` + + The output is as follows: + + ![png](./images/cifar10_c_transforms.png) + + +2. A user-defined Python function is used to perform data augmentation. During data augmentation, the multi-process optimization solution is used, and four processes are enabled to concurrently complete the task. + + + ```python + def generator_func(): + for i in range(5): + yield (np.array([i, i+1, i+2, i+3, i+4]),) + + ds3 = ds.GeneratorDataset(source=generator_func, column_names=["data"]) + print("before map:") + for data in ds3.create_dict_iterator(): + print(data["data"]) + + func = lambda x:x**2 + ds4 = ds3.map(operations=func, input_columns="data", python_multiprocessing=True, num_parallel_workers=4) + print("after map:") + for data in ds4.create_dict_iterator(): + print(data["data"]) + ``` + + The output is as follows: + ``` + before map: + [0 1 2 3 4] + [1 2 3 4 5] + [2 3 4 5 6] + [3 4 5 6 7] + [4 5 6 7 8] + after map: + [ 0 1 4 9 16] + [ 1 4 9 16 25] + [ 4 9 16 25 36] + [ 9 16 25 36 49] + [16 25 36 49 64] + ``` + +## Performance Optimization Solution Summary + +### Multi-thread Optimization Solution + +During the data pipeline process, the number of threads for related operators can be set to improve the concurrency and performance. For example: +- During data loading, the `num_parallel_workers` parameter in the built-in data loading class is used to set the number of threads. +- During data augmentation, the `num_parallel_workers` parameter in the `map` function is used to set the number of threads. +- During batch processing, the `num_parallel_workers` parameter in the `batch` function is used to set the number of threads. + +For details, see [Built-in Loading Operators](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.dataset.html). + +### Multi-process Optimization Solution + +During data processing, operators implemented by Python support the multi-process mode. For example: +- By default, the `GeneratorDataset` class is in multi-process mode. The `num_parallel_workers` parameter indicates the number of enabled processes. The default value is 1. For details, see [Generator Dataset](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.dataset.html#mindspore.dataset.GeneratorDataset) +- If the user-defined Python function or the `py_transforms` module is used to perform data augmentation and the `python_multiprocessing` parameter of the `map` function is set to True, the `num_parallel_workers` parameter indicates the number of processes and the default value of the `python_multiprocessing` parameter is False. In this case, the `num_parallel_workers` parameter indicates the number of threads. For details, see [Built-in Loading Operators](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.dataset.html). + +### Compose Optimization Solution + +Map operators can receive the Tensor operator list and apply all these operators based on a specific sequence. Compared with the Map operator used by each Tensor operator, such Fat Map operators can achieve better performance, as shown in the following figure: + +![title](./images/compose.png) + +### Operator Fusion Optimization Solution + +Some fusion operators are provided to aggregate the functions of two or more operators into one operator. For details, see [Data Augmentation Operators](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.dataset.vision.html). Compared with the pipelines of their components, such fusion operators provide better performance. As shown in the figure: + +![title](./images/operator_fusion.png) diff --git a/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md index d42c89c840..b7408e5837 100644 --- a/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md +++ b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md @@ -1,6 +1,6 @@ # Synchronizing Model Training and Validation -`Ascend` `GPU` `CPU` `Beginner` `Intermediate` `Expert` `Model Export` `Model Training` +`Linux` `Ascend` `GPU` `CPU` `Beginner` `Intermediate` `Expert` `Model Export` `Model Training` diff --git a/tutorials/training/source_en/index.rst b/tutorials/training/source_en/index.rst index cf286fd883..d68ca36465 100644 --- a/tutorials/training/source_en/index.rst +++ b/tutorials/training/source_en/index.rst @@ -31,6 +31,7 @@ MindSpore Tutorials advanced_use/computer_vision_application advanced_use/nlp_application advanced_use/synchronization_training_and_evaluation.md + advanced_use/optimize_the_performance_of_data_preparation.md .. toctree:: :glob: diff --git a/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md index 94250841f2..9a159b0529 100644 --- a/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md @@ -1,6 +1,6 @@ # 自动数据增强 -`Ascend` `GPU` `CPU` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/cache.md b/tutorials/training/source_zh_cn/advanced_use/cache.md index 2039720a55..9268187593 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cache.md +++ b/tutorials/training/source_zh_cn/advanced_use/cache.md @@ -1,6 +1,6 @@ # 单节点缓存 -`Ascend` `GPU` `CPU` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md b/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md index 4a54e92841..c00a1d9efd 100644 --- a/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md +++ b/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md @@ -9,11 +9,11 @@ - [图像分类](#图像分类) - [任务描述及准备](#任务描述及准备) - [下载CIFAR-10数据集](#下载cifar-10数据集) - - [数据预加载和预处理](#数据预加载和预处理) - - [定义卷积神经网络](#定义卷积神经网络) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [调用`Model`高阶API进行训练和保存模型文件](#调用model高阶api进行训练和保存模型文件) - - [加载保存的模型,并进行验证](#加载保存的模型并进行验证) + - [数据预加载和预处理](#数据预加载和预处理) + - [定义卷积神经网络](#定义卷积神经网络) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [调用`Model`高阶API进行训练和保存模型文件](#调用model高阶api进行训练和保存模型文件) + - [加载保存的模型,并进行验证](#加载保存的模型并进行验证) - [参考文献](#参考文献) diff --git a/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md b/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md index 141b82df3c..4f3edad004 100644 --- a/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md +++ b/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md @@ -1,6 +1,6 @@ # 数据处理性能调试 -`Ascend` `GPU` `CPU` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md b/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md index f4f4e73e2f..d0f3e06d79 100644 --- a/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md +++ b/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md @@ -1,6 +1,6 @@ # MindSpore数据格式转换 -`Ascend` `GPU` `CPU` `初级` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `初级` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md b/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md index 93436976f5..af2717f74c 100644 --- a/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md +++ b/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md @@ -1,5 +1,5 @@ # 深度概率编程 -`Ascend` `GPU` `全流程` `初级` `中级` `高级` +`Linux` `Ascend` `GPU` `全流程` `初级` `中级` `高级` @@ -39,7 +39,7 @@ MindSpore深度概率编程(MindSpore Deep Probabilistic Programming, MDP) 本例子使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 #### 定义贝叶斯神经网络 -本例子使用的是贝叶斯LeNet。利用bnn_layers构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,bnn_layers和普通的神经网络层可以互相组合。 +本例子使用的是贝叶斯LeNet。利用`bnn_layers`构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,`bnn_layers`和普通的神经网络层可以互相组合。 ``` import mindspore.nn as nn @@ -89,8 +89,8 @@ class BNNLeNet5(nn.Cell): ``` #### 定义损失函数和优化器 接下来需要定义损失函数(Loss)和优化器(Optimizer)。损失函数是深度学习的训练目标,也叫目标函数,可以理解为神经网络的输出(Logits)和标签(Labels)之间的距离,是一个标量数据。 -常见的损失函数包括均方误差、L2损失、Hinge损失、交叉熵等等。图像分类应用通常采用交叉熵损失(CrossEntropy)。 -优化器用于神经网络求解(训练)。由于神经网络参数规模庞大,无法直接求解,因而深度学习中采用随机梯度下降算法(SGD)及其改进算法进行求解。MindSpore封装了常见的优化器,如SGD、Adam、Momemtum等等。本例采用Adam优化器,通常需要设定两个参数,学习率(learnin _rate)和权重衰减项(weight decay)。 +常见的损失函数包括均方误差、L2损失、Hinge损失、交叉熵等等。图像分类应用通常采用交叉熵损失(`CrossEntropy`)。 +优化器用于神经网络求解(训练)。由于神经网络参数规模庞大,无法直接求解,因而深度学习中采用随机梯度下降算法(SGD)及其改进算法进行求解。MindSpore封装了常见的优化器,如`SGD`、`Adam`、`Momemtum`等等。本例采用`Adam`优化器,通常需要设定两个参数,学习率(`learnin _rate`)和权重衰减项(`weight decay`)。 MindSpore中定义损失函数和优化器的代码样例如下: ``` @@ -198,7 +198,7 @@ decoder = Decoder() vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) ``` ### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用的损失函数是ELBO,ELBO是变分推断专用的损失函数;本例使用的优化器是Adam。 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用的损失函数是`ELBO`,`ELBO`是变分推断专用的损失函数;本例使用的优化器是`Adam`。 MindSpore中定义损失函数和优化器的代码样例如下: ``` @@ -307,7 +307,7 @@ class LeNet5(nn.Cell): return x ``` #### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,Adam作为优化器。 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,`Adam`作为优化器。 ``` network = LeNet5() @@ -403,7 +403,7 @@ train_bnn_network = bnn_transformer.transform_to_bnn_model() ### 不确定性估计 不确定性估计工具箱基于MindSpore Deep probability Programming (MDP),适用于主流的深度学习模型,如回归、分类、目标检测等。在推理阶段,利用不确定性估计工具箱,开发人员只需通过训练模型和训练数据集,指定需要估计的任务和样本,即可得到任意不确定性(aleatoric uncertainty)和认知不确定性(epistemic uncertainty)。基于不确定性信息,开发人员可以更好地理解模型和数据集。 -以分类任务为例,本例中使用的模型是LeNet,数据集为MNist,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。为了评估测试示例的不确定性,使用工具箱的方法如下: +以分类任务为例,本例中使用的模型是LeNet,数据集为MNIST,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。为了评估测试示例的不确定性,使用工具箱的方法如下: ``` from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation diff --git a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md index bc6327d561..0be1d8efee 100644 --- a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md @@ -1,6 +1,6 @@ ## 使用MindSpore Hub提交、加载和微调模型 -`Ascend` `GPU` `MindSpore Hub` `模型上传` `模型加载` `模型微调` `初级` `中级` `高级` +`Linux` `Ascend` `GPU` `MindSpore Hub` `模型上传` `模型加载` `模型微调` `初级` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/membership_inference.md b/tutorials/training/source_zh_cn/advanced_use/membership_inference.md index c54935a650..4f887583fb 100644 --- a/tutorials/training/source_zh_cn/advanced_use/membership_inference.md +++ b/tutorials/training/source_zh_cn/advanced_use/membership_inference.md @@ -1,5 +1,7 @@ # 成员推理攻击 +`Linux` `Ascend` `全流程` `初级` `中级` `高级` + - [成员推理攻击](#成员推理攻击) diff --git a/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md b/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md index 3822551830..c24653f644 100644 --- a/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md +++ b/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md @@ -1,5 +1,6 @@ # MobileNetV2 增量学习 -`Linux` `CPU` `Ascend` `GPU` `模型开发` `中级` `高级` + +`Linux` `Windows` `CPU` `Ascend` `GPU` `模型开发` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md b/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md index 604349df91..5661595f88 100644 --- a/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md +++ b/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md @@ -1,6 +1,6 @@ # 模型脚本迁移 -`Ascend` `模型开发` `初级` `Linux` +`Linux` `Ascend` `模型开发` `初级` `Linux` diff --git a/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md b/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md index 83125c64b7..4cb2224235 100644 --- a/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md +++ b/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md @@ -27,8 +27,8 @@ -   - +   + ## 概述 @@ -127,7 +127,7 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 cifar10_path = "./dataset/Cifar10Data/cifar-10-batches-bin/" # create Cifar10Dataset for reading data - cifar10_dataset = ds.Cifar10Dataset(cifar10_path,num_parallel_workers=4) + cifar10_dataset = ds.Cifar10Dataset(cifar10_path, num_parallel_workers=4) # create a dictionary iterator and read a data record through the iterator print(next(cifar10_dataset.create_dict_iterator())) ``` @@ -156,12 +156,12 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 cifar10_path = './dataset/Cifar10Data/cifar-10-batches-py/' cifar10_mindrecord_path = './transform/cifar10.record' - cifar10_transformer = Cifar10ToMR(cifar10_path,cifar10_mindrecord_path) + cifar10_transformer = Cifar10ToMR(cifar10_path, cifar10_mindrecord_path) # executes transformation from Cifar10 to MindRecord cifar10_transformer.transform(['label']) # create MindDataset for reading data - cifar10_mind_dataset = ds.MindDataset(dataset_file=cifar10_mindrecord_path,num_parallel_workers=4) + cifar10_mind_dataset = ds.MindDataset(dataset_file=cifar10_mindrecord_path, num_parallel_workers=4) # create a dictionary iterator and read a data record through the iterator print(next(cifar10_mind_dataset.create_dict_iterator())) ``` @@ -180,7 +180,7 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 yield (np.array([i]),) # create GeneratorDataset for reading data - dataset = ds.GeneratorDataset(source=generator_func(5),column_names=["data"],num_parallel_workers=4) + dataset = ds.GeneratorDataset(source=generator_func(5), column_names=["data"], num_parallel_workers=4) # create a dictionary iterator and read a data record through the iterator print(next(dataset.create_dict_iterator())) ``` @@ -213,7 +213,7 @@ shuffle性能优化建议如下: cifar10_path = "./dataset/Cifar10Data/cifar-10-batches-bin/" # create Cifar10Dataset for reading data - cifar10_dataset = ds.Cifar10Dataset(cifar10_path,shuffle=True) + cifar10_dataset = ds.Cifar10Dataset(cifar10_path, shuffle=True) # create a dictionary iterator and read a data record through the iterator print(next(cifar10_dataset.create_dict_iterator())) ``` @@ -239,9 +239,9 @@ shuffle性能优化建议如下: ```python def generator_func(): for i in range(5): - yield (np.array([i,i+1,i+2,i+3,i+4]),) + yield (np.array([i, i+1, i+2, i+3, i+4]),) - ds1 = ds.GeneratorDataset(source=generator_func,column_names=["data"]) + ds1 = ds.GeneratorDataset(source=generator_func, column_names=["data"]) print("before shuffle:") for data in ds1.create_dict_iterator(): print(data["data"]) @@ -308,7 +308,7 @@ shuffle性能优化建议如下: cifar10_path = "./dataset/Cifar10Data/cifar-10-batches-bin/" # create Cifar10Dataset for reading data - cifar10_dataset = ds.Cifar10Dataset(cifar10_path,num_parallel_workers=4) + cifar10_dataset = ds.Cifar10Dataset(cifar10_path, num_parallel_workers=4) transforms = C.RandomResizedCrop((800,800)) # apply the transform to the dataset through dataset.map() cifar10_dataset = cifar10_dataset.map(operations=transforms, input_columns="image", num_parallel_workers=4) @@ -329,15 +329,15 @@ shuffle性能优化建议如下: ```python def generator_func(): for i in range(5): - yield (np.array([i,i+1,i+2,i+3,i+4]),) + yield (np.array([i, i+1, i+2, i+3, i+4]),) - ds3 = ds.GeneratorDataset(source=generator_func,column_names=["data"]) + ds3 = ds.GeneratorDataset(source=generator_func, column_names=["data"]) print("before map:") for data in ds3.create_dict_iterator(): print(data["data"]) func = lambda x:x**2 - ds4 = ds3.map(operations=func, input_columns="data", python_multiprocessing=True,num_parallel_workers=4) + ds4 = ds3.map(operations=func, input_columns="data", python_multiprocessing=True, num_parallel_workers=4) print("after map:") for data in ds4.create_dict_iterator(): print(data["data"]) diff --git a/tutorials/training/source_zh_cn/use/image_loading.md b/tutorials/training/source_zh_cn/use/image_loading.md index be239acfd1..db5545aeb2 100644 --- a/tutorials/training/source_zh_cn/use/image_loading.md +++ b/tutorials/training/source_zh_cn/use/image_loading.md @@ -1,6 +1,6 @@ # 加载图像 -`Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/use/text_loading.md b/tutorials/training/source_zh_cn/use/text_loading.md index 76f8109e0e..340d2c0828 100644 --- a/tutorials/training/source_zh_cn/use/text_loading.md +++ b/tutorials/training/source_zh_cn/use/text_loading.md @@ -1,6 +1,6 @@ # 加载文本 -`Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` -- Gitee From 04de5be43a0eb58d6be327ce8bae723b71576c21 Mon Sep 17 00:00:00 2001 From: yingchen Date: Tue, 15 Sep 2020 14:51:05 +0800 Subject: [PATCH 023/100] update SMTandV1.0 --- .../advanced_use/synchronization_training_and_evaluation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md index d42c89c840..193c6f9f11 100644 --- a/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md +++ b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md @@ -32,7 +32,7 @@ Implementation idea: The model accuracy is validated every n epochs. The model a Core implementation: Validation points are set in `epoch_end` of the callback function as follows: -`cur_epoch % eval_per_epoch == 0`: indicates that the model accuracy is validated every `eval_per_epoch` epochs. +`cur_epoch % eval_per_epoch == 0`: indicates that the model accuracy is validated every `eval_per_epoch` epoch. - `cur_epoch`: indicates epoch value in the current training process. - `eval_per_epoch`: indicates user-defined value, that is, the validation frequency. @@ -40,7 +40,7 @@ Core implementation: Validation points are set in `epoch_end` of the callback fu Other parameters are described as follows: - `model`: indicates `Model` function in MindSpore. -- `eval_dataset`: indicates validation dataset. +- `eval_dataset`: indicates the validation dataset. - `epoch_per_eval`: records the accuracy of the validation model and the corresponding number of epochs. The data format is `{"epoch": [], "acc": []}`. ```python @@ -75,7 +75,7 @@ The parameters are described as follows: - `keep_checkpoint_max`: indicates the maximum number of models that can be saved. - `ckpoint_cb`: defines the name and path for saving the model. - `model`: defines a model. -- `model.train`: indicates model training function. +- `model.train`: indicates the model training function. - `epoch_per_eval`: defines the number for collecting `epoch` and the dictionary of corresponding model accuracy information. ```python -- Gitee From 4f308b3b2136f32c45da3896cb4faee070cb2f02 Mon Sep 17 00:00:00 2001 From: liuxiao78 Date: Tue, 15 Sep 2020 16:11:03 +0800 Subject: [PATCH 024/100] add r0.1 post training quantization --- .../use/post_training_quantization.md | 110 +++++++++++++----- 1 file changed, 84 insertions(+), 26 deletions(-) diff --git a/tutorials/lite/source_zh_cn/use/post_training_quantization.md b/tutorials/lite/source_zh_cn/use/post_training_quantization.md index 839a7347ac..921b60211e 100644 --- a/tutorials/lite/source_zh_cn/use/post_training_quantization.md +++ b/tutorials/lite/source_zh_cn/use/post_training_quantization.md @@ -4,9 +4,15 @@ - [训练后量化](#训练后量化) - [概述](#概述) - - [使用示例](#使用示例) - - [部分模型精度结果](#部分模型精度结果) - - [参数说明](#参数说明) + - [权重量化](#权重量化) + - [参数说明](#参数说明) + - [使用步骤](#使用步骤) + - [部分模型精度结果](#部分模型精度结果) + - [全量化](#全量化) + - [参数说明](#参数说明-1) + - [使用步骤](#使用步骤-1) + - [部分模型精度结果](#部分模型精度结果-1) + @@ -14,14 +20,83 @@ ## 概述 -对于已经训练好的`float32`模型,通过训练后量化将模型转为`int8`模型,不仅能减小模型大小,而且能显著提高推理性能。在MindSpore端侧框架中,这部分功能集成在模型转换工具`conveter_lite`中,通过增加命令行参数,便能够转换得到量化后模型。 +对于已经训练好的`float32`模型,通过训练后量化将其转为`int8`,不仅能减小模型大小,而且能显著提高推理性能。在MindSpore Lite中,这部分功能集成在模型转换工具`conveter_lite`内,通过增加命令行参数,便能够转换得到量化后模型。 目前训练后量化属于alpha阶段(支持部分网络,不支持多输入模型),正在持续完善中。 +MindSpore Lite训练后量化分为两类: +1. 权重量化:单独对模型的权值进行量化; +2. 全量化:对模型的权值、激活值、bias值统一进行量化。 + +训练后量化在两种情况下所需的数据类型和参数设定不同,但均可通过转换工具设定。有关转换工具`converter_lite`的使用方法可参考[转换为MindSpore Lite模型](https://www.mindspore.cn/lite/tutorial/zh-CN/master/use/converter_tool.html)。在此基础之上进行配置,启用训练后量化。 + +## 权重量化 + +下面对权重量化的使用方式和效果进行阐述。 + +### 参数说明 + +权重量化转换命令的一般形式为: +``` +./converter_lite --fmk=ModelType --modelFile=ModelFilePath --outputFile=ConvertedModelPath --quantType=WeightQuant --bitNum=BitNumValue --quantSize=QuantizationSizeThresholdValue --convWeightQuantChannelThreshold=ConvWeightQuantChannelThresholdValue +``` +下面对此命令的量化相关参数进行说明: + +| 参数 | 属性 | 功能描述 | 参数类型 | 默认值 | 取值范围 | +| -------- | ------- | ----- | ----- |----- | ----- | +| `--quantType=` | 必选 | 设置为WeightQuant,启用权重量化 | String | - | 必须设置为WeightQuant | +| `--bitNum=` | 可选 | 设定权重量化的比特数,目前仅支持8bit量化 | Integer | 8 | 8 | +| `--quantSize=` | 可选 | 设定参与权重量化的卷积核尺寸阈值,若卷积核尺寸大于该值,则对此权重进行量化;建议设置为500 | Integer | 0 | (0,+∞) | +| `--convWeightQuantChannelThreshold=` | 可选 | 设定参与权重量化的卷积通道数阈值,若卷积通道数大于该值,则对此权重进行量化;建议设置为16 | Integer | 16 | (0,+∞) | + +用户可根据模型及自身需要对权重量化的参数作出调整。 + + +### 使用步骤 + +1. 正确编译出`converter_lite`可执行文件。该部分可参考构建文档[编译MindSpore Lite](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html),获得`converter_lite`工具,并配置环境变量。 +2. 以TensorFlow Lite模型为例,执行权重量化模型转换命令: + ``` + ./converter_lite --fmk=TFLITE --modelFile=Inception_v3.tflite --outputFile=Inception_v3.tflite --quantType=WeightQuant --bitNum=8 --quantSize=0 --convWeightQuantChannelThreshold=0 + ``` +3. 上述命令执行成功后,便可得到量化后的模型`Inception_v3.tflite.ms`,量化后的模型大小通常会下降到FP32模型的1/4。 + +### 部分模型精度结果 + + | 模型 | 测试数据集 | FP32模型精度 | 权重量化精度 | + | -------- | ------- | ----- | ----- | + | [Inception_V3](https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz) | [ImageNet](http://image-net.org/) | 77.92% | - | + | [Mobilenet_V1_1.0_224](https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz) | [ImageNet](http://image-net.org/) | 70.96% | - | + +> 以上所有结果均在x86环境上测得。 + +## 全量化 + +下面对全量化的使用方式和效果进行阐述。 + +### 参数说明 + +全量化转换命令的一般形式为: ``` ./converter_lite --fmk=ModelType --modelFile=ModelFilePath --outputFile=ConvertedModelPath --quantType=PostTraining --config_file=config.cfg ``` +下面对此命令的量化相关参数进行说明: + +| 参数 | 属性 | 功能描述 | 参数类型 | 默认值 | 取值范围 | +| -------- | ------- | ----- | ----- |----- | ----- | +| `--quantType=` | 必选 | 设置为PostTraining,启用全量化 | String | - | 必须设置为PostTraining | +| `--config_file=` | 必选 | 校准数据集配置文件路径 | String | - | - | + +为了计算激活值的量化参数,用户需要提供校准数据集。校准数据集最好来自真实推理场景,能表征模型的实际输入情况,数量在100个左右。 +校准数据集配置文件采用`key=value`的方式定义相关参数,需要配置的`key`如下: + +| 参数名 | 属性 | 功能描述 | 参数类型 | 默认值 | 取值范围 | +| -------- | ------- | ----- | ----- | ----- | ----- | +| image_path | 必选 | 存放校准数据集的目录 | String | - | 该目录存放可直接用于执行推理的输入数据。由于目前框架还不支持数据预处理,所有数据必须事先完成所需的转换,使得它们满足推理的输入要求。 | +| batch_count | 可选 | 使用的输入数目 | Integer | 100 | (0,+∞) | +| method_x | 可选 | 网络层输入输出数据量化算法 | String | KL | KL,MAX_MIN。 KL: 基于[KL散度](http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf)对数据范围作量化校准; MAX_MIN:基于最大值、最小值计算数据的量化参数。 在模型以及数据集比较较简单的情况下,推荐使用MAX_MIN | +| thread_num | 可选 | 使用校准数据集执行推理流程时的线程数 | Integer | 1 | (0,+∞) | -## 使用示例 +### 使用步骤 1. 正确编译出`converter_lite`可执行文件。 2. 准备校准数据集,假设存放在`/dir/images`目录,编写配置文件`config.cfg`,内容如下: @@ -32,34 +107,17 @@ thread_num=1 ``` 校准数据集可以选择测试数据集的子集,要求`/dir/images`目录下存放的每个文件均是预处理好的输入数据,每个文件都可以直接用于推理的输入。 -3. 以MindSpore模型为例,执行带训练后量化的模型转换命令: +3. 以MindSpore模型为例,执行全量化的模型转换命令: ``` ./converter_lite --fmk=MS --modelFile=lenet.ms --outputFile=lenet_quant --quantType=PostTraining --config_file=config.cfg ``` -4. 上述命令执行成功后,便可得到量化后的模型lenet_quant.ms,通常量化后的模型大小会下降到FP32模型的1/4。 +4. 上述命令执行成功后,便可得到量化后的模型`lenet_quant.ms`,通常量化后的模型大小会下降到FP32模型的1/4。 -## 部分模型精度结果 +### 部分模型精度结果 - | 模型 | 测试数据集 | method_x | FP32模型精度 | 训练后量化精度 | 说明 | + | 模型 | 测试数据集 | method_x | FP32模型精度 | 全量化精度 | 说明 | | -------- | ------- | ----- | ----- | ----- | ----- | | [Inception_V3](https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz) | [ImageNet](http://image-net.org/) | KL | 77.92% | 77.95% | 校准数据集随机选择ImageNet Validation数据集中的100张 | | [Mobilenet_V1_1.0_224](https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz) | [ImageNet](http://image-net.org/) | KL | 70.96% | 70.69% | 校准数据集随机选择ImageNet Validation数据集中的100张 | > 以上所有结果均在x86环境上测得。 - -## 参数说明 - -| 参数 | 属性 | 功能描述 | 参数类型 | 默认值 | 取值范围 | -| -------- | ------- | ----- | ----- |----- | ----- | -| --quantType | 必选 | 设置为PostTraining,启用训练后量化 | String | - | 必须设置为PostTraining | -| --config_file | 必选 | 校准数据集配置文件路径 | String | - | - | - -为了计算激活值的量化参数,用户需要提供校准数据集。校准数据集最好来自真实推理场景,能表征模型的实际输入情况,数量在100个左右。 -校准数据集配置文件采用`key=value`的方式定义相关参数,需要配置的`key`如下: - -| 参数名 | 属性 | 功能描述 | 参数类型 | 默认值 | 取值范围 | -| -------- | ------- | ----- | ----- | ----- | ----- | -| image_path | 必选 | 存放校准数据集的目录 | String | - | 该目录存放可直接用于执行推理的输入数据。由于目前框架还不支持数据预处理,所有数据必须事先完成所需的转换,使得它们满足推理的输入要求。 | -| batch_count | 可选 | 使用的输入数目 | Integer | 100 | 大于0 | -| method_x | 可选 | 网络层输入输出数据量化算法 | String | KL | KL,MAX_MIN。 KL: 基于[KL散度](http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf)对数据范围作量化校准; MAX_MIN:基于最大值、最小值计算数据的量化参数。 在模型以及数据集比较较简单的情况下,推荐使用MAX_MIN | -| thread_num | 可选 | 使用校准数据集执行推理流程时的线程数 | Integer | 1 | 大于0 | \ No newline at end of file -- Gitee From ee6630f7feeda72b9075c53f4e4856a9896ca409 Mon Sep 17 00:00:00 2001 From: meng_chunyang Date: Tue, 15 Sep 2020 15:51:30 +0800 Subject: [PATCH 025/100] update docs of benchmark & timeprofiler tools --- tutorials/lite/source_en/build.md | 12 ++++++------ tutorials/lite/source_en/use/benchmark_tool.md | 9 ++++----- tutorials/lite/source_en/use/timeprofiler_tool.md | 8 ++++---- tutorials/lite/source_zh_cn/build.md | 14 +++++++------- tutorials/lite/source_zh_cn/use/benchmark_tool.md | 9 ++++----- .../lite/source_zh_cn/use/timeprofiler_tool.md | 8 ++++---- 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/tutorials/lite/source_en/build.md b/tutorials/lite/source_en/build.md index b33d449665..f482934a0f 100644 --- a/tutorials/lite/source_en/build.md +++ b/tutorials/lite/source_en/build.md @@ -22,7 +22,7 @@ This chapter introduces how to quickly compile MindSpore Lite, which includes th | converter | Linux | Model Conversion Tool | | runtime | Linux、Android | Model Inference Framework | | benchmark | Linux、Android | Benchmarking Tool | -| time_profiler | Linux、Android | Performance Analysis Tool | +| timeprofiler | Linux、Android | Performance Analysis Tool | ## Linux Environment Compilation @@ -30,7 +30,7 @@ This chapter introduces how to quickly compile MindSpore Lite, which includes th - The compilation environment supports Linux x86_64 only. Ubuntu 18.04.02 LTS is recommended. -- Compilation dependencies of runtime、benchmark and time_profiler: +- Compilation dependencies of runtime、benchmark and timeprofiler: - [CMake](https://cmake.org/download/) >= 3.14.1 - [GCC](https://gcc.gnu.org/releases.html) >= 7.3.0 - [Android_NDK r20b](https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip) @@ -142,7 +142,7 @@ The inference framework can be obtained under `-I x86_64`, `-I arm64` and `-I ar │ └── third_party # Header files and libraries of third party libraries │ ├── flatbuffers # Header files of FlatBuffers │ └── include # Header files of inference framework - │ └── time_profile # Model network layer time-consuming analysis tool + │ └── time_profiler # Model network layer time-consuming analysis tool ``` @@ -157,7 +157,7 @@ The inference framework can be obtained under `-I x86_64`, `-I arm64` and `-I ar │ └── third_party # Header files and libraries of third party libraries │ ├── flatbuffers # Header files of FlatBuffers │ └── include # Header files of inference framework - │ └── time_profile # Model network layer time-consuming analysis tool + │ └── time_profiler # Model network layer time-consuming analysis tool ``` @@ -171,10 +171,10 @@ The inference framework can be obtained under `-I x86_64`, `-I arm64` and `-I ar │ └── third_party # Header files and libraries of third party libraries │ ├── flatbuffers # Header files of FlatBuffers │ └── include # Header files of inference framework - │ └── time_profile # Model network layer time-consuming analysis tool + │ └── time_profiler # Model network layer time-consuming analysis tool ``` > 1. `liboptimize.so` only exists in the output package of runtime-arm64 and is only used on ARMv8.2 and CPUs that support fp16. > 2. Compile ARM64 to get the inference framework output of arm64-cpu by default, if you add `-e gpu`, you will get the inference framework output of arm64-gpu, and the package name is `mindspore-lite-{version}-runtime-arm64-gpu.tar.gz`, compiling ARM32 is in the same way. -> 3. Before running the tools in the converter, benchmark or time_profile directory, you need to configure environment variables, and configure the path where the dynamic libraries of MindSpore Lite and Protobuf are located to the path where the system searches for dynamic libraries. Take the compiled under version 0.7.0-beta as an example: configure converter: `export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`; configure benchmark and timeprofiler: `export LD_LIBRARY_PATH= ./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`. +> 3. Before running the tools in the converter, benchmark or time_profiler directory, you need to configure environment variables, and configure the path where the dynamic libraries of MindSpore Lite and Protobuf are located to the path where the system searches for dynamic libraries. Take the compiled under version 0.7.0-beta as an example: configure converter: `export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`; configure benchmark and timeprofiler: `export LD_LIBRARY_PATH= ./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`. diff --git a/tutorials/lite/source_en/use/benchmark_tool.md b/tutorials/lite/source_en/use/benchmark_tool.md index d6b3a09ae8..000e270c60 100644 --- a/tutorials/lite/source_en/use/benchmark_tool.md +++ b/tutorials/lite/source_en/use/benchmark_tool.md @@ -76,11 +76,10 @@ The command used for benchmark testing based on the compiled Benchmark tool is a ```bash ./benchmark [--modelPath=] [--accuracyThreshold=] - [--calibDataPath=] [--cpuBindMode=] - [--device=] [--help] [--inDataPath=] - [--inDataType=] [--loopCount=] - [--numThreads=] [--omModelPath=] - [--resizeDims=] [--warmUpLoopCount=] + [--calibDataPath=] [--calibDataType=] + [--cpuBindMode=] [--device=] [--help] + [--inDataPath=] [--loopCount=] + [--numThreads=] [--warmUpLoopCount=] [--fp16Priority=] ``` diff --git a/tutorials/lite/source_en/use/timeprofiler_tool.md b/tutorials/lite/source_en/use/timeprofiler_tool.md index b0e3d35860..1442ecc46d 100644 --- a/tutorials/lite/source_en/use/timeprofiler_tool.md +++ b/tutorials/lite/source_en/use/timeprofiler_tool.md @@ -20,16 +20,16 @@ After model conversion and before inference, you can use the TimeProfiler tool t To use the TimeProfiler tool, you need to prepare the environment as follows: -- Compilation: Install build dependencies and perform build. The code of the TimeProfiler tool is stored in the `mindspore/lite/tools/time_profile` directory of the MindSpore source code. For details about the build operations, see the [Environment Requirements](https://www.mindspore.cn/lite/tutorial/en/master/build.html#environment-requirements) and [Compilation Example](https://www.mindspore.cn/lite/tutorial/en/master/build.html#compilation-example) in the build document. +- Compilation: Install build dependencies and perform build. The code of the TimeProfiler tool is stored in the `mindspore/lite/tools/time_profiler` directory of the MindSpore source code. For details about the build operations, see the [Environment Requirements](https://www.mindspore.cn/lite/tutorial/en/master/build.html#environment-requirements) and [Compilation Example](https://www.mindspore.cn/lite/tutorial/en/master/build.html#compilation-example) in the build document. -- Run: Obtain the `timeprofile` tool and configure environment variables by referring to [Output Description](https://www.mindspore.cn/lite/tutorial/en/master/build.html#output-description) in the build document. +- Run: Obtain the `timeprofiler` tool and configure environment variables by referring to [Output Description](https://www.mindspore.cn/lite/tutorial/en/master/build.html#output-description) in the build document. ## Parameter Description The command used for analyzing the time consumption of forward inference at the network layer based on the compiled TimeProfiler tool is as follows: ```bash -./timeprofile --modelPath= [--help] [--loopCount=] [--numThreads=] [--cpuBindMode=] [--inDataPath=] [--fp16Priority=] +./timeprofiler --modelPath= [--help] [--loopCount=] [--numThreads=] [--cpuBindMode=] [--inDataPath=] [--fp16Priority=] ``` The following describes the parameters in detail. @@ -49,7 +49,7 @@ The following describes the parameters in detail. Take the `test_timeprofiler.ms` model as an example and set the number of model inference cycles to 10. The command for using TimeProfiler to analyze the time consumption at the network layer is as follows: ```bash -./timeprofile --modelPath=./models/test_timeprofiler.ms --loopCount=10 +./timeprofiler --modelPath=./models/test_timeprofiler.ms --loopCount=10 ``` After this command is executed, the TimeProfiler tool outputs the statistics on the running time of the model at the network layer. In this example, the command output is as follows: The statistics are displayed by`opName` and `optype`. `opName` indicates the operator name, `optype` indicates the operator type, and `avg` indicates the average running time of the operator per single run, `percent` indicates the ratio of the operator running time to the total operator running time, `calledTimess` indicates the number of times that the operator is run, and `opTotalTime` indicates the total time that the operator is run for a specified number of times. Finally, `total time` and `kernel cost` show the average time consumed by a single inference operation of the model and the sum of the average time consumed by all operators in the model inference, respectively. diff --git a/tutorials/lite/source_zh_cn/build.md b/tutorials/lite/source_zh_cn/build.md index 0ef2ee0312..12df7b60f4 100644 --- a/tutorials/lite/source_zh_cn/build.md +++ b/tutorials/lite/source_zh_cn/build.md @@ -22,7 +22,7 @@ | converter | Linux | 模型转换工具 | | runtime | Linux、Android | 模型推理框架 | | benchmark | Linux、Android | 基准测试工具 | -| time_profiler | Linux、Android | 性能分析工具 | +| timeprofiler | Linux、Android | 性能分析工具 | ## Linux环境编译 @@ -30,7 +30,7 @@ - 系统环境:Linux x86_64,推荐使用Ubuntu 18.04.02LTS -- runtime、benchmark、time_profiler编译依赖 +- runtime、benchmark、timeprofiler编译依赖 - [CMake](https://cmake.org/download/) >= 3.14.1 - [GCC](https://gcc.gnu.org/releases.html) >= 7.3.0 - [Android_NDK](https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip) >= r20 @@ -101,7 +101,7 @@ git clone https://gitee.com/mindspore/mindspore.git 编译完成后,进入`mindspore/output/`目录,可查看编译后生成的文件。文件分为两部分: - `mindspore-lite-{version}-converter-{os}.tar.gz`:包含模型转换工具converter。 -- `mindspore-lite-{version}-runtime-{os}-{device}.tar.gz`:包含模型推理框架runtime、基准测试工具benchmark和性能分析工具time_profiler。 +- `mindspore-lite-{version}-runtime-{os}-{device}.tar.gz`:包含模型推理框架runtime、基准测试工具benchmark和性能分析工具timeprofiler。 > version:输出件版本号,与所编译的分支代码对应的版本一致。 > @@ -143,7 +143,7 @@ tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz │ └── third_party # 第三方库头文件和库 │ ├── flatbuffers # FlatBuffers头文件 │ └── include # 推理框架头文件 - │ └── time_profile # 模型网络层耗时分析工具 + │ └── time_profiler # 模型网络层耗时分析工具 ``` @@ -158,7 +158,7 @@ tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz │ └── third_party # 第三方库头文件和库 │ ├── flatbuffers # FlatBuffers头文件 │ └── include # 推理框架头文件 - │ └── time_profile # 模型网络层耗时分析工具 + │ └── time_profiler # 模型网络层耗时分析工具 ``` @@ -172,10 +172,10 @@ tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz │ └── third_party # 第三方库头文件和库 │ ├── flatbuffers # FlatBuffers头文件 │ └── include # 推理框架头文件 - │ └── time_profile # 模型网络层耗时分析工具 + │ └── time_profiler # 模型网络层耗时分析工具 ``` > 1. `liboptimize.so`仅在runtime-arm64的输出包中存在,仅在ARMv8.2和支持fp16特性的CPU上使用。 > 2. 编译ARM64默认可获得arm64-cpu的推理框架输出件,若添加`-e gpu`则获得arm64-gpu的推理框架输出件,此时包名为`mindspore-lite-{version}-runtime-arm64-gpu.tar.gz`,编译ARM32同理。 -> 3. 运行converter、benchmark或time_profile目录下的工具前,都需配置环境变量,将MindSpore Lite和Protobuf的动态库所在的路径配置到系统搜索动态库的路径中。以0.7.0-beta版本下编译为例:配置converter:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`;配置benchmark和timeprofiler:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`。 +> 3. 运行converter、benchmark或time_profiler目录下的工具前,都需配置环境变量,将MindSpore Lite和Protobuf的动态库所在的路径配置到系统搜索动态库的路径中。以0.7.0-beta版本下编译为例:配置converter:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`;配置benchmark和timeprofiler:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`。 diff --git a/tutorials/lite/source_zh_cn/use/benchmark_tool.md b/tutorials/lite/source_zh_cn/use/benchmark_tool.md index 83c6aadc63..7caaad2e63 100644 --- a/tutorials/lite/source_zh_cn/use/benchmark_tool.md +++ b/tutorials/lite/source_zh_cn/use/benchmark_tool.md @@ -76,11 +76,10 @@ Mean bias of all nodes: 0% ```bash ./benchmark [--modelPath=] [--accuracyThreshold=] - [--calibDataPath=] [--cpuBindMode=] - [--device=] [--help] [--inDataPath=] - [--inDataType=] [--loopCount=] - [--numThreads=] [--omModelPath=] - [--resizeDims=] [--warmUpLoopCount=] + [--calibDataPath=] [--calibDataType=] + [--cpuBindMode=] [--device=] [--help] + [--inDataPath=] [--loopCount=] + [--numThreads=] [--warmUpLoopCount=] [--fp16Priority=] ``` diff --git a/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md b/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md index fbe404c178..7c7a60576b 100644 --- a/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md +++ b/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md @@ -20,16 +20,16 @@ 使用TimeProfiler工具,需要进行如下环境准备工作。 -- 编译:TimeProfiler工具代码在MindSpore源码的`mindspore/lite/tools/time_profile`目录中,参考构建文档中的[环境要求](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id1)和[编译示例](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id3)执行编译。 +- 编译:TimeProfiler工具代码在MindSpore源码的`mindspore/lite/tools/time_profiler`目录中,参考构建文档中的[环境要求](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id1)和[编译示例](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id3)执行编译。 -- 运行:参考部署文档中的[编译输出](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id4),获得`timeprofile`工具,并配置环境变量。 +- 运行:参考部署文档中的[编译输出](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id4),获得`timeprofiler`工具,并配置环境变量。 ## 使用示例 使用TimeProfiler对`test_timeprofiler.ms`模型的网络层进行耗时分析,并且设置模型推理循环运行次数为10,则其命令代码如下: ```bash -./timeprofile --modelPath=./models/test_timeprofiler.ms --loopCount=10 +./timeprofiler --modelPath=./models/test_timeprofiler.ms --loopCount=10 ``` 该条命令执行后,TimeProfiler工具会输出模型网络层运行耗时的相关统计信息。对于本例命令,输出的统计信息如下。其中统计信息按照`opName`和`optype`两种划分方式分别显示,`opName`表示算子名,`optype`表示算子类别,`avg`表示该算子的平均单次运行时间,`percent`表示该算子运行耗时占所有算子运行总耗时的比例,`calledTimess`表示该算子的运行次数,`opTotalTime`表示该算子运行指定次数的总耗时。最后,`total time`和`kernel cost`分别显示了该模型单次推理的平均耗时和模型推理中所有算子的平均耗时之和。 @@ -77,7 +77,7 @@ total time : 2.90800 ms, kernel cost : 2.74851 ms 使用编译好的TimeProfiler工具进行模型网络层耗时分析时,其命令格式如下所示。 ```bash -./timeprofile --modelPath= [--help] [--loopCount=] [--numThreads=] [--cpuBindMode=] [--inDataPath=] [--fp16Priority=] +./timeprofiler --modelPath= [--help] [--loopCount=] [--numThreads=] [--cpuBindMode=] [--inDataPath=] [--fp16Priority=] ``` 下面提供详细的参数说明。 -- Gitee From f502a5c6b9360b2d2f8b3bb1d654c01d12ce10a9 Mon Sep 17 00:00:00 2001 From: cjh9368 Date: Tue, 15 Sep 2020 17:20:47 +0800 Subject: [PATCH 026/100] bug fix --- tutorials/lite/source_en/use/converter_tool.md | 5 ++--- tutorials/lite/source_zh_cn/use/converter_tool.md | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index de9a3020e2..83f2d426ff 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -81,7 +81,7 @@ The following describes how to use the conversion command by using several commo - TensorFlow Lite aware quantization model `model_quant.tflite` set the input and output data type to be int8 ```bash - ./converter_lite --fmk=TFLITE --modelFile=model.tflite --outputFile=model --quantType=AwareTraining --inputInferenceType=INT8 --inferenceType=INT8 + ./converter_lite --fmk=TFLITE --modelFile=model.tflite --outputFile=model --quantType=AwareTraining --inferenceType=FLOAT ``` In the preceding scenarios, the following information is displayed, indicating that the conversion is successful. In addition, the target file `model.ms` is obtained. @@ -105,8 +105,7 @@ The following describes the parameters in detail. | `--outputFile=` | Yes | Path of the output model. (If the path does not exist, a directory will be automatically created.) The suffix `.ms` can be automatically generated. | - | - | | `--weightFile=` | Yes (for Caffe models only) | Path of the weight file of the input model. | - | - | | `--quantType=` | No | Sets the quant type of the model. | PostTraining: quantization after training
    AwareTraining: perceptual quantization | - | -|`--inputInferenceType=` | No(supported by aware quant models only) | Sets the input data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the input data type is same as the input of origin model. | FLOAT or INT8 | FLOAT | -|`--inferenceType= `| No(supported by aware quant models only) | Sets the output data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the output data type is same as the input of origin model. | FLOAT or INT8 | FLOAT | +|`--inferenceType= `| No(supported by aware quant models only) | Sets the input and output data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the output data type is same as the input of origin model. | SAME FLOAT or INT8 | SAME | |`--stdDev=`| No(supported by aware quant models only) | Sets the standard deviation of the input data. | (0,+∞) | 128 | |`--mean=`| No(supported by aware quant models only) | Sets the mean value of the input data. | [-128, 127] | -0.5 | diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index d63fefb842..62349642cf 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -79,10 +79,10 @@ bash build.sh -I x86_64 ./converter_lite --fmk=TFLITE --modelFile=model_quant.tflite --outputFile=model --quantType=AwareTraining ``` - - 感知量化模型输入设置为int8,输出设置为int8 + - 感知量化模型输入输出类型设置为float ```bash - ./converter_lite --fmk=TFLITE --modelFile=model_quant.tflite --outputFile=model --quantType=AwareTraining --inputInferenceType=INT8 --inferenceType=INT8 + ./converter_lite --fmk=TFLITE --modelFile=model_quant.tflite --outputFile=model --quantType=AwareTraining --inferenceType=FLOAT ``` 以上几种情况下,均显示如下转换成功提示,且同时获得`model.ms`目标文件。 @@ -106,8 +106,7 @@ MindSpore Lite模型转换工具提供了多种参数设置,用户可根据需 | `--outputFile=` | 是 | 输出模型的路径(不存在时将自动创建目录),不需加后缀,可自动生成`.ms`后缀。 | - | - | | `--weightFile=` | 转换Caffe模型时必选 | 输入模型weight文件的路径。 | - | - | | `--quantType=` | 否 | 设置模型的量化类型。 | PostTraining:训练后量化
    AwareTraining:感知量化。 | - | -|` --inputInferenceType=` | 否 | 设置感知量化模型输入数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inputInferenceType保持一致。 | FLOAT、INT8 | FLOAT | -| `--inferenceType=` | 否 | 设置感知量化模型输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输出类型和inferenceType保持一致。 | FLOAT、INT8 | FLOAT | +|` --inferenceType=` | 否 | 设置感知量化模型输入输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inferenceType保持一致。 |SAME、 FLOAT、INT8 | SAME | | `--stdDev= `| 否 | 感知量化模型转换时用于设置输入数据的标准差。 | (0,+∞) | 128 | | `--mean=` | 否 | 感知量化模型转换时用于设置输入数据的均值。 | [-128, 127] | -0.5 | -- Gitee From b93a91e58c8b95907dc8a76d007aec0d76661cd0 Mon Sep 17 00:00:00 2001 From: lihongkang <[lihongkang1@huawei.com]> Date: Tue, 15 Sep 2020 17:28:57 +0800 Subject: [PATCH 027/100] update op list --- docs/note/source_en/operator_list.md | 2 +- docs/note/source_zh_cn/operator_list.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/note/source_en/operator_list.md b/docs/note/source_en/operator_list.md index 5f8f57179a..680dc94188 100644 --- a/docs/note/source_en/operator_list.md +++ b/docs/note/source_en/operator_list.md @@ -99,7 +99,7 @@ | :----------- |:------ |:------ |:-----|:--- | [mindspore.ops.operations.Flatten](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Flatten) | Supported | Supported |Supported | nn_ops | [mindspore.ops.operations.Softmax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Softmax) | Supported | Supported | Supported | nn_ops -| [mindspore.ops.operations.Acosh](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Acosh) | Doing | Doing | Doing | nn_ops +| [mindspore.ops.operations.Acosh](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Acosh) | Supported | Doing | Doing | nn_ops | [mindspore.ops.operations.FloorMod](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorMod) | Supported | Doing | Doing | nn_ops | [mindspore.ops.operations.Elu](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Elu) | Supported | Doing | Doing | nn_ops | [mindspore.ops.operations.MirrorPad](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.MirrorPad) | Supported | Supported | Doing | nn_ops diff --git a/docs/note/source_zh_cn/operator_list.md b/docs/note/source_zh_cn/operator_list.md index f29cc3fd7e..49fe2ae19f 100644 --- a/docs/note/source_zh_cn/operator_list.md +++ b/docs/note/source_zh_cn/operator_list.md @@ -99,7 +99,7 @@ | :----------- |:------ |:------ |:-----|:--- | [mindspore.ops.operations.Flatten](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Flatten) | Supported | Supported |Supported | nn_ops | [mindspore.ops.operations.Softmax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Softmax) | Supported | Supported | Supported | nn_ops -| [mindspore.ops.operations.Acosh](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Acosh) | Doing | Doing | Doing | nn_ops +| [mindspore.ops.operations.Acosh](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Acosh) | Supported | Doing | Doing | nn_ops | [mindspore.ops.operations.FloorMod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorMod) | Supported | Doing | Doing | nn_ops | [mindspore.ops.operations.Elu](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Elu) | Supported | Doing | Doing | nn_ops | [mindspore.ops.operations.MirrorPad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.MirrorPad) | Supported | Supported | Doing | nn_ops -- Gitee From dea751346b37e2acd7c189cf768ae385cecf76ae Mon Sep 17 00:00:00 2001 From: caifubi Date: Tue, 15 Sep 2020 18:37:41 +0800 Subject: [PATCH 028/100] Combine E2E Dump And Async Dump --- .../customized_debugging_information.md | 108 ++++++++++++++---- .../customized_debugging_information.md | 107 +++++++++++++---- 2 files changed, 166 insertions(+), 49 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/customized_debugging_information.md b/tutorials/training/source_en/advanced_use/customized_debugging_information.md index 4d2add7d7a..996b1baac7 100644 --- a/tutorials/training/source_en/advanced_use/customized_debugging_information.md +++ b/tutorials/training/source_en/advanced_use/customized_debugging_information.md @@ -11,7 +11,9 @@ - [Custom Callback](#custom-callback) - [MindSpore Metrics](#mindspore-metrics) - [MindSpore Print Operator](#mindspore-print-operator) - - [Asynchronous Data Dump](#asynchronous-data-dump) + - [Data Dump Introduction](#data-dump-introduction) + - [Synchronous Dump](#synchronous-dump) + - [Asynchronous Dump](#asynchronous-dump) - [Log-related Environment Variables and Configurations](#log-related-environment-variables-and-configurations) @@ -259,50 +261,106 @@ val:[[1 1] [1 1]] ``` -## Asynchronous Data Dump +## Data Dump Introduction -When the training result deviates from the expectation on Ascend, the input and output of the operator can be dumped for debugging through Asynchronous Data Dump. +The input and output of the operator can be saved for debugging through the data dump when the training result deviates from the expectation. Data dump includes Synchronous Dump and Asynchronous Dump. -> `comm_ops` operators are not supported by Asynchronous Data Dump. `comm_ops` can be found in [Operator List](https://www.mindspore.cn/docs/en/master/operator_list.html). +### Synchronous Dump -1. Turn on the switch to save graph IR: `context.set_context(save_graphs=True)`. -2. Execute training script. -3. Open `hwopt_d_end_graph_{graph id}.ir` in the directory you execute the script and find the name of the operators you want to Dump. -4. Configure json file: `data_dump.json`. +1. Create dump json file:`data_dump.json`. + + The name and location of the JSON file can be customized. ```json { - "DumpSettings": { + "common_dump_settings": { + "dump_mode": 0, + "path": "/tmp/net/", "net_name": "ResNet50", + "iteration": 0, + "input_output": 0, + "kernels": ["Default/Conv-op12"], + "support_device": [0,1,2,3,4,5,6,7] + }, + "e2e_dump_settings": { + "enable": false, + "trans_flag": false + } + } + ``` + + - `dump_mode`:0:dump all kernels in graph, 1: dump kernels in kernels list. + - `path`:The absolute path where dump saves data. + - `net_name`:net name eg:ResNet50. + - `iteration`:Specify the iterations to dump. All kernels in graph will be dumped. + - `input_output`:0:dump input and output of kernel, 1:dump input of kernel, 2:dump output of kernel. + - `kernels`:full name of kernel. Enable `context.set_context(save_graphs=True)` and get full name of kernel from `hwopt_d_end_graph_{graph_id}.ir`. + - `support_device`:support devices, default setting is `[0,1,2,3,4,5,6,7]`. You can specify specific device ids to dump specific device data. + - `enable`:enable synchronous dump. + - `trans_flag`:enable trans flag. Transform the device data format into NCHW. + +2. Specify the location of the JSON file. + + ```bash + export MINDSPORE_DUMP_CONFIG={Absolute path of data_dump.json} + ``` + + - Set the environment variables before executing the training script. Settings will not take effect during training. + - Dump environment variables need to be configured before calling `mindspore.communication.management.init`. + +3. Execute the training script to dump data. + +4. Parse the Dump file + + Call `numpy.fromfile` to parse dump data file. + +### Asynchronous Dump + +1. Create dump json file:`data_dump.json`. + + The name and location of the JSON file can be customized. + ```json + { + "common_dump_settings": { "dump_mode": 0, - "op_debug_mode": 0, + "path": "/relative_path", + "net_name": "ResNet50", "iteration": 0, - "kernels": ["Default/Conv2D-op2", "Default/TensorAdd-op10"] + "input_output": 0, + "kernels": ["Default/Conv-op12"], + "support_device": [0,1,2,3,4,5,6,7] + }, + "async_dump_settings": { + "enable": false, + "op_debug_mode": 0 } } ``` - > - `net_name`: net name eg:ResNet50. - > - `dump_mode`: 0: dump all kernels, 1: dump kernels in kernels list. - > - `op_debug_mode`: please set to 0. - > - `iteration`: specified iteration to dump. `iteration` should be set to 0 when `dataset_sink_mode` is False and data of every iteration will be dumped. - > - `kernels`: `fullname_with_scope` of kernel which need to dump. + - `dump_mode`:0:dump all kernels in graph, 1: dump kernels in kernels list. + - `path`:Relative path where dump data saves. eg:data will be saved in `/var/log/npu/ide_deam/dump/relative_path`. + - `net_name`:net name eg:ResNet50. + - `iteration`:Specify the iterations to dump. Iteration should be set to 0 when dataset_sink_mode is False and data of every iteration will be dumped. + - `input_output`:0:dump input and output of kernel, 1:dump input of kernel, 2:dump output of kernel. + - `kernels`:Full name of kernel. Enable `context.set_context(save_graphs=True)` and get full name of kernel from `hwopt_d_end_graph_{graph_id}.ir`. `kernels` only support TBE operator, AiCPU operator and communication operator. Data of communication operation input operator will be dumped if `kernels` is set to the name of communication operator. + - `support_device`:support devices, default setting is `[0,1,2,3,4,5,6,7]`. You can specify specific device ids to dump specific device data. + - `enable`:enable Asynchronous Dump. + - `op_debug_mode`:please set to 0. -5. Set environment variables. +2. Specify the json configuration file of Dump. ```bash - export ENABLE_DATA_DUMP=1 - export DATA_DUMP_PATH=/test - export DATA_DUMP_CONFIG_PATH=data_dump.json + export MINDSPORE_DUMP_CONFIG={Absolute path of data_dump.json} ``` - > - Set the environment variables before executing the training script. Setting environment variables during training will not take effect. - > - Dump environment variables need to be configured before calling `mindspore.communication.management.init`. + - Set the environment variables before executing the training script. Setting environment variables during training will not take effect. + - Dump environment variables need to be configured before calling `mindspore.communication.management.init`. + +3. Execute the training script to dump data. -6. Execute the training script again. -7. Parse the Dump file. +4. Parse the Dump file - Change directory to `/var/log/npu/ide_daemon/dump/` after training and execute the following commands to parse Dump data file: + Change directory to /var/log/npu/ide_daemon/dump/ after training, execute the following commands to parse Dump data file: ```bash python /usr/local/Ascend/toolkit/tools/operator_cmp/compare/dump_data_conversion.pyc -type offline -target numpy -i ./{Dump file path}} -o ./{output file path} diff --git a/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md b/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md index 2099dded63..57f34688e9 100644 --- a/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md +++ b/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md @@ -11,7 +11,9 @@ - [自定义Callback](#自定义callback) - [MindSpore metrics功能介绍](#mindspore-metrics功能介绍) - [print算子功能介绍](#print算子功能介绍) - - [异步数据Dump功能介绍](#异步数据dump功能介绍) + - [数据Dump功能介绍](#数据dump功能介绍) + - [同步Dump功能介绍](#同步dump功能介绍) + - [异步Dump功能介绍](#异步dump功能介绍) - [日志相关的环境变量和配置](#日志相关的环境变量和配置) @@ -263,48 +265,105 @@ val:[[1 1] [1 1]] ``` -## 异步数据Dump功能介绍 +## 数据Dump功能介绍 -在Ascend环境上执行训练,当训练结果和预期有偏差时,可以通过异步数据Dump功能保存算子的输入输出进行调试。 +训练网络时,当训练结果和预期有偏差时,可以通过数据Dump功能保存算子的输入输出进行调试。Dump功能分为同步Dump和异步Dump,同步Dump同时支持GPU和Ascend,而异步Dump只支持Ascend。 -> 异步数据Dump不支持`comm_ops`类别的算子,算子类别详见[算子支持列表](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html)。 +### 同步Dump功能介绍 -1. 开启IR保存开关: `context.set_context(save_graphs=True)`。 -2. 执行网络脚本。 -3. 查看执行目录下的`hwopt_d_end_graph_{graph id}.ir`,找到需要Dump的算子名称。 -4. 配置Dump的json配置文件`data_dump.json`。 +1. 创建配置文件`data_dump.json`。 + + JSON文件的名称和位置可以自定义设置。 ```json { - "DumpSettings": { + "common_dump_settings": { + "dump_mode": 0, + "path": "/tmp/net/", "net_name": "ResNet50", + "iteration": 0, + "input_output": 0, + "kernels": ["Default/Conv-op12"], + "support_device": [0,1,2,3,4,5,6,7] + }, + "e2e_dump_settings": { + "enable": false, + "trans_flag": false + } + } + ``` + + - `dump_mode`:设置成0,表示Dump出改网络中的所有算子;设置成1,表示Dump`"kernels"`里面制定的算子。 + - `path`:Dump保存数据的绝对路径。 + - `net_name`:自定义的网络名称,例如:"ResNet50"。 + - `iteration`:指定需要Dump的迭代,若设置成0,表示Dump所有的迭代。 + - `input_output`:设置成0,表示Dump出算子的输入和算子的输出;设置成1,表示Dump出算子的输入;设置成2,表示Dump出算子的输出。 + - `kernels`:算子的全称,可以通过开启IR保持开关`context.set_context(save_graphs=True)`执行用例,从生成的`hwopt_d_end_graph_{graph_id}.ir`文件获取。 + - `support_device`:支持的设备,默认设置成0到7即可;在分布式训练场景下,需要dump个别设备上的数据,可以只在`support_device`中指定需要Dump的设备Id。 + - `enable`:开启E2E Dump。 + - `trans_flag`:开启格式转换。将设备上的数据格式转换成NCHW格式。 + +2. 指定Dump的json配置文件。 + + ```bash + export MINDSPORE_DUMP_CONFIG={Absolute path of data_dump.json} + ``` + + - 在网络脚本执行前,设置好环境变量;网络脚本执行过程中设置将会不生效。 + - 在分布式场景下,Dump环境变量需要调用`mindspore.communication.management.init`之前配置。 + +3. 执行用例Dump数据。 + +4. 解析Dump数据。 + + 通过`numpy.fromfile`读取Dump数据文件即可解析。 + +### 异步Dump功能介绍 + +1. 创建配置文件`data_dump.json`。 + + JSON文件的名称和位置可以自定义设置。 + + ```json + { + "common_dump_settings": { "dump_mode": 0, - "op_debug_mode": 0, + "path": "/test", + "net_name": "ResNet50", "iteration": 0, - "kernels": ["Default/Conv2D-op2", "Default/TensorAdd-op10"] + "input_output": 0, + "kernels": ["Default/Conv-op12"], + "support_device": [0,1,2,3,4,5,6,7] + }, + "async_dump_settings": { + "enable": false, + "op_debug_mode": 0 } } ``` - > - `net_name`:自定义的网络名称,例如:"Resnet50"。 - > - `dump_mode`:设置成0,表示Dump所有的算子;设置成1,表示Dump`"kernel"`里面制定的算子。 - > - `op_debug_mode`:该属性用于算子溢出调试,在使用Dump功能的时候,请设置成0。 - > - `iteration`:指定需要Dump的迭代。非数据下沉模式下,`iteration`需要设置成0,并且会Dump出每个迭代的数据。 - > - `kernels`:指定需要Dump的算子名称(`fullname_with_scope`)。 + - `dump_mode`:设置成0,表示Dump出改网络中的所有算子;设置成1,表示Dump`"kernels"`里面指定的算子。 + - `path`:Dump保存数据的相对路径,异步Dump生成的数据都会保存在`/var/log/npu/ide_deam/dump/`目录下。 + - `net_name`:自定义的网络名称,例如:"ResNet50"。 + - `iteration`:指定需要Dump的迭代。非数据下沉模式下,`iteration`需要设置成0,并且会Dump出每个迭代的数据。 + - `input_output`:设置成0,表示Dump出算子的输入和算子的输出;设置成1,表示Dump出算子的输入;设置成2,表示Dump出算子的输出。 + - `kernels`:算子的全称。开启IR保持开关`context.set_context(save_graphs=True)`并执行用例,从生成的`hwopt_d_end_graph_{graph_id}.ir`文件获取。`kernels`仅支持TBE算子、AiCPU算子、通信算子,若设置成通信算子的名称,将会Dump出通信算子的输入算子的数据。 + - `support_device`:支持的设备,默认设置成0到7即可;在分布式训练场景下,需要dump个别设备上的数据,可以只在`support_device`中指定需要Dump的设备Id。 + - `enable`:开启异步Dump。 + - `op_debug_mode`:该属性用于算子溢出调试,在使用Dump功能的时候,请设置成0。 -5. 设置数据Dump的环境变量。 +2. 设置数据Dump的环境变量。 ```bash - export ENABLE_DATA_DUMP=1 - export DATA_DUMP_PATH=/test - export DATA_DUMP_CONFIG_PATH=data_dump.json + export MINDSPORE_DUMP_CONFIG={Absolute path of data_dump.json} ``` - > - 在网络脚本执行前,设置好环境变量;网络脚本执行过程中设置将会不生效。 - > - 在分布式场景下,Dump环境变量需要调用`mindspore.communication.management.init`之前配置。 + - 在网络脚本执行前,设置好环境变量;网络脚本执行过程中设置将会不生效。 + - 在分布式场景下,Dump环境变量需要调用`mindspore.communication.management.init`之前配置。 + +3. 执行用例Dump数据。 -6. 再次执行用例进行异步数据Dump。 -7. 解析文件。 +4. 解析文件。 执行完用例后去`/var/log/npu/ide_daemon/dump/`目录下,运行如下命令解析Dump数据: -- Gitee From 28bd50211c827bb7fc8b8f65f4e06e74dd06593a Mon Sep 17 00:00:00 2001 From: cjh9368 Date: Tue, 15 Sep 2020 17:20:47 +0800 Subject: [PATCH 029/100] bug fix --- tutorials/lite/source_en/use/converter_tool.md | 7 +++---- tutorials/lite/source_zh_cn/use/converter_tool.md | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index de9a3020e2..cf0fca347e 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -79,9 +79,9 @@ The following describes how to use the conversion command by using several commo ./converter_lite --fmk=TFLITE --modelFile=model.tflite --outputFile=model --quantType=AwareTraining ``` - - TensorFlow Lite aware quantization model `model_quant.tflite` set the input and output data type to be int8 + - TensorFlow Lite aware quantization model `model_quant.tflite` set the input and output data type to be float ```bash - ./converter_lite --fmk=TFLITE --modelFile=model.tflite --outputFile=model --quantType=AwareTraining --inputInferenceType=INT8 --inferenceType=INT8 + ./converter_lite --fmk=TFLITE --modelFile=model.tflite --outputFile=model --quantType=AwareTraining --inferenceType=FLOAT ``` In the preceding scenarios, the following information is displayed, indicating that the conversion is successful. In addition, the target file `model.ms` is obtained. @@ -105,8 +105,7 @@ The following describes the parameters in detail. | `--outputFile=` | Yes | Path of the output model. (If the path does not exist, a directory will be automatically created.) The suffix `.ms` can be automatically generated. | - | - | | `--weightFile=` | Yes (for Caffe models only) | Path of the weight file of the input model. | - | - | | `--quantType=` | No | Sets the quant type of the model. | PostTraining: quantization after training
    AwareTraining: perceptual quantization | - | -|`--inputInferenceType=` | No(supported by aware quant models only) | Sets the input data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the input data type is same as the input of origin model. | FLOAT or INT8 | FLOAT | -|`--inferenceType= `| No(supported by aware quant models only) | Sets the output data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the output data type is same as the input of origin model. | FLOAT or INT8 | FLOAT | +|`--inferenceType= `| No(supported by aware quant models only) | Sets the input and output data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the output data type is same as the input of origin model. | SAME FLOAT or INT8 | SAME | |`--stdDev=`| No(supported by aware quant models only) | Sets the standard deviation of the input data. | (0,+∞) | 128 | |`--mean=`| No(supported by aware quant models only) | Sets the mean value of the input data. | [-128, 127] | -0.5 | diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index d63fefb842..62349642cf 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -79,10 +79,10 @@ bash build.sh -I x86_64 ./converter_lite --fmk=TFLITE --modelFile=model_quant.tflite --outputFile=model --quantType=AwareTraining ``` - - 感知量化模型输入设置为int8,输出设置为int8 + - 感知量化模型输入输出类型设置为float ```bash - ./converter_lite --fmk=TFLITE --modelFile=model_quant.tflite --outputFile=model --quantType=AwareTraining --inputInferenceType=INT8 --inferenceType=INT8 + ./converter_lite --fmk=TFLITE --modelFile=model_quant.tflite --outputFile=model --quantType=AwareTraining --inferenceType=FLOAT ``` 以上几种情况下,均显示如下转换成功提示,且同时获得`model.ms`目标文件。 @@ -106,8 +106,7 @@ MindSpore Lite模型转换工具提供了多种参数设置,用户可根据需 | `--outputFile=` | 是 | 输出模型的路径(不存在时将自动创建目录),不需加后缀,可自动生成`.ms`后缀。 | - | - | | `--weightFile=` | 转换Caffe模型时必选 | 输入模型weight文件的路径。 | - | - | | `--quantType=` | 否 | 设置模型的量化类型。 | PostTraining:训练后量化
    AwareTraining:感知量化。 | - | -|` --inputInferenceType=` | 否 | 设置感知量化模型输入数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inputInferenceType保持一致。 | FLOAT、INT8 | FLOAT | -| `--inferenceType=` | 否 | 设置感知量化模型输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输出类型和inferenceType保持一致。 | FLOAT、INT8 | FLOAT | +|` --inferenceType=` | 否 | 设置感知量化模型输入输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inferenceType保持一致。 |SAME、 FLOAT、INT8 | SAME | | `--stdDev= `| 否 | 感知量化模型转换时用于设置输入数据的标准差。 | (0,+∞) | 128 | | `--mean=` | 否 | 感知量化模型转换时用于设置输入数据的均值。 | [-128, 127] | -0.5 | -- Gitee From d3657ed8a6f697600702620246cf7861ba9dea07 Mon Sep 17 00:00:00 2001 From: leiyuning Date: Tue, 15 Sep 2020 19:49:33 +0800 Subject: [PATCH 030/100] optimize traning out line --- ...ation.md => accelerate_data_processing.md} | 6 +- ... => apply_deep_probability_programming.md} | 37 +++++----- ...tion.md => apply_gradient_accumulation.md} | 7 +- ...ining.md => apply_host_device_training.md} | 4 +- ....md => apply_parameter_server_training.md} | 2 +- ...d => apply_quantization_aware_training.md} | 8 +-- ...aset_conversion.md => converse_dataset.md} | 15 ++-- ...nformation.md => custom_debugging_info.md} | 0 .../advanced_use/custom_operator.rst | 6 ++ .../custom_operator_ascend.md} | 2 +- .../training/source_zh_cn/advanced_use/cv.rst | 9 +++ ...=> cv_mobilenetv2_incremental_learning.md} | 7 +- ...r_vision_application.md => cv_resnet50.md} | 4 +- ... => cv_resnet50_second_order_optimizer.md} | 17 +++-- .../source_zh_cn/advanced_use/dashboard.md | 4 +- ...tive_mode.md => debug_in_pynative_mode.md} | 0 .../distributed_training_tutorials.rst | 6 +- ...ntation.md => enable_auto_augmentation.md} | 7 +- .../{cache.md => enable_cache.md} | 6 +- ...usion.md => enable_graph_kernel_fusion.md} | 2 +- ...precision.md => enable_mixed_precision.md} | 4 +- ...ve_model_security_differential_privacy.md} | 4 +- ...urity.md => improve_model_security_nad.md} | 2 +- .../lineage_and_scalars_comparision.md | 4 +- ...rk_migration.md => migrate_3rd_scripts.md} | 4 +- ...d => migrate_3rd_scripts_mindconverter.md} | 2 +- .../advanced_use/migrate_script.rst | 9 +++ .../{auto_data_acceleration.rst => nlp.rst} | 8 +-- .../{bert_poetry.md => nlp_bert_poetry.md} | 6 +- .../{nlp_application.md => nlp_lstm.md} | 4 +- ...aration.md => optimize_data_processing.md} | 4 +- ....md => save_load_model_hybrid_parallel.md} | 6 +- .../advanced_use/summary_record.md | 6 +- ...zzer.md => test_model_security_fuzzing.md} | 10 +-- ...st_model_security_membership_inference.md} | 7 +- .../advanced_use/visualization_tutorials.rst | 2 +- tutorials/training/source_zh_cn/index.rst | 68 ++++++++++--------- .../source_zh_cn/use/data_preparation.rst | 7 +- .../source_zh_cn/use/defining_the_network.rst | 3 +- ...image_loading.md => load_dataset_image.md} | 4 +- .../{text_loading.md => load_dataset_text.md} | 4 +- ...l_parameters.md => save_and_load_model.md} | 4 +- 42 files changed, 179 insertions(+), 142 deletions(-) rename tutorials/training/source_zh_cn/advanced_use/{data_processing_acceleration.md => accelerate_data_processing.md} (96%) rename tutorials/training/source_zh_cn/advanced_use/{deep_probability_program.md => apply_deep_probability_programming.md} (93%) rename tutorials/training/source_zh_cn/advanced_use/{gradient_accumulation.md => apply_gradient_accumulation.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{host_device_training.md => apply_host_device_training.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{parameter_server_training.md => apply_parameter_server_training.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{quantization_aware.md => apply_quantization_aware_training.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{dataset_conversion.md => converse_dataset.md} (94%) rename tutorials/training/source_zh_cn/advanced_use/{customized_debugging_information.md => custom_debugging_info.md} (100%) create mode 100644 tutorials/training/source_zh_cn/advanced_use/custom_operator.rst rename tutorials/training/source_zh_cn/{use/custom_operator.md => advanced_use/custom_operator_ascend.md} (99%) create mode 100644 tutorials/training/source_zh_cn/advanced_use/cv.rst rename tutorials/training/source_zh_cn/advanced_use/{mobilenetv2_incremental_learning.md => cv_mobilenetv2_incremental_learning.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{computer_vision_application.md => cv_resnet50.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{second_order_optimizer_for_resnet50_application.md => cv_resnet50_second_order_optimizer.md} (96%) rename tutorials/training/source_zh_cn/advanced_use/{debugging_in_pynative_mode.md => debug_in_pynative_mode.md} (100%) rename tutorials/training/source_zh_cn/advanced_use/{auto_augmentation.md => enable_auto_augmentation.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{cache.md => enable_cache.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{graph_kernel_fusion.md => enable_graph_kernel_fusion.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{mixed_precision.md => enable_mixed_precision.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{differential_privacy.md => improve_model_security_differential_privacy.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{model_security.md => improve_model_security_nad.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{network_migration.md => migrate_3rd_scripts.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{model_scripts_transformation.md => migrate_3rd_scripts_mindconverter.md} (99%) create mode 100644 tutorials/training/source_zh_cn/advanced_use/migrate_script.rst rename tutorials/training/source_zh_cn/advanced_use/{auto_data_acceleration.rst => nlp.rst} (30%) rename tutorials/training/source_zh_cn/advanced_use/{bert_poetry.md => nlp_bert_poetry.md} (98%) rename tutorials/training/source_zh_cn/advanced_use/{nlp_application.md => nlp_lstm.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{optimize_the_performance_of_data_preparation.md => optimize_data_processing.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{checkpoint_for_hybrid_parallel.md => save_load_model_hybrid_parallel.md} (99%) rename tutorials/training/source_zh_cn/advanced_use/{fuzzer.md => test_model_security_fuzzing.md} (96%) rename tutorials/training/source_zh_cn/advanced_use/{membership_inference.md => test_model_security_membership_inference.md} (98%) rename tutorials/training/source_zh_cn/use/{image_loading.md => load_dataset_image.md} (98%) rename tutorials/training/source_zh_cn/use/{text_loading.md => load_dataset_text.md} (98%) rename tutorials/training/source_zh_cn/use/{saving_and_loading_model_parameters.md => save_and_load_model.md} (98%) diff --git a/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md similarity index 96% rename from tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md rename to tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md index 4f3edad004..0736705c6d 100644 --- a/tutorials/training/source_zh_cn/advanced_use/data_processing_acceleration.md +++ b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md @@ -1,10 +1,10 @@ -# 数据处理性能调试 +# 提升数据处理性能 `Linux` `Ascend` `GPU` `CPU` `中级` `高级` - + -- [数据处理性能调试](#数据处理性能调试) +- [提升数据处理性能](#提升数据处理性能) - [概述](#概述) - [脚本撰写](#脚本撰写) - [操作系统的影响](#操作系统的影响) diff --git a/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md similarity index 93% rename from tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md rename to tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md index af2717f74c..c8325271ea 100644 --- a/tutorials/training/source_zh_cn/advanced_use/deep_probability_program.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md @@ -1,25 +1,28 @@ -# 深度概率编程 +# 进行深度概率编程 `Linux` `Ascend` `GPU` `全流程` `初级` `中级` `高级` -- [深度概率编程](#深度概率编程) +- [进行深度概率编程](#进行深度概率编程) - [概述](#概述) - - [贝叶斯神经网络](#贝叶斯神经网络) - - [处理数据集](#处理数据集) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [训练网络](#训练网络) - - [变分推断](#变分推断) - - [定义变分自编码器](#定义变分自编码器) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [处理数据](#处理数据) - - [训练网络](#训练网络) - - [DNN一键转换成BNN](#DNN一键转换成BNN) - - [定义DNN模型](#定义DNN模型) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [功能一:转换整个模型](#功能一:转换整个模型) - - [功能二:转换指定类型的层](#功能二:转换指定类型的层) - - [不确定性估计](#不确定性估计) + - [贝叶斯神经网络](#贝叶斯神经网络) + - [处理数据集](#处理数据集) + - [定义贝叶斯神经网络](#定义贝叶斯神经网络) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [训练网络](#训练网络) + - [变分推断](#变分推断) + - [定义变分自编码器](#定义变分自编码器) + - [定义损失函数和优化器](#定义损失函数和优化器-1) + - [处理数据](#处理数据) + - [训练网络](#训练网络-1) + - [生成新样本或重构输入样本](#生成新样本或重构输入样本) + - [DNN一键转换成BNN](#dnn一键转换成bnn) + - [定义DNN模型](#定义dnn模型) + - [定义损失函数和优化器](#定义损失函数和优化器-2) + - [实例化TransformToBNN](#实例化transformtobnn) + - [功能一:转换整个模型](#功能一转换整个模型) + - [功能二:转换指定类型的层](#功能二转换指定类型的层) + - [不确定性估计](#不确定性估计) diff --git a/tutorials/training/source_zh_cn/advanced_use/gradient_accumulation.md b/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/gradient_accumulation.md rename to tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md index 8a232a39b3..1aff383ad0 100644 --- a/tutorials/training/source_zh_cn/advanced_use/gradient_accumulation.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md @@ -1,12 +1,12 @@ -# 梯度累积 +# 应用梯度累积算法 `Linux` `Ascend` `GPU` `模型调优` `中级` `高级` -- [梯度累积](#梯度累积) +- [应用梯度累积算法](#应用梯度累积算法) - [概述](#概述) - - [建立梯度累积模型](#建立梯度累积模型) + - [创建梯度累积模型](#创建梯度累积模型) - [导入需要的库文件](#导入需要的库文件) - [加载数据集](#加载数据集) - [定义网络](#定义网络) @@ -14,7 +14,6 @@ - [定义训练过程](#定义训练过程) - [训练并保存模型](#训练并保存模型) - [实验结果](#实验结果) - diff --git a/tutorials/training/source_zh_cn/advanced_use/host_device_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/host_device_training.md rename to tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md index 801e1eb4ba..c20f533db6 100644 --- a/tutorials/training/source_zh_cn/advanced_use/host_device_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md @@ -1,10 +1,10 @@ -# Host+Device混合训练 +# 应用Host&Device混合训练 `Linux` `Ascend` `CPU` `模型训练` `中级` `高级` -- [Host+Device混合训练](#hostdevice混合训练) +- [Host&Device混合训练](#hostdevice混合训练) - [概述](#概述) - [准备工作](#准备工作) - [配置混合执行](#配置混合执行) diff --git a/tutorials/training/source_zh_cn/advanced_use/parameter_server_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/parameter_server_training.md rename to tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md index 934e6bbeb2..515d07d280 100644 --- a/tutorials/training/source_zh_cn/advanced_use/parameter_server_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md @@ -1,4 +1,4 @@ -# Parameter Server训练 +# 使用Parameter Server训练 `Linux` `Ascend` `GPU` `模型训练` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/quantization_aware.md b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/quantization_aware.md rename to tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md index 4d72f7f6a7..abf3180fc0 100644 --- a/tutorials/training/source_zh_cn/advanced_use/quantization_aware.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md @@ -1,15 +1,15 @@ -# 量化 +# 感知量化训练 `Linux` `Ascend` `GPU` `模型调优` `高级` -- [量化](#量化) +- [感知量化训练](#感知量化训练) - [背景](#背景) - [概念](#概念) - - [量化](#量化-1) + - [量化](#量化) - [伪量化节点](#伪量化节点) - - [感知量化训练](#感知量化训练) + - [感知量化训练](#感知量化训练-1) - [感知量化训练示例](#感知量化训练示例) - [定义融合网络](#定义融合网络) - [转化为量化网络](#转化为量化网络) diff --git a/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md b/tutorials/training/source_zh_cn/advanced_use/converse_dataset.md similarity index 94% rename from tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md rename to tutorials/training/source_zh_cn/advanced_use/converse_dataset.md index d0f3e06d79..089f3b0d96 100644 --- a/tutorials/training/source_zh_cn/advanced_use/dataset_conversion.md +++ b/tutorials/training/source_zh_cn/advanced_use/converse_dataset.md @@ -1,14 +1,15 @@ -# MindSpore数据格式转换 +# 转换数据集为MindRecord `Linux` `Ascend` `GPU` `CPU` `初级` `中级` `高级` - -- [MindSpore数据格式转换](#mindspore数据格式转换) - - [概述](#概述) - - [基本概念](#基本概念) - - [相关接口说明](#相关接口说明) - - [将数据集转换为MindRecord](#将数据集转换为mindrecord) + + +- [转换数据集为MindRecord](#转换数据集为mindrecord) + - [概述](#概述) + - [基本概念](#基本概念) + - [相关接口说明](#相关接口说明) + - [将数据集转换为MindRecord](#将数据集转换为mindrecord) diff --git a/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md b/tutorials/training/source_zh_cn/advanced_use/custom_debugging_info.md similarity index 100% rename from tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md rename to tutorials/training/source_zh_cn/advanced_use/custom_debugging_info.md diff --git a/tutorials/training/source_zh_cn/advanced_use/custom_operator.rst b/tutorials/training/source_zh_cn/advanced_use/custom_operator.rst new file mode 100644 index 0000000000..fc5b6b08cd --- /dev/null +++ b/tutorials/training/source_zh_cn/advanced_use/custom_operator.rst @@ -0,0 +1,6 @@ +.. toctree:: + :maxdepth: 1 + + custom_operator_ascend + 自定义算子(GPU) + 自定义算子(CPU) \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/use/custom_operator.md b/tutorials/training/source_zh_cn/advanced_use/custom_operator_ascend.md similarity index 99% rename from tutorials/training/source_zh_cn/use/custom_operator.md rename to tutorials/training/source_zh_cn/advanced_use/custom_operator_ascend.md index 1d90e904aa..430953f9e7 100644 --- a/tutorials/training/source_zh_cn/use/custom_operator.md +++ b/tutorials/training/source_zh_cn/advanced_use/custom_operator_ascend.md @@ -1,4 +1,4 @@ -# 自定义算子 +# 自定义算子(Ascend) `Linux` `Ascend` `模型开发` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/cv.rst b/tutorials/training/source_zh_cn/advanced_use/cv.rst new file mode 100644 index 0000000000..e8fbeb5f30 --- /dev/null +++ b/tutorials/training/source_zh_cn/advanced_use/cv.rst @@ -0,0 +1,9 @@ +机器视觉类 +=========== + +.. toctree:: + :maxdepth: 1 + + cv_resnet50 + cv_resnet50_second_order_optimizer + cv_mobilenetv2_incremental_learning \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md b/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md rename to tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md index c24653f644..f33f3e9ae7 100644 --- a/tutorials/training/source_zh_cn/advanced_use/mobilenetv2_incremental_learning.md +++ b/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md @@ -1,10 +1,9 @@ -# MobileNetV2 增量学习 - -`Linux` `Windows` `CPU` `Ascend` `GPU` `模型开发` `中级` `高级` +# 使用MobileNetV2网络实现增量学习 +`Windows` `Linux` `CPU` `Ascend` `GPU` `模型开发` `中级` `高级` -- [MobileNetV2 增量学习](#mobilenetv2-增量学习) +- [使用MobileNetV2网络实现增量学习](#使用mobilenetv2网络实现增量学习) - [概述](#概述) - [任务描述及准备](#任务描述及准备) - [环境配置](#环境配置) diff --git a/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md b/tutorials/training/source_zh_cn/advanced_use/cv_resnet50.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md rename to tutorials/training/source_zh_cn/advanced_use/cv_resnet50.md index c00a1d9efd..c7ea8e102f 100644 --- a/tutorials/training/source_zh_cn/advanced_use/computer_vision_application.md +++ b/tutorials/training/source_zh_cn/advanced_use/cv_resnet50.md @@ -1,10 +1,10 @@ -# 计算机视觉应用 +# 使用ResNet-50网络实现图像分类 `Linux` `Ascend` `GPU` `全流程` `初级` `中级` `高级` -- [计算机视觉应用](#计算机视觉应用) +- [使用ResNet-50网络实现图像分类](#使用resnet-50网络实现图像分类) - [概述](#概述) - [图像分类](#图像分类) - [任务描述及准备](#任务描述及准备) diff --git a/tutorials/training/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md b/tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md similarity index 96% rename from tutorials/training/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md rename to tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md index 35dd89dd17..0d2dfcd4b2 100644 --- a/tutorials/training/source_zh_cn/advanced_use/second_order_optimizer_for_resnet50_application.md +++ b/tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md @@ -1,24 +1,33 @@ -# ResNet-50二阶优化实践 +# 在ResNet-50网络上应用二阶优化实践 `Linux` `Ascend` `GPU` `模型开发` `模型调优` `高级` -- [ResNet-50二阶优化实践](#resnet-50二阶优化实践) +- [在ResNet-50网络上应用二阶优化实践](#在resnet-50网络上应用二阶优化实践) - [概述](#概述) + - [示例代码目录结构](#示例代码目录结构) - [准备环节](#准备环节) - [准备数据集](#准备数据集) - [配置分布式环境变量](#配置分布式环境变量) + - [Ascend 910](#ascend-910) + - [GPU](#gpu) - [加载处理数据集](#加载处理数据集) - [定义网络](#定义网络) - [定义损失函数及THOR优化器](#定义损失函数及thor优化器) - [定义损失函数](#定义损失函数) - [定义优化器](#定义优化器) - [训练网络](#训练网络) - - [配置模型保存](#配置模型保存) + - [配置模型保存](#配置模型保存) - [配置训练网络](#配置训练网络) - - [运行脚本](#运行脚本) + - [运行脚本](#运行脚本) + - [Ascend 910](#ascend-910-1) + - [GPU](#gpu-1) - [模型推理](#模型推理) + - [定义推理网络](#定义推理网络) + - [执行推理](#执行推理) + - [Ascend 910](#ascend-910-2) + - [GPU](#gpu-2)    diff --git a/tutorials/training/source_zh_cn/advanced_use/dashboard.md b/tutorials/training/source_zh_cn/advanced_use/dashboard.md index 110dfa34ff..4cd8689353 100644 --- a/tutorials/training/source_zh_cn/advanced_use/dashboard.md +++ b/tutorials/training/source_zh_cn/advanced_use/dashboard.md @@ -1,10 +1,10 @@ -# 训练看板 +# 查看训练看板 `Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` -- [训练看板](#训练看板) +- [查看训练看板](#查看训练看板) - [概述](#概述) - [标量可视化](#标量可视化) - [参数分布图可视化](#参数分布图可视化) diff --git a/tutorials/training/source_zh_cn/advanced_use/debugging_in_pynative_mode.md b/tutorials/training/source_zh_cn/advanced_use/debug_in_pynative_mode.md similarity index 100% rename from tutorials/training/source_zh_cn/advanced_use/debugging_in_pynative_mode.md rename to tutorials/training/source_zh_cn/advanced_use/debug_in_pynative_mode.md diff --git a/tutorials/training/source_zh_cn/advanced_use/distributed_training_tutorials.rst b/tutorials/training/source_zh_cn/advanced_use/distributed_training_tutorials.rst index 1bac19659b..005bc22c96 100644 --- a/tutorials/training/source_zh_cn/advanced_use/distributed_training_tutorials.rst +++ b/tutorials/training/source_zh_cn/advanced_use/distributed_training_tutorials.rst @@ -19,6 +19,6 @@ distributed_training_ascend distributed_training_gpu - host_device_training - checkpoint_for_hybrid_parallel - parameter_server_training + apply_host_device_training + apply_parameter_server_training + save_load_model_hybrid_parallel diff --git a/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md rename to tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md index 9a159b0529..e29d21f58f 100644 --- a/tutorials/training/source_zh_cn/advanced_use/auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md @@ -1,10 +1,11 @@ -# 自动数据增强 +# 应用自动数据增强 `Linux` `Ascend` `GPU` `CPU` `中级` `高级` - -- [自动数据增强](#自动数据增强) + + +- [应用自动数据增强](#应用自动数据增强) - [概述](#概述) - [ImageNet自动数据增强](#imagenet自动数据增强) - [参考文献](#参考文献) diff --git a/tutorials/training/source_zh_cn/advanced_use/cache.md b/tutorials/training/source_zh_cn/advanced_use/enable_cache.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/cache.md rename to tutorials/training/source_zh_cn/advanced_use/enable_cache.md index 9268187593..463df2f550 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cache.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_cache.md @@ -1,10 +1,10 @@ -# 单节点缓存 +# 应用单节点缓存加速数据集读取 `Linux` `Ascend` `GPU` `CPU` `中级` `高级` - + -- [单节点缓存](#单节点缓存) +- [应用单节点缓存加速数据集读取](#应用单节点缓存加速数据集读取) - [概述](#概述) - [缓存基础使用](#缓存基础使用) - [缓存经过数据增强的数据](#缓存经过数据增强的数据) diff --git a/tutorials/training/source_zh_cn/advanced_use/graph_kernel_fusion.md b/tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/graph_kernel_fusion.md rename to tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md index b6a81aefae..f37771211e 100644 --- a/tutorials/training/source_zh_cn/advanced_use/graph_kernel_fusion.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md @@ -1,4 +1,4 @@ -# 图算融合 +# 使能图算融合 `Linux` `Ascend` `模型调优` `中级` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/mixed_precision.md b/tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/mixed_precision.md rename to tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md index 6d31c1d743..c374919e93 100644 --- a/tutorials/training/source_zh_cn/advanced_use/mixed_precision.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md @@ -1,10 +1,10 @@ -# 混合精度 +# 使能自动混合精度 `Linux` `Ascend` `GPU` `模型训练` `中级` `高级` -- [混合精度](#混合精度) +- [使能自动混合精度](#使能自动混合精度) - [概述](#概述) - [计算流程](#计算流程) - [自动混合精度](#自动混合精度) diff --git a/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_differential_privacy.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/differential_privacy.md rename to tutorials/training/source_zh_cn/advanced_use/improve_model_security_differential_privacy.md index d2cd750269..209a15f740 100644 --- a/tutorials/training/source_zh_cn/advanced_use/differential_privacy.md +++ b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_differential_privacy.md @@ -1,10 +1,10 @@ -# 机器学习中的差分隐私 +# 应用差分隐私优化器提升模型安全性 `Linux` `Ascend` `模型开发` `模型调优` `企业` `高级` -- [机器学习中的差分隐私](#机器学习中的差分隐私) +- [应用差分隐私优化器](#应用差分隐私优化器) - [概述](#概述) - [实现阶段](#实现阶段) - [导入需要的库文件](#导入需要的库文件) diff --git a/tutorials/training/source_zh_cn/advanced_use/model_security.md b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/model_security.md rename to tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md index 52d4a2fd09..bbbbe17dd9 100644 --- a/tutorials/training/source_zh_cn/advanced_use/model_security.md +++ b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md @@ -1,4 +1,4 @@ -# 模型安全 +# 使用NAD算法提升模型安全 `Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md b/tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md index 3022aa5b4d..140ad47488 100644 --- a/tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md +++ b/tutorials/training/source_zh_cn/advanced_use/lineage_and_scalars_comparision.md @@ -1,10 +1,10 @@ -# 溯源和对比看板 +# 查看溯源和对比看板 `Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` -- [溯源和对比看板](#溯源和对比看板) +- [查看溯源和对比看板](#查看溯源和对比看板) - [概述](#概述) - [模型溯源](#模型溯源) - [数据溯源](#数据溯源) diff --git a/tutorials/training/source_zh_cn/advanced_use/network_migration.md b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/network_migration.md rename to tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts.md index 663c24616e..c6ccc309fb 100644 --- a/tutorials/training/source_zh_cn/advanced_use/network_migration.md +++ b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts.md @@ -1,10 +1,10 @@ -# 网络迁移 +# 迁移第三方框架训练脚本 `Linux` `Ascend` `GPU` `CPU` `全流程` `初级` `中级` `高级` -- [网络迁移](#网络迁移) +- [迁移第三方框架训练脚本](#迁移第三方框架训练脚本) - [概述](#概述) - [准备环节](#准备环节) - [算子评估](#算子评估) diff --git a/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md rename to tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md index 5661595f88..4da5c1953e 100644 --- a/tutorials/training/source_zh_cn/advanced_use/model_scripts_transformation.md +++ b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md @@ -1,4 +1,4 @@ -# 模型脚本迁移 +# 使用工具迁移第三方框架脚本 `Linux` `Ascend` `模型开发` `初级` `Linux` diff --git a/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst b/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst new file mode 100644 index 0000000000..b4aeabcb92 --- /dev/null +++ b/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst @@ -0,0 +1,9 @@ +迁移第三方框架训练脚本 +=========== + +.. toctree:: + :maxdepth: 1 + + advanced_use/migrate_3rd_scripts_mindconverter + advanced_use/migrate_3rd_scripts + \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/auto_data_acceleration.rst b/tutorials/training/source_zh_cn/advanced_use/nlp.rst similarity index 30% rename from tutorials/training/source_zh_cn/advanced_use/auto_data_acceleration.rst rename to tutorials/training/source_zh_cn/advanced_use/nlp.rst index 003693d04b..4c766dc870 100644 --- a/tutorials/training/source_zh_cn/advanced_use/auto_data_acceleration.rst +++ b/tutorials/training/source_zh_cn/advanced_use/nlp.rst @@ -1,8 +1,8 @@ -自动数据加速 -======== +自然语言处理 +=========== .. toctree:: :maxdepth: 1 - data_processing_acceleration - cache + nlp_lstm + nlp_bert_poetry \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/bert_poetry.md b/tutorials/training/source_zh_cn/advanced_use/nlp_bert_poetry.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/bert_poetry.md rename to tutorials/training/source_zh_cn/advanced_use/nlp_bert_poetry.md index 238e968cfa..40a1569c77 100644 --- a/tutorials/training/source_zh_cn/advanced_use/bert_poetry.md +++ b/tutorials/training/source_zh_cn/advanced_use/nlp_bert_poetry.md @@ -1,10 +1,10 @@ -# 智能写诗 +# 使用BERT网络实现智能写诗 `Linux` `Ascend` `模型训练` `推理应用` `端侧` `高级` -- [智能写诗](#智能写诗) +- [使用BERT实现智能写诗](#使用bert实现智能写诗) - [案例简介](#案例简介) - [模型介绍](#模型介绍) - [模型训练](#模型训练) @@ -18,7 +18,7 @@ - [训练](#训练) - [推理验证](#推理验证) - [服务部署](#服务部署) - - [参考资料](#参考资料) + - [参考文献](#参考文献) diff --git a/tutorials/training/source_zh_cn/advanced_use/nlp_application.md b/tutorials/training/source_zh_cn/advanced_use/nlp_lstm.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/nlp_application.md rename to tutorials/training/source_zh_cn/advanced_use/nlp_lstm.md index d7b292163e..98722247eb 100644 --- a/tutorials/training/source_zh_cn/advanced_use/nlp_application.md +++ b/tutorials/training/source_zh_cn/advanced_use/nlp_lstm.md @@ -1,10 +1,10 @@ -# 自然语言处理应用 +# 使用LSTM实现情感分类 `Linux` `GPU` `CPU` `全流程` `初级` `中级` `高级` -- [自然语言处理应用](#自然语言处理应用) +- [使用LSTM实现情感分类](#使用lstm实现情感分类) - [概述](#概述) - [准备及设计](#准备及设计) - [下载数据集](#下载数据集) diff --git a/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md b/tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md rename to tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md index 4cb2224235..4e0567236d 100644 --- a/tutorials/training/source_zh_cn/advanced_use/optimize_the_performance_of_data_preparation.md +++ b/tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md @@ -1,10 +1,10 @@ -# 优化数据准备的性能 +# 优化数据处理 `Linux` `Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` -- [优化数据准备的性能](#优化数据准备的性能) +- [优化数据处理](#优化数据处理) - [概述](#概述) - [整体流程](#整体流程) - [准备环节](#准备环节) diff --git a/tutorials/training/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md b/tutorials/training/source_zh_cn/advanced_use/save_load_model_hybrid_parallel.md similarity index 99% rename from tutorials/training/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md rename to tutorials/training/source_zh_cn/advanced_use/save_load_model_hybrid_parallel.md index 394ac2947c..9b210fe417 100644 --- a/tutorials/training/source_zh_cn/advanced_use/checkpoint_for_hybrid_parallel.md +++ b/tutorials/training/source_zh_cn/advanced_use/save_load_model_hybrid_parallel.md @@ -1,12 +1,10 @@ - - -# 手动设置并行场景模型参数的保存和加载 +# 保存和加载模型(HyBrid Parallel模式) `Linux` `Ascend` `GPU` `模型训练` `中级` `高级` -- [手动设置并行场景模型参数的保存和加载](#手动设置并行场景模型参数的保存和加载) +- [保存和加载模型(HyBrid Parallel模式)](#保存和加载模型hybrid-parallel模式) - [概述](#概述) - [背景](#背景) - [使用场景](#使用场景) diff --git a/tutorials/training/source_zh_cn/advanced_use/summary_record.md b/tutorials/training/source_zh_cn/advanced_use/summary_record.md index da92ca826e..12dd5dc447 100644 --- a/tutorials/training/source_zh_cn/advanced_use/summary_record.md +++ b/tutorials/training/source_zh_cn/advanced_use/summary_record.md @@ -1,17 +1,17 @@ -# Summary数据收集 +# 收集Summary数据 `Linux` `Ascend` `GPU` `CPU` `模型调优` `中级` `高级` -- [Summary数据收集](#summary数据收集) +- [收集Summary数据](#收集summary数据) - [概述](#概述) - [操作流程](#操作流程) - [准备训练脚本](#准备训练脚本) - [方式一:通过SummaryCollector自动收集](#方式一通过summarycollector自动收集) - [方式二:结合Summary算子和SummaryCollector,自定义收集网络中的数据](#方式二结合summary算子和summarycollector自定义收集网络中的数据) - [方式三:自定义Callback记录数据](#方式三自定义callback记录数据) - - [运行MindInsight](#运行MindInsight) + - [运行MindInsight](#运行mindinsight) - [注意事项](#注意事项) diff --git a/tutorials/training/source_zh_cn/advanced_use/fuzzer.md b/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md similarity index 96% rename from tutorials/training/source_zh_cn/advanced_use/fuzzer.md rename to tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md index a1740ae530..988ce9576d 100644 --- a/tutorials/training/source_zh_cn/advanced_use/fuzzer.md +++ b/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md @@ -1,16 +1,16 @@ -# AI模型安全测试 +# 使用fuzzer模块测试模型安全性 `Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` -- [AI模型安全测试](#ai模型安全测试) +- [使用fuzzer模块测试模型安全性](#使用fuzzer模块测试模型安全性) - [概述](#概述) - [实现阶段](#实现阶段) - - [导入需要的库文件](#引入相关包) + - [导入需要的库文件](#导入需要的库文件) - [参数配置](#参数配置) - - [运用Fuzzer](#运用Fuzzer) - + - [运用Fuzzer](#运用fuzzer) +    diff --git a/tutorials/training/source_zh_cn/advanced_use/membership_inference.md b/tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md similarity index 98% rename from tutorials/training/source_zh_cn/advanced_use/membership_inference.md rename to tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md index 4f887583fb..c1bad5d744 100644 --- a/tutorials/training/source_zh_cn/advanced_use/membership_inference.md +++ b/tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md @@ -1,18 +1,19 @@ -# 成员推理攻击 +# 使用成员推理测试模型安全性 `Linux` `Ascend` `全流程` `初级` `中级` `高级` -- [成员推理攻击](#成员推理攻击) +- [使用成员推理测试模型安全性](#使用成员推理测试模型安全性) - [概述](#概述) - [实现阶段](#实现阶段) - [导入需要的库文件](#导入需要的库文件) + - [引入相关包](#引入相关包) - [加载数据集](#加载数据集) - [建立模型](#建立模型) - [运用MembershipInference](#运用membershipinference) - [参考文献](#参考文献) - +    diff --git a/tutorials/training/source_zh_cn/advanced_use/visualization_tutorials.rst b/tutorials/training/source_zh_cn/advanced_use/visualization_tutorials.rst index aeebef6943..c935f696c5 100644 --- a/tutorials/training/source_zh_cn/advanced_use/visualization_tutorials.rst +++ b/tutorials/training/source_zh_cn/advanced_use/visualization_tutorials.rst @@ -1,4 +1,4 @@ -训练过程可视化 +使用可视化组件MindInsight =============== .. toctree:: diff --git a/tutorials/training/source_zh_cn/index.rst b/tutorials/training/source_zh_cn/index.rst index 16b66adce5..5878b4a0f9 100644 --- a/tutorials/training/source_zh_cn/index.rst +++ b/tutorials/training/source_zh_cn/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore教程 +使用MindSpore进行训练 ============= .. toctree:: @@ -18,69 +18,73 @@ MindSpore教程 .. toctree:: :glob: :maxdepth: 1 - :caption: 使用指南 + :caption: 基础使用 use/data_preparation use/defining_the_network - use/saving_and_loading_model_parameters + use/save_and_load_model .. toctree:: :glob: :maxdepth: 1 - :caption: 应用实践 + :caption: 处理数据 - advanced_use/computer_vision_application - advanced_use/nlp_application - advanced_use/second_order_optimizer_for_resnet50_application - advanced_use/synchronization_training_and_evaluation - advanced_use/bert_poetry - advanced_use/optimize_the_performance_of_data_preparation - advanced_use/mobilenetv2_incremental_learning + advanced_use/converse_dataset + advanced_use/enable_cache + advanced_use/optimize_data_processing + .. toctree:: :glob: :maxdepth: 1 - :caption: 模型调优 + :caption: 构建网络 + + advanced_use/custom_operator + advanced_use/migrate_script - advanced_use/debugging_in_pynative_mode - advanced_use/customized_debugging_information +.. toctree:: + :glob: + :maxdepth: 1 + :caption: 调试网络 + + advanced_use/debug_in_pynative_mode + advanced_use/custom_debugging_info advanced_use/visualization_tutorials + advanced_use/enable_auto_augmentation + advanced_use/synchronization_training_and_evaluation .. toctree:: :glob: :maxdepth: 1 - :caption: 性能优化 + :caption: 优化训练性能 advanced_use/distributed_training_tutorials - advanced_use/mixed_precision - advanced_use/graph_kernel_fusion - advanced_use/quantization_aware - advanced_use/gradient_accumulation - advanced_use/dataset_conversion - advanced_use/auto_augmentation - advanced_use/auto_data_acceleration + advanced_use/enable_mixed_precision + advanced_use/enable_graph_kernel_fusion + advanced_use/apply_gradient_accumulation .. toctree:: :glob: :maxdepth: 1 - :caption: 云上使用 + :caption: 压缩模型 - advanced_use/use_on_the_cloud + advanced_use/apply_quantization_aware_training .. toctree:: :glob: :maxdepth: 1 - :caption: 网络迁移 + :caption: 模型安全和隐私 - advanced_use/network_migration - advanced_use/model_scripts_transformation + advanced_use/improve_model_security_nad + advanced_use/improve_model_security_differential_privacy + advanced_use/test_model_security_fuzzing + advanced_use/test_model_security_membership_inference .. toctree:: :glob: :maxdepth: 1 - :caption: AI安全和隐私 + :caption: 应用实践 - advanced_use/model_security - advanced_use/differential_privacy - advanced_use/fuzzer - advanced_use/membership_inference + advanced_use/cv + advanced_use/nlp + advanced_use/use_on_the_cloud \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/use/data_preparation.rst b/tutorials/training/source_zh_cn/use/data_preparation.rst index c7b3c2a76a..66e8e430a0 100644 --- a/tutorials/training/source_zh_cn/use/data_preparation.rst +++ b/tutorials/training/source_zh_cn/use/data_preparation.rst @@ -1,9 +1,8 @@ -准备数据 +加载数据集 ======== .. toctree:: :maxdepth: 1 - image_loading - text_loading - + load_dataset_image + load_dataset_text \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/use/defining_the_network.rst b/tutorials/training/source_zh_cn/use/defining_the_network.rst index d6d2bfba31..7b9be86a28 100644 --- a/tutorials/training/source_zh_cn/use/defining_the_network.rst +++ b/tutorials/training/source_zh_cn/use/defining_the_network.rst @@ -4,5 +4,4 @@ .. toctree:: :maxdepth: 1 - 网络支持 - custom_operator \ No newline at end of file + 网络支持 \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/use/image_loading.md b/tutorials/training/source_zh_cn/use/load_dataset_image.md similarity index 98% rename from tutorials/training/source_zh_cn/use/image_loading.md rename to tutorials/training/source_zh_cn/use/load_dataset_image.md index db5545aeb2..d0a7995e23 100644 --- a/tutorials/training/source_zh_cn/use/image_loading.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_image.md @@ -1,10 +1,10 @@ -# 加载图像 +# 加载图像数据集 `Linux` `Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` -- [加载图像](#加载图像) +- [加载图像数据集](#加载图像数据集) - [概述](#概述) - [准备](#准备) - [加载数据集](#加载数据集) diff --git a/tutorials/training/source_zh_cn/use/text_loading.md b/tutorials/training/source_zh_cn/use/load_dataset_text.md similarity index 98% rename from tutorials/training/source_zh_cn/use/text_loading.md rename to tutorials/training/source_zh_cn/use/load_dataset_text.md index 340d2c0828..0c7317b0d1 100644 --- a/tutorials/training/source_zh_cn/use/text_loading.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_text.md @@ -1,10 +1,10 @@ -# 加载文本 +# 加载文本数据集 `Linux` `Ascend` `GPU` `CPU` `数据准备` `初级` `中级` `高级` -- [加载文本](#加载文本) +- [加载文本数据集](#加载文本数据集) - [概述](#概述) - [准备](#准备) - [加载数据集](#加载数据集) diff --git a/tutorials/training/source_zh_cn/use/saving_and_loading_model_parameters.md b/tutorials/training/source_zh_cn/use/save_and_load_model.md similarity index 98% rename from tutorials/training/source_zh_cn/use/saving_and_loading_model_parameters.md rename to tutorials/training/source_zh_cn/use/save_and_load_model.md index f624b8712c..47e516cd3b 100644 --- a/tutorials/training/source_zh_cn/use/saving_and_loading_model_parameters.md +++ b/tutorials/training/source_zh_cn/use/save_and_load_model.md @@ -1,10 +1,10 @@ -# 模型参数的保存和加载 +# 保存和加载模型 `Linux` `Ascend` `GPU` `CPU` `模型导出` `初级` `中级` `高级` -- [模型参数的保存和加载](#模型参数的保存和加载) +- [保存和加载模型](#保存和加载模型) - [概述](#概述) - [模型参数保存](#模型参数保存) - [CheckPoint配置策略](#checkpoint配置策略) -- Gitee From 45f3072f2ee30696a11439d029087d7e78a71799 Mon Sep 17 00:00:00 2001 From: buxue Date: Tue, 15 Sep 2020 10:01:11 +0800 Subject: [PATCH 031/100] add restrict modify class member that is not parameter (cherry picked from commit 035e105082e895e741208607db7c1e12ae09a432) --- .../constraints_on_network_construction.md | 73 +++++++++++-------- .../constraints_on_network_construction.md | 73 +++++++++++-------- 2 files changed, 88 insertions(+), 58 deletions(-) diff --git a/docs/note/source_en/constraints_on_network_construction.md b/docs/note/source_en/constraints_on_network_construction.md index 2da31582ec..ccd96972dc 100644 --- a/docs/note/source_en/constraints_on_network_construction.md +++ b/docs/note/source_en/constraints_on_network_construction.md @@ -232,34 +232,49 @@ Currently, the following syntax is not supported in network constructors: ### Other Constraints -Input parameters of the construct function on the entire network and parameters of functions modified by the ms_function decorator are generalized during the graph compilation. Therefore, they cannot be transferred to operators as constant input. Therefore, in graph mode, the parameter passed to the entry network can only be Tensor. As shown in the following example: -* The following is an example of incorrect input: - ```python - class ExpandDimsTest(Cell): - def __init__(self): - super(ExpandDimsTest, self).__init__() - self.expandDims = P.ExpandDims() - - def construct(self, input_x, input_axis): - return self.expandDims(input_x, input_axis) - expand_dim = ExpandDimsTest() - input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) - expand_dim(input_x, 0) - ``` - In the example, ExpandDimsTest is a single-operator network with two inputs: input_x and input_axis. The second input of the ExpandDims operator must be a constant. This is because input_axis is required when the output dimension of the ExpandDims operator is deduced during graph compilation. As the network parameter input, the value of input_axis is generalized into a variable and cannot be determined. As a result, the output dimension of the operator cannot be deduced, causing the graph compilation failure. Therefore, the input required by deduction in the graph compilation phase must be a constant. In APIs, the "constant input is needed" is marked for parameters that require constant input of these operators. +1. Input parameters of the `construct` function on the entire network and parameters of functions modified by the `ms_function` decorator are generalized during the graph compilation and cannot be passed to operators as constant input. Therefore, in graph mode, the parameter passed to the entry network can only be `Tensor`. As shown in the following example: + + * The following is an example of incorrect input: + ```python + class ExpandDimsTest(Cell): + def __init__(self): + super(ExpandDimsTest, self).__init__() + self.expandDims = P.ExpandDims() + + def construct(self, input_x, input_axis): + return self.expandDims(input_x, input_axis) + expand_dim = ExpandDimsTest() + input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) + expand_dim(input_x, 0) + ``` + In the example, `ExpandDimsTest` is a single-operator network with two inputs: `input_x` and `input_axis`. The second input of the `ExpandDims` operator must be a constant. This is because `input_axis` is required when the output dimension of the `ExpandDims` operator is deduced during graph compilation. As the network parameter input, the value of `input_axis` is generalized into a variable and cannot be determined. As a result, the output dimension of the operator cannot be deduced, causing the graph compilation failure. Therefore, the input required by deduction in the graph compilation phase must be a constant. In the API, the parameters of this type of operator that require constant input will be explained, marked `const input is needed`. + + * Directly enter the needed value or a member variable in a class for the constant input of the operator in the construct function. The following is an example of correct input: + ```python + class ExpandDimsTest(Cell): + def __init__(self, axis): + super(ExpandDimsTest, self).__init__() + self.expandDims = P.ExpandDims() + self.axis = axis + + def construct(self, input_x): + return self.expandDims(input_x, self.axis) + axis = 0 + expand_dim = ExpandDimsTest(axis) + input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) + expand_dim(input_x) + ``` + +2. It is not allowed to modify `non-Parameter` type data members of the network. Examples are as follows: -* Directly enter the needed value or a member variable in a class for the constant input of the operator in the construct function. The following is an example of correct input: - ```python - class ExpandDimsTest(Cell): - def __init__(self, axis): - super(ExpandDimsTest, self).__init__() - self.expandDims = P.ExpandDims() - self.axis = axis - - def construct(self, input_x): - return self.expandDims(input_x, self.axis) - axis = 0 - expand_dim = ExpandDimsTest(axis) - input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) - expand_dim(input_x) ``` + class Net(Cell): + def __init__(self): + super(Net, self).__init__() + self.num = 2 + self.par = Parameter(Tensor(np.ones((2, 3, 4))), name="par") + + def construct(self, x, y): + return x + y + ``` +In the network defined above, `self.num` is not a `Parameter` and cannot be modified, but `self.par` is a `Parameter` and can be modified. diff --git a/docs/note/source_zh_cn/constraints_on_network_construction.md b/docs/note/source_zh_cn/constraints_on_network_construction.md index 8b352b2625..6b3b2204a0 100644 --- a/docs/note/source_zh_cn/constraints_on_network_construction.md +++ b/docs/note/source_zh_cn/constraints_on_network_construction.md @@ -231,34 +231,49 @@ tuple也支持切片取值操作, 但不支持切片类型为Tensor类型,支 ### 其他约束 -整网construct函数输入的参数以及使用ms_function装饰器修饰的函数的参数在图编译过程中会进行泛化,不能作为常量输入传给算子使用。所以,在图模式下,限制入口网络的参数只能是Tensor,如下例所示: -* 错误的写法如下: - ```python - class ExpandDimsTest(Cell): - def __init__(self): - super(ExpandDimsTest, self).__init__() - self.expandDims = P.ExpandDims() - - def construct(self, input_x, input_axis): - return self.expandDims(input_x, input_axis) - expand_dim = ExpandDimsTest() - input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) - expand_dim(input_x, 0) - ``` - 在示例中,ExpandDimsTest是一个只有单算子的网络,网络的输入有input_x和input_axis两个。因为ExpandDims算子的第二个输入需要是常量,这是因为在图编译过程中推导ExpandDims算子输出维度的时候需要用到,而input_axis作为网络参数输入会泛化成变量,无法确定其值,从而无法推导算子的输出维度导致图编译失败。所以在图编译阶段需要值推导的输入都应该是常量输入。在API中,这类算子需要常量输入的参数会进行说明,标注"constant input is needed"。 +1. 整网`construct`函数输入的参数以及使用`ms_function`装饰器修饰的函数的参数在图编译过程中会进行泛化,不能作为常量输入传给算子使用。所以,在图模式下,限制入口网络的参数只能是`Tensor`,如下例所示: + + * 错误的写法如下: + ```python + class ExpandDimsTest(Cell): + def __init__(self): + super(ExpandDimsTest, self).__init__() + self.expandDims = P.ExpandDims() + + def construct(self, input_x, input_axis): + return self.expandDims(input_x, input_axis) + expand_dim = ExpandDimsTest() + input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) + expand_dim(input_x, 0) + ``` + 在示例中,`ExpandDimsTest`是一个只有单算子的网络,网络的输入有`input_x`和`input_axis`两个。因为`ExpandDims`算子的第二个输入需要是常量,这是因为在图编译过程中推导`ExpandDims`算子输出维度的时候需要用到,而`input_axis`作为网络参数输入会泛化成变量,无法确定其值,从而无法推导算子的输出维度导致图编译失败。所以在图编译阶段需要值推导的输入都应该是常量输入。在API中,这类算子需要常量输入的参数会进行说明,标注"constant input is needed"。 + + * 正确的写法是在construct函数里面对算子的常量输入直接填入需要的值或者是一个类的成员变量,如下: + ```python + class ExpandDimsTest(Cell): + def __init__(self, axis): + super(ExpandDimsTest, self).__init__() + self.expandDims = P.ExpandDims() + self.axis = axis + + def construct(self, input_x): + return self.expandDims(input_x, self.axis) + axis = 0 + expand_dim = ExpandDimsTest(axis) + input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) + expand_dim(input_x) + ``` + +2. 不允许修改网络的非`Parameter`类型数据成员。示例如下: -* 正确的写法是在construct函数里面对算子的常量输入直接填入需要的值或者是一个类的成员变量,如下: - ```python - class ExpandDimsTest(Cell): - def __init__(self, axis): - super(ExpandDimsTest, self).__init__() - self.expandDims = P.ExpandDims() - self.axis = axis - - def construct(self, input_x): - return self.expandDims(input_x, self.axis) - axis = 0 - expand_dim = ExpandDimsTest(axis) - input_x = Tensor(np.random.randn(2,2,2,2).astype(np.float32)) - expand_dim(input_x) ``` + class Net(Cell): + def __init__(self): + super(Net, self).__init__() + self.num = 2 + self.par = Parameter(Tensor(np.ones((2, 3, 4))), name="par") + + def construct(self, x, y): + return x + y + ``` + 上面所定义的网络里,`self.num`不是一个`Parameter`,不允许被修改,而`self.par`是一个`Parameter`,可以被修改。 -- Gitee From c89620f6b4cabe024ee2824bbcc6fb373a7e19df Mon Sep 17 00:00:00 2001 From: xuanyue Date: Tue, 15 Sep 2020 21:05:31 +0800 Subject: [PATCH 032/100] add errorcode --- docs/api_cpp/source_en/errorcode_and_metatype.md | 3 +++ docs/api_cpp/source_zh_cn/errorcode_and_metatype.md | 3 +++ tutorials/lite/source_en/use/converter_tool.md | 2 ++ tutorials/lite/source_zh_cn/use/converter_tool.md | 2 ++ 4 files changed, 10 insertions(+) diff --git a/docs/api_cpp/source_en/errorcode_and_metatype.md b/docs/api_cpp/source_en/errorcode_and_metatype.md index df56621340..45b4877a85 100644 --- a/docs/api_cpp/source_en/errorcode_and_metatype.md +++ b/docs/api_cpp/source_en/errorcode_and_metatype.md @@ -13,6 +13,7 @@ Description of error code and meta type supported in MindSpore Lite. | RET_NO_CHANGE | -4 | No change. | | RET_SUCCESS_EXIT | -5 | No error but exit. | | RET_MEMORY_FAILED | -6 | Fail to create memory. | +| RET_NOT_SUPPORT | -7 | Fail to support. | | RET_OUT_OF_TENSOR_RANGE | -101 | Failed to check range. | | RET_INPUT_TENSOR_ERROR | -102 | Failed to check input tensor. | | RET_REENTRANT_ERROR | -103 | Exist executor running. | @@ -24,6 +25,8 @@ Description of error code and meta type supported in MindSpore Lite. | RET_FORMAT_ERR | -401 | Failed to check the tensor format. | | RET_INFER_ERR | -501 | Failed to infer shape. | | RET_INFER_INVALID | -502 | Invalid infer shape before runtime. | +| RET_INPUT_PARAM_INVALID | -601 | Invalid input param by user. | +| RET_INPUT_PARAM_LACK | -602 | Lack input param by user. | ## MetaType An **enum** type. diff --git a/docs/api_cpp/source_zh_cn/errorcode_and_metatype.md b/docs/api_cpp/source_zh_cn/errorcode_and_metatype.md index 4195eaedcf..59f0d81ea4 100644 --- a/docs/api_cpp/source_zh_cn/errorcode_and_metatype.md +++ b/docs/api_cpp/source_zh_cn/errorcode_and_metatype.md @@ -13,6 +13,7 @@ | RET_NO_CHANGE | -4 | 无改变。 | | RET_SUCCESS_EXIT | -5 | 无错误退出。 | | RET_MEMORY_FAILED | -6 | 创建内存失败。 | +| RET_NOT_SUPPORT | -7 | 尚未支持。 | | RET_OUT_OF_TENSOR_RANGE | -101 | 输出检查越界。 | | RET_INPUT_TENSOR_ERROR | -102 | 输入检查越界。 | | RET_REENTRANT_ERROR | -103 | 存在运行中的执行器。 | @@ -24,6 +25,8 @@ | RET_FORMAT_ERR | -401 | 张量格式检查失败。 | | RET_INFER_ERR | -501 | 维度推理失败。 | | RET_INFER_INVALID | -502 | 无效的维度推理。 | +| RET_INPUT_PARAM_INVALID | -601 | 无效的用户输入参数。 | +| RET_INPUT_PARAM_LACK | -602 | 缺少必要的输入参数。 | ## MetaType diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index cf0fca347e..99f3d5464f 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -88,6 +88,7 @@ The following describes how to use the conversion command by using several commo ``` INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! ``` +- If fail to run the conversion command, an [errorcode](https://www.mindspore.cn/lite/docs/en/master/apicc/errorcode_and_metatype.html) will be output. ### Parameter Description @@ -173,3 +174,4 @@ Several common examples are selected below to illustrate the use of conversion c ``` INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! ``` +- If fail to run the conversion command, an [errorcode](https://www.mindspore.cn/lite/docs/en/master/apicc/errorcode_and_metatype.html) will be output. diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index 62349642cf..ba77498100 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -89,6 +89,7 @@ bash build.sh -I x86_64 ``` INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! ``` +- 如果转换命令执行失败,程序会返回一个[错误码](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/errorcode_and_metatype.html)。 > 训练后量化示例请参考。 @@ -174,3 +175,4 @@ set MSLOG=INFO ``` INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! ``` +- 如果转换命令执行失败,程序会返回一个[错误码](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/errorcode_and_metatype.html)。 -- Gitee From 3ba8d20bfb95d770b89aafc8f3076d8d148f3f09 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Tue, 15 Sep 2020 18:24:29 +0800 Subject: [PATCH 033/100] Modify the conf files --- docs/api_cpp/source_en/conf.py | 60 +++++++++++++++++++ docs/api_cpp/source_zh_cn/conf.py | 65 +++++++++++++++++++++ docs/api_java/source_en/conf.py | 61 +++++++++++++++++++ docs/api_java/source_zh_cn/conf.py | 65 +++++++++++++++++++++ docs/api_python/source_zh_cn/conf.py | 2 +- docs/faq/source_en/conf.py | 58 ++++++++++++++++++ docs/faq/source_zh_cn/conf.py | 62 ++++++++++++++++++++ docs/note/source_en/conf.py | 2 - docs/note/source_zh_cn/conf.py | 4 +- docs/programming_guide/source_en/conf.py | 58 ++++++++++++++++++ docs/programming_guide/source_zh_cn/conf.py | 62 ++++++++++++++++++++ tutorials/inference/source_zh_cn/conf.py | 2 +- tutorials/lite/source_zh_cn/conf.py | 2 + tutorials/training/source_zh_cn/conf.py | 2 +- 14 files changed, 497 insertions(+), 8 deletions(-) create mode 100644 docs/api_cpp/source_en/conf.py create mode 100644 docs/api_cpp/source_zh_cn/conf.py create mode 100644 docs/api_java/source_en/conf.py create mode 100644 docs/api_java/source_zh_cn/conf.py create mode 100644 docs/faq/source_en/conf.py create mode 100644 docs/faq/source_zh_cn/conf.py create mode 100644 docs/programming_guide/source_en/conf.py create mode 100644 docs/programming_guide/source_zh_cn/conf.py diff --git a/docs/api_cpp/source_en/conf.py b/docs/api_cpp/source_en/conf.py new file mode 100644 index 0000000000..4787de3f63 --- /dev/null +++ b/docs/api_cpp/source_en/conf.py @@ -0,0 +1,60 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +# import sys +# sys.path.append('..') +# sys.path.insert(0, os.path.abspath('.')) + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/api_cpp/source_zh_cn/conf.py b/docs/api_cpp/source_zh_cn/conf.py new file mode 100644 index 0000000000..625e5acd3b --- /dev/null +++ b/docs/api_cpp/source_zh_cn/conf.py @@ -0,0 +1,65 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +# import sys +# sys.path.append('..') +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_search_language = 'zh' + +html_search_options = {'dict': '../../resource/jieba.txt'} + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/api_java/source_en/conf.py b/docs/api_java/source_en/conf.py new file mode 100644 index 0000000000..4020d50f7b --- /dev/null +++ b/docs/api_java/source_en/conf.py @@ -0,0 +1,61 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +# import sys +# sys.path.append('..') +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/api_java/source_zh_cn/conf.py b/docs/api_java/source_zh_cn/conf.py new file mode 100644 index 0000000000..e3dfb2a0a9 --- /dev/null +++ b/docs/api_java/source_zh_cn/conf.py @@ -0,0 +1,65 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +# import sys +# sys.path.append('..') +# sys.path.insert(0, os.path.abspath('.')) + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_search_language = 'zh' + +html_search_options = {'dict': '../../resource/jieba.txt'} + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/api_python/source_zh_cn/conf.py b/docs/api_python/source_zh_cn/conf.py index 2e2c89c42b..e10907fd01 100644 --- a/docs/api_python/source_zh_cn/conf.py +++ b/docs/api_python/source_zh_cn/conf.py @@ -76,7 +76,7 @@ html_theme = 'sphinx_rtd_theme' html_search_language = 'zh' -html_search_options = {'dict': '../resource/jieba.txt'} +html_search_options = {'dict': '../../resource/jieba.txt'} html_static_path = ['_static'] diff --git a/docs/faq/source_en/conf.py b/docs/faq/source_en/conf.py new file mode 100644 index 0000000000..a1fd767271 --- /dev/null +++ b/docs/faq/source_en/conf.py @@ -0,0 +1,58 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os + + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/faq/source_zh_cn/conf.py b/docs/faq/source_zh_cn/conf.py new file mode 100644 index 0000000000..95d7701759 --- /dev/null +++ b/docs/faq/source_zh_cn/conf.py @@ -0,0 +1,62 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os + + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_search_language = 'zh' + +html_search_options = {'dict': '../../resource/jieba.txt'} + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/note/source_en/conf.py b/docs/note/source_en/conf.py index 6db42071de..a1fd767271 100644 --- a/docs/note/source_en/conf.py +++ b/docs/note/source_en/conf.py @@ -48,8 +48,6 @@ exclude_patterns = [] pygments_style = 'sphinx' -autodoc_inherit_docstrings = False - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for diff --git a/docs/note/source_zh_cn/conf.py b/docs/note/source_zh_cn/conf.py index f58451f3fa..95d7701759 100644 --- a/docs/note/source_zh_cn/conf.py +++ b/docs/note/source_zh_cn/conf.py @@ -48,8 +48,6 @@ exclude_patterns = [] pygments_style = 'sphinx' -autodoc_inherit_docstrings = False - # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for @@ -59,6 +57,6 @@ html_theme = 'sphinx_rtd_theme' html_search_language = 'zh' -html_search_options = {'dict': '../resource/jieba.txt'} +html_search_options = {'dict': '../../resource/jieba.txt'} html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/programming_guide/source_en/conf.py b/docs/programming_guide/source_en/conf.py new file mode 100644 index 0000000000..a1fd767271 --- /dev/null +++ b/docs/programming_guide/source_en/conf.py @@ -0,0 +1,58 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os + + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/conf.py b/docs/programming_guide/source_zh_cn/conf.py new file mode 100644 index 0000000000..95d7701759 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/conf.py @@ -0,0 +1,62 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os + + +# -- Project information ----------------------------------------------------- + +project = 'MindSpore' +copyright = '2020, MindSpore' +author = 'MindSpore' + +# The full version, including alpha/beta/rc tags +release = 'master' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx_markdown_tables', + 'recommonmark', +] + +source_suffix = { + '.rst': 'restructuredtext', + '.md': 'markdown', +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +pygments_style = 'sphinx' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +html_search_language = 'zh' + +html_search_options = {'dict': '../../resource/jieba.txt'} + +html_static_path = ['_static'] \ No newline at end of file diff --git a/tutorials/inference/source_zh_cn/conf.py b/tutorials/inference/source_zh_cn/conf.py index c2d1fb8282..0c819a8b06 100644 --- a/tutorials/inference/source_zh_cn/conf.py +++ b/tutorials/inference/source_zh_cn/conf.py @@ -58,6 +58,6 @@ html_theme = 'sphinx_rtd_theme' html_search_language = 'zh' -html_search_options = {'dict': '../resource/jieba.txt'} +html_search_options = {'dict': '../../resource/jieba.txt'} html_static_path = ['_static'] \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/conf.py b/tutorials/lite/source_zh_cn/conf.py index c2ba20320a..b0893bf9b0 100644 --- a/tutorials/lite/source_zh_cn/conf.py +++ b/tutorials/lite/source_zh_cn/conf.py @@ -58,4 +58,6 @@ html_theme = 'sphinx_rtd_theme' html_search_language = 'zh' +html_search_options = {'dict': '../../resource/jieba.txt'} + html_static_path = ['_static'] \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/conf.py b/tutorials/training/source_zh_cn/conf.py index c2d1fb8282..0c819a8b06 100644 --- a/tutorials/training/source_zh_cn/conf.py +++ b/tutorials/training/source_zh_cn/conf.py @@ -58,6 +58,6 @@ html_theme = 'sphinx_rtd_theme' html_search_language = 'zh' -html_search_options = {'dict': '../resource/jieba.txt'} +html_search_options = {'dict': '../../resource/jieba.txt'} html_static_path = ['_static'] \ No newline at end of file -- Gitee From c90ec0ffb1e521364b0620343355deaa757869b0 Mon Sep 17 00:00:00 2001 From: Jolin Zhang46 Date: Tue, 15 Sep 2020 21:15:19 +0800 Subject: [PATCH 034/100] update lite quick start ,add image_classification and object_detection --- docs/note/source_en/image_classification.md | 33 ++++ .../images/image_classification_result.png | Bin 0 -> 338804 bytes .../source_en/images/object_detection.png | Bin 0 -> 164013 bytes docs/note/source_en/object_detection.md | 29 +++ .../note/source_zh_cn/image_classification.md | 33 ++++ .../images/image_classification_result.png | Bin 0 -> 338804 bytes .../source_zh_cn/images/object_detection.png | Bin 0 -> 164013 bytes docs/note/source_zh_cn/object_detection.md | 29 +++ .../lite/source_en/quick_start/quick_start.md | 167 +++++++++-------- .../source_zh_cn/quick_start/quick_start.md | 170 ++++++++++-------- 10 files changed, 315 insertions(+), 146 deletions(-) create mode 100644 docs/note/source_en/image_classification.md create mode 100644 docs/note/source_en/images/image_classification_result.png create mode 100644 docs/note/source_en/images/object_detection.png create mode 100644 docs/note/source_en/object_detection.md create mode 100644 docs/note/source_zh_cn/image_classification.md create mode 100644 docs/note/source_zh_cn/images/image_classification_result.png create mode 100644 docs/note/source_zh_cn/images/object_detection.png create mode 100644 docs/note/source_zh_cn/object_detection.md diff --git a/docs/note/source_en/image_classification.md b/docs/note/source_en/image_classification.md new file mode 100644 index 0000000000..4f478abb72 --- /dev/null +++ b/docs/note/source_en/image_classification.md @@ -0,0 +1,33 @@ +# Image classification + + + +## Image classification introduction + +Image classification is to identity what an image represents, to predict the object list and the probabilites. For example,the following tabel shows the classification results after mode inference. + +![image_classification](images/image_classification_result.png) + +| Category | Probability | +| ---------- | ----------- | +| plant | 0.9359 | +| flower | 0.8641 | +| tree | 0.8584 | +| houseplant | 0.7867 | + +Using MindSpore Lite to realize image classification [example](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/lite/image_classification). + +## Image classification model list + +The following table shows the data of some image classification models using MindSpore Lite inference. + +> The performance of the table below is tested on the mate30. + +| model name | link | size | precision | CPU 4 thread delay | +|-----------------------|----------|----------|----------|-----------| +| MobileNetV2 | | | | | +| LeNet | | | | | +| AlexNet | | | | | +| GoogleNet | | | | | +| ResNext50 | | | | | + diff --git a/docs/note/source_en/images/image_classification_result.png b/docs/note/source_en/images/image_classification_result.png new file mode 100644 index 0000000000000000000000000000000000000000..a7cc49f582440e31b6b5b14dbba5131bfed2a4b4 GIT binary patch literal 338804 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%0DSdJHt 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 z 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┓`DxKnX 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

    $1E)9Z<%U>B`%qOH!V7BNK2ld!+9p0 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

    $1E)9Z<%U>B`%qOH!V7BNK2ld!+9p0 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

    Cb6 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 z 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 QJs0P>Zi+IgHS&!AA20U->Hq)$ literal 0 HcmV?d00001 diff --git a/docs/note/source_zh_cn/object_detection.md b/docs/note/source_zh_cn/object_detection.md new file mode 100644 index 0000000000..c4f741a6bb --- /dev/null +++ b/docs/note/source_zh_cn/object_detection.md @@ -0,0 +1,29 @@ +# 对象检测 + + + +## 对象检测介绍 + +对象检测可以识别出图片中的对象和该对象在图片中的位置。 如:对下图使用对象检测模型的输出如下表所示,使用矩形框识别图中对象的位置并且标注出对象类别的概率,其中坐标中的4个数字分别为Xmin,Ymin,,Xmax,,Ymax;概率表示反应被检测物理的可信程度。 + +![image_classification](images/object_detection.png) + +| 类别 | 概率 | 坐标 | +| ----- | ---- | ---------------- | +| mouse | 0.78 | [10, 25, 35, 43] | + +使用MindSpore Lite实现对象检测的[示例代码](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/lite/object_detection)。 + +## 对象检测模型列表 + +下表是使用MindSpore Lite推理的部分对象检测模型的数据。 + +> 下表的性能是在mate30手机上测试的。 + +| 模型名称 | 模型链接 | 大小 | 精度 | CPU 4线程时延 | +|-----------------------|----------|----------|----------|-----------| +| SSD | | | | | +| Faster_RCNN | | | | | +| YoloV3_Darknet53 | | | | | +| Mask_RCNN | | | | | + diff --git a/tutorials/lite/source_en/quick_start/quick_start.md b/tutorials/lite/source_en/quick_start/quick_start.md index b0712f03d6..f76a8f21a0 100644 --- a/tutorials/lite/source_en/quick_start/quick_start.md +++ b/tutorials/lite/source_en/quick_start/quick_start.md @@ -54,9 +54,9 @@ The following section describes how to build and execute an on-device image clas - Android Studio 3.2 or later (Android 4.0 or later is recommended.) - Native development kit (NDK) 21.3 -- CMake 3.10.2 +- [CMake](https://cmake.org/download) 3.10.2 - Android software development kit (SDK) 26 or later -- OpenCV 4.0.0 or later (included in the sample code) +- [JDK]( https://www.oracle.com/downloads/otn-pub/java/JDK/) 1.8 or later ### Building and Running @@ -80,6 +80,8 @@ The following section describes how to build and execute an on-device image clas For details about how to connect the Android Studio to a device for debugging, see . + The mobile phone needs to be turn on "USB debugging mode" before Android Studio can recognize the mobile phone. Huawei mobile phones generally turn on "USB debugging model" in Settings > system and update > developer Options > USB debugging. + 3. Continue the installation on the Android device. After the installation is complete, you can view the content captured by a camera and the inference result. ![result](../images/lite_quick_start_app_result.png) @@ -95,23 +97,14 @@ This image classification sample program on the Android device includes a Java l ``` app -| -├── libs # library files that store MindSpore Lite dependencies -│ └── arm64-v8a -│ ├── libopencv_java4.so -│ └── libmindspore-lite.so │ -├── opencv # dependency files related to OpenCV -│ └── ... -| ├── src/main │ ├── assets # resource files -| | └── model.ms # model file +| | └── mobilenetv2.ms # model file │ | │ ├── cpp # main logic encapsulation classes for model loading and prediction -| | ├── include # header files related to MindSpore calling -| | | └── ... -│ | | +| | |── ... +| | ├── mindspore_lite_x.x.x-minddata-arm64-cpu` #MindSpore Lite version | | ├── MindSporeNetnative.cpp # JNI methods related to MindSpore calling │ | └── MindSporeNetnative.h # header file │ | @@ -119,7 +112,7 @@ app │ │ └── com.huawei.himindsporedemo │ │ ├── gallery.classify # implementation related to image processing and MindSpore JNI calling │ │ │ └── ... -│ │ └── obejctdetect # implementation related to camera enabling and drawing +│ │ └── widget # implementation related to camera enabling and drawing │ │ └── ... │ │ │ ├── res # resource files related to Android @@ -128,6 +121,7 @@ app ├── CMakeList.txt # CMake compilation entry file │ ├── build.gradle # Other Android configuration file +├── download.gradle # MindSpore version download └── ... ``` @@ -156,42 +150,40 @@ android{ Create a link to the `.so` library file in the `app/CMakeLists.txt` file: ``` -# Set MindSpore Lite Dependencies. -include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include/MindSpore) +# ============== Set MindSpore Dependencies. ============= +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/third_party/flatbuffers/include) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include/ir/dtype) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include/schema) + add_library(mindspore-lite SHARED IMPORTED ) -set_target_properties(mindspore-lite PROPERTIES - IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/libs/libmindspore-lite.so") +add_library(minddata-lite SHARED IMPORTED ) -# Set OpenCV Dependecies. -include_directories(${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni/include) -add_library(lib-opencv SHARED IMPORTED ) -set_target_properties(lib-opencv PROPERTIES - IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/libs/libopencv_java4.so") +set_target_properties(mindspore-lite PROPERTIES IMPORTED_LOCATION + ${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/lib/libmindspore-lite.so) +set_target_properties(minddata-lite PROPERTIES IMPORTED_LOCATION + ${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/lib/libminddata-lite.so) +# --------------- MindSpore Lite set End. -------------------- # Link target library. target_link_libraries( ... - mindspore-lite - lib-opencv + # --- mindspore --- + minddata-lite + mindspore-lite ... ) ``` -In this example, the download.gradle File configuration auto download ` libmindspot-lite.so `and `libopencv_ Java4.so` library file, placed in the 'app / libs / arm64-v8a' directory. +In this example, the download.gradle File configuration auto download MindSpore Lite version, placed in the `app/src/main/cpp/mindspore_lite_x.x.x-minddata-arm64-cpu` directory. Note: if the automatic download fails, please manually download the relevant library files and put them in the corresponding location. -libmindspore-lite.so [libmindspore-lite.so]( https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/libmindspore-lite.so) - -libmindspore-lite include [libmindspore-lite include]( https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/include.zip) - -libopencv_java4.so [libopencv_java4.so](https://download.mindspore.cn/model_zoo/official/lite/lib/opencv%204.4.0/libopencv_java4.so) - -libopencv include [libopencv include]( https://download.mindspore.cn/model_zoo/official/lite/lib/opencv%204.4.0/include.zip) - - +MindSpore Lite version [MindSpore Lite version]( https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/libmindspore-lite.so) ### Downloading and Deploying a Model File @@ -201,8 +193,6 @@ Note: if the automatic download fails, please manually download the relevant lib mobilenetv2.ms [mobilenetv2.ms]( https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ms) - - ### Compiling On-Device Inference Code Call MindSpore Lite C++ APIs at the JNI layer to implement on-device inference. @@ -225,10 +215,8 @@ The inference code process is as follows. For details about the complete code, s *labelEnv = labelNet; // Create context. - lite::Context *context = new lite::Context; - - context->device_ctx_.type = lite::DT_CPU; - context->thread_num_ = numThread; //Specify the number of threads to run inference + mindspore::lite::Context *context = new mindspore::lite::Context; + context->thread_num_ = num_thread; // Create the mindspore session. labelNet->CreateSessionMS(modelBuffer, bufferLen, "device label", context); @@ -253,7 +241,7 @@ The inference code process is as follows. For details about the complete code, s ```cpp // Convert the Bitmap image passed in from the JAVA layer to Mat for OpenCV processing - BitmapToMat(env, srcBitmap, matImageSrc); + BitmapToMat(env, srcBitmap, matImageSrc); // Processing such as zooming the picture size. matImgPreprocessed = PreProcessImageData(matImageSrc); @@ -278,7 +266,38 @@ The inference code process is as follows. For details about the complete code, s delete[] (dataHWC); ``` -3. Perform inference on the input tensor based on the model, obtain the output tensor, and perform post-processing. +3. Pretreat the input data. + + ```cpp + bool PreProcessImageData(const LiteMat &lite_mat_bgr, LiteMat *lite_norm_mat_ptr) { + bool ret = false; + LiteMat lite_mat_resize; + LiteMat &lite_norm_mat_cut = *lite_norm_mat_ptr; + ret = ResizeBilinear(lite_mat_bgr, lite_mat_resize, 256, 256); + if (!ret) { + MS_PRINT("ResizeBilinear error"); + return false; + } + LiteMat lite_mat_convert_float; + ret = ConvertTo(lite_mat_resize, lite_mat_convert_float, 1.0 / 255.0); + if (!ret) { + MS_PRINT("ConvertTo error"); + return false; + } + LiteMat lite_mat_cut; + ret = Crop(lite_mat_convert_float, lite_mat_cut, 16, 16, 224, 224); + if (!ret) { + MS_PRINT("Crop error"); + return false; + } + float means[3] = {0.485, 0.456, 0.406}; + float vars[3] = {1.0 / 0.229, 1.0 / 0.224, 1.0 / 0.225}; + SubStractMeanNormalize(lite_mat_cut, lite_norm_mat_cut, means, vars); + return true; + } + ``` + +4. Perform inference on the input tensor based on the model, obtain the output tensor, and perform post-processing. - Perform graph execution and on-device inference. @@ -289,7 +308,12 @@ The inference code process is as follows. For details about the complete code, s - Obtain the output data. ```cpp - auto msOutputs = mSession->GetOutputs(); + auto names = mSession->GetOutputTensorNames(); + std::unordered_map msOutputs; + for (const auto &name : names) { + auto temp_dat =mSession->GetOutputByTensorName(name); + msOutputs.insert(std::pair {name, temp_dat}); + } std::string retStr = ProcessRunnetResult(msOutputs, ret); ``` @@ -298,39 +322,34 @@ The inference code process is as follows. For details about the complete code, s std::string ProcessRunnetResult(std::unordered_map msOutputs, int runnetRet) { - // Get model output results. - std::unordered_map::iterator iter; - iter = msOutputs.begin(); - auto brach1_string = iter->first; - auto branch1_tensor = iter->second; + std::unordered_map::iterator iter; + iter = msOutputs.begin(); - int OUTPUTS_LEN = branch1_tensor->ElementsNum(); + // The mobilenetv2.ms model output just one branch. + auto outputTensor = iter->second; + int tensorNum = outputTensor->ElementsNum(); - float *temp_scores = static_cast(branch1_tensor->MutableData()); + // Get a pointer to the first score. + float *temp_scores = static_cast(outputTensor->MutableData()); - float scores[RET_CATEGORY_SUM]; - for (int i = 0; i < RET_CATEGORY_SUM; ++i) { - scores[i] = temp_scores[i]; + float scores[RET_CATEGORY_SUM]; + for (int i = 0; i < RET_CATEGORY_SUM; ++i) { + if (temp_scores[i] > 0.5) { + MS_PRINT("MindSpore scores[%d] : [%f]", i, temp_scores[i]); } + scores[i] = temp_scores[i]; + } - // Converted to text information that needs to be displayed in the APP. - std::string retStr = ""; - if (runnetRet == 0) { - for (int i = 0; i < RET_CATEGORY_SUM; ++i) { - if (scores[i] > 0.3){ - retStr += g_labels_name_map[i]; - retStr += ":"; - std::string score_str = std::to_string(scores[i]); - retStr += score_str; - retStr += ";"; - } - } - else { - MS_PRINT("MindSpore run net failed!"); - for (int i = 0; i < RET_CATEGORY_SUM; ++i) { - retStr += " :0.0;"; - } - } - return retStr; + // Score for each category. + // Converted to text information that needs to be displayed in the APP. + std::string categoryScore = ""; + for (int i = 0; i < RET_CATEGORY_SUM; ++i) { + categoryScore += labels_name_map[i]; + categoryScore += ":"; + std::string score_str = std::to_string(scores[i]); + categoryScore += score_str; + categoryScore += ";"; + } + return categoryScore; } ``` \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/quick_start/quick_start.md b/tutorials/lite/source_zh_cn/quick_start/quick_start.md index ef76d900d3..974d38de10 100644 --- a/tutorials/lite/source_zh_cn/quick_start/quick_start.md +++ b/tutorials/lite/source_zh_cn/quick_start/quick_start.md @@ -53,9 +53,9 @@ MindSpore Model Zoo中图像分类模型可[在此下载](https://download.minds - Android Studio >= 3.2 (推荐4.0以上版本) - NDK 21.3 -- CMake 3.10.2 +- [CMake](https://cmake.org/download) 3.10.2 - Android SDK >= 26 -- OpenCV >= 4.0.0 (本示例代码已包含) +- [JDK]( https://www.oracle.com/downloads/otn-pub/java/JDK/) >= 1.8 ### 构建与运行 @@ -79,10 +79,14 @@ MindSpore Model Zoo中图像分类模型可[在此下载](https://download.minds Android Studio连接设备调试操作,可参考。 + 手机需开启“USB调试模式”,Android Studio才能识别到手机。 华为手机一般在`设置->系统和更新->开发人员选项->USB调试`中打开“USB调试模式”。 + 3. 在Android设备上,点击“继续安装”,安装完即可查看到设备摄像头捕获的内容和推理结果。 ![install](../images/lite_quick_start_install.png) + + 识别结果如下图所示。 ![result](../images/lite_quick_start_app_result.png) @@ -98,29 +102,22 @@ MindSpore Model Zoo中图像分类模型可[在此下载](https://download.minds ``` app -| -├── libs # 存放MindSpore Lite依赖的库文件 -│ └── arm64-v8a -│ ├── libopencv_java4.so -│ └── libmindspore-lite.so -│ -├── opencv # opencv 相关依赖文件 -│ └── ... -| ├── src/main │ ├── assets # 资源文件 -| | └── model.ms # 存放模型文件 +| | └── mobilenetv2.ms # 存放模型文件 │ | │ ├── cpp # 模型加载和预测主要逻辑封装类 | | ├── .. +| | ├── mindspore_lite_x.x.x-minddata-arm64-cpu # MindSpore Lite版本 | | ├── MindSporeNetnative.cpp # MindSpore调用相关的JNI方法 │ | └── MindSporeNetnative.h # 头文件 +| | └── MsNetWork.cpp # MindSpore接口封装 │ | │ ├── java # java层应用代码 │ │ └── com.huawei.himindsporedemo │ │ ├── gallery.classify # 图像处理及MindSpore JNI调用相关实现 │ │ │ └── ... -│ │ └── obejctdetect # 开启摄像头及绘制相关实现 +│ │ └── widget # 开启摄像头及绘制相关实现 │ │ └── ... │ │ │ ├── res # 存放Android相关的资源文件 @@ -129,6 +126,7 @@ app ├── CMakeList.txt # cmake编译入口文件 │ ├── build.gradle # 其他Android配置文件 +├── download.gradle # 工程依赖文件下载 └── ... ``` @@ -136,19 +134,11 @@ app Android JNI层调用MindSpore C++ API时,需要相关库文件支持。可通过MindSpore Lite[源码编译](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html)生成`libmindspore-lite.so`库文件。 -本示例中,bulid过程由download.gradle文件配置自动下载`libmindspore-lite.so`以及OpenCV的`libopencv_java4.so`库文件,并放置在`app/libs/arm64-v8a`目录下。 +本示例中,build过程由download.gradle文件自动从华为服务器下载MindSpore Lite版本文件,并放置在`app/src/ main/cpp/mindspore_lite_x.x.x-minddata-arm64-cpu`目录下。 注: 若自动下载失败,请手动下载相关库文件并将其放在对应位置: -libmindspore-lite.so [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/libmindspore-lite.so) - -libmindspore-lite include文件 [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/include.zip) - -libopencv_java4.so [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/opencv%204.4.0/libopencv_java4.so) - -libopencv include文件 [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/opencv%204.4.0/include.zip) - - +MindSpore Lite版本 [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/libmindspore-lite.so) ``` android{ @@ -169,23 +159,29 @@ android{ 在`app/CMakeLists.txt`文件中建立`.so`库文件链接,如下所示。 ``` -# Set MindSpore Lite Dependencies. -include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include/MindSpore) +# ============== Set MindSpore Dependencies. ============= +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/third_party/flatbuffers/include) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include/ir/dtype) +include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/include/schema) + add_library(mindspore-lite SHARED IMPORTED ) -set_target_properties(mindspore-lite PROPERTIES - IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/libs/libmindspore-lite.so") +add_library(minddata-lite SHARED IMPORTED ) -# Set OpenCV Dependecies. -include_directories(${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni/include) -add_library(lib-opencv SHARED IMPORTED ) -set_target_properties(lib-opencv PROPERTIES - IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/libs/libopencv_java4.so") +set_target_properties(mindspore-lite PROPERTIES IMPORTED_LOCATION + ${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/lib/libmindspore-lite.so) +set_target_properties(minddata-lite PROPERTIES IMPORTED_LOCATION + ${CMAKE_SOURCE_DIR}/src/main/cpp/${MINDSPORELITE_VERSION}/lib/libminddata-lite.so) +# --------------- MindSpore Lite set End. -------------------- # Link target library. target_link_libraries( ... - mindspore-lite - lib-opencv + # --- mindspore --- + minddata-lite + mindspore-lite ... ) ``` @@ -218,13 +214,12 @@ target_link_libraries( *labelEnv = labelNet; // Create context. - lite::Context *context = new lite::Context; - context->device_ctx_.type = lite::DT_CPU; - context->thread_num_ = numThread; //Specify the number of threads to run inference + mindspore::lite::Context *context = new mindspore::lite::Context; + context->thread_num_ = num_thread; // Create the mindspore session. - labelNet->CreateSessionMS(modelBuffer, bufferLen, "device label", context); - delete(context); + labelNet->CreateSessionMS(modelBuffer, bufferLen, context); + delete (context); ``` @@ -245,7 +240,7 @@ target_link_libraries( ```cpp // Convert the Bitmap image passed in from the JAVA layer to Mat for OpenCV processing - BitmapToMat(env, srcBitmap, matImageSrc); + BitmapToMat(env, srcBitmap, matImageSrc); // Processing such as zooming the picture size. matImgPreprocessed = PreProcessImageData(matImageSrc); @@ -270,7 +265,38 @@ target_link_libraries( delete[] (dataHWC); ``` -3. 对输入Tensor按照模型进行推理,获取输出Tensor,并进行后处理。 +3. 对输入数据进行处理。 + + ```cpp + bool PreProcessImageData(const LiteMat &lite_mat_bgr, LiteMat *lite_norm_mat_ptr) { + bool ret = false; + LiteMat lite_mat_resize; + LiteMat &lite_norm_mat_cut = *lite_norm_mat_ptr; + ret = ResizeBilinear(lite_mat_bgr, lite_mat_resize, 256, 256); + if (!ret) { + MS_PRINT("ResizeBilinear error"); + return false; + } + LiteMat lite_mat_convert_float; + ret = ConvertTo(lite_mat_resize, lite_mat_convert_float, 1.0 / 255.0); + if (!ret) { + MS_PRINT("ConvertTo error"); + return false; + } + LiteMat lite_mat_cut; + ret = Crop(lite_mat_convert_float, lite_mat_cut, 16, 16, 224, 224); + if (!ret) { + MS_PRINT("Crop error"); + return false; + } + float means[3] = {0.485, 0.456, 0.406}; + float vars[3] = {1.0 / 0.229, 1.0 / 0.224, 1.0 / 0.225}; + SubStractMeanNormalize(lite_mat_cut, lite_norm_mat_cut, means, vars); + return true; + } + ``` + +4. 对输入Tensor按照模型进行推理,获取输出Tensor,并进行后处理。 - 图执行,端测推理。 @@ -281,7 +307,12 @@ target_link_libraries( - 获取输出数据。 ```cpp - auto msOutputs = mSession->GetOutputs(); + auto names = mSession->GetOutputTensorNames(); + std::unordered_map msOutputs; + for (const auto &name : names) { + auto temp_dat =mSession->GetOutputByTensorName(name); + msOutputs.insert(std::pair {name, temp_dat}); + } std::string retStr = ProcessRunnetResult(msOutputs, ret); ``` @@ -290,39 +321,34 @@ target_link_libraries( std::string ProcessRunnetResult(std::unordered_map msOutputs, int runnetRet) { - // Get model output results. - std::unordered_map::iterator iter; - iter = msOutputs.begin(); - auto brach1_string = iter->first; - auto branch1_tensor = iter->second; + std::unordered_map::iterator iter; + iter = msOutputs.begin(); - int OUTPUTS_LEN = branch1_tensor->ElementsNum(); + // The mobilenetv2.ms model output just one branch. + auto outputTensor = iter->second; + int tensorNum = outputTensor->ElementsNum(); - float *temp_scores = static_cast(branch1_tensor->MutableData()); - float scores[RET_CATEGORY_SUM]; - for (int i = 0; i < RET_CATEGORY_SUM; ++i) { - scores[i] = temp_scores[i]; - } + // Get a pointer to the first score. + float *temp_scores = static_cast(outputTensor->MutableData()); - // Converted to text information that needs to be displayed in the APP. - std::string retStr = ""; - if (runnetRet == 0) { - for (int i = 0; i < RET_CATEGORY_SUM; ++i) { - if (scores[i] > 0.3){ - retStr += g_labels_name_map[i]; - retStr += ":"; - std::string score_str = std::to_string(scores[i]); - retStr += score_str; - retStr += ";"; - } - } - else { - MS_PRINT("MindSpore run net failed!"); - for (int i = 0; i < RET_CATEGORY_SUM; ++i) { - retStr += " :0.0;"; - } - } + float scores[RET_CATEGORY_SUM]; + for (int i = 0; i < RET_CATEGORY_SUM; ++i) { + if (temp_scores[i] > 0.5) { + MS_PRINT("MindSpore scores[%d] : [%f]", i, temp_scores[i]); + } + scores[i] = temp_scores[i]; + } - return retStr; + // Score for each category. + // Converted to text information that needs to be displayed in the APP. + std::string categoryScore = ""; + for (int i = 0; i < RET_CATEGORY_SUM; ++i) { + categoryScore += labels_name_map[i]; + categoryScore += ":"; + std::string score_str = std::to_string(scores[i]); + categoryScore += score_str; + categoryScore += ";"; + } + return categoryScore; } ``` -- Gitee From 74736f1e76c539c03d55e704fce1f81d2205a008 Mon Sep 17 00:00:00 2001 From: leiyuning Date: Tue, 15 Sep 2020 21:38:33 +0800 Subject: [PATCH 035/100] optimize training_en ouline --- tutorials/lite/requirements.txt | 5 +- ...tion.md => apply_gradient_accumulation.md} | 4 +- ...ining.md => apply_host_device_training.md} | 4 +- ....md => apply_parameter_server_training.md} | 4 +- ...d => apply_quantization_aware_training.md} | 6 +- ...nformation.md => custom_debugging_info.md} | 4 +- .../advanced_use/custom_operator.rst | 6 + .../custom_operator_ascend.md} | 4 +- .../training/source_en/advanced_use/cv.rst | 7 + ...r_vision_application.md => cv_resnet50.md} | 4 +- .../source_en/advanced_use/dashboard.md | 4 +- ...tive_mode.md => debug_in_pynative_mode.md} | 4 +- .../distributed_training_tutorials.rst | 6 +- ...usion.md => enable_graph_kernel_fusion.md} | 14 +- ...precision.md => enable_mixed_precision.md} | 4 +- .../source_en/advanced_use/hub_tutorial.md | 10 +- ...ve_model_security_differential_privacy.md} | 4 +- ...urity.md => improve_model_security_nad.md} | 4 +- .../lineage_and_scalars_comparision.md | 4 +- ...rk_migration.md => migrate_3rd_scripts.md} | 4 +- .../training/source_en/advanced_use/nlp.rst | 7 + .../{nlp_application.md => nlp_lstm.md} | 0 ...aration.md => optimize_data_processing.md} | 4 +- .../advanced_use/performance_profiling.md | 3 +- .../advanced_use/performance_profiling_gpu.md | 2 +- ....md => save_load_model_hybrid_parallel.md} | 6 +- .../source_en/advanced_use/summary_record.md | 4 +- ...synchronization_training_and_evaluation.md | 4 +- tutorials/training/source_en/index.rst | 40 ++- .../source_en/quick_start/quick_start.md | 1 - .../source_en/use/data_preparation.rst | 8 + .../data_preparation/converting_datasets.md | 241 ------------- .../use/data_preparation/data_preparation.rst | 9 - .../data_processing_and_augmentation.md | 340 ------------------ .../data_preparation/loading_the_datasets.md | 262 -------------- ...l_parameters.md => save_and_load_model.md} | 0 .../apply_quantization_aware_training.md | 2 +- .../training/source_zh_cn/advanced_use/cv.rst | 2 +- ...synchronization_training_and_evaluation.md | 2 +- 39 files changed, 119 insertions(+), 924 deletions(-) rename tutorials/training/source_en/advanced_use/{gradient_accumulation.md => apply_gradient_accumulation.md} (98%) rename tutorials/training/source_en/advanced_use/{host_device_training.md => apply_host_device_training.md} (98%) rename tutorials/training/source_en/advanced_use/{parameter_server_training.md => apply_parameter_server_training.md} (98%) rename tutorials/training/source_en/advanced_use/{quantization_aware.md => apply_quantization_aware_training.md} (98%) rename tutorials/training/source_en/advanced_use/{customized_debugging_information.md => custom_debugging_info.md} (99%) create mode 100644 tutorials/training/source_en/advanced_use/custom_operator.rst rename tutorials/training/source_en/{use/custom_operator.md => advanced_use/custom_operator_ascend.md} (99%) create mode 100644 tutorials/training/source_en/advanced_use/cv.rst rename tutorials/training/source_en/advanced_use/{computer_vision_application.md => cv_resnet50.md} (98%) rename tutorials/training/source_en/advanced_use/{debugging_in_pynative_mode.md => debug_in_pynative_mode.md} (99%) rename tutorials/training/source_en/advanced_use/{graph_kernel_fusion.md => enable_graph_kernel_fusion.md} (96%) rename tutorials/training/source_en/advanced_use/{mixed_precision.md => enable_mixed_precision.md} (98%) rename tutorials/training/source_en/advanced_use/{differential_privacy.md => improve_model_security_differential_privacy.md} (99%) rename tutorials/training/source_en/advanced_use/{model_security.md => improve_model_security_nad.md} (99%) rename tutorials/training/source_en/advanced_use/{network_migration.md => migrate_3rd_scripts.md} (98%) create mode 100644 tutorials/training/source_en/advanced_use/nlp.rst rename tutorials/training/source_en/advanced_use/{nlp_application.md => nlp_lstm.md} (100%) rename tutorials/training/source_en/advanced_use/{optimize_the_performance_of_data_preparation.md => optimize_data_processing.md} (99%) rename tutorials/training/source_en/advanced_use/{checkpoint_for_hybrid_parallel.md => save_load_model_hybrid_parallel.md} (98%) create mode 100644 tutorials/training/source_en/use/data_preparation.rst delete mode 100644 tutorials/training/source_en/use/data_preparation/converting_datasets.md delete mode 100644 tutorials/training/source_en/use/data_preparation/data_preparation.rst delete mode 100644 tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md delete mode 100644 tutorials/training/source_en/use/data_preparation/loading_the_datasets.md rename tutorials/training/source_en/use/{saving_and_loading_model_parameters.md => save_and_load_model.md} (100%) diff --git a/tutorials/lite/requirements.txt b/tutorials/lite/requirements.txt index 595e6d8df7..ea17a9e736 100644 --- a/tutorials/lite/requirements.txt +++ b/tutorials/lite/requirements.txt @@ -1,4 +1,5 @@ -sphinx +sphinx >= 2.2.1, <= 2.4.4 recommonmark sphinx-markdown-tables -sphinx_rtd_theme \ No newline at end of file +sphinx_rtd_theme +jieba \ No newline at end of file diff --git a/tutorials/training/source_en/advanced_use/gradient_accumulation.md b/tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md similarity index 98% rename from tutorials/training/source_en/advanced_use/gradient_accumulation.md rename to tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md index 0cd34505ef..73724e1b4a 100644 --- a/tutorials/training/source_en/advanced_use/gradient_accumulation.md +++ b/tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md @@ -1,10 +1,10 @@ -# Gradient Accumulation +# Apply Gradient Accumulation Algorithm `Linux` `Ascend` `GPU` `Model Optimization` `Intermediate` `Expert` -- [Gradient Accumulation](#gradient-accumulation) +- [Apply Gradient Accumulation Algorithm](#apply-gradient-accumulation-algorithm) - [Overview](#overview) - [Creating a Gradient Accumulation Model](#creating-a-gradient-accumulation-model) - [Importing Library Files](#importing-library-files) diff --git a/tutorials/training/source_en/advanced_use/host_device_training.md b/tutorials/training/source_en/advanced_use/apply_host_device_training.md similarity index 98% rename from tutorials/training/source_en/advanced_use/host_device_training.md rename to tutorials/training/source_en/advanced_use/apply_host_device_training.md index 559954774a..23ab2d078f 100644 --- a/tutorials/training/source_en/advanced_use/host_device_training.md +++ b/tutorials/training/source_en/advanced_use/apply_host_device_training.md @@ -1,10 +1,10 @@ -# Host+Device Hybrid Training +# Apply Host&Device Hybrid Training `Linux` `Ascend` `CPU` `Model Training` `Intermediate` `Expert` -- [Host+Device Hybrid Training](#hostdevice-hybrid-training) +- [Apply Host&Device Hybrid Training](#apply-hostdevice-hybrid-training) - [Overview](#overview) - [Preliminaries](#preliminaries) - [Configuring for Hybrid Training](#configuring-for-hybrid-training) diff --git a/tutorials/training/source_en/advanced_use/parameter_server_training.md b/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md similarity index 98% rename from tutorials/training/source_en/advanced_use/parameter_server_training.md rename to tutorials/training/source_en/advanced_use/apply_parameter_server_training.md index 570bb28d7f..2edd972542 100644 --- a/tutorials/training/source_en/advanced_use/parameter_server_training.md +++ b/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md @@ -1,10 +1,10 @@ -# Parameter Server Training +# Train with Parameter Server `Linux` `Ascend` `GPU` `Model Training` `Intermediate` `Expert` -- [Parameter Server Training](#parameter-server-training) +- [Train with Parameter Server](#train-with-parameter-server) - [Overview](#overview) - [Preparations](#preparations) - [Training Script Preparation](#training-script-preparation) diff --git a/tutorials/training/source_en/advanced_use/quantization_aware.md b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md similarity index 98% rename from tutorials/training/source_en/advanced_use/quantization_aware.md rename to tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md index 4908573015..83bef466d0 100644 --- a/tutorials/training/source_en/advanced_use/quantization_aware.md +++ b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md @@ -1,13 +1,13 @@ -# Quantization +# Apply Quantization Aware Training `Linux` `Ascend` `GPU` `Model Optimization` `Expert` -- [Quantization](#quantization) +- [Apply Quantization Aware Training](#apply-quantization-aware-training) - [Background](#background) - [Concept](#concept) - - [Quantization](#quantization-1) + - [Quantization](#quantization) - [Fake Quantization Node](#fake-quantization-node) - [Quantization Aware Training](#quantization-aware-training) - [Quantization Aware Training Example](#quantization-aware-training-example) diff --git a/tutorials/training/source_en/advanced_use/customized_debugging_information.md b/tutorials/training/source_en/advanced_use/custom_debugging_info.md similarity index 99% rename from tutorials/training/source_en/advanced_use/customized_debugging_information.md rename to tutorials/training/source_en/advanced_use/custom_debugging_info.md index 996b1baac7..26c93ab83e 100644 --- a/tutorials/training/source_en/advanced_use/customized_debugging_information.md +++ b/tutorials/training/source_en/advanced_use/custom_debugging_info.md @@ -1,10 +1,10 @@ -# Customized Debugging Information +# Custom Debugging Information `Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` -- [Customized Debugging Information](#customized-debugging-information) +- [Custom Debugging Information](#custom-debugging-information) - [Overview](#overview) - [Introduction to Callback](#introduction-to-callback) - [Callback Capabilities of MindSpore](#callback-capabilities-of-mindspore) diff --git a/tutorials/training/source_en/advanced_use/custom_operator.rst b/tutorials/training/source_en/advanced_use/custom_operator.rst new file mode 100644 index 0000000000..a2889e7882 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/custom_operator.rst @@ -0,0 +1,6 @@ +.. toctree:: + :maxdepth: 1 + + custom_operator_ascend + Custom Operator(GPU) + Custom Operator(CPU) \ No newline at end of file diff --git a/tutorials/training/source_en/use/custom_operator.md b/tutorials/training/source_en/advanced_use/custom_operator_ascend.md similarity index 99% rename from tutorials/training/source_en/use/custom_operator.md rename to tutorials/training/source_en/advanced_use/custom_operator_ascend.md index eefd452bf8..e1243ebaa1 100644 --- a/tutorials/training/source_en/use/custom_operator.md +++ b/tutorials/training/source_en/advanced_use/custom_operator_ascend.md @@ -1,10 +1,10 @@ -# Custom Operators +# Custom Operators(Ascend) `Linux` `Ascend` `Model Development` `Expert` -- [Custom Operators](#custom-operators) +- [Custom Operators(Ascend)](#custom-operatorsascend) - [Overview](#overview) - [Registering the Operator Primitive](#registering-the-operator-primitive) - [Implementing a TBE Operator and Registering the Operator Information](#implementing-a-tbe-operator-and-registering-the-operator-information) diff --git a/tutorials/training/source_en/advanced_use/cv.rst b/tutorials/training/source_en/advanced_use/cv.rst new file mode 100644 index 0000000000..3a00c3a8b2 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/cv.rst @@ -0,0 +1,7 @@ +Computer Vision +=========== + +.. toctree:: + :maxdepth: 1 + + cv_resnet50 \ No newline at end of file diff --git a/tutorials/training/source_en/advanced_use/computer_vision_application.md b/tutorials/training/source_en/advanced_use/cv_resnet50.md similarity index 98% rename from tutorials/training/source_en/advanced_use/computer_vision_application.md rename to tutorials/training/source_en/advanced_use/cv_resnet50.md index 950540f3ae..7a262ebc00 100644 --- a/tutorials/training/source_en/advanced_use/computer_vision_application.md +++ b/tutorials/training/source_en/advanced_use/cv_resnet50.md @@ -1,10 +1,10 @@ -# Computer Vision Applications +# Image Classification Using Resnet-50 Network `Linux` `Ascend` `GPU` `Whole Process` `Beginner` `Intermediate` `Expert` -- [Computer Vision Applications](#computer-vision-applications) +- [Image Classification Using Resnet-50 Network](#image-classification-using-resnet-50-network) - [Overview](#overview) - [Image Classification](#image-classification) - [Task Description and Preparation](#task-description-and-preparation) diff --git a/tutorials/training/source_en/advanced_use/dashboard.md b/tutorials/training/source_en/advanced_use/dashboard.md index 8094cd7947..55520c7a2a 100644 --- a/tutorials/training/source_en/advanced_use/dashboard.md +++ b/tutorials/training/source_en/advanced_use/dashboard.md @@ -1,10 +1,10 @@ -# Dashboard +# View Dashboard `Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` -- [Dashboard](#dashboard) +- [View Dashboard](#view-dashboard) - [Overview](#overview) - [Scalar Visualization](#scalar-visualization) - [Parameter Distribution Visualization](#parameter-distribution-visualization) diff --git a/tutorials/training/source_en/advanced_use/debugging_in_pynative_mode.md b/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md similarity index 99% rename from tutorials/training/source_en/advanced_use/debugging_in_pynative_mode.md rename to tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md index 98c55656a9..d83c61807d 100644 --- a/tutorials/training/source_en/advanced_use/debugging_in_pynative_mode.md +++ b/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md @@ -1,10 +1,10 @@ -# Debugging in PyNative Mode +# Debug in PyNative Mode `Linux` `Ascend` `GPU` `Model Development` `Beginner` `Intermediate` `Expert` -- [Debugging in PyNative Mode](#debugging-in-pynative-mode) +- [Debug in PyNative Mode](#debug-in-pynative-mode) - [Overview](#overview) - [Executing a Single Operator](#executing-a-single-operator) - [Executing a Common Function](#executing-a-common-function) diff --git a/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst b/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst index 4807338b07..84fcdf2fc5 100644 --- a/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst +++ b/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst @@ -17,6 +17,6 @@ MindSpore also provides the parallel distributed training function. It supports :maxdepth: 1 distributed_training_ascend - host_device_training - checkpoint_for_hybrid_parallel - parameter_server_training + apply_host_device_training + apply_parameter_server_training + save_load_model_hybrid_parallel diff --git a/tutorials/training/source_en/advanced_use/graph_kernel_fusion.md b/tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md similarity index 96% rename from tutorials/training/source_en/advanced_use/graph_kernel_fusion.md rename to tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md index 25a44a0d46..abe3f20292 100644 --- a/tutorials/training/source_en/advanced_use/graph_kernel_fusion.md +++ b/tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md @@ -1,15 +1,15 @@ -# Graph Kernel Fusion +# Enable Graph Kernel Fusion `Linux` `Ascend` `Model Optimization` `Intermediate` `Expert` -- [Graph Kernel Fusion](#graph-kernel-fusion) - - [Overview](#overview) - - [Enabling Method](#enabling-method) - - [Sample Scripts](#sample-scripts) - - [Effect Evaluation](#effect-evaluation) - - [Computational Graph](#computational-graph) +- [Enable Graph Kernel Fusion](#enable-graph-kernel-fusion) + - [Overview](#overview) + - [Enabling Method](#enabling-method) + - [Sample Scripts](#sample-scripts) + - [Effect Evaluation](#effect-evaluation) + - [Computational Graph](#computational-graph) diff --git a/tutorials/training/source_en/advanced_use/mixed_precision.md b/tutorials/training/source_en/advanced_use/enable_mixed_precision.md similarity index 98% rename from tutorials/training/source_en/advanced_use/mixed_precision.md rename to tutorials/training/source_en/advanced_use/enable_mixed_precision.md index b211b1737c..bc10129a5e 100644 --- a/tutorials/training/source_en/advanced_use/mixed_precision.md +++ b/tutorials/training/source_en/advanced_use/enable_mixed_precision.md @@ -1,10 +1,10 @@ -# Mixed Precision +# Enable Mixed Precision `Linux` `Ascend` `GPU` `Model Training` `Intermediate` `Expert` -- [Mixed Precision](#mixed-precision) +- [Enable Mixed Precision](#enable-mixed-precision) - [Overview](#overview) - [Computation Process](#computation-process) - [Automatic Mixed Precision](#automatic-mixed-precision) diff --git a/tutorials/training/source_en/advanced_use/hub_tutorial.md b/tutorials/training/source_en/advanced_use/hub_tutorial.md index 26f6e5398f..963e0505d1 100644 --- a/tutorials/training/source_en/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_en/advanced_use/hub_tutorial.md @@ -5,11 +5,11 @@ - [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](#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) diff --git a/tutorials/training/source_en/advanced_use/differential_privacy.md b/tutorials/training/source_en/advanced_use/improve_model_security_differential_privacy.md similarity index 99% rename from tutorials/training/source_en/advanced_use/differential_privacy.md rename to tutorials/training/source_en/advanced_use/improve_model_security_differential_privacy.md index 13ea9770f5..ffe88955c8 100644 --- a/tutorials/training/source_en/advanced_use/differential_privacy.md +++ b/tutorials/training/source_en/advanced_use/improve_model_security_differential_privacy.md @@ -1,10 +1,10 @@ -# Differential Privacy in Machine Learning +# Improve Model Security with Differential Privacy Mechanism `Linux` `Ascend` `Model Development` `Model Optimization` `Enterprise` `Expert` -- [Differential Privacy in Machine Learning](#differential-privacy-in-machine-learning) +- [Improve Model Security with Differential Privacy Mechanism](#improve-model-security-with-differential-privacy-mechanism) - [Overview](#overview) - [Implementation](#implementation) - [Importing Library Files](#importing-library-files) diff --git a/tutorials/training/source_en/advanced_use/model_security.md b/tutorials/training/source_en/advanced_use/improve_model_security_nad.md similarity index 99% rename from tutorials/training/source_en/advanced_use/model_security.md rename to tutorials/training/source_en/advanced_use/improve_model_security_nad.md index ecfab36032..1116b2718c 100644 --- a/tutorials/training/source_en/advanced_use/model_security.md +++ b/tutorials/training/source_en/advanced_use/improve_model_security_nad.md @@ -1,10 +1,10 @@ -# Model Security +# Improve Model Security with NAD Algorithm `Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Model Development` `Model Training` `Model Optimization` `Enterprise` `Expert` -- [Model Security](#model-security) +- [Improve Model Security with NAD Algorithm](#improve-model-security-with-nad-algorithm) - [Overview](#overview) - [Creating an Target Model](#creating-an-target-model) - [Importing Related Packages](#importing-related-packages) diff --git a/tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md b/tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md index 6823b61801..919701dc4a 100644 --- a/tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md +++ b/tutorials/training/source_en/advanced_use/lineage_and_scalars_comparision.md @@ -1,10 +1,10 @@ -# Lineage and Scalars Comparision +# View Lineage and Scalars Comparision `Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` -- [Lineage and Scalars Comparision](#lineage-and-scalars-comparision) +- [View Lineage and Scalars Comparision](#view-lineage-and-scalars-comparision) - [Overview](#overview) - [Model Lineage](#model-lineage) - [Dataset Lineage](#dataset-lineage) diff --git a/tutorials/training/source_en/advanced_use/network_migration.md b/tutorials/training/source_en/advanced_use/migrate_3rd_scripts.md similarity index 98% rename from tutorials/training/source_en/advanced_use/network_migration.md rename to tutorials/training/source_en/advanced_use/migrate_3rd_scripts.md index 7f9ac4b69c..fb0ef76b02 100644 --- a/tutorials/training/source_en/advanced_use/network_migration.md +++ b/tutorials/training/source_en/advanced_use/migrate_3rd_scripts.md @@ -1,10 +1,10 @@ -# Network Migration +# Migrate Training Scripts of Third Party Frameworks `Linux` `Ascend` `GPU` `CPU` `Whole Process` `Beginner` `Intermediate` `Expert` -- [Network Migration](#network-migration) +- [Migrate Training Scripts of Third Party Frameworks](#migrate-training-scripts-of-third-party-frameworks) - [Overview](#overview) - [Preparations](#preparations) - [Operator Assessment](#operator-assessment) diff --git a/tutorials/training/source_en/advanced_use/nlp.rst b/tutorials/training/source_en/advanced_use/nlp.rst new file mode 100644 index 0000000000..1f501ac032 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/nlp.rst @@ -0,0 +1,7 @@ +Natural Language Processing +=========== + +.. toctree:: + :maxdepth: 1 + + nlp_lstm diff --git a/tutorials/training/source_en/advanced_use/nlp_application.md b/tutorials/training/source_en/advanced_use/nlp_lstm.md similarity index 100% rename from tutorials/training/source_en/advanced_use/nlp_application.md rename to tutorials/training/source_en/advanced_use/nlp_lstm.md diff --git a/tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md b/tutorials/training/source_en/advanced_use/optimize_data_processing.md similarity index 99% rename from tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md rename to tutorials/training/source_en/advanced_use/optimize_data_processing.md index 9844a4d539..b8a68f47c1 100644 --- a/tutorials/training/source_en/advanced_use/optimize_the_performance_of_data_preparation.md +++ b/tutorials/training/source_en/advanced_use/optimize_data_processing.md @@ -1,10 +1,10 @@ -# Optimizing the Data Preparation Performance +# Optimize Data Processing `Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Beginner` `Intermediate` `Expert` -- [Optimizing the Data Preparation Performance](#optimizing-the-data-preparation-performance) +- [Optimize Data Processing](#optimize-data-processing) - [Overview](#overview) - [Overall Process](#overall-process) - [Preparations](#preparations) diff --git a/tutorials/training/source_en/advanced_use/performance_profiling.md b/tutorials/training/source_en/advanced_use/performance_profiling.md index 53551b6126..a055ff95d6 100644 --- a/tutorials/training/source_en/advanced_use/performance_profiling.md +++ b/tutorials/training/source_en/advanced_use/performance_profiling.md @@ -4,9 +4,10 @@ -- [Performance Profiler(Ascend)](#performance-profiler-ascend) +- [Performance Profiler(Ascend)](#performance-profilerascend) - [Overview](#overview) - [Operation Process](#operation-process) + - [Preparing the Environment](#preparing-the-environment) - [Preparing the Training Script](#preparing-the-training-script) - [Launch MindInsight](#launch-mindinsight) - [Performance Analysis](#performance-analysis) diff --git a/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md b/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md index 7a5745fd62..7c51ece76a 100644 --- a/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md +++ b/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md @@ -4,7 +4,7 @@ -- [Performance Profiler(GPU)](#performance-profiler-gpu) +- [Performance Profiler(GPU)](#performance-profilergpu) - [Overview](#overview) - [Operation Process](#operation-process) - [Preparing the Training Script](#preparing-the-training-script) diff --git a/tutorials/training/source_en/advanced_use/checkpoint_for_hybrid_parallel.md b/tutorials/training/source_en/advanced_use/save_load_model_hybrid_parallel.md similarity index 98% rename from tutorials/training/source_en/advanced_use/checkpoint_for_hybrid_parallel.md rename to tutorials/training/source_en/advanced_use/save_load_model_hybrid_parallel.md index f9a96c3bdb..9f818e9c15 100644 --- a/tutorials/training/source_en/advanced_use/checkpoint_for_hybrid_parallel.md +++ b/tutorials/training/source_en/advanced_use/save_load_model_hybrid_parallel.md @@ -1,10 +1,10 @@ -# Saving and Loading Model Parameters in the Hybrid Parallel Scenario +# Save and Load Models in Hybrid Parallel Mode `Linux` `Ascend` `GPU` `Model Training` `Intermediate` `Expert` -- [Saving and Loading Model Parameters in the Hybrid Parallel Scenario](#saving-and-loading-model-parameters-in-the-hybrid-parallel-scenario) +- [Save and Load Models in Hybrid Parallel Mode](#save-and-load-models-in-hybrid-parallel-mode) - [Overview](#overview) - [Background](#background) - [Application Scenario](#application-scenario) @@ -12,7 +12,7 @@ - [Overall Process](#overall-process) - [Preparations](#preparations) - [Importing the Checkpoint Files in rank id order](#importing-the-checkpoint-files-in-rank-id-order) - - [Obtaining the slice strategy of model](#obtaining-the-slice-strategy-of-model) + - [Obtaining a List of All Parameters on the Network](#obtaining-a-list-of-all-parameters-on-the-network) - [Integrate the Model Parallel Parameters](#integrate-the-model-parallel-parameters) - [Saving the Data and Generating a New Checkpoint File](#saving-the-data-and-generating-a-new-checkpoint-file) - [Loading the Integrated and Saved Checkpoint File](#loading-the-integrated-and-saved-checkpoint-file) diff --git a/tutorials/training/source_en/advanced_use/summary_record.md b/tutorials/training/source_en/advanced_use/summary_record.md index 7522d87ec4..04303709ab 100644 --- a/tutorials/training/source_en/advanced_use/summary_record.md +++ b/tutorials/training/source_en/advanced_use/summary_record.md @@ -1,10 +1,10 @@ -# Summary Record +# Collect Summary Record `Linux` `Ascend` `GPU` `CPU` `Model Optimization` `Intermediate` `Expert` -- [Summary Record](#summary-record) +- [Collect Summary Record](#collect-summary-record) - [Overview](#overview) - [Operation Process](#operation-process) - [Preparing The Training Script](#preparing-the-training-script) diff --git a/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md index b818def8e5..b71b51561e 100644 --- a/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md +++ b/tutorials/training/source_en/advanced_use/synchronization_training_and_evaluation.md @@ -1,10 +1,10 @@ -# Synchronizing Model Training and Validation +# Evaluate the Model while Training `Linux` `Ascend` `GPU` `CPU` `Beginner` `Intermediate` `Expert` `Model Export` `Model Training` -- [Synchronizing Model Training and Validation](#synchronizing-model-training-and-validation) +- [Evaluate the Model while Training](#evaluate-the-model-while-training) - [Overview](#overview) - [Defining the Callback Function EvalCallBack](#defining-the-callback-function-evalcallback) - [Defining and Executing the Training Network](#defining-and-executing-the-training-network) diff --git a/tutorials/training/source_en/index.rst b/tutorials/training/source_en/index.rst index d68ca36465..fc6aa64a29 100644 --- a/tutorials/training/source_en/index.rst +++ b/tutorials/training/source_en/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore Tutorials +Train with MindSpore =================== .. toctree:: @@ -17,21 +17,29 @@ MindSpore Tutorials .. toctree:: :glob: :maxdepth: 1 - :caption: Use + :caption: Basic Use use/data_preparation/data_preparation use/defining_the_network - use/saving_and_loading_model_parameters + use/save_and_load_model .. toctree:: :glob: :maxdepth: 1 - :caption: Application + :caption: Process Data - advanced_use/computer_vision_application - advanced_use/nlp_application - advanced_use/synchronization_training_and_evaluation.md - advanced_use/optimize_the_performance_of_data_preparation.md + advanced_use/converse_dataset + advanced_use/enable_cache + advanced_use/optimize_data_processing + + +.. toctree:: + :glob: + :maxdepth: 1 + :caption: + + advanced_use/custom_operator + advanced_use/migrate_script .. toctree:: :glob: @@ -63,8 +71,18 @@ MindSpore Tutorials .. toctree:: :glob: :maxdepth: 1 - :caption: AI Security and Privacy + :caption: Model Security and Privacy - advanced_use/model_security - advanced_use/differential_privacy + advanced_use/improve_model_security_nad + advanced_use/improve_model_security_differential_privacy + +.. toctree:: + :glob: + :maxdepth: 1 + :caption: Application + + advanced_use/computer_vision_application + advanced_use/nlp_application + advanced_use/synchronization_training_and_evaluation.md + advanced_use/optimize_the_performance_of_data_preparation.md diff --git a/tutorials/training/source_en/quick_start/quick_start.md b/tutorials/training/source_en/quick_start/quick_start.md index f6d779af8a..52603ecf94 100644 --- a/tutorials/training/source_en/quick_start/quick_start.md +++ b/tutorials/training/source_en/quick_start/quick_start.md @@ -4,7 +4,6 @@ - - [Implementing an Image Classification Application](#implementing-an-image-classification-application) - [Overview](#overview) - [Preparations](#preparations) diff --git a/tutorials/training/source_en/use/data_preparation.rst b/tutorials/training/source_en/use/data_preparation.rst new file mode 100644 index 0000000000..9a9fc3d1a4 --- /dev/null +++ b/tutorials/training/source_en/use/data_preparation.rst @@ -0,0 +1,8 @@ +Load Dataset +======== + +.. toctree:: + :maxdepth: 1 + + load_dataset_image + load_dataset_text \ No newline at end of file diff --git a/tutorials/training/source_en/use/data_preparation/converting_datasets.md b/tutorials/training/source_en/use/data_preparation/converting_datasets.md deleted file mode 100644 index b1d8a21224..0000000000 --- a/tutorials/training/source_en/use/data_preparation/converting_datasets.md +++ /dev/null @@ -1,241 +0,0 @@ -# Converting Datasets to the Mindspore Data Format - -`Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Beginner` `Intermediate` `Expert` - - - -- [Converting Datasets to the Mindspore Data Format](#converting-datasets-to-the-mindspore-data-format) - - [Overview](#overview) - - [Converting Non-Standard Datasets to the Mindspore Data Format](#converting-non-standard-datasets-to-the-mindspore-data-format) - - [Converting Images and Labels](#converting-images-and-labels) - - [Converting Common Datasets to the MindSpore Data Format](#converting-common-datasets-to-the-mindspore-data-format) - - [Converting the CIFAR-10 Dataset](#converting-the-cifar-10-dataset) - - [Converting the CIFAR-100 Dataset](#converting-the-cifar-100-dataset) - - [Converting the ImageNet Dataset](#converting-the-imagenet-dataset) - - [Converting the MNIST Dataset](#converting-the-mnist-dataset) - - - - - -## Overview - -You can convert non-standard datasets and common datasets to the MindSpore data format so that they can be easily loaded to MindSpore for training. In addition, the performance of MindSpore in some scenarios is optimized, therefore using datasets in the MindSpore data format can deliver a better user experience. -The MindSpore data format has the following features: -1. Unified storage and access of user data are implemented, simplifying training data reading. -2. Data is aggregated for storage, efficient reading, and easy management and transfer. -3. Data encoding and decoding are efficient and transparent to users. -4. The partition size is flexibly controlled to implement distributed training. - -## Converting Non-Standard Datasets to the Mindspore Data Format - -MindSpore provides write operation tools to write user-defined raw data in MindSpore format. - -### Converting Images and Labels - -1. Import the `FileWriter` class for file writing. - - ```python - from mindspore.mindrecord import FileWriter - ``` - -2. Define a dataset schema which specifies dataset fields and field types. - - ```python - cv_schema_json = {"file_name": {"type": "string"}, "label": {"type": "int32"}, "data": {"type": "bytes"}} - ``` - Schema specifications are as follows: - A field name can contain only letters, digits, and underscores (_). - The field type can be int32, int64, float32, float64, string, or bytes. - The field shape can be a one-dimensional array represented by [-1], a two-dimensional array represented by [m, n], or a three-dimensional array represented by [x, y, z]. - > 1. The type of a field with the shape attribute can only be int32, int64, float32, or float64. - > 2. If the field has the shape attribute, prepare the data type as `numpy.ndarray` before transferring the data to the `write_raw_data` API. - - Examples: - - Image classification - ```python - cv_schema_json = {"file_name": {"type": "string"}, "label": {"type": "int32"}, "data": {"type": "bytes"}} - ``` - - Natural Language Processing (NLP) - ```python - cv_schema_json = {"id": {"type": "int32"}, "masks": {"type": "int32", "shape": [-1]}, "inputs": {"type": "int64", "shape": [4, 32]}, "labels": {"type": "int64", "shape": [-1]}} - ``` - -3. Prepare the data sample list to be written based on the user-defined schema format. - - ```python - data = [{"file_name": "1.jpg", "label": 0, "data": b"\x10c\xb3w\xa8\xee$o&\xd4\x00\xf8\x129\x15\xd9\xf2q\xc0\xa2\x91YFUO\x1dsE1\x1ep"}, - {"file_name": "3.jpg", "label": 99, "data": b"\xaf\xafU<\xb8|6\xbd}\xc1\x99[\xeaj+\x8f\x84\xd3\xcc\xa0,i\xbb\xb9-\xcdz\xecp{T\xb1\xdb"}] - ``` - -4. Prepare index fields. Adding index fields can accelerate data reading. This step is optional. - - ```python - indexes = ["file_name", "label"] - ``` - -5. Create a `FileWriter` object, transfer the file name and number of slices, add the schema and index, call the `write_raw_data` API to write data, and call the `commit` API to generate a local data file. - - ```python - writer = FileWriter(file_name="testWriter.mindrecord", shard_num=4) - writer.add_schema(cv_schema_json, "test_schema") - writer.add_index(indexes) - writer.write_raw_data(data) - writer.commit() - ``` - In the preceding information: - `write_raw_data`: writes data to the memory. - `commit`: writes the data in the memory to the disk. - -6. Add data to the existing data format file, call the `open_for_append` API to open the existing data file, call the `write_raw_data` API to write new data, and then call the `commit` API to generate a local data file. - ```python - writer = FileWriter.open_for_append("testWriter.mindrecord0") - writer.write_raw_data(data) - writer.commit() - ``` - -## Converting Common Datasets to the MindSpore Data Format - -MindSpore provides utility classes to convert common datasets to the MindSpore data format. The following table lists common datasets and utility classes to be called: - -| Dataset | Utility Class | -| -------- | ------------ | -| CIFAR-10 | Cifar10ToMR | -| CIFAR-100| Cifar100ToMR | -| ImageNet | ImageNetToMR | -| MNIST | MnistToMR | - - -### Converting the CIFAR-10 Dataset -You can use the `Cifar10ToMR` class to convert the raw CIFAR-10 data into the MindSpore data format. - -1. Prepare the CIFAR-10 python version dataset and decompress the file to a specified directory (the `cifar10` directory in the example), as the following shows: - ``` - % ll cifar10/cifar-10-batches-py/ - batches.meta - data_batch_1 - data_batch_2 - data_batch_3 - data_batch_4 - data_batch_5 - readme.html - test_batch - ``` - > CIFAR-10 dataset download address: - -2. Import the `Cifar10ToMR` class for dataset converting. - - ```python - from mindspore.mindrecord import Cifar10ToMR - ``` -3. Instantiate the `Cifar10ToMR` object and call the `transform` API to convert the CIFAR-10 dataset to the MindSpore data format. - - ```python - CIFAR10_DIR = "./cifar10/cifar-10-batches-py" - MINDRECORD_FILE = "./cifar10.mindrecord" - cifar10_transformer = Cifar10ToMR(CIFAR10_DIR, MINDRECORD_FILE) - cifar10_transformer.transform(['label']) - ``` - In the preceding information: - `CIFAR10_DIR`: path where the CIFAR-10 dataset folder is stored. - `MINDRECORD_FILE`: path where the output file in the MindSpore data format is stored. - -### Converting the CIFAR-100 Dataset -You can use the `Cifar100ToMR` class to convert the raw CIFAR-100 data to the MindSpore data format. - -1. Prepare the CIFAR-100 dataset and decompress the file to a specified directory (the `cifar100` directory in the example). - ``` - % ll cifar100/cifar-100-python/ - meta - test - train - ``` - > CIFAR-100 dataset download address: - -2. Import the `Cifar100ToMR` class for converting the dataset. - - ```python - from mindspore.mindrecord import Cifar100ToMR - ``` -3. Instantiate the `Cifar100ToMR` object and call the `transform` API to convert the CIFAR-100 dataset to the MindSpore data format. - - ```python - CIFAR100_DIR = "./cifar100/cifar-100-python" - MINDRECORD_FILE = "./cifar100.mindrecord" - cifar100_transformer = Cifar100ToMR(CIFAR100_DIR, MINDRECORD_FILE) - cifar100_transformer.transform(['fine_label', 'coarse_label']) - ``` - In the preceding information: - `CIFAR100_DIR`: path where the CIFAR-100 dataset folder is stored. - `MINDRECORD_FILE`: path where the output file in the MindSpore data format is stored. - -### Converting the ImageNet Dataset - -You can use the `ImageNetToMR` class to convert the raw ImageNet data (images and labels) to the MindSpore data format. - -1. Download and prepare the ImageNet dataset as required. - - > ImageNet dataset download address: - - Store the downloaded ImageNet dataset in a folder. The folder contains all images and a mapping file that records labels of the images. - - In the mapping file, there are two columns, which are separated by spaces. They indicate image classes and label IDs. The following is an example of the mapping file: - ``` - n01440760 0 - n01443537 1 - n01484850 2 - n01491361 3 - n01494475 4 - n01496331 5 - ``` - -2. Import the `ImageNetToMR` class for dataset converting. - - ```python - from mindspore.mindrecord import ImageNetToMR - ``` - -3. Instantiate the `ImageNetToMR` object and call the `transform` API to convert the dataset to the MindSpore data format. - ```python - IMAGENET_MAP_FILE = "./testImageNetDataWhole/labels_map.txt" - IMAGENET_IMAGE_DIR = "./testImageNetDataWhole/images" - MINDRECORD_FILE = "./testImageNetDataWhole/imagenet.mindrecord" - PARTITION_NUMBER = 4 - imagenet_transformer = ImageNetToMR(IMAGENET_MAP_FILE, IMAGENET_IMAGE_DIR, MINDRECORD_FILE, PARTITION_NUMBER) - imagenet_transformer.transform() - ``` - In the preceding information: - `IMAGENET_MAP_FILE`: path where the label mapping file of the ImageNetToMR dataset is stored. - `IMAGENET_IMAGE_DIR`: path where all ImageNet images are stored. - `MINDRECORD_FILE`: path where the output file in the MindSpore data format is stored. - -### Converting the MNIST Dataset -You can use the `MnistToMR` class to convert the raw MNIST data to the MindSpore data format. - -1. Prepare the MNIST dataset and save the downloaded file to a specified directory, as the following shows: - ``` - % ll mnist_data/ - train-images-idx3-ubyte.gz - train-labels-idx1-ubyte.gz - t10k-images-idx3-ubyte.gz - t10k-labels-idx1-ubyte.gz - ``` - > MNIST dataset download address: - -2. Import the `MnistToMR` class for dataset converting. - - ```python - from mindspore.mindrecord import MnistToMR - ``` -3. Instantiate the `MnistToMR` object and call the `transform` API to convert the MNIST dataset to the MindSpore data format. - - ```python - MNIST_DIR = "./mnist_data" - MINDRECORD_FILE = "./mnist.mindrecord" - mnist_transformer = MnistToMR(MNIST_DIR, MINDRECORD_FILE) - mnist_transformer.transform() - ``` - In the preceding information: - `MNIST_DIR`: path where the MNIST dataset folder is stored. - `MINDRECORD_FILE`: path where the output file in the MindSpore data format is stored. diff --git a/tutorials/training/source_en/use/data_preparation/data_preparation.rst b/tutorials/training/source_en/use/data_preparation/data_preparation.rst deleted file mode 100644 index ec222aac33..0000000000 --- a/tutorials/training/source_en/use/data_preparation/data_preparation.rst +++ /dev/null @@ -1,9 +0,0 @@ -Data Preparation -================ - -.. toctree:: - :maxdepth: 1 - - loading_the_datasets - converting_datasets - data_processing_and_augmentation \ No newline at end of file diff --git a/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md b/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md deleted file mode 100644 index 74a9ad497e..0000000000 --- a/tutorials/training/source_en/use/data_preparation/data_processing_and_augmentation.md +++ /dev/null @@ -1,340 +0,0 @@ -# Data Processing and Augmentation - -`Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Beginner` `Intermediate` `Expert` - - - -- [Data Processing and Augmentation](#data-processing-and-augmentation) - - [Overview](#overview) - - [Data Processing Operations Supported by Mindspore](#data-processing-operations-supported-by-mindspore) - - [repeat](#repeat) - - [batch](#batch) - - [shuffle](#shuffle) - - [map](#map) - - [zip](#zip) - - [Data Augmentation](#data-augmentation) - - [Using the `c_transforms` Module](#using-the-c_transforms-module) - - [Using the `py_transforms` Module](#using-the-py_transforms-module) - - - - - -## Overview - -Data is the basis of deep learning. Data input plays an important role in the deep neural network training. Therefore, after the original dataset is obtained and before data is loaded and trained, data processing or augmentation is often required due to data size and performance restrictions, to obtain optimized data input. -MindSpore provides users with data processing and augmentation functions. -> Essentially, data augmentation is implemented through the data processing operation `map`. Yet data augmentation is described separately due to its diversified transform operations. - -## Data Processing Operations Supported by Mindspore -MindSpore supports multiple data processing operations, including repeat, batch, shuffle, and map, as shown in the following table. - -| Operation | Description | -| -------- | -------------------------------------- | -| repeat | Repeat a dataset to increase the data size. | -| batch | Process data in batches to accelerate the training process. | -| shuffle | Shuffle data. | -| map | Apply the provided functions or operators to the specified column data. | -| zip | Combine multiple datasets into one dataset. | - - - -The operations can be performed separately. In practice, they are often used together as needed. You are advised to use them in the following sequence: - -![avatar](../images/dataset_pipeline.png) - -In the following example, the `shuffle`, `batch`, and `repeat` operations are performed when the MNIST dataset is read. - -```python -import mindspore.dataset as ds - -ds1 = ds.MnistDataset(MNIST_DATASET_PATH, MNIST_SCHEMA) # Create MNIST dataset. - -ds1 = ds1.shuffle(buffer_size=10000) -ds1 = ds1.batch(32, drop_remainder=True) -ds1 = ds1.repeat(10) -``` -In the preceding operations, data is shuffled, every 32 data records are combined into a batch, and then the dataset is repeated for 10 times. - -The following describes how to construct a simple dataset `ds1` and perform data processing operations on it. -1. Import the module on which data processing depends. - ```python - import mindspore.dataset as ds - ``` -2. Define the `generator_func` function for dataset generating. - ```python - def generator_func(): - for i in range(5): - yield (np.array([i, i+1, i+2]),) - ``` -3. Use `GeneratorDataset` to create the dataset `ds1` for data processing. - ```python - ds1 = ds.GeneratorDataset(generator_func, ["data"]) - print("ds1:") - for data in ds1.create_dict_iterator(): - print(data["data"]) - ``` - The output is as follows: - ``` - ds1: - [0 1 2] - [1 2 3] - [2 3 4] - [3 4 5] - [4 5 6] - ``` -### repeat -In limited datasets, to optimize the network, a dataset is usually trained for multiple times. - -![avatar](../images/repeat.png) - -> In machine learning, an epoch refers to one cycle through the full training dataset. - -During training, `repeat` can be used to increase the data size. The definition of `repeat` is as follows: -```python -def repeat(self, count=None): -``` - -You can define the dataset `ds2` and call `repeat` to increase the data size. The sample code is as follows: - -```python -ds2 = ds.GeneratorDataset(generator_func, ["data"]) -ds2 = ds2.repeat(2) -print("ds2:") -for data in ds2.create_dict_iterator(): - print(data["data"]) -``` -Set the multiple to 2. Therefore, the data size of `ds2` is twice that of the original dataset `ds1`. The output is as follows: - -``` -ds2: -[0 1 2] -[1 2 3] -[2 3 4] -[3 4 5] -[4 5 6] -[0 1 2] -[1 2 3] -[2 3 4] -[3 4 5] -[4 5 6] -``` -### batch -Combine data records in datasets into batches. In practice, data can be processed in batches. Training data in batches can reduce training steps and accelerate the training process. MindSpore uses the `batch` function to implement the batch operation. The function is defined as follows: - -![avatar](../images/batch.png) - -```python -def batch(self, batch_size, drop_remainder=False, num_parallel_workers=None) -``` - -Use the dataset `ds1` generated by GeneratorDataset to construct two datasets. -- In the first dataset `ds2`, combine every two data records into a batch. -- In the second dataset `ds3`, combine every three data records into a batch, and remove the remaining data records that are less than three. - -The sample code of `ds2` is as follows: -```python -ds2 = ds1.batch(batch_size=2) # Default drop_remainder is False, the last remainder batch isn't dropped. -print("batch size:2 drop remainder:False") -for data in ds2.create_dict_iterator(): - print(data["data"]) -``` -The output is as follows: -``` -batch size:2 drop remainder:False -[[0 1 2] - [1 2 3]] -[[2 3 4] - [3 4 5]] -[[4 5 6]] -``` - -The sample code of `ds3` is as follows: -```python -ds3 = ds1.batch(batch_size=3, drop_remainder=True) # When drop_remainder is True, the last remainder batch will be dropped. -print("batch size:3 drop remainder:True") -for data in ds3.create_dict_iterator(): - print(data["data"]) -``` -The output is as follows: -``` -batch size:3 drop remainder:True -[[0 1 2] - [1 2 3] - [2 3 4]] -``` -### shuffle -You can shuffle ordered or repeated datasets. - -![avatar](../images/shuffle.png) - -The shuffle operation is used to shuffle data. A larger value of buffer_size indicates a higher shuffling degree, consuming more time and computing resources. -The definition of `shuffle` is as follows: -```python -def shuffle(self, buffer_size): -``` -Call `shuffle` to shuffle the dataset `ds1`. The sample code is as follows: - -```python -print("Before shuffle:") -for data in ds1.create_dict_iterator(): - print(data["data"]) - -ds2 = ds1.shuffle(buffer_size=5) -print("After shuffle:") -for data in ds2.create_dict_iterator(): - print(data["data"]) -``` -The possible output is as follows. After data is shuffled, the data sequence changes randomly. -``` -Before shuffle: -[0 1 2] -[1 2 3] -[2 3 4] -[3 4 5] -[4 5 6] -After shuffle: -[3 4 5] -[2 3 4] -[4 5 6] -[1 2 3] -[0 1 2] -``` -### map -The map operation is used to process data. For example, convert the dataset of color images into the dataset of grayscale images. You can flexibly perform the operation as required. -MindSpore provides the `map` function to map datasets. You can apply the provided functions or operators to the specified column data. -You can customize the function or use `c_transforms` or `py_transforms` for data augmentation. -> For details about data augmentation operations, see Data Augmentation section. - -![avatar](../images/map.png) - -The definition of `map` is as follows: - -```python -def map(self, input_columns=None, operations=None, output_columns=None, columns_order=None, - num_parallel_workers=None): -``` -In the following example, the `map` function is used to apply the defined anonymous function (lambda function) to the dataset `ds1` so that the data values in the dataset are multiplied by 2. -```python -func = lambda x : x*2 # Define lambda function to multiply each element by 2. -ds2 = ds1.map(operations=func, input_columns="data") -for data in ds2.create_dict_iterator(): - print(data["data"]) -``` -The code output is as follows. Data values in each row of the dataset `ds2` is multiplied by 2. -``` -[0 2 4] -[2 4 6] -[4 6 8] -[6 8 10] -[8 10 12] -``` -### zip -MindSpore provides the `zip` function to combine multiple datasets into one dataset. - -![avatar](../images/zip.png) - -> If the column names in the two datasets are the same, the two datasets are not combined. Therefore, pay attention to column names. -> If the number of rows in the two datasets is different, the number of rows after combination is the same as the smaller number. -```python -def zip(self, datasets): -``` -1. Use the preceding construction method of the dataset `ds1` to construct the dataset `ds2`. - ```python - def generator_func2(): - for i in range(5): - yield (np.array([i-3, i-2, i-1]),) - - ds2 = ds.GeneratorDataset(generator_func2, ["data2"]) - ``` - -2. Use `zip()` to combine the `data` column of the dataset `ds1`and the `data2` column of the dataset `ds2` into the dataset `ds3`. - ```python - ds3 = ds.zip((ds1, ds2)) - for data in ds3.create_dict_iterator(): - print(data) - ``` - The output is as follows: - ``` - {'data': array([0, 1, 2], dtype=int64), 'data2': array([-3, -2, -1], dtype=int64)} - {'data': array([1, 2, 3], dtype=int64), 'data2': array([-2, -1, 0], dtype=int64)} - {'data': array([2, 3, 4], dtype=int64), 'data2': array([-1, 0, 1], dtype=int64)} - {'data': array([3, 4, 5], dtype=int64), 'data2': array([0, 1, 2], dtype=int64)} - {'data': array([4, 5, 6], dtype=int64), 'data2': array([1, 2, 3], dtype=int64)} - ``` -## Data Augmentation -During image training, especially when the dataset size is relatively small, you can preprocess images by using a series of data augmentation operations, thereby enriching the datasets. -MindSpore provides the `c_transforms` and `py_transforms` module functions for users to perform data augmentation. You can also customize functions or operators to perform data augmentation. The following table describes the two modules provided by MindSpore. For details, see the related description in the API reference document. - -| Module | Implementation | Description | -| ---------------| ------------------------------------------------------ | --- | -| `c_transforms` | C++-based [OpenCV](https://opencv.org/) implementation | The performance is high. | -| `py_transforms` | Python-based [PIL](https://pypi.org/project/Pillow/) implementation | This module provides multiple image augmentation functions and the method for converting between PIL images and NumPy arrays. | - -For users who would like to use Python PIL in image learning tasks, the `py_transforms` module is a good tool for image augmentation. You can use Python PIL to customize extensions. -Data augmentation requires the `map` function. For details about how to use the `map` function, see [map](#map). - -### Using the `c_transforms` Module - -1. Import the module to the code. - ```python - from mindspore.dataset.vision import Inter - import mindspore.dataset.vision.c_transforms as transforms - import matplotlib.pyplot as plt - ``` -2. Define data augmentation operators. The following uses `Resize` as an example: - ```python - # path to imagefolder directory. This directory needs to contain sub-directories which contain the images - DATA_DIR = "/path/to/imagefolder_directory" - dataset = ds.ImageFolderDataset(DATA_DIR, decode=True) # Decode images. - resize_op = transforms.Resize(size=(500,500), interpolation=Inter.LINEAR) - dataset.map(operations=resize_op, input_columns="image") - - for data in dataset.create_dict_iterator(): - imgplot_resized = plt.imshow(data["image"]) - plt.show() - ``` -The running result shows that the original image is changed from 1024 x 683 pixels to 500 x 500 pixels after data processing by using `Resize`. -![avatar](../images/image.png) - -Figure 1: Original image - -![avatar](../images/image_resized.png) - -Figure 2: Image after its size is reset - -### Using the `py_transforms` Module - -1. Import the module to the code. - ```python - import mindspore.dataset.vision.py_transforms as transforms - from mindspore.transforms.py_transforms import Compose - import matplotlib.pyplot as plt - ``` -2. Define data augmentation operators and use the `Compose` API to combine multiple data augmentation operations. The following uses `RandomCrop` as an example: - ```python - # path to imagefolder directory. This directory needs to contain sub-directories which contain the images - DATA_DIR = "/path/to/imagefolder_directory" - dataset = ds.ImageFolderDataset(DATA_DIR) - - transforms_list = [ - transforms.Decode(), # Decode images to PIL format. - transforms.RandomCrop(size=(500,500)), - transforms.ToTensor() # Convert PIL images to Numpy ndarray. - ] - compose = Compose(transforms_list) - dataset = dataset.map(operations=compose, input_columns="image") - for data in dataset.create_dict_iterator(): - print(data["image"]) - imgplot_resized = plt.imshow(data["image"].transpose(1, 2, 0)) - plt.show() - ``` - -The running result shows that the original image is changed from 1024 x 683 pixels to 500 x 500 pixels after data processing by using `RandomCrop`. -![avatar](../images/image.png) - -Figure 1: Original image - -![avatar](../images/image_random_crop.png) - -Figure 2: 500 x 500 image that is randomly cropped from the original image diff --git a/tutorials/training/source_en/use/data_preparation/loading_the_datasets.md b/tutorials/training/source_en/use/data_preparation/loading_the_datasets.md deleted file mode 100644 index ad339502f6..0000000000 --- a/tutorials/training/source_en/use/data_preparation/loading_the_datasets.md +++ /dev/null @@ -1,262 +0,0 @@ -# Loading the Dataset - -`Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Beginner` `Intermediate` `Expert` - - - -- [Loading the Dataset](#loading-the-dataset) - - [Overview](#overview) - - [Loading Common Datasets](#loading-common-datasets) - - [Loading Datasets of a Specific Data Format](#loading-datasets-of-a-specific-data-format) - - [MindSpore Data Format](#mindspore-data-format) - - [`Manifest` Data Format](#manifest-data-format) - - [`TFRecord` Data Format](#tfrecord-data-format) - - [Loading a Custom Dataset](#loading-a-custom-dataset) - - - - - -## Overview - -MindSpore helps you load common datasets, datasets of specific data formats, or custom datasets. Before loading a dataset, you need to import the required library `mindspore.dataset`. -```python -import mindspore.dataset as ds -``` - -## Loading Common Datasets -MindSpore can load common standard datasets. The following table lists the supported datasets: - -| Dataset | Description | -| --------- | -------------------------------------------------------------------------------------------------------------------------- | -| ImageNet | An image database organized based on the WordNet hierarchical structure. Each node in the hierarchical structure is represented by hundreds of images. | -| MNIST | A large database of handwritten digit images, which is usually used to train various image processing systems. | -| CIFAR-10 | A collection of images that are commonly used to train machine learning and computer vision algorithms. The CIFAR-10 dataset contains 60,000 32x32 color images in 10 different classes. | -| CIFAR-100 | The dataset is similar to CIFAR-10. The difference is that this dataset has 100 classes, and each class contains 600 images, including 500 training images and 100 test images. | -| PASCAL-VOC | The data content is diversified and can be used to train computer vision models (such as classification, positioning, detection, segmentation, and action recognition). | -| CelebA | CelebA face dataset contains tens of thousands of face images of celebrities with 40 attribute annotations, which are usually used for face-related training tasks. | - -The procedure for loading common datasets is as follows. The following describes how to create the `CIFAR-10` object to load supported datasets. - -1. Download and decompress the [CIFAR-10 Dataset](https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz). The dataset in binary format (CIFAR-10 binary version) is used. -2. Configure the dataset directory and define the dataset instance to be loaded. - ```python - DATA_DIR = "cifar10_dataset_dir/" - - cifar10_dataset = ds.Cifar10Dataset(DATA_DIR) - ``` -3. Create an iterator and read data through the iterator. - ```python - for data in cifar10_dataset.create_dict_iterator(): - # In CIFAR-10 dataset, each dictionary of data has keys "image" and "label". - print(data["image"]) - print(data["label"]) - ``` - -## Loading Datasets of a Specific Data Format - -### MindSpore Data Format -MindSpore supports reading datasets stored in MindSpore data format, such as reading datasets stored in `MindRecord`. By this nature, MindSpore may have better performance and characteristics. -> For details about how to convert datasets to the MindSpore data format, see [Converting the Dataset to MindSpore Data Format](converting_datasets.md). - -To read a dataset using the `MindDataset` object, perform the following steps: - -1. Create `MindDataset` for reading data. - ```python - import os - CV_FILE_NAME = os.path.join(MODULE_PATH, "./imagenet.mindrecord") - data_set = ds.MindDataset(dataset_file=CV_FILE_NAME) - ``` - In the preceding information: - `dataset_file`: specifies the MindRecord file or the list of MindRecord files. - -2. Create a dictionary iterator and read data records through the iterator. - ```python - num_iter = 0 - for data in data_set.create_dict_iterator(): - print(data["label"]) - num_iter += 1 - ``` - -### `Manifest` Data Format -`Manifest` is a data format file supported by Huawei ModelArts. For details, see . - -MindSpore provides dataset classes for datasets in `Manifest` format. Run the following commands to configure the dataset directory and define the dataset instance to be loaded: -```python -DATA_DIR = "manifest_dataset_path" - -manifest_dataset = ds.ManifestDataset(DATA_DIR) -``` -Currently, ManifestDataset supports only datasets of images and labels. The default column names are 'image' and 'label'. - -### `TFRecord` Data Format -MindSpore can also read datasets in the `TFRecord` data format through the `TFRecordDataset` object. - -1. Input the dataset path or the .tfrecord file list to create the `TFRecordDataset`. - ```python - DATA_DIR = ["tfrecord_dataset_path/train-0000-of-0001.tfrecord"] - - dataset = ds.TFRecordDataset(DATA_DIR) - ``` - -2. Create schema files or schema classes to set the dataset format and features. - - The following is an example of the schema file: - - ``` - { - "datasetType": "TF", - "numRows": 3, - "columns": { - "image": { - "type": "uint8", - "rank": 1 - }, - "label" : { - "type": "int64", - "rank": 1 - } - } - } - ``` - In the preceding information: - `datasetType`: data format. TF indicates the TFRecord data format. - `columns`: column information field, which is defined based on the actual column names of the dataset. In the preceding schema file example, the dataset columns are 'image' and 'label'. - `numRows`: row information field, which controls the maximum number of rows for loading data. If the number of defined rows is greater than the actual number of rows, the actual number of rows prevails during loading. - - When creating the TFRecordDataset, input the schema file path. An example is as follows: - ```python - DATA_DIR = ["tfrecord_dataset_path/train-0000-of-0001.tfrecord"] - SCHEMA_DIR = "dataset_schema_path/schema.json" - - dataset = ds.TFRecordDataset(DATA_DIR, schema=SCHEMA_DIR) - ``` - - An example of creating a schema class is as follows: - ```python - import mindspore.common.dtype as mstype - schema = ds.Schema() - schema.add_column('image', de_type=mstype.uint8) # Binary data usually use uint8 here. - schema.add_column('label', de_type=mstype.int32) - - dataset = ds.TFRecordDataset(DATA_DIR, schema=schema) - ``` - -3. Create a dictionary iterator and read data through the iterator. - ```python - for data in dataset.create_dict_iterator(): - # The dictionary of data has keys "image" and "label" which are consistent with columns names in its schema. - print(data["image"]) - print(data["label"]) - ``` - -## Loading a Custom Dataset -In real scenarios, there are various datasets. For a custom dataset or a dataset that cannot be loaded by APIs directly, there are two ways. -One is to convert the dataset to MindSpore data format (for details, see [Converting Datasets to the Mindspore Data Format](https://www.mindspore.cn/tutorial/en/master/use/data_preparation/converting_datasets.html)). The other one is to use the `GeneratorDataset` object. -The following shows how to use `GeneratorDataset`. - -1. Define an iterable object to generate a dataset. There are two examples following. One is a customized function which contains `yield`. The other one is a customized class which contains `__getitem__`. - Both of them will generate a dataset with numbers from 0 to 9. - > The custom iterable object returns a tuple of `numpy arrays` as a row of data each time. - - An example of a custom function is as follows: - ```python - import numpy as np # Import numpy lib. - def generator_func(num): - for i in range(num): - yield (np.array([i]),) # Notice, tuple of only one element needs following a comma at the end. - ``` - An example of a custom class is as follows: - ```python - import numpy as np # Import numpy lib. - class Generator(): - - def __init__(self, num): - self.num = num - - def __getitem__(self, item): - return (np.array([item]),) # Notice, tuple of only one element needs following a comma at the end. - - def __len__(self): - return self.num - ``` - -2. Create a dataset with `GeneratorDataset`. Transfer `generator_func` to `GeneratorDataset` to create a dataset and set `column` to `data`. -Define a `Generator` and transfer it to `GeneratorDataset` to create a dataset and set `column` to `data`. - ```python - dataset1 = ds.GeneratorDataset(source=generator_func(10), column_names=["data"], shuffle=False) - dataset2 = ds.GeneratorDataset(source=Generator(10), column_names=["data"], shuffle=False) - ``` - -3. After creating a dataset, create an iterator for the dataset to obtain the corresponding data. Iterator creation methods are as follows: - - Create an iterator whose return value is a sequence type. As shown in the following, create the iterators for `dataset1` and `dataset2`, and print the output. - ```python - print("dataset1:") - for data in dataset1.create_tuple_iterator(): # each data is a sequence - print(data[0]) - - print("dataset2:") - for data in dataset2.create_tuple_iterator(): # each data is a sequence - print(data[0]) - ``` - The output is as follows: - ``` - dataset1: - [array([0], dtype=int64)] - [array([1], dtype=int64)] - [array([2], dtype=int64)] - [array([3], dtype=int64)] - [array([4], dtype=int64)] - [array([5], dtype=int64)] - [array([6], dtype=int64)] - [array([7], dtype=int64)] - [array([8], dtype=int64)] - [array([9], dtype=int64)] - dataset2: - [array([0], dtype=int64)] - [array([1], dtype=int64)] - [array([2], dtype=int64)] - [array([3], dtype=int64)] - [array([4], dtype=int64)] - [array([5], dtype=int64)] - [array([6], dtype=int64)] - [array([7], dtype=int64)] - [array([8], dtype=int64)] - [array([9], dtype=int64)] - ``` - - - Create an iterator whose return value is a dictionary type. As shown in the following, create the iterators for `dataset1` and `dataset2`, and print the output. - ```python - print("dataset1:") - for data in dataset1.create_dict_iterator(): # each data is a dictionary - print(data["data"]) - - print("dataset2:") - for data in dataset2.create_dict_iterator(): # each data is a dictionary - print(data["data"]) - ``` - The output is as follows: - ``` - dataset1: - {'data': array([0], dtype=int64)} - {'data': array([1], dtype=int64)} - {'data': array([2], dtype=int64)} - {'data': array([3], dtype=int64)} - {'data': array([4], dtype=int64)} - {'data': array([5], dtype=int64)} - {'data': array([6], dtype=int64)} - {'data': array([7], dtype=int64)} - {'data': array([8], dtype=int64)} - {'data': array([9], dtype=int64)} - dataset2: - {'data': array([0], dtype=int64)} - {'data': array([1], dtype=int64)} - {'data': array([2], dtype=int64)} - {'data': array([3], dtype=int64)} - {'data': array([4], dtype=int64)} - {'data': array([5], dtype=int64)} - {'data': array([6], dtype=int64)} - {'data': array([7], dtype=int64)} - {'data': array([8], dtype=int64)} - {'data': array([9], dtype=int64)} - ``` \ No newline at end of file diff --git a/tutorials/training/source_en/use/saving_and_loading_model_parameters.md b/tutorials/training/source_en/use/save_and_load_model.md similarity index 100% rename from tutorials/training/source_en/use/saving_and_loading_model_parameters.md rename to tutorials/training/source_en/use/save_and_load_model.md diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md index abf3180fc0..fc7a7b9182 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md @@ -1,4 +1,4 @@ -# 感知量化训练 +# 应用感知量化训练 `Linux` `Ascend` `GPU` `模型调优` `高级` diff --git a/tutorials/training/source_zh_cn/advanced_use/cv.rst b/tutorials/training/source_zh_cn/advanced_use/cv.rst index e8fbeb5f30..f352741fe7 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cv.rst +++ b/tutorials/training/source_zh_cn/advanced_use/cv.rst @@ -1,4 +1,4 @@ -机器视觉类 +机器视觉 =========== .. toctree:: diff --git a/tutorials/training/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md b/tutorials/training/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md index df6dad7351..f27d6a0703 100644 --- a/tutorials/training/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md +++ b/tutorials/training/source_zh_cn/advanced_use/synchronization_training_and_evaluation.md @@ -1,4 +1,4 @@ -# 同步训练和验证模型 +# 训练时验证模型 `Linux` `Ascend` `GPU` `CPU` `初级` `中级` `高级` `模型导出` `模型训练` -- Gitee From f079e137a0b55127394adf687e04fc97829ab0cf Mon Sep 17 00:00:00 2001 From: caifubi Date: Wed, 16 Sep 2020 09:57:12 +0800 Subject: [PATCH 036/100] fix bug --- .../advanced_use/customized_debugging_information.md | 2 +- .../advanced_use/customized_debugging_information.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/customized_debugging_information.md b/tutorials/training/source_en/advanced_use/customized_debugging_information.md index 996b1baac7..878d7a067f 100644 --- a/tutorials/training/source_en/advanced_use/customized_debugging_information.md +++ b/tutorials/training/source_en/advanced_use/customized_debugging_information.md @@ -338,7 +338,7 @@ The input and output of the operator can be saved for debugging through the data ``` - `dump_mode`:0:dump all kernels in graph, 1: dump kernels in kernels list. - - `path`:Relative path where dump data saves. eg:data will be saved in `/var/log/npu/ide_deam/dump/relative_path`. + - `path`:Relative path where dump data saves. eg:data will be saved in `/var/log/npu/ide_daemon/dump/relative_path`. - `net_name`:net name eg:ResNet50. - `iteration`:Specify the iterations to dump. Iteration should be set to 0 when dataset_sink_mode is False and data of every iteration will be dumped. - `input_output`:0:dump input and output of kernel, 1:dump input of kernel, 2:dump output of kernel. diff --git a/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md b/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md index 57f34688e9..73764773a6 100644 --- a/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md +++ b/tutorials/training/source_zh_cn/advanced_use/customized_debugging_information.md @@ -328,7 +328,7 @@ val:[[1 1] { "common_dump_settings": { "dump_mode": 0, - "path": "/test", + "path": "/relative_path", "net_name": "ResNet50", "iteration": 0, "input_output": 0, @@ -343,7 +343,7 @@ val:[[1 1] ``` - `dump_mode`:设置成0,表示Dump出改网络中的所有算子;设置成1,表示Dump`"kernels"`里面指定的算子。 - - `path`:Dump保存数据的相对路径,异步Dump生成的数据都会保存在`/var/log/npu/ide_deam/dump/`目录下。 + - `path`:Dump保存数据的相对路径,异步Dump生成的数据都会保存在`/var/log/npu/ide_daemon/dump/relative_path`目录下。 - `net_name`:自定义的网络名称,例如:"ResNet50"。 - `iteration`:指定需要Dump的迭代。非数据下沉模式下,`iteration`需要设置成0,并且会Dump出每个迭代的数据。 - `input_output`:设置成0,表示Dump出算子的输入和算子的输出;设置成1,表示Dump出算子的输入;设置成2,表示Dump出算子的输出。 -- Gitee From 0daa0061a5f0c5d9c9a14a8c8dace377af8c53e4 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Wed, 16 Sep 2020 09:58:40 +0800 Subject: [PATCH 037/100] Modify the .gitignore file --- .gitignore | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 5cd9b811d9..e6af4aa9f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,20 @@ # Built html files -api/build_en -api/build_zh_cn -docs/build_en -docs/build_zh_cn -tutorials/build_en -tutorials/build_zh_cn +docs/api_cpp/build_en +docs/api_cpp/build_zh_cn +docs/api_java/build_en +docs/api_java/build_zh_cn +docs/api_python/build_en +docs/api_python/build_zh_cn +docs/faq/build_en +docs/faq/build_zh_cn +docs/note/build_en +docs/note/build_zh_cn +docs/programming_guide/build_en +docs/programming_guide/build_zh_cn +tutorials/inference/build_en +tutorials/inference/build_zh_cn +tutorials/training/build_en +tutorials/training/build_zh_cn # Workspace .idea/ -- Gitee From dbdf9e59ed8dbb811667f3332dd5880856cfcbea Mon Sep 17 00:00:00 2001 From: leiyuning Date: Wed, 16 Sep 2020 11:52:43 +0800 Subject: [PATCH 038/100] update index.rst --- docs/api_cpp/source_en/apicc.rst | 12 ----------- .../source_en/index.rst} | 19 ++++++++++-------- docs/api_cpp/source_zh_cn/apicc.rst | 12 ----------- docs/api_cpp/source_zh_cn/index.rst | 18 +++++++++++++++++ .../source_en/index.rst} | 14 ++++++------- docs/faq/source_zh_cn/index.rst | 13 ++++++++++++ docs/note/source_en/community.rst | 2 +- docs/note/source_en/design.rst | 4 ++-- .../{ => design/mindspore}/architecture.md | 2 +- .../mindspore}/architecture_lite.md | 2 +- .../images/MindSpore-Lite-architecture.png | Bin .../mindspore}/images/architecture.eddx | Bin .../mindspore}/images/architecture.png | Bin .../design/mindspore/{ir.md => mindir.md} | 0 docs/note/source_en/glossary.md | 4 +++- docs/note/source_en/glossary_lite.md | 14 ------------- docs/note/source_en/index.rst | 15 ++++---------- docs/note/source_en/others.rst | 11 ++++++++++ docs/note/source_en/specification_note.rst | 9 +++++++++ docs/note/source_zh_cn/design.rst | 8 ++++---- .../{ => design/mindspore}/architecture.md | 6 +++--- .../mindspore}/architecture_lite.md | 4 ++-- .../images/MindSpore-Lite-architecture.png | Bin .../mindspore}/images/architecture.eddx | Bin .../mindspore}/images/architecture.png | Bin .../design/mindspore/{ir.md => mindir.md} | 0 .../{ => design}/technical_white_paper.md | 0 docs/note/source_zh_cn/glossary.md | 3 +++ docs/note/source_zh_cn/glossary_lite.md | 14 ------------- docs/note/source_zh_cn/help_seeking_path.md | 2 +- docs/note/source_zh_cn/index.rst | 13 +++--------- docs/note/source_zh_cn/others.rst | 11 ++++++++++ docs/note/source_zh_cn/specification_note.rst | 9 +++++++++ .../source_en/network_list.md | 0 .../source_en/operator_list.md | 0 .../source_en/operator_list_lite.md | 0 .../source_zh_cn/network_list.md | 0 .../source_zh_cn/operator_list.md | 0 .../source_zh_cn/operator_list_lite.md | 0 tutorials/inference/source_en/index.rst | 6 +++--- .../{use => }/multi_platform_inference.md | 0 .../source_en/{advanced_use => }/serving.md | 0 tutorials/inference/source_zh_cn/index.rst | 10 ++++----- .../{use => }/multi_platform_inference.md | 2 +- .../{advanced_use => }/serving.md | 0 tutorials/lite/source_en/index.rst | 6 +++--- tutorials/lite/source_en/{ => use}/build.md | 0 tutorials/lite/source_zh_cn/index.rst | 8 ++++---- .../lite/source_zh_cn/{ => use}/build.md | 0 49 files changed, 132 insertions(+), 121 deletions(-) delete mode 100644 docs/api_cpp/source_en/apicc.rst rename docs/{note/source_en/index_lite.rst => api_cpp/source_en/index.rst} (48%) delete mode 100644 docs/api_cpp/source_zh_cn/apicc.rst create mode 100644 docs/api_cpp/source_zh_cn/index.rst rename docs/{note/source_zh_cn/index_lite.rst => faq/source_en/index.rst} (51%) create mode 100644 docs/faq/source_zh_cn/index.rst rename docs/note/source_en/{ => design/mindspore}/architecture.md (94%) rename docs/note/source_en/{ => design/mindspore}/architecture_lite.md (95%) rename docs/note/source_en/{ => design/mindspore}/images/MindSpore-Lite-architecture.png (100%) rename docs/note/source_en/{ => design/mindspore}/images/architecture.eddx (100%) rename docs/note/source_en/{ => design/mindspore}/images/architecture.png (100%) rename docs/note/source_en/design/mindspore/{ir.md => mindir.md} (100%) delete mode 100644 docs/note/source_en/glossary_lite.md create mode 100644 docs/note/source_en/others.rst create mode 100644 docs/note/source_en/specification_note.rst rename docs/note/source_zh_cn/{ => design/mindspore}/architecture.md (86%) rename docs/note/source_zh_cn/{ => design/mindspore}/architecture_lite.md (89%) rename docs/note/source_zh_cn/{ => design/mindspore}/images/MindSpore-Lite-architecture.png (100%) rename docs/note/source_zh_cn/{ => design/mindspore}/images/architecture.eddx (100%) rename docs/note/source_zh_cn/{ => design/mindspore}/images/architecture.png (100%) rename docs/note/source_zh_cn/design/mindspore/{ir.md => mindir.md} (100%) rename docs/note/source_zh_cn/{ => design}/technical_white_paper.md (100%) delete mode 100644 docs/note/source_zh_cn/glossary_lite.md create mode 100644 docs/note/source_zh_cn/others.rst create mode 100644 docs/note/source_zh_cn/specification_note.rst rename docs/{note => programming_guide}/source_en/network_list.md (100%) rename docs/{note => programming_guide}/source_en/operator_list.md (100%) rename docs/{note => programming_guide}/source_en/operator_list_lite.md (100%) rename docs/{note => programming_guide}/source_zh_cn/network_list.md (100%) rename docs/{note => programming_guide}/source_zh_cn/operator_list.md (100%) rename docs/{note => programming_guide}/source_zh_cn/operator_list_lite.md (100%) rename tutorials/inference/source_en/{use => }/multi_platform_inference.md (100%) rename tutorials/inference/source_en/{advanced_use => }/serving.md (100%) rename tutorials/inference/source_zh_cn/{use => }/multi_platform_inference.md (99%) rename tutorials/inference/source_zh_cn/{advanced_use => }/serving.md (100%) rename tutorials/lite/source_en/{ => use}/build.md (100%) rename tutorials/lite/source_zh_cn/{ => use}/build.md (100%) diff --git a/docs/api_cpp/source_en/apicc.rst b/docs/api_cpp/source_en/apicc.rst deleted file mode 100644 index 82bbf145ca..0000000000 --- a/docs/api_cpp/source_en/apicc.rst +++ /dev/null @@ -1,12 +0,0 @@ -C++ API -======= - -.. toctree:: - :maxdepth: 1 - - class_list - lite - session - tensor - dataset - errorcode_and_metatype \ No newline at end of file diff --git a/docs/note/source_en/index_lite.rst b/docs/api_cpp/source_en/index.rst similarity index 48% rename from docs/note/source_en/index_lite.rst rename to docs/api_cpp/source_en/index.rst index c333a1965a..6b3fb87da0 100644 --- a/docs/note/source_en/index_lite.rst +++ b/docs/api_cpp/source_en/index.rst @@ -1,15 +1,18 @@ .. MindSpore documentation master file, created by - sphinx-quickstart on Thu Aug 17 10:00:00 2020. + sphinx-quickstart on Thu Mar 24 10:00:00 2020. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore Lite Documentation -============================ +MindSpore C++ API +================= .. toctree:: - :glob: - :maxdepth: 1 + :glob: + :maxdepth: 1 - architecture_lite - operator_list_lite - glossary_lite + class_list + lite + session + tensor + dataset + errorcode_and_metatype \ No newline at end of file diff --git a/docs/api_cpp/source_zh_cn/apicc.rst b/docs/api_cpp/source_zh_cn/apicc.rst deleted file mode 100644 index 82bbf145ca..0000000000 --- a/docs/api_cpp/source_zh_cn/apicc.rst +++ /dev/null @@ -1,12 +0,0 @@ -C++ API -======= - -.. toctree:: - :maxdepth: 1 - - class_list - lite - session - tensor - dataset - errorcode_and_metatype \ No newline at end of file diff --git a/docs/api_cpp/source_zh_cn/index.rst b/docs/api_cpp/source_zh_cn/index.rst new file mode 100644 index 0000000000..6b3fb87da0 --- /dev/null +++ b/docs/api_cpp/source_zh_cn/index.rst @@ -0,0 +1,18 @@ +.. MindSpore documentation master file, created by + sphinx-quickstart on Thu Mar 24 10:00:00 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +MindSpore C++ API +================= + +.. toctree:: + :glob: + :maxdepth: 1 + + class_list + lite + session + tensor + dataset + errorcode_and_metatype \ No newline at end of file diff --git a/docs/note/source_zh_cn/index_lite.rst b/docs/faq/source_en/index.rst similarity index 51% rename from docs/note/source_zh_cn/index_lite.rst rename to docs/faq/source_en/index.rst index 715f7b1b5c..a8969301c9 100644 --- a/docs/note/source_zh_cn/index_lite.rst +++ b/docs/faq/source_en/index.rst @@ -1,15 +1,13 @@ .. MindSpore documentation master file, created by - sphinx-quickstart on Thu Aug 17 10:00:00 2020. + sphinx-quickstart on Thu Mar 24 10:00:00 2020. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore端侧文档 -================== +MindSpore FAQ +================= .. toctree:: - :glob: - :maxdepth: 1 + :glob: + :maxdepth: 1 - architecture_lite - operator_list_lite - glossary_lite + faq \ No newline at end of file diff --git a/docs/faq/source_zh_cn/index.rst b/docs/faq/source_zh_cn/index.rst new file mode 100644 index 0000000000..a8969301c9 --- /dev/null +++ b/docs/faq/source_zh_cn/index.rst @@ -0,0 +1,13 @@ +.. MindSpore documentation master file, created by + sphinx-quickstart on Thu Mar 24 10:00:00 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +MindSpore FAQ +================= + +.. toctree:: + :glob: + :maxdepth: 1 + + faq \ No newline at end of file diff --git a/docs/note/source_en/community.rst b/docs/note/source_en/community.rst index 80c0ddf710..a0743659bf 100644 --- a/docs/note/source_en/community.rst +++ b/docs/note/source_en/community.rst @@ -1,4 +1,4 @@ -Community +Participate in MindSpore Community ========= Contributing Code diff --git a/docs/note/source_en/design.rst b/docs/note/source_en/design.rst index 359add5edc..225f2914a5 100644 --- a/docs/note/source_en/design.rst +++ b/docs/note/source_en/design.rst @@ -4,8 +4,8 @@ Design .. toctree:: :maxdepth: 1 - architecture - design/mindspore/ir + design/mindspore/architecture + design/mindspore/mindir design/mindinsight/training_visual_design design/mindinsight/graph_visual_design design/mindinsight/tensor_visual_design \ No newline at end of file diff --git a/docs/note/source_en/architecture.md b/docs/note/source_en/design/mindspore/architecture.md similarity index 94% rename from docs/note/source_en/architecture.md rename to docs/note/source_en/design/mindspore/architecture.md index 43cf28ef2f..accf4a9b5a 100644 --- a/docs/note/source_en/architecture.md +++ b/docs/note/source_en/design/mindspore/architecture.md @@ -2,7 +2,7 @@ `Linux` `Windows` `Ascend` `GPU` `CPU` `On Device` `Model Development` `Model Optimization` `Framework Development` `Intermediate` `Expert` `Contributor` - + The MindSpore framework consists of the Frontend Expression layer, Graph Engine layer, and Backend Runtime layer. diff --git a/docs/note/source_en/architecture_lite.md b/docs/note/source_en/design/mindspore/architecture_lite.md similarity index 95% rename from docs/note/source_en/architecture_lite.md rename to docs/note/source_en/design/mindspore/architecture_lite.md index c0bd5c1234..de7a82a18f 100644 --- a/docs/note/source_en/architecture_lite.md +++ b/docs/note/source_en/design/mindspore/architecture_lite.md @@ -2,7 +2,7 @@ `Linux` `Windows` `On Device` `Inference Application` `Intermediate` `Expert` `Contributor` - + The overall architecture of MindSpore Lite is as follows: diff --git a/docs/note/source_en/images/MindSpore-Lite-architecture.png b/docs/note/source_en/design/mindspore/images/MindSpore-Lite-architecture.png similarity index 100% rename from docs/note/source_en/images/MindSpore-Lite-architecture.png rename to docs/note/source_en/design/mindspore/images/MindSpore-Lite-architecture.png diff --git a/docs/note/source_en/images/architecture.eddx b/docs/note/source_en/design/mindspore/images/architecture.eddx similarity index 100% rename from docs/note/source_en/images/architecture.eddx rename to docs/note/source_en/design/mindspore/images/architecture.eddx diff --git a/docs/note/source_en/images/architecture.png b/docs/note/source_en/design/mindspore/images/architecture.png similarity index 100% rename from docs/note/source_en/images/architecture.png rename to docs/note/source_en/design/mindspore/images/architecture.png diff --git a/docs/note/source_en/design/mindspore/ir.md b/docs/note/source_en/design/mindspore/mindir.md similarity index 100% rename from docs/note/source_en/design/mindspore/ir.md rename to docs/note/source_en/design/mindspore/mindir.md diff --git a/docs/note/source_en/glossary.md b/docs/note/source_en/glossary.md index ae1fb21e91..2137f0ee96 100644 --- a/docs/note/source_en/glossary.md +++ b/docs/note/source_en/glossary.md @@ -37,11 +37,13 @@ | MindInsight | MindSpore visualization component, which visualizes information such as scalars, images, computational graphs, and model hyperparameters. | | MindSpore | Huawei-leaded open-source deep learning framework. | | MindSpore Lite | A lightweight deep neural network inference engine that provides the inference function for models trained by MindSpore on the device side. | +| MindSpore Micro | MindSpore AI engine with smaller package size for IOT devices. | | MNIST database | Modified National Handwriting of Images and Technology database, a large handwritten digit database, which is usually used to train various image processing systems. | | ONNX | Open Neural Network Exchange, is an open format built to represent machine learning models.| | PyNative Mode | MindSpore dynamic graph mode. In this mode, operators in the neural network are delivered and executed one by one, facilitating the compilation and debugging of the neural network model. | | ResNet-50 | Residual Neural Network 50, a residual neural network proposed by four Chinese people, including Kaiming He from Microsoft Research Institute. | +| RT | Runtime. | | Schema | Data set structure definition file, which defines the fields contained in a dataset and the field types. | | Summary | An operator that monitors the values of tensors on the network. It is a peripheral operation in the figure and does not affect the data flow. | | TBE | Tensor Boost Engine, an operator development tool that is extended based on the Tensor Virtual Machine (TVM) framework. | -| TFRecord | Data format defined by TensorFlow. | +| TFRecord | Data format defined by TensorFlow. | \ No newline at end of file diff --git a/docs/note/source_en/glossary_lite.md b/docs/note/source_en/glossary_lite.md deleted file mode 100644 index fedf2cf2c9..0000000000 --- a/docs/note/source_en/glossary_lite.md +++ /dev/null @@ -1,14 +0,0 @@ -# Glossary - -`Linux` `Windows` `On Device` `Whole Process` `Beginner` `Intermediate` `Expert` - - - -| Acronym and Abbreviation | Description | -| ----- | ----- | -| MindSpore Lite | MindSpore AI engine is applied to the intelligent terminal and resource constrained scenes on the edge side. | -| MindSpore Micro | MindSpore AI engine with smaller package size for IOT devices. | -| GHLO | Graph high-level optimization. | -| GLLO | Graph low-level optimization. | -| RT | Runtime. | - diff --git a/docs/note/source_en/index.rst b/docs/note/source_en/index.rst index b998ceb9e7..d6befad46c 100644 --- a/docs/note/source_en/index.rst +++ b/docs/note/source_en/index.rst @@ -3,20 +3,13 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore Documentation -======================= +MindSpore Note +================= .. toctree:: :glob: :maxdepth: 1 design - roadmap - benchmark - network_list - operator_list - constraints_on_network_construction - glossary - FAQ - help_seeking_path - community + Specification_list + note diff --git a/docs/note/source_en/others.rst b/docs/note/source_en/others.rst new file mode 100644 index 0000000000..61a9cdf757 --- /dev/null +++ b/docs/note/source_en/others.rst @@ -0,0 +1,11 @@ +Others +=========== + +.. toctree:: + :maxdepth: 1 + + glossary + roadmap + help_seeking_path + community + diff --git a/docs/note/source_en/specification_note.rst b/docs/note/source_en/specification_note.rst new file mode 100644 index 0000000000..00875e6023 --- /dev/null +++ b/docs/note/source_en/specification_note.rst @@ -0,0 +1,9 @@ +规格说明 +=========== + +.. toctree:: + :maxdepth: 1 + + benchmark + constraints_on_network_construction + diff --git a/docs/note/source_zh_cn/design.rst b/docs/note/source_zh_cn/design.rst index 5db1a38152..4e1eb6ed8f 100644 --- a/docs/note/source_zh_cn/design.rst +++ b/docs/note/source_zh_cn/design.rst @@ -1,12 +1,12 @@ -设计文档 +设计说明 =========== .. toctree:: :maxdepth: 1 - architecture - technical_white_paper - design/mindspore/ir + design/technical_white_paper + design/mindspore/architecture + design/mindspore/mindir design/mindspore/distributed_training_design design/mindinsight/profiler_design design/mindinsight/training_visual_design diff --git a/docs/note/source_zh_cn/architecture.md b/docs/note/source_zh_cn/design/mindspore/architecture.md similarity index 86% rename from docs/note/source_zh_cn/architecture.md rename to docs/note/source_zh_cn/design/mindspore/architecture.md index 091f5ca131..36ac191ca8 100644 --- a/docs/note/source_zh_cn/architecture.md +++ b/docs/note/source_zh_cn/design/mindspore/architecture.md @@ -2,20 +2,20 @@ `Linux` `Windows` `Ascend` `GPU` `CPU` `端侧` `模型开发` `模型调优` `框架开发` `中级` `高级` `贡献者` - + MindSpore框架架构总体分为MindSpore前端表示层、MindSpore计算图引擎和MindSpore后端运行时三层。 ![architecture](./images/architecture.png) -- MindSpore前端表示层(Mind Expression,简称ME) +- MindSpore前端表示层(MindExpression,简称ME) 该部分包含Python API、MindSpore IR(Intermediate representation,简称IR)、计算图高级别优化(Graph High Level Optimization,简称GHLO)三部分。 - Python API向用户提供统一的模型训练、推理、导出接口,以及统一的数据处理、增强、格式转换接口。 - GHLO包含硬件无关的优化(如死代码消除等)、自动并行和自动微分等功能。 - MindSpore IR提供统一的中间表示,MindSpore基于此IR进行pass优化。 -- MindSpore计算图引擎(Graph Engine,简称GE) +- MindSpore计算图引擎(GraphEngine,简称GE) 该部分包含计算图低级别优化(Graph Low Level Optimization,简称GLLO)、图执行。 - GLLO包含硬件相关的优化,以及算子融合、Buffer融合等软硬件结合相关的深度优化。 diff --git a/docs/note/source_zh_cn/architecture_lite.md b/docs/note/source_zh_cn/design/mindspore/architecture_lite.md similarity index 89% rename from docs/note/source_zh_cn/architecture_lite.md rename to docs/note/source_zh_cn/design/mindspore/architecture_lite.md index 86697a237b..acbffc6d65 100644 --- a/docs/note/source_zh_cn/architecture_lite.md +++ b/docs/note/source_zh_cn/design/mindspore/architecture_lite.md @@ -3,11 +3,11 @@ `Linux` `Windows` `端侧` `推理应用` `中级` `高级` `贡献者` - + MindSpore Lite框架的总体架构如下所示: -![architecture](images/MindSpore-Lite-architecture.png) +![architecture](./images/MindSpore-Lite-architecture.png) - **前端(Frontend):** 负责模型生成,用户可以通过模型构建接口构建模型,将第三方模型和MindSpore训练的模型转换为MindSpore Lite模型,其中第三方模型包括TensorFlow Lite、Caffe 1.0和ONNX模型。 diff --git a/docs/note/source_zh_cn/images/MindSpore-Lite-architecture.png b/docs/note/source_zh_cn/design/mindspore/images/MindSpore-Lite-architecture.png similarity index 100% rename from docs/note/source_zh_cn/images/MindSpore-Lite-architecture.png rename to docs/note/source_zh_cn/design/mindspore/images/MindSpore-Lite-architecture.png diff --git a/docs/note/source_zh_cn/images/architecture.eddx b/docs/note/source_zh_cn/design/mindspore/images/architecture.eddx similarity index 100% rename from docs/note/source_zh_cn/images/architecture.eddx rename to docs/note/source_zh_cn/design/mindspore/images/architecture.eddx diff --git a/docs/note/source_zh_cn/images/architecture.png b/docs/note/source_zh_cn/design/mindspore/images/architecture.png similarity index 100% rename from docs/note/source_zh_cn/images/architecture.png rename to docs/note/source_zh_cn/design/mindspore/images/architecture.png diff --git a/docs/note/source_zh_cn/design/mindspore/ir.md b/docs/note/source_zh_cn/design/mindspore/mindir.md similarity index 100% rename from docs/note/source_zh_cn/design/mindspore/ir.md rename to docs/note/source_zh_cn/design/mindspore/mindir.md diff --git a/docs/note/source_zh_cn/technical_white_paper.md b/docs/note/source_zh_cn/design/technical_white_paper.md similarity index 100% rename from docs/note/source_zh_cn/technical_white_paper.md rename to docs/note/source_zh_cn/design/technical_white_paper.md diff --git a/docs/note/source_zh_cn/glossary.md b/docs/note/source_zh_cn/glossary.md index 647c9076f9..b597de6ad5 100644 --- a/docs/note/source_zh_cn/glossary.md +++ b/docs/note/source_zh_cn/glossary.md @@ -37,11 +37,14 @@ | MindInsight | MindSpore可视化组件,可视化标量、图像、计算图以及模型超参等信息。 | | MindSpore | 华为主导开源的深度学习框架。 | | MindSpore Lite | 一个轻量级的深度神经网络推理引擎,提供了将MindSpore训练出的模型在端侧进行推理的功能。 | +| MindSpore Micro | 应用在IoT设备的,包大小更小的MindSpore AI引擎。 | | MNIST database | Modified National Institute of Standards and Technology database,一个大型手写数字数据库,通常用于训练各种图像处理系统。 | | ONNX | Open Neural Network Exchange,是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。| | PyNative Mode | MindSpore的动态图模式,将神经网络中的各个算子逐一下发执行,方便用户编写和调试神经网络模型。 | | ResNet-50 | Residual Neural Network 50,由微软研究院的Kaiming He等四名华人提出的残差神经网络。 | +| RT | Runtime运行时。 | | Schema | 数据集结构定义文件,用于定义数据集包含哪些字段以及字段的类型。 | | Summary | 是对网络中Tensor取值进行监测的一种算子,在图中是“外围”操作,不影响数据流本身。 | | TBE | Tensor Boost Engine,在TVM( Tensor Virtual Machine )框架基础上扩展的算子开发工具。 | | TFRecord | Tensorflow定义的数据格式。 | + diff --git a/docs/note/source_zh_cn/glossary_lite.md b/docs/note/source_zh_cn/glossary_lite.md deleted file mode 100644 index 947bea9a25..0000000000 --- a/docs/note/source_zh_cn/glossary_lite.md +++ /dev/null @@ -1,14 +0,0 @@ -# 术语 - -`Linux` `Windows` `端侧` `全流程` `初级` `中级` `高级` - - - -| 术语/缩略语 | 说明 | -| ----- | ----- | -| MindSpore Lite | 应用在智能终端,边缘册资源受限场景的MindSpore AI 引擎。 | -| MindSpore Micro | 应用在IoT设备的,包大小更小的MindSpore AI引擎。 | -| GHLO | Graph high-level optimization,图高层优化。 | -| GLLO | Graph low-level optimization,图底层优化。 | -| RT | Runtime运行时。 | - diff --git a/docs/note/source_zh_cn/help_seeking_path.md b/docs/note/source_zh_cn/help_seeking_path.md index 0c469483bb..7db3efb56b 100644 --- a/docs/note/source_zh_cn/help_seeking_path.md +++ b/docs/note/source_zh_cn/help_seeking_path.md @@ -1,4 +1,4 @@ -# 问题求助路径 +# 如何求助(求助路径) `Linux` `Windows` `Ascend` `GPU` `CPU` `全流程` `初级` `中级` `高级` diff --git a/docs/note/source_zh_cn/index.rst b/docs/note/source_zh_cn/index.rst index 91ddd47bd4..40d2a2ee36 100644 --- a/docs/note/source_zh_cn/index.rst +++ b/docs/note/source_zh_cn/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore文档 +MindSpore Note ================= .. toctree:: @@ -11,12 +11,5 @@ MindSpore文档 :maxdepth: 1 design - roadmap - benchmark - network_list - operator_list - constraints_on_network_construction - glossary - FAQ - help_seeking_path - community + Specification_list + note diff --git a/docs/note/source_zh_cn/others.rst b/docs/note/source_zh_cn/others.rst new file mode 100644 index 0000000000..e3c3d6fd55 --- /dev/null +++ b/docs/note/source_zh_cn/others.rst @@ -0,0 +1,11 @@ +其他说明 +=========== + +.. toctree:: + :maxdepth: 1 + + glossary + roadmap + help_seeking_path + community + diff --git a/docs/note/source_zh_cn/specification_note.rst b/docs/note/source_zh_cn/specification_note.rst new file mode 100644 index 0000000000..00875e6023 --- /dev/null +++ b/docs/note/source_zh_cn/specification_note.rst @@ -0,0 +1,9 @@ +规格说明 +=========== + +.. toctree:: + :maxdepth: 1 + + benchmark + constraints_on_network_construction + diff --git a/docs/note/source_en/network_list.md b/docs/programming_guide/source_en/network_list.md similarity index 100% rename from docs/note/source_en/network_list.md rename to docs/programming_guide/source_en/network_list.md diff --git a/docs/note/source_en/operator_list.md b/docs/programming_guide/source_en/operator_list.md similarity index 100% rename from docs/note/source_en/operator_list.md rename to docs/programming_guide/source_en/operator_list.md diff --git a/docs/note/source_en/operator_list_lite.md b/docs/programming_guide/source_en/operator_list_lite.md similarity index 100% rename from docs/note/source_en/operator_list_lite.md rename to docs/programming_guide/source_en/operator_list_lite.md diff --git a/docs/note/source_zh_cn/network_list.md b/docs/programming_guide/source_zh_cn/network_list.md similarity index 100% rename from docs/note/source_zh_cn/network_list.md rename to docs/programming_guide/source_zh_cn/network_list.md diff --git a/docs/note/source_zh_cn/operator_list.md b/docs/programming_guide/source_zh_cn/operator_list.md similarity index 100% rename from docs/note/source_zh_cn/operator_list.md rename to docs/programming_guide/source_zh_cn/operator_list.md diff --git a/docs/note/source_zh_cn/operator_list_lite.md b/docs/programming_guide/source_zh_cn/operator_list_lite.md similarity index 100% rename from docs/note/source_zh_cn/operator_list_lite.md rename to docs/programming_guide/source_zh_cn/operator_list_lite.md diff --git a/tutorials/inference/source_en/index.rst b/tutorials/inference/source_en/index.rst index 8428dc87e7..1983b3e761 100644 --- a/tutorials/inference/source_en/index.rst +++ b/tutorials/inference/source_en/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore Tutorials +Inference Using MindSpore =================== .. toctree:: @@ -11,11 +11,11 @@ MindSpore Tutorials :maxdepth: 1 :caption: Use - use/multi_platform_inference + multi_platform_inference .. toctree:: :glob: :maxdepth: 1 :caption: Inference Service - advanced_use/serving + serving diff --git a/tutorials/inference/source_en/use/multi_platform_inference.md b/tutorials/inference/source_en/multi_platform_inference.md similarity index 100% rename from tutorials/inference/source_en/use/multi_platform_inference.md rename to tutorials/inference/source_en/multi_platform_inference.md diff --git a/tutorials/inference/source_en/advanced_use/serving.md b/tutorials/inference/source_en/serving.md similarity index 100% rename from tutorials/inference/source_en/advanced_use/serving.md rename to tutorials/inference/source_en/serving.md diff --git a/tutorials/inference/source_zh_cn/index.rst b/tutorials/inference/source_zh_cn/index.rst index c7dbc13004..1f91d08c52 100644 --- a/tutorials/inference/source_zh_cn/index.rst +++ b/tutorials/inference/source_zh_cn/index.rst @@ -3,19 +3,19 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore教程 +使用MindSpore推理 ============= .. toctree:: :glob: :maxdepth: 1 - :caption: 使用指南 + :caption: 推理模型 - use/multi_platform_inference + multi_platform_inference .. toctree:: :glob: :maxdepth: 1 - :caption: 推理服务 + :caption: 搭建推理服务 - advanced_use/serving + serving diff --git a/tutorials/inference/source_zh_cn/use/multi_platform_inference.md b/tutorials/inference/source_zh_cn/multi_platform_inference.md similarity index 99% rename from tutorials/inference/source_zh_cn/use/multi_platform_inference.md rename to tutorials/inference/source_zh_cn/multi_platform_inference.md index 39c0870168..69f025a21d 100644 --- a/tutorials/inference/source_zh_cn/use/multi_platform_inference.md +++ b/tutorials/inference/source_zh_cn/multi_platform_inference.md @@ -1,4 +1,4 @@ -# 多平台推理 +# 推理模型 `Linux` `Ascend` `GPU` `CPU` `推理应用` `初级` `中级` `高级` diff --git a/tutorials/inference/source_zh_cn/advanced_use/serving.md b/tutorials/inference/source_zh_cn/serving.md similarity index 100% rename from tutorials/inference/source_zh_cn/advanced_use/serving.md rename to tutorials/inference/source_zh_cn/serving.md diff --git a/tutorials/lite/source_en/index.rst b/tutorials/lite/source_en/index.rst index 26e9445ec1..757fccaf22 100644 --- a/tutorials/lite/source_en/index.rst +++ b/tutorials/lite/source_en/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore Lite Tutorials +Using MindSpore on Mobile and IoT ======================== .. toctree:: @@ -16,9 +16,9 @@ MindSpore Lite Tutorials .. toctree:: :glob: :maxdepth: 1 - :caption: Use + :caption: Basic Use - build + use/build use/converter_tool use/evaluating_the_model use/runtime diff --git a/tutorials/lite/source_en/build.md b/tutorials/lite/source_en/use/build.md similarity index 100% rename from tutorials/lite/source_en/build.md rename to tutorials/lite/source_en/use/build.md diff --git a/tutorials/lite/source_zh_cn/index.rst b/tutorials/lite/source_zh_cn/index.rst index 3bfde552d2..6c70679a8a 100644 --- a/tutorials/lite/source_zh_cn/index.rst +++ b/tutorials/lite/source_zh_cn/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore端侧教程 +在手机或IoT设备上使用MindSpore ================== .. toctree:: @@ -16,9 +16,9 @@ MindSpore端侧教程 .. toctree:: :glob: :maxdepth: 1 - :caption: 使用指南 + :caption: 基础使用 - build + use/build use/converter_tool use/evaluating_the_model - use/runtime + use/runtime \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/build.md b/tutorials/lite/source_zh_cn/use/build.md similarity index 100% rename from tutorials/lite/source_zh_cn/build.md rename to tutorials/lite/source_zh_cn/use/build.md -- Gitee From e67db56306b6eb3829b8170fd9847ec6ecd9bacb Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Wed, 16 Sep 2020 12:02:00 +0800 Subject: [PATCH 039/100] Modify the format of markdown --- .../accelerate_data_processing.md | 28 +++++++++---------- .../apply_gradient_accumulation.md | 6 ++-- .../apply_parameter_server_training.md | 20 ++++++------- .../advanced_use/custom_debugging_info.md | 4 +-- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md index 0736705c6d..ccdd08fecc 100644 --- a/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md +++ b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md @@ -27,10 +27,10 @@ 数据加载的方式有三种: 1. 内置高性能的数据加载类算子,如CIFAR数据集、MNIST数据集等; - 2. 将数据集转换成MindRecord,使用MindDataset算子进行加载; - 3. 用户自定义数据集——GeneratorDataset。 + 2. 将数据集转换成MindRecord,使用`MindDataset`算子进行加载; + 3. 用户自定义数据集——`GeneratorDataset`。 - > 优先使用内置的数据加载类算子以及MindDataset,如果无法满足用户需求,则在撰写用户自定数据集加载时,需要关注本身数据集加载的性能优化。 + > 优先使用内置的数据加载类算子以及`MindDataset`,如果无法满足用户需求,则在撰写用户自定数据集加载时,需要关注本身数据集加载的性能优化。 - 数据混洗 @@ -77,20 +77,20 @@ - 计算资源的分配 - 当我们进行分布式训练时,一台设备机器上会启动多个训练进程,而这些训练进程会通过操作系统本身的策略进行计算资源的分配与抢占,当进程较多时,可能会由于计算资源的竞争而导致数据处理性能的下降,因此这时需要进行人工分配计算资源,避免各个进程的计算资源竞争。 + 当我们进行分布式训练时,一台设备机器上会启动多个训练进程,而这些训练进程会通过操作系统本身的策略进行计算资源的分配与抢占,当进程较多时,可能会由于计算资源的竞争而导致数据处理性能的下降,因此这时需要进行人工分配计算资源,避免各个进程的计算资源竞争。 - ```shell - numactl --cpubind=0 python train.py - or - taskset -c 0-15 python train.py - ``` + ```shell + numactl --cpubind=0 python train.py + or + taskset -c 0-15 python train.py + ``` - > `numactl`的方式较为粗粒度,直接指定`numa node id`,而`taskset`的方式是细粒度的,它能够直接指定`numa node`上的`cpu core`,其中0-15表示的`core id`从0到15。 + > `numactl`的方式较为粗粒度,直接指定`numa node id`,而`taskset`的方式是细粒度的,它能够直接指定`numa node`上的`cpu core`,其中0-15表示的`core id`从0到15。 - CPU频率设置 - 要想充分发挥host端CPU的最大算力,CPU频率的设置至关重要。一般地,linux内核支持调节CPU主频,降低功耗,已到达节能的效果。通过选择系统空闲状态不同的电源管理策略,可以实现不同程度降低服务器功耗。但是,更低的功耗策略意味着CPU唤醒更慢对性能影响更大。因此如果发现CPU模式为conservative或者powersave,可以使用cpupower设置CPU Performance模式,对数据处理的性能提升有非常大的效果。 + 要想充分发挥host端CPU的最大算力,CPU频率的设置至关重要。一般地,linux内核支持调节CPU主频,降低功耗,已到达节能的效果。通过选择系统空闲状态不同的电源管理策略,可以实现不同程度降低服务器功耗。但是,更低的功耗策略意味着CPU唤醒更慢对性能影响更大。因此如果发现CPU模式为conservative或者powersave,可以使用cpupower设置CPU Performance模式,对数据处理的性能提升有非常大的效果。 - ```shell - cpupower frequency-set -g performance - ``` + ```shell + cpupower frequency-set -g performance + ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md b/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md index 1aff383ad0..2c66ade5f7 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md @@ -58,11 +58,11 @@ from model_zoo.official.cv.lenet.src.lenet import LeNet5 ### 加载数据集 -利用MindSpore的dataset提供的`MnistDataset`接口加载MNIST数据集,此部分代码由model_zoo中lenet目录下的[dataset.py]()导入。 +利用MindSpore的`dataset`提供的`MnistDataset`接口加载MNIST数据集,此部分代码由`model_zoo`中`lenet`目录下的[dataset.py]()导入。 ### 定义网络 -这里以LeNet网络为例进行介绍,当然也可以使用其它的网络,如ResNet-50、BERT等, 此部分代码由model_zoo中lenet目录下的[lenet.py]()导入。 +这里以LeNet网络为例进行介绍,当然也可以使用其它的网络,如ResNet-50、BERT等, 此部分代码由`model_zoo`中`lenet`目录下的[lenet.py]()导入。 ### 定义训练模型 将训练流程拆分为正向反向训练、参数更新和累积梯度清理三个部分: @@ -252,7 +252,7 @@ if __name__ == "__main__": **验证模型** -通过model_zoo中lenet目录下的[eval.py](),使用保存的CheckPoint文件,加载验证数据集,进行验证。 +通过`model_zoo`中`lenet`目录下的[eval.py](),使用保存的CheckPoint文件,加载验证数据集,进行验证。 ```shell $ python eval.py --data_path=./MNIST_Data --ckpt_path=./gradient_accumulation.ckpt diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md index 515d07d280..83e6df2654 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md @@ -40,21 +40,21 @@ Parameter Server(参数服务器)是分布式训练中一种广泛使用的架 1. 首先调用`mindspore.context.set_ps_context(enable_ps=True)`开启Parameter Server训练模式. -- 此接口需在`mindspore.communication.management.init()`之前调用。 -- 若没有调用此接口,下面的[环境变量设置](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/parameter_server_training.html#id5)则不会生效。 -- 调用`mindspore.context.reset_ps_context()`可以关闭Parameter Server训练模式。 + - 此接口需在`mindspore.communication.management.init()`之前调用。 + - 若没有调用此接口,下面的[环境变量设置](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/parameter_server_training.html#id5)则不会生效。 + - 调用`mindspore.context.reset_ps_context()`可以关闭Parameter Server训练模式。 2. 在本训练模式下,有以下两种调用接口方式以控制训练参数是否通过Parameter Server进行更新: -- 通过`mindspore.nn.Cell.set_param_ps()`对`nn.Cell`中所有权重递归设置。 -- 通过`mindspore.common.Parameter.set_param_ps()`对此权重进行设置。 + - 通过`mindspore.nn.Cell.set_param_ps()`对`nn.Cell`中所有权重递归设置。 + - 通过`mindspore.common.Parameter.set_param_ps()`对此权重进行设置。 3. 在[原训练脚本](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/train.py)基础上,设置LeNet模型所有权重通过Parameter Server训练: -```python -context.set_ps_context(enable_ps=True) -network = LeNet5(cfg.num_classes) -network.set_param_ps() -``` + ```python + context.set_ps_context(enable_ps=True) + network = LeNet5(cfg.num_classes) + network.set_param_ps() + ``` ### 环境变量设置 diff --git a/tutorials/training/source_zh_cn/advanced_use/custom_debugging_info.md b/tutorials/training/source_zh_cn/advanced_use/custom_debugging_info.md index 57f34688e9..1e176a7be0 100644 --- a/tutorials/training/source_zh_cn/advanced_use/custom_debugging_info.md +++ b/tutorials/training/source_zh_cn/advanced_use/custom_debugging_info.md @@ -199,7 +199,7 @@ output = model.eval(ds_eval) `model.eval`方法会返回一个字典,里面是传入metrics的指标和结果。 -在eval过程中也可以使用callback功能,用户可以调用相关API或自定义callback方法实现想要的功能。 +在eval过程中也可以使用`Callback`功能,用户可以调用相关API或自定义`Callback`方法实现想要的功能。 用户也可以定义自己的`metrics`类,通过继承`Metric`基类,并重写`clear`、`update`、`eval`三个方法即可实现。 @@ -207,7 +207,7 @@ output = model.eval(ds_eval) `accuracy`继承了`EvaluationBase`基类,重写了上述三个方法。 `clear`方法会把类中相关计算参数初始化。 -`update`方法接受预测值和标签值,更新accuracy内部变量。 +`update`方法接受预测值和标签值,更新`accuracy`内部变量。 `eval`方法会计算相关指标,返回计算结果。 调用`accuracy`的`eval`方法,即可得到计算结果。 -- Gitee From 37420bbc86f9831b07a9f0fb64a62329318a3ec3 Mon Sep 17 00:00:00 2001 From: Payne Date: Wed, 16 Sep 2020 14:05:04 +0800 Subject: [PATCH 040/100] update mobilenetv2 incremental learning doc, fix some error and confused expression --- .../cv_mobilenetv2_incremental_learning.md | 99 ++++++++++--------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md b/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md index f33f3e9ae7..ef0e0843e7 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md +++ b/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md @@ -25,7 +25,7 @@ -   +   ## 概述 @@ -33,7 +33,7 @@ MindSpore是一个多元化的机器学习框架。既可以在手机等端侧和PC等设备上运行,也可以在云上的服务器集群上运行。目前MobileNetV2支持在Windows系统中使用单核CPU做增量学习,在EulerOS、Ubuntu系统中使用单个或者多个Ascend AI处理器或GPU中做增量学习,本教程将会介绍如何在不同系统与处理器下的MindSpore框架中做增量学习的训练与验证。 -目前,Window上暂只支持支持CPU,Ubuntu与EulerOS上支持CPU、GPU与Ascend AI处理器三种处理器。 +目前,Window上暂只支持支持CPU,Ubuntu与EulerOS上支持CPU、GPU与Ascend AI处理器三种处理器。 >你可以在这里找到完整可运行的样例代码: @@ -43,6 +43,8 @@ MindSpore是一个多元化的机器学习框架。既可以在手机等端侧 若在本地环境运行,需要安装MindSpore框架,配置CPU、GPU或Ascend AI处理器。若在华为云环境上运行,不需要安装MindSpore框架,不需要配置Ascend AI处理器、CPU与GPU,可以跳过本小节。 +Windows操作系统中使用`\`,Linux操作系统中使用`/`分割路径地址中不同层级目录,下文中默认使用`/`,若用户使用Windows操作系统,路径地址中`/`需自行更改为`\`。 + 1. 安装MindSpore框架 在EulerOS、Ubuntu或者Windows等系统上需要根据系统和处理器架构[安装对应版本MindSpore框架](https://www.mindspore.cn/install)。 @@ -120,7 +122,7 @@ cd ./mindspore/model_zoo/official/cv/mobilenetv2 代码结构如下: -``` +```bash ├─MobileNetV2 ├─README.md # descriptions about MobileNetV2 ├─scripts @@ -132,6 +134,7 @@ cd ./mindspore/model_zoo/official/cv/mobilenetv2 │ launch.py # start Python script │ lr_generator.py # learning rate config │ mobilenetV2.py # MobileNetV2 architecture + │ mobilenetV2_fusion.py # MobileNetV2 fusion architecture │ models.py # net utils to load ckpt_file, define_net... │ utils.py # net utils to switch precision, set_context and so on ├─train.py # training script @@ -145,9 +148,9 @@ cd ./mindspore/model_zoo/official/cv/mobilenetv2 ### 准备预训练模型 [下载预训练模型](https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ckpt)到以下目录: -`./pretrain_checkpoint/[pretrain_checkpoint_file]` +`./pretrain_checkpoint/` -```Python +```bash mkdir pretrain_checkpoint wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ckpt ``` @@ -158,7 +161,7 @@ wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/l 数据集结构如下: -``` +```bash └─ImageFolder ├─train │ class1Folder @@ -203,17 +206,20 @@ wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/l 24: param.requires_grad = False ``` -## 参数简介 +## 参数简介 + +每个参数需要用户根据自己本地的处理器类型、数据地址与预训练模型地址等修改为相应的值。 ### 运行Python文件 + 在Windows与Linux系统上训练时,运行`train.py`时需要传入`dataset_path`、`platform`、`train_method`与`pretrain_ckpt`四个参数。验证时,运行`eval.py`并且传入`dataset_path`、`platform`、`pretrain_ckpt`与`head_ckpt`四个参数。 -```Shell +```bash # Windows/Linux train with Python file -python train.py --dataset_path [dataset_path] --platform [platform] --pretrain_ckpt [pretrain_checkpoint_path] --train_method[("train", "fine_tune", "incremental_learn")] +python train.py --platform [PLATFORM] --dataset_path [DATASET_PATH] --train_method[("train", "fine_tune", "incremental_learn")] --pretrain_ckpt [PRETRAIN_CHECKPOINT_PATH] # Windows/Linux eval with Python file -python eval.py --dataset_path [dataset_path] --platform [platform] --pretrain_ckpt [pretrain_checkpoint_path] --head_ckpt [head_ckpt_path] +python eval.py --platform [PLATFORM] --dataset_path [DATASET_PATH] --pretrain_ckpt [PRETRAIN_CHECKPOINT_PATH] --head_ckpt [HEAD_CHECKPOINT_PATH] ``` - `--dataset_path`:训练与验证数据集地址,无默认值,用户训练/验证时必须输入。 @@ -222,13 +228,13 @@ python eval.py --dataset_path [dataset_path] --platform [platform] --pretrain_ck - `--pretrain_ckpt`:增量训练或调优时,需要传入pretrain_checkpoint文件路径以加载预训练好的模型参数权重。 - `--head_ckpt`:增量训练模型验证时,需要传入head_net预训练模型路径以加载预训练好的模型参数权重。 - ### 运行Shell脚本 + 在Linux系统上时,可以选择运行Shell脚本文件`./scripts/run_train.sh`与`./scripts/run_eval.sh`。运行时需要在交互界面中同时传入参数。 -```Shell +```bash # Windows doesn't support Shell -# Linux train with Shell script +# Linux train with Shell script sh run_train.sh [PLATFORM] [DEVICE_NUM] [VISIABLE_DEVICES(0,1,2,3,4,5,6,7)] [RANK_TABLE_FILE] [DATASET_PATH] [TRAIN_METHOD] [CKPT_PATH] # Linux eval with Shell script for incremental learn @@ -247,9 +253,9 @@ sh run_eval.sh [PLATFORM] [DATASET_PATH] [PRETRAIN_CKPT_PATH] [HEAD_CKPT_PATH] ## 加载增量学习训练 -Windows系统上,MobileNetV2做增量学习训练时,只能运行`train.py`。Linux系统上,使用MobileNetV2做增量学习训练时,可以选择运行`run_train.sh`, 并在运行Shell脚本文件时传入[参数](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/mobilenetv2_incremental_learning.html#id8)。 +Windows系统上,MobileNetV2做增量学习训练时,只能运行`train.py`。Linux系统上,使用MobileNetV2做增量学习训练时,可以选择运行`run_train.sh`, 并在运行Shell脚本文件时传入[参数](https://www.mindspore.cn/tutorials/training/source_zh_cn/r1.0/advanced_use/cv_mobilenetv2_incremental_learning.html#id8)。 -Windows系统输出信息到交互式命令行,Linux系统环境下运行`run_train.sh`时,命令行结尾使用`&> [log_file_path]`将标准输出与错误输出写入log文件。 增量学习成功开始训练,`./train/device*/log*.log`中会持续写入每一个epoch的训练时间与Loss等信息。若未成功,上述log文件会写入失败报错信息。 +Windows系统输出信息到交互式命令行,Linux系统环境下运行`run_train.sh`时,命令行结尾使用`&> [log_file_path]`将标准输出与错误输出写入log文件。 增量学习成功开始训练,`./train/rank*/log*.log`中会持续写入每一个epoch的训练时间与Loss等信息。若未成功,上述log文件会写入失败报错信息。 ### CPU加载训练 @@ -261,16 +267,16 @@ Windows系统输出信息到交互式命令行,Linux系统环境下运行`run_ 使用样例1:通过Python文件调用1个CPU处理器。 - ```Shell + ```bash # Windows or Linux with Python - python train.py --platform CPU --dataset_path /store/dataset/OpenImage/train/ -- train_method incremental_learn --pretrain_ckpt ./pretrain_checkpoint/mobilenetV2.ckpt + python train.py --platform CPU --dataset_path [TRAIN_DATASET_PATH] -- train_method incremental_learn --pretrain_ckpt ./pretrain_checkpoint/mobilenetv2.ckpt ``` 使用样例2:通过Shell文件调用1个CPU处理器。 - ```Shell + ```bash # Linux with Shell - sh run_train.sh CPU /store/dataset/OpenImage/train/ incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt + sh run_train.sh CPU [TRAIN_DATASET_PATH] incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt ``` ### GPU加载训练 @@ -283,23 +289,23 @@ Windows系统输出信息到交互式命令行,Linux系统环境下运行`run_ - 使用样例1:通过Python文件调用1个GPU处理器。 - ```Shell + ```bash # Windows or Linux with Python - python train.py --platform GPU --dataset_path /store/dataset/OpenImage/train/ --pretrain_ckpt ./pretrain_checkpoint/mobilenetV2.ckpt --train_method incremental_learn + python train.py --platform GPU --dataset_path [TRAIN_DATASET_PATH] --train_method incremental_learn --pretrain_ckpt ./pretrain_checkpoint/mobilenetV2.ckpt ``` - 使用样例2:通过Shell脚本调用1个GPU处理器,设备ID为`“0”`。 - ```Shell + ```bash # Linux with Shell - sh run_train.sh GPU 1 0 /store/dataset/OpenImage/train/ incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt + sh run_train.sh GPU 1 0 [TRAIN_DATASET_PATH] incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt ``` - 使用样例3:通过Shell脚本调用8个GPU处理器,设备ID为`“0,1,2,3,4,5,6,7”`。 - ```Shell + ```bash # Linux with Shell - sh run_train.sh GPU 8 0,1,2,3,4,5,6,7 /store/dataset/OpenImage/train/ incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt + sh run_train.sh GPU 8 0,1,2,3,4,5,6,7 [TRAIN_DATASET_PATH] incremental_learn ../pretrain_checkpoint/mobilenetv2.ckpt ``` ### Ascend加载训练 @@ -312,23 +318,23 @@ Windows系统输出信息到交互式命令行,Linux系统环境下运行`run_ - 使用样例1:通过Python文件调用1个Ascend处理器。 - ```Shell + ```bash # Windows or Linux with Python - python train.py --platform Ascend --dataset_path /store/dataset/OpenImage/train/ --train_method incremental_learn --pretrain_ckpt ./pretrain_checkpoint/mobilenetV2.ckpt + python train.py --platform Ascend --dataset_path [TRAIN_DATASET_PATH] --train_method incremental_learn --pretrain_ckpt ./pretrain_checkpoint mobilenetv2.ckpt ``` - 使用样例2:通过Shell脚本调用1个Ascend AI处理器,设备ID为“0”。 - ```Shell + ```bash # Linux with Shell - sh run_train.sh Ascend 1 0 ~/rank_table.json /store/dataset/OpenImage/train/ incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt + sh run_train.sh Ascend 1 0 ~/rank_table.json [TRAIN_DATASET_PATH] incremental_learn ../pretrain_checkpoint/mobilenetv2.ckpt ``` - 使用样例3:通过Shell脚本调用8个Ascend AI处理器,设备ID为”0,1,2,3,4,5,6,7“。 - ```Shell + ```bash # Linux with Shell - sh run_train.sh Ascend 8 0,1,2,3,4,5,6,7 ~/rank_table.json /store/dataset/OpenImage/train/ incremental_learn ../pretrain_checkpoint/mobilenetV2.ckpt + sh run_train.sh Ascend 8 0,1,2,3,4,5,6,7 ~/rank_table.json [TRAIN_DATASET_PATH] incremental_learn ../pretrain_checkpoint/mobilenetv2.ckpt ``` ### 增量学习训练结果 @@ -337,23 +343,23 @@ Windows系统输出信息到交互式命令行,Linux系统环境下运行`run_ - 运行Python文件时在交互式命令行中查看打印信息,`Linux`上运行Shell脚本运行后使用`cat ./train/device0/log0.log`中查看打印信息,输出结果如下: - ``` - train args: Namespace(dataset_path='.\\dataset\\train', platform='CPU', \ - pretrain_ckpt='.\\pretrain_checkpoint\\mobilenetV2.ckpt', train_method='incremental_learn') + ```bash + train args: Namespace(dataset_path='./dataset/train', platform='CPU', \ + pretrain_ckpt='./pretrain_checkpoint/mobilenetv2.ckpt', train_method='incremental_learn') cfg: {'num_classes': 26, 'image_height': 224, 'image_width': 224, 'batch_size': 150, \ - 'epoch_size': 15, 'warmup_epochs': 0, 'lr_max': 0.03, 'lr_end': 0.03, 'momentum': 0.9, \ + 'epoch_size': 200, 'warmup_epochs': 0, 'lr_max': 0.03, 'lr_end': 0.03, 'momentum': 0.9, \ 'weight_decay': 4e-05, 'label_smooth': 0.1, 'loss_scale': 1024, 'save_checkpoint': True, \ 'save_checkpoint_epochs': 1, 'keep_checkpoint_max': 20, 'save_checkpoint_path': './checkpoint', \ 'platform': 'CPU'} Processing batch: 16: 100%|███████████████████████████████████████████ █████████████████████| 16/16 [00:00 Date: Wed, 16 Sep 2020 15:50:27 +0800 Subject: [PATCH 041/100] add differential_privacy_design.md in english. --- docs/note/source_en/design.rst | 3 +- .../mindarmour/differential_privacy_design.md | 71 ++++++++++++++++++ .../design/mindarmour/images/dp_arch.png | Bin 0 -> 61680 bytes .../mindarmour/differential_privacy_design.md | 2 +- 4 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 docs/note/source_en/design/mindarmour/differential_privacy_design.md create mode 100644 docs/note/source_en/design/mindarmour/images/dp_arch.png diff --git a/docs/note/source_en/design.rst b/docs/note/source_en/design.rst index 359add5edc..e0a79ac16b 100644 --- a/docs/note/source_en/design.rst +++ b/docs/note/source_en/design.rst @@ -8,4 +8,5 @@ Design design/mindspore/ir design/mindinsight/training_visual_design design/mindinsight/graph_visual_design - design/mindinsight/tensor_visual_design \ No newline at end of file + design/mindinsight/tensor_visual_design + design/mindarmour/differential_privacy_design.md diff --git a/docs/note/source_en/design/mindarmour/differential_privacy_design.md b/docs/note/source_en/design/mindarmour/differential_privacy_design.md new file mode 100644 index 0000000000..86ce6049a2 --- /dev/null +++ b/docs/note/source_en/design/mindarmour/differential_privacy_design.md @@ -0,0 +1,71 @@ +# Differential Privacy + +`Ascend` `Model Development` `Model Optimization` `Framework Development` `Enterprise` `Expert` `Contributor` + + + +- [Differential Privacy](#differential-privacy) + - [Overall Design](#overall-design) + - [DP Optimizer](#dp-optimizer) + - [DP Mechanisms](#dp-mechanisms) + - [Monitor](#monitor) + - [Code Implementation](#code-implementation) + - [References](#references) + + + + + +## Overall Design + +The Differential-Privacy module of MindArmour implements the differential privacy training capability. Model training consists of building training dataset, computing loss, computing gradient, and updating model parameters. Currently, the differential privacy training of MindArmour focuses on the gradient computing process and uses the corresponding algorithm to clip and add noise to the gradient. In this way, user data privacy is protected. + +![dp_arch](./images/dp_arch.png) + +

    Figure 1 Overall design of differential privacy
    + +Figure 1 shows an overall design of differential privacy training, and mainly including differential privacy noise mechanisms (DP mechanisms), a differential privacy optimizer (DP optimizer), and a privacy monitor. + + +### DP Optimizer + +DP optimizer inherits capabilities of the MindSpore optimizer and uses the DP mechanisms to scramble and protect gradients. Currently, MindArmour provides three types of DP optimizers: constant Gaussian optimizer, adaptive Gaussian optimizer, and adaptive clipping optimizer. Each type of DP optimizer adds differential privacy protection capabilities to common optimizers such as SGD and Momentum from different perspectives. + +* Constant Gaussian optimizer is a DP optimizer for non-adaptive Gaussian noise. The advantage is that the differential privacy budget ϵ can be strictly controlled. The disadvantage is that in the model training process, the noise amount added in each step is fixed. If the number of training steps is too large, the noise in the later phase of training makes the model convergence difficult, or even causes the performance to deteriorate greatly and the model availability to be poor. +* Adaptive Gaussian optimizer adaptively adjusts the standard deviation to adjust the Gaussian distribution noise. In the initial phase of model training, a large amount of noise is added. As the model gradually converges, the noise amount gradually decreases, and the impact of the noise on the model availability is reduced. A disadvantage of the adaptive Gaussian noise is that a differential privacy budget cannot be strictly controlled. +* Adaptive clipping optimizer is a DP optimizer that adaptively adjusts a clipping granularity. Gradient clipping is an important operation in differential privacy training. The adaptive clipping optimizer can control a ratio of gradient clipping to fluctuate within a given range and control the gradient clipping granularity during training steps. + +### DP Mechanisms + +The noise mechanism is a basis for building a differential privacy training capability. Different noise mechanisms meet requirements of different DP optimizers, including multiple mechanisms such as constant Gaussian distribution noise, adaptive Gaussian distribution noise, adaptive clipping Gaussian distribution noise, and Laplace distribution noise. + +### Monitor + +Monitor provides callback functions such as Rényi differential privacy (RDP) and zero-concentrated differential privacy (ZCDP) to monitor the differential privacy budget of the model. + +* ZCDP[2] + + ZCDP is a loose differential privacy definition. It uses the Rényi divergence to measure the distribution difference of random functions on adjacent datasets. + +* RDP[3] + + RDP is a more general differential privacy definition based on the Rényi divergence. It uses the Rényi divergence to measure the distribution difference between two adjacent datasets. + + +Compared with traditional differential privacy, ZCDP and RDP provide stricter privacy budget upper bound guarantee. + + +## Code Implementation + +* [mechanisms.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/mechanisms/mechanisms.py): implements the noise generation mechanism required by differential privacy training, including simple Gaussian noise, adaptive Gaussian noise, and adaptive clipping Gaussian noise. +* [optimizer.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/optimizer/optimizer.py): implements the fundamental logic of using the noise generation mechanism to add noise during backward propagation. +* [monitor.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/monitor/monitor.py): implements the callback function for computing the differential privacy budget. During model training, the current differential privacy budget is returned. +* [model.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/privacy/diff_privacy/train/model.py): implements the logic of computing the loss and gradient as well as the gradient truncation logic of differential privacy training, which is the entry for users to use the differential privacy training capability. + +## References + +[1] Dwork, Cynthia, and Jing Lei. "Differential privacy and robust statistics." *Proceedings of the forty-first annual ACM symposium on Theory of computing*. 2009. + +[2] Lee, Jaewoo, and Daniel Kifer. "Concentrated differentially private gradient descent with adaptive per-iteration privacy budget." *Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining*. 2018. + +[3] Mironov, Ilya. "Rényi differential privacy." *2017 IEEE 30th Computer Security Foundations Symposium (CSF)*. IEEE, 2017. diff --git a/docs/note/source_en/design/mindarmour/images/dp_arch.png b/docs/note/source_en/design/mindarmour/images/dp_arch.png new file mode 100644 index 0000000000000000000000000000000000000000..c903e4e2acece6c6de882852dc3570126b6fcb05 GIT binary patch literal 61680 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 Ha^L>~&!+}) literal 0 HcmV?d00001 diff --git a/docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md b/docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md index b919d27912..72868f5dc7 100644 --- a/docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md +++ b/docs/note/source_zh_cn/design/mindarmour/differential_privacy_design.md @@ -14,7 +14,7 @@ - + ## 总体设计 -- Gitee From 9d54e138b41545ee77ef4a7f2e8bdfc7a5277e05 Mon Sep 17 00:00:00 2001 From: liyong Date: Wed, 16 Sep 2020 11:00:33 +0800 Subject: [PATCH 042/100] fix autoaug doc --- .../advanced_use/enable_auto_augmentation.md | 234 +++++++++--------- 1 file changed, 123 insertions(+), 111 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md index e29d21f58f..0187c18543 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md @@ -1,6 +1,6 @@ # 应用自动数据增强 -`Linux` `Ascend` `GPU` `CPU` `中级` `高级` +`Linux` `Ascend` `GPU` `CPU` `中级` `高级` `数据准备` @@ -16,11 +16,12 @@ ## 概述 -AutoAugment是在一系列图像增强子策略的搜索空间中通过搜索算法找到适合特定数据集的图像增强方案,针对ImageNet数据集的数据增强增强策略包含25条子策略,每条子策略中包含两种变换,针对一个batch中的每张图像随机挑选一个子策略的组合,以预定的概率来决定是否执行子策略中的每种变换。 +自动数据增强(AutoAugment)[1]是在一系列图像增强子策略的搜索空间中,通过搜索算法找到适合特定数据集的图像增强方案。MindSpore的`c_transforms`模块提供了丰富的C++算子来实现AutoAugment,用户也可以自定义函数或者算子来实现。 +更多MindSpore算子的详细说明参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html)。 -MindSpore的`c_transforms`模块提供了丰富的c_vision++算子来实现AutoAugment,用户也可以自定义函数或者算子来实现。更多MindSpore算子的详细说明参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html)。 +MindSpore算子和AutoAugment中的算子的对应关系如下: -| AutoAugment增强算子 | MindSpore算子 |描述 | +| AutoAugment算子 | MindSpore算子 |描述 | |:-------------------:|:------|--------------| |shearX|RandomAffine|横向剪切| |shearY|RandomAffine|纵向剪切| @@ -37,115 +38,25 @@ MindSpore的`c_transforms`模块提供了丰富的c_vision++算子来实现AutoA |equalize|Equalize|均衡图像直方图| |invert|Invert|反转图像| -ImageNet数据集的增强策略定义如下: - -```python -# define autoAugment operators - -PARAMETER_MAX = 10 - -def float_parameter(level, maxval): - return float(level) * maxval / PARAMETER_MAX - -def int_parameter(level, maxval): - return int(level * maxval / PARAMETER_MAX) - -def shear_x(level): - v = float_parameter(level, 0.3) - return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(-v,-v)), c_vision.RandomAffine(degrees=0, shear=(v, v))]) - -def shear_y(level): - v = float_parameter(level, 0.3) - return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(0, 0, -v,-v)), c_vision.RandomAffine(degrees=0, shear=(0, 0, v, v))]) - -def translate_x(level): - v = float_parameter(level, 150 / 331) - return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(-v,-v)), c_vision.RandomAffine(degrees=0, translate=(v, v))]) - -def translate_y(level): - v = float_parameter(level, 150 / 331) - return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(0, 0, -v,-v)), c_vision.RandomAffine(degrees=0, translate=(0, 0, v, v))]) - -def color_impl(level): - v = float_parameter(level, 1.8) + 0.1 - return c_vision.RandomColor(degrees=(v, v)) - -def rotate_impl(level): - v = int_parameter(level, 30) - return c_transforms.RandomChoice([c_vision.RandomRotation(degrees=(-v, -v)), c_vision.RandomRotation(degrees=(v, v))]) - -def solarize_impl(level): - level = int_parameter(level, 256) - v = 256 - level - return c_vision.RandomSolarize(threshold=(0, v)) - -def posterize_impl(level): - level = int_parameter(level, 4) - v = 4 - level - return c_vision.RandomPosterize(bits=(v, v)) - -def contrast_impl(level): - v = float_parameter(level, 1.8) + 0.1 - return c_vision.RandomColorAdjust(contrast=(v, v)) - -def autocontrast_impl(level): - return c_vision.AutoContrast() - -def sharpness_impl(level): - v = float_parameter(level, 1.8) + 0.1 - return c_vision.RandomSharpness(degrees=(v, v)) - -def brightness_impl(level): - v = float_parameter(level, 1.8) + 0.1 - return c_vision.RandomColorAdjust(brightness=(v, v)) - -# define AutoAugment policy -imagenet_policy = [ - [(posterize_impl(8), 0.4), (rotate_impl(9), 0.6)], - [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)], - [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)], - [(posterize_impl(7), 0.6), (posterize_impl(6), 0.6)], - [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)], - - [(c_vision.Equalize(), 0.4), (rotate_impl(8), 0.8)], - [(solarize_impl(3), 0.6), (c_vision.Equalize(), 0.6)], - [(posterize_impl(5), 0.8), (c_vision.Equalize(), 1.0)], - [(rotate_impl(3), 0.2), (solarize_impl(8), 0.6)], - [(c_vision.Equalize(), 0.6), (posterize_impl(6), 0.4)], - - [(rotate_impl(8), 0.8), (color_impl(0), 0.4)], - [(rotate_impl(9), 0.4), (c_vision.Equalize(), 0.6)], - [(c_vision.Equalize(), 0.0), (c_vision.Equalize(), 0.8)], - [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)], - [(color_impl(4), 0.6), (contrast_impl(8), 1.0)], - - [(rotate_impl(8), 0.8), (color_impl(2), 1.0)], - [(color_impl(8), 0.8), (solarize_impl(7), 0.8)], - [(sharpness_impl(7), 0.4), (c_vision.Invert(), 0.6)], - [(shear_x(5), 0.6), (c_vision.Equalize(), 1.0)], - [(color_impl(0), 0.4), (c_vision.Equalize(), 0.6)], - - [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)], - [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)], - [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)], - [(color_impl(4), 0.6), (contrast_impl(8), 1.0)], - [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)], - ] -``` - ## ImageNet自动数据增强 +本教程以在ImageNet数据集上实现AutoAugment作为示例。 + +针对ImageNet数据集的数据增强策略包含25条子策略,每条子策略中包含两种变换,针对一个batch中的每张图像随机挑选一个子策略的组合,以预定的概率来决定是否执行子策略中的每种变换。 -用户可以使用Mindspore提供的`RandomSelectSubpolicy`接口来实现自动数据增强, +用户可以使用MindSpore中`c_transforms`模块的`RandomSelectSubpolicy`接口来实现AutoAugment, 在ImageNet分类训练中标准的数据增强方式分以下几个步骤: -1. `RandomCropDecodeResize`:随机裁剪后进行解码。 -2. `RandomHorizontalFlip`:水平方向上随机翻转。 -3. `Normalize`:归一化。 -4. `HWC2CHW`:shape变换。 +一. `RandomCropDecodeResize`:随机裁剪后进行解码。 + +二. `RandomHorizontalFlip`:水平方向上随机翻转。 + +三. `Normalize`:归一化。 -在步骤1后插入AutoAugment变换,如下所示: +四. `HWC2CHW`:shape变换。 -1. 引入mindspore数据增强模块。 +在步骤一后插入AutoAugment变换,如下所示: + +1. 引入MindSpore数据增强模块。 ```python import mindspore.common.dtype as mstype @@ -155,7 +66,108 @@ imagenet_policy = [ import matplotlib.pyplot as plt ``` -2. 在`RandomCropDecodeResize`操作后插入AutoAugment变换。 +2. 定义MindSpore算子到AutoAugment算子的映射: + + ```python + # define AutoAugment operators + + PARAMETER_MAX = 10 + + def float_parameter(level, maxval): + return float(level) * maxval / PARAMETER_MAX + + def int_parameter(level, maxval): + return int(level * maxval / PARAMETER_MAX) + + def shear_x(level): + v = float_parameter(level, 0.3) + return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(-v,-v)), c_vision.RandomAffine(degrees=0, shear=(v, v))]) + + def shear_y(level): + v = float_parameter(level, 0.3) + return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(0, 0, -v,-v)), c_vision.RandomAffine(degrees=0, shear=(0, 0, v, v))]) + + def translate_x(level): + v = float_parameter(level, 150 / 331) + return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(-v,-v)), c_vision.RandomAffine(degrees=0, translate=(v, v))]) + + def translate_y(level): + v = float_parameter(level, 150 / 331) + return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(0, 0, -v,-v)), c_vision.RandomAffine(degrees=0, translate=(0, 0, v, v))]) + + def color_impl(level): + v = float_parameter(level, 1.8) + 0.1 + return c_vision.RandomColor(degrees=(v, v)) + + def rotate_impl(level): + v = int_parameter(level, 30) + return c_transforms.RandomChoice([c_vision.RandomRotation(degrees=(-v, -v)), c_vision.RandomRotation(degrees=(v, v))]) + + def solarize_impl(level): + level = int_parameter(level, 256) + v = 256 - level + return c_vision.RandomSolarize(threshold=(0, v)) + + def posterize_impl(level): + level = int_parameter(level, 4) + v = 4 - level + return c_vision.RandomPosterize(bits=(v, v)) + + def contrast_impl(level): + v = float_parameter(level, 1.8) + 0.1 + return c_vision.RandomColorAdjust(contrast=(v, v)) + + def autocontrast_impl(level): + return c_vision.AutoContrast() + + def sharpness_impl(level): + v = float_parameter(level, 1.8) + 0.1 + return c_vision.RandomSharpness(degrees=(v, v)) + + def brightness_impl(level): + v = float_parameter(level, 1.8) + 0.1 + return c_vision.RandomColorAdjust(brightness=(v, v)) + + ``` + +3. 定义ImageNet数据集的AutoAugment策略: + ```python + # define AutoAugment policy + imagenet_policy = [ + [(posterize_impl(8), 0.4), (rotate_impl(9), 0.6)], + [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)], + [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)], + [(posterize_impl(7), 0.6), (posterize_impl(6), 0.6)], + [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)], + + [(c_vision.Equalize(), 0.4), (rotate_impl(8), 0.8)], + [(solarize_impl(3), 0.6), (c_vision.Equalize(), 0.6)], + [(posterize_impl(5), 0.8), (c_vision.Equalize(), 1.0)], + [(rotate_impl(3), 0.2), (solarize_impl(8), 0.6)], + [(c_vision.Equalize(), 0.6), (posterize_impl(6), 0.4)], + + [(rotate_impl(8), 0.8), (color_impl(0), 0.4)], + [(rotate_impl(9), 0.4), (c_vision.Equalize(), 0.6)], + [(c_vision.Equalize(), 0.0), (c_vision.Equalize(), 0.8)], + [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)], + [(color_impl(4), 0.6), (contrast_impl(8), 1.0)], + + [(rotate_impl(8), 0.8), (color_impl(2), 1.0)], + [(color_impl(8), 0.8), (solarize_impl(7), 0.8)], + [(sharpness_impl(7), 0.4), (c_vision.Invert(), 0.6)], + [(shear_x(5), 0.6), (c_vision.Equalize(), 1.0)], + [(color_impl(0), 0.4), (c_vision.Equalize(), 0.6)], + + [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)], + [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)], + [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)], + [(color_impl(4), 0.6), (contrast_impl(8), 1.0)], + [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)], + ] + + ``` + +4. 在`RandomCropDecodeResize`操作后插入AutoAugment变换。 ```python def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, shuffle=True, num_samples=5, target="Ascend"): @@ -201,7 +213,7 @@ imagenet_policy = [ return ds ``` -3. 验证自动数据增强效果。 +5. 验证自动数据增强效果。 ```python # path to imagefolder directory. This directory needs to contain sub-directories which contain the images @@ -224,12 +236,12 @@ imagenet_policy = [ plt.show() ``` - >为了更好演示效果从数据集中只读取5张图片并且不进行`shuffle`,并且为了更好显示图片不进行`Normalize`和`HWC2CHW`操作。 + >为了更好演示效果,从数据集中只读取5张图片并且不进行`shuffle`且不进行`Normalize`和`HWC2CHW`操作。 - 运行结果可以看到,batch中每张图像的增强效果,X方向表示1个batch的5张图像,Y方向表示5个bacth。 ![augment](./images/auto_augmentation.png) + 运行结果可以看到,batch中每张图像的增强效果,X方向表示1个batch的5张图像,Y方向表示5个bacth。 ## 参考文献 [1] [AutoAugment: Learning Augmentation Policies from Data](https://arxiv.org/abs/1805.09501) -- Gitee From 8946a28580254214c72c3a0c274d08a0f36c766a Mon Sep 17 00:00:00 2001 From: zhangyi Date: Tue, 15 Sep 2020 20:14:15 +0800 Subject: [PATCH 043/100] Adjust the structure of API's contents in the web. --- docs/api_python/source_en/index.rst | 14 +-- .../source_en/mindspore/mindspore.dtype.rst | 111 ----------------- .../mindspore/mindspore.ops.composite.rst | 5 - .../mindspore/mindspore.ops.operations.rst | 5 - .../source_en/mindspore/mindspore.rst | 106 ++++++++++++++++- .../source_en/mindspore/mindspore.train.rst | 12 ++ docs/api_python/source_zh_cn/index.rst | 14 +-- .../mindspore/mindspore.dtype.rst | 112 ------------------ .../mindspore/mindspore.ops.composite.rst | 5 - .../mindspore/mindspore.ops.operations.rst | 5 - .../source_zh_cn/mindspore/mindspore.rst | 106 ++++++++++++++++- .../mindspore/mindspore.train.rst | 12 ++ .../_static/logo_online_experience.png | Bin 0 -> 1991 bytes .../source_zh_cn/quick_start/quick_start.md | 2 + 14 files changed, 246 insertions(+), 263 deletions(-) delete mode 100644 docs/api_python/source_en/mindspore/mindspore.dtype.rst delete mode 100644 docs/api_python/source_en/mindspore/mindspore.ops.composite.rst delete mode 100644 docs/api_python/source_en/mindspore/mindspore.ops.operations.rst delete mode 100644 docs/api_python/source_zh_cn/mindspore/mindspore.dtype.rst delete mode 100644 docs/api_python/source_zh_cn/mindspore/mindspore.ops.composite.rst delete mode 100644 docs/api_python/source_zh_cn/mindspore/mindspore.ops.operations.rst create mode 100644 tutorials/training/source_zh_cn/_static/logo_online_experience.png diff --git a/docs/api_python/source_en/index.rst b/docs/api_python/source_en/index.rst index 5e24b2f5ab..c7cf2eb81d 100644 --- a/docs/api_python/source_en/index.rst +++ b/docs/api_python/source_en/index.rst @@ -11,25 +11,21 @@ MindSpore API :caption: MindSpore Python API mindspore/mindspore - mindspore/mindspore.dtype mindspore/mindspore.common.initializer mindspore/mindspore.communication mindspore/mindspore.context - mindspore/mindspore.nn - mindspore/mindspore.nn.dynamic_lr - mindspore/mindspore.nn.learning_rate_schedule - mindspore/mindspore.nn.probability - mindspore/mindspore.ops - mindspore/mindspore.ops.composite - mindspore/mindspore.ops.operations - mindspore/mindspore.train mindspore/mindspore.dataset mindspore/mindspore.dataset.config mindspore/mindspore.dataset.text mindspore/mindspore.dataset.transforms mindspore/mindspore.dataset.vision mindspore/mindspore.mindrecord + mindspore/mindspore.nn + mindspore/mindspore.nn.dynamic_lr + mindspore/mindspore.nn.probability + mindspore/mindspore.ops mindspore/mindspore.profiler + mindspore/mindspore.train .. toctree:: :maxdepth: 1 diff --git a/docs/api_python/source_en/mindspore/mindspore.dtype.rst b/docs/api_python/source_en/mindspore/mindspore.dtype.rst deleted file mode 100644 index ecedea9718..0000000000 --- a/docs/api_python/source_en/mindspore/mindspore.dtype.rst +++ /dev/null @@ -1,111 +0,0 @@ -mindspore.dtype -=============== - -Data Type ----------- - -.. class:: mindspore.dtype - -Create a data type object of MindSpore. - -The actual path of ``dtype`` is ``/mindspore/common/dtype.py``. -Run the following command to import the package: - -.. code-block:: - - import mindspore.common.dtype as mstype - -or - -.. code-block:: - - from mindspore import dtype as mstype - -Numeric Type -~~~~~~~~~~~~ - -Currently, MindSpore supports ``Int`` type, ``Uint`` type and ``Float`` type. -The following table lists the details. - -============================================== ============================= -Definition Description -============================================== ============================= -``mindspore.int8`` , ``mindspore.byte`` 8-bit integer -``mindspore.int16`` , ``mindspore.short`` 16-bit integer -``mindspore.int32`` , ``mindspore.intc`` 32-bit integer -``mindspore.int64`` , ``mindspore.intp`` 64-bit integer -``mindspore.uint8`` , ``mindspore.ubyte`` unsigned 8-bit integer -``mindspore.uint16`` , ``mindspore.ushort`` unsigned 16-bit integer -``mindspore.uint32`` , ``mindspore.uintc`` unsigned 32-bit integer -``mindspore.uint64`` , ``mindspore.uintp`` unsigned 64-bit integer -``mindspore.float16`` , ``mindspore.half`` 16-bit floating-point number -``mindspore.float32`` , ``mindspore.single`` 32-bit floating-point number -``mindspore.float64`` , ``mindspore.double`` 64-bit floating-point number -============================================== ============================= - -Other Type -~~~~~~~~~~ - -For other defined types, see the following table. - -============================ ================= -Type Description -============================ ================= -``tensor`` MindSpore's ``tensor`` type. Data format uses NCHW. For details, see [tensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/tensor.py). -``MetaTensor`` A tensor only has data type and shape. For details, see [MetaTensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/parameter.py). -``bool_`` Boolean ``True`` or ``False``. -``int_`` Integer scalar. -``uint`` Unsigned integer scalar. -``float_`` Floating-point scalar. -``number`` Number, including ``int_`` , ``uint`` , ``float_`` and ``bool_`` . -``list_`` List constructed by ``tensor`` , such as ``List[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. -``tuple_`` Tuple constructed by ``tensor`` , such as ``Tuple[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. -``function`` Function. Return in two ways, when function is not None, returns Func directly, the other returns Func(args: List[T0,T1,...,Tn], retval: T) when function is None. -``type_type`` Type definition of type. -``type_none`` No matching return type, corresponding to the ``type(None)`` in Python. -``symbolic_key`` The value of a variable is used as a key of the variable in ``env_type`` . -``env_type`` Used to store the gradient of the free variable of a function, where the key is the ``symbolic_key`` of the free variable's node and the value is the gradient. -============================ ================= - -Tree Topology -~~~~~~~~~~~~~~ - -The relationships of the above types are as follows: - -.. code-block:: - - - └─────── number - │ ├─── bool_ - │ ├─── int_ - │ │ ├─── int8, byte - │ │ ├─── int16, short - │ │ ├─── int32, intc - │ │ └─── int64, intp - │ ├─── uint - │ │ ├─── uint8, ubyte - │ │ ├─── uint16, ushort - │ │ ├─── uint32, uintc - │ │ └─── uint64, uintp - │ └─── float_ - │ ├─── float16 - │ ├─── float32 - │ └─── float64 - ├─── tensor - │ ├─── Array[Float32] - │ └─── ... - ├─── list_ - │ ├─── List[Int32,Float32] - │ └─── ... - ├─── tuple_ - │ ├─── Tuple[Int32,Float32] - │ └─── ... - ├─── function - │ ├─── Func - │ ├─── Func[(Int32, Float32), Int32] - │ └─── ... - ├─── MetaTensor - ├─── type_type - ├─── type_none - ├─── symbolic_key - └─── env_type \ No newline at end of file diff --git a/docs/api_python/source_en/mindspore/mindspore.ops.composite.rst b/docs/api_python/source_en/mindspore/mindspore.ops.composite.rst deleted file mode 100644 index 4dc22f1dcf..0000000000 --- a/docs/api_python/source_en/mindspore/mindspore.ops.composite.rst +++ /dev/null @@ -1,5 +0,0 @@ -mindspore.ops.composite -======================= - -.. automodule:: mindspore.ops.composite - :members: diff --git a/docs/api_python/source_en/mindspore/mindspore.ops.operations.rst b/docs/api_python/source_en/mindspore/mindspore.ops.operations.rst deleted file mode 100644 index 29bf49176b..0000000000 --- a/docs/api_python/source_en/mindspore/mindspore.ops.operations.rst +++ /dev/null @@ -1,5 +0,0 @@ -mindspore.ops.operations -======================== - -.. automodule:: mindspore.ops.operations - :members: diff --git a/docs/api_python/source_en/mindspore/mindspore.rst b/docs/api_python/source_en/mindspore/mindspore.rst index 44c49e3df3..f510c8b5fc 100644 --- a/docs/api_python/source_en/mindspore/mindspore.rst +++ b/docs/api_python/source_en/mindspore/mindspore.rst @@ -1,5 +1,109 @@ mindspore ========= +.. class:: mindspore.dtype + + Create a data type object of MindSpore. + + The actual path of ``dtype`` is ``/mindspore/common/dtype.py``. + Run the following command to import the package: + + .. code-block:: + + import mindspore.common.dtype as mstype + + or + + .. code-block:: + + from mindspore import dtype as mstype + + * **Numeric Type** + + Currently, MindSpore supports ``Int`` type, ``Uint`` type and ``Float`` type. + The following table lists the details. + + ============================================== ============================= + Definition Description + ============================================== ============================= + ``mindspore.int8`` , ``mindspore.byte`` 8-bit integer + ``mindspore.int16`` , ``mindspore.short`` 16-bit integer + ``mindspore.int32`` , ``mindspore.intc`` 32-bit integer + ``mindspore.int64`` , ``mindspore.intp`` 64-bit integer + ``mindspore.uint8`` , ``mindspore.ubyte`` unsigned 8-bit integer + ``mindspore.uint16`` , ``mindspore.ushort`` unsigned 16-bit integer + ``mindspore.uint32`` , ``mindspore.uintc`` unsigned 32-bit integer + ``mindspore.uint64`` , ``mindspore.uintp`` unsigned 64-bit integer + ``mindspore.float16`` , ``mindspore.half`` 16-bit floating-point number + ``mindspore.float32`` , ``mindspore.single`` 32-bit floating-point number + ``mindspore.float64`` , ``mindspore.double`` 64-bit floating-point number + ============================================== ============================= + + * **Other Type** + + For other defined types, see the following table. + + ============================ ================= + Type Description + ============================ ================= + ``tensor`` MindSpore's ``tensor`` type. Data format uses NCHW. For details, see [tensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/tensor.py). + ``MetaTensor`` A tensor only has data type and shape. For details, see [MetaTensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/parameter.py). + ``bool_`` Boolean ``True`` or ``False``. + ``int_`` Integer scalar. + ``uint`` Unsigned integer scalar. + ``float_`` Floating-point scalar. + ``number`` Number, including ``int_`` , ``uint`` , ``float_`` and ``bool_`` . + ``list_`` List constructed by ``tensor`` , such as ``List[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. + ``tuple_`` Tuple constructed by ``tensor`` , such as ``Tuple[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. + ``function`` Function. Return in two ways, when function is not None, returns Func directly, the other returns Func(args: List[T0,T1,...,Tn], retval: T) when function is None. + ``type_type`` Type definition of type. + ``type_none`` No matching return type, corresponding to the ``type(None)`` in Python. + ``symbolic_key`` The value of a variable is used as a key of the variable in ``env_type`` . + ``env_type`` Used to store the gradient of the free variable of a function, where the key is the ``symbolic_key`` of the free variable's node and the value is the gradient. + ============================ ================= + + * **Tree Topology** + + The relationships of the above types are as follows: + + .. code-block:: + + + └─────── number + │ ├─── bool_ + │ ├─── int_ + │ │ ├─── int8, byte + │ │ ├─── int16, short + │ │ ├─── int32, intc + │ │ └─── int64, intp + │ ├─── uint + │ │ ├─── uint8, ubyte + │ │ ├─── uint16, ushort + │ │ ├─── uint32, uintc + │ │ └─── uint64, uintp + │ └─── float_ + │ ├─── float16 + │ ├─── float32 + │ └─── float64 + ├─── tensor + │ ├─── Array[Float32] + │ └─── ... + ├─── list_ + │ ├─── List[Int32,Float32] + │ └─── ... + ├─── tuple_ + │ ├─── Tuple[Int32,Float32] + │ └─── ... + ├─── function + │ ├─── Func + │ ├─── Func[(Int32, Float32), Int32] + │ └─── ... + ├─── MetaTensor + ├─── type_type + ├─── type_none + ├─── symbolic_key + └─── env_type + .. automodule:: mindspore - :members: \ No newline at end of file + :members: + :exclude-members: Model, dataset_helper, \ No newline at end of file diff --git a/docs/api_python/source_en/mindspore/mindspore.train.rst b/docs/api_python/source_en/mindspore/mindspore.train.rst index eb6753e672..3d24633055 100644 --- a/docs/api_python/source_en/mindspore/mindspore.train.rst +++ b/docs/api_python/source_en/mindspore/mindspore.train.rst @@ -1,6 +1,18 @@ mindspore.train =============== +mindspore.train.model +--------------------- + +.. automodule:: mindspore.train.model + :members: + +mindspore.train.dataset_helper +------------------------------ + +.. automodule:: mindspore.train.dataset_helper + :members: + mindspore.train.summary ----------------------- diff --git a/docs/api_python/source_zh_cn/index.rst b/docs/api_python/source_zh_cn/index.rst index 13bd141b9f..7131254879 100644 --- a/docs/api_python/source_zh_cn/index.rst +++ b/docs/api_python/source_zh_cn/index.rst @@ -17,25 +17,21 @@ MindSpore API :caption: MindSpore Python API mindspore/mindspore - mindspore/mindspore.dtype mindspore/mindspore.common.initializer mindspore/mindspore.communication mindspore/mindspore.context - mindspore/mindspore.nn - mindspore/mindspore.nn.dynamic_lr - mindspore/mindspore.nn.learning_rate_schedule - mindspore/mindspore.nn.probability - mindspore/mindspore.ops - mindspore/mindspore.ops.composite - mindspore/mindspore.ops.operations - mindspore/mindspore.train mindspore/mindspore.dataset mindspore/mindspore.dataset.config mindspore/mindspore.dataset.text mindspore/mindspore.dataset.transforms mindspore/mindspore.dataset.vision mindspore/mindspore.mindrecord + mindspore/mindspore.nn + mindspore/mindspore.nn.dynamic_lr + mindspore/mindspore.nn.probability + mindspore/mindspore.ops mindspore/mindspore.profiler + mindspore/mindspore.train .. toctree:: :maxdepth: 1 diff --git a/docs/api_python/source_zh_cn/mindspore/mindspore.dtype.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.dtype.rst deleted file mode 100644 index 633cd1e23e..0000000000 --- a/docs/api_python/source_zh_cn/mindspore/mindspore.dtype.rst +++ /dev/null @@ -1,112 +0,0 @@ -mindspore.dtype -=============== - -Data Type ----------- - -.. class:: mindspore.dtype - -Create a data type object of MindSpore. - -The actual path of ``dtype`` is ``/mindspore/common/dtype.py``. -Run the following command to import the package: - -.. code-block:: - - import mindspore.common.dtype as mstype - -or - -.. code-block:: - - from mindspore import dtype as mstype - -Numeric Type -~~~~~~~~~~~~ - -Currently, MindSpore supports ``Int`` type, ``Uint`` type and ``Float`` type. -The following table lists the details. - -============================================== ============================= -Definition Description -============================================== ============================= -``mindspore.int8`` , ``mindspore.byte`` 8-bit integer -``mindspore.int16`` , ``mindspore.short`` 16-bit integer -``mindspore.int32`` , ``mindspore.intc`` 32-bit integer -``mindspore.int64`` , ``mindspore.intp`` 64-bit integer -``mindspore.uint8`` , ``mindspore.ubyte`` unsigned 8-bit integer -``mindspore.uint16`` , ``mindspore.ushort`` unsigned 16-bit integer -``mindspore.uint32`` , ``mindspore.uintc`` unsigned 32-bit integer -``mindspore.uint64`` , ``mindspore.uintp`` unsigned 64-bit integer -``mindspore.float16`` , ``mindspore.half`` 16-bit floating-point number -``mindspore.float32`` , ``mindspore.single`` 32-bit floating-point number -``mindspore.float64`` , ``mindspore.double`` 64-bit floating-point number -============================================== ============================= - -Other Type -~~~~~~~~~~ - -For other defined types, see the following table. - -============================ ================= -Type Description -============================ ================= -``tensor`` MindSpore's ``tensor`` type. Data format uses NCHW. For details, see [tensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/tensor.py). -``MetaTensor`` A tensor only has data type and shape. For details, see [MetaTensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/parameter.py). -``bool_`` Boolean ``True`` or ``False``. -``int_`` Integer scalar. -``uint`` Unsigned integer scalar. -``float_`` Floating-point scalar. -``number`` Number, including ``int_`` , ``uint`` , ``float_`` and ``bool_`` . -``list_`` List constructed by ``tensor`` , such as ``List[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. -``tuple_`` Tuple constructed by ``tensor`` , such as ``Tuple[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. -``function`` Function. Return in two ways, when function is not None, returns Func directly, the other returns Func(args: List[T0,T1,...,Tn], retval: T) when function is None. -``type_type`` Type definition of type. -``type_none`` No matching return type, corresponding to the ``type(None)`` in Python. -``symbolic_key`` The value of a variable is used as a key of the variable in ``env_type`` . -``env_type`` Used to store the gradient of the free variable of a function, where the key is the ``symbolic_key`` of the free variable's node and the value is the gradient. -============================ ================= - -Tree Topology -~~~~~~~~~~~~~~ - -The relationships of the above types are as follows: - -.. code-block:: - - - └─── mindspore.dtype - ├─── number - │ ├─── bool_ - │ ├─── int_ - │ │ ├─── int8, byte - │ │ ├─── int16, short - │ │ ├─── int32, intc - │ │ └─── int64, intp - │ ├─── uint - │ │ ├─── uint8, ubyte - │ │ ├─── uint16, ushort - │ │ ├─── uint32, uintc - │ │ └─── uint64, uintp - │ └─── float_ - │ ├─── float16 - │ ├─── float32 - │ └─── float64 - ├─── tensor - │ ├─── Array[float32] - │ └─── ... - ├─── list_ - │ ├─── List[int32,float32] - │ └─── ... - ├─── tuple_ - │ ├─── Tuple[int32,float32] - │ └─── ... - ├─── function - │ ├─── Func - │ ├─── Func[(int32, float32), int32] - │ └─── ... - ├─── MetaTensor - ├─── type_type - ├─── type_none - ├─── symbolic_key - └─── env_type \ No newline at end of file diff --git a/docs/api_python/source_zh_cn/mindspore/mindspore.ops.composite.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.ops.composite.rst deleted file mode 100644 index 4dc22f1dcf..0000000000 --- a/docs/api_python/source_zh_cn/mindspore/mindspore.ops.composite.rst +++ /dev/null @@ -1,5 +0,0 @@ -mindspore.ops.composite -======================= - -.. automodule:: mindspore.ops.composite - :members: diff --git a/docs/api_python/source_zh_cn/mindspore/mindspore.ops.operations.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.ops.operations.rst deleted file mode 100644 index 29bf49176b..0000000000 --- a/docs/api_python/source_zh_cn/mindspore/mindspore.ops.operations.rst +++ /dev/null @@ -1,5 +0,0 @@ -mindspore.ops.operations -======================== - -.. automodule:: mindspore.ops.operations - :members: diff --git a/docs/api_python/source_zh_cn/mindspore/mindspore.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.rst index 44c49e3df3..f510c8b5fc 100644 --- a/docs/api_python/source_zh_cn/mindspore/mindspore.rst +++ b/docs/api_python/source_zh_cn/mindspore/mindspore.rst @@ -1,5 +1,109 @@ mindspore ========= +.. class:: mindspore.dtype + + Create a data type object of MindSpore. + + The actual path of ``dtype`` is ``/mindspore/common/dtype.py``. + Run the following command to import the package: + + .. code-block:: + + import mindspore.common.dtype as mstype + + or + + .. code-block:: + + from mindspore import dtype as mstype + + * **Numeric Type** + + Currently, MindSpore supports ``Int`` type, ``Uint`` type and ``Float`` type. + The following table lists the details. + + ============================================== ============================= + Definition Description + ============================================== ============================= + ``mindspore.int8`` , ``mindspore.byte`` 8-bit integer + ``mindspore.int16`` , ``mindspore.short`` 16-bit integer + ``mindspore.int32`` , ``mindspore.intc`` 32-bit integer + ``mindspore.int64`` , ``mindspore.intp`` 64-bit integer + ``mindspore.uint8`` , ``mindspore.ubyte`` unsigned 8-bit integer + ``mindspore.uint16`` , ``mindspore.ushort`` unsigned 16-bit integer + ``mindspore.uint32`` , ``mindspore.uintc`` unsigned 32-bit integer + ``mindspore.uint64`` , ``mindspore.uintp`` unsigned 64-bit integer + ``mindspore.float16`` , ``mindspore.half`` 16-bit floating-point number + ``mindspore.float32`` , ``mindspore.single`` 32-bit floating-point number + ``mindspore.float64`` , ``mindspore.double`` 64-bit floating-point number + ============================================== ============================= + + * **Other Type** + + For other defined types, see the following table. + + ============================ ================= + Type Description + ============================ ================= + ``tensor`` MindSpore's ``tensor`` type. Data format uses NCHW. For details, see [tensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/tensor.py). + ``MetaTensor`` A tensor only has data type and shape. For details, see [MetaTensor](https://www.gitee.com/mindspore/mindspore/blob/master/mindspore/common/parameter.py). + ``bool_`` Boolean ``True`` or ``False``. + ``int_`` Integer scalar. + ``uint`` Unsigned integer scalar. + ``float_`` Floating-point scalar. + ``number`` Number, including ``int_`` , ``uint`` , ``float_`` and ``bool_`` . + ``list_`` List constructed by ``tensor`` , such as ``List[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. + ``tuple_`` Tuple constructed by ``tensor`` , such as ``Tuple[T0,T1,...,Tn]`` , where the element ``Ti`` can be of different types. + ``function`` Function. Return in two ways, when function is not None, returns Func directly, the other returns Func(args: List[T0,T1,...,Tn], retval: T) when function is None. + ``type_type`` Type definition of type. + ``type_none`` No matching return type, corresponding to the ``type(None)`` in Python. + ``symbolic_key`` The value of a variable is used as a key of the variable in ``env_type`` . + ``env_type`` Used to store the gradient of the free variable of a function, where the key is the ``symbolic_key`` of the free variable's node and the value is the gradient. + ============================ ================= + + * **Tree Topology** + + The relationships of the above types are as follows: + + .. code-block:: + + + └─────── number + │ ├─── bool_ + │ ├─── int_ + │ │ ├─── int8, byte + │ │ ├─── int16, short + │ │ ├─── int32, intc + │ │ └─── int64, intp + │ ├─── uint + │ │ ├─── uint8, ubyte + │ │ ├─── uint16, ushort + │ │ ├─── uint32, uintc + │ │ └─── uint64, uintp + │ └─── float_ + │ ├─── float16 + │ ├─── float32 + │ └─── float64 + ├─── tensor + │ ├─── Array[Float32] + │ └─── ... + ├─── list_ + │ ├─── List[Int32,Float32] + │ └─── ... + ├─── tuple_ + │ ├─── Tuple[Int32,Float32] + │ └─── ... + ├─── function + │ ├─── Func + │ ├─── Func[(Int32, Float32), Int32] + │ └─── ... + ├─── MetaTensor + ├─── type_type + ├─── type_none + ├─── symbolic_key + └─── env_type + .. automodule:: mindspore - :members: \ No newline at end of file + :members: + :exclude-members: Model, dataset_helper, \ No newline at end of file diff --git a/docs/api_python/source_zh_cn/mindspore/mindspore.train.rst b/docs/api_python/source_zh_cn/mindspore/mindspore.train.rst index eb6753e672..3d24633055 100644 --- a/docs/api_python/source_zh_cn/mindspore/mindspore.train.rst +++ b/docs/api_python/source_zh_cn/mindspore/mindspore.train.rst @@ -1,6 +1,18 @@ mindspore.train =============== +mindspore.train.model +--------------------- + +.. automodule:: mindspore.train.model + :members: + +mindspore.train.dataset_helper +------------------------------ + +.. automodule:: mindspore.train.dataset_helper + :members: + mindspore.train.summary ----------------------- diff --git a/tutorials/training/source_zh_cn/_static/logo_online_experience.png b/tutorials/training/source_zh_cn/_static/logo_online_experience.png new file mode 100644 index 0000000000000000000000000000000000000000..c630af6e0c580998357c4865f25f459e9508333c GIT binary patch literal 1991 zcmV;&2RQhNP)H00009a7bBm000XT z000XT0n*)m`~Uz4c}YY;RA_#sFF z>i_GF9;?;x(Gd<6e$Z%)i19zG)zH~9hIU@Nz zOb90AnV9idG|rV%l$cbmvnrg){^!huGg-s?25nS@JlNZvCIvNMx4mGs4&RJZ6m`*N zoAhRVXV%vBcU&|*?Qzd~`wr^DzRv91Z@Fmt0Fps5Nm10o;J|?mcya{AWK1e& z-+l{%Ik4XWtmT%slF-V^TRNCVec+bM}L| z!E^S7!GXud^)O)CD1d zw|Z#nXh-``+S?Q5yUyk7i@Chn$bj9J;72C9yCy#Vq+*ij7=&Cj4ZmrRn?Wd2C{PqN zmr4t=tck%TCS+!9J*Oyhsr1a+`dlhqrwtPVVn9$%QG#M}W^LUpBbgzb$?AvbFJbDL zwe_Hwgj5+6lbWgFOjffBtc9$rjfxbC@Klg73=e0rn2?3R0Uyg!6y;-CNE@1@o&-=5 zlgfHp>R8eX&!y5$O3Z#}18Ra5-yB`MaQ=f=hi(jC+#VnM_1QD;-ntzvm735rf9~a0 zgy!#j`GmB>o(pHPf{gX#3NproXldL<(~T)zkTEbN$QXQsr4tmBPZeE3mi3frms2aN zkwVc$(>|8XDazE!r|?wcTE7UwnQTldGYCzsti~h>mTyo@LhJ=u2FXaFIO*tSbT0!K zgf>PmPkY>YlQbou5R@3Q1j6A=)bll+ z*J46qQhCudf#GCb?;n{;&RiyY5!F-eL^WuCM1oL!JHWMi#$SQs3DAB0dJr%8uHkgt)sAeh07F#fQfZ#EPkY?j%Zh1_JDka? zG9EY}%zFD^TQ{=Ab9NugsApMDt#pzZH!Y!1=tn0{&fob`tW-wZ+fTH#7|QjXJjtCn z@wZ*+7cai}-f1t0ZC9&5UHz1^ocO)Tdw{XdPRk>O9Ttm^WmmuY%HP(;bKL!}zfRq| zw_B@$8~(N*c33Q!5d9GKew(3A{iEI5eNf(HcD)!hqAx3xjr_2JIHEG;cpoX+3& z{}{%q{&u)%`iiq>w|4(e`TTCJcE#!ZW$#Nc(2%9E&d$`mf5XZE$vRH~`|prNj03TF zD?)~^Db$x!t*rTFAE5*Sv!4%Lj{8`KTYudh4V*oeJ(&z Z)HjqDSD~6lCIkQg002ovPDHLkV1f|c?x+9& literal 0 HcmV?d00001 diff --git a/tutorials/training/source_zh_cn/quick_start/quick_start.md b/tutorials/training/source_zh_cn/quick_start/quick_start.md index 0a2b025632..eef29cfe8d 100644 --- a/tutorials/training/source_zh_cn/quick_start/quick_start.md +++ b/tutorials/training/source_zh_cn/quick_start/quick_start.md @@ -28,6 +28,8 @@    +   + ## 概述 -- Gitee From 54e5116263f52e686efc03eaa0d85d6c04ff8df4 Mon Sep 17 00:00:00 2001 From: yingchen Date: Wed, 16 Sep 2020 17:18:27 +0800 Subject: [PATCH 044/100] update debugging in pynative mode --- .../source_en/advanced_use/debug_in_pynative_mode.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md b/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md index d83c61807d..b64fa616fc 100644 --- a/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md +++ b/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md @@ -17,7 +17,7 @@ ## Overview -MindSpore supports the following running modes which are optimized in terms of debugging or running: +MindSpore supports the following running modes which are optimized for debugging or running: - PyNative mode: dynamic graph mode. In this mode, operators in the neural network are delivered and executed one by one, facilitating the compilation and debugging of the neural network model. - Graph mode: static graph mode. In this mode, the neural network model is compiled into an entire graph and then delivered for execution. This mode uses technologies such as graph optimization to improve the running performance and facilitates large-scale deployment and cross-platform running. @@ -105,12 +105,12 @@ print(output.asnumpy()) [3. 3. 3.]] ``` -> Parallel execution and summary is not supported in PyNative mode, so parallel and summary related operators can not be used. +> Parallel execution and summary are not supported in PyNative mode, so parallel and summary related operators cannot be used. ### Improving PyNative Performance -MindSpore provides the staging function to improve the execution speed of inference tasks in PyNative mode. This function compiles Python functions or Python class methods into computational graphs in PyNative mode and improves the execution speed by using graph optimization technologies, as shown in the following example: +MindSpore provides the Staging function to improve the execution speed of inference tasks in PyNative mode. This function compiles Python functions or Python class methods into computational graphs in PyNative mode and improves the execution speed by using graph optimization technologies, as shown in the following example: ```python import numpy as np -- Gitee From 6126df69553c50aec58d643382b87e87fd5efc86 Mon Sep 17 00:00:00 2001 From: xuxinyu Date: Wed, 16 Sep 2020 17:50:48 +0800 Subject: [PATCH 045/100] update r1.0 glossary --- docs/note/source_en/glossary.md | 9 ++++----- docs/note/source_zh_cn/glossary.md | 8 +++----- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/note/source_en/glossary.md b/docs/note/source_en/glossary.md index 2137f0ee96..3f08ac2a41 100644 --- a/docs/note/source_en/glossary.md +++ b/docs/note/source_en/glossary.md @@ -32,18 +32,17 @@ | LSTM | Long short-term memory, an artificial recurrent neural network (RNN) architecture used for processing and predicting an important event with a long interval and delay in a time sequence. | | Manifest | A data format file. Huawei ModelArt adopts this format. For details, see . | | ME | Mind Expression, MindSpore frontend, which is used to compile tasks from user source code to computational graphs, control execution during training, maintain contexts (in non-sink mode), and dynamically generate graphs (in PyNative mode). | -| MindArmour | MindSpore security component, which is used for AI adversarial example management, AI model attack defense and enhancement, and AI model robustness evaluation. | +| MindArmour | The security module of MindSpore, which improves the confidentiality, integrity and usability of the model through technical means such as differential privacy and adversarial attack and defense. MindArmour prevents attackers from maliciously modifying the model or cracking the internal components of the model to steal the parameters of the model. | | MindData | MindSpore data framework, which provides data loading, enhancement, dataset management, and visualization. | | MindInsight | MindSpore visualization component, which visualizes information such as scalars, images, computational graphs, and model hyperparameters. | +| MindRecord | It is a data format defined by MindSpore, it is a module for reading, writing, searching and converting data sets in MindSpore format. | | MindSpore | Huawei-leaded open-source deep learning framework. | | MindSpore Lite | A lightweight deep neural network inference engine that provides the inference function for models trained by MindSpore on the device side. | -| MindSpore Micro | MindSpore AI engine with smaller package size for IOT devices. | | MNIST database | Modified National Handwriting of Images and Technology database, a large handwritten digit database, which is usually used to train various image processing systems. | | ONNX | Open Neural Network Exchange, is an open format built to represent machine learning models.| | PyNative Mode | MindSpore dynamic graph mode. In this mode, operators in the neural network are delivered and executed one by one, facilitating the compilation and debugging of the neural network model. | | ResNet-50 | Residual Neural Network 50, a residual neural network proposed by four Chinese people, including Kaiming He from Microsoft Research Institute. | -| RT | Runtime. | | Schema | Data set structure definition file, which defines the fields contained in a dataset and the field types. | | Summary | An operator that monitors the values of tensors on the network. It is a peripheral operation in the figure and does not affect the data flow. | -| TBE | Tensor Boost Engine, an operator development tool that is extended based on the Tensor Virtual Machine (TVM) framework. | -| TFRecord | Data format defined by TensorFlow. | \ No newline at end of file +| TBE | Tensor Boost Engine, it is a self-developed NPU operator development tool developed by Huawei, which is expanded on the basis of the TVM (Tensor Virtual Machine) framework. It provides a set of Python API to implement development activities and develop custom operators. | +| TFRecord | Data format defined by TensorFlow. | diff --git a/docs/note/source_zh_cn/glossary.md b/docs/note/source_zh_cn/glossary.md index b597de6ad5..c5721652b0 100644 --- a/docs/note/source_zh_cn/glossary.md +++ b/docs/note/source_zh_cn/glossary.md @@ -32,19 +32,17 @@ | LSTM | Long short-term memory,长短期记忆,对应的网络是一种时间循环神经网络,适合于处理和预测时间序列中间隔和延迟非常长的重要事件。 | | Manifest | 一种数据格式文件,华为ModelArts采用了该格式,详细说明请参见。 | | ME | Mind Expression,MindSpore前端,主要完成从用户源码到计算图的编译任务、训练中控制执行及上下文维护(非下沉模式配置下)、动态图(PyNative模式)等。 | -| MindArmour | MindSpore安全组件,用于AI对抗样本管理,AI模型防攻击和增强,AI模型健壮性评测。 | +| MindArmour | MindSpore安全模块,通过差分隐私、对抗性攻防等技术手段,提升模型的保密性、完整性和可用性,阻止攻击者对模型进行恶意修改或是破解模型的内部构件,窃取模型的参数。 | | MindData | MindSpore数据框架,提供数据加载、增强、数据集管理以及可视化。 | | MindInsight | MindSpore可视化组件,可视化标量、图像、计算图以及模型超参等信息。 | +| MindRecord | MindSpore定义的一种数据格式,是一个执行读取、写入、搜索和转换MindSpore格式数据集的模块。 | | MindSpore | 华为主导开源的深度学习框架。 | | MindSpore Lite | 一个轻量级的深度神经网络推理引擎,提供了将MindSpore训练出的模型在端侧进行推理的功能。 | -| MindSpore Micro | 应用在IoT设备的,包大小更小的MindSpore AI引擎。 | | MNIST database | Modified National Institute of Standards and Technology database,一个大型手写数字数据库,通常用于训练各种图像处理系统。 | | ONNX | Open Neural Network Exchange,是一种针对机器学习所设计的开放式的文件格式,用于存储训练好的模型。| | PyNative Mode | MindSpore的动态图模式,将神经网络中的各个算子逐一下发执行,方便用户编写和调试神经网络模型。 | | ResNet-50 | Residual Neural Network 50,由微软研究院的Kaiming He等四名华人提出的残差神经网络。 | -| RT | Runtime运行时。 | | Schema | 数据集结构定义文件,用于定义数据集包含哪些字段以及字段的类型。 | | Summary | 是对网络中Tensor取值进行监测的一种算子,在图中是“外围”操作,不影响数据流本身。 | -| TBE | Tensor Boost Engine,在TVM( Tensor Virtual Machine )框架基础上扩展的算子开发工具。 | +| TBE | Tensor Boost Engine,华为自研的NPU算子开发工具,在TVM( Tensor Virtual Machine )框架基础上扩展,提供了一套Python API来实施开发活动,进行自定义算子开发。 | | TFRecord | Tensorflow定义的数据格式。 | - -- Gitee From 971a79103331fafc67bc4aa8695ec854e1fbcee3 Mon Sep 17 00:00:00 2001 From: liuchongming Date: Wed, 16 Sep 2020 17:52:17 +0800 Subject: [PATCH 046/100] Fix cli. --- .../migrate_3rd_scripts_mindconverter.md | 51 ++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md index 4da5c1953e..a7e42cb7c1 100644 --- a/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md +++ b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md @@ -34,29 +34,35 @@ MindConverter是一款将PyTorch模型脚本转换至MindSpore的脚本迁移工 MindConverter提供命令行(Command-line interface, CLI)的使用方式,命令如下。 ```bash -mindconverter [-h] [--version] --in_file IN_FILE [--output OUTPUT] - [--report REPORT] +usage: mindconverter [-h] [--version] [--in_file IN_FILE] + [--model_file MODEL_FILE] [--shape SHAPE] + [--output OUTPUT] [--report REPORT] + [--project_path PROJECT_PATH] optional arguments: - -h, --help Show this help message and exit. - --version Show program's version number and exit. - --in_file IN_FILE Specify path for script file to use AST schema to - do script conversation. - --model_file MODEL_FILE PyTorch .pth model file path to use graph - based schema to do script generation. When - `--in_file` and `--model_path` are both provided, - use AST schema as default. - --shape SHAPE Optional, excepted input tensor shape of - `--model_file`. It's required when use graph based - schema. - --output OUTPUT Optional, specify path for converted script file - directory. Default is output directory in the - current working directory. - --report REPORT Optional, specify report directory. Default is - the current working directorys. - --project_path PROJECT Optional, pytorch scripts project path. If pytorch - project is not in PYTHONPATH, please assign - `--project_path` when use graph based schema. + -h, --help show this help message and exit + --version show program version number and exit + --in_file IN_FILE Specify path for script file to use AST schema to do + script conversation. + --model_file MODEL_FILE + PyTorch .pth model file path to use graph based schema + to do script generation. When `--in_file` and + `--model_file` are both provided, use AST schema as + default. + --shape SHAPE Optional, excepted input tensor shape of + `--model_file`. It is required when use graph based + schema. Usage: --shape 3,244,244 + --output OUTPUT Optional, specify path for converted script file + directory. Default output directory is `output` folder + in the current working directory. + --report REPORT Optional, specify report directory. Default is + converted script directory. + --project_path PROJECT_PATH + Optional, PyTorch scripts project path. If PyTorch + project is not in PYTHONPATH, please assign + `--project_path` when use graph based schema. Usage: + --project_path ~/script_file/ + ``` **MindConverter提供两种模型脚本迁移方案:** @@ -149,6 +155,5 @@ mindconverter --model_file /home/user/model.pth --shape 3,224,224 \ ## 注意事项 -1. PyTorch不作为MindInsight明确声明的依赖库,但若想使用基于图结构的脚本生成工具,需要用户手动安装与生成PyTorch模型版本一致的PyTorch库; +1. PyTorch不作为MindInsight明确声明的依赖库。若想使用基于图结构的脚本生成工具,需要用户手动安装与生成PyTorch模型版本一致的PyTorch库(MindConverter推荐使用PyTorch 1.4.0或PyTorch 1.6.0进行脚本生成); 2. 脚本转换工具本质上为算子驱动,对于MindConverter未维护的PyTorch或ONNX算子与MindSpore算子映射,将会出现相应的算子无法转换的问题,对于该类算子,用户可手动修改,或基于MindConverter实现映射关系,向MindInsight仓库贡献。 - -- Gitee From 64b1286ca2b0abb6bf07921b9a0c995d3980aed0 Mon Sep 17 00:00:00 2001 From: xiefangqi Date: Wed, 16 Sep 2020 21:59:25 +0800 Subject: [PATCH 047/100] minddate api change --- .../source_zh_cn/augmentation.md | 36 ++++---- .../source_zh_cn/dataset_conversion.md | 6 +- .../source_zh_cn/dataset_loading.md | 10 +-- .../source_zh_cn/pipeline.md | 86 +++++++++---------- .../programming_guide/source_zh_cn/sampler.md | 6 +- .../source_zh_cn/tokenizer.md | 36 ++++---- .../computer_vision_application.ipynb | 2 +- ...ert_dataset_to_mindspore_data_format.ipynb | 15 ++-- .../data_loading_enhancement.ipynb | 14 +-- .../notebook/debugging_in_pynative_mode.ipynb | 4 +- tutorials/notebook/loading_dataset.ipynb | 42 ++++----- ...nsight_image_histogram_scalar_tensor.ipynb | 4 +- tutorials/notebook/mixed_precision.ipynb | 4 +- tutorials/notebook/model_security.ipynb | 8 +- tutorials/notebook/nlp_application.ipynb | 4 +- ..._the_performance_of_data_preparation.ipynb | 16 ++-- tutorials/notebook/quick_start.ipynb | 10 +-- .../improve_model_security_nad.md | 4 +- .../advanced_use/optimize_data_processing.md | 16 ++-- .../apply_deep_probability_programming.md | 12 +-- .../advanced_use/enable_auto_augmentation.md | 2 +- .../improve_model_security_nad.md | 4 +- .../advanced_use/optimize_data_processing.md | 16 ++-- .../test_model_security_fuzzing.md | 6 +- .../source_zh_cn/use/load_dataset_image.md | 8 +- .../source_zh_cn/use/load_dataset_text.md | 10 +-- .../model_safety/mnist_attack_fgsm.py | 4 +- .../model_safety/mnist_defense_nad.py | 4 +- 28 files changed, 197 insertions(+), 192 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/augmentation.md b/docs/programming_guide/source_zh_cn/augmentation.md index 35920d2dfb..6d20f22c24 100644 --- a/docs/programming_guide/source_zh_cn/augmentation.md +++ b/docs/programming_guide/source_zh_cn/augmentation.md @@ -96,12 +96,12 @@ num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): plt.subplot(2, len(image_list1), i + 1) - plt.imshow(image_list1[i]) - plt.title(label_list1[i]) + plt.imshow(image_list1[i].asnumpy()) + plt.title(label_list1[i].asnumpy()) else: plt.subplot(2, len(image_list2), i + 1) - plt.imshow(image_list2[i % len(image_list2)]) - plt.title(label_list2[i % len(image_list2)]) + plt.imshow(image_list2[i % len(image_list2)].asnumpy()) + plt.title(label_list2[i % len(image_list2)].asnumpy()) plt.show() ``` @@ -167,12 +167,12 @@ num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): plt.subplot(2, len(image_list1), i + 1) - plt.imshow(image_list1[i]) - plt.title(label_list1[i]) + plt.imshow(image_list1[i].asnumpy()) + plt.title(label_list1[i].asnumpy()) else: plt.subplot(2, len(image_list2), i + 1) - plt.imshow(image_list2[i % len(image_list2)]) - plt.title(label_list2[i % len(image_list2)]) + plt.imshow(image_list2[i % len(image_list2)].asnumpy()) + plt.title(label_list2[i % len(image_list2)].asnumpy()) plt.show() ``` @@ -236,12 +236,12 @@ num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): plt.subplot(2, len(image_list1), i + 1) - plt.imshow(image_list1[i].squeeze(), cmap=plt.cm.gray) - plt.title(label_list1[i]) + plt.imshow(image_list1[i].asnumpy().squeeze(), cmap=plt.cm.gray) + plt.title(label_list1[i].asnumpy()) else: plt.subplot(2, len(image_list2), i + 1) - plt.imshow(image_list2[i % len(image_list2)].squeeze(), cmap=plt.cm.gray) - plt.title(label_list2[i % len(image_list2)]) + plt.imshow(image_list2[i % len(image_list2)].asnumpy().squeeze(), cmap=plt.cm.gray) + plt.title(label_list2[i % len(image_list2)].asnumpy()) plt.show() ``` @@ -307,12 +307,12 @@ num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): plt.subplot(2, len(image_list1), i + 1) - plt.imshow(image_list1[i].squeeze(), cmap=plt.cm.gray) - plt.title(label_list1[i]) + plt.imshow(image_list1[i].asnumpy().squeeze(), cmap=plt.cm.gray) + plt.title(label_list1[i].asnumpy()) else: plt.subplot(2, len(image_list2), i + 1) - plt.imshow(image_list2[i % len(image_list2)].squeeze(), cmap=plt.cm.gray) - plt.title(label_list2[i % len(image_list2)]) + plt.imshow(image_list2[i % len(image_list2)].asnumpy().squeeze(), cmap=plt.cm.gray) + plt.title(label_list2[i % len(image_list2)].asnumpy()) plt.show() ``` @@ -376,8 +376,8 @@ for data in dataset2.create_dict_iterator(): num_samples = len(image_list) for i in range(num_samples): plt.subplot(1, len(image_list), i + 1) - plt.imshow(image_list[i].transpose(1, 2, 0)) - plt.title(label_list[i]) + plt.imshow(image_list[i].asnumpy().transpose(1, 2, 0)) + plt.title(label_list[i].asnumpy()) plt.show() ``` diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index 255bab0f4d..29f7557b12 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -93,7 +93,7 @@ decode_op = vision.Decode() data_set = data_set.map(operations=decode_op, input_columns=["data"], num_parallel_workers=2) # 解码data字段 count = 0 - for item in data_set.create_dict_iterator(): # 循环读取MindRecord中所有数据 + for item in data_set.create_dict_iterator(output_numpy=True): # 循环读取MindRecord中所有数据 print("sample: {}".format(item)) count += 1 print("Got {} samples".format(count)) @@ -391,7 +391,7 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) # 创建读取对象,默认开启shuffle count = 0 - for item in data_set.create_dict_iterator(): # 循环读取MindRecord中所有数据 + for item in data_set.create_dict_iterator(output_numpy=True): # 循环读取MindRecord中所有数据 print("sample: {}".format(item)) count += 1 print("Got {} samples".format(count)) @@ -514,7 +514,7 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 decode_op = vision.Decode() data_set = data_set.map(operations=decode_op, input_columns=["image_bytes"], num_parallel_workers=2) # 解码图像字段 count = 0 - for item in data_set.create_dict_iterator(): # 循环读取MindRecord中所有数据 + for item in data_set.create_dict_iterator(output_numpy=True): # 循环读取MindRecord中所有数据 print("sample: {}".format(item)) count += 1 print("Got {} samples".format(count)) diff --git a/docs/programming_guide/source_zh_cn/dataset_loading.md b/docs/programming_guide/source_zh_cn/dataset_loading.md index e3695494d5..320b8300c5 100644 --- a/docs/programming_guide/source_zh_cn/dataset_loading.md +++ b/docs/programming_guide/source_zh_cn/dataset_loading.md @@ -213,7 +213,7 @@ DATA_DIR = "mindrecord_dataset_path" mindrecord_dataset = ds.MindDataset(DATA_DIR) # 启动数据管道读取 -for data in mindrecord_dataset.create_dict_iterator(): +for data in mindrecord_dataset.create_dict_iterator(output_numpy=True): print(data["label"]) ``` @@ -369,8 +369,8 @@ TFRecord是Tensorflow定义的一种二进制数据文件格式。 ``` ``` - {'col1': array(1, dtype=int64), 'col2': array(3, dtype=int64)} - {'col1': array(2, dtype=int64), 'col2': array(4, dtype=int64)} + {'col1': Tensor(shape=[], dtype=Int64, value= 1), 'col2': Tensor(shape=[], dtype=Int64, value= 3)} + {'col1': Tensor(shape=[], dtype=Int64, value= 2), 'col2': Tensor(shape=[], dtype=Int64, value= 4)} ``` ### text数据格式 @@ -383,7 +383,7 @@ DATA_DIR = "text_file_path" text_dataset = ds.TextFileDataset(DATA_DIR) # 启动数据管道读取 -for data in text_dataset.create_dict_iterator(): +for data in text_dataset.create_dict_iterator(output_numpy=True): print(data["label"]) ``` @@ -397,7 +397,7 @@ DATA_DIR = "csv_file_path" csv_dataset = ds.CSVDataset(DATA_DIR) # 启动数据管道读取 -for data in csv_dataset.create_dict_iterator(): +for data in csv_dataset.create_dict_iterator(output_numpy=True): print(data["label"]) ``` diff --git a/docs/programming_guide/source_zh_cn/pipeline.md b/docs/programming_guide/source_zh_cn/pipeline.md index bb87c70caf..a7a4fdcb60 100644 --- a/docs/programming_guide/source_zh_cn/pipeline.md +++ b/docs/programming_guide/source_zh_cn/pipeline.md @@ -71,11 +71,11 @@ for data in dataset1.create_dict_iterator(): ``` ``` -{'data': array([0, 1, 2], dtype=int64)} -{'data': array([2, 3, 4], dtype=int64)} -{'data': array([3, 4, 5], dtype=int64)} -{'data': array([1, 2, 3], dtype=int64)} -{'data': array([4, 5, 6], dtype=int64)} +{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} ``` ### map @@ -119,17 +119,17 @@ for data in dataset.create_dict_iterator(): ``` ``` -{'data': array([0, 1, 2], dtype=int64)} -{'data': array([1, 2, 3], dtype=int64)} -{'data': array([2, 3, 4], dtype=int64)} -{'data': array([3, 4, 5], dtype=int64)} -{'data': array([4, 5, 6], dtype=int64)} - -{'data': array([0, 2, 4], dtype=int64)} -{'data': array([2, 4, 6], dtype=int64)} -{'data': array([4, 6, 8], dtype=int64)} -{'data': array([ 6, 8, 10], dtype=int64)} -{'data': array([ 8, 10, 12], dtype=int64)} +{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} + +{'data': Tensor(shape=[3], dtype=Int64, value= [0, 2, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value= [2, 4, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value= [4, 6, 8])} +{'data': Tensor(shape=[3], dtype=Int64, value= [ 6, 8, 10])} +{'data': Tensor(shape=[3], dtype=Int64, value= [ 8, 10, 12])} ``` ### batch @@ -171,12 +171,12 @@ for data in dataset2.create_dict_iterator(): ``` ``` -{'data': array([[0, 1, 2], [1, 2, 3]], dtype=int64)} -{'data': array([[2, 3, 4], [3, 4, 5]], dtype=int64)} -{'data': array([[4, 5, 6]], dtype=int64)} +{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[0, 1, 2], [1, 2, 3]])} +{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[2, 3, 4], [3, 4, 5]])} +{'data': Tensor(shape=[1, 3], dtype=Int64, value= [[4, 5, 6]])} -{'data': array([[0, 1, 2], [1, 2, 3]], dtype=int64)} -{'data': array([[2, 3, 4], [3, 4, 5]], dtype=int64)} +{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[0, 1, 2], [1, 2, 3]])} +{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[2, 3, 4], [3, 4, 5]])} ``` ### repeat @@ -209,16 +209,16 @@ for data in dataset1.create_dict_iterator(): ``` ``` -{'data': array([0, 1, 2], dtype=int64)} -{'data': array([1, 2, 3], dtype=int64)} -{'data': array([2, 3, 4], dtype=int64)} -{'data': array([3, 4, 5], dtype=int64)} -{'data': array([4, 5, 6], dtype=int64)} -{'data': array([0, 1, 2], dtype=int64)} -{'data': array([1, 2, 3], dtype=int64)} -{'data': array([2, 3, 4], dtype=int64)} -{'data': array([3, 4, 5], dtype=int64)} -{'data': array([4, 5, 6], dtype=int64)} +{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} ``` ### zip @@ -259,10 +259,10 @@ for data in dataset3.create_dict_iterator(): ``` ``` -{'data1': array([0, 1, 2], dtype=int64), 'data2': array([1, 2], dtype=int64)} -{'data1': array([1, 2, 3], dtype=int64), 'data2': array([1, 2], dtype=int64)} -{'data1': array([2, 3, 4], dtype=int64), 'data2': array([1, 2], dtype=int64)} -{'data1': array([3, 4, 5], dtype=int64), 'data2': array([1, 2], dtype=int64)} +{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} ``` ### concat @@ -305,10 +305,10 @@ for data in dataset3.create_dict_iterator(): ``` ``` -{'data1': array([0, 0, 0], dtype=int64)} -{'data1': array([0, 0, 0], dtype=int64)} -{'data1': array([1, 2, 3], dtype=int64)} -{'data1': array([1, 2, 3], dtype=int64)} +{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} ``` ### project @@ -348,9 +348,9 @@ for data in dataset.create_dict_iterator(): ``` ``` -{'data1': array([1, 2, 3], dtype=int64), 'data2': array([7, 8, 9], dtype=int64)} -{'data1': array([1, 2, 3], dtype=int64), 'data2': array([7, 8, 9], dtype=int64)} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[3], dtype=Int64, value= [7, 8, 9])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[3], dtype=Int64, value= [7, 8, 9])} -{'data1': array([1, 2, 3], dtype=int64)} -{'data1': array([1, 2, 3], dtype=int64)} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} ``` diff --git a/docs/programming_guide/source_zh_cn/sampler.md b/docs/programming_guide/source_zh_cn/sampler.md index dc76658852..acdf43341e 100644 --- a/docs/programming_guide/source_zh_cn/sampler.md +++ b/docs/programming_guide/source_zh_cn/sampler.md @@ -310,9 +310,9 @@ for data in dataset.create_dict_iterator(): ``` ``` -{'data': array(0, dtype=int64)} -{'data': array(3, dtype=int64)} -{'data': array(6, dtype=int64)} +{'data': Tensor(shape=[], dtype=Int64, value= 0)} +{'data': Tensor(shape=[], dtype=Int64, value= 3)} +{'data': Tensor(shape=[], dtype=Int64, value= 6)} ``` ## 自定义采样器 diff --git a/docs/programming_guide/source_zh_cn/tokenizer.md b/docs/programming_guide/source_zh_cn/tokenizer.md index 225ce08707..65c73d8a7d 100644 --- a/docs/programming_guide/source_zh_cn/tokenizer.md +++ b/docs/programming_guide/source_zh_cn/tokenizer.md @@ -53,7 +53,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) #打印分词后的数据输出 @@ -65,7 +65,7 @@ basic_tokenizer = text.BasicTokenizer() dataset = dataset.map(operations=basic_tokenizer) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` @@ -104,7 +104,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) # 字符串列表,其中每个元素都是字符串类型的单词。 @@ -126,7 +126,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` @@ -171,7 +171,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.JiebaTokenizer(HMM_FILE, MP_FILE) @@ -181,7 +181,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=jieba_op, input_columns=["text"], num_parallel_workers=1) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` @@ -212,7 +212,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.RegexTokenizer(delim_pattern) @@ -222,7 +222,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` @@ -250,7 +250,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) # 从文件数据中构建一个vocab对象 @@ -262,7 +262,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` @@ -290,7 +290,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.UnicodeCharTokenizer() @@ -300,7 +300,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` @@ -332,7 +332,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.UnicodeScriptTokenizer() @@ -342,7 +342,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` @@ -374,7 +374,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.WhitespaceTokenizer() @@ -384,7 +384,7 @@ print("------------------------after tokenize-----------------------------") dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` @@ -417,7 +417,7 @@ dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False print("------------------------before tokenize----------------------------") # 输出分词之前的数据 -for data in dataset.create_dict_iterator(): +for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) #打印分词后的数据输出 @@ -432,7 +432,7 @@ tokenizer_op = text.WordpieceTokenizer(vocab=vocab) dataset = dataset.map(operations=tokenizer_op) -for i in dataset.create_dict_iterator(num_epochs=1): +for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` diff --git a/tutorials/notebook/computer_vision_application.ipynb b/tutorials/notebook/computer_vision_application.ipynb index 17065fcbb5..2b2f978b16 100644 --- a/tutorials/notebook/computer_vision_application.ipynb +++ b/tutorials/notebook/computer_vision_application.ipynb @@ -314,7 +314,7 @@ "import matplotlib.pyplot as plt\n", "dataset_show = create_dataset()\n", "iterator_show= dataset_show.create_dict_iterator()\n", - "images = iterator_show.get_next()[\"image\"]\n", + "images = iterator_show.get_next()[\"image\"].asnumpy()\n", "# Images[0].shape is (3,224,224).We need transpose as (224,224,3) for using in plt.show().\n", "picture_show = np.transpose(images[0],(1,2,0))\n", "plt.imshow(picture_show)\n" diff --git a/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb b/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb index f34bc0c817..0fea6b2a76 100644 --- a/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb +++ b/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb @@ -194,7 +194,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'data': array([255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1,\n", + "{'data': Tensor(shape=[803], dtype=UInt8, value= [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1,\n", " 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2,\n", " 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2,\n", " 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6,\n", @@ -250,8 +250,7 @@ " 143, 6, 252, 112, 209, 62, 35, 120, 247, 224, 174, 137, 168,\n", " 77, 241, 3, 92, 240, 206, 167, 29, 245, 142, 155, 115, 114,\n", " 80, 27, 5, 157, 73, 203, 164, 139, 42, 249, 103, 12, 145,\n", - " 195, 22, 229, 5, 128, 31, 149, 148, 81, 69, 21, 255, 217],\n", - " dtype=uint8), 'label': array(3, dtype=int64)}\n" + " 195, 22, 229, 5, 128, 31, 149, 148, 81, 69, 21, 255, 217]), 'label': Tensor(shape=[], dtype=Int64, value= 3)}\n" ] } ], @@ -376,7 +375,7 @@ "# create MindDataset for reading data\n", "csv_data_set = ds.MindDataset(dataset_file=csv_mindrecord_path)\n", "# create a dictionary iterator and read a data record through the iterator\n", - "print(next(csv_data_set.create_dict_iterator()))" + "print(next(csv_data_set.create_dict_iterator(output_numpy=True)))" ] }, { @@ -493,7 +492,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'data': array([255, 216, 255, ..., 35, 255, 217], dtype=uint8), 'id': array(30707, dtype=int64), 'label': array(4, dtype=int64)}\n" + "{'data': Tensor(shape=[1431], dtype=UInt8, value= [255, 216, 255, ..., 35, 255, 217]), 'id': Tensor(shape=[], dtype=Int64, value= 30707), 'label': Tensor(shape=[], dtype=Int64, value= 4)}\n" ] } ], @@ -620,7 +619,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'data': array([255, 216, 255, ..., 127, 255, 217], dtype=uint8), 'fine_label': array(88, dtype=int64), 'coarse_label': array(8, dtype=int64), 'id': array(10349, dtype=int64)}\n" + "{'data': Tensor(shape=[1374], dtype=UInt8, value= [255, 216, 255, ..., 127, 255, 217]), 'fine_label': Tensor(shape=[], dtype=Int64, value= 88), 'coarse_label': Tensor(shape=[], dtype=Int64, value= 8), 'id': Tensor(shape=[], dtype=Int64, value= 10349)}\n" ] } ], @@ -767,7 +766,7 @@ "# create MindDataset for reading data\n", "imagenet_data_set = ds.MindDataset(dataset_file=file_name)\n", "# create a dictionary iterator and read a data record through the iterator\n", - "print(next(imagenet_data_set.create_dict_iterator()))" + "print(next(imagenet_data_set.create_dict_iterator(output_numpy=True)))" ] }, { @@ -938,7 +937,7 @@ "# create MindDataset for reading data\n", "define_data_set = ds.MindDataset(dataset_file=file_name)\n", "# create a dictionary iterator and read a data record through the iterator\n", - "print(next(define_data_set.create_dict_iterator()))" + "print(next(define_data_set.create_dict_iterator(output_numpy=True)))" ] }, { diff --git a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb index 60aaa92e94..6733e3aa75 100644 --- a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb +++ b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb @@ -383,11 +383,11 @@ "[ 3 2 1 0 -1]\n", "[4 3 2 1 0]\n", "After zip:\n", - "{'data': array([0, 1, 2, 3, 4], dtype=int32), 'data2': array([ 0, -1, -2, -3, -4], dtype=int32)}\n", - "{'data': array([1, 2, 3, 4, 5], dtype=int32), 'data2': array([ 1, 0, -1, -2, -3], dtype=int32)}\n", - "{'data': array([2, 3, 4, 5, 6], dtype=int32), 'data2': array([ 2, 1, 0, -1, -2], dtype=int32)}\n", - "{'data': array([3, 4, 5, 6, 7], dtype=int32), 'data2': array([ 3, 2, 1, 0, -1], dtype=int32)}\n", - "{'data': array([4, 5, 6, 7, 8], dtype=int32), 'data2': array([4, 3, 2, 1, 0], dtype=int32)}\n" + "{'data': Tensor(shape=[5], dtype=Int64, value= [0, 1, 2, 3, 4]), 'data2': Tensor(shape=[5], dtype=Int64, value= [ 0, -1, -2, -3, -4])}\n", + "{'data': Tensor(shape=[5], dtype=Int64, value= [1, 2, 3, 4, 5]), 'data2': Tensor(shape=[5], dtype=Int64, value= [ 1, 0, -1, -2, -3])}\n", + "{'data': Tensor(shape=[5], dtype=Int64, value= [2, 3, 4, 5, 6]), 'data2': Tensor(shape=[5], dtype=Int64, value= [ 2, 1, 0, -1, -2])}\n", + "{'data': Tensor(shape=[5], dtype=Int64, value= [3, 4, 5, 6, 7]), 'data2': Tensor(shape=[5], dtype=Int64, value= [ 3, 2, 1, 0, -1])}\n", + "{'data': Tensor(shape=[5], dtype=Int64, value= [4, 5, 6, 7, 8]), 'data2': Tensor(shape=[5], dtype=Int64, value= [4, 3, 2, 1, 0])}\n" ] } ], @@ -518,7 +518,7 @@ ], "source": [ "for data in ds2.create_dict_iterator():\n", - " imgplot_resized = plt.imshow(data[\"image\"])\n", + " imgplot_resized = plt.imshow(data[\"image\"].asnumpy())\n", " plt.show()" ] }, @@ -589,7 +589,7 @@ "compose = Compose(transforms_list)\n", "ds4 = ds3.map(operations=compose, input_columns=\"image\")\n", "for data in ds4.create_dict_iterator():\n", - " imgplot_resized = plt.imshow(data[\"image\"].transpose(1, 2, 0))\n", + " imgplot_resized = plt.imshow(data[\"image\"].asnumpy().transpose(1, 2, 0))\n", " plt.show()" ] }, diff --git a/tutorials/notebook/debugging_in_pynative_mode.ipynb b/tutorials/notebook/debugging_in_pynative_mode.ipynb index c5e9993c98..1e93c5bcc4 100644 --- a/tutorials/notebook/debugging_in_pynative_mode.ipynb +++ b/tutorials/notebook/debugging_in_pynative_mode.ipynb @@ -187,8 +187,8 @@ "datas = create_dataset(train_data_path)\n", "data1 = datas.create_dict_iterator()\n", "data= data1.get_next()\n", - "images = data[\"image\"]\n", - "labels = data[\"label\"]\n", + "images = data[\"image\"].asnumpy()\n", + "labels = data[\"label\"].asnumpy()\n", "print(images.shape)\n", "count = 1\n", "for i in images:\n", diff --git a/tutorials/notebook/loading_dataset.ipynb b/tutorials/notebook/loading_dataset.ipynb index d1865e5fd7..5fbe6d57b4 100644 --- a/tutorials/notebook/loading_dataset.ipynb +++ b/tutorials/notebook/loading_dataset.ipynb @@ -283,7 +283,7 @@ "count = 0\n", "for data in cifar10_dataset.create_dict_iterator():\n", "# In CIFAR-10 dataset, each dictionary of data has keys \"image\" and \"label\".\n", - " image = data[\"image\"]\n", + " image = data[\"image\"].asnumpy()\n", " print(f\"The data of image {count+1} is below:\")\n", " print(image)\n", " plt.figure(count)\n", @@ -491,27 +491,27 @@ "output_type": "stream", "text": [ "dataset1:\n", - "[array([0], dtype=int32)]\n", - "[array([1], dtype=int32)]\n", - "[array([2], dtype=int32)]\n", - "[array([3], dtype=int32)]\n", - "[array([4], dtype=int32)]\n", - "[array([5], dtype=int32)]\n", - "[array([6], dtype=int32)]\n", - "[array([7], dtype=int32)]\n", - "[array([8], dtype=int32)]\n", - "[array([9], dtype=int32)]\n", + "[Tensor(shape=[1], dtype=Int32, value= [0])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [1])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [2])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [3])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [4])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [5])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [6])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [7])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [8])]\n", + "[Tensor(shape=[1], dtype=Int32, value= [9])]\n", "dataset2:\n", - "[array([0], dtype=int64)]\n", - "[array([1], dtype=int64)]\n", - "[array([2], dtype=int64)]\n", - "[array([3], dtype=int64)]\n", - "[array([4], dtype=int64)]\n", - "[array([5], dtype=int64)]\n", - "[array([6], dtype=int64)]\n", - "[array([7], dtype=int64)]\n", - "[array([8], dtype=int64)]\n", - "[array([9], dtype=int64)]\n" + "[Tensor(shape=[1], dtype=Int64, value= [0])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [1])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [2])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [3])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [4])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [5])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [6])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [7])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [8])]\n", + "[Tensor(shape=[1], dtype=Int64, value= [9])]\n" ] } ], diff --git a/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb b/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb index 3b0654081e..f1fb22e942 100644 --- a/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb +++ b/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb @@ -240,8 +240,8 @@ "ds_iterator = ds_train.create_dict_iterator()\n", "ds_iterator.get_next()\n", "batch_1 = ds_iterator.get_next()\n", - "batch_image = batch_1[\"image\"]\n", - "batch_label = batch_1[\"label\"]\n", + "batch_image = batch_1[\"image\"].asnumpy()\n", + "batch_label = batch_1[\"label\"].asnumpy()\n", "%matplotlib inline\n", "plt.figure(dpi=144)\n", "for i,image in enumerate(batch_image):\n", diff --git a/tutorials/notebook/mixed_precision.ipynb b/tutorials/notebook/mixed_precision.ipynb index a595551727..e9f8b54d07 100644 --- a/tutorials/notebook/mixed_precision.ipynb +++ b/tutorials/notebook/mixed_precision.ipynb @@ -167,7 +167,7 @@ "print(\"the cifar dataset size is :\", ds.get_dataset_size())\n", "dict1 = ds.create_dict_iterator()\n", "datas = dict1.get_next()\n", - "image = datas[\"image\"]\n", + "image = datas[\"image\"].asnumpy()\n", "print(\"the tensor of image is:\", image.shape)\n", "plt.imshow(np.array(image))\n", "plt.show()" @@ -282,7 +282,7 @@ "print(\"the cifar dataset size is:\", ds.get_dataset_size())\n", "dict1 = ds.create_dict_iterator()\n", "datas = dict1.get_next()\n", - "image = datas[\"image\"]\n", + "image = datas[\"image\"].asnumpy()\n", "single_pic = np.transpose(image[0], (1,2,0))\n", "print(\"the tensor of image is:\", image.shape)\n", "plt.imshow(np.array(single_pic))\n", diff --git a/tutorials/notebook/model_security.ipynb b/tutorials/notebook/model_security.ipynb index 79c458f78c..bac7061f0b 100644 --- a/tutorials/notebook/model_security.ipynb +++ b/tutorials/notebook/model_security.ipynb @@ -281,8 +281,8 @@ "ds_iterator = ds_train.create_dict_iterator()\n", "ds_iterator.get_next()\n", "batch_1 = ds_iterator.get_next()\n", - "batch_image = batch_1[\"image\"]\n", - "batch_label = batch_1[\"label\"]\n", + "batch_image = batch_1[\"image\"].asnumpy()\n", + "batch_label = batch_1[\"label\"].asnumpy()\n", "%matplotlib inline\n", "plt.figure(dpi=144)\n", "for i,image in enumerate(batch_image):\n", @@ -506,8 +506,8 @@ "i = 0\n", "for data in ds_test.create_tuple_iterator():\n", " i += 1\n", - " images = data[0].astype(np.float32)\n", - " labels = data[1]\n", + " images = data[0].asnumpy().astype(np.float32)\n", + " labels = data[1].asnumpy()\n", " test_images.append(images)\n", " test_labels.append(labels)\n", " pred_labels = np.argmax(model.predict(Tensor(images)).asnumpy(),\n", diff --git a/tutorials/notebook/nlp_application.ipynb b/tutorials/notebook/nlp_application.ipynb index 02cf130217..47fa6ebe6d 100644 --- a/tutorials/notebook/nlp_application.ipynb +++ b/tutorials/notebook/nlp_application.ipynb @@ -652,8 +652,8 @@ ], "source": [ "iterator = ds_train.create_dict_iterator().get_next()\n", - "first_batch_label = iterator[\"label\"]\n", - "first_batch_first_feature = iterator[\"feature\"][0]\n", + "first_batch_label = iterator[\"label\"].asnumpy()\n", + "first_batch_first_feature = iterator[\"feature\"].asnumpy()[0]\n", "print(f\"The first batch contains label below:\\n{first_batch_label}\\n\")\n", "print(f\"The feature of the first item in the first batch is below vector:\\n{first_batch_first_feature}\")" ] diff --git a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb index 4e92276777..11fc98b8c8 100644 --- a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb +++ b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb @@ -210,7 +210,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'image': array([[[235, 235, 235],\n", + "{'image': Tensor(shape=[32, 32, 3], dtype=UInt8, value=\n", + " [[[235, 235, 235],\n", " [230, 230, 230],\n", " [234, 234, 234],\n", " ...,\n", @@ -258,7 +259,7 @@ " ...,\n", " [120, 120, 119],\n", " [146, 146, 146],\n", - " [177, 174, 190]]], dtype=uint8), 'label': array(9, dtype=uint32)}\n" + " [177, 174, 190]]]), 'label': Tensor(shape=[], dtype=UInt32, value= 9)}\n" ] } ], @@ -287,7 +288,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'data': array([255, 216, 255, ..., 63, 255, 217], dtype=uint8), 'id': array(30474, dtype=int64), 'label': array(2, dtype=int64)}\n" + "{'data': Tensor(shape=[1431], dtype=UInt8, value= [255, 216, 255, ..., 63, 255, 217]), 'id': Tensor(shape=[], dtype=Int64, value= 30474), 'label': Tensor(shape=[], dtype=Int64, value= 2)}\n" ] } ], @@ -323,7 +324,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'data': array([0], dtype=int64)}\n" + "{'data': Tensor(shape=[1], dtype=Int64, value= [0])}\n" ] } ], @@ -400,7 +401,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "{'image': array([[[254, 254, 254],\n", + "{'image': Tensor(shape=[32, 32, 3], dtype=UInt8, value=\n", + " [[[254, 254, 254],\n", " [255, 255, 254],\n", " [255, 255, 254],\n", " ...,\n", @@ -448,7 +450,7 @@ " ...,\n", " [ 64, 61, 63],\n", " [ 63, 58, 60],\n", - " [ 61, 56, 58]]], dtype=uint8), 'label': array(9, dtype=uint32)}\n" + " [ 61, 56, 58]]]), 'label': Tensor(shape=[], dtype=UInt32, value= 9)}\n" ] } ], @@ -611,7 +613,7 @@ "cifar10_dataset = cifar10_dataset.map(operations=transforms,input_columns=\"image\",num_parallel_workers=4)\n", "\n", "data = next(cifar10_dataset.create_dict_iterator())\n", - "plt.imshow(data[\"image\"])\n", + "plt.imshow(data[\"image\"].asnumpy())\n", "plt.show()" ] }, diff --git a/tutorials/notebook/quick_start.ipynb b/tutorials/notebook/quick_start.ipynb index 18590d37b5..99757efd66 100644 --- a/tutorials/notebook/quick_start.ipynb +++ b/tutorials/notebook/quick_start.ipynb @@ -250,15 +250,15 @@ "\n", "dic_ds = mnist_ds.create_dict_iterator()\n", "item = dic_ds.get_next()\n", - "img = item[\"image\"]\n", - "label = item[\"label\"]\n", + "img = item[\"image\"].asnumpy()\n", + "label = item[\"label\"].asnumpy()\n", "\n", "print(\"The item of mnist_ds:\", item.keys())\n", "print(\"Tensor of image in item:\", img.shape) \n", "print(\"The label of item:\", label)\n", "\n", "plt.imshow(np.squeeze(img))\n", - "plt.title(\"number:%s\"% item[\"label\"])\n", + "plt.title(\"number:%s\"% item[\"label\"].asnumpy())\n", "plt.show()" ] }, @@ -1062,8 +1062,8 @@ "source": [ "ds_test = create_dataset(test_data_path).create_dict_iterator()\n", "data = ds_test.get_next()\n", - "images = data[\"image\"]\n", - "labels = data[\"label\"]\n", + "images = data[\"image\"].asnumpy()\n", + "labels = data[\"label\"].asnumpy()\n", "\n", "output = model.predict(Tensor(data['image']))\n", "prb = output.asnumpy()\n", diff --git a/tutorials/training/source_en/advanced_use/improve_model_security_nad.md b/tutorials/training/source_en/advanced_use/improve_model_security_nad.md index 1116b2718c..d6e6415b31 100644 --- a/tutorials/training/source_en/advanced_use/improve_model_security_nad.md +++ b/tutorials/training/source_en/advanced_use/improve_model_security_nad.md @@ -198,8 +198,8 @@ The LeNet model is used as an example. You can also create and train your own mo inputs = [] labels = [] for data in ds_test.create_tuple_iterator(): - inputs.append(data[0].astype(np.float32)) - labels.append(data[1]) + inputs.append(data[0].asnumpy().astype(np.float32)) + labels.append(data[1].asnumpy()) test_inputs = np.concatenate(inputs) test_labels = np.concatenate(labels) ``` diff --git a/tutorials/training/source_en/advanced_use/optimize_data_processing.md b/tutorials/training/source_en/advanced_use/optimize_data_processing.md index b8a68f47c1..3fa96619a2 100644 --- a/tutorials/training/source_en/advanced_use/optimize_data_processing.md +++ b/tutorials/training/source_en/advanced_use/optimize_data_processing.md @@ -132,7 +132,8 @@ Based on the preceding suggestions of data loading performance optimization, the The output is as follows: ``` - {'image': array([[[235, 235, 235], + {'image': Tensor(shape=[32, 32, 3], dtype=UInt8, value= + [[[235, 235, 235], [230, 230, 230], [234, 234, 234], ..., @@ -142,7 +143,7 @@ Based on the preceding suggestions of data loading performance optimization, the ..., [120, 120, 119], [146, 146, 146], - [177, 174, 190]]], dtype=uint8), 'label': array(9, dtype=uint32)} + [177, 174, 190]]]), 'label': Tensor(shape=[], dtype=UInt32, value= 9)} ``` 2. Use the `Cifar10ToMR` class to convert the CIFAR-10 dataset into MindSpore data format. In this example, the CIFAR-10 dataset in Python file format is used. Then use the `MindDataset` class to load the dataset in MindSpore data format. The multi-thread optimization solution is used for data loading. Four threads are enabled to concurrently complete the task. Finally, a dictionary iterator is created for data and a data record is read through the iterator. @@ -166,7 +167,7 @@ Based on the preceding suggestions of data loading performance optimization, the The output is as follows: ``` - {'data': array([255, 216, 255, ..., 63, 255, 217], dtype=uint8), 'id': array(30474, dtype=int64), 'label': array(2, dtype=int64)} + {'data': Tensor(shape=[1431], dtype=UInt8, value= [255, 216, 255, ..., 63, 255, 217]), 'id': Tensor(shape=[], dtype=Int64, value= 30474), 'label': Tensor(shape=[], dtype=Int64, value= 2)} ``` 3. The `GeneratorDataset` class is used to load the user-defined dataset, and the multi-process optimization solution is used. Four processes are enabled to concurrently complete the task. Finally, a dictionary iterator is created for the data, and a data record is read through the iterator. @@ -185,7 +186,7 @@ Based on the preceding suggestions of data loading performance optimization, the The output is as follows: ``` - {'data': array([0], dtype=int64)} + {'data': Tensor(shape=[1], dtype=Int64, value= [0])} ``` ## Optimizing the Shuffle Performance @@ -218,7 +219,8 @@ Based on the preceding shuffle performance optimization suggestions, the `shuffl The output is as follows: ``` - {'image': array([[[254, 254, 254], + {'image': Tensor(shape=[32, 32, 3], dtype=UInt8, value= + [[[254, 254, 254], [255, 255, 254], [255, 255, 254], ..., @@ -228,7 +230,7 @@ Based on the preceding shuffle performance optimization suggestions, the `shuffl ..., [ 64, 61, 63], [ 63, 58, 60], - [ 61, 56, 58]]], dtype=uint8), 'label': array(9, dtype=uint32)} + [ 61, 56, 58]]]), 'label': Tensor(shape=[], dtype=UInt32, value= 9)} ``` 2. Use the `shuffle` function to shuffle data. Set `buffer_size` to 3 and use the `GeneratorDataset` class to generate data. @@ -312,7 +314,7 @@ Based on the preceding suggestions of data augmentation performance optimization cifar10_dataset = cifar10_dataset.map(operations=transforms, input_columns="image", num_parallel_workers=4) data = next(cifar10_dataset.create_dict_iterator()) - plt.imshow(data["image"]) + plt.imshow(data["image"].asnumpy()) plt.show() ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md index c8325271ea..465769b4b9 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md @@ -132,8 +132,8 @@ def train_model(train_net, net, dataset): accs = [] loss_sum = 0 for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].astype(np.float32)) - label = Tensor(data['label'].astype(np.int32)) + train_x = Tensor(data['image'].asnumpy().astype(np.float32)) + label = Tensor(data['label'].asnumpy().astype(np.int32)) loss = train_net(train_x, label) output = net(train_x) log_output = P.LogSoftmax(axis=1)(output) @@ -149,8 +149,8 @@ def train_model(train_net, net, dataset): def validate_model(net, dataset): accs = [] for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].astype(np.float32)) - label = Tensor(data['label'].astype(np.int32)) + train_x = Tensor(data['image'].asnumpy().astype(np.float32)) + label = Tensor(data['label'].asnumpy().astype(np.int32)) output = net(train_x) log_output = P.LogSoftmax(axis=1)(output) acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) @@ -234,7 +234,7 @@ trained_loss = vi.get_train_loss() IMAGE_SHAPE = (-1, 1, 32, 32) generated_sample = vae.generate_sample(64, IMAGE_SHAPE) for sample in ds_train.create_dict_iterator(): - sample_x = Tensor(sample['image'], dtype=mstype.float32) + sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) reconstructed_sample = vae.reconstruct_sample(sample_x) ``` @@ -427,7 +427,7 @@ evaluation = UncertaintyEvaluation(model=network, ale_uncer_model_path=None, save_model=False) for eval_data in ds_eval.create_dict_iterator(): - eval_data = Tensor(eval_data['image'], mstype.float32) + eval_data = Tensor(eval_data['image'].asnumpy(), mstype.float32) epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md index e29d21f58f..1905e0ac17 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md @@ -220,7 +220,7 @@ imagenet_policy = [ step_num += 1 for index in range(rows): fig.add_subplot(rows, columns, ep_num * rows + index + 1) - plt.imshow(data['image'][index]) + plt.imshow(data['image'].asnumpy()[index]) plt.show() ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md index bbbbe17dd9..9d101729a3 100644 --- a/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md +++ b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md @@ -198,8 +198,8 @@ def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, inputs = [] labels = [] for data in ds_test.create_tuple_iterator(): - inputs.append(data[0].astype(np.float32)) - labels.append(data[1]) + inputs.append(data[0].asnumpy().astype(np.float32)) + labels.append(data[1].asnumpy()) test_inputs = np.concatenate(inputs) test_labels = np.concatenate(labels) ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md b/tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md index 4e0567236d..6530642b81 100644 --- a/tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md +++ b/tutorials/training/source_zh_cn/advanced_use/optimize_data_processing.md @@ -134,7 +134,8 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 输出: ``` - {'image': array([[[235, 235, 235], + {'image': Tensor(shape=[32, 32, 3], dtype=UInt8, value= + [[[235, 235, 235], [230, 230, 230], [234, 234, 234], ..., @@ -144,7 +145,7 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 ..., [120, 120, 119], [146, 146, 146], - [177, 174, 190]]], dtype=uint8), 'label': array(9, dtype=uint32)} + [177, 174, 190]]]), 'label': Tensor(shape=[], dtype=UInt32, value= 9)} ``` 2. 使用`Cifar10ToMR`这个类将CIFAR-10数据集转换为MindSpore数据格式,这里使用的是CIFAR-10 python文件格式的数据集,然后使用`MindDataset`类加载MindSpore数据格式数据集,加载数据采取多线程优化方案,开启了4个线程并发完成任务,最后对数据创建了字典迭代器,并通过迭代器读取了一条数据记录。 @@ -168,7 +169,7 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 输出: ``` - {'data': array([255, 216, 255, ..., 63, 255, 217], dtype=uint8), 'id': array(30474, dtype=int64), 'label': array(2, dtype=int64)} + {'data': Tensor(shape=[1431], dtype=UInt8, value= [255, 216, 255, ..., 63, 255, 217]), 'id': Tensor(shape=[], dtype=Int64, value= 30474), 'label': Tensor(shape=[], dtype=Int64, value= 2)} ``` 3. 使用`GeneratorDataset`类加载自定义数据集,并且采取多进程优化方案,开启了4个进程并发完成任务,最后对数据创建了字典迭代器,并通过迭代器读取了一条数据记录。 @@ -187,7 +188,7 @@ MindSpore为用户提供了多种数据加载方式,其中包括常用数据 输出: ``` - {'data': array([0], dtype=int64)} + {'data': Tensor(shape=[1], dtype=Int64, value= [0])} ``` ## shuffle性能优化 @@ -220,7 +221,8 @@ shuffle性能优化建议如下: 输出: ``` - {'image': array([[[254, 254, 254], + {'image': Tensor(shape=[32, 32, 3], dtype=UInt8, value= + [[[254, 254, 254], [255, 255, 254], [255, 255, 254], ..., @@ -230,7 +232,7 @@ shuffle性能优化建议如下: ..., [ 64, 61, 63], [ 63, 58, 60], - [ 61, 56, 58]]], dtype=uint8), 'label': array(9, dtype=uint32)} + [ 61, 56, 58]]]), 'label': Tensor(shape=[], dtype=UInt32, value= 9)} ``` 2. 使用`shuffle`函数进行数据混洗,参数`buffer_size`设置为3,数据采用`GeneratorDataset`类自定义生成。 @@ -314,7 +316,7 @@ shuffle性能优化建议如下: cifar10_dataset = cifar10_dataset.map(operations=transforms, input_columns="image", num_parallel_workers=4) data = next(cifar10_dataset.create_dict_iterator()) - plt.imshow(data["image"]) + plt.imshow(data["image"].asnumpy()) plt.show() ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md b/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md index 988ce9576d..78a717a180 100644 --- a/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md +++ b/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md @@ -72,7 +72,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) ds = generate_mnist_dataset(data_list, batch_size, sparse=False) train_images = [] for data in ds.create_tuple_iterator(): - images = data[0].astype(np.float32) + images = data[0].asnumpy().astype(np.float32) train_images.append(images) train_images = np.concatenate(train_images, axis=0) @@ -83,8 +83,8 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) test_images = [] test_labels = [] for data in ds.create_tuple_iterator(): - images = data[0].astype(np.float32) - labels = data[1] + images = data[0].asnumpy().astype(np.float32) + labels = data[1].asnumpy() test_images.append(images) test_labels.append(labels) test_images = np.concatenate(test_images, axis=0) diff --git a/tutorials/training/source_zh_cn/use/load_dataset_image.md b/tutorials/training/source_zh_cn/use/load_dataset_image.md index d0a7995e23..e77f68363f 100644 --- a/tutorials/training/source_zh_cn/use/load_dataset_image.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_image.md @@ -63,8 +63,8 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 # 创建迭代器并展示样本及标签 mnist_it = mnist_dataset.create_dict_iterator() data = mnist_it.get_next() - plt.imshow(data['image'].squeeze(), cmap=plt.cm.gray) - plt.title(data['label'], fontsize=20) + plt.imshow(data['image'].asnumpy().squeeze(), cmap=plt.cm.gray) + plt.title(data['label'].asnumpy(), fontsize=20) plt.show() ``` @@ -175,8 +175,8 @@ for data in mnist_dataset.create_dict_iterator(): ```python mnist_it = ds4.create_dict_iterator() data = mnist_it.get_next() - plt.imshow(data['image'].squeeze(), cmap=plt.cm.gray) - plt.title(data['label'], fontsize=20) + plt.imshow(data['image'].asnumpy().squeeze(), cmap=plt.cm.gray) + plt.title(data['label'].asnumpy(), fontsize=20) plt.show() ``` diff --git a/tutorials/training/source_zh_cn/use/load_dataset_text.md b/tutorials/training/source_zh_cn/use/load_dataset_text.md index 0c7317b0d1..55372ccdfb 100644 --- a/tutorials/training/source_zh_cn/use/load_dataset_text.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_text.md @@ -64,7 +64,7 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 2. 创建迭代器,通过迭代器获取数据。 ```python - for data in dataset.create_dict_iterator(): + for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) ``` @@ -94,7 +94,7 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 2. 原始数据输出效果。 ```python - for data in dataset.create_dict_iterator(): + for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text']).tolist()) ``` @@ -111,7 +111,7 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 4. 执行之后输出效果。 ```python - for data in dataset.create_dict_iterator(): + for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text']).tolist()) ``` @@ -136,7 +136,7 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 2. 数据输出效果。 ```python - for data in dataset.create_dict_iterator(): + for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text']).tolist()) ``` @@ -177,7 +177,7 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 3. 创建迭代器,通过迭代器获取数据。 ```python - for i in dataset.create_dict_iterator(num_epochs=1): + for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` diff --git a/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py b/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py index 9561b5cebd..743b083ace 100644 --- a/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py +++ b/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py @@ -72,8 +72,8 @@ def test_fast_gradient_sign_method(): i = 0 for data in ds.create_tuple_iterator(): i += 1 - images = data[0].astype(np.float32) - labels = data[1] + images = data[0].asnumpy().astype(np.float32) + labels = data[1].asnumpy() test_images.append(images) test_labels.append(labels) pred_labels = np.argmax(model.predict(Tensor(images)).asnumpy(), diff --git a/tutorials/tutorial_code/model_safety/mnist_defense_nad.py b/tutorials/tutorial_code/model_safety/mnist_defense_nad.py index d587f960ac..3c19eeed38 100644 --- a/tutorials/tutorial_code/model_safety/mnist_defense_nad.py +++ b/tutorials/tutorial_code/model_safety/mnist_defense_nad.py @@ -71,8 +71,8 @@ def test_nad_method(): inputs = [] labels = [] for data in ds_test.create_tuple_iterator(): - inputs.append(data[0].astype(np.float32)) - labels.append(data[1]) + inputs.append(data[0].asnumpy().astype(np.float32)) + labels.append(data[1].asnumpy()) inputs = np.concatenate(inputs) labels = np.concatenate(labels) -- Gitee From 5ea1ec2836ebb01fcbe0bc4e8320afe330631c31 Mon Sep 17 00:00:00 2001 From: liuchongming Date: Thu, 17 Sep 2020 10:00:52 +0800 Subject: [PATCH 048/100] Add example. --- .../migrate_3rd_scripts_mindconverter.md | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md index a7e42cb7c1..7b86cbbdde 100644 --- a/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md +++ b/tutorials/training/source_zh_cn/advanced_use/migrate_3rd_scripts_mindconverter.md @@ -1,6 +1,6 @@ -# 使用工具迁移第三方框架脚本 +# 迁移第三方框架脚本 -`Linux` `Ascend` `模型开发` `初级` `Linux` +`Linux` `Ascend` `模型开发` `初级` @@ -8,6 +8,7 @@ - [概述](#概述) - [安装](#安装) - [用法](#用法) + - [使用场景](#使用场景) - [使用示例](#使用示例) - [基于AST的脚本转换示例](#基于AST的脚本转换示例) - [基于图结构的脚本生成示例](#基于图结构的脚本生成示例) @@ -78,6 +79,7 @@ optional arguments: 另外,当使用基于图结构的脚本生成方案时,请确保原PyTorch项目已在Python包搜索路径中,可通过CLI进入Python交互式命令行,通过import的方式判断是否已满足;若未加入,可通过`--project_path`命令手动将项目路径传入,以确保MindConverter可引用到原PyTorch脚本。 + > 假设用户项目目录为`/home/user/project/model_training`,用户可通过如下命令手动项目添加至包搜索路径中:`export PYTHONPATH=/home/user/project/model_training:$PYTHONPATH` > 此处MindConverter需要引用原PyTorch脚本,是因为PyTorch模型反向序列化过程中会引用原脚本。 @@ -99,6 +101,7 @@ MindConverter提供两种技术方案,以应对不同脚本迁移场景: > 2. 基于图结构的脚本生成方案,由于要基于推理模式加载PyTorch模型,会导致转换后网络中Dropout算子丢失,需要用户手动补齐; > 3. 基于图结构的脚本生成方案持续优化中。 + ## 使用示例 ### 基于AST的脚本转换示例 @@ -148,7 +151,48 @@ mindconverter --model_file /home/user/model.pth --shape 3,224,224 \ 基于图结构的脚本生成方案产生的转换报告格式与AST方案相同。然而,由于基于图结构方案属于生成式方法,转换过程中未参考原PyTorch脚本,因此生成的转换报告中涉及的代码行、列号均指生成后脚本。 -另外对于未成功转换的算子,在代码中会相应的标识该节点输入、输出Tensor的shape(以input_shape, output_shape标识),便于用户手动修改。 +另外对于未成功转换的算子,在代码中会相应的标识该节点输入、输出Tensor的shape(以`input_shape`, `output_shape`标识),便于用户手动修改。以Reshape算子为例(暂不支持Reshape),将生成如下代码: + +```python +class Classifier(nn.Cell): + + def __init__(self): + super(Classifier, self).__init__() + ... + self.reshape = onnx.Reshape(input_shape=(1, 1280, 1, 1), + output_shape=(1, 1280)) + ... + + def construct(self, x): + ... + # Suppose input of `reshape` is x. + reshape_output = self.reshape(x) + ... + +``` + +通过`input_shape`、`output_shape`参数,用户可以十分便捷地完成算子替换,替换结果如下: + +```python +from mindspore.ops import operations as P +... + +class Classifier(nn.Cell): + + def __init__(self): + super(Classifier, self).__init__() + ... + self.reshape = P.Reshape(input_shape=(1, 1280, 1, 1), + output_shape=(1, 1280)) + ... + + def construct(self, x): + ... + # Suppose input of `reshape` is x. + reshape_output = self.reshape(x, (1, 1280)) + ... + +``` > 注意:其中`--output`与`--report`参数可省略,若省略,该命令将在当前工作目录(Working directory)下自动创建`output`目录,将生成的脚本、转换报告输出至该目录。 -- Gitee From d737b2c546e810c3ee6424df2b58b8cfe4e2978c Mon Sep 17 00:00:00 2001 From: lvmingfu <630944715@qq.com> Date: Wed, 16 Sep 2020 19:39:53 +0800 Subject: [PATCH 049/100] modify linear_regression files in tutorials --- tutorials/notebook/linear_regression.ipynb | 712 ++++++++---------- tutorials/training/source_zh_cn/index.rst | 2 +- .../quick_start/images/linear_regression.gif | Bin 73509 -> 163898 bytes .../linear_regression_eval_datasets.png | Bin 6278 -> 10314 bytes .../images/model_net_and_eval_datasets.png | Bin 6903 -> 10854 bytes .../quick_start/linear_regression.md | 411 +++++----- tutorials/tutorial_code/linear_regression.py | 115 ++- 7 files changed, 530 insertions(+), 710 deletions(-) diff --git a/tutorials/notebook/linear_regression.ipynb b/tutorials/notebook/linear_regression.ipynb index 4e3665dcf1..25008ff1e3 100644 --- a/tutorials/notebook/linear_regression.ipynb +++ b/tutorials/notebook/linear_regression.ipynb @@ -4,33 +4,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "##
    使用MindSpore实现简单线性函数拟合" + "# 使用MindSpore实现简单线性函数拟合" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## 概述" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "回归问题算法通常是利用一系列属性来预测一个值,预测的值是连续的。例如给出一套房子的一些特征数据,如面积、卧室数等等来预测房价,利用最近一周的气温变化和卫星云图来预测未来的气温情况等。如果一套房子实际价格为500万元,通过回归分析的预测值为499万元,则认为这是一个比较好的回归分析。在机器学习问题中,常见的回归分析有线性回归、多项式回归、逻辑回归等。本例子介绍线性回归算法,并通过MindSpore进行线性回归AI训练体验。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "主要流程如下:\n", + "## 概述\n", + "\n", + "回归问题算法通常是利用一系列属性来预测一个值,预测的值是连续的。例如给出一套房子的一些特征数据,如面积、卧室数等等来预测房价,利用最近一周的气温变化和卫星云图来预测未来的气温情况等。如果一套房子实际价格为500万元,通过回归分析的预测值为499万元,则认为这是一个比较好的回归分析。在机器学习问题中,常见的回归分析有线性回归、多项式回归、逻辑回归等。本例子介绍线性回归算法,并通过MindSpore进行线性回归AI训练体验。\n", + "\n", + "整体流程如下:\n", "\n", "1. 生成数据集\n", - "2. 定义前向传播网络\n", - "3. 定义反向传播网络\n", - "4. 定义线性拟合过程的可视化函数\n", + "2. 定义训练网络\n", + "3. 定义前向传播网络与反向传播网络并关联\n", + "4. 拟合过程可视化准备\n", "5. 执行训练" ] }, @@ -38,114 +28,90 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 环境准备" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "系统:Ubuntu18.04\n", - "\n", - "MindSpore版本:GPU\n", + "## 环境准备\n", "\n", - "设置MindSpore运行配置\n", - "\n", - "第三方支持包:`matplotlib`,未安装此包的,可使用命令`pip install matplotlib`预先安装。" + "设置MindSpore运行配置" ] }, { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.002170Z", + "start_time": "2020-09-14T10:38:39.441746Z" + } + }, "outputs": [], "source": [ "from mindspore import context\n", "\n", - "context.set_context(mode=context.PYNATIVE_MODE, device_target=\"GPU\")" + "context.set_context(mode=context.GRAPH_MODE, device_target=\"CPU\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "`PYNATIVE_MODE`:自定义调试模式。\n", + "`GRAPH_MODE`:自定义调试模式。\n", "\n", - "`device_target`:设置MindSpore的训练硬件为GPU。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 生成数据集" + "`device_target`:设置MindSpore的训练硬件为CPU。\n", + "\n", + "> 本教程代码依赖`matplotlib`第三方支持包,可使用命令`pip install matplotlib`安装。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "## 生成数据集\n", + "\n", "### 定义数据集生成函数\n", "\n", - "`get_data`用于生成训练数据集和测试数据集。由于拟合的是线性数据,假定要拟合的目标函数为:$y=2x+3$,那么我们需要的训练数据集应随机分布于函数周边,这里采用了$y=2x+3+noise$的方式生成,其中`noise`为遵循标准正态分布规律的随机数值。" + "`get_data`用于生成训练数据集和测试数据集。由于拟合的是线性数据,假定要拟合的目标函数为:$f(x)=2x+3$,那么我们需要的训练数据集应随机分布于函数周边,这里采用了$f(x)=2x+3+noise$的方式生成,其中`noise`为遵循标准正态分布规律的随机数值。" ] }, { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.007850Z", + "start_time": "2020-09-14T10:38:40.003169Z" + } + }, "outputs": [], "source": [ "import numpy as np\n", - "import mindspore as ms\n", - "from mindspore import Tensor\n", - " \n", - "def get_data(num,w=2.0, b=3.0):\n", - " np_x = np.ones([num, 1])\n", - " np_y = np.ones([num, 1])\n", + "\n", + "def get_data(num, w=2.0, b=3.0):\n", " for i in range(num):\n", " x = np.random.uniform(-10.0, 10.0)\n", - " np_x[i] = x\n", " noise = np.random.normal(0, 1)\n", " y = x * w + b + noise\n", - " np_y[i] = y\n", - " return Tensor(np_x,ms.float32), Tensor(np_y,ms.float32)" + " yield np.array([x]).astype(np.float32), np.array([y]).astype(np.float32)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "对于数据生成函数我们将有以下两个作用。\n", - "\n", - "1. 生成训练数据,对模型函数进行训练。\n", - "2. 生成验证数据,在训练结束后,对模型函数进行精度验证。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 生成测试数据" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "使用数据生成函数`get_data`随机生成50组验证数据,并可视化展示。" + "使用`get_data`生成50组测试数据,并可视化。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { - "scrolled": true + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.355635Z", + "start_time": "2020-09-14T10:38:40.009930Z" + } }, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
    " ] @@ -159,10 +125,14 @@ "source": [ "import matplotlib.pyplot as plt\n", "\n", - "eval_x, eval_label = get_data(50)\n", - "x1, y1 = eval_x.asnumpy(), eval_label.asnumpy()\n", - "plt.scatter(x1, y1, color=\"red\", s=5)\n", - "plt.title(\"Eval_data\")\n", + "eval_data = list(get_data(50))\n", + "x_target_label = np.array([-10, 10, 0.1])\n", + "y_target_label = x_target_label * 2 + 3\n", + "x_eval_label,y_eval_label = zip(*eval_data)\n", + "\n", + "plt.scatter(x_eval_label, y_eval_label, color=\"red\", s=5)\n", + "plt.plot(x_target_label, y_target_label, color=\"green\")\n", + "plt.title(\"Eval data\")\n", "plt.show()" ] }, @@ -170,500 +140,426 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 定义前向传播网络" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 初始化网络模型" + "上图中绿色线条部分为目标函数,红点部分为验证数据`eval_data`。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "使用`nn.Dense`定义了网络模型,即为线性模型,\n", + "### 定义数据增强函数\n", "\n", - "$$y=wx+b\\tag{1}$$\n", + "使用MindSpore的数据增强函数,将数据进行增强操作,操作解释如下:\n", "\n", - "其中,权重值$w$对应`weight`,$b$对应`bias`,并将其打印出来。" + "- `ds.GeneratorDataset`:将生成的数据转换为MindSpore的数据集,并且将生成的数据的x,y值存入到`data`和`label`的数组中。\n", + "- `batch`:将`batch_size`个数据组合成一个batch。\n", + "- `repeat`:将数据集数量倍增。" ] }, { "cell_type": "code", "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "weight: -0.00034249047 bias: -0.019308656\n" - ] + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.390782Z", + "start_time": "2020-09-14T10:38:40.356644Z" } - ], + }, + "outputs": [], "source": [ - "from mindspore.common.initializer import TruncatedNormal\n", - "from mindspore import nn\n", + "from mindspore import dataset as ds\n", "\n", - "net = nn.Dense(1,1,TruncatedNormal(0.02),TruncatedNormal(0.02))\n", - "print(\"weight:\", net.weight.set_data([0][0]), \"bias:\", net.bias.set_data([0]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 查看初始化的网络模型" + "def create_dataset(num_data, batch_size=16, repeat_size=1):\n", + " input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data','label'])\n", + " input_data = input_data.batch(batch_size)\n", + " input_data = input_data.repeat(repeat_size)\n", + " return input_data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "我们将验证数据集和初始化的模型函数可视化。" + "使用数据集增强函数生成训练数据,并查看训练数据的格式。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { - "scrolled": true + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.435708Z", + "start_time": "2020-09-14T10:38:40.391790Z" + } }, "outputs": [ { - "data": { - "image/png": "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\n", - "text/plain": [ - "
    " - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" + "name": "stdout", + "output_type": "stream", + "text": [ + "The dataset size of ds_train: 100\n", + "dict_keys(['data', 'label'])\n", + "The x label value shape: (16, 1)\n", + "The y label value shape: (16, 1)\n" + ] } ], "source": [ - "x = np.arange(-10, 10, 0.1)\n", - "y = x * (net.weight.set_data([0][0]).asnumpy()) + (net.bias.set_data([0]).asnumpy())\n", - "plt.scatter(x1, y1, color=\"red\", s=5)\n", - "plt.plot(x, y, \"blue\")\n", - "plt.title(\"Eval data and net\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "红色的点:为之前生成的50组验证数据集。\n", + "num_data = 1600\n", + "batch_size = 16\n", + "repeat_size = 1\n", "\n", - "蓝色的线:初始化的模型网络。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 定义损失函数" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "我们的网络模型表达式为:\n", + "ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size) \n", + "print(\"The dataset size of ds_train:\", ds_train.get_dataset_size())\n", + "dict_datasets = ds_train.create_dict_iterator().get_next()\n", "\n", - "$$h(x)=wx+b\\tag{2}$$" + "print(dict_datasets.keys())\n", + "print(\"The x label value shape:\", dict_datasets[\"data\"].shape)\n", + "print(\"The y label value shape:\", dict_datasets[\"label\"].shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "一般地,数学上对线性回归模型采用均方差的方式来判断模型是否拟合得很好,即均方差的值$J(w)$值越小,函数模型便拟合得越好,验证数据代入后,预测得到的y值就越准确。公式2对应m个数据的均方差公式为:" + "通过定义的`create_dataset`将生成的1600个数据增强为了100组shape为16x1的数据集。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "$$J(w)=\\frac{1}{m}\\sum_{i=1}^m(h(x_i)-y^{(i)})^2\\tag{3}$$" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "为了方便后续的计算,我们采用0.5倍的均方差的表达式来进行计算,均方差值整体缩小至0.5倍的计算方式对判断模型拟合的好坏没有影响。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "$$J(w)=\\frac{1}{2m}\\sum_{i=1}^m(h(x_i)-y^{(i)})^2\\tag{4}$$" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "公式4即为网络训练中的损失函数,其中参数:\n", - "\n", - "- $J(w)$为均方差。\n", + "## 定义训练网络\n", "\n", - "- $m$为样本数据的数量。\n", + "在MindSpore中使用`nn.Dense`生成单个数据输入,单个数据输出的线性函数模型:\n", "\n", - "- $h(x_i)$为第$i$个数据的$x_i$值代入模型网络(公式2)后的预测值。\n", + "$$f(x)=wx+b\\tag{1}$$\n", "\n", - "- $y^{(i)}$为第$i$个数据中的$y$值(label值)。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "在MindSpore中定义损失函数的方法如下。" + "并使用Normal算子随机初始化权重$w$和$b$。" ] }, { "cell_type": "code", "execution_count": 6, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.441532Z", + "start_time": "2020-09-14T10:38:40.436780Z" + } + }, "outputs": [], "source": [ - "from mindspore.ops import operations as P\n", - "\n", - "class MyLoss(nn.loss.loss._Loss):\n", - " def __init__(self,reduction='mean'):\n", - " super().__init__(reduction)\n", - " self.square = P.Square()\n", - " def construct(self, data, label):\n", - " x = self.square(data-label) * 0.5\n", - " return self.get_loss(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "其中:\n", - "\n", - "- `nn.loss.loss._Loss`:是MindSpore自定义loss算子的一个基类。\n", + "from mindspore.common.initializer import Normal\n", + "from mindspore import nn\n", "\n", - "- `P.Square`:MindSpore训练的框架中的平方算子,算子需要注册过才能在框架的计算图中使用。" + "class LinearNet(nn.Cell):\n", + " def __init__(self):\n", + " super(LinearNet, self).__init__()\n", + " self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02))\n", + " \n", + " def construct(self, x):\n", + " x = self.fc(x)\n", + " return x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### 损失函数与网络结合\n", - "\n", - "接下来我们需要将loss函数的表达式和网络net关联在一起,在MindSpore中需要`nn.WithLossCell`,实现方法如下:" + "调用网络查看初始化的模型参数。" ] }, { "cell_type": "code", "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "criterion = MyLoss()\n", - "loss_opeartion = nn.WithLossCell(net, criterion) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.456400Z", + "start_time": "2020-09-14T10:38:40.442544Z" + }, + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[Parameter (name=fc.weight, value=Tensor(shape=[1, 1], dtype=Float32,\n", + "[[3.68014202e-002]])), Parameter (name=fc.bias, value=Tensor(shape=[1], dtype=Float32, [3.68014202e-002]))]\n" + ] + } + ], "source": [ - "其中:\n", - "\n", - "- `net`:网络模型。\n", - "\n", - "- `criterion`:即为实例化的loss函数。" + "net = LinearNet()\n", + "model_params = net.trainable_params()\n", + "print(model_params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "上述从数据代入到计算出loss值的过程为AI训练中的前向传播过程。" + "初始化网络模型后,接下来将初始化的网络函数和训练数据集进行可视化,了解拟合前的模型函数情况。" ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": 8, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.607733Z", + "start_time": "2020-09-14T10:38:40.457985Z" + }, + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
    " + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ - "## 定义反向传播网络" + "from mindspore import Tensor\n", + "\n", + "x_model_label = np.array([-10, 10, 0.1])\n", + "y_model_label = (x_model_label * Tensor(model_params[0]).asnumpy()[0][0] + \n", + " Tensor(model_params[1]).asnumpy()[0])\n", + "\n", + "plt.axis([-10, 10, -20, 25])\n", + "plt.scatter(x_eval_label, y_eval_label, color=\"red\", s=5)\n", + "plt.plot(x_model_label, y_model_label, color=\"blue\")\n", + "plt.plot(x_target_label, y_target_label, color=\"green\")\n", + "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "有了损失函数后,我们如何使得损失函数最小呢?我们可以将公式1代入到损失函数公式4中展开:\n", - "\n", - "$$J(w,b)=\\frac{1}{2m}\\sum_{i=1}^m(wx_i+b-y^{(i)})^2\\tag{5}$$" + "从上图中可以看出,蓝色线条的初始化模型函数与绿色线条的目标函数还是有较大的差别的。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "公式5可以将$J(w)$看作为凹函数,对权重值$w$微分可求得:\n", - "\n", - "$$\\frac{\\partial{J(w)}}{\\partial{w}}=\\frac{1}{m}\\sum_{i=1}^mx_i(wx_i+b-y^{(i)})\\tag{6}$$\n" + "## 定义前向传播网络与反向传播网络并关联" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "由凹函数的特性可以知道,当公式6等于0时,损失函数有最小值:\n", + "接下来需要定义模型的损失函数,这里采用均方差的方法用于判断拟合的效果如何,即均方差值越小,拟合的效果越好,其损失损失函数公式为:\n", "\n", - "$$\\sum_{i=1}^mx_i(wx_i+b-y^{(i)})=0\\tag{7}$$ \n", + "$$J(w)=\\frac{1}{2m}\\sum_{i=1}^m(h(x_i)-y^{(i)})^2\\tag{2}$$\n", "\n", - "假设有一个$w_{min}$使得公式7成立。我们如何将初始的权重$w_{s}$逐步的变成$w_{min}$,在这里采取迭代法,也就是梯度下降方法\n", + "假设训练数据第$i$个数据为$(x_i,y^{(i)})$,公式2中的参数解释如下:\n", "\n", - "当权重$w_{s}w_{min}$,权重值需要左移即权重值变小接近$w_{min}$,才能使得损失函数逐步的变小,由凹函数的性质可知,在$w_{s}$处的导数为正(损失函数在$w_{min}$右边单调上升),公式8的值为正。其权重的更新公式为:\n", - "\n", - "$$w_{ud}=w_{s}-\\alpha\\frac{\\partial{J(w_{s})}}{\\partial{w}}\\tag{10}$$\n" + "net = LinearNet()\n", + "net_loss = nn.loss.MSELoss()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "当$w_{s}=w_{min}$时,到$\\frac{\\partial{J(w_{s})}}{\\partial{w}}$=0,即梯度消失,其表达式也可写为公式9的样式。\n", + "### 定义反向传播网络\n", "\n", - "在考虑了全区间的情况后,可以得出权重$w$的更新公式即为:\n", + "反向传播网络的目标是不断变换权重值,使得loss值取得最小值,一般的在线性网络中采用权重更新公式:\n", "\n", - "$$w_{ud}=w_{s}-\\alpha\\frac{\\partial{J(w_{s})}}{\\partial{w}}\\tag{11}$$\n", + "$$w_{t}=w_{t-1}-\\alpha\\frac{\\partial{J(w_{t-1})}}{\\partial{w}}\\tag{3}$$\n", "\n", - "当权重$w$在更新的过程中假如临近$w_{min}$在增加或者减少一个$\\Delta{w}$,从左边或者右边越过了$w_{min}$,公式11都会使权重往反的方向移动,那么最终$w_{s}$的值会在$w_{min}$附近来回迭代,在实际训练中我们也是这样采用迭代的方式取得最优权重$w$,使得损失函数无限逼近局部最小值。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "同理:对于公式5中的另一个权重$b$容易得出其更新公式为:\n", + "公式3参数解释:\n", "\n", - "$$b_{ud}=b_{s}-\\alpha\\frac{\\partial{J(b_{s})}}{\\partial{b}}\\tag{12}$$\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "当所有的权重更新完成后,将新的权重赋值给初始权重:即$w_{s}$=$w_{ud}$,$b_{s}$=$b_{ud}$。将新的初始权重传递回到模型函数中,这样就完成了反向传播的过程。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> 当遇到多项式的回归模型时,上述梯度方法也适用,由于权重数量的增加,需要将权重的名称更新为$w_0,w_1,w_2,...,w_n$,引入矩阵的表达方式,公式将会更加简洁,这里就不多介绍了。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 实现梯度函数" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "在MindSpore中的所有要编入计算图的类都需要继承`nn.Cell`算子,MindSpore的梯度计算函数采用如下方式。" + "- $w_{t}$为迭代后的权重值。\n", + "- $w_{t-1}$为迭代前的权重值。\n", + "- $\\alpha$为学习率。\n", + "- $\\frac{\\partial{J(w_{t-1}\\ )}}{\\partial{w}}$为损失函数对权重$w_{t-1}$的微分。\n", + "\n", + "函数中所有的权重值更新完成后,将值传入到模型函数中,这个过程就是反向传播过程,实现此过程需要使用MindSpore中的优化器函数,如下:" ] }, { "cell_type": "code", - "execution_count": 8, - "metadata": {}, + "execution_count": 10, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.629217Z", + "start_time": "2020-09-14T10:38:40.616392Z" + } + }, "outputs": [], "source": [ - "from mindspore.ops import composite as C\n", - "\n", - "class GradWrap(nn.Cell):\n", - " \"\"\" GradWrap definition \"\"\"\n", - " def __init__(self, network):\n", - " super().__init__(auto_prefix=False)\n", - " self.network = network\n", - " self.weights = ms.ParameterTuple(filter(lambda x: x.requires_grad,\n", - " network.get_parameters()))\n", - "\n", - " def construct(self, data, label):\n", - " weights = self.weights\n", - " return C.GradOperation(get_by_list=True) \\\n", - " (self.network, weights)(data, label)\n" + "opt = nn.Momentum(net.trainable_params(), learning_rate=0.005, momentum=0.9)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "上述代码中`GradWrap`实现的是对各个权重的微分$\\frac{\\partial{J(w)}}{\\partial{w}}$,其展开式子参考公式6。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 反向传播更新权重" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`nn.RMSProp`为完成权重更新的函数,更新方式大致为公式11,但是考虑的因素更多,具体信息请参考[官网说明](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html?highlight=rmsprop#mindspore.nn.RMSProp)。" + "### 关联前向和反向传播网络\n", + "\n", + "定义完成前向传播和反向传播后,在MindSpore中需要调用`Model`函数,将前面定义的网络,损失函数,优化器函数关联起来,使之变成完整的计算网络。" ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": {}, + "execution_count": 11, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.645718Z", + "start_time": "2020-09-14T10:38:40.630789Z" + } + }, "outputs": [], "source": [ - "train_network = GradWrap(loss_opeartion) \n", - "train_network.set_train()\n", - "optim = nn.RMSProp(params=net.trainable_params(),learning_rate=0.02)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "通过以上操作,我们就完成了前向传播网络和反向传播网络的定义,接下来可以加载训练数据进行线性拟合了。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## 定义模型拟合过程可视化函数" + "from mindspore.train import Model\n", + "\n", + "model = Model(net, net_loss, opt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "定义一个可视化函数`plot_model_and_datasets`,将模型函数和验证数据集打印出来,观察其变化。" + "## 拟合过程可视化准备\n", + "\n", + "### 定义绘图函数\n", + "\n", + "为了使得整个训练过程更容易理解,需要将训练过程的测试数据、目标函数和模型网络进行可视化,这里定义了可视化函数,将在每个step训练结束后调用,展示模型网络的拟合过程。" ] }, { "cell_type": "code", - "execution_count": 10, - "metadata": {}, + "execution_count": 12, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.680586Z", + "start_time": "2020-09-14T10:38:40.646738Z" + } + }, "outputs": [], "source": [ - "import time \n", + "import matplotlib.pyplot as plt\n", + "import time\n", "\n", - "def plot_model_and_datasets(weight, bias, data_x, data_y):\n", + "def plot_model_and_datasets(net, eval_data):\n", + " weight = net.trainable_params()[0]\n", + " bias = net.trainable_params()[1]\n", " x = np.arange(-10, 10, 0.1)\n", - " y = x * ((weight[0][0]).asnumpy()) + ((bias[0]).asnumpy())\n", - " plt.scatter(x1,y1,color=\"red\",s=5)\n", - " plt.scatter(data_x.asnumpy(), data_y.asnumpy(), color=\"black\", s=5)\n", - " plt.plot(x, y, \"blue\")\n", + " y = x * Tensor(weight).asnumpy()[0][0] + Tensor(bias).asnumpy()[0]\n", + " x1, y1 = zip(*eval_data)\n", + " x_target = x\n", + " y_target = x_target * 2 + 3\n", + " \n", " plt.axis([-11, 11, -20, 25])\n", + " plt.scatter(x1, y1, color=\"red\", s=5)\n", + " plt.plot(x, y, color=\"blue\")\n", + " plt.plot(x_target, y_target, color=\"green\")\n", " plt.show()\n", - " time.sleep(0.02)" + " time.sleep(0.2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "上述函数的参数:\n", - "\n", - "- `weight`:模型函数的权重,即$w$。\n", + "### 定义回调函数\n", "\n", - "- `bias`:模型函数的权重,即$b$。\n", + "MindSpore提供的工具,可对模型训练过程进行自定义控制,这里在`step_end`中调用可视化函数,展示拟合过程。更多的使用可参考[官网说明](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/customized_debugging_information.html#callback)\n", "\n", - "- `data_x`:训练数据的x值。\n", - "\n", - "- `data_y`:训练数据的y值。" + "- `display.clear_output`:清除打印内容,实现动态拟合效果。" ] }, { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "> 可视化过程中,红色的点是验证数据集,黑色的点是单个batch的训练数据,蓝色的线条是正在训练的回归模型。" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": 13, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T10:38:40.706063Z", + "start_time": "2020-09-14T10:38:40.681635Z" + } + }, + "outputs": [], "source": [ - "## 执行训练" + "from IPython import display\n", + "from mindspore.train.callback import Callback\n", + "\n", + "class ImageShowCallback(Callback):\n", + " def __init__(self, net, eval_data):\n", + " self.net = net\n", + " self.eval_data = eval_data\n", + " \n", + " def step_end(self, run_context):\n", + " plot_model_and_datasets(self.net, self.eval_data)\n", + " display.clear_output(wait=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "其训练过程如下:\n", + "## 执行训练\n", "\n", - "1. 设置训练的迭代次数`step_size`。\n", - "2. 设置单次迭代的训练数据量`batch_size`。\n", - "3. 正向传播训练`grads`。\n", - "4. 反向传播训练`optim`。\n", - "5. 图形展示模型函数和数据集。\n", - "6. 清除本轮迭代的输出`display.clear_output`,起到动态可视化效果。\n", + "完成以上过程后,可以使用训练数`ds_train`对模型训练,这里调用`model.train`进行,其中参数解释:\n", "\n", - "迭代完成后,输出网络模型的权重值$w和b$。" + "- `epoch`:训练迭代的整个数据集的次数。\n", + "- `ds_train`:训练数据集。\n", + "- `callbacks`:训练过程中需要调用的回调函数。\n", + "- `dataset_sink_model`:数据集下沉模式,支持Ascend、GPU计算平台,本例为CPU计算平台设置为False。" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "metadata": { - "scrolled": true + "ExecuteTime": { + "end_time": "2020-09-14T10:47:22.917679Z", + "start_time": "2020-09-14T10:38:40.707096Z" + } }, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "loss_value: 0.42879593\n" - ] - }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
    " ] @@ -677,49 +573,41 @@ "name": "stdout", "output_type": "stream", "text": [ - "weight: 1.9990227 bias: 2.9115517\n" + "Parameter (name=fc.weight, value=[[2.0405223]]) \n", + "Parameter (name=fc.bias, value=[2.9574146])\n" ] } ], "source": [ - "from IPython import display\n", "\n", - "step_size = 200\n", - "batch_size = 16\n", + "from mindspore.train.callback import LossMonitor\n", "\n", - "for i in range(step_size):\n", - " data_x,data_y = get_data(batch_size)\n", - " grads = train_network(data_x,data_y) \n", - " optim(grads)\n", - " plot_model_and_datasets(net.weight.data, \n", - " net.bias.data, data_x, data_y)\n", - " display.clear_output(wait=True)\n", + "epoch = 1\n", + "imageshow_cb = ImageShowCallback(net, eval_data)\n", + "model.train(epoch, ds_train, callbacks=[imageshow_cb], dataset_sink_mode=False)\n", "\n", - "output = net(eval_x)\n", - "loss_output = criterion(output, eval_label)\n", - "print(\"loss_value:\", loss_output.asnumpy())\n", - "plot_model_and_datasets(net.weight.data, net.bias.data, data_x,data_y)\n", - "print(\"weight:\", net.weight.set_data([0][0]), \"bias:\", net.bias.set_data([0]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "可以看到最终得到的线性拟合的权重值非常接近目标函数权重weight=2、bias=3。" + "plot_model_and_datasets(net,eval_data)\n", + "print(net.trainable_params()[0], \"\\n%s\" % net.trainable_params()[1])" ] }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2020-09-14T04:00:18.787349Z", + "start_time": "2020-09-14T04:00:18.784236Z" + } + }, "source": [ - "## 总结" + "训练完成后打印出最终模型的权重参数,其中weight接近于2.0,bias接近于3.0,模型训练完成,符合预期。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "## 总结\n", + "\n", "本次体验我们了解了线性拟合的算法原理,并在MindSpore框架下实现了相应的算法定义,了解了线性拟合这类的线性回归模型在MindSpore中的训练过程,并最终拟合出了一条接近目标函数的模型函数。另外有兴趣的可以调整数据集的生成区间从(-10,10)扩展到(-100,100),看看权重值是否更接近目标函数;调整学习率大小,看看拟合的效率是否有变化;当然也可以探索如何使用MindSpore拟合$f(x)=ax^2+bx+c$这类的二次函数或者更高次的函数。" ] } @@ -745,4 +633,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/tutorials/training/source_zh_cn/index.rst b/tutorials/training/source_zh_cn/index.rst index 5878b4a0f9..fea9456540 100644 --- a/tutorials/training/source_zh_cn/index.rst +++ b/tutorials/training/source_zh_cn/index.rst @@ -11,8 +11,8 @@ :maxdepth: 1 :caption: 快速入门 - quick_start/linear_regression quick_start/quick_start + quick_start/linear_regression quick_start/quick_video .. toctree:: diff --git a/tutorials/training/source_zh_cn/quick_start/images/linear_regression.gif b/tutorials/training/source_zh_cn/quick_start/images/linear_regression.gif index 41cc751e9d5d0d1205de31187bfa4e6103958795..ff616e2782ba2fecb54064ffb867d944d5b29f10 100644 GIT binary patch literal 163898 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%0D`^0pCqiQM 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 diff --git a/docs/programming_guide/source_zh_cn/images/ctrans_resize.png b/docs/programming_guide/source_zh_cn/images/ctrans_resize.png index f4f2b23642cc8d87f3ad5684205c968c79bd794d..e5275e371cbe0b668a0f6f1d699ea67efa09956f 100644 GIT binary patch literal 19400 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 UaIWU&yL|xQ;)p^v*$1Tl8#_^9)c^nh literal 43654 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 VkNUheB%Plf>e_$ZRy*kb{{SNY@=gE% diff --git a/docs/programming_guide/source_zh_cn/images/map.png b/docs/programming_guide/source_zh_cn/images/map.png index abe704717045e3816f3ffe4d10a8b023ec983b3d..275631c1c5f0ea256be00004251e61c382748487 100644 GIT binary patch literal 14962 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 diff --git a/docs/programming_guide/source_zh_cn/images/pytrans_compose.png b/docs/programming_guide/source_zh_cn/images/pytrans_compose.png index 66221a4f5e7a9f985475fa2dd68f1994903636c3..6d74fc231a7253393f98a645c0c68c7b2c517fb2 100644 GIT binary patch literal 42922 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 Gh5rX&v1E<_ literal 64995 zcmeFYWmsHY(l*+-yIar@2tk505C~3y0KpxCyE_Dz#w`$nyK90p)<{AG2~OiQgb*OO zyM4Q#nR%aiznSyv{5sclen9VD?7i1oRd-e0Rkes!f2BZxON$Evfe4foTU4ifJo`mPf z5MMuj0<{%?C~hongrD@oIQHVpl&3frO3kFCTAXB-L-KWl1&b{9fcsDf9*@p$aOIVIr4ltk=4 zRhcb(EZ`SrpDMpNfDiU8Hl^T`5=MmIYU1+s(s}SvTEU|4a?ter>sa5NS@+GdjMwhp zD0lePF3N;SF3du+8(n+N^LzbU>#ZhDSyuj`~@z&vs#Z9osgxwn4wXL=*Mg zoqo9gOcZ<&PSt4^2`1y86F-G(^&D~aXkM`Xe#q-Tu+$acyT8=+@uM4{hLFo2rokuU z3b%+4fooh9xgLX(x08}}u!cw{5#)}zkUR1Oc2v}x4(zCXyB>D7hqx{m?%GUM=4n6Z z#cOq5nC4pR?d^ReaTrS!^hY*6KK|}k&Fj-@I+wOENns`{#hZ24yY-o#JMWMV@9k;c zpiSj~^F4w|uV;D5NVQ&#Mfb)pUro0zos3%<+< zX-BwRbIq8B+&aEK&L+v0>n}Z$yg!z7_4`71V_!3c)Oo_HB!y;^(1SDSIJ#Da&AFwx8#};{l z)ZaE50A6-909I3(8gx>MU4GXK%MbFG-1`_x8Y5G1)|15c+JN2MYy!q|cQbn58S=j8 zGN%VeP4YNv6#pB)Og}DiogY^UmHOE}yQkF>0zNZ!bx2?oUk&R%pNiSat@|kbLu3VV zd2qP){S!c~%CC=7GcG3gL+-E7mqYH=6Idf_0cc0!(*Yn?A*B}{*!l@LX3<^(Ih1C@ zIt>Gvess@W=uA{a#_KnmOzpS>xDaBQ7pQ<;L=hl2fCFs6+wCYRgc=TfxZC(9T?wZAt=_iI;{S?Ojw1G5=#gZT#AR+W5`g7TIb58;JaU5gl?7 zeIR)A5m>eA#bI)YQ{8C=U<}etbM$Ph%BEKnd}~M)K!uZt8)g3U1*HH=B(F*&ug+R~ zc0c3>9u4gK^@+W(BV{HV$n#yI$=-^HZxZkQWqfP zRxp!te)}PJe=#>2d^UQ2GYS|Jp5*PO+I2k3QTu3+%kla!t6)M(>~CAiYXiRy$C>)i z$N9lmn|C5gsaTAGZgsURk@$pwY^Dj2;sgQWJe;Hk;$STo(r`95HV_TfBg4ZC&%FN3 zHdsQe>U6i83T}4*W1B%p$*>pnF@}hX2km(li1{ta{EEOL%6I=x<7i3AT#5@QDS;Ar zYXTMU))ZiwbNY*Kw(9^y-cEMzd4IT`?UV3X^53XSR*G~IBxIDJ&v%(?v_9yBd{ujX z3ZI{q!`?&zmi7V<*z0#ZKy8Xhwej! zP})~ZZxg@m?9|!-cR$Ma`_(6Tceo*O-Y(p^LcoH`q?B6oq5BH(@)z4ZciS3t%KcHF zlw7@Ib-e3_nInG#FH@}hS*WBq3;;h0{n38^_p))jo!N%fMbA;B$Mr{e&mcU0a07-` z52NTi1U&DhZOEBz2{a`owsg)ZssaxW4_F|Z3)Iljl8o631VE|r&TWj%DiC<(G%?bG zJOCjEox_%c0H?S2A@F9EvFB>5M&U0k4GpRIy%7(Ic3SH6cXncltfdFkQj10}h?7MP z_@LD=0L)&1)PKx$pF!P1QqH^fgWTzp$Jk`plXn+dqbr)4nvnDJkOQ)|MdH{AX$VS4 zLx@5e!YmL3#g+~UL#{rd5g7v!fweh0Wx#S{ByVN&3z4L_-x3f&E7de2Q%<7+;L1XP zAV3C0z{Y1l1XO$rI9%10&C?lENfue`EES*qC5C*7gHLD?8$k!3v2NYTGj2PW~Z^Q8c+p;?#KFY@TN z`TjN~{}KVrpN0j@kNemBsySdtMPCvFUHZdF6}Eu0ou}nuS2qXIlJssB z$&7ag(Rr`>3i3nlE*)LznXT4bJ~pSvpRu9?FW?nOCm3r5SRC+{ z!wLZAKnSB_TlMX^MjV`E1aD?c&jK#+FMu5YnCSnFbb+XV0yTdFAw1acYR6VGK>Iy0 ze^uvUqAR}I{q6F7P>S)4v8QSQz${CU%l}(^e=VO-=XOi4hxRoxU@2JRGp7v#VYlVr z9sa|aEpA9q-BFu6I8+}zWs>PXJdW?V zi2o3LT64QuBpWSpcbI%WdXy1znX$47TRN>T(tm+%z>HJ}7^x06Kpj(`2gLXrb{1Oq z_wVoa0l$GY>Tx=y2kd>H@WajC{@vbtZlmdWK^g4&&ZEJDlL*F}pWLmB6I_QC5~o#; zAG)Rske(yMH29J@k=07J*F7y|z845+w7^yEqufqbvL6DY;>Te`foA7>2p|Mr2VZ<) zJW~r?aBejTzFY&CkimsPeV&*vGWIewW<@%w^R)j??Fu-*nk*|Ti|6gWKn7I2foFLm z3KBLpGI7J6hODWN>$ud+xnI1Rz$EB_+(Re(=C{ zewf~Qkju+L<5CiF03Yf=2>4J33;_1|2ewUC7IV$^laKEjCY-=X;<>lnQ;`2I#rtQj z=SchIdd`=iwt#Ubu;c|mxYoE#R~VTi@qw@z38zOAOTe*PJzp6V;~$`x2)yXIzwYU| z-E{@x^YU^}NDs6{Z*X&S^LSM9zRophdo9DXJLvlCR4|pexLVIN=u}6~#CuXzI9;KP z+o+{;joZ~9crfH_&Nlh0xD1#O09BPF0IDh?AZT;|plZ~}%*lZviAc}=9T05-eSCb} z-Q58*dz9bk;MoFzNhYX}@_P_6Jo^h;pTf`-k{>t=(u(=)h-~C~zP_5sXaU$k z&WrvifPpd#MFVaC3Ro1)V*pxz=W(Uw$awL0*5`l=nE2mWUlr&7efLq)-#KJTb}!(Q z{=WVH-NP>};g|^t*ZV#9$e2@-Eb&ZCEC9gW-aK?W{X?KNKs2BxkxpKfKt_QBRZ@Ij z1jea)1ZQWqBAAOw^99_-u;ksUo#1Tq4MAP_@8gxqf5E}@4UV1*n2WXZ>*j?HRS`agGKU81sd zd**t7)^qctr)_olGH?0vW<%06YiAF(A3Pra8t&4HB1oHv%uNymM)W1QaOV8}b1mvm zOTcE&_4W1J*0UXNHnAiQ!d`P0+}~{UTn@YX^tsa`6O;!X?vYMr|1QaY=x^33W&j3c zBrd_hOAMxdD-hd)AfJM-04s(_-d)Y~NErXXo}2y8Nk7gJ1A2cQP$wC@>u9e1 z0=E-fJOt!M_&{7l{0sKn&;N(V0Kb(ZNho=!HLyOMV|r3dbve1<+7qO2L(;hNFJPTU z{!?Qq=1t7(`)B*h`^m^O#Co#8e?9B&0^tADajKETfI2(=9VFN^;512p-;0A4Ag#Eb zoK%wxntNiN9kADK%kkge?_K!R0WE6eEvv%K;n2_!u%wJ(k3r6gi&bPi=deLhNTR zDT-b^L}poJYU1wAXY`W5;)KP-wv#I=DzFAf*#Y~Qed#Ff^=AyYp~0!~uQ)s!u+%is zi<6~T%t6aW16AsO_63L*NYrYoO-tvHvomw8bn?oQoWisfsGCx~6%o+_urg}l79A-thcpyGh5UNxWiSFjL zyqwN$7@f>w2*SJ8&G@jrxA)dNO~~p1$5MXUObX73KcpbRM;p58vFUExOi+ymwBMIULlNTT33j97lqrH z0Jm-k1H_^}ye5>@CH+9JTW6|JptsoRGsyR*gmL#8{z!7W{;T_9k3FG7+B|+-F*v$- zSmA;H$>9A=;)drUei0b&yH?KHHJlx4V8R4da$YyEb=J(B!qCi2<5B??fstxHbDh`! zGyua*n#{UeVZ2*0S~_}forVC4G_JwNIf%o06IecAVdpQaOzNIVE2z)z1SQF-xC%cN zDUvi1vL231nlf*8tcQ))yoBJQhf*lcXt8C5=FPpBl4(5ge`pk&+oaA0f@i;mo}N@V z$djompgi4j1{GFCV|7NW-d3GFA$DNO_N@9wixAX(cN!|IO=0n+1NW@Nx1dCf_H;vmGL$#I!0jOjS>5NNG z1xgy6E9ViI=ES@U!b0#}v?!Z*eiuy?d&hPI}Z>K>?93(LSjbTTiStr@HKMcO?tG zzR2IL#DOeKUO>pjIFfxs%%`j$EljT3ZfYFGK6iU=b4DI_Xvj2LK%_Icw(B%&j5F=g$l8Up2!D55C~DcOJz=#-V$1_D|UdFkse04?y)lUcf6W@t#Ew;SUsKnz*&x45%c|g z$9L`TGL@?8Ie=E%Nh^oxnuG1Sr?QRl3_l zfKx9^9uf#I{*(-Cw;jy~cst?fM-jwBk*iydMz1W}fHW1J$+Qces-0o_8N7i;YaH=h8SGpwP|(aJ&EYqu)TJf9!{fnu;U0OFt=7*VL4N zJ;8Nv!N=-jy=A*VaXRT-@}m=Ji_?bpmu2M=mxt>l4bnrxhXR zz9BPQYd}f-HqkZk3xhCi;t$@Qz(3zfWcdG+^9&=o3rOOmh)5_$)%ONj6-KhxL3>In zst;|y;(TDcuR`|EgZF`Ip|K=cjhmxfnAhv)IjR{h#%y`buZ(G#GO-!Wvg|%^^fCEg zt0$E`v3vpUGR>sh7t-02l}W8XlW)mvfn~NoD`B~2Q+Ku0o%R`!_)2cAR&AtrRZ2e6 z5y-taFkhRpR2fF=Z4lTklNyL#OZQcZHd|kQj5$#Fh^W~p16Iqd<6VVb#QZ6S+6t!d zy9gX{R5cvedu?RYm^W`+1`Y~;QL;ip_3k_e1hA`nfa~1>iEh3a0`QGk zKsx3vzzcV~Tk}$Wky!n9NB8vsYGNohZ5b9<)d&?eybX-6SvcU*aazx=xb4I8@is8b z*J^|=+F9-V^oie#^W%#h-=lW)#suXbq8UrNvHMDTHl;Cee|S9={)^AyX%oHc<@FPS zWwbip+f&fyqxLb)m#P5y0SoaJOEZ!=@a9R_T^SfI9!oaErR(YuC_glmNe{d15n8Fcf*K ziE9(8_F5ZUml2qDh~vS;;HI8gl<(8*{5MT($3f}xrD@xrAwxZ}F~`;2L}?bUv41YM zLdS;Qu6MpDFlSOt^9lYLh4`LjP~%CYtz}EQG?;{f{q>AiFx&&3ZxfH{+jH{XrL$y@ zc2v*AEy<(wJqNdnU(zs_bQdi9c2~TT34mRDeIXDI1)N>gaA3)_X-*N}{fXNB$(!Sy1&{e2eGlutN~kvIS~Q1-u<f&~QAS1gwZuEVKL6}>@ZREe z%xjwK%!b-bOlUW%Fhjw~5jkp1<@ip7#3kEzY8`IdcTWUKM5e;uE>%I2(5lCVQgXlO zq!D0JIGTByJi=83ck^uQMUY;J4O(;F!sKwFdROklEbJ>e2L0)DiJ{3sJC=+Pn_)F4i+Z>jIKt|R){>y{tZlQD`&74gVXgfaK#t;=MO3yJg zC2d~*5U!gEkpw@ANIYsX=mW@W_tn&g*FmRKK*ND+&{yr*W~p!2wh54dEYK}qd_Qdk z+E@VT#|Oe90Z`-ox5QS_sW9C)A890jhv~Y%yLN3~d#}J4dpPt^!b+Eq_nr!LX=28iymKL-cCAWy965s^?-}3QX`|d&Jf1sl)n4%- z@`iycX&Gl5!10P!TBr8ORWeM~k8wXSXDtc-#pz#~(Pwem+T}P7&C(Kegu-RR`!tN( zK#FY;1t5c~=&u;EW}}IWo=VPV0FwAPhX!BItM}6Tf`9$avji$#K%wXXl)_|ii#snK2=^ii1r#SbFJpZn!u--B!Jd~$=((J5rx+EaEqPZEDS^{B`17}4|*wJ;w zW2ddPA{MER@UG(XH=+s}F^>nYpO&twx+_Es${5Fo2O`ERt~7ATS+chq#=aRjLVLed zsOLc9kj}u^@Dr_L(`b)1z;xx2e4d9JX(5vyRRBv63hnhe=T!OaqE^dyeKY$#e(_&t z0UAWRofZdR9U2}X-~;Z^g)|M6eUFJ&nl9tHmuRf*o5x{kkh_MT&-9*c)Jau7l|Ov6 zzvAvn_U(RV_ffX<+|Tk|yl+-{o5AEC%u$}(?jhJQ?&^O#<3$U&wt*}riQ_=18ssXQ zPj!{fbw8fVrI@vINsT*RDzt1B%3Tm@Q?gv1=`+!x!;CgYdZOvpCd!zc>aJ@~_$)-IYR?1CX?m)zAVDM85zBpPp0IJ z%4e5bgK>f0D93i2k2_*)e%|J$^|f-|iPIg*OYELQCB;N45}Cj4 z9g&CG2oK-Otmu}CRzhU`zyVoI;c5#aqNGY>C=fjIrHYHPdaZw86XKADP%l{j%ND~0 zN)wNw4ZLJt6-qE|%wj%fdN&N_92qC`B~|X6`|`XQZvH&;6Aj!-0e0{3IjGJ z6ba}_IG?XiHYeiC0L+k?g*|8nj>$qX;2+y-4_&4oOS^hk)cl5G@788Tmp6I!2T_+B zvpcU?z{481zU*fj?)AEOd24-`mDxwhmqFQPvZ^HV=qP5^Sq32@0*n0_Z}4q1>V_&& zA;TW+JGX;s1e63|`?0|ApUrJJoO0$tJS29bo#`cdn*$EuC+Ur7WANm7)EBp$G9^NE zC)$s{cVEdkQ+lSSY2=U<54)4HR}OpBdjK_od3p@E%~L&5pv2%@FGl{?B}A0Dm%d37 zj1`{dd&-gtZwc=Y@|%-ES(X3YtzB2%qg6aHA(8hj%U-a=5SB z`K?#lGI|mAkZsfQZ$$)CtwHjrrw+WZqmNtRG;`{Ph?fH~?@G!!st;-6jFrO& znSdG`Q6V%Bw19Z;_tahzjs5Sks+GmhK^W}>VwWG`s5!MCla1)#Jv4|BApeCKF$P#- zwDF(9cY0`ex9KuVjh}z$>Ny9xRnYNsP=MsB2h1qi6_wrlrh~uR2~VdyB+<)Djua7- zm)977ln!mf*ad|uey#4{*}bIMj|06OpzOng_hO!<7mS12GPutSz4pVFaIb51G(_o-(Vg0HppoW+r1CxhFJZdE4&#BKOAw0FnA z1bRrmPL1m+em`rB`D$qj9fKcgbrm*Khiirsanic<<3eKKJ<5lEW!<>PPl{w}E-|_! ztQqwdHU!1%YaK6J6!&b;f@z%HmJ3^Xe~3|eb0)s@|1rUz%}&TQx}O*apL+Z=gUoiM zve{pXD$SYK&_z`@&C`~aG80x~FO7E1OMz`{i)AG6yW`;#NvHB{u9A;oFl`JrI(gKY z9#TmOApde`N>!R(H=9nN2M|;nIZrQ&R0|GN)R0337x)|HdZwKxhTBm+d!+;AoZE(C z33KR-^m<*&F&D*^fjM94Pk%fK7h(n7tnvxTs8`b)kJSb;Ze^H*HDfL#CCWmKOoZd4 zbkvI-y@bVg9@eIJq zaU7b0)icT2!I^x0YsteDeD=G4*Wj7|0@Kx4;tLS5zGPE9%Sxx`n+CCA;LtTCC>PyoY=wx>n*BcE1kOh z9`|EznR+LWwqfZM_Jn?WpG8-ySdUB|j+dcvirOYc;CM{+9J0FMr{VKYXps*0H1wYr zKoA5*%wIMC6-1-~hpWoL6Q=DQ*90QRK`)*Iqko&xV@|1!loZhXzX2nbaSEgHRxJ=a}~SsO`h`0(EeTCpWXe4M;Vy;-)Asp z;fxM%I6YHBt0`it7Xo@;Mh@+EMA@|zQ>S9H5G)$Z;Om?>g+xN2&KXUzGty)EA z`Y6?LUjDKkjbdzwH+rg_m7u;xs%u#_Z!7LzXGN@Z3-NI-7&9Dxu*DB5H7cWYb_?QY z4+@Kn^q;0!>GCHG=i3<2 zxtibB+r{8Mt(*ut5euNC^pMwx3RpBDg+r6xz>jHpVAWqDdUte=8of0#S2>3o0D-$* ze8&A>ohLoOO=(b&)NEB~Q7HCORAavnic`Egc6FCTO&;@{=*cOYsp~xn6uD;@i8;?= z*k@$a*Qm859@NNir~y&57PkeYcx$^vgi2I8%(l7=_V9cCbctmLu@PWq?$lGF@^<5- zat+Mh_;#U0UPqm6+AgaQl*smTd+<;%)>L}H!tu6bWj{*~h=)}(ZF?Hw? z&w5ZiH0RCx=HBl{Sw5hSh9_%<@;6~em!1Fa_B<(N_1x8JBX|FFm|ixmAUCWyz1s*y zs`fZ5OHvzhQ8v2fGS0`_$PNCMm<^F|=gMTYgPyD54Z%cgqk7L6d9HZ$_R6bV_$Q#h zRuFr~6qVK9YeowUBbvzx*7q3dWR=5E$UHrka}pMOeO?BTy(0#+y#*+Et!D#k<|bbk z!S)otn>8lM?X1DrgHo2d7Qrz6(qm#cd!Q1&n=e~cKznGjEc`LYkKd6w*c;sIXW=~@ zC;Spk$>8OF*Ui%R^L-4{^-v-vqK8+8f}xru$Zc=UyrmFp~zb<_q85`S3^GinEP zHB;!WL=z0`+mF*po}8(vcjqFwbt!zR0&)VZGTbjW2%-MD>N%E`!-t{s;;(?1;Hjvd z(}$!(glM?OB1L>akXt?MTaU|}eF*tGG)E?g8T;$;!m-?r7{Pl&Cfsu$mcOLPQ`6|% zWA{=~>vrwD(KFSvi+YM#My)8S*vL-qh{Izej4OGO;Uv*bH?#@OpOa5Z8QD{KyuxC; z&81F7>o!wVj98DwK8mlxK(N$dZYO^00loe4M^ZljTF#gFtJ`ze#<;iL^3n?d=lTV< zwDlT9o|n2+4*Ig9F6$ZVM(06?7LhMWc0Q_yR1Qx`{}rH>fB>zBv|U0v2TyOL_|=Q} z^speJQN8p6&V;Cs_P4?VFq~T|b+lEJ>z@8-PdQgD8oKiPespAcl9DAUlznUVfNv|9 zzkrLcx#H(9E-n);++V!sIjFIp$R*bqP;fvx3%0YwB)fNmJ=+-+{Wts|h(_D6?4+Qm zZ%Or>$DdD+Gp643tS;Ksb8k*Ku{})lcqIaT`E^(3@ltiS>v$upHD}Ohr)a?9h4q99 zF*$8_T)hEx0V6G-1T?5<)I2>AkW7e6AQb~N41qCVFF3fzeuYTIJmZLl>dh{b@O0;!Kjb#3m^pBL@Z>Y05+kl3eW>wb2gZh&d>hP(PY zo)e5Lbqq;^9zG<`ee&`{KuCs0p`OLAyRkvIuqA`IebK}qb7{zNhCt)?2ex<|yQ0}o zkas;#Y21&J- z&JTzHG9W4rECxyPqp_g=;z-S>6!IlwAzKIBH)a_BMht`?T>D#)nAsh%@zk70dNIrP z{DT_}>LgG9tSb`@k}a)eD$Rvjmk&&G-s}aVLwbMomB@teN_IUTahimVoEn8Qy&Mzv zC=MmC?P?nFdhUoIwTALZUr4=#l=-6s@l$s!{m-y;AjwK|OuP$ZHqDch&}U!Pd3Q3|cjDI8@LxezRN7ddB*X z-%R2_+h-R$t17VDTKiWyr!T(!TD%D^6BT}kaJyEPYT}mE(b0x89m`874~SLS^z8bw z8qZ5rPTfcu7aQ5wBLb|`-ij_Z>p1=-n7Y1S<#EU>1kcbrG^sc@i-Lg!5vhNE`1<32 zjN(JvH93ZaqI;ic(V1H$G>b9;u8xFazd0ltMM|cRie8zcRfexL1X9&%tn{;YYIkUN z3Y~CdO|RueUvc)nxCRsvwP9j*?yl{VQ1cLxAr;6^ zG61IJ2o~>mHGABTVFbtDD#r}mTZu2-#2Q5S&ShMl`D8w&Kbl+-U9>AXQ_pe4gU%I< zJ9s7l)X}r92z(8M6T-hdGf=t4itIHu;uyL+NFEl7{$Dw|rdHcgJ!Rw%<1atvoZJsg z3Yp@?IMAQ>u6+$+C9VFbIXhm+&){)*)BUPN981GfBqL(MP*U0{jkgHgDMH#nGe;Rbw=u6!9H+hYv}5u8egMsYkgKmjl6;_#nr+ zm^R2(amr$$F5~BM>hVHof*!GV|oc6 zVK5T+BmVSDOO371X6iAh$-cV58ZV)lQ4G8A_9xn518cl89-b#2sJ42pv&{R569fkO z{;@!dZfHcSbR0eO0Rr!W0J~8at$6N1*=54Fov_iNeW-mH$9=+0EDn`GjbUbUX8&`2 z9ngz!GPk|!y%F5W{t+o^uG(pX={qmXA0l#f8mlLFZH|+mFzf(&0DkC5n*lcYSN#Qm zsHZBj3j>Ap8j}H;jb}5E(ojA*ep6;7XXBx%btq3$0RBL!<9#jEF(bAB8wU|*O0SoA zzTvfd?t1x5LA>KsMkN&#Q{d;ca(BIeMd+0;g3h$*^-RH*%n?OSU~)djiS&`$1I$8& zWVzw;r;nB6L2Pk54Z6~|b@YuAMxHq-u?Ljh7poiB0npy82AA$B?305uPv1q1PZC!t&o7uB_|Fb; zqY{S&*^ID14gJQZYisU=!W0XgYsMtlxT9sa=P43G12K%-5;C^$PL~jggUpVb3Oonn zUkCQqBS2$rZ#1m7Q<^X)>ZktnJQEIlVb3Jbl#Lf2YqMq@hNmidV--N)Jnj5^3su!tLTYPb5#_S9M zo$yf)z1l3^;Pp-_mR~*(KcbQ}v^&w>wC<_rU{nq(&8+)j1GNYoWKNF*w?RREqLJI6 z;CfC#V%^8re*)+)FI^hz39rgUKagB`MKL?$%$dR?M~SAxwP~pA9zd+k3cVxhXRx$PjW09C(Zx58%6PL@2hdE=LDl3c9NFlH!QLol;1 zd0CPx=c{NMpl?j33i>p!_%MzNh0R&D96pb(ixShk(>u=Udq@7Mp^wr34DvzZGMDO_ zq9%A&F{l6?bHO;;?-~)dKNa4iIUuguGG30Z{4Qt(QY>f`=rnw!R&?Izj}tW+_e464 z00h-749i0Z7H{HJYd&G4V_s~$X)wN222hb!Kiojh4%h*(cP;=OO3u^7K!^H6ggaQAGJuRWzn?k)(}h+0BL|p+1f8zG^8Ng5Kx9`4zT(Um?)rww3=J zRQmMcM3d~`ZCZe4xBUpz&y-A@U_j!C0KFt@KX;GlnqrO++YqWGwI*vYenEv#mpYx> z4KbwNAfBEm@syL(IpRfRN;^kYz}LUpdnOctzi1&PKm@n(dkIKID6AJ>jdLiLY@OP% zi7E|DqxAQw!~U!91?GIk_%Kvxj9tzBw+2w9IX#1LO)r3 zCY0RfnY*9R+8ybItyQh;Z+ubLvJ3f~u=*&0E%TLFw`b3yX9j&Rt(3Cm^EX2e{Aoi4 z>of#yvlGb-LBF%uUJE8hf$VZcC`NhaAKL4qq*TT++56I}qL`H@xWw+fLkaa!c>5Ks z5epJz(OEFq5(Me1nAhJP5Ou?v`S5-=Kj*b~3VM$T6FvF7us{Ec3ePBv$h5MOX#n@# zlbmaMzfDIPSa^COhTv_U;xkPR*l4wYNiMYCnJF`P0RJOUa%W zW$a9bKY&dJ6%-ryG_k6GH@qs`PRq&=Gc+;Hs>(S*#W@Rg%)rSgC#EtJJ2cB>mga3a zYACdta(?sc2zkkb?j-tHzA3znqwxyvEQ#{b>-T0JuY~KurY&lyy`4?h?DAAbcyKiRmm$}kR8;aL-76Y5g=gr^`Ui(0m42R$Z@ zsCkbVDnj;7Lg$BGmVhI=F`%MvDu-(Y9R&UuspphL|2=HMF;pvviyY2`0;h|;i#{x+ z1l$XrPuP0?qF7Tr5Ielv?>zJSEZ;#&Cx`M`yOpw@p6FMLrr&`y$YUmNy`SVcnCo~H zG{&a;Nst9JULHlAS@(9HI#f`_@%Y`b*uV{Ht#ck<8kkk-nR0{RL>(3%g}hdx4=I|W z6TU_XrUQz84x7@#JQ!q__PyM5hjX_XCFX1L$f!?#Fz%%~zhPPp0x`aG$sB~w4C9hktBy0-TK5_95P0@3elkkA>iQT;6*7mvSU+YZdj}ZB7UeIi;npMq$n$-xyc6F z`IQ>`RqjP9dMK?>>eVz`gVLfRX_JUBQDIjbc0ZY~7wE|_qu5$!M%J*=gqqO@D|#Y{ z5;o$Tyh}naL>~Fkh1%_G_0~-U2SGhza#305>W|tKOgpKCW}y3|Uj1ZAPS*qD8I?Hr z?%n)OTIzhRoO2QZ+@|0iGSbRa4oh$X#V=27^~@kmpnAtK)BuE)g9wU$s}I1*>pN>W zA<(MltC*zUW#S%|rv0`j|AGOgFDJg0vX^+iuqD-zwl|R&{o9d-qxLPActJP6NAc$m z%OxT$zDrAfTkaqmcj+{UU7DcUEdD2+7IQKf9CPfM`%9Z*HhVM%&^UX4^VcS2(AR1i z9kCev&_4#;b5^OBNqGD*at_W`6ro?Un=PRh*_5Di^tZH7kl-Gh^4r7`5tPu8Ud@WM z+>>J%3fuXUZ%ToK?Yzs)YmspyJL8g%H=kLxRo4xI+{sBaBIKspy6~D|Mv==(&E!xH z7umv~)@Y7Jf(-NPZ5E3J{hZw*(56;-%>o7UFP0Zv0k&Jn1pUlHvsttr$T@9zD~HFC z)t|0HumUzj$sG7gq-e{p9fC*u4s!QXJyTw-)n4^YFom#~w);}k6eUyB&2k=_;fJZI z$!C%==MQu->LrvyV!E@TRb3vjI#2mnK*b6V-eQGNau1_~er0KCw{&cFrVSM@>wte! zAqy3+38Rr-09)Y#wc7~0m!MgB{hDkxjT#itBzIP9ol;7v#DLcmN()d-8rv)FCg_(q zt27EZ&{uZwtJK-Au_&O#BnI)y28@rp8~J1luWHXkd4p*}tLjD{U&rJ2tmi84DZlie znGGUl4@g32e`cNZQu0|p!o|x(xbyPj3`SlkCjq zD_FswJuQz-CJt!|&FQ7b32Jy66rc1nFD*ekyRG0P3GS^kT6KH*@%1PK8_4Pvtxi06 zhzpx@64^hP32=}d*#$%5!-dT}DGkU&|4Z`OR#3vLyoTS}W1vy{m}&3FjQuB;+;k!b zDhPzdD4}}7q<#^P>ryFT^PKBM;~xjbrasF+=C()oa!x z%XyxlsctFgsm! z1mht&sMd(4P939JtgOCz?wNT`5B8`1$IQhJ0r%CC#skLP*dPl}Dxq_;FGg#SF%}Dz zcRq%uXpIXz&ukOkOFq+9s2pylcJTaS_gA+EDX48+Xci@s`g@1>jwd+T{Oc@$N_-KY zaKb-YKgc|Xi8w5B-(5ai0v2aus{V?>vidnm=GZ7@ZdFK59+xnp4ySZ9zCO628Z}IL z_9>py;9upxP))P=y0GVOaKHg z;=jo+z=Dx|u|huKfA+-y;k+r_YyAzmc)_gntsd8&vb0#sZc7j58_?a9eVwdUg-Z@5 z_Qq85q0hHzq3972Ff;oKB92AX@J&vle;WNDK1l)xH2*d#)@KBiLL-;g@||**Iuv{7 z-BVSn0}V%=?C;K%I60Nc{F>LpmBz ztd675rrnlckupPKag?K6#iTv&llG&HlQ4y|TeIV{G!zx*xpMnV*4>)d$!!TC;pQTr zlWTt!#GcS41i_01Fn^lAaY&}yU@n3Hh6WQ>#6d;DE33s0qx5o984VjT6jN?^b$>rzXa z8eao_oXBc94h7E1nhVzx`c9s(9|8Idi|k%5On~wpFVv%p<)vP4<>_6>CQFTWZWPMX}$@SKcGO$Dk|9k%C?bY9z8KU2{w4 zvSoA2CM{5YN7aA%3nG_Bm@0yqB2`OaNecQdclb1&BT?n6!*16#k%TQ(=;Z4+%tt(> z7gjI^7RZ=_o2ksBho4`RrmE>l1td-4#)LHA_Oh2v1csTvJny#V4K*}kpcp@a(hFoD z^Me2BW&!_K1GppuS)fP))JYxxO9K7QDYh|3Lzjx^PkQY$SFkI>Bq6)b4@?Y+DL2Q) zAkW5-T0Cj%h($D~n0YLIc;-W=|GxYSG(*RF;`SxX(OL(jfhU#!W{^IJ-7r_!9siS{ zikF3Qiz?bD#dRa)H)daIj_>_>!t4gyeEn*g8S`=3A#s4H# z%4N&*!IyF_&en&p@w|@|(SW@J*@5K~T2@OZ-G>trNF2#P4k)|L8g74X^%sKEM96*v;H;kM19a(DvoYKD?AbDhzxq97a z!wA&9wHkfBvV7~0x<)_fzhXj_(!Oz>(kaX~^5&eAnLBZm{+OPxffg|s5OZZc6qNE2 z-BwvYLgpF3ZM4*~F54@gC$nLOW?_~mCQ^ZBFTW`kSBkDlj75~Se4hsAhSH^0s@6LD zHa4>6_^XguvaW*bwe3)K=)_o6CKZ2t9n}YcH5M9(rGGC{{F?m^M$8B_X0vUL$kkTU zwno^nP0#yPML^_1+;i}JQ<1BK2+)I`)oFp(-tN;4JeH6zxYwY$kC?MVL~BbJI;YP! zbBnA@s=Mgz4wdX?^k9jog7-9qOjVma>5K=A9Hcy5E$#f@x^yqS$5zpS_=cKk=S--p zd5b*I34+@ImF&Mh5rur5Dj+iMA@^I$CZgOqt$27A^7JSy{bw)D_AZk`6vFWm;SZ)wr8e5eE#)~v`hll(ixio5BR>esm@0eEnR(ijVX+NGP_==uHpyhDk{y%q-`}t8*^pr-$<)RK@GE7h_C-?{QwJa z!2&x^9hxMNoN(3>ZWDy8M}7oOM*`hI%}n!TjZ7iPf5!avi?xz=`)LWT<_ObMSb8se zPPk84JbI`;t3~*13?$P`r}1JDeE*b5siNh!iak|#KE#`+k#PZL_fq(X1z}njZ%5vm z6P*t-TVGcRSQ_CiO&3ZSYF25&02w9nun(j{T}sf&q~(CpMWwWr%3?#uJJ3f9IxQ`* z$^OEo7b&zsML2h}I2J5N*2+QiLfeGz>%-O!67*z6cf7 zO>?l=cgT+@)xI@zcOm>FkSyVKkbes^ZDCCyS+l_KN2d%O?~jugB~N|MEOiS;r$iuF z>A8#_)=C`)JkNr%OeCh`tJf}zux99LSz?*sJSSAo0Rab`fL2&Z)I7SB^ZUurd3vDM z2Xbi2#e}Z|X9rN!GuH$Q`5dtUIvp8VU_~j-@o1`^@rTbAzGu2}jeew47(67F1>sE! zGLw0<*@TAB8H-pjb!Q+Rrue;3SsmJuK2*%t)a0>)4Km23Nc4pCN69sVKPo&I~sF3~T6}aC)$N8HL8P0a&b}sX*0||{h zWdV@3V1^-zzVCwb-XFp%vbK|8t!oZZt%9W*gaJo(re(BhC-x_{2JA5hdq>>Rx!`c8 zIksU;P@;LZ1sxu3-~VCjy`$m$+V<~j^cuYrT?nFgq6^V`?=pIe-X}UiB)UPg=tQ(c zi{6bIy-V~SLW1yK^S$qTJ8l%!u*pAB581CWq3s2Z6?u$o?+58_6hf7i zj?JIDbJNtnq_j1waQX2>NjUHY9&N++(Xd5%mG$>c9prgYnsjkAqJkgPU(Y zxA$nJp7RxcyGwdu$4A=s=S@s5<>1zPWJBEd-Cb+P&yY^AdfhH@aKZsfN_mA`vvtAs zzTpLLJICUoq#+H$TfeFI(-9ZMrUV~Y;EH8*g;>3f<;#rkRg|^?PS<{F&-8t%PwfTt zTy3mh9j5=n*Wx5sVywaLS75T4DQPbtR>Ys{0UJO^C60cwMN=y4FzdiSlhm{$vf0Y5FuIO6!%(BoSlKf%2nQ^lzh$P4JM)v>04^R(Nk&!76P zkidW90v_Rv1UGHL&L}Y$9B|c_W>-TVX8GMiVDLYelL`OX`Faw0mVEebs3e7qTCF~P z=dI9+PNzB_g$=_3mmsOrHxxp?{YN#^H*A>>ek7+OYKPQO_?wLAH-GoHw#XG)c@t51 z&%Gv>t9%!MUVvCOVM#0F#=(oT7DKpw?1%Qkz&m|doh=1Bq^vRMr&Ihi%c>M`@hX#)m|`rk!8Z=x$2KvCYuhZxP;zF-VIJ;(xZCpQ;o~(XEGfH>X%iD{-g-LcB37t zu(YUx#p|_`laa|xn_FkRjx5&H%{TB#?lzZHk1(t#^tBtwYQ@bPKpya2*80!+URl>! zQt*xcRBr6ng@%t31d#KMNv9c4)aO~0pB`y8HzD~!Qjdth%)@-AdY(f71$C&2rS{!1 z&He{;TcFeA;Q7c>O7kx(>zCH7UThuTP>iAUs0fo%SiA|4*j)Od{zub}i%a&TXp=+h zRtpA<@^eb5dKHmTFIeyrc0nW9Aq?mE_2oCuRqd?QTBhdvD{wq(sGWo?5?pN>Q@-?8 zmqUwYAQS17N`gb;D?*F02QHCgeHE1Y2L>>CYMa97IBFmv?i~v^QyfWFwu$7=(djo* zI959~0=*ZMm0){w&pw^YJD;p0-mI`d*ZkR4CRlcW z^Ueo3pukgjNm}5oCont@a7akmz~)d)ieF>?vk9eo5dnCore^hh;2U2$U5X*LoR#2a z)e5oFgErm-cEC9|T8Pu^_H%oEr*c=`MRB2yUAi2nlvDaBS)N6NIv}`hpQw&bDP-zd z`n{0@!It2ufl$DI-K4(gsExqlwq1EvWQxy4O*1fAl3s~td?7z$qOOoI@`42J?XrCA zkOR~vDl;qK?@-M=W>8WD8qj0aTDT)B8uz8+Szzi@c@0dk*f{ar2Y{_wVO&e@v+Dk% zF9IUc_q~ijZr`8ni|v==3_+tCY0nMGZ_CzprY-jVR;Goera2V&hBewpGn6o*&|9iJ zyEWsVE>-jam#qIaxm5qT?FRjeOg}oA-wCe%%RXSsJdp@Dv88my92-wznm0E4CtB0{ z+a{c%4SjWKp=unXx9qtsC1X2tmsa(GjWlSJmQcQ!91Li!ba((p_uOEPC;NKX1aWPr&E%;7&+H zy^T5SBt)Yar5hzD>BS;K!xQlGiC|?IeQb$AU{T}Zk$|57F?Ug=ursau#9Dwz=PLhj z?CZYftD(PrGfJOjJYxLy!_2#}E1##6*LtOoIXOA&L*4UIPE4~DApq-oh=~p@Z!H^n zxO>-<1Hz1qM-NBnYcu^5Jdzz+fE!(ogY}0NSNT<58fNXMx>xx2X#_K(f+FEjsX7m| z{HcRaNqxS*mqi(F!r|(V?19tF=(jhKcUO7l*X|7^aPty6!5Hi2qr=<$avY7R*d^wz2YuDi;+Wfzl{wTU(M#W@KgFh zhBw54a$&2dRW<784Bl%tR5tI70bE{m8J!hOzyNF#*%hq2WgSS?- z?qd2GzgsTH5@!t{v_U`5A~K%3lW-1F7Ck)l6L^mbm+lrlmx(QJ(o(uiSp17P;)+iRQ zozBu=ybZ4rp1!R6s<9L;#7OMrd=9Q|qOeaIwGx&QzslsM!kZYO84R|1GSdgP(d8-D zrA^=azbQEe^|LKxjuawlIh=L7SC_61?L?qe1Gw`%KaO?4anc;Ku-tBi48^F+SS3F= zd`7ovA0x+0kJa%$J$yP1^JH7@FXPV8Ba6<$2%>Dh-$TL4ha4)gFm-X?`{)9%I9#z9 za||^5Snm?jTyhS&8pZsB1*ZN;!NV$GNQPkH_)DWuPSX^zc@hEOmzZIAnzCvF(K4F64;3;C+S1HujX)4+59a zv8ZJNv&aAYa@I&=1|vvNZImzme3c0rcy(X1`lDYA?e8&STq z8V92C<@#g7(X{x@;wYUTrer#rAixYpv^<`(F(m*Cr_q=2wG4_Qc_4!m8=GqLiG>}5 zwSpQ(r51^Eg58Nl{8Wjb1Wi$k9cXD=OZDdi754H{rWKakx1VwlWx+u`Dr^ z%0wJ36i&-*vyxF$W`n3&ofBU+Cw}=PkV%*aZXXtVeHdlqhl}DaETa#Dvk{D|y34V0z^U64QhA-56rrRLyqo^S#3+GGL_lsJ2A33B(T z)n8YF*i4SoucZvq*_wP!u1g3}yx&k1;royQ;ezxOK!ucyWvl;eesTz=ZSCgMO-q#}_+hp)YH2Uq{_|EbbQrT?yZ zWrhsJ_QJq+jTV#yIV=Bp0}A!JOYKs?I6p-7GOTT8-s);?*1BIfI-*s@%D*qh=!DzX z+m0!d?LGYg39n5Hreh4@#ZRH=?%fK^ZW7lr{aK?=CKK_DRow2~P*G}6q8uLVO6i(c z0C=YH8ifgpA~W7x_T-X})>QH{7tT%}c-_FoRen^J8!&pClnk}de1)S1C>LzgGIlNK zC^J^*DSXDznhVtx9-Jn;hCnK!#9ORd_0lE-A`01^BAzt}p^fT}K!6>( z-s1R@wnfSZn$^)ag=m=J=wT=-dsVQf&BH#M7=US8#WZ<>42kwZ8RDba{J~7wQyP}V^^*IY~ zARbzAPvQePv1PtlmDFHZjooM;r~UY1fMKaUFw{DHY9pALwpMXO*aT^F?@;^;i+wMtnFB`y zw*00eI~C{f{zFra)pTltgap27X72#kHq|vXuB&q7vquZ37N%FYwDRSQN35~^(S_LY ztLFWJV3Z``^ULbPE>KW+otKY7!T5>A3|m2Y$Ju!Orr#i39}}!1>I-L_=T5PM7VdaH z%~RUEz0{)KKY99f$V>@!1;QnDjQ^1F&)CE38fI2~k7EktGF+xxBTq9|LE3 ztLxt-F}FFi&a0d;^IwiBi-22yg%2M;UIkJy28`61;%j&!qXi3j9yw9#D7v z6RnE>6|F1Y%z1>1h9M}saMk%t50Cfg$qwihMKTv`{9Qy#e__Ru5_JoYKQZOke&_KG zwa*_?!jTZANTZjf=0^afL%<7)j5xfYpc+ZwnlVj5`Yg*BLcmsJ(O+CI6xVgBiyXU>`MY z7$+oDI=g@ZdZd#ofIv3RBFt4;8}0lDqF32#)z~3_V=+*Q7KNRHyj0Kji@{4y%8+RW z#OCs3v2mT}&?-ckB%=Q%t07J{`!VG!+F*&JA|_Im%GzmDBYnx11wr%735_=+-wroy zgDA{DYB)f3`nfn9cL&VJOZnl0F2XaEHH~u%%VhtEvqJ;$6QEvCQ^AQ@U*7Lg4Qdef zh&Vi`ZsLYX5Z&m?Pg}2N!?*@^FaG<5D1Z55#VmH^?GL5gA#}M4QBK+5_rXw72hn^P zzu#hNck|oa46U9cIUWWqn4Q9sj3lfv4c4EJ7;aM|SK~y!O{U3W^$0?6KLl7FOK5R% zLu9m3zJ=UC5|Z#gy&M!y(xC&ivndaV0B#J=!f%U!l`Ix$$8`FbU72Eby$8{W2CaD*qz{=A-Zat%wK~ zQZ741`vJo!9{%7fhAQJQrSlmZXk+Y{ZNSv_!N!{zbUYuo4n=3gr`MpjSn)z4=1<%9_4&nZ8$=h_E2yx0L4XSwiT&VxA8g zF&P@;us#6!JCc}Vp7(WJPf+r;;&mS6U|M;se(>EVs(p8QDo$|LrAKB`OPgFoxv5&= z1T$*{8h?(tivpo`1|%5K`k}OaMTF?Qgqc_ctn!x{iliv{T(~<5eRdg0c}SILPG` zl(=H=|CQ9d%J85VUYZfjuftr%^pNwj@AFkqrQgWB87dQkW}SQ$AG4pkN+hYdfgyGrN#QBSzLd3xLTt zJ;#&f_T?(FSQ{db0i7Uj+=b70up)d83`(v^G{9V6W^-|B1{+U?#GMR~=Vq$o1sEQV z30L`6Ny55`(h76{51e`(y`F2C!m$}9>PNl~6g(&jqu4p_Ioi)j34ztOlLJJO+DGOU za#&jMjj)NBKRBbYi_R*VsOyfaBMz>puq#K;_i-)z{`7#%WVDj%Pa$u5O8UarDa;C+ zI!}k_QWnuGveWU2Kkbq@9y5Q@VpqsPVb-JIrc)(QE@fEJ@qSplzTud|O|t)#_q+MSvYIByj^^a4aGWXj4UpiM^aF(GyqHU6w8$iy}q)N9~ZMyl;@mAPK<7# zX0i7jPhm0ZGRy(PhWPE->*$!)#smqGGrQnwb2cm{n#K7~KeSFhREV*^svS=1=llJE zbrK?DZiFHuByMlLsxGZ?v@6_64dW`~#+i!&ma{1;UG-wbo+5f?@>YS`OWtm-U_p1Z zwtB0d-QJm=*P6`O?gj%7l<+1=qc`i9LW%=0y9YboKK(+S%0#SI5KHN3=Mj=Avg2f_ z5A252?tBu$RvqT3Cb+J<(@u}s+23t5hSHhKl31B*qp z03eBzw)Fy_#B*sVz=%hgcnO)&B5KNT@kZIMvcQyiyD7F~V}uGbjp<6ypvu@YCiJvB}$Rm zj=06gYZc-#hToPTEDU6RRK%5$IO-B6Z_!P&raBQ6C?jNWs5XBy7ym~v%jc5SS$Juk z|3x^*Y_o1fLy4xd%6CJG+Qvb;7#zXoB{?yy$9&ro3%bZO?FZ&=ay7eudVc}>|B8_O z3toZDR;p2{KehrqMsL&p`z2I5{MOH_nwQB9%F=@dsm^?=lkK59#h&cjAW@9{fRJ5` z%9i$g7cW^;RO!o>AljLYod{kN4K??4n~sg1p)()WYwL*Q!rq_602lX^L_uWddYu`7 zV;=Ybprftbn1kq&0o!e<4TQMnSPX&duxeKzzwF5qh%?~8sE}n{1L@FKW#sKuhQfX% zKZF(GrjSH-U9X$Rr?^&-Lub!;99rqzu%o~}#}dq*xlxOG9S=4`R=N1*F~b+LiL71# z=+-MDe#EY+73Pd0A@m3A-r5Y|!;;yKzSV}iaW%%W3`F+^ z*7}!^os-CSl=flU}OyhcEk$!Gr=I@ZP!4( zDt@l7m~pDje%W(*J@uC!{coRNL%=?|Kz*!O@pmZ+_HeuRpR+Sy4onrc8w)O2r7I9@ z9lZ}&xLZby@m(l@zb>h_&nI30(B~K?t*SJ@_iBQ9c_FB9o(|Cxo_#g4h&uW#=)Kk9TObX^*0g6UwhJc~BU~ zUzAm8{v|Tu*SnC2KJRLW{F{QoYSvPr%jE8ot3p_<9t&;>R~3O`t$>h1?J}`jvrx&| zLpdq6hWDPM58u(g4nEGFvzVgOc*zGYYf#~(ieZOs>Wb0rWp+>_ zxl}%m5W50((s`Aj*{CCdmegGsH^E+*g$4$Qw)k*dzYt;tMsH(pU&p9_WIG1iMu0K+eUt!i_| zQG+#4v0F04)f){U(AIwYMZ8hq1b>52#g=iC#$H+1R_SpsjzS7rxZ;ketTy(01(u@^ z6~eecSAyUPUHASA@g(-WVYco&^6`EyBtFCT(`75rq;+mN|rE#nYgSGp;i*L zn)c1&Uc~yu?$Z1H_okONVRKEFB%`BV$7#r3u`xKk{?D3)D--eem~~6+r0)Os+SU{M z>6Vu!7hC$!rGycNo!M{Qr@$(%nPBrA*ZDY8ODssH74EslId!{oORAU&yh_=NnjV;g zbkZsZqU2-67IFcExV>5o)TloAt6HQ${9lT_DOrvjD**PZqSDZ3jTn$=d zs^a!p(M>8G%%0^Ge{A~*_*?pwpzIn14B9UnPdIjEg+^-4xD<{XD?HQ4RAm%GQ+Y*D zkE^9-jTY`ah*q2=<+rj;;{{hcf9X+0Ig92aa$L7yk-CzP944jhz1waW|1_-TKOsj9 zIFAlF>c!}hWpU7=s@3t&e>au2CRyIj+r9dJ8s4Hb%c=%2Y>45DHF%KlF&T;{M{3P; z5L`s!yXI#aQ_6DfrwSrC&r(X#i-{tesbS=(a@kCd#>&Q-Gk_MVD(=~GpVyCNia0vI z%4fjuifBf)p|}m@Q4W9`m>@|Kr2n|phVT6C;iR}6aE=D+)4_|Pf)#4L%AD+CRzIh* zsdh{%@WOhb2cfbUf3$f)(7u!)`z>0IBmWB6U&K$?mIMMLjI;Fxa=O0ZNI46wD*BYf z@9O(XL%%H14~SuvIex6o5@PbPM|_vLt~Ce@w6NpaIVQ8uQmm&G;$~oQY|+DsMA^8| zI{ae*B^h)%_W9TTLv#ePt#`|TRFMMzv^|o>IJxUx4lt#Bb2@wa(ro%MCWZaMg^#+<2nsAv zm%B}-5y;D1F6tZFDwEC{dbm3NU%%#Wz?fFDy;kRN-VLR`529qI#WJ828v|k ztuzs0oUb)nu~~gXY=xahp{`p>$=hKHDSp$-XV~(sD4MquL#c8Eg7w||28KBn6;|@C zBE6Z-GM$bqf6O?+5h95@zZ~*^?LtW6b}pxZTQXC}lx>v<*8=bVj55EGMA8R9VvFQS zz<4VNeX#u9O_AptZTV-|5HzT+LHecp`20e;rQQA<`3PFlcUgIC$KR3)`t)l7Ho3bm zA}3y;F!A=5K1~=_AJ}vv!-vjE*!K{j6IbaURrz8aKiEM8 zXuo|Gi9=}gMHtrIJ-i4oJZ9==>NgA`VV0%m%!DbM4Vy?@rB|r1n(#(Te|o@yLZ67O z*gFa-%hk0+nXODaEm(8G+51y^jW5Taqgd8|-d$u<%sP&(Q0*>2qnRcn3DF_C#>U|AUMV;;6Qaz!il@&bf)sH(mO%?Ve@c$zmiU-LK_94~Re zz3~6(w}L&wx-75@?d1of>OO9e(#%wjj`I`uNNDB+#0!-f!7+07+>A z$`5Zur*y_^Jo1ZW}{ypBpQ3i?jZ7l0^)%bn2UozUHwP={w!NXWt0y%M+^ zXoCLfFGwC(MG_t?ZyGII*TZprO$Mu~%t1s$-tFfbq(MIBN$W`$=EL8^*ZoTKVW0u{ z-JhE~tJ3CNQO}H zYTfUXuL!}C7!iJrBl?g_;#am>z?cT{UG&@tyqI6&M0hnVRmaDZ&|<6fo6h6z=c^Hr zOI*61nOq&=S)vjOIOs-6_2U?yTku^Bl+ce)7PgzGbxjb*!UDDu^nx({|!7 zryxGL)h@gs%B^?BlIdP9Vd404@Y*kIU7o)E{uSni$+OFG2n$7RYfSIvmubXpBm6+-%iP-Em9^aRWdI4IdU_F3kL`|KCd|1GN+8^c?@`P_cwN`L=*04_yg;lD8h zLLxvW#?#;H5q_%y_Wo>nAR7ruiFtqf;}Oy$Gp{R1On!f%G0yPo3$C{S-p5WqLgfZ` zDDwim<>hV5v}PPpl^RA!{bq8{>=wEE7%Y^D&dY!qbbpTKXeIZE)*VH zcjYG??Fph$g=b7ZdyS#jI3XuxD!_pvK+yTeq*_O1T3#6|RfB9b&Yhgdn_L^mRgk+| zvdP4D4@>g*g#7!Cb6f#9i+O>c=7bxK66b5mcF^lKbg$p?2C>*&;=&VfMwVgr@@#Q& zF#=?7{3zG8zL#FT);u^kxL^8stMeYA74<2?>C(4j*G||T*}4m6n?IE71k-;I$WhT0 zq8EVIr!Fk3x_|*R6vh+~>i1n}JHWkfq2s;Zpucx?btP6)d*PMgm;JBqv)2$5JQEQh zZs`D@RmOJ)%2>EYS06D+T+1zyJIWzyi~x8rX~{kKr~|2Y+Dy&N+79bR9tNLwO^aSl zg4Ubo@U`WH<@Rl%kAFazRT1aMHvVARM5U9Elc2D>ov^Pp&H&OqG<3@_bW0@kyNK}6 zDUu@tf7=SKL?8#`Z?EQUZ+ExcycbAq>o_n!!P!6*P40qg*UcP=ML~Lf3O>K%avbht zEwJ{Tgc7l+Txt*-uUsVheaOIuj2ij320iJ1$zQEb?-gBpUl;h8Q6UPw94&tpLVm3% zK!G#3fdO#iP;n{MRN@ppPw3n9f^=r|ZAO_DP*;X5%!`sQJ`Bw<$rVLzYl(89v*GRE&Rr0>I4 zJ^wB(5x*lpfeyz^&2 zumG&98|1%4Ccw7Mc+R}*qeBH2_I9EfHr__*mt5&k*4-m}_Y9(_IOSL~GBT~~jHAyI z?~W9OgOs!7yhG^1&peOa&|FTai3{`bVF4eD7!eRco^8d{Do((ov%BzjrdWZ=lOoWo zK})iHaCMX!ML-50+IviD|EjMN6UT!=}z6HhK0i zwlM3$s!r)fMengW1BVs7MeS0nB<|_E=K>E+sXOyyoYo68ng7-IX?h8~(2my?w>ebwZ1S(`f z&`$E+QF!2=mRCUfr-g7T9I`y3`c)N=e3zkZ%1r5dFKGd?QRj~VzgRL?nABf*eeFUn zW?&oD^1SPx{I=aO(ZtQF{E-xutt7HnwD$-m_Uq-+S_kMZD3vcj9^iMn-X*~Q5_A3U zNm$3#2Ew}yd?j(tEuOzqJVHyzVI0%5VV9kln24n4=xS0;BNLhhxcpf!iCx`Y zb%d3&h7G?HjQNr22v;7Ixv}GNh&4^0D8_OTrNhh&$tqcI%V_TyTI@w`~+` z>oydk4TlK*zKTL)ZSvxQDdP0>U~S^gO%!qp1+o|AH}9PdGRd~?aKAkLQM+0DZV?N{ z>%Ohdenj#RkE@!!fjzamc1#$Xzkgmt$X&+up&XWMgpA;w0Cs8b0%`DY*9U5>XhFTm ztgNhbMZwSILo6XMsXFpDvny>Y7}#I<`;*6(_ebFL&F9eJsf=RhkAMBvPVvX#YE;A>zqqC6X|KPPy3-^o zr4VQcRkTR(!zH-1zz6Wh`;%D7==K9#a79{ic{tzkF)_n&p4M4z(RZE}^&Bi&8s4i^ zs_=@P9UfI^AS-3Cld0p?`JYGTyI64^l^$svoah^5m2^a9>pFY4J<)(^57!*7nam1y zy;R#{rvIZ{{}*Jzc%`I**wQT|UZ}RcsY%$UF9B&aZfy7l6%E;m3e^xBO;v$pg@+l(y;BUJX?3#X@jmDwGhtu}_!zr;jEgM55 zp+NoE`cw3Z!itK=OvO<;v4Azz!^pd_^|pX#Cre>auq&`C&XgrAr92T4t;P81yWLt< zVpz^(Ylq%kYt2;O-bW;p!| z1KVR<>VCF34CH%(1y3lL{IU?GX^5Ja9nD3=FNDW>4hV_iVFSC2dJ!L)q0b5GzxT z|2`aNa4dL}F=%!Cf;S3lZjmh$I=j$;|6}0UMSsVHn_sHmmBTT{36hV-6U_L8MK65| zN!vk8BN?vlO{F!Xf58$#M3+Q!=D^~rr7q!BE2#8#Kx9;Nz_mcx7>U?Q^rCRyQ@M6h zxwm5{Jandr53Q8vf~+H}4-7=u9IF&ys>uK!x$mtBoFZf6<%W(@!Qzmv?@!W7Y7{a> zAvq!H*!aiK$exio+dDho^?Fjd4mzM#p<5W?I&=3CMqfGCDXC~POYJ!_#Jy7Z9Iaf- zaE8H{?Ka(Jd~`4zUJjAr|H1-9Y79NI#UQlkjY+Z|HNn;^e@=$Qh%>{R;lL}Pl>K?} zX4n+nzzW@Kll!*bZo*X{K!CtMJ0c)6#_vLCmof-$bf=`=B!#OSTbfy3dcCgcrJ(+e zysi);>3cgbZ~4bbw1_?4{pA`)UgT2nryxw=DctoO_dCg{Y1Z$?OFMT~) z5)Ly$?tFktJ)>~YxZJUbtpT{!=ONs*XTGq)Q>>Vz8gv(EQFSA2U5?ZLGl!a9md4?2 zFF>H8q~W-qQK64N`#_d&ab4@5^|E#4h}!ZXAJEr}4`5zHny`bcfsTM{u<~qLxciyW z(H0Pm;3}wZ2)n<_=(yd2+h?Zv`0j7Sbj-SR>_%m{|H-~hGYr)YI%a;O!RCKEL4vqM za&Zw}BQD@F3SQ2uuUvMAzR1nXqt3L1t0hYys;UGEN1+A=vrlH0@mE(sP7~r133lb4 z1|9Bs@&et8f{qrQknoB9kd${MI~aRLBKY7PLO#1kKinSHpstgY z;a6HvUdV)wgU_>JYa}~NX#6@5Ei*N$EH?gk_Ajg%!kJ{}M*)XeZzTISaAG(;4#ZDe z%=TZZbdE|GX8CQ?sc^sckXWU)4(*~q<-p))N6-IQ9e1xEg`=z$QS0dNi3GmH0Qa#rO~%nNqiJvp^QpL!oQLP! z8=_kVM0DvN%4Av{%0%mEluVJpSXn&YZh4) zjcD2;;`SKow54#IU)y4a&MXgTf2*gl-zAX9EO6dpvEYw{|M6M86TwP=6J^e&R6o z-UQT!#$q1p09Lock8kBOje=CHFjbx-buvl)EJUW_Kg(TRb4$}Ax6CnkJz`_nUJ9;@ zfhBD3g^`)rw;e^1w^l6O2zJO@UNW?W$PqTRv^1%Tt0T|Oj=H#2EIamd@n;56jW*rp zqM8O5xQ;z~tr0EIF;OzWbmtm_Wz8g4XnyVc5jk@;azrOxEWIZcO-rOb);p)Bbn3?r zhf*H3M)<8PgRs5NTdH4dDWn2^{_q_R#voOptyi)2e47BR7kMuV!HLp!$ztGw($PDr z7zAPBXuM5wrRz{Y%RXA8vwLFGRppP$pk!*vljlVU=rgjXlXoBD3cd`H;^L?tx$!?N zlMem%1q0ZM<#h*SGy~r(3M}Xv-AqZ~Jug53^ks+`s>)oq9X-YXJ!Z?9ZR=E{d$eHw z7;6^GcW1=eh9bPv{@{sS?DNSu>MQDueU7dy@}E_M?8CL@ODa-Kl`!W@C2d7 zg=Pk~n$6fFfA0UB1<0VHRu~nJ(n-@|lro+5@0>VzUO-NOTiY}nDii?r48kLmFPP9L z1jB|6Zh!u?vbNUJ_nH6H)DmiSe`l46T~$-B_-H}V07sLr;`H&HJiM(}5v z=#5D(590ttzjX&TD&|*2!^v_nJBMGB2;jpWaasWh7d5liRNd9w(T8mN>R3~xu&Zq; zDGuxh^;SU}L?{78rJcpK+f1a>v$llC44EeJsTE&!-CbQt1WEMO8k&tSD3u%B(tk$8 zPT)9w)LsPZ>!E~|X#S|)*I0y!2YSzXjf`H3v)<9U;lYbuN1$Ag60?L1^8G@uCMPG) zJ`wNvm8i!Ih%OrqJV;wOME1Ue1LtXdUz(cbaE%u8!$V#OUopUEZ^WK=vs5RGrrY;` zTHhuq8L@Eqs=4XmbE0|Ln#N{VT}?W0$M@|*f?x7N4(C73D-TRBT&N^A(<#8v!kWp4 ziIP9TC|PbAQs5eW#3DtFpfGVTV)4^-tie2K%8?Ot2nhJ|`|Nv4>3d%{UCp(xp&-Zg zzMsZjGLfXdZrhk9_x(jgRMb&UU2QGUi`AN#sLk{FZr}*q&q))~w@*h*mi_goj_}I@ zm%03Dz{}Ixx)I_ve~ z(CVlkck(cM@EO}?@lsW3fSkB&HGgxM37;rm%G-Pz;%k;9XFMuUkr+%%w6svRv~!X#3+tgay=}kUXXjtpb_2W zoqD#ss-N8b5!=ede{y@+rT+rCy)!+$JsOl-J_=QPzp&iuqR}?)#)n}QHt zKimBsE*vD|CF1V~GN7TY66a%V`)mh!q5WP#N-XsW7UJTpLN_<4>gdy59(RJwOCuHZ z_N~+Q=7s7fsdkIsu)gmQUSKc-fhogL%&TH6lsK_g{CdB8t;2p}0p=#(x`^}qvZMpJ zNGW39wuT!00n>X|5b$7Iq=J-DBdvQB{`%v9b3q05HvX@?2wAF#vP3-DuZ)_V969!) zn~WI0c>`W4cTrlc&^d;K=gk%P^Wae4!vC;vmhv#_7|Vfd=FYGIynlvvA0v zq(XqVv!v0wi%kL%-m`CQASx$6e!(-&8Y8rfT@`#pKD!<6I|vpUx0$76x-6Li`2l@E z=g*%y&fWS=RM^N~JUES9;Jc2t^)#+?iQP*I$jGnS*9$x)3?(kU$sO7j&18YkkimOH zgj=niaPtUvxL|W}pR^#QqX!H4*R<312q^M&%~MoM2Sstso>?p3C)_JXh>nR%lU7tV z?}Jw>D`k@YpCgu=%HLm?zYjbxU2Az!hxyQd9ccQ7Qi3@t^4o93dq070kJAZgfxI` zY}s?W)z@hBxK>@I?~e5o5y{fB$`@IJWP(uqo@ZqGlXYAGrSpbN_R#YM@ziV%$(E#8 z3pWf|e1IA%!wz7*w)$#nNnQjYBYRb<;HN&PJ*4$#XgH1`b2wSvRwN_6MS8EYi9>}U zP>w}RlBH4EYj|pt$<~)}@Mry*`J?*gttez273wxVv2G6a8o_-b{N5bYUP0Y@vh%43 zK3+I|CA@Y4-ODqeTr4Vl%YNv4+QRZrIq)H|`Iap^UZ!;|M_5G*GcVbhhKmU|EjbS_ zSUU8G@}sj6I(Lzd(q=EuAXgKwajDM>t7B?8m6es|xW7Ssx1WI<*dum!b~b&IgCwmQ zgNYI3Q%(BL4k3mY%@@~(bAl$&r#N%AShB6UoWD%KzZxy#xxKs>np03*Hh4&jTrh>{tyua z5{eD>P>v^&;Aaqkg?LH+M)Kz%$g^+$i`NFnDuW^=he_NG`?L_eL2{EsXipz7s$<#M6vqX54d%Rn5i{-;<^j* zIEu^_r7g_<)YeIS{OQ?xG)G1^Eilm&^l7;2C%{`ZDrTw$utye8dNYDj1S(hry1-Vo zT{-5`qHCq=q34s68^(KSM|rrety;Avf3~O5eq!x;S{o>m@9Bnu{h1@1{8BjEU-2No z;hl;J)S-fc>DwpPHxYygeuWDrlU}8aB->uOGaUh{R^t!%m|;;qEBq*|vOlL(7u~UA z-q7N2@g0aswpIuK9-Q3%F1AAp;-~+vID_EFS0Oj)b93JZZ@~S!lI>}IXnh#+NI<{mt@@A|eM5D`Y15LM zGyn3>XUZZy++b79)kZUDUpf}eM$i$ZBuGtMH|X-=T2}t$o5HQOflebcZs^j%LSZVZ zxT>&t>fH z$Y;k*X1Aq3X~)!(z}*>UszTN9c8Tl*Jf3V^|;u1u&L1m&wg-aL<)s?8q zkCrs2Ps$K=y;$>bOt}M_>_P5S`R!N!BR{^!LGX0fH|t4mDDYupQC3;5$w5k zMkCB;{__}gjs*vjm?D~YI?-Uf>l8eXOv4vC=j>|5GTXbJqJ$68!*lpfKL;U~`?a6k zYf~;^XRj^IEG^gO-k?xU+dn=1wy{{bNhx>hpmB(L?4miMMCMCFH|qN^s})|2q>oF?xuvfbV}W&l-O z?JDIsoidf?%`FdP$jQsXg% zylp^>?-llpB&2g)%2^Y9s!{$YJ@8vX|8r&XuHCG*z({{A$D!kkuY9$(j+=?4Z!pSm zdfEz5o|};kc7I0aoAFGEv?CI6Ebh*x);xNVPtBUH01)V=0^Mpwi9-($-tAQ%#2-i} z@-BR&5LE#v;=mpJkYTnQJl70j zu%T=0pt2LqMwY7hWsk?iDo^M{xkRp^!MsRk^WI!A`b8;obi>#? zp10U>hK^W_Wwz-JbaWX;ED-HH-c8He!n<7&{K_F?wm14?>F`hz4_n# z*TXfL1he6T(R}YKmd|JcD;_5POr##dnTK3nUB8Ksf4@PfKV$Rz0Ob}rci9K&@0jo- z>6?1#C6=xBtJRzF``dBrp!>VOx-ox{XAPe43}h)FiSr;<+AjqU+`8E=?;9K*MmgPg zZ*5t)iwV0OW#ga^IXt^L4&!y<;pVpZJIoQ<$7wmMaefA3OBuncz~}#C>n(ud+P1CX z-MEt=Ap}iuCqQtI;1b*=xLa@yBq6xF2Lizf?s5oDgL-4rI>`Xk08xSNT?xu6&2);ut9{q zz{6YytqvE<{tqSbZD+b|leS=JJsgi!*EC)n%wHtdHJj}+nKT}?-iV&WM14M}Wc5Fl z^8X078uED#!?yj1q91ktvcO_(l;<>C@szE;sUlTIig~Yj8LlsL4zlHWzJb|>h7icUNs@FBb6ies&Q%g&XeNA)c znn%ThJiXvGl^R~TqdsnjniXNG>c>#@i*M3C^P=o}icdSO zm!Q58&@pD?CCKAX0i4`SSWH-Kq0Y*o;wa{sJkiyhP6e)HbhgsdJrko^ve6hJq|FK_ zq}&Sb@4Ut?bgQ5ZOlTjB^S6ZzZgz>fBIX}9;ZanAMCB+1Q|1yk<^E@X=;70P@B?gY zYyykl-y*q@(XoTL9>`wd+UM-70#R0;9HIN8_DhxOH-y0C;19+mfj_8c>cI=CxQQJL9wu1H5 z&Ljil?R`hpP5N+tkBhOS*3;{~a{PI9^_F#tqo;Vmaeeo@<@ZH@^jTS17aTirtGI3_ z!D;VC){q4sI23GS`-`NQ^OJ)^K95SqBv-`FO~lUEz)H`w@OwP3o51z8xo#ERX#7{r z#pl#?_h~pLOZnH_j~``MA5C8ny46BtOnW{k=@=uiqBA~04)QahP0)POFB$qtSDO&& z?WgZ6Ki4dO&sCjMm%8ziPudip%@rAnY)(&Ush2Qo)J$eRu_JGpY&}7Ad%PdJnu2=+ zIBQPL8l;lh`4@?@KNXdOYI1n%jcjpNvn0PL7pdgV?y7&{(Jgvrm;NoE33&77E!JcO z#Q~`m8h7&O{3S^Y(;4rLNfSj@{Lpic*LENKn$NjHP+#VfhF6#>o6P-`V{bhcYFkfr z40Snl_j^#1%6-q3J=%#CZ-&?js|R~W z>gF!^m9uw{M~4n%wgz5(Z_AH9U0LLUr`#TYv%QB?WE}-w)z&o^HiRk6ENuSml>?vA zq?`r2xSYcyBy&U46Lx{5u{9xm_m=uMUlJ?qYm@O{U?BioeF7dA+qqGGHRTMMmYQ2m zL%yz(Qc;u{sgn_4?-m5G6~3TJ$#?j|M~M%~ljqsp;nDq}?(+4NIbsrdCSriGMn@Sq zk2ni#KHG`5Zn8OCwJhJXbbmyu-^%oEy=iJ|(w<(sg%2;AG9GKkX;s=RY7oi_>DfyX zDu;g{B6!5C70@-o%BQZC@NNvF5kKgj?Fk_L2{T+8FS+bzwxo|okEj5yq(AV;T9VDq zvkldoBzVmV%%zBWLkzWA!Y4OowB07P9*ZFGmf2HpzzXH3Z3| z=^ZKXAy1|6=OrR6N})y8yN+5y6Y;5QsET>!&8he>x>Q``_S3(_ghY`6dTJ)dzr?Vf zD$xP&Bf8(d>F2tXiS=}*DBf&*weTy-j%3b>MM0S61+BvOut&(!&lHIF)Yq;O0d8_vQ0*+Y3|~U zFkxqD@D?yuHHd(M5JnnqGHzOr(#Lil?~~)vm%K`udYF?!-LQGT?He-Ahl5shhs(2v z(`}PrOM;n_qH7bXhm8lP@gu&Jww;@0$5mAH&gkEXwuc&j`yle^hi!)vKxex=AcS5u zP0wj!R)Rx3Y7mxTN^6yl1=G5|bHAeA(y8=@WEj*+%B2 z`V=KPuD61bsnRSokG7IyE4`=%b_wU?usM{QEF8BzDbauBmtE|BP&3tBdKTen9r>&K z7X4vm_%=mMwPXp=!@e68yOw&`$hwUaJ4O~eE_LwT8!)^-LCE}mCs}t@{^tlv2erFt z$hv9pKT*2x6T1z5c+_rRcaxHJmBQh>BPVwHTI}?6XT018Y#V~Dq8oViqP_ng68}F4 zJ8Hz{7s;)>hx_vT^5x6L<+j7^qq}>)hm&E-d*n5#`vZ>K&9=*}D5d+~45If{4_8Y5 zJLUJobn}M~H^mS8VmGr7=jfsrvr27ugk9=I3wW5}?V8wq&%@IW^X<$XAxv2LUBN?_{{?c^&3?i1{YKRmM=L>`IpZla7Vqnv z5#Om@x3q)n7^l$<>^QwZwAqvtY z1_3>uQMs_q_?R=n*nxGxO4@(qu-n-k(}V2O+#!C!;c>;aEC7-4-;eUSZ@Xpj|KoqP ze1CB={7k0pJYo5=ru??MW76<;)gQEOU_VH3eMjS+mLkgYnosouu}L-jscmcXxe@ow ztzzZu8C>k)?-vyu#xg-^yM)UtmY!JuNrcw{ALg&uF(EfATqi@=VO~LM`=m4+3UIgI z_TEeA2A=2~n>5fSmAI(AP*53u)i>1>_mF+y{+@cr^0!QpK1@QeDe2*tCtr1Uy1V}0 zTPjQ235(d>xY(j$4#gQ_g8b3LUE4$5{nWD8?d2akS?`mLzUBLQ|C^(`mNpP!`mA1V z>pHZYCEbr1UMCn{B~aasQr)@D-@V`ERa$fmWUTImb?e|x-c_h;25CbpFJhSmH`PBb z!j47^vSkHjh{LY8oiKwm+&0rW%1<^EG7Xt6Fct*dBT1Sf1uJiEI2h@*0(ZU`-YwnS z-(&kfbRD)>!0pfXYt#>;-@i-g00y+-`|y3|>x9?LR~%azl{CYd7Q>{DPp#f@({sB| zK6OrD8@)MSxBa!*Rq@L`PH&7a+D`LG1udR8&3P`id)(q;R%GDDUAuo>jBmp)ZR?Ys zn5LEWo$o#VL;LW3LffULAFQC3 zge(bpH-tR#=gu9|W%*rA+Y{SX>q+njxuP(38OfE3`ml8SNF6=xB3j{KF91pfI@9+3 zZ;Kz!xI+HwA=Vb zf}^*Jc_px?Hp72t@;EGyo*h4@6h_H*Uw-|B-5uZ|t>jLrB?M@#W$}<4bDa}WXo0zq zB$rGJK-6N>R<}3=$@y>z$^9bLAOV046c=v^k%(ZoC)l7jB-vwWu-fTPQ#Ikrp6*_> zbCtH^;e5Vse`WEWB0Ihozs?Sg;76=kRr-oE%bhc0LsJ^tH1C5V+?9u;$KXdNAFLM* zXge0W)$DOU-_}$aKS}YfI#zLR+46wzj6ZCP-G*e{!u=1k?!oeWN7i-&b!fd=SzB9o z@ZEP=erP%JxmFD>)k){Xqs0jtC$??X!48BP!Lv7_LZLLMY2{OaM)2ENVKl-zBlrdt zX9hG%#P^!S?}WkcWcZ;0gtLY>-ADIJd~IikUFU0r;9tFId+-*!J7>VhYQs&lK&1!& z9QTYKT^htZ;A-?XsFq65lQ>zOi`ly9KtxAJ=pLO-E34w!oOU3gcH7k>f7>NU=|#=# z`}u=&rH37{yT?y18-{%kU8t-Nj$C)uXt{v^3cOH*Z8Q{kN2o8qcab%H%Yz^#()%Dj zrm45~uQSjSp(Uu{wKZPUbC28VM>>0egk z>Z{9{v$wp+&#eB4@kz89BSly4;kxbIv-*8uK|`wU;r6q@eno-;LsxuW2VD!W>iJpB zG?!&`!0h&Lc!QvOvkRPef5c9%M9oW=H;-EIJ7L;^A>hK|@M;!<#Ziwmx%bBAW6LpU z<0ZrTBAKJiNc8W^qD6+(#-hjwv@Eo-+W+ol#MY#67Tq5P!&k1`@2_4z zI=XC}da8?kUUS|xFv>1y%h!X|${Xh;U=CrY5sfv$i%jpDs|F;qmKF z@e@m7QnrNJyy`x;O(7C4U|7*49~g8Qn)Qq+n(oCc-@64E+gtF=c4%x^WYe9UzM3{@ z`Xd3R?p$p5`CRmiWFzR&oRya)KwdnnHpRQb>r)-0D%xP=><#v36V806FU6h?BP*c> zPc*Ej@Oelk##;ZSF56&eCmlv*e*87Tax?CEU!d%Qh+OKF@!lW0ysL?M&tf%j{g$|S zhu{6Zf0U{Ib5RB(&~vz5I8BV#P~w+I9l>PqS!&Onxi@pQxEX_Z!lF4w^2(*#!H$7` zFiyn=38O@_C%?JVys6KscXP!8 z#cGc+ZGqt;??2I7%9?p zg|vHoC`SEM`tT=$Je-B*mH?sY-8aSwqDKtLng>#-8XMyUfKQWxsb_?t^Fd{bS^NMl z3E7jd1S9-f-r@TWVnB4kTF6NVvXVaDh1@o0HvGd>X7dH%0%2J^Wup8qp?WPo-(Xsj zflCECTwo8YRa%@*;%AJRyp32xvn#vC%`^`0<||x@Gf7&O$P8##t!+X?qI>(?{Wj5r z8eOX0X*Xeh& zEK8`x_*quJnwWWOHq>Td*6zYc#yp2)S*?PXKedm&hVGH-2AUL{p? zj`iL>uTT*wyG=(db6HMMUg7u>6R_nFrW@i0HdAI(V(oZ=jVgu2Eec@Fvbr`n(r^f{ z>iWW!B)&n=Ym-;Pu3W%lHq5@E&#vIe5MdWZX`x#s#YK~?mrg*WMH4KMAXl>gBCqo3 zJsGhK&z?4N$(M&jCr%x!4cO}22NiV#nkdxX`JR0|8`38zn1vr3-bkzR#{k)jk7~(` zi*$W2WJ&zHj+-ecB;kL3)9^L=F|atV;r``=_aJS@wcg<3FpZn`xwE#_WXY?U%% zsc3kI(ZQucM3TmT1{4y!P}14S55BIRsAdVr3%{QMtibU= z%G8oO!>g1TT`krWh}pWGOun8ixjsF0(zg!*Z#dJo|xis0AxjG7Uq z;(Tn2mev8&A^!Vp+W0($4jlI|Gc{J5}CAesR1U5mTdZIh7$EaTjg1|zE>fWh0*K58^#ais><0v2c6r#iXz>+K7pUg`bU{xj1yE}(2<@hZY;^@vT%}$q{NBxuI zHYub;$(-jfO;T_b6UdK6&DPH@ zgYVu7a;1M%`7y|?jtCQV-r;BeB~0{D;R_El!i8GRx?y;fAG29q>t3CxhD~kO5hyj? za^;!RZfqExh~|0unviPPS&2!rzbtz*5H`y(r&~3>B>bM+((jf{*e9Tv1fcC{4jPqR z;1E7C*seqoI7-einp4~yyuBqz`;2rM#3a(3>@EaouXXqH#QvClIUs|~dE~Q|*%HYG zT^Rt+H-pzEx+M*>H<(J-5Sl30#`LB3(Wq9&19@uPA&T?3fZP->B)ETZ_wkBz@3puL zK?`nf&e4XxRKh^dYT*i3c}EyF#z3#;#Q@WRf7{chx!BF0Iv>V$bZ^ojM6VAA6eU^T zvbwxu*;=tOtU^F5gI}KS5GC2jCF7sV7c5TXL2pzT>D@0+@7Vz*%>P?s%3nYBtb2lM z)A`D|no95_4kv8t`v`39W>nBnQL##8KF^qo^|y2wO6E@lljJOD1!&la9fwwniATo62@ zC!nGytCKN)(nvgOu?xqgZaR`DC0}>gBk&7Zu(J?EnL7PJ{Wg@=xK>pk=a^r+8=YMk0&rr`W1^!Ab)2H6gV4{x`IlF8l}K`~(qBvx8A4c3Pb#m`=*p zVx{i~a|vgnX$RcI$T1jYsJa60pQ~_;2i}at+vv@ z8+@&J;&T!k=KaH&AiQX5(2DW#d`r+LyZy^tJJoGi6yO{d%ERT0D|$|&pKJlJWs=Rh zSOs>x8E^)w7VL_y-u#%|Zs;<`?zSe45lMN>JI#a6+$RB^4{q|VkTj4~>w7+h^gH@_ zVNb0h4L(!x5G?jT?VGowYtcF?9)fZcoX@}gIA0y?P&~kQz<++|20!NA?fuAHBW-?= zCDXpQq0hnwCsIB?Wg^Auk9=1GnRIQ+A`}$zeg>8lSKx>z%>tc15ad%eyGAZ{h{zEP z=zygXft3dFugSq*mLcFSj-^hmOMD#Rd=s-O3W=MQDaWKX`L~mq-Rj{%<8UN6L8E-;JxZ{X+-W7xPi;f zD*`8*I9UgOkm-=y<6&DIvR?1&-G3jSAem8yX`#ViAze4c>1b13+z zU9}H`F_24xudlLM9^zcxbq34!2&r#F8(J-hRHXK%+12iR_VB(>B=ZTmdo<}yC!bh8 z-x5mu#d2K_KD_F}X0oY7+nzK4rtNu-pUGkY`0!tGdqy<=$UNdY(R0Q%wX5y3$>Xz= zt!l1TX3fM&Y$>GZEn~rGSM04q84?$u%|7h23(zaNQPJcGejK1sxWJZZHvv88MSejg z?8B*m30-`@h)!U&PJR5@JDY;S8HM~U%TYs`*YkCzI=R7|T>P`x!*4=mPF5MRSfAH! zs4eXZ7%;r?L@4ci5(;VD5&9ZR{kodbLaw zHEr1p0Sy2B>2_fjUWXrGnT|mTE_ud45I=pn;rwm$)!Di7bnYie z84_#)81Hfyuvv`~;X9W#x1^?H{#JRIxKs;4-6};HwpQGErHEzVNXR zCiM@VtywxKX#l;k$-N{%3uE<9)ON=GCOY}lV$?R)u(1iE9H=MYtw6TYZOsLFU&fm7 z$P7|+G=r10ay8C_ciSxc6>7?swl+2iCVjEhlq$VfJ?Yb=2$?*_R? zFkd9QW#hS}an+$gU`mo?;*5sWM8)Yan+I0`3)0(I0D1mJ9mX#hI%@yT zs_QZdo58on{RJFtbAgD1dGqDn^2og!H6bknhOy(pw6CMOcA?+D^E0|dArs*reb=mMJOjBJ>b&%(S6vSIppa= zl_e%Xh`Q~}?v3o3*lwG;2$;q(R+;$wqIfdDhkwRE-RhY;YsRJhR0UnOH0RiAU)HHE$VagOC^pA{|XgG(rqoDIF zPmZR(SN>e6T}7*?e}*+=iu#Stpn<)bDnT{z2m(>e{W#E5Yx16)nvQIvwHQg*F^b%d zW$DQhWQNIQ9!rw@^rnK3)wG&amfk@0S%@f1p`5rgEDP$0#n9dyNuWro!yiw6tSA9ugeax-A zmV#M*xiw#B^f7$j-{0|68cOQyvDiU8C)QZb1X;0Yl`?#I#$FC`QG33tS@_Ap=ApF6Sizz`}XXqt(>Ck7tYEZ4haJexI_@XZe!|I)K}gi6av4SM#P)5-{jkQ1})* zDfd;brEEo}=O?SVRE0zpD`G2i6iz!n{3RciXZ{NhPLI@7L)rW2d))}>xQp#0y3%;U ztuFk?g$mDo7^VeZbQdSaqf^Zhs$eq>J=()`dcGQe0V5{@^W-8BivNCPPvh^T*+bNv zf9DQ1=P)>hJ?ZZl=|p!IODUiok(-moMAN*&srY?1b@33Vrm9K6Wya8-veQkDg1&|+ zR7YM3Df1m`bRrd+;`(~%Yt_RrMf1Zj%S+e6Z;;(^r2`ygr`uf58f=8wy;!9$L$reO zdFKymK=EwVsG;5mE@1q8bn>u&5wcN&6T&ETZ@S%I^)0qNr+Isso{MxxSq?*@vf#s` zXmaKToOm3&4>TQpoZ2bCpi1TEctAdiot;u-JL6T(7KKOO_`8+0xnX>svR_`ZSAc8UhXHpXyau$Ih5fy@ck zPlR|6%pZEx#MJ`wy#ie^bF+CF&hax^tPmgVFfaD=V zF~X}RTEl&6wdezT`6Xd+l*Q$>c4LPgpNPk2C113omIA3^$clA0j7!WLA|B1fR?}kU z+#O%!>&L$n#6oM%a@MQD?BW77)9ZfJ z;-;u3*4ccVHif=1(=-Jque^Bi^*6wL0sgqTWD|$k`f=+pzQDqp)aWAhMJm47CE0Bg z_c5+WSPiB1Q1s|fm;>RcC)>$l` z^VTIxVd@;OCd&^Q$%;IO~JZ8@1Y zWV}=O2o$4$rhOpO@W7k|YD&0!xL6Ty4z$}3MW(v9W9GcOOYE+%#wjEXX&e+&AW)G7 zK)sK>mUFL#lY3qss8ynT{@50E3?Mt?@7N`K98ta7WJ%^}D0B&hSCdpX9|b;*8j}!` z#c=AMcDg}X8y@27Mj-H92aK5*tRM&>?;m|e6g3$GWCU;o)RjEY&U@Bq zLcRAVPVjR@pb=&in<4Pd9GtT9xX~AIVN1_el2CA&xI zmM}}6su?|iMAw#G_QjXtEsim_z;Sn%!jY<@{+EH~(IjNRgiX;`e>xGlJwV!sr@w3Zl!%DvC-0rWSh>0;HlidZ zFe(7TE6oIyxd;3C2yXx zK-%L?b(aqSBjg@Bm01sTqK`lHgr#{3D*0anWuIA|4~qsdPEARZ0%nP}xdzU-(RswG zjD2+TwE1>c#093RNMHedk%W`cXPZ{5#12wz%aC`Kreti)S%iI={ncv5n~wgsDrcQl&{Y3@s6 zz@(;q+r0RoY5ehvx$Y&tnxKHz42BkYfU283m#@VaM&@wMundWAyAsV3t&Q>}2Shz$ zw)BTGGXNfzruZ=K&yvm+w#08}c#AUJOs%C3r2%af1#pgWX;iNd-qV)_7Xuc`E zjabfdnYAIivUdB672-(3sjsh}U}%QPG=S6Ya#0LDmlaLoj__1W8Ke#%O@;6CLO46> z4l_lP9&J0*gbpx;R9mf?W4G6)Ri~T~yp_+7uO$N#Z5wB7Ichh(XSfL1Vm%wC59*wW z!i4r#4w2b>U$+eR&@}tdKzad*Vv8UHJ@JBf_o+>%p_$RXS*p2TLgV9*X@9L^qts%HMUg)HF=$Gpd6uvYlL<+C46JZPl>VFAy8-_2 z@TgC}%%0j%BGp;nYavAwp8t4`@{En|vwWXKFqN3)MhBhA`yN9BhDwp|==jQZ^~jG( zvfSvgc$FAu^c1mq4buXlgjl>u#Y`_ z>86#Y?~5=)Q%_S8f;W|Bj~$KlJ}247eO;-*-3Y-oE7R01)>Lx${Ky9J8i*7q8;lYu zq9BQ;2gWaamp7-|hCs~jAgtgZ(saAa*Dt#8B7V^p3E-X`YM7S++(?sBnoI%n4npA{ z;cIj&c!R&e=%GWFL;JKS9F#g3`?x)QYj&}D4td_TK816VqG{ZmSwl-Xm7d|m9_@H# z^t^*Csz{`|^4D+RCJ((_OXH1sQwuZm z@BaAHJxpfyAfud94wzps)$~+q{H*e`5CbL?9dvcr^jH|l4dkT=bv-3Aw}*U+s2Z*kYsjYhb))OlMC^ullX_GTF+ z+I@D}dx#|C;@1N4RVDVh2Zyl)mzO3=fS$0gDLp3yP>nD# zKcKdgL6-n3oCgPcpCPwCEnI(22Z?mrLFaqZ$v057YUb^n&xK3JUu;Jwi}smNuznF8 zzUTKB7ScN}n<&hXUf_*{YQx!`^OQk}eg{m&yTVg!Mi?8^#UpFb!D^IBWXt~djWv-G zc$0jAJm_*|0#6_cb7zS`wr(IM9NAY~Y_fP6Bd(oADHbN&J3E`XuqGA*e5>@ez$kQ^ zTs2vg*)#k8cxkV(MZIMRrRh0t$Ya^QTsn%X6z9hJ%hy@xj%Q0v&FNPi+|3V2?ds>V z6!UDryrbJ{pNXD5upw;m^ODD{jC902u0{TRh&-Vu9eVU4l`RJ>HdfU+CS6toiKan@ zRre}SVa`5oHr)c?!qV9<{Ij;&8BFCLx@NWmH++>pWNiTXi=Xn@me~FgvRM%y+(=j| zDdh8DzjI3T59{WndGz*Ag;51zR((iL16E^$iL^C9v=%m+vAlu3R!SB?MFrDL{R-}3 zh~DkL1kV4|IdM3L4Z!fBJd<;f?+c@U#6=FWJ<`Dr_+bM=j?V!FVI zSf(R4n-trA=|cHMcgy$jaXvu!wlmBBh|8f$6jU(bN0)Gm;b`uF(~TI5%|&)4%z&*~ zm)6EcBu-V*-gnQDdy)7EYgLgT^5%JVa`XA7<9V>`cKX?TogAyCj4`xmZ#2#$Hx70~ zJ$(ZtqslPo`5#>+TitWy7lWa}pMnBl2}Oi-5#INo*55DO6p=2iIx$l1uVhjj%_tHW zEvtXyccQURXKIMoWfP^2)o^zs_ywNZoT-;-jn)kjKu2g&cOT$tZ2uyL|BD}Ta1IAU z=b3p+F#f4J|D)b%6nz8Pk=nYklvseAE1Rdsw70e}J9b}>B3g~38T-Hp3iU`%wc*jL z;?eJTlDV^D;eJtZ?2#saI7htnzG^z5tvuTr%&ZGWas0C*=6JQ=HMAu)KMbh{y+C*6 z_in9?Na9uUbGgCzV)ssf?hO1wEZHpySn@yrbWnyf7a#vUkXF(Y)F__T;#18Ap@Yqu zh{RY0GGO-2#Ec^;cZzT3A_RP<*Wj=$-wG+!o?Sh^D(FgZ~e_6dq1dF0^7&$lQ0BR zJwN+IsEqO41A6u0gGYyv?5;D z9#xA-Gc6bLNlD4>Fg&9;k5_iG@%Hq*Y0x-6&}yCG4hZ{QzY*|u12jcdQ{ji!L%@bt zwXcyXQgo*6SSMR46gPxct_(smDsR0*4-I{ff~yyfSLn>HOo^OZqn{4c@?^zoRk}`L zC+RY^;|HZ){B|=;=PD?;do309`@^;_wz>}HBQohbD>E6dQC<-wAhRMTw@(xsnGEDu z&F;1a%l)sI{@+Dg65=fP28Ol%&b%*n*)taPop4 z3$y!Ihg;ISqTFn}lU&SI5%uzlp)Eb%R)9@qF^O|tS!PwWeYbb zfoPRyxEewsn?+s)sZgTk0unlzd@l>k$Cy*-MMBRp;s*eE>Par$c(RW?LXq9}w|-V% zIq5m671U&iigZ>DKJndpY5cF|)PMG<0C@9%Bj(I6jx=7#JWGm|Arr<&n(_N^dCcW> zn(JQeKZ5_#Y=>Cd@YtAE9i5_3++1p1v>q}K*_{9G2?C-IVBPK~dAj!prHucpD zI|Y%UNM$~%(U~7Py4sv+v9q-+*}|L_5>FM|VqF0BoetoXd#SC9Kh_-&W_dFs?qo-YXI!=!P}Zr?^YZgOlE-@0a&WxCE!6`t*6$n#fC)g-f}?=uKYdEgf6nKL;M7|@jUY|o-Or}1eV&59KRD1A)QVNbn6#>yrXjjQ8 z4(iCGMx3#)BZo_7N_6zvH($%u7-;MsGV`r>X}RVH z9RG4(nicgu*(j}B@&U~l^TA4%^w*$9q<7#3x36nzMyi-^nSl!Fi%d5oXBTG-S8d_6 z3-?*n9Hgoo_?@vmoyCnyv7E$~sLUf$e5Ru z;R4ynrZw(FtI=~JFK#l_UiRf7EBEP-xbqgZhB;d+;6cPWsU;Rgb=v&94onWdT66Y% z6?8b`1%jWrr9amw1taTs3)m>l0dL+^G{}OxDYylkF@Y=Qbkr`4&ujP=0YZP3dAbbG zkY}7Rza@^a|8_EP0(GUY33S@{!fz$mbRfzw@*gD?I230irN490k;DRVn&*-Hg6!>;uWH>9R ziL{t%i~Ju#gVnK{yoniX<4*Wd8BTU^>;jRe14SA)P{mSp}WCn!q1NuF8>xwrBu{oP}kl5Y#Ny0xYl6%pvq2Q9Q|ALSt27xA%rKTLgqDDuX$Uz zbfP)>3X_~m;uZmHQPNp%prrNqsHJeyn#V*C?KG0~UDE0c241=8)?p~^wO0FmkEpB( zacRDr6u?<^P^&_9X<19}nKBDew**a*%)+{rsVnkr- z{QrH``~g%kA_|EPqLA$5`cEiwy6NW!#OlXRmBnV?ci%uMqfC&!7684@X2*0sS0|_V zg9<6xa+_~+>VRqBZtd(NNDvpm+o|K8z?;0C`i)dPHI_OUS=ur)=EJCwIZT5WkUb1> zZmjFBwg2;Zhsth~UpaRV5X~^8LWq?n*(r8Fp#5>Ze^6Bi>dTZp$wLG&xyu z8TRN@^lZV`+k@u7;G#%_chTs8OS#sgyf|$#%ZXP8xoZhpty&9@UzdID7)h$>a+h12$pnm20Gr!|D zQrG~Ri224}<~Cjj_DNC>`?lq6-@w+(V-MkvMxN-!PA`%h7^~V=qSV;X=ihq2hss^c z7m|KYd^SEQ-zzV>^jaY#)?3v~>ev($H8{4gUFYNJ8^-CFx@RT9Bqczg0Vqn@V%K=hyV_cV#KSV>9A>L+#MrHB5)~*4;POUsVDcXErddG1JxetS(E|Ykozjp1p;hWbV1MW!utl{0`HmUW zMvUcrbLjN0S2cQP1U3ztL(t%_U(RZkhUKt0x_^A1AJ`#&zNGhj)ioij0Jg5Q~}^4x|s7xJscwfaV?A zp)*PGyD3CRerq+w+pu<&u@xsaI!V!u1G@6K_+jo5q|fmK0h@;Vm3v>|R)Ow>@1ER9 zY8PwFq^rReft}y<{tgSGxM~i-L^MHMgO>K6oVM)AU{iN~%WeGs$ydfxL82IUcYQW) z(+GvK=e4fmo1OJ*5~lNtI>j0?qrgMnh-!%TRKE%q^Bdcc#}}$TfO7#k_c_46Cc`5Up2RwYH2XR2&M>#*fUxp<={5{cku;7}4@B|rOa`|epuOE|w=ao)?o>(5ee&mfPw z_b$>oLG0U7HDI+n??aaN3(sJ=$r~YJuxd`mVDf6_{;)JfY5bZ#@N>V50(RY z%_QGitL?6+@LTP6SkHN#8+EaG@ez$|miHB&+2A+S3kigRiXS3ejVKYD%JfgIW+80f z`EDY!Uu~^e9G>39&GSUd7B!j$nN4FMhpm?*&+H&I0dshoRoSV><4vPysWF5|veqMH zgBKDJrHyNFMh%anM*ugA017#Q5tlJ?y9lztu-^G^hUa9clu!0%`_HOaIGd=zGUSvhsyhtaSp>QQph18M8v=7h%OkzC^mm5G@G z6$>SWIs8+Ngsh^7Hr3i!V1R-xS45ot&*g8EGx8v}@PzowZ_y)?uW{&U5VM{C`6zHs2I z>x)s>)@s0OPI>_Iv^64Pv?}OuSMJ((oE+10C;VeG!_`=9j!aGTZu(0cyyC+EM#Jpo z)JD7E75!PUMxqkRXG`~O(~RfR>rN}5H)TeYk%|T^>n|-igI!3(FeDD%rnLof*qk9~ zYg0G<;kSS6Uj_f+0xSFEsR^D-ugbc#_-gSsx%Oi$8pg;;SHvz8rszjbm!6UW0ddR> z3anzoNSKlpYsVraV5n1cDxyG6>sK??83CD|5?5TbHUaw2yyuKka(zG2DlvP1>)}XB zav9rqESPV|Cm}n^#MPK1OGi&L4J4cg7cwweE-J0(+zn$wYms7|?HsdsW#O~AmFgGM z_AvY#87f6T(OxG&TY;>}U)9U!W+dU7%$RQC_G9R$)NSMROo5M7v`777?)JrC*a?&H zD(Sfv{9`T_{11=u77}dHg!{?SVJ`VfB_?jSs|{PqD>*di2Qf^eGRlBd!Ig6dJ;PvV zM`-)fO8`ADF1CwAp2Vf%%g+Zl(c?MY5HR!I4dL9jkZ&Xy75D z0DqMb=ja>YV_(LkH;u%zB6^o9dT+N44{^Nwc5{2#5Ofn2+q$SLl)?S%4Zl8I;s{NM z%*_^+j&AnR*zbD`Wx(@VLYXgH&dRlDXDL<4QmM`N@6?$Qc3t)TFZB^J*wkYV{zOs< z1x@H@NYo16O(!_P{r19)9hE38?|tJmH_$95T;1U9&6&aw%Le(R{0|*jomS$weFwfw z^wt7}9t>!Ns!H4)Z*3OBx<6QlLHY(yo$X(;N5b|TYXI|@bnAM4o41Soiz7XEL+mX& zJ`^=nFK%F44Esj-7*y+p_+K;Fh#Dr%M3y}GUD`-}Y4J4>X1vHq)u- zQ;-->U%rmabzAhc9fm4K5sDNYl0csN^0zdY2z~u4B8*%7g^?PrB(F+9KbA<$lOqLz z(fnEuvDdy)_OYKQTPkH5`kK{uzc=CgVOB;JH4^U3EPhm>8@T`{!yAQW6D}c#;+y29 z4NL7epjs!O-{;;XTLgt-za6MA+<5lX_o=UveP@hKu7KUSAH^=Z!5R#%? zhxyG@#1^JfF)NCYFG7ioYNJ5TaHX$~$fK6f!nNqWv0zU5LnkTXS}ZhMltn$LgzW(? z##uWoHxYYqGs3+x{f8H-_|FY2;t|$cm6}w2O94Wl{j;7Iz%N5LHd^_KJrT7+xHHy`3fO+Rn3?A!wnh(6(TC z=Kq@pLObiRz8DwX*KE!wQQ*ORxlo^BvjyO^LC4=D*D zEn4pc+D&77C*%c~5`4cTP5@`G3*~Dl)~RvfPrjzWDh$yT3HrRuH79coPUy3*-2n{6 z@3ew!!A7oMPn>04aw?#LHMm*}Tzn!r?@ryckF4%Sj)ID4Fq^yM+%&;CkcQ7}%aWls z*o|peycZk@F{OraW}%G-fk(gw=ffD_(q**NCB{p$rT_mw6ZUttuT}vGaK=~%*OhDW z&h*d2VJ;8p#GjfIubd$VXBQe4<@?l*XA@zEb@x)(@S% zFQ3J~q9g}L5bJZX|LR#n3wS5nut<}5IAIciy_*>ZekjMzP98HJPbS!c;>oQ4(*M`p zmxn|3{(q|vN+~2uWUW;8Y>|)}lr=lUATh+C3?_To3fZ%cEo2)@_MIkV9s4%c5VG&P z;kl>!eV^a;T)*f0yRPTCo`0VC!#U?Z$IShH->>&_pL6c_OG>R72P9iKC#Ksz>#q5w zLYL@5^5n6zMlj-w5Esc}Tph_`c*r+*I%lrj20rnltxfL5eC8hN%k}D!q;p0EX_3>{ zuO^z2Kv?RuJRbbu8y=W`r9M%TkqmEUA1Ix0@z~ zE~RKCh3|K+2Eq4hS#Gq1e|z9K+afhE`aYaJO7Ij#vjYhiD&?j^WLVo4#W_cdRn5CL zch==o7#^}mUK5S08dorRE$-5Gqh%#cU5a?G=RUL8Ds2pL4rGGN{d0r%_p*VaQ=9z9 z1y=%5DA{Z9X`!R_(>sO1!LOnjbPmZxu8-{VjZMFTnTL&4F!~uyPq8sNfH(6MG1{o~ zXic&=YmFF=VupE&H{nAzJ+PcURdD=FHzF#)tg^ ze^=sNt$#fo(I9CC?zmI?RgpX$lc*!$+CW~z9kE$U7LLvh*1u1 zt-1PEC!g*`n^Xj3PW*>C1YyUkb@ z*uu5q>xHY=S?wn})_j%!I05c^rjl%a>30<+kHL`s9#Cc-pa10rIO0OHF)|iOses_= z$Gdq}-PtxTT%BRYe4jG0U)_GFGr0-W2e{u})}}94%k@L9Wl`EPUil%_s!P&8?s2ov zjj8nYOH~KMe$l6aUE*AqhEkIkOGHWZEREE5XG^lNDM zQmDpyi@2iw>Fqm^z}_fmLUS8?U(CQSI|+dMaTK&qG>(KVs;^K^|PGn5E$G{ zZJ&~Cey74V{r0mB_cP6Vo9s~@op1f(TqafJh1ht&pmv6+jGhPM3`|z_&*t|+#QnF< z48MJERkHV7i6?l>PIsOxKsz#MJ@zmidr&HyUVk-(EnN|R``UZkZ&C1Mc(Ow?#?h-c zr-@?~Rn4S1pi>Dov@2kLiFM`j)p$|R!A(>5<7skM{DL4F`oPi8)hiMX&r(=u)k{g8 z4~)#3KW(Y1Hb(N~bRf1v>QnZmfS@H!T)0^uiFl2|^&-7hs{^Zw()&z8Gdjv`J#=46ef{0={~?-5Z7W-QW_cJ~303NJ4>WEc&S&!QlcFBP2N zU3%il)0->5tyF)oLe{9nr(<;c^Nag)=7sJqhZez&N%oO_MHE{&>m9YqQjfy9hkW|~ z9R2X=jqHE8C~L<|(;q;2De7`E*K6U-k9PyPDY7$mYCrAMU&6g>#oyQB${eeke1Jcl zbzRf)%4w^A`U1a*IW?}^!xa3Z)RQGIR@@gH3_9uRd*uB(;gnS6rRtdodlVgl|BM$d zH5lL!0Mwp+=>CG`mwl%H)U0$0G=BxnZ}!7@{_BO02^gbFoiQm6Li_Q)_SiL}=wn&F zu=c}G+2-eM(xOGqksK~=aSId{)xkZ>3q1-$F4BlA2R%JU(sbdg#FDvcsma&^^w%Qc zM)m-Sqvt~k$~=ah!c*ZFE9uJ~&AZ%wD^fDnPW!$v7G>>MwHs8SBK1^{DHcLSd_h|``ES#vBhT0S(w9LN=avhmsmT7la$^gZV76Uv<3MfBn3uUO zll*;y>)rKl^o2q$+1gtaRiBQd^J``8e)LnYM*bgNW{WYB;0w|#>JpgYl*u1L&%RPf zjI?b(@_dI>><`s)nkMh^!eGn=w2Q584<*(xw_UH1JL$Rk^b6&Km;Web+&FEkGxB4l zgQiLH4iSzk@bSk1WQUe9(olP)5x=+fxNg%`!6>6v1v>m=dPIcYYxl%c!P!JE1OCi?jkE3#5Zl(Ks2pmnm333T;tpY-4 zEu1Xo`CS9+)9wF(&bi#$aZmgCgRivq8yg#+3^I4P4@|?Ogz&j~0*VCBR66Fi+vMJr zD~(8` zI4{_2UB4?#vU2f@t_9qcz@6^CR{wD{)Ba{fJTFG&6v+fLqt)8hN44$R5Xp0I$^F|J zxR#_yxcIXuvzg6f!tK6f56=IbM(rYgf#u8!#4zCkWF!W{?OQ`vi8CS|^*0j4wYtXn zrt2&GmToTt;tlTy-vzzi6o!qh7n;#BN(T1U`u@}Om?tuIk(_(ks>v_x6y(dU zQlU#-wl0LCzi#SdRQvhs(beR^i@mty}4Lz&&+)A0(Qlwjs=K05{7!%s*Y-XLfy))F$W)x9O98iXHm02{*Q{Rjs zxB7H$shle=NFm4-bP_7XcM~Oc=h`>7oL3}-I}b~~N(zG(WT#ul5OM{%qQ#Cji$J9N zBf?b*W4S;jr53o?SuX7L7|kGTm5=gX3C1z5L|F_uQr)bt5WP)KcJOGFtkov+70kcF z_F?<3V&3$ZGQBLkxOBDjcha-g4ZqRlj$;VwYX%U%*V#%d*9-8s%wRY=Br`%Q}Z* zGl!PAMNCDelxYl>eCT*)4kPI&d8PNJ1-`s+~eXd)sq&9Tw5@txx?2qO6VbTR=*;H z>K3UF)gvKck$nP@)zauUsZ6uhG73~mZ{!u2NIBw7<%Bc@RJ_|Lx8f*~sis;jVEIUW z6cYEd#3HUt`_i2@twz3U?3|NwgV}|a+_9DYOj_DUq+YSvR@)C9PSi(XHQu}Dwj z+)}+XIvpP6k^=imnW78@-7hp*aAevetvIon#=P`eH{581dz)3}!j@`CD3Dh;0hbru zqwv2fU{?7I(xnLRi>*rQ&*NfoH*UKSjadsF23*{(wLQX4tl|eL=m5PrJB{v{fJ3{) zXr*_v3-nBD3NOBFy;;TF*llx-^KVWmg`HjC=H-q;X&Y#J8x`ueHKtq?yQ#zfC^^OI zm}-@;+_Ks!8$$?t{}Udr&sD3SwQhlp)|BY9O3B`@+{j*4)Shb)iZB$SX(>`}P-c+3 z9+A?tMdl|}8(CxXv_5A@Wx$``DIs)0z+rY!llo3~^`2~xGV-JVxl5rCtuPWVnNt2` zc=pK7fAxq@7YFrdwicZ~cpHBXSZT*gu|w43tN80+$W_2`IF6J?*-N4x8^3@kHC?kk zSL|fbA78eM(pbK&wOGW)C#8iP_7DnzmL= zIPy|X*F4j$-fpbi$!Dk(TO@aXoJNWGq-`+7JWsFRvA8tT$Gt$NbvF{u8AY~uH|EfC zc0iL+C8!+zC{ku_rP${N=7gZxy;EdxC>3J`L>b5yVa6le9V$`bA{ z++}KIFMUi8f)q(!s9*nMtoU5&4VybVP-CV;rRnLpLrq~G{$xk0G0qe@j$-*$204?~itGOXPinhes*}(2qSHA$=SfRYu(! zc#TQsQUdOi2TX&m#FP`eVS2Ak88WLy&qpPVTFc_T;W)l=`?WM}*v7!L9IQ%OS3fzs z!~gx|^B*hE;{tgG0+Gx{LSvb4vR5DF#wb{0%r+-KaG+(iThe9d%!H*2uV_Ug4m4%O zrmy|0QOFB4nt(>Z=Tm-kf6VqlO8JKEJs*aAF@eXn+Et+=?N--*T|`NdDO3C z)HZs*p*1kHQA<=fV#98!iP90(UneH_JQg~_lv&~(M^<@Yp)>ZRL4NV#d#m-Pla-)) zDWo>vzuhiMcouMP=jgNJ zDbwO`v1ijmapT|O$ii_Xcte<3QN|beTQlJYV!AZg-&bKN)0mWF!#ojw!0E=Fc%Te( zq4O5#rk(2R{fVZO2H{bfdoN+)j;%5M(cm)B+^U#!ax$SLaf zIvaSY7Rss~FCMY6U`;1#W9=7P;TMb8VY>w&EB{dJkc#MwuW_IWXU+k<-l1+k{>Rtk zQu{~2*U`m!0>&|)6YJ|gh$h*2WPY z@^OEgDM!!R^hm&bsu`}!;+4|Oh5zsd;ndG@D*!l@v;S(m%7k6Ye)RM*NCmP?aFTxj z%C2tc9G#bV#edjx*XOfi0H#Cwl4A_U_`K`L@Faf%RC>vIBJZBE#vE6Fb!pLlzfdDA zXGw>yxqeZ33=L1^u~SKFe$Bs-XT_gqWMn!vikYNRQz&Umgn@z;)>nT0$|oo^z9<0e zu*W$$U@QLqlIJO}6G zv@%7?W=KFiwY23n?cesSPmGg>;R>3f>{P^fR;5Mp@f{{a)S16B6Bac?E)~oeMBrMh zB5>Mrf=#RjwW8RZ>cc)#&Gc-}WW4~3K+fIXDHalBR zCNrhq82#g|fkof-`*r=g<~?>#T$*P|-$mfEI%bPG(X>}p!61>EA-(EbxbOgj@jqUA zN%Uh4Ra0*UW2+oW(jR8So*_HCdXtMGEd&z)W}Ovqd@aiqrA?2 zLoJ%HcF6Z2)L^KxQ6-o?^r$ zmq+yS7Pb9Se1RMFt&RN&Plq0ndD`X;*=Kbd+S6>(-o~4jbIXd$(hO8+ct*AtSGSMQ z%OUv~IB|_>wL=Y=p(ZM)vcwcNYuXE=Hq(2Mg#BW6G%kTC$0> zIG?p9bi_W=YNnDRXj4Zf!Um?1E6u&~U7RzIA!$i*R$i*@l1Q&|Lx47gkS>0z5U#FW zkfJ8k0>KrIvW+9373CMjy|0oUj=X7=A{Q1LK&KQi-~qvC=N^9$g=Xx0&Kyf+*sk-9jOSpJYKX(8Gj^_f9jr??jy$pqxDlN5XU}hI9GV2j4?dbg|u;CA$6)% zuxxq7_aj=-S-^>Jyi9ND6Q*?Abj(3<*MY=zyr2mvpRk7vZk?;un)1$`0xrvQq) zfeBngn<2$Xk*1``VQ&d@e0)QWJL?}bnZRGpz@Xo-)5A|)7R$lYd#o4Fau7-zeYPR_}max;CxN){Ki<_`s7pzFLhze^c&VNx}EJF(2ds&$St(3|9SBSwN5KShj+re4E45=6)7(SlV z8};G^LB7<`Yot)``GmBRhSKm*>j(4xWy8Q5cSZ#4m$}pIaZYM1qbymA6sz}`8?91V zCfN+G%uDmN9ZNAgdcxDEY?t`r4jajYy5+*|Zzic|1zapah_?lfxM6-yW3sa={9hOu z736THejB@Zyrj2Q-+NRUOz2a(*ZG74o!|?y%PVyFC0-xUxy)v`1qX=Z-yaD|p67@m z6?Uc^zk&0V%)O^&>{`3+>K5c|ggtHj?l4a)w^SM%^So^(+2XBgu8s0NmdSgctOW4L z$4wzYhuRp=xn!@#oV&B2*h7$hOaJ*&9#1$Mf}CA3$>SYLnw(S=9*v?_Y3n zb5_LB$tdwTZWuQl%xSSWe#2D><#sJF&a=jlFRG1Suro@RUFnf`24u?9D$UB<*Q;C)|Xc=tzKzB_YWXBVQ#U`FeS8)$@e8>Kq9)RE2~@ zhuKq%8MiW4#pb$H0IF(9u1o?Nn^L<8)-pwF-1>A=9bgl!u<1Bi%QLK)%AcF4aYc=` z`ZU8G%!E_Syl-;?n&jw-V^EW|6!1vCkJLvu!y#t0Qs8e3JmTaLGYj?u4<5nK?2YOk zeLWon%1K)s)dMO+&#hFpAiX5f;7vBUI3=o3T-wXychPV`xu39Am*|P{g6C(9Ka@Am zt~GOU$%=t9V*4`1PbQBP!r)@jK{9BvKR)SF;}4cUd!e_8;t@Y@Aa`E>>rMprU%4aY z_^ChV{Y}>{{@Htc*&Fp|??DPDtedl7*+^j$Xb zmp_*9MFl)DQM5Nzj{xC{6ez+EP&TpOfja0Fm656Y(9;nwfdu4k;PShjC*Qt(BN7Go zoqmDSe`w85fp0Le#I?{UQ~Hx9T*WtpT6VRBsVJW(UnO@uKH3MIWXZ8LUAVgwM_avW zO?fZe-chlQ7g?xTHz_LUxiv_L5+UOKHdjpH7l_eiT<#OW>)vD z?&CbGEW$ikQ+O9K^n*&b9~31SB$?h{r=T6RIFQ94C*`x(;+e*Gp%$d3xH^g&4{|nye+CXLro#a#sPP{1^Cwv zyWU9`S08WnWoh0WbBK^}8q9+MI#VytZLrYc088aToyWA+d@W>);jwkcB`ESqGZ**A)5jveel~OYLA+Ii5vB`*ukVI}G4XjN(+^p4ooxdZO8ne7a~ITb4N^4YV=jhQx_y9b~?@^Rng$*=Cw z{-fZ}oM=Y!+=}a@wBDa&qkRyjf+D|w_{uC`;5LHn-0BsqCu-ecRW*Q*=h$k*ad99) z{FQ05BG=4l1rldu=S-Lfe6+K(v!m+FVhC}kCB4B!D(Sss0l-;IfK_$J75NMpau@nP z>xxr)D0qjF$>F!0-bBC<^?5d$A67Z($Lw}GgjH&|Xp^uzvATN%kS(KkBjek~LGP;j zs_Stk5kD543`Vc9s}--NzYj>zLXlBjaXh{VQ}gaP9xoHq#_nVuFT~#sr+KW&HUVg) z!eKsqq!tiD5II}6ma08ZJn9IWNhfZO)}>-T(YM}Zl+6PwuEU=n#rvyF*F7>bC|ke7HkT_Vh!ezocW1Tk%afLeJgRrWat`j>+D_lIJ47(q{8Zv9fPt8qWvDL8z$n|bj>khP6E@hhFg ze(@~tC(++hS$}^h*d0P1M#a9@R~I1u|7 z^GEaD-sC~=0X`|mb1Q*|*jrxAuk#3h^lhvoNv3YY5vruKbJRd<+kFt)wvDjtWx#3HU+$DN5%l1?W;7d}!Z%m1zHHu%DsbhPaT6=2BfFL)P! z-?;}Y-m7ObinPkTGD$(HhKPQd1bq8Do14Y6h)<%^0P+v5(f zDI1$D3t^Lyb~^Dq-b~7EGQE;F^K%t2Q=5aRqxlH@msq#=zz1KGKahgRFp1C?`eT7B z^9gZZdhT(Ew@6x^*auPphAG3v0zJPqQt91MBya``6DQ4K*K(UmrJq=I{>yss;GX<5cFjmU)iX~;j-=FLO+Hm>2D)MCLJ0g&-?}$ zz~)x6=yQ&kKL+#12#5f?FbODnYK{*U$99T3r4Oe91$LH>rrA!0>^%3|jE(vOa%m=C z9Ce3y^cBqo3e*D2IPSKw8!dkYMg-?>NeqbJ<;1#u2R^(v`J=bLP<+cszP_FBIhM2u zOww_Ar$9=gLNV^Rsec#{TrwF;{v@|q28ZT*8?{}dom}PMo z30!gQ5#ewbwJiTTX2^xABFn}hV(7~xV2hmR{u2uW z*wK2gif2o%#pqoS`Bica{de>DiZ`lW;`Lgx+Tg+VBAe&YI*)GNp04rhNnb$^gHnWq z`+-BlaQY7r{seRhz`w3%{2DN@bFY{Lc?L|*7d19sVm;WMszAU1=7)jjAyV{CVSuUf zvFF%t1@hD38w4$JH#lM#DKAuB2L}8nK2-t`#bb2y2L{qcLCOFa?8{KA;~=7IY7;g= z2-*YwldYSWOKUx~>l78q`0mUGo(%tZ^x+ zv;FN4qXQ78j3E3|D^vQB!!7~Db|otTPYPqKX71bHoU7Z2%-`BQJ5p-nx{#G&Iw(TH zGm;dC&-d8IKnL+#{b1*t@A(L=kbjp&I6Pb9_qv(*dTOO=)fR5IIg2}U@v1m-R(a`M zx@jYLK;b$abhmap*Und0)D=K{_jj75*h6$}@gVp4YKeOSIv7HpK#Ffzv+Q~TqBVnP z(Pt0y0!|~q7cXVVZY`R@d*cnj>zA6Fe$bs*y1#uLR zZV){^+tH6R(J=P^eJm+p`k%>mWMkf+w43CO)BjzD{@-N5|0hZR{}*3*Aam2!+y8CU Rz9Ui5Pvle~c@Isz{s-NG5NQAa diff --git a/docs/programming_guide/source_zh_cn/images/randomcrop.png b/docs/programming_guide/source_zh_cn/images/randomcrop.png index 8095bceb67cd3643dda1dce6c060a98ccb40373f..ef62fe1a08f221a2c4ce81f9e60ba5c9e0d93a61 100644 GIT binary patch literal 92040 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�tjU|&j0$g}OUPpi-C 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�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%0AK!t;JK`|T6^tq@B})QTh%^G#|m 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 BFd+Z{ diff --git a/docs/programming_guide/source_zh_cn/images/randomhorizontalflip.png b/docs/programming_guide/source_zh_cn/images/randomhorizontalflip.png index f127d7ab479851049262fc3713dba7d14b2c908a..2d851183a8f858c54a26b636703b9177df4ec80e 100644 GIT binary patch literal 130799 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%0AxaMaSsu`|~2^m8wN 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

    W%w1iV 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� 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 N0A`|Fp!4hR{|&rxSPK9E diff --git a/docs/programming_guide/source_zh_cn/images/repeat.png b/docs/programming_guide/source_zh_cn/images/repeat.png index 7cb40834c41b8d17e37cf2da8ba368ad72212f48..9717ec81c52f23615e236d27e0f7c96bd6ac1155 100644 GIT binary patch literal 11920 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 literal 38083 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 S#>dV$x?5VLm6q=AMkztMOQgHIhBy9R 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�I>VuBm-sTlfR|5*4 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 diff --git a/docs/programming_guide/source_zh_cn/images/tranform_bad.png b/docs/programming_guide/source_zh_cn/images/tranform_bad.png index 2d3ee60ccffdbe7c9ad3f5adb4235cdc8f3532d2..0f659a14be8d8af05cee1757adc3d67664e1c259 100644 GIT binary patch literal 10375 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 Vi!Z$s0doz3X&T%qxOM;0zX9;D3qAk< literal 24757 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 aj;97YeX%S;qXPqN*xp^1JG0D=Uid$Uq^7q3 diff --git a/docs/programming_guide/source_zh_cn/images/tranform_good_2.png b/docs/programming_guide/source_zh_cn/images/tranform_good_2.png index 066a5d082387206a01ceb6ad54cc9dd7e074c672..f6ed65482d233d88f46b108c3fe4e21bd00df4c5 100644 GIT binary patch literal 9300 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 T-#Ws8JBQ#8)#VH1o(BFmf~eIT literal 24291 zcmeIad0dlc*Di{+)&YUG4uA+WwTg;@ihu%1D5+9KL`6hIK&6N>Dub9n5~>V!BozS} zL!``;f`|-BoR9!QB7@8cN+e;7gfJvzIQJ9Ow|w9CcEfx2`JMg8<_|Tk=DDABukl*f zTGtL8v{YKQW|@M5g3`WUe>tL{uq;49;j5G--+=!T8|dx>e*4H&L>2iW?a4G22z=ceH9Uw%G%Icca1efREo zJa@D-G4|2UQ#Xp#zFm3pj}5!_RViKFyY05sm8_qx-rT^xaIbg&y^DP}H(dNV?bY_Z zCwI8NqWzTiyISw{x~$&Vnrr4~;-eR7UhGgmbj5j9jL)If+0)fzjx%v{-uQ`FCRi*ZVCA6%cq~tl2&~A@WXb+E(`ZyKJe~*%)pNs<5!5{sA4xx=9fcHg|3S-+aV}vb=D|<_=Y?j%B;6r z{^hIx=_O`A)w+dpy5`P$5?)y662WvQV)rxspDj`iWBO7h7Nw6K9W{kiNB+aO;obHC zCa8_kMd2qaSV|IY*{C+@#^k*W>%_O=O$!2$L4Oz4?B~q7mrrlE&AlOsK}Sq`aUFfi z(%EpLRFH{$e(v-0%w6m%!Ou z->Tqn46Tx#pP!$&VF6cbWR4p0_UNz%6E{6vL1WerGT zaJ(p_^m2_WPfeL2x|j&0OuaVQ8b%-I(1ViXWvH`NU+e3_NI z1+G!>)tEQ;_mGUe+P)Rtzo9qqyx*hu{SAFRv{!qP8;SR%_cjAO-Z1$Z^TR}^uS$1U z*U2WjDJRL_qR^o@BZIj3^C6mb=IlZC!xglB8j^OCz`LOE?-X5@VBb2phvVK~)3I;~ zc(cc8my@^IRL|9H%hb5U?XG(VzWe+Tg`7U+f9v7@;d(uxM|RWxTvvyno^Q%v3pHxShUKxPXqED84h9=Tu=7FdAeK zIMB?%kK5x{mAg=JZtk@o{M?Atz68(xTGJf7l*6dP_w9|+(!@x`LK1THn$2CwYt8LJ zBV7#B;YYTa_zj;WV4h!wnp?~~Zac7`?c!i-p$c{|zcdyrfkm$U9`pL%b~hruXp18y z1kKG%!E6?6%1ruRq)MII!`S%Yv5L<9GO+_!JvUgu@Mim`Wg;J5v}SaT)jLv0Mn23!Y2zw)Dn z9T8ov8FUvbZM4$giXM9KLRnD){unOh$5GdcMk;v9l3TtZ>jGR|1E;%L!iJ#zTDnp= zTqYhP*&rnXMvFAX$d`F?)Npusn54Sp_@Nf}=I83}Nq_#Qj^*RKv#;-chhe1tOqy(W zCo(KG1CMf(FLh)O(UE-GIx8)W?Pq@Bvc!GHBp2*>3!^S}t0K1N_r(#+AQrZ+fwAJ2 zx#2XTk!p3oJ7P>RMpEHFz`4%KF~t4jM7Rz_x_@5-U8;)wLhN6ZAKsSOHDeBj1Q9wWu%AS6OnyMf{_n!IZaF1YGA}Ge<=mQOSPT>KwdPP)d~yGhAQY zTq?=;#pc=?{Iv}$5-^OJmtDCx^vbi?@Ms+yWpY4&V-az?f8T3{l9E!(&3i9>abt-^ zbXhx5;!xu{)>p4cK3ku_h&$=GkNf93%UCRBiY|svcC9F%s!%rxI9GE37^r8B>t~TG zXtU?)GOe>0r@FTXwmPA-v4S@wZ8ZB&M)g|%1JIQp#7d2+!umVa(s$ZYn7|i5-O13W ziv2PX#X3_RtrVa%;JLZ%heVl}LyA<=SS{-Er{@nCVD7KCioFY+(mggts$MzzN&{uQ zb7z?Jl`-YJ^0Kns0R6IZ{}m%i7xC@m=om%fR@t;9SJTUw%i6VYEjSfGfV><)^=eSEgq zis|35n-hi`DdUvm9_;u=Me8L0_$VuyJkgPxnDMDH2^F38U78g%pK#k)Cg#^!X$4Eh zTT##v5byt3XJK=18)3*vNm+~e*z;^XPx!W!vPx8=LtIXt9;t|Ay2UwJ zsI1+!Ex^jks-0tMVq$@uXmed}aBGcW4tx9OD-Knet5waej||hbLIbq$;?X}Y;wv%?o-H;6cZA@kUfoP_7f+44RlL3Q+ukn^JTor=ph2WP@~><~;kQ}; zI_dv?ZTAn6|Np=w{4L1AdeR&op4r1SlFKR5_RF`DKu-`?Txrx-V|J*LjWAj03B1n&OKEY3LPeEq@9UrK1 zM^3jxzEA~z=H(wFYa^XA8ij1HuMnF#GgY?fbLRJlcyoQ~?0ZoPw;&y=*YGPl+0FsU zROUBVDCerKuOe~k6IC(Y<$>#Y>N|e>l}i=ZQI}(Bu*fhiLyx1}XIB^7!*vKu(fA;W z%CFTW;U$AEki!dDX-ccoE3sq-B`r# zM7gL$8-lIO$#YKBBfv?s`jkMbE>HVx7yj(>0P?y9?hVU9@c0fh(44&<+522ke|a|* zFVjm<&eBOV@?M5*v9k}S$fVOKV6_j}?pvHIcL_k+S#iz;lhBZ2Q{`?OyPFs~JU9eN z6*?I=acJv;@dnK~LLY0E0U;(Bv;E47=s<`EmA)Q72O>Giot~nJfrKefEVLm7OE~y4ZC`8>LuJB=?nP^bKQfUxnC}w8P(=u=c;6R|IOteQegtG&TtVm z##vB7YDWTj%LpTQq|Dv>n}u0DAL3l}&_j1^4=(KnP>)DD&4bFCuJNmH)+gDR``U#d z>`W4iUJK@-49eOj&s4|6eVvReZvtWPkJqQWtm=3mc+|4sf1q0H*JD#gr0-&ksIofd;jeQO=95Ws{|cBJ^@3(}23bX8#{ z=K^BE`2EKAyKW7i$_I@0df!PRivo_3oP=UwHR?rmU!m)`=U2 z%0A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 diff --git a/docs/programming_guide/source_zh_cn/images/tranform_good_3.png b/docs/programming_guide/source_zh_cn/images/tranform_good_3.png index 500b36c18eb53253c58f84515d5b90b1136d23c0..575d8038bb7f8260b86d226033c30e15c3b20e0e 100644 GIT binary patch literal 9246 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 I+kd|JFDGoYi~s-t literal 23743 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 diff --git a/docs/programming_guide/source_zh_cn/images/tranform_pipeline.png b/docs/programming_guide/source_zh_cn/images/tranform_pipeline.png index 07906d4751f286de989a4c873d9fd422207eb5eb..7278418d5ebfb3db921627f213ceb455aba53794 100644 GIT binary patch literal 14272 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 JK+h%We*rL&v*Z8( diff --git a/docs/programming_guide/source_zh_cn/index.rst b/docs/programming_guide/source_zh_cn/index.rst new file mode 100644 index 0000000000..82c4400a4a --- /dev/null +++ b/docs/programming_guide/source_zh_cn/index.rst @@ -0,0 +1,21 @@ +.. MindSpore documentation master file, created by + sphinx-quickstart on Thu Mar 24 11:00:00 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +MindSpore API +============= + +.. toctree:: + :maxdepth: 1 + :caption: 编程指南 + + api_structure + data_type + compute_component + data_pipeline + execution_management + auto_parallel + advanced_use + network_list + operator_list diff --git a/docs/programming_guide/source_zh_cn/component.md b/docs/programming_guide/source_zh_cn/network_component.md similarity index 76% rename from docs/programming_guide/source_zh_cn/component.md rename to docs/programming_guide/source_zh_cn/network_component.md index dd92ce5515..f94077009e 100644 --- a/docs/programming_guide/source_zh_cn/component.md +++ b/docs/programming_guide/source_zh_cn/network_component.md @@ -4,24 +4,25 @@ - [常用网络组件](#常用网络组件) - [概述](#概述) - - [GradOperation](#GradOperation) - - [WithLossCell](#WithLossCell) - - [TrainOneStepCell](#TrainOneStepCell) + - [GradOperation](#gradoperation) + - [WithLossCell](#withlosscell) + - [TrainOneStepCell](#trainonestepcell) + + ## 概述 -MindSpore封装一些常用的网络组件,用于网络的训练,推理,求梯度和数据处理等。 +MindSpore封装了一些常用的网络组件,用于网络的训练、推理、求梯度和数据处理等操作。 这些网络组件可以直接被用户使用,同样也会在`model.train`和`model.eval`等更高级的封装接口内部进行使用。 -本节内容将会介绍三个网络组件,分别是`GradOperation`,`WithLossCell`和`TrainOneStepCell`,将会从功能,用户使用和内部使用三个方面来进行介绍。 +本节内容将会介绍三个网络组件,分别是`GradOperation`、`WithLossCell`和`TrainOneStepCell`,将会从功能、用户使用和内部使用三个方面来进行介绍。 ## GradOperation -GradOperation组件用于生成输入函数的梯度,利用`get_all`,`get_by_list`和`sens_param`参数 -控制梯度的计算方式,细节内容详见API文档。 +GradOperation组件用于生成输入函数的梯度,利用`get_all`、`get_by_list`和`sens_param`参数控制梯度的计算方式,细节内容详见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.html#mindspore.ops.GradOperation)。 GradOperation的使用实例如下: @@ -59,9 +60,7 @@ y = Tensor([[0.01, 0.3, 1.1], [0.1, 0.2, 1.3], [2.1, 1.2, 3.3]], dtype=mstype.fl GradNetWrtX(Net())(x, y) ``` -上面的例子是计算`Net`相对与x的梯度值,首先需要定义网络`Net`作为`GradOperation`的输入, -实例创建了包含梯度运算的`GradNetWrtX`。调用`GradNetWrtX`是将网络传入`GradOperation`生成梯度函数, -将输入数据传入梯度函数中返回最终结果。 +上面的例子是计算`Net`相对与x的梯度值,首先需要定义网络`Net`作为`GradOperation`的输入,实例创建了包含梯度运算的`GradNetWrtX`。调用`GradNetWrtX`是将网络传入`GradOperation`生成梯度函数,将输入数据传入梯度函数中返回最终结果。 输出如下: @@ -76,7 +75,7 @@ MindSpore涉及梯度计算的其他组件,例如`WithGradCell`和`TrainOneSte ## WithLossCell -`WithLossCell`本质上是一个包含损失函数的`Cell`, 构造`WithLossCell`需要事先定义好网络和损失函数。 +`WithLossCell`本质上是一个包含损失函数的`Cell`,构造`WithLossCell`需要事先定义好网络和损失函数。 下面通过一个实例来介绍其具体的使用, 首先需要构造一个网络,内容如下: @@ -124,20 +123,19 @@ class LeNet(nn.Cell): return output ``` -下面是`WithLossCell`的使用实例,分别定义好网络和损失函数,然后创建一个`WithLossCell`, -然后传入输入数据和标签数据,`WithLossCell`内部根据网络和损失函数返回计算结果 +下面是`WithLossCell`的使用实例,分别定义好网络和损失函数,然后创建一个`WithLossCell`,传入输入数据和标签数据,`WithLossCell`内部根据网络和损失函数返回计算结果。 ``` data = Tensor(np.ones([32, 1, 32, 32]).astype(np.float32) * 0.01) label = Tensor(np.ones([32]).astype(np.int32)) net = LeNet() -criterion = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True) +criterion = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') net_with_criterion = WithLossCell(net, criterion) loss = net_with_criterion(data, label) print("+++++++++Loss+++++++++++++") print(loss) ``` -输出结果如下: +输出如下: ``` +++++++++Loss+++++++++++++ 2.302585 @@ -157,7 +155,7 @@ learning_rate = 0.01 momentum = 0.9 optimizer = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), learning_rate, momentum) -criterion = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True) +criterion = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') net_with_criterion = WithLossCell(net, criterion) train_network = TrainOneStepCell(net_with_criterion, optimizer) # optimizer for i in range(5): @@ -167,10 +165,9 @@ for i in range(5): print(res) ``` -用例中构造了优化器和一个`WithLossCell`的实例,然后传入`TrainOneStepCell` 中初始化一个训练网络,用例循环五次,相当于网络训练了五次, -并输出每次的loss结果,由结果可以看出每次训练后loss值在逐渐减小。 +用例中构造了优化器和一个`WithLossCell`的实例,然后传入`TrainOneStepCell`中初始化一个训练网络,用例循环五次,相当于网络训练了五次,并输出每次的loss结果,由结果可以看出每次训练后loss值在逐渐减小。 -输出结果如下: +输出如下: ``` +++++++++result:0++++++++++++ 2.302585 diff --git a/docs/programming_guide/source_zh_cn/nn.md b/docs/programming_guide/source_zh_cn/nn.md index a1bb61ec96..eba17df4fb 100644 --- a/docs/programming_guide/source_zh_cn/nn.md +++ b/docs/programming_guide/source_zh_cn/nn.md @@ -1,6 +1,6 @@ # nn模块 - + MindSpore的nn模块是Python实现的模型组件,是对低阶API的封装,主要包括各种模型层、损失函数、优化器等。 diff --git a/docs/programming_guide/source_zh_cn/operator.md b/docs/programming_guide/source_zh_cn/operator.md index 0bf4eb35f4..40f995715e 100644 --- a/docs/programming_guide/source_zh_cn/operator.md +++ b/docs/programming_guide/source_zh_cn/operator.md @@ -1,126 +1,103 @@ -# 算子组件 - -算子组件指常用的算子及其操作,按功能大致可分为张量操作,网络操作,数组操作,图像操作,编码操作,调试操作,量化操作等七个模块。所有的算子在Ascend芯片或者CPU, GPU的支持情况,参见[这里](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html "list") - - -这七类算子操作的相互关系见下: +# 算子 -- [算子组件](#算子组件) - - [张量操作](#张量操作) - - [标量运算](#标量运算) - - [加法](#加法) - - [Element-wise 除法](#element-wise-除法) - - [Element-wise 乘](#element-wise-乘) - - [三角函数](#求三角函数) - - [向量运算](#向量运算) - - [Concat](#concat-算子) - - [Squeeze](#squeeze) - - [Sparse2Dense](#求sparse2dense改变tensor维度使其变稠密) - - [ScalarCast](#scalarcast) - - [矩阵运算](#矩阵运算) - - [矩阵乘法](#矩阵乘法) - - [常见范数](#常见范数) - - [广播机制](#广播机制) - - [网络操作](#网络操作) - - [特征提取](#特征提取) - - [卷积操作](#卷积操作) - - [卷积的反向传播操作](#卷积的反向传播算子操作) - - [激活函数](#激活函数) - - [LossFunction](#lossfunction) - - [L1 Loss](#l1loss) - - [优化算法](#优化算法) - - [SGD](#sgd) - - [数组操作](#数组操作) - - [DType](#dtype) - - [Cast](#cast) - - [Shape](#shape) - - [图像操作](#图像操作) - - [编码运算](#编码运算) - - [BoundingBoxEncode](#boundingboxencode) - - [BoundingBoxDecode](#boundingboxdecode) - - [IOU](#iou-计算) - - [调试操作](#调试操作) - - [Debug](#debug) - - [HookBackward](#hookbackward) - - [量化操作](#量化操作) - - [MinMaxUpdatePerLayer](#minmaxupdateperlayer) +- [算子](#算子) + - [概述](#概述) + - [张量操作](#张量操作) + - [标量运算](#标量运算) + - [加法](#加法) + - [Element-wise乘法](#element-wise乘法) + - [求三角函数](#求三角函数) + - [向量运算](#向量运算) + - [Squeeze](#squeeze) + - [求Sparse2Dense](#求sparse2dense) + - [矩阵运算](#矩阵运算) + - [矩阵乘法](#矩阵乘法) + - [广播机制](#广播机制) + - [网络操作](#网络操作) + - [特征提取](#特征提取) + - [卷积操作](#卷积操作) + - [卷积的反向传播算子操作](#卷积的反向传播算子操作) + - [激活函数](#激活函数) + - [LossFunction](#lossfunction) + - [L1Loss](#l1loss) + - [优化算法](#优化算法) + - [SGD](#sgd) + - [数组操作](#数组操作) + - [DType](#dtype) + - [Cast](#cast) + - [Shape](#shape) + - [图像操作](#图像操作) + - [编码运算](#编码运算) + - [BoundingBoxEncode](#boundingboxencode) + - [BoundingBoxDecode](#boundingboxdecode) + - [IOU计算](#iou计算) + - [调试操作](#调试操作) + - [Debug](#debug) + - [HookBackward](#hookbackward) + - [量化操作](#量化操作) + - [MinMaxUpdatePerLayer](#minmaxupdateperlayer) + +## 概述 + +算子组件包含了常用的算子及其操作,按功能大致可分为张量操作、网络操作、数组操作、图像操作、编码操作、调试操作和量化操作七个模块。所有的算子在Ascend AI处理器、GPU和CPU的支持情况,参见[算子支持列表](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html)。 ## 张量操作 - -主要包括张量的结构操作和张量的数学运算。 -张量结构操作诸如:张量创建,索引切片,维度变换,合并分割。 -张量数学运算主要有:标量运算,向量运算,矩阵运算。另外我们会介绍张量运算的广播机制。 -本篇我们介绍张量的数学运算。 - - +张量操作包括张量的结构操作和张量的数学运算。 + +张量结构操作有:张量创建、索引切片、维度变换和合并分割。 + +张量数学运算有:标量运算、向量运算和矩阵运算。 + +这里以张量的数学运算和运算的广播机制为例,介绍使用方法。 ### 标量运算 -张量的数学运算符可以分为标量运算符、向量运算符、以及矩阵运算符。 -加减乘除乘方,以及三角函数,指数,对数等常见函数,逻辑比较运算符等都是标量运算符。 + +张量的数学运算符可以分为标量运算符、向量运算符以及矩阵运算符。 + +加减乘除乘方,以及三角函数、指数、对数等常见函数,逻辑比较运算符等都是标量运算符。 + 标量运算符的特点是对张量实施逐元素运算。 -有些标量运算符对常用的数学运算符进行了重载。并且支持类似numpy的广播特性。 -举例说明: +有些标量运算符对常用的数学运算符进行了重载。并且支持类似NumPy的广播特性。 + +以下代码实现了对input_x作乘方数为input_y的乘方操作: ```python import numpy as np -import mindspore # 导入mindspore包 -from mindspore import Tensor # 导入mindspore下的Tensor包 +import mindspore +from mindspore import Tensor import mindspore.ops.operations as P input_x = mindspore.Tensor(np.array([1.0, 2.0, 4.0]), mindspore.float32) input_y = 3.0 -input_x**input_y +print(input_x**input_y) ``` -真实输入为: -```python -print(input_x) -[ 1. 8. 64.] +输出如下: ``` - -真实输出为: -```python -print(input_x**input_y) [ 1. 8. 64.] ``` #### 加法 -```python -input_x + input_y -[4.0 5.0 7.0] -``` -除普通加外,还有element-wise加法: +上述代码中`input_x`和`input_y`的相加实现方式如下: ```python -net = NetAddN() -input_x = Tensor(np.array([1, 2, 3]), mindspore.float32) -input_y = Tensor(np.array([4, 5, 6]), mindspore.float32) -net(input_x, input_y, input_x, input_y)[10.0, 14.0, 18.0] +print(input_x + input_y) ``` -#### Element-wise 除法 -```python -input_x = Tensor(np.array([-4.0, 5.0, 6.0]), mindspore.float32) -input_y = Tensor(np.array([3.0, 2.0, 3.0]), mindspore.float32) -div = P.Div() -div(input_x, input_y) +输出如下: ``` - -求FloorDiv: -```python -input_x = Tensor(np.array([2, 4, -1]), mindspore.int32)) -input_y = Tensor(np.array([3, 3, 3]), mindspore.int32) -floor_div = P.FloorDiv() -floor_div(input_x, input_y)[0, 1, -1] +[4.0 5.0 7.0] ``` -#### Element-wise 乘 +#### Element-wise乘法 + +以下代码实现了Element-wise乘法示例: ```python input_x = Tensor(np.array([1.0, 2.0, 3.0]), mindspore.float32) input_y = Tensor(np.array([4.0, 5.0, 6.0]), mindspore.float32) @@ -128,37 +105,42 @@ mul = P.Mul() mul(input_x, input_y) ``` -真实输出: -```python +输出如下: +``` [4, 10, 18] ``` -#### 求三角函数: +#### 求三角函数 + +以下代码实现了Acos: ```python acos = P.ACos() input_x = Tensor(np.array([0.74, 0.04, 0.30, 0.56]), mindspore.float32) output = acos(input_x) ``` +输出如下:[42.268584, 87.707557, 72.542397,55.944202] + ### 向量运算 -向量运算符只在一个特定轴上运算,将一个向量映射到一个标量或者另外一个向量。 -#### Concat 算子: -```python -data1 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) -data2 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32)) -op = P.Concat() -output = op((data1, data2)) -``` +向量运算符只在一个特定轴上运算,将一个向量映射到一个标量或者另外一个向量。 #### Squeeze + +以下代码实现了压缩第3个通道维度为1的通道: ```python input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32) squeeze = P.Squeeze(2) output = squeeze(input_tensor) ``` -#### 求Sparse2Dense(改变tensor维度使其变稠密): +输出如下:[[1, 1], + [1, 1], + [1, 1]] + +#### 求Sparse2Dense + +以下代码实现了对Sparse2Dense示例: ```python indices = Tensor([[0, 1], [1, 2]]) values = Tensor([1, 2], dtype=ms.float32) @@ -166,16 +148,17 @@ dense_shape = (3, 4) out = P.SparseToDense()(indices, values, dense_shape) ``` -#### ScalarCast: -```python -scalar_cast = P.ScalarCast() -output = scalar_cast(255.0, mindspore.int32) -``` +输出如下:[[0, 1, 0, 0], + [0, 0, 2, 0], + [0, 0, 0, 0]] ### 矩阵运算 -矩阵运算包括: 矩阵乘法,矩阵范数,矩阵行列式,矩阵求特征值,矩阵分解等运算。 -#### 矩阵乘法: +矩阵运算包括矩阵乘法、矩阵范数、矩阵行列式、矩阵求特征值、矩阵分解等运算。 + +#### 矩阵乘法 + +以下代码实现了input_x 和 input_y的矩阵乘法: ```python input_x = Tensor(np.ones(shape=[1, 3]), mindspore.float32) input_y = Tensor(np.ones(shape=[3, 4]), mindspore.float32) @@ -183,27 +166,19 @@ matmul = P.MatMul() output = matmul(input_x, input_y) ``` -#### 常见范数: - -```python -input_x = Tensor(np.ones([128, 64, 32, 64]), mindspore.float32) -scale = Tensor(np.ones([64]), mindspore.float32) -bias = Tensor(np.ones([64]), mindspore.float32) -mean = Tensor(np.ones([64]), mindspore.float32) -variance = Tensor(np.ones([64]), mindspore.float32) -batch_norm = P.BatchNorm() -output = batch_norm(input_x, scale, bias, mean, variance) -``` +输出如下:[3, 12] #### 广播机制 -Broadcast 广播一个tensor到整个group -举例说明: +广播表示输入各变量channel数目不一致时,改变他们的channel 数以得到结果。 + +以下代码实现了广播机制的示例: ```python from mindspore import Tensor from mindspore.communication import init import mindspore.nn as nn import mindspore.ops.operations as P + init() class Net(nn.Cell): def __init__(self): @@ -220,13 +195,15 @@ output = net(input_) ## 网络操作 - -网络操作包括特征提取, 激活函数, LossFunction, 优化算法等: +网络操作包括特征提取、激活函数、LossFunction、优化算法等。 ### 特征提取 +特征提取是机器学习中的常见操作,核心是提取较原输入更且代表性的Tensor表达。 + #### 卷积操作 -举例说明: + +以下代码实现了常见卷积操作之一的2D convolution 操作: ```python input = Tensor(np.ones([10, 32, 32, 32]), mindspore.float32) weight = Tensor(np.ones([32, 32, 3, 3]), mindspore.float32)) @@ -234,8 +211,10 @@ conv2d = P.Conv2D(out_channel=32, kernel_size=3) conv2d(input, weight) ``` -#### 卷积的反向传播算子操作: -输出结果: +#### 卷积的反向传播算子操作 + +以下代码实现了反向梯度算子传播操作的具体代码,输出存于dout, weight: + ```python dout = Tensor(np.ones([10, 32, 30, 30]), mindspore.float32) weight = Tensor(np.ones([32, 32, 3, 3]), mindspore.float32) @@ -245,22 +224,24 @@ conv2d_backprop_input(dout, weight, F.shape(x)) ``` ### 激活函数 -举例说明: + +以下代码实现Softmax激活函数计算: ```python input_x = Tensor(np.array([1, 2, 3, 4, 5]), mindspore.float32) softmax = P.Softmax() softmax(input_x) ``` -输出结果: -```python +输出如下: +``` [0.01165623, 0.03168492, 0.08612854, 0.23412167, 0.6364086] ``` ### LossFunction -#### L1Loss: -举例说明: +#### L1Loss + +以下代码实现了L1 loss function: ```python loss = P.SmoothL1Loss() input_data = Tensor(np.array([1, 2, 3]), mindspore.float32) @@ -268,13 +249,16 @@ target_data = Tensor(np.array([1, 2, 2]), mindspore.float32) loss(input_data, target_data) ``` -输出结果: -```python +输出如下: +``` [0, 0, 0.5] ``` ### 优化算法 -#### SGD: + +#### SGD + +以下代码实现了SGD梯度下降算法的具体实现,输出是result: ```python sgd = P.SGD() parameters = Tensor(np.array([2, -0.5, 1.7, 4]), mindspore.float32) @@ -288,44 +272,49 @@ result = sgd(parameters, gradient, learning_rate, accum, momentum, stat) ## 数组操作 - - 数组操作指操作对象是一些数组的操作。 -### DType -返回跟输入的数据类型一致的并且适配Mindspore的tensor变量, 常用于Mindspore 工程内。 -举例说明: +### DType + +返回跟输入的数据类型一致的并且适配Mindspore的Tensor变量,常用于Mindspore工程内。 + ```python input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32) type = P.DType()(input_tensor) ``` ### Cast -转换输入的数据类型并且输出与目标数据类型相同的变量 -举例说明: + +转换输入的数据类型并且输出与目标数据类型相同的变量。 + ```python input_np = np.random.randn(2, 3, 4, 5).astype(np.float32) input_x = Tensor(input_np) type_dst = mindspore.float16 cast = P.Cast() result = cast(input_x, type_dst) +print(result.type()) ``` +输出结果: mindspore.float16 -### Shape -返回输入数据的形状 -举例说明: +### Shape + +返回输入数据的形状。 + +以下代码实现了返回输入数据input_tensor的操作: ```python input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32) shape = P.Shape() output = shape(input_tensor) ``` +输出如下: [3, 2, 1] + ## 图像操作 - -图像操作包括图像预处理操作, 如图像剪切(Crop,便于得到大量训练样本)和大小变化(Reise,用于构建图像金子塔等): +图像操作包括图像预处理操作,如图像剪切(Crop,便于得到大量训练样本)和大小变化(Reise,用于构建图像金子塔等)。 -举例说明: +以下代码实现了Crop和Resize操作: ```python class CropAndResizeNet(nn.Cell): def __init__(self, crop_size): @@ -352,58 +341,66 @@ print(output.asnumpy()) ## 编码运算 - -编码运算包括 BoundingBox Encoding和 BoundingBox Decoding, IOU计算等。 +编码运算包括BoundingBox Encoding、BoundingBox Decoding、IOU计算等。 ### BoundingBoxEncode + 对物体所在区域方框进行编码,得到类似PCA的更精简信息,以便做后续类似特征提取,物体检测,图像恢复等任务。 -举例说明: +以下代码实现了对anchor_box和groundtruth_box的boundingbox encode: ```python anchor_box = Tensor([[4,1,2,1],[2,2,2,3]],mindspore.float32) groundtruth_box = Tensor([[3,1,2,2],[1,2,1,4]],mindspore.float32) boundingbox_encode = P.BoundingBoxEncode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0)) boundingbox_encode(anchor_box, groundtruth_box) ``` -输出结果为: -```python +输出如下: + +``` [[5.0000000e-01 5.0000000e-01 -6.5504000e+04 6.9335938e-01] [-1.0000000e+00 2.5000000e-01 0.0000000e+00 4.0551758e-01]] ``` -### BoundingBoxDecode +### BoundingBoxDecode + 编码器对区域位置信息解码之后,用此算子进行解码。 -举例说明: +以下代码实现了: ```python anchor_box = Tensor([[4,1,2,1],[2,2,2,3]],mindspore.float32) deltas = Tensor([[3,1,2,2],[1,s2,1,4]],mindspore.float32) boundingbox_decode = P.BoundingBoxDecode(means=(0.0, 0.0, 0.0, 0.0), stds=(1.0, 1.0, 1.0, 1.0), max_shape=(768, 1280), wh_ratio_clip=0.016) boundingbox_decode(anchor_box, deltas) ``` -输出结果: -```python + +输出如下 + +``` [[4.1953125 0. 0. 5.1953125] [2.140625 0. 3.859375 60.59375]] ``` -### IOU 计算: -计算预测的物体所在方框和真实物体所在方框的交集区域与并集区域的占比大小。其常作为一种损失函数,用以优化模型。 +### IOU计算 -举例说明: +计算预测的物体所在方框和真实物体所在方框的交集区域与并集区域的占比大小,常作为一种损失函数,用以优化模型。 + +以下代码实现了计算两个变量anchor_boxes和gt_boxes之间的IOU,以out输出: ```python iou = P.IOU() anchor_boxes = Tensor(np.random.randint(1.0, 5.0, [3, 4]), mindspore.float16) gt_boxes = Tensor(np.random.randint(1.0, 5.0, [3, 4]), mindspore.float16) +out = iou(anchor_boxes, gt_boxes) ``` ## 调试操作 -调试操作指的是用于调试网络的一些常用算子及其操作, 例如Debug等 + +调试操作指的是用于调试网络的一些常用算子及其操作,例如Debug等, 此操作非常方便,对入门深度学习重要,极大提高学习者的学习体验。 ### Debug -输出tensor变量的数值, 方便用户随时随地打印想了解或者debug必需的某变量数值。 -参考示例: +输出Tensor变量的数值,方便用户随时随地打印想了解或者debug必需的某变量数值。 + +以下代码实现了输出x这一变量的值: ```python class DebugNN(nn.Cell): def __init__(self,): @@ -416,8 +413,10 @@ class DebugNN(nn.Cell): ``` ### HookBackward -打印中间变量的梯度,这一算子特别常用,遂举例在此,虽目前仅支持Pynative 形式 -参考示例: + +打印中间变量的梯度,是比较常用的算子,目前仅支持Pynative模式。 + +以下代码实现了打印中间变量(例中x,y)的梯度: ```python def hook_fn(grad_out): print(grad_out) @@ -439,13 +438,13 @@ backward(1, 2) ## 量化操作 - -量化操作指对tensor做量化或者反量化操作。 量化操作指将浮点数用整数的加和表示,利用整数加和并行加速时速度快的优点, 实 -现在可接受精度损失下的性能提升。反量化指其反过程,其在精度要求高的地方常被用到。 +量化操作指对Tensor做量化或者反量化操作。量化操作指将浮点数用整数的加和表示,利用整数加和并行加速时速度快的优点,实现在可接受精度损失下的性能提升。反量化指其反过程,其在精度要求高的地方常被用到。 + +### MinMaxUpdatePerLayer + +完成在训练时的量化和反量化操作。 -### MinMaxUpdatePerLayer -完成在训练时的量化和反量化操作 -举例说明: +以下代码实现了设置量化所需输入三个参数,输入tensor, 输出tensor和量化结果范围,最后对它实现量化,量化结果为output_tensor: ```python input_tensor = Tensor(np.random.rand(3, 16, 5, 5), mstype.float32) min_tensor = Tensor(np.array([-6]), mstype.float32) diff --git a/docs/programming_guide/source_zh_cn/operator_list.rst b/docs/programming_guide/source_zh_cn/operator_list.rst new file mode 100644 index 0000000000..23ec64f1a8 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/operator_list.rst @@ -0,0 +1,8 @@ +算子支持 +=========== + +.. toctree:: + :maxdepth: 1 + + operator_list_ms + operator_list_lite \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/operator_list_lite.md b/docs/programming_guide/source_zh_cn/operator_list_lite.md index 9360f8f626..a68dbe8b72 100644 --- a/docs/programming_guide/source_zh_cn/operator_list_lite.md +++ b/docs/programming_guide/source_zh_cn/operator_list_lite.md @@ -1,4 +1,4 @@ -# 算子支持 +# MindSpore Lite 算子支持 `Linux` `Ascend` `端侧` `推理应用` `初级` `中级` `高级` diff --git a/docs/programming_guide/source_zh_cn/operator_list.md b/docs/programming_guide/source_zh_cn/operator_list_ms.md similarity index 99% rename from docs/programming_guide/source_zh_cn/operator_list.md rename to docs/programming_guide/source_zh_cn/operator_list_ms.md index 49fe2ae19f..66b700633c 100644 --- a/docs/programming_guide/source_zh_cn/operator_list.md +++ b/docs/programming_guide/source_zh_cn/operator_list_ms.md @@ -1,10 +1,10 @@ -# 算子支持 +# MindSpore 算子支持 `Linux` `Ascend` `GPU` `CPU` `模型开发` `初级` `中级` `高级` -- [算子支持](#算子支持) +- [MindSpore 算子支持](#mindspore-算子支持) - [mindspore.nn](#mindsporenn) - [mindspore.ops.operations](#mindsporeopsoperations) - [mindspore.ops.functional](#mindsporeopsfunctional) diff --git a/docs/programming_guide/source_zh_cn/ops.md b/docs/programming_guide/source_zh_cn/ops.md index 53bb69f5df..58c7e1119f 100644 --- a/docs/programming_guide/source_zh_cn/ops.md +++ b/docs/programming_guide/source_zh_cn/ops.md @@ -9,7 +9,7 @@ - + MindSpore的ops模块主要存放算子相关接口,同时包含算子的校验和正反向关联的逻辑。 diff --git a/docs/programming_guide/source_zh_cn/optim.md b/docs/programming_guide/source_zh_cn/optim.md index 7a8ebb7096..58cb7fb2f5 100644 --- a/docs/programming_guide/source_zh_cn/optim.md +++ b/docs/programming_guide/source_zh_cn/optim.md @@ -1,52 +1,57 @@ -# optim模块 +# 优化算法 -- [优化器](#优化器) - - [概述](#概述) - - [学习率](#学习率) - - [dynamic_lr](#dynamic_lr) - - [learning_rate_schedule](#learning_rate_schedule) - - [optimzer](#optimzer) - - [如何使用](#如何使用) - - [内置优化器](#内置优化器) +- [优化算法](#优化算法) + - [概述](#概述) + - [学习率](#学习率) + - [dynamic_lr](#dynamic_lr) + - [learning_rate_schedule](#learning_rate_schedule) + - [Optimzer](#optimzer) + - [如何使用](#如何使用) + - [内置优化器](#内置优化器) - + ## 概述 -mindSpore.nn.optim是Mindspore框架中实现各种优化算法的模块,包含常用的优化器,学习率等,并且接口具备足够的通用性,可以将以后更新、更复杂的方法集成到模块里。 +`mindspore.nn.optim`是MindSpore框架中实现各种优化算法的模块,包含常用的优化器、学习率等,并且接口具备足够的通用性,可以将以后更新、更复杂的方法集成到模块里。 -mindspore.nn.optim为模型提供常用的优化器,如SGD、ADAM、Momentum。优化器用于计算和更新梯度,模型优化算法的选择直接关系到最终模型的性能,如果有时候效果不好,未必是特征或者模型设计的问题,很有可能是优化算法的问题; -同时还有mindspore.nn提供的学习率的模块,学习率learing_rate分为dynamic_lr和learning_rate_schedule,都是动态学习率,但是实现方式不同,学习率最为监督学习以及深度学习中重要的参数,其决定着目标函数是否能收敛到局部最小值以及何时能收敛到最小值。 -合适的学习率能够使目标函数在合适的的时间内收敛到局部最小值。 +`mindspore.nn.optim`为模型提供常用的优化器,如`SGD`、`ADAM`、`Momentum`。优化器用于计算和更新梯度,模型优化算法的选择直接关系到最终模型的性能,如果有时候效果不好,未必是特征或者模型设计的问题,很有可能是优化算法的问题;同时还有`mindspore.nn`提供的学习率的模块,学习率分为`dynamic_lr`和`learning_rate_schedule`,都是动态学习率,但是实现方式不同,学习率最为监督学习以及深度学习中重要的参数,其决定着目标函数是否能收敛到局部最小值以及何时能收敛到最小值。合适的学习率能够使目标函数在合适的的时间内收敛到局部最小值。 > 本文档中的所有示例,支持CPU,GPU,Ascend环境。 ## 学习率 ### dynamic_lr -mindspore.nn.dynamic_lr模块有以下几个类,piecewise_constant_lr类是得到分段不变的学习速率,exponential_decay_lr类是基于指数衰减函数计算学习率,natural_exp_decay_lr类是基于自然指数衰减函数计算学习率,inverse_decay_lr类是基于反时间衰减函数计算学习速率,cosine_decay_lr类是基于余弦衰减函数计算学习率,polynomial_decay_lr类是基于多项式衰减函数计算学习率,warmup_lr类是提高学习率,它们是属于dynamic_lr的不同实现方式。 +`mindspore.nn.dynamic_lr`模块有以下几个类: -例如piecewise_constant_lr类代码样例如下: +- `piecewise_constant_lr`类:基于得到分段不变的学习速率。 +- `exponential_decay_lr`类:基于指数衰减函数计算学习率。 +- `natural_exp_decay_lr`类:基于自然指数衰减函数计算学习率。 +- `inverse_decay_lr`类:基于反时间衰减函数计算学习速率。 +- `cosine_decay_lr`类:基于余弦衰减函数计算学习率。 +- `polynomial_decay_lr`类:基于多项式衰减函数计算学习率。 +- `warmup_lr`类:提高学习率。 -``` -class mindspore.nn.dynamic_lr.piecewise_constant_lr(milestone, learning_rates) +它们是属于`dynamic_lr`的不同实现方式。 -Parameters: - milestone (Union[list[int], tuple[int]]) – A list of milestone. This list is a monotone increasing list. Every element is a milestone step, and must be greater than 0. - learning_rates (Union[list[float], tuple[float]]) – A list of learning rates. +例如`piecewise_constant_lr`类代码样例如下: -Returns: - list[float]. The size of list ``` +from mindspore.nn.dynamic_lr import piecewise_constant_lr -``` -milestone = [2, 5, 10] -learning_rates = [0.1, 0.05, 0.01] -piecewise_constant_lr(milestone, learning_rates) +def test_dynamic_lr(): + milestone = [2, 5, 10] + learning_rates = [0.1, 0.05, 0.01] + lr = piecewise_constant_lr(milestone, learning_rates) + print(lr) + + +if __name__ == '__main__': + test_dynamic_lr() ``` 返回结果如下: @@ -56,49 +61,50 @@ piecewise_constant_lr(milestone, learning_rates) ### learning_rate_schedule -mindspore.nn.learning_rate_schedule模块下有以下几个类。ExponentialDecayLR类,NaturalExpDecayLR类,InverseDecayLR类,CosineDecayLR类,PolynomialDecayLR类,WarmUpLR类。它们都属于learning_rate_schedule,只是实现方式不同。 +`mindspore.nn.learning_rate_schedule`模块下有以下几个类:`ExponentialDecayLR`类、`NaturalExpDecayLR`类、`InverseDecayLR`类、`CosineDecayLR`类、`PolynomialDecayLR`类和`WarmUpLR`类。它们都属于`learning_rate_schedule`,只是实现方式不同,各自含义如下: -ExponentialDecayLR类是基于指数衰减函数计算学习率,NaturalExpDecayLR类是基于自然指数衰减函数巨酸学习率,InverseDecayLR类是基于反时间衰减函数计算学习速率,CosineDecayLR类是基于余弦衰减函数计算学习率,PolynomialDecayLR类是基于多项式衰减函数计算学习率,WarmUpLR类是提高学习率,它们是属于learning_rate_schedule的不同实现方式。 +- `ExponentialDecayLR`类:基于指数衰减函数计算学习率。 +- `NaturalExpDecayLR`类:基于自然指数衰减函数计算学习率。 +- `InverseDecayLR`类:基于反时间衰减函数计算学习速率。 +- `CosineDecayLR`类:基于余弦衰减函数计算学习率。 +- `PolynomialDecayLR`类:基于多项式衰减函数计算学习率。 +- `WarmUpLR`类:提高学习率。 + +它们是属于`learning_rate_schedule`的不同实现方式。 例如ExponentialDecayLR类代码样例如下: ``` -class ExponentialDecayLR(learning_rate, decay_rate, decay_steps, is_stair=False) +from mindspore.common import dtype as mstype +from mindspore import Tensor +from mindspore.nn.learning_rate_schedule import ExponentialDecayLR -Parameters: - learning_rate(float) - The initial value of learning rate. - decay_rate(float) - The decay rate. - decay_steps(int) - A value used to calculate decayed learning rate. - is_stair(bool) - if true,learning rate decay once every decay_steps times. Default: False. +def test_learning_rate_schedule(): + learning_rate = 0.1 # learning_rate(float) - The initial value of learning rate. + decay_rate = 0.9 # decay_rate(float) - The decay rate. + decay_steps = 4 # decay_steps(int) - A value used to calculate decayed learning rate. + global_step = Tensor(2, mystype.int32) + exponential_decay_lr = ExponentialDecayLR(learning_rate, decay_rate, decay_steps) + res = exponential_decay_lr(global_step) + print(res) -inputs: - Tensor.The current step number. -Returns: - Tensor. The learning rate value for the current step. +if __name__ == '__main__': + test_learning_rate_schedule() ``` +返回结果如下: ``` -from mindspore.common import dtype as mstype -from mindspore import Tensor - - -learning_rate = 0.1 # learning_rate(float) - The initial value of learning rate. -decay_rate = 0.9 # decay_rate(float) - The decay rate. -decay_steps = 4 # decay_steps(int) - A value used to calculate decayed learning rate. -global_step = Tensor(2, mystype.int32) -exponential_decay_lr = ExponentialDecayLR(learning_rate, decay_rate, decay_steps) -exponential_decay_lr(global_step) - +0.094868325 ``` -## optimzer +## Optimzer ### 如何使用 -为了使用mindspore.nn.optim,我们需要构建一个optimizer对象。这个对象能够保持当前参数状态并基于计算得到的梯度进行参数更新。 +为了使用`mindspore.nn.optim`,我们需要构建一个`Optimizer`对象。这个对象能够保持当前参数状态并基于计算得到的梯度进行参数更新。 - 构建 -为了构建一个Optimizer,我们需要给它一个包含可需要优化的参数(必须是Variable对象)的iterable。然后,你可以设置optimizer的参数选项,比如学习率,权重衰减等等。 +为了构建一个`Optimizer`,我们需要给它一个包含可需要优化的参数(必须是Variable对象)的iterable。然后,你可以设置Optimizer的参数选项,比如学习率,权重衰减等等。 代码样例如下: @@ -117,7 +123,7 @@ optim = nn.Adam(group_params, learning_rate=0.1, weight_decay=0.0) 优化器也支持为没个参数单独设置选项。若想这么做,不要直接传入变量Variable,而是传入一个字典的iterable。每一个字典都分别定义了一组参数,并且包含一个key键,这个key键对应相应的参数value值。其他的key键应该是优化器所接受的其他参数,并且会被用于对这组参数的优化。 我们仍然能够传递选项作为关键字参数,在未重写这些选项的组中,它们会被用作默认值。当你只想改动一个参数组的选项,但其他参数组的选项不变时,这是非常有用的。 -例如,当我们想制定每一层的学习率时,以SGD为例: +例如,当我们想制定每一层的学习率时,以`SGD`为例: ``` from mindspore import nn @@ -132,16 +138,16 @@ optim = nn.SGD([{'params': conv_params, 'weight_decay': 0.01}, ### 内置优化器 -深度学习优化算法大概常用的有SGD、Adam、Ftrl、lazyadam、Momentum、RMSprop、Lars、Proximal_ada_grad和lamb这几种。 -在mindspore.nn.optim模块中,他们都有对应的类实现。例如: +深度学习优化算法大概常用的有`SGD`、`Adam`、`Ftrl`、`lazyadam`、`Momentum`、`RMSprop`、`Lars`、`Proximal_ada_grad`和`lamb`这几种。 +在`mindspore.nn.optim`模块中,他们都有对应的类实现。例如: -- SGD,默认参数为纯SGD,设置momentum参数不为0,考虑了一阶动量,设置nesterov为True后变成NAG,即Nesterov Accelerated Gradient,在计算梯度时计算的是向前走一步所在位置的梯度。 +- `SGD`,默认参数为纯SGD,设置`momentum`参数不为0,考虑了一阶动量,设置`nesterov`为True后变成`NAG`,即`Nesterov Accelerated Gradient`,在计算梯度时计算的是向前走一步所在位置的梯度。 -- RMSprop,考虑了二阶动量,对于不同的参数有不同的学习率,即自适应学习率,对Adagrad进行了优化,通过指数平滑只考虑一定窗口内的二阶动量。 +- `RMSprop`,考虑了二阶动量,对于不同的参数有不同的学习率,即自适应学习率,对`Adagrad`进行了优化,通过指数平滑只考虑一定窗口内的二阶动量。 -- Adam,同时考虑了一阶动量和二阶动量,可以看成RMSprop上进一步考虑了一阶动量。 +- `Adam`,同时考虑了一阶动量和二阶动量,可以看成`RMSprop`上进一步考虑了一阶动量。 -例如SGD的代码样例如下: +例如`SGD`的代码样例如下: ``` from mindspore import nn diff --git a/docs/programming_guide/source_zh_cn/parameter.md b/docs/programming_guide/source_zh_cn/parameter.md index 4e6bf70213..8c093c9b4d 100644 --- a/docs/programming_guide/source_zh_cn/parameter.md +++ b/docs/programming_guide/source_zh_cn/parameter.md @@ -6,18 +6,16 @@ - [概述](#概述) - [初始化](#初始化) - [属性](#属性) - - [接口](#方法) + - [方法](#方法) - [ParameterTuple](#parametertuple) - - - + ## 概述 -Parameter是变量张量,代表在训练网络时,需要被更新的参数,是MetaTensor的一个子类。 +`Parameter`是变量张量,代表在训练网络时,需要被更新的参数。本章主要介绍了`Parameter`的初始化以及属性和方法的使用,同时介绍了`ParameterTuple`。 ## 初始化 ``` @@ -25,17 +23,19 @@ def __init__(self, default_input, name, requires_grad=True, layerwise_parallel=F ``` 初始化一个`Parameter`对象,传入的数据支持`Tensor`、`Initializer`、`int`和`float`四种类型。 -`Initializer`是初始化器,保存了shape和dtype信息,可调用`to_tensor`方法生成存有数据的Tensor。 +`Initializer`是初始化器,保存了shape和dtype信息,提供`to_tensor`方法生成存有数据的`Tensor`,可调用`initializer`接口生成`Initializer`对象。 -当网络采用半自动或者全自动并行策略,并且使用`Initializer`初始化`Parameter`时, -`Parameter`里保存的不是`Tensor`,而是`MetaTensor`。 +当网络采用半自动或者全自动并行策略,并且使用`Initializer`初始化`Parameter`时,`Parameter`里保存的不是`Tensor`,而是`MetaTensor`。 -`MetaTensor`与`Tensor`不同,`MetaTensor`仅保存张量的形状和类型,而不保存实际数据, -所以不会占用任何内存,可调用`init_data`接口将`Parameter`里保存的`MetaTensor`转化为`Tensor`。 +`MetaTensor`与`Tensor`不同,`MetaTensor`仅保存张量的形状和类型,而不保存实际数据,所以不会占用任何内存,可调用`init_data`接口将`Parameter`里保存的`MetaTensor`转化为`Tensor`。 可为每个`Parameter`指定一个名称,便于后续操作和更新。 -当`layerwise_parallel`为`True`时,参数广播和参数梯度聚合时会过滤掉该参数。 +当参数需要被更新时,需要将`requires_grad`设置为`True`。 + +当`layerwise_parallel`(混合并行)配置为True时,参数广播和参数梯度聚合时会过滤掉该参数。 + +有关分布式并行的相关配置,可以参考文档:。 下例通过三种不同的数据类型构造了`Parameter`,三个`Parameter`都需要更新,都不采用layerwise并行。如下: ``` @@ -64,6 +64,7 @@ Parameter (name=z, value=2.0) ``` ## 属性 + - `inited_param`:返回保存了实际数据的`Parameter`,如果`Parameter`原本保存的是`MetaTensor`,会将其转换为`Tensor`。 - `name`:实例化`Parameter`时,为其指定的名字。 @@ -75,7 +76,8 @@ Parameter (name=z, value=2.0) 如果是,就不再对其进行切分,如果不是,需要根据网络并行策略确认是否对其进行切分。 -- `is_init`:`Parameter`的初始化状态。 +- `is_init`:`Parameter`的初始化状态。在GE后端,Parameter需要一个`init graph`来从主机同步数据到设备侧,该标志表示数据是否已同步到设备。 + 此标志仅在GE后端起作用,其他后端将被设置为False。 - `layerwise_parallel`:`Parameter`是否支持layerwise并行。如果支持,参数就不会进行广播和梯度聚合,反之则需要。 @@ -124,7 +126,7 @@ data: Parameter (name=x, value=[[0 1 2] - `set_data`:设置`Parameter`保存的数据,支持传入`Tensor`、`Initializer`、`int`和`float`进行设置, 将slice_shape设置为True时,可改变`Parameter`的shape,反之,设置的数据shape必须与`Parameter`原来的shape保持一致。 -- `set_param_ps`:控制训练参数是否通过[Parameter Server](https://gitee.com/mindspore/docs/blob/master/tutorials/source_zh_cn/advanced_use/parameter_server_training.md)进行训练。 +- `set_param_ps`:控制训练参数是否通过[Parameter Server](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/parameter_server_training.html)进行训练。 - `clone`:克隆`Parameter`,需要指定克隆之后的参数名称。 diff --git a/docs/programming_guide/source_zh_cn/pipeline.md b/docs/programming_guide/source_zh_cn/pipeline.md index a7a4fdcb60..a3aeed918e 100644 --- a/docs/programming_guide/source_zh_cn/pipeline.md +++ b/docs/programming_guide/source_zh_cn/pipeline.md @@ -11,11 +11,10 @@ - [repeat](#repeat) - [zip](#zip) - [concat](#concat) - - [project](#project) - + ## 概述 @@ -45,37 +44,33 @@ MindSpore目前支持的常用数据处理算子如下表所示,更多数据 ![shuffle](./images/shuffle.png) -```python -# 将数据集进行混洗操作 +下面的样例先构建了一个随机数据集,然后对其进行混洗操作,最后展示了混洗后的数据结果。 +```python import numpy as np import mindspore.dataset as ds -# 设置全局随机种子,确保shuffle的行为可预测 ds.config.set_seed(0) -# 构建一个generator def generator_func(): for i in range(5): yield (np.array([i, i+1, i+2]),) -# 从generator中构建数据管道 dataset1 = ds.GeneratorDataset(generator_func, ["data"]) -# 为数据集创建一个混洗操作 -# buffer_size代表创建一个存放size个样本的容器,再从此容器中随机采样样本进行输出 -# 当buffer_size设置为dataset的长度时,是全局混洗 dataset1 = dataset1.shuffle(buffer_size=2) for data in dataset1.create_dict_iterator(): print(data) ``` +输出结果如下: + ``` -{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} -{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} -{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} -{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} -{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} +{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} ``` ### map @@ -86,13 +81,12 @@ for data in dataset1.create_dict_iterator(): ![map](./images/map.png) -```python -# 将数据集进行映射操作 +下面的样例先构建了一个随机数据集,然后定义了数据翻倍的映射函数并将其作用于数据集,最后对比展示了映射前后的数据结果。 +```python import numpy as np import mindspore.dataset as ds -# 构建一个generator def generator_func(): for i in range(5): yield (np.array([i, i+1, i+2]),) @@ -100,36 +94,33 @@ def generator_func(): def pyfunc(x): return x*2 -# 从generator中构建数据管道 dataset = ds.GeneratorDataset(generator_func, ["data"]) -# 创建数据管道,输出原始数据 for data in dataset.create_dict_iterator(): print(data) -print("") +print("------ after processing ------") -# 为数据集创建一个映射操作 -# input_columns指定要处理的列,operation指定映射函数 dataset = dataset.map(operations=pyfunc, input_columns=["data"]) -# 创建数据管道,输出映射后的数据 for data in dataset.create_dict_iterator(): print(data) ``` +输出结果如下: + ``` -{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} -{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} -{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} -{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} -{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} - -{'data': Tensor(shape=[3], dtype=Int64, value= [0, 2, 4])} -{'data': Tensor(shape=[3], dtype=Int64, value= [2, 4, 6])} -{'data': Tensor(shape=[3], dtype=Int64, value= [4, 6, 8])} -{'data': Tensor(shape=[3], dtype=Int64, value= [ 6, 8, 10])} -{'data': Tensor(shape=[3], dtype=Int64, value= [ 8, 10, 12])} +{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} +------ after processing ------ +{'data': Tensor(shape=[3], dtype=int64, value=[0, 2, 4])} +{'data': Tensor(shape=[3], dtype=int64, value=[2, 4, 6])} +{'data': Tensor(shape=[3], dtype=int64, value=[4, 6, 8])} +{'data': Tensor(shape=[3], dtype=int64, value=[ 6, 8, 10])} +{'data': Tensor(shape=[3], dtype=int64, value=[ 8, 10, 12])} ``` ### batch @@ -138,45 +129,40 @@ for data in dataset.create_dict_iterator(): ![batch](./images/batch.png) -```python -# 将数据集进行分批操作 +下面的样例先构建了一个随机数据集,然后分别展示了保留多余数据与否的数据集分批结果,其中批大小为2。 +```python import numpy as np import mindspore.dataset as ds -# 构建一个generator def generator_func(): for i in range(5): yield (np.array([i, i+1, i+2]),) -# 从generator中构建数据管道 dataset1 = ds.GeneratorDataset(generator_func, ["data"]) -# 为数据集划分批次,batch_size代表每2个样本为一个批次 -# drop_remainder代表是否丢弃最后不能完整构成批次的样本 -# 在此例子中,5%2=1,但因为drop_remainder=False,因此保留最后一个单独的样本 dataset1 = dataset1.batch(batch_size=2, drop_remainder=False) for data in dataset1.create_dict_iterator(): print(data) -print("") +print("------ drop remainder ------") -# 从generator中构建数据管道 dataset2 = ds.GeneratorDataset(generator_func, ["data"]) -# 丢弃最后不能完整构成批次的样本 dataset2 = dataset2.batch(batch_size=2, drop_remainder=True) for data in dataset2.create_dict_iterator(): print(data) ``` -``` -{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[0, 1, 2], [1, 2, 3]])} -{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[2, 3, 4], [3, 4, 5]])} -{'data': Tensor(shape=[1, 3], dtype=Int64, value= [[4, 5, 6]])} +输出结果如下: -{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[0, 1, 2], [1, 2, 3]])} -{'data': Tensor(shape=[2, 3], dtype=Int64, value= [[2, 3, 4], [3, 4, 5]])} +``` +{'data': Tensor(shape=[2, 3], dtype=int64, value=[[0, 1, 2], [1, 2, 3]])} +{'data': Tensor(shape=[2, 3], dtype=int64, value=[[2, 3, 4], [3, 4, 5]])} +{'data': Tensor(shape=[1, 3], dtype=int64, value=[[4, 5, 6]])} +------ drop remainder ------ +{'data': Tensor(shape=[2, 3], dtype=int64, value=[[0, 1, 2], [1, 2, 3]])} +{'data': Tensor(shape=[2, 3], dtype=int64, value=[[2, 3, 4], [3, 4, 5]])} ``` ### repeat @@ -187,38 +173,36 @@ for data in dataset2.create_dict_iterator(): ![repeat](./images/repeat.png) -```python -# 将数据集进行加倍操作 +下面的样例先构建了一个随机数据集,然后将其重复2次,最后展示了重复后的数据结果。 +```python import numpy as np import mindspore.dataset as ds -# 构建一个generator def generator_func(): for i in range(5): yield (np.array([i, i+1, i+2]),) -# 从generator中构建数据管道 dataset1 = ds.GeneratorDataset(generator_func, ["data"]) -# 为数据集创建一个加倍操作 -# count参数代表将数据集内容扩充为原来的count倍 dataset1 = dataset1.repeat(count=2) for data in dataset1.create_dict_iterator(): print(data) ``` +输出结果如下: + ``` -{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} -{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} -{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} -{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} -{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} -{'data': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2])} -{'data': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} -{'data': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4])} -{'data': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5])} -{'data': Tensor(shape=[3], dtype=Int64, value= [4, 5, 6])} +{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} +{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} ``` ### zip @@ -230,39 +214,36 @@ for data in dataset1.create_dict_iterator(): ![zip](./images/zip.png) -```python -# 将数据集进行合并操作 +下面的样例先构建了两个不同样本数的随机数据集,然后将其进行列拼接,最后展示了拼接后的数据结果。 +```python import numpy as np import mindspore.dataset as ds -# 构建一个generator def generator_func(): for i in range(7): yield (np.array([i, i+1, i+2]),) -# 构建另一个generator def generator_func2(): for i in range(4): yield (np.array([1, 2]),) -# 从generator中构建数据管道 dataset1 = ds.GeneratorDataset(generator_func, ["data1"]) dataset2 = ds.GeneratorDataset(generator_func2, ["data2"]) -# 为数据集创建一个合并操作 -# 新的dataset3会拥有2个列名,分别为data1,data2,同时因为data2的数据较少,会与data2的数据长度对齐 dataset3 = ds.zip((dataset1, dataset2)) for data in dataset3.create_dict_iterator(): print(data) ``` +输出结果如下: + ``` -{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=int64, value= [0, 1, 2]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=int64, value= [1, 2, 3]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=int64, value= [2, 3, 4]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=int64, value= [3, 4, 5]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} ``` ### concat @@ -273,84 +254,34 @@ for data in dataset3.create_dict_iterator(): ![concat](./images/concat.png) -```python -# 将数据集进行连接操作 +下面的样例先构建了两个随机数据集,然后将其进行行拼接,最后展示了拼接后的数据结果。值得一提的是,使用`+`运算符也能达到同样的效果。 +```python import numpy as np import mindspore.dataset as ds -# 构建一个generator def generator_func(): for i in range(2): yield (np.array([0, 0, 0]),) -# 构建另一个generator def generator_func2(): for i in range(2): yield (np.array([1, 2, 3]),) -# 从generator中构建数据管道 dataset1 = ds.GeneratorDataset(generator_func, ["data1"]) dataset2 = ds.GeneratorDataset(generator_func2, ["data1"]) -# 为数据集创建一个连接操作,将dataset2合并到dataset1的data1列中 dataset3 = dataset1.concat(dataset2) -# 值得一提的是,使用'+'运算符可以达到上面同样的效果 -# dataset3 = dataset1 + dataset2 - for data in dataset3.create_dict_iterator(): print(data) - -``` - -``` -{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} ``` -### project +输出结果如下: -对数据集列进行映射,将指定列按顺序保留并向下传递到数据管道中,其余列将被丢弃。 - ->`project`还可以用于改变column排列的顺序! - -![project](./images/project.png) - -```python -# 将数据集进行投影操作 - -import numpy as np -import mindspore.dataset as ds - -# 构建一个generator -def generator_func(): - for i in range(2): - yield (np.array([1, 2, 3]), np.array([7, 8, 9]), ) - -# 从generator中构建数据管道 -dataset = ds.GeneratorDataset(generator_func, ["data1", "data2"]) - -# 构建数据管道,获得原始数据 -for data in dataset.create_dict_iterator(): - print(data) - -print("") - -# 为数据集创建一个投影操作,只保留data1的数据 -dataset = dataset.project(columns=["data1"]) - -# 构建数据管道,获得投影后的数据 -for data in dataset.create_dict_iterator(): - print(data) ``` - -``` -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[3], dtype=Int64, value= [7, 8, 9])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[3], dtype=Int64, value= [7, 8, 9])} - -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} -{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data1': Tensor(shape=[3], dtype=int64, value= [0, 0, 0])} +{'data1': Tensor(shape=[3], dtype=int64, value= [0, 0, 0])} +{'data1': Tensor(shape=[3], dtype=int64, value= [1, 2, 3])} +{'data1': Tensor(shape=[3], dtype=int64, value= [1, 2, 3])} ``` diff --git a/docs/programming_guide/source_zh_cn/probability.md b/docs/programming_guide/source_zh_cn/probability.md new file mode 100644 index 0000000000..d47554f8ca --- /dev/null +++ b/docs/programming_guide/source_zh_cn/probability.md @@ -0,0 +1,1419 @@ +# 深度概率编程库编程指南 + + + +- [深度概率编程库编程指南](#深度概率编程库编程指南) + - [概率分布: mindspore.nn.probability.distribution](#概率分布-mindsporennprobabilitydistribution) + - [概率分布类](#概率分布类) + - [Distribution基类](#distribution基类) + - [伯努利分布Bernoulli](#伯努利分布bernoulli) + - [指数分布Exponential](#指数分布exponential) + - [几何分布Geometric](#几何分布geometric) + - [正态分布Normal](#正态分布normal) + - [均匀分布Uniform](#均匀分布uniform) + - [概率分布类在PyNative模式下的应用](#概率分布类在pynative模式下的应用) + - [概率分布类在图模式下的应用](#概率分布类在图模式下的应用) + - [概率分布映射: mindspore.nn.probability.bijector](#概率分布映射-mindsporennprobabilitybijector) + - [Bijector类接口设计](#bijector类接口设计) + - [Bijector基类](#bijector基类) + - [幂函数变换映射PowerTransform](#幂函数变换映射powertransform) + - [指数变换映射Exp](#指数变换映射exp) + - [标量仿射变换映射ScalarAffine](#标量仿射变换映射scalaraffine) + - [Softplus变换映射Softplus](#softplus变换映射softplus) + - [PyNative模式下调用Bijector实例](#pynative模式下调用bijector实例) + - [图模式下调用Bijector实例](#图模式下调用bijector实例) + - [TransformedDistribution类接口设计](#transformeddistribution类接口设计) + - [PyNative模式下调用TransformedDistribution实例](#pynative模式下调用transformeddistribution实例) + - [图模式下调用TransformedDistribution实例](#图模式下调用transformeddistribution实例) + - [深度概率网络:mindspore.nn.probability.dpn](#深度概率网络mindsporennprobabilitydpn) + - [VAE](#vae) + - [ConditionalVAE](#conditionalvae) + - [概率推断算法:mindspore.nn.probability.infer](#概率推断算法mindsporennprobabilityinfer) + - [贝叶斯层:mindspore.nn.probability.bnn_layers](#贝叶斯层mindsporennprobabilitybnn_layers) + - [定义模型](#定义模型) + - [训练模型](#训练模型) + - [贝叶斯转换:mindspore.nn.probability.transform](#贝叶斯转换mindsporennprobabilitytransform) + - [定义DNN模型](#定义dnn模型) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [实例化TransformToBNN](#实例化transformtobnn) + - [功能一:转换整个模型](#功能一转换整个模型) + - [功能二:转换指定类型的层](#功能二转换指定类型的层) + - [贝叶斯工具箱:mindspore.nn.probability.toolbox](#贝叶斯工具箱mindsporennprobabilitytoolbox) + + + + + +## 概率分布: mindspore.nn.probability.distribution + +概率分布是概率编程的基础。**Distribution** 类提供多样的概率统计接口, 例如概率密度函数 *pdf* 、累积密度函数*cdf* ,散度计算 *kl_loss* ,抽样 *sample* 等。现有的概率分布实例包括高斯分布,伯努利分布,指数型分布,几何分布和均匀分布。 + +### 概率分布类 + +- `Distribution`: 所有概率分布的基类。 + +- `Bernoulli`: 伯努利分布。参数为试验成功的概率。 + +- `Exponential`: 指数型分布。参数为率参数。 + +- `Geometric`: 几何分布。参数为一次伯努利试验成功的概率。 + +- `Normal`: 正态(高斯)分布。参数为均值和标准差。 + +- `Uniform`: 均匀分布。参数为数轴上的最小值和最大值。 + +#### Distribution基类 + +`Distribution` 继承`Cell`,是所有概率分布的基类。构造函数参数包括: + +- `seed`: 随机抽样种子。 +- `dtype`: 分布的数据类型。 +- `name`: 分布的名称。 +- `param`: 分布初始化时所用参数。 + +接口介绍:`Distribution`类支持的函数包括 `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`, `mean`, `sd`, `var`, `entropy`, `kl_loss`, `cross_entropy`,和 `sample`。分布不同,所需传入的参数也不同。只有在派生类中才能使用,由派生类的函数实现决定参数。 + +- `prob` : 概率密度函数(pdf)/ 概率质量函数(pmf) +- `log_prob` :对数似然函数。 +- `cdf` : 累积分布函数(cdf)。 +- `log_cdf` : 对数累积分布函数(cdf)。 +- `survival_function` : 生存函数。 +- `log_survival` : 对数生存函数。 +- `mean` : 均值。 +- `sd` : 标准差。 +- `var` : 方差。 +- `entropy` : 熵。 +- `kl_loss` : Kullback-Leibler散度。 +- `cross_entropy` : 两个概率分布的交叉熵。 +- `sample` : 概率分布的随机抽样。 + +#### 伯努利分布Bernoulli +伯努利分布,继承自 `Distribution` 类。构造函数参数如下: +- `probs`: 伯努利试验成功的概率。 +- `seed`: 随机种子。 +- `dtype`: 分布类型。 +- `name`: 分布名称。 + +Property: +- `Bernoulli.probs`: 伯努利试验成功的概率。 + +`Distribution` 基类调用 `Bernoulli` 中私有接口以实现基类中的公有接口。`Bernoulli` 支持的公有接口为 + +- `mean`, `mode`, `var`: 可选择传入 *probs1* 指定试验成功的概率。 +- `entropy`:可选择传入 *probs1* 指定试验成功的概率. +- `cross_entropy`, `kl_loss`:必须传入 *dist* 和 *probs1_b* 。*dist*: 另一分布类型的名称,目前只支持此处为 *‘Bernoulli’* , *probs1_b* 指定分布 *b* 的试验成功概率。可选择传入 *probs1_a* 分布 *a* 的参数。 +- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value* 。 可选择传入 *probs* 指定试验成功的概率。 +- `sample`: 可选择传入 *shape* 样本形状和 *probs1* 指定试验成功的概率。 + +#### 指数分布Exponential +指数分布,继承自`Distribution`类。其构造函数参数如下: +- `rate`: 分布的率参数。 +- `seed`: 随机种子。 +- `dtype`: 分布类型。 +- `name`: 分布名称。 + +Property: +- `Exponential.rate`: 率参数。 + +`Distribution` 基类调用 `Exponential` 私有接口以实现基类中的公有接口。`Exponential` 支持的公有接口为 + +- `mean`, `mode`, `var`: 可选择传入 *rate* 指定率参数 +- `entropy`:可选择传入 *rate* 指定率参数 +- `cross_entropy`, `kl_loss`:。必须传入 *dist* 和 *rate_b*. *dist*: 另一分布类型的名称, 目前只支持此处为 *‘Exponential’* ,*rate_b* 指定分布 *b* 的率参数。可选择传入 *rate_a* 分布 *a* 的参数. +- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value*,可选择传入 *rate* 指定率参数。 +- `sample`: 可选择传入 *shape* 样本形状,以及 *rate* 指定率参数。 + +#### 几何分布Geometric +几何分布,继承自`Distribution`类。其构造函数参数如下: +- `probs`: 伯努利试验成功的概率。 +- `seed`: 随机种子。 +- `dtype`: 分布类型。 +- `name`: 分布名称。 + +Property: +- `Geometric.probs`: 伯努利试验成功的概率。 + +`Distribution` 基类调用 `Geometric` 中私有接口以实现基类中的公有接口。`Geometric` 支持的公有接口为 + +- `mean`, `mode`, `var`: 可选择传入 *probs1* 指定试验成功的概率。 +- `entropy`:可选择传入 *probs1* 指定试验成功的概率. +- `cross_entropy`, `kl_loss`:必须传入 *dist* 和 *probs1_b* 。*dist*: 另一分布类型的名称,目前只支持此处为 *‘Geometric’* , *probs1_b* 指定分布 *b* 的试验成功概率。可选择传入 *probs1_a* 分布 *a* 的参数。 +- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value*。 可选择传入 *probs1* 指定试验成功的概率。 +- `sample`: 可选择传入 *shape* 样本形状和 *probs1* 指定试验成功的概率。 + +#### 正态分布Normal +正态(高斯)分布,继承自 **Distribution** 类。其构造函数参数如下: +- `mean`: 分布均值。 +- `sd`: 分布方差。 +- `seed`: 随机种子。 +- `dtype`: 分布类型。 +- `name`: 分布名称。 + +**Distribution** 基类调用 **Normal** 中私有接口以实现基类中的公有接口。**Normal** 支持的公有接口为 +- `mean`, `mode`, `var`: 可选择传入 *mean* 和 *sd* 指定分布的参数。 +- `entropy`:可选择传入 *mean* 和 *sd* 指定分布的参数。 +- `cross_entropy`, `kl_loss`:必须传入 *dist* ,*mean_b* 和 *sd_b*。*dist*: 另一分布类型的名称,目前只支持此处为 *‘Normal’* ,*mean_b* 和 *sd_b* 指定分布b的参数。可选择传入 *mean_a* 和 *sd_a* 指定分布的参数。 +- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value*。可选择传入 *mean* 和 *sd* 指定分布的参数。 +- `sample`: 可选择传入 *shape* 样本形状。可选择传入 *mean_a* 和 *sd_a* 指定分布的参数。 + +#### 均匀分布Uniform +均匀分布,继承自`Distribution`类。其构造函数参数如下: +- `low`: 最小值。 +- `high`: 最大值。 +- `seed`: 随机种子。 +- `dtype`: 分布类型。 +- `name`: 分布名称。 + +Property: +- `Uniform.low`: 最小值。 +- `Uniform.high`: 最大值。 + +`Distribution` 基类调用 `Uniform` 以实现基类中的公有接口。`Uniform` 支持的公有接口为 + +- `mean`, `mode`, `var`: 可选择传入 *high* 和 *low* 指定分布的参数。 +- `entropy`:可选择传入 *high* 和 *low* 指定分布的参数。 +- `cross_entropy`, `kl_loss`:必须传入 *dist* ,*high_b* 和 *low_b* 。*dist* : 另一分布类型的名称,目前只支持此处为 *‘Uniform’* ,*high_b* 和 *low_b* 指定分布 *b* 的参数。可选择传入 *high_a* 和 *low_a* 指定分布的参数。 +- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value* 。可选择传入 *high* 和 *low* 指定分布的参数。 +- `sample`: 可选择传入 *shape* 。 可选择传入 *high* 和 *low* 指定分布的参数。 + +### 概率分布类在PyNative模式下的应用 + +`Distribution`子类可在 **PyNative** 模式下使用。 +导入相关模块: + +```python +from mindspore import Tensor +from mindspore import dtype as mstype +import mindspore.context as context +import mindspore.nn.probability.distribution as msd +context.set_context(mode=context.PYNATIVE_MODE) +``` +以 **Normal** 为例, 创建一个均值为0.0 标准差为1.0 的正态分布: +```python +my_normal = msd.Normal(0.0, 1.0, dtype=mstype.float32) +``` +计算均值: +```python +mean = my_normal.mean() +print(mean) +``` +输出为: +``` +0.0 +``` +计算方差: +```python +var = my_normal.var() +print(var) +``` +输出为: +``` +1.0 +``` +计算熵: +```python +entropy = my_normal.entropy() +print(entropy) +``` +``` +1.4189385 +``` +计算 **pdf**: +```python +value = Tensor([-0.5, 0.0, 0.5], dtype=mstype.float32) +prob = my_normal.prob(value) +print(prob) +``` +输出为: +``` +[0.35206532, 0.3989423, 0.35206532] +``` +计算 **cdf**: +```python +cdf = my_normal.cdf(value) +print(cdf) +``` +输出为: +``` +[0.30852754, 0.5, 0.69146246] +``` +计算 **kl_loss**: +```python +mean_b = Tensor(1.0, dtype=mstype.float32) +sd_b = Tensor(2.0, dtype=mstype.float32) +kl = my_normal.kl_loss('Normal', mean_b, sd_b) +print(kl) +``` +输出为: +``` +0.44314718 +``` + +### 概率分布类在图模式下的应用 + +在图模式下,**Distribution**子类可用在网络中。 +导入相关模块: +```python +import mindspore.nn as nn +from mindspore import Tensor +from mindspore import dtype as mstype +import mindspore.context as context +import mindspore.nn.probability.distribution as msd +context.set_context(mode=context.GRAPH_MODE) +``` +创建网络: +```python +# 网络继承nn.Cell +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + # 创建 Normal 实例 + self.normal = msd.Normal(0.0, 1.0, dtype=mstype.float32) + + #定义计算 + def construct(self, value, mean, sd): + pdf = self.normal.prob(value) + kl = self.normal.kl_loss("Normal", mean, sd) + return pdf, kl +``` +调用网络 +```python +net = Net() +value = Tensor([-0.5, 0.0, 0.5], dtype=mstype.float32) +mean = Tensor(1.0, dtype=mstype.float32) +sd = Tensor(1.0, dtype=mstype.float32) +pdf, kl = net(value, mean, sd) +print("pdf: ", pdf) +print("kl: ", kl) +``` +输出为: +``` +pdf: [0.3520653, 0.39894226, 0.3520653] +kl: 0.5 +``` + +## 概率分布映射: mindspore.nn.probability.bijector + +Bijector是概率编程的基本组成部分。Bijector描述了一种随机变量的变换方法,可以通过一个已有的随机变量X和一个映射函数f生成一个新的随机变量Y = f(x)。 +`Bijector`提供了映射相关的四种变换方法。它可以当做算子直接使用,也可以作用在某个随机变量`Distribution`类实例上生成新的随机变量的`Distribution`类实例。 + +### Bijector类接口设计 + +#### Bijector基类 + +`Bijector`类是所有Bejictor的基类,继承自`Cell`基类。 + +* 基类构造函数__init__ + + 输入参数: + `is_constant_jacobian`:映射函数的导数是否常数,只在创建衍生类的时候使用,默认false。 + `is_injective`:射函数是否是单设,只在创建衍生类的时候使用,默认true。 + `name`:Bijector的名字,创建派生类后由派生类的具体函数名决定,只在创建衍生类的时候使用,可以接受输入为str。默认None。 + `dtype`:Bijector对应的函数的类型(自变量和因变量的数据类型),创建派生类后由由派生类的具体函数决定,只在创建衍生类的时候使用,默认为None。 + `param`:Bijector内部的参数,创建派生类后由由派生类的具体函数参数决定,只在创建衍生类的时候使用,默认为None。 + +* 类特征函数property +`name`:无参函数,返回`name`的值。 +`is_dtype`:无参函数,返回`dtype`的值。 +`parameter`:无参函数,返回`parameter`的值。 +`is_constant_jacobian`:无参函数,返回`is_constant_jacobian`的值。 +`is_injective`:无参函数,返回`is_injective`的值。 + +* 映射函数 +`forward (args)`:正向映射,创建派生类后由派生类的`_forward`决定参数。 +`inverse (args)`:反向映射,创建派生类后由派生类的`_inverse`决定参数。 +`forward_log_jacobian (args)`:正向映射的(log)导数,创建派生类后由派生类的`_forward_log_jacobian`决定参数。 +`inverse_log_jacobian (args)`:反向映射的(log)导数,创建派生类后由派生类的`_inverse_log_jacobian`决定参数。 + +* `Bijector` 作为函数调用: +输入是一个`Distribution`类:生成一个`TransformedDistribution`**(不可在图内调用)** +其他输入:内部使用,不对外开放。 + +#### 幂函数变换映射PowerTransform +`PowerTransform`做如下变量替换:Y = g(X) = (1 + X * c)^(1 / c)。 + +* `PowerTransform`构造函数`__init__` +输入参数: +`power`:`PowerTransform`双射类对象的指数,可以接受输入为scalar(int or float), 默认0。 +`name`:`PowerTransform`双射类对象的名字,可以接受输入为str。默认为“PowerTransform”。 +`param`:`PowerTransform`内部的参数,创建派生类后由由派生类(exp)的具体函数参数决定,只在创建衍生类的时候使用。默认为None。 + +* 类特征函数property +`power`:无参函数,返回power的值。 + +* 映射函数 +`forward (args)`:正向映射,输入为tensor。 +`inverse (args)`:反向映射,输入为tensor。 +`forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。 +`inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。 + +#### 指数变换映射Exp +`Exp`做如下变量替换:Y = g(X)= exp(X)。 + +* `Exp`构造函数`__init__` +输入参数: +`name`:Exp双射类对象的名字,可以接受输入为str。默认为“Exp”。 + +* 映射函数 +`forward (args)`:正向映射,输入为tensor。继承自父类`PowerTransform`双射。 +`inverse (args)`:反向映射,输入为tensor。继承自父类`PowerTransform`双射。 +`forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。继承自父类`PowerTransform`双射。 +`inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。继承自父类`PowerTransform`双射。 + +#### 标量仿射变换映射ScalarAffine +`ScalarAffine`做如下变量替换:Y = g(X) = a * X + b。 + +* `ScalarAffine`构造函数`__init__` +输入参数: +`scale`:ScalarAffine的斜率,可以接受输入为float, 默认1.0。 +`shift`:ScalarAffine的截距,可以接受输入为float, 默认0.0。 +`name`:ScalarAffine的名字,可以接受输入为str。默认“ScalarAffine”。 + +* 类特征函数property +`scale`:无参函数,返回scale的值。 +`shift`:无参函数,返回shift的值。 + +* 映射函数 +`forward (args)`:正向映射,输入为tensor。 +`inverse (args)`:反向映射,输入为tensor。 +`forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。 +`inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。 + +#### Softplus变换映射Softplus +`Softplus`做如下变量替换:Y = g(X) = \frac{\log(1 + e ^ {kX})}{k}。 + +* `Softplus`构造函数`__init__` +输入参数: +`sharpness`:Softplus的斜率,可以接受输入为float, 默认1.0。 +`name`:Softplus的名字,可以接受输入为str。默认“Softplus”。 +* 类特征函数property +`sharpness`:无参函数,返回sharpness的值。 +* 映射函数 + `forward (args)`:正向映射,输入为tensor。 + `inverse (args)`:反向映射,输入为tensor。 + `forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。 + `inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。 + +### PyNative模式下调用Bijector实例 + +PyNative模式类似于命令行调用,可以即时输入函数及其参数,完成函数调用。PyNative模式为异步执行,仅在访问函数结果时函数会被调用。 + +在执行之前,我们需要导入需要的库文件包。双射类最主要的库是`mindspore.nn.probability.bijector`,导入后我们使用`msb`作为库的缩写并进行调用。 + +导入相关模块: +```python +import numpy as np +import mindspore.nn as nn +import mindspore.nn.probability.bijector as msb +import mindspore.context as context +from mindspore import Tensor +from mindspore import dtype +context.set_context(mode=context.PYNATIVE_MODE) +``` + +通常我们并不直接构造基类`Bijector`,而是直接构造派生的子类,并调用子类对应的函数接口。下面我们以`PowerTransform`为例。 + +创建一个`powertransform`对象,初始化参数中power=2。 + +构造`PowerTransform`: +```python +powertransform = msb.PowerTransform(power=2) +powertransform +``` + +输出: +```python +PowerTransform +``` + +接下来可以使用映射函数进行运算。 + +调用`forward`方法,计算正向映射: +```python +x = np.array([2.0, 3.0, 4.0, 5.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +forward = powertransform.forward(tx) +foward +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [ 2.23606801e+00 2.64575124e+00 3.00000000e+00 3.31662488e+00]) +``` + +输入`inverse`方法,计算反向映射: +```python +inverse = powertransform.inverse(tx) +inverse +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [ 1.50000000e+00 4.00000048e+00 7.50000000e+00 1.20000010e+01]) +``` + +输入`forward_log_jacobian`方法,计算正向映射导数: +```python +forward_log_jaco = powertransform.forward_log_jacobian(tx) +forward_log_jaco +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [-8.04718971e-01 -9.72955048e-01 -1.09861231e+00 -1.19894767e+00]) +``` + +输入`inverse_log_jacobian`方法,计算正向映射导数: +```python +inverse_log_jaco = powertransform.inverse_log_jacobian(tx) +inverse_log_jaco +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [ 6.93147182e-01 1.09861231e+00 1.38629436e+00 1.60943794e+00]) +``` + +### 图模式下调用Bijector实例 + +在图模式下,`Bijector`子类可用在网络中。 + +导入相关模块: +```python +import mindspore.nn as nn +from mindspore import Tensor +from mindspore import dtype as mstype +import mindspore.context as context +import mindspore.nn.probability.Bijector as msb +context.set_context(mode=context.GRAPH_MODE) +``` + +创建网络: +```python +# 网络继承nn.Cell +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + # 创建PowerTransform实例 + self.powertransform = msb.PowerTransform(power=2) + + #定义计算 + def construct(self, value): + forward = self.s1.forward(value) + inverse = self.s1.inverse(value) + forward_log_jaco = self.s1.forward_log_jacobian(value) + inverse_log_jaco = self.s1.inverse_log_jacobian(value) + return forward, inverse, forward_log_jaco, inverse_log_jaco +``` +调用网络 +```python +net = Net() +x = np.array([2.0, 3.0, 4.0, 5.0]).astype(np.float32) +tx = Tensor(x, dtype=dtype.float32) +forward, inverse, forward_log_jaco, inverse_log_jaco = net(tx) +print("forward: ", forward) +print("inverse: ", inverse) +print("forward_log_jaco: ", forward_log_jaco) +print("inverse_log_jaco: ", inverse_log_jaco) +``` +输出为: +```python +forward: [2.236068 2.6457512 3. 3.3166249] +inverse: [ 1.5 4.0000005 7.5 12.000001 ] +forward_log_jaco: [-0.804719 -0.97295505 -1.0986123 -1.1989477 ] +inverse_log_jaco: [0.6931472 1.0986123 1.3862944 1.609438 ] +``` + +### TransformedDistribution类接口设计 + +`TransformedDistribution`继承自`Distribution`,是可通过映射f(x)变化得到的数学分布的基类。 + +* 构造函数`__init__` + + 输入参数: + `bijector`:分布的变换方法。可以接受输入为bijector的派生类,作为映射变换函数f。 + `distribution`:原始分布。可以接受输入为distribution的派生类,作为映射需要变换的分布类*X*。 + `seed`: 随机种子。 + `dtype`: 分布类型。 + `name`:分布名称。可以接受输入为str。默认为“transformed_distribution”。 + +* 类特征函数property +`bijector`:无参函数,返回分布的变换方法。 +`distribution`:无参函数,返回原始分布。 +`is_linear_transformation`:无参函数,返回线性变换标志。 + +* 接口函数 +`cdf`:累积分布函数(cdf)。 +`log_cdf`:对数累积分布函数(cdf)。 +`survival_function`:生存函数。与 cdf 互补。 +`log_survival`:对数生存函数。 +`prob`:概率密度函数(pdf)/ 概率质量函数(pmf)。 +`log_prob`:对数似然函数。 +`sample`:随机取样。必须传入shape,类型tuple。 +`mean`:无参数。只有当`Bijector.is_constant_jacobian=true`时可调用。 + +### PyNative模式下调用TransformedDistribution实例 + +`TransformedDistribution` 子类可在 **PyNative** 模式下使用。 +在执行之前,我们需要导入需要的库文件包。 + +导入相关模块: +```python +import numpy as np +import mindspore.nn as nn +import mindspore.nn.probability.bijector as msb +import mindspore.nn.probability.distribution as msd +import mindspore.context as context +from mindspore import Tensor +from mindspore import dtype +context.set_context(mode=context.PYNATIVE_MODE) +``` + +构造一个`TransformedDistribution`实例,使用Normal分布作为需要变换的分布类,使用Exp作为映射变换,可以生成`LogNormal`分布。 +```python +normal = msd.Normal(0.0, 1.0, dtype=dtype.float32) +exp = msb.Exp() +LogNormal = msd.TransformedDistribution(exp, normal, dtype=dtype.float32, seed=0, name="LogNormal") +LogNormal +``` + +输出: +```python +TransformedDistribution< + (_bijector): Exp + (_distribution): Normal + > +``` + +可以对`LogNormal`进行概率分布计算。例如: + +计算 **cdf** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +cdf = LogNormal.cdf(tx) +cdf +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [ 7.55891383e-01 9.46239710e-01 9.89348888e-01]) +``` + +计算 **log_cdf** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +log_cdf = LogNormal.log_cdf(tx) +log_cdf +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [-2.79857576e-01 -5.52593507e-02 -1.07082408e-02]) +``` + +计算 **survival_function** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +survival_function = LogNormal.survival_function(tx) +survival_function +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [ 2.44108617e-01 5.37602901e-02 1.06511116e-02]) +``` + +计算 **log_survival** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +log_survival = LogNormal.log_survival(tx) +log_survival +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [-1.41014194e+00 -2.92322016e+00 -4.54209089e+00]) +``` + +计算 **prob** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +prob = LogNormal.prob(tx) +prob +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [ 1.56874031e-01 2.18507163e-02 2.81590177e-03]) +``` + +计算 **log_prob** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +log_prob = LogNormal.log_prob(tx) +log_prob +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [-1.85231221e+00 -3.82352161e+00 -5.87247276e+00]) +``` + +调用取样函数 **sample** : +```python +shape = ((3, 2)) +sample = LogNormal.sample(shape) +sample +``` + +输出: +```python +Tensor(shape=[3, 2], dtype=Float32, +[[ 7.64315844e-01 3.01435232e-01] + [ 1.17166102e+00 2.60277224e+00] + [ 7.02699006e-01 3.91564220e-01]]) +``` + +### 图模式下调用TransformedDistribution实例 + +在图模式下,**TransformedDistribution**子类可用在网络中。 + +导入相关模块: +```python +import mindspore.nn as nn +from mindspore import Tensor +from mindspore import dtype +import mindspore.context as context +import mindspore.nn.probability.Bijector as msb +import mindspore.nn.probability.Distribution as msd +context.set_context(mode=self.GRAPH_MODE) +``` + +创建网络: +```python +# 网络继承nn.Cell +class Net(nn.Cell): + def __init__(self, shape, dtype=dtype.float32, seed=0, name='transformed_distribution'): + super(Net, self).__init__() + # 创建TransformedDistribution实例 + self.exp = msb.Exp() + self.normal = msd.Normal(0.0, 1.0, dtype=dtype) + self.lognormal = msd.TransformedDistribution(self.exp, self.normal, dtype=dtype, seed=seed, name=name) + self.shape = shape + + #定义计算cdf,以及随机取样 + def construct(self, value): + cdf = self.lognormal.cdf(value) + sample = self.lognormal.sample(self.shape) + return cdf, sample +``` + +调用网络 +```python +shape = (2, 3) +net = Net(shape=shape, name="LogNormal") +x = np.array([2.0, 3.0, 4.0, 5.0]).astype(np.float32) +tx = Tensor(x, dtype=dtype.float32) +cdf, sample = net(tx) +print("cdf: ", cdf) +print("sample: ", sample) +``` +输出为: +```python +cdf: [0.7558914 0.8640314 0.9171715 0.9462397] +sample: [[0.21036398 0.44932044 0.5669641 ] + [1.4103683 6.724116 0.97894996]] +``` + +## 深度概率网络:mindspore.nn.probability.dpn + +使用MindSpore深度概率编程库来构造变分自编码器(VAE)进行推理尤为简单。我们只需要自定义编码器和解码器(DNN模型),调用VAE或CVAE接口形成其派生网络,然后调用ELBO接口进行优化,最后使用SVI接口进行变分推理。这样做的好处是,不熟悉变分推理的用户可以像构建DNN模型一样来构建概率模型,而熟悉的用户可以调用这些接口来构建更为复杂的概率模型。VAE的接口在`mindspore.nn.probability.dpn`下面,dpn代表的是Deep probabilistic network,这里提供了一些基本的深度概率网络的接口,例如VAE。 + +### VAE + +首先,我们需要先自定义encoder和decoder,调用`mindspore.nn.probability.dpn.VAE`接口来构建VAE网络,我们除了传入encoder和decoder之外,还需要传入encoder输出变量的维度hidden size,以及VAE网络存储潜在变量的维度latent size,一般latent size会小于hidden size。 + +```python +import mindspore.nn as nn +from mindspore.ops import operations as P +from mindspore.nn.probability.dpn import VAE + +IMAGE_SHAPE = (-1, 1, 32, 32) + + +class Encoder(nn.Cell): + def __init__(self): + super(Encoder, self).__init__() + self.fc1 = nn.Dense(1024, 800) + self.fc2 = nn.Dense(800, 400) + self.relu = nn.ReLU() + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + return x + + +class Decoder(nn.Cell): + def __init__(self): + super(Decoder, self).__init__() + self.fc1 = nn.Dense(400, 1024) + self.sigmoid = nn.Sigmoid() + self.reshape = P.Reshape() + + def construct(self, z): + z = self.fc1(z) + z = self.reshape(z, IMAGE_SHAPE) + z = self.sigmoid(z) + return z + + +encoder = Encoder() +decoder = Decoder() +vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) +``` +### ConditionalVAE + +类似地,ConditionalVAE与VAE的使用方法比较相近,不同的是,ConditionalVAE利用了数据集的标签信息,属于有监督学习算法,其生成效果一般会比VAE好。 + +首先,先自定义encoder和decoder,并调用`mindspore.nn.probability.dpn.ConditionalVAE`接口来构建ConditionalVAE网络,这里的encoder和VAE的不同,因为需要传入数据集的标签信息;decoder和上述的一样。ConditionalVAE接口的传入则还需要传入数据集的标签类别个数,其余和VAE接口一样。 + +``` +import mindspore.nn as nn +from mindspore.ops import operations as P +from mindspore.nn.probability.dpn import ConditionalVAE + +IMAGE_SHAPE = (-1, 1, 32, 32) + + +class Encoder(nn.Cell): + def __init__(self, num_classes): + super(Encoder, self).__init__() + self.fc1 = nn.Dense(1024 + num_classes, 400) + self.relu = nn.ReLU() + self.flatten = nn.Flatten() + self.concat = P.Concat(axis=1) + self.one_hot = nn.OneHot(depth=num_classes) + + def construct(self, x, y): + x = self.flatten(x) + y = self.one_hot(y) + input_x = self.concat((x, y)) + input_x = self.fc1(input_x) + input_x = self.relu(input_x) + return input_x + + +class Decoder(nn.Cell): + def __init__(self): + super(Decoder, self).__init__() + self.fc1 = nn.Dense(400, 1024) + self.sigmoid = nn.Sigmoid() + self.reshape = P.Reshape() + + def construct(self, z): + z = self.fc1(z) + z = self.reshape(z, IMAGE_SHAPE) + z = self.sigmoid(z) + return z + + +encoder = Encoder(num_classes=10) +decoder = Decoder() +cvae = ConditionalVAE(encoder, decoder, hidden_size=400, latent_size=20, num_classes=10) +``` + +加载数据集,我们可以使用Mnist数据集,具体的数据加载和预处理过程可以参考这里[Implementing an Image Classification Application](https://www.mindspore.cn/tutorial/en/master/quick_start/quick_start.html),这里会用到create_dataset函数创建数据迭代器。 + +```python +ds_train = create_dataset(image_path, 128, 1) +``` +接下来,需要用到infer接口进行VAE网络的变分推断。 + +## 概率推断算法:mindspore.nn.probability.infer + +调用ELBO接口(`mindspore.nn.probability.infer.ELBO`)来定义VAE网络的损失函数,调用`WithLossCell`封装VAE网络和损失函数,并定义优化器,之后传入SVI接口(`mindspore.nn.probability.infer.SVI`)。SVI的`run`函数可理解为VAE网络的训练,可以指定训练的`epochs`,返回结果为训练好的网络;`get_train_loss`函数可以返回训练好后模型的loss。 + +```python +from mindspore.nn.probability.infer import ELBO, SVI + +net_loss = ELBO(latent_prior='Normal', output_prior='Normal') +net_with_loss = nn.WithLossCell(vae, net_loss) +optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) + +vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) +vae = vi.run(train_dataset=ds_train, epochs=10) +trained_loss = vi.get_train_loss() +``` +最后,得到训练好的VAE网络后,我们可以使用`vae.generate_sample`生成新样本,需要传入待生成样本的个数,及生成样本的shape,shape需要保持和原数据集中的样本shape一样;当然,我们也可以使用`vae.reconstruct_sample`重构原来数据集中的样本,来测试VAE网络的重建能力。 +```python +generated_sample = vae.generate_sample(64, IMAGE_SHAPE) +for sample in ds_train.create_dict_iterator(): + sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) + reconstructed_sample = vae.reconstruct_sample(sample_x) +print('The shape of the generated sample is ', generated_sample.shape) +``` +我们可以看一下新生成样本的shape: +``` +The shape of the generated sample is (64, 1, 32, 32) +``` +ConditionalVAE训练过程和vae的过程类似,但需要注意的是使用训练好的ConditionalVAE网络生成新样本和重建新样本时,需要输入标签信息,例如下面生成的新样本就是64个0-7的数字。 + +``` +sample_label = Tensor([i for i in range(0, 8)] * 8, dtype=mstype.int32) +generated_sample = cvae.generate_sample(sample_label, 64, IMAGE_SHAPE) +for sample in ds_train.create_dict_iterator(): + sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) + sample_y = Tensor(sample['label'].asnumpy(), dtype=mstype.int32) + reconstructed_sample = cvae.reconstruct_sample(sample_x, sample_y) +print('The shape of the generated sample is ', generated_sample.shape) +``` +查看一下新生成的样本的shape: +``` +The shape of the generated sample is (64, 1, 32, 32) +``` + +如果希望新生成的样本更好,更清晰,用户可以自己定义更复杂的encoder和decoder,这里的示例只用了两层全连接层,仅供示例的指导。 + +## 贝叶斯层:mindspore.nn.probability.bnn_layers + +下面的范例使用MindSpore的`nn.probability.bnn_layers`中的API实现BNN图片分类模型。MindSpore的`nn.probability.bnn_layers`中的API包括`NormalPrior`,`NormalPosterior`,`ConvReparam`,`DenseReparam`和`WithBNNLossCell`。 + +- ### 处理数据 + +``` +import mindspore.dataset as ds +import mindspore.dataset.transforms.vision.c_transforms as CV +import mindspore.dataset.transforms.c_transforms as C +from mindspore.dataset.transforms.vision import Inter +from mindspore.common import dtype as mstype + + +def create_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1): + """ + create dataset for train or test + """ + # 定义数据集 + mnist_ds = ds.MnistDataset(data_path) + + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + rescale_nml = 1 / 0.3081 + shift_nml = -1 * 0.1307 / 0.3081 + + # 定义映射操作 + resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) + rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = C.TypeCast(mstype.int32) + + # 对图像应用映射操作 + mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) + + # 应用DatasetOps + buffer_size = 10000 + mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script + mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True) + mnist_ds = mnist_ds.repeat(repeat_size) + + return mnist_ds + +``` +### 定义模型 + +利用bnn_layers构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,bnn_layers和普通的神经网络层可以互相组合。当网络中包含bnn_layers时,需要将`WithLossCel`l替换为适用于BNN的`WithBNNLossCell`。除了`backbone`和`loss_fn`两个参数之外,`WithBNNLossCell`增加了`dnn_factor`和`bnn_factor`两个参数。`dnn_factor`是由损失函数计算得到的网络整体损失的系数,`bnn_factor`是每个贝叶斯层的KL散度的系数,这两个参数是用来平衡网络整体损失和贝叶斯层的KL散度的,防止KL散度的值过大掩盖了网络整体损失。 + +``` +import mindspore.nn as nn +from mindspore.nn.probability import bnn_layers +from mindspore.ops import operations as P + +class BNNLeNet5(nn.Cell): + def __init__(self, num_class=10): + super(BNNLeNet5, self).__init__() + self.num_class = num_class + self.conv1 = bnn_layers.ConvReparam(1, 6, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") + self.conv2 = bnn_layers.ConvReparam(6, 16, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") + self.fc1 = bnn_layers.DenseReparam(16 * 5 * 5, 120, activation=nn.ReLU()) + self.fc2 = bnn_layers.DenseReparam(120, 84) + self.fc3 = bnn_layers.DenseReparam(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x + +network = BNNLeNet5() +# 定义损失函数 +criterion = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") +# 定义优化器 +optimizer = nn.AdamWeightDecay(params=network.trainable_params(), learning_rate=0.001) +net_with_loss = bnn_layers.WithBNNLossCell(network, criterion, dnn_factor=60000, bnn_factor=0.00001) +train_bnn_network = TrainOneStepCell(net_with_loss, optimizer) +train_bnn_network.set_train() +``` +### 训练模型 + +``` +def train_model(train_net, net, dataset): + accs = [] + loss_sum = 0 + for i, data in enumerate(dataset.create_dict_iterator()): + train_x = Tensor(data['image'].asnumpy().astype(np.float32)) + label = Tensor(data['label'].asnumpy().astype(np.int32)) + loss = train_net(train_x, label) + output = net(train_x) + log_output = P.LogSoftmax(axis=1)(output) + acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) + accs.append(acc) + loss_sum += loss.asnumpy() + + loss_sum = loss_sum / len(accs) + acc_mean = np.mean(accs) + return loss_sum, acc_mean + + +def validate_model(net, dataset): + accs = [] + for _, data in enumerate(dataset.create_dict_iterator()): + train_x = Tensor(data['image'].asnumpy().astype(np.float32)) + label = Tensor(data['label'].asnumpy().astype(np.int32)) + output = net(train_x) + log_output = P.LogSoftmax(axis=1)(output) + acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) + accs.append(acc) + + acc_mean = np.mean(accs) + return acc_mean + +train_set = create_dataset('./mnist_data/train', 64, 1) +test_set = create_dataset('./mnist_data/test', 64, 1) + +epoch = 10 + +for i in range(epoch): + train_loss, train_acc = train_model(train_bnn_network, network, train_set) + + valid_acc = validate_model(network, test_set) + + print('Epoch: {} \tTraining Loss: {:.4f} \tTraining Accuracy: {:.4f} \tvalidation Accuracy: {:.4f}'.format( + i, train_loss, train_acc, valid_acc)) +``` + + +``` +Epoch 0 Training Loss 12925.5249 Training Accuracy 0.9413 validation Accuracy 0.9279 +Epoch 1 Training Loss 5287.0440 Training Accuracy 0.9771 validation Accuracy 0.9592 +Epoch 2 Training Loss 4186.9598 Training Accuracy 0.9821 validation Accuracy 0.9786 +Epoch 3 Training Loss 3538.2411 Training Accuracy 0.9857 validation Accuracy 0.9696 +Epoch 4 Training Loss 3255.8431 Training Accuracy 0.9869 validation Accuracy 0.9756 +Epoch 5 Training Loss 2880.1353 Training Accuracy 0.9880 validation Accuracy 0.9792 +Epoch 6 Training Loss 2569.0690 Training Accuracy 0.9897 validation Accuracy 0.9802 +Epoch 7 Training Loss 2391.5061 Training Accuracy 0.9906 validation Accuracy 0.9825 +Epoch 8 Training Loss 2165.1392 Training Accuracy 0.9912 validation Accuracy 0.9794 +Epoch 9 Training Loss 1910.2262 Training Accuracy 0.9931 validation Accuracy 0.9833 +``` + +## 贝叶斯转换:mindspore.nn.probability.transform + +对于不熟悉贝叶斯模型的DNN研究人员,MDP提供了高级API`TransformToBNN`,支持DNN模型一键转换成BNN模型。 + +### 定义DNN模型 + +本例使用的DNN模型是LeNet。 + +``` +from mindspore.common.initializer import TruncatedNormal +import mindspore.nn as nn +import mindspore.ops.operations as P + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + """weight initial for conv layer""" + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + """weight initial for fc layer""" + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + """weight initial""" + return TruncatedNormal(0.02) + + +class LeNet5(nn.Cell): + """ + Lenet network + + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + Examples: + >>> LeNet5(num_class=10) + + """ + def __init__(self, num_class=10): + super(LeNet5, self).__init__() + self.num_class = num_class + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16 * 5 * 5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` +LeNet网络结构如下: + +``` +LeNet5 + (conv1) Conv2dinput_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (conv2) Conv2dinput_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (fc1) Densein_channels=400, out_channels=120, weight=Parameter (name=fc1.weight), has_bias=True, bias=Parameter (name=fc1.bias) + (fc2) Densein_channels=120, out_channels=84, weight=Parameter (name=fc2.weight), has_bias=True, bias=Parameter (name=fc2.bias) + (fc3) Densein_channels=84, out_channels=10, weight=Parameter (name=fc3.weight), has_bias=True, bias=Parameter (name=fc3.bias) + (relu) ReLU + (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID + (flatten) Flatten + +``` + +### 定义损失函数和优化器 + +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,Adam作为优化器。 + +``` +network = LeNet5() + +# loss function definition +criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + +# optimization definition +optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) + +net_with_loss = WithLossCell(network, criterion) +train_network = TrainOneStepCell(net_with_loss, optimizer) +``` +### 实例化TransformToBNN + +`TransformToBNN`的`__init__`函数定义如下: + +``` +class TransformToBNN: + def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): + net_with_loss = trainable_dnn.network + self.optimizer = trainable_dnn.optimizer + self.backbone = net_with_loss.backbone_network + self.loss_fn = getattr(net_with_loss, "_loss_fn") + self.dnn_factor = dnn_factor + self.bnn_factor = bnn_factor + self.bnn_loss_file = None +``` +参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 +MindSpore中实例化`TransformToBNN`的代码如下: + +``` +from mindspore.nn.probability import transforms + +bnn_transformer = transforms.TransformToBNN(train_network, 60000, 0.000001) +``` +#### 功能一:转换整个模型 +`transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下 + +``` + def transform_to_bnn_model(self, + get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, + "out_channels": dp.out_channels, "activation": dp.activation}, + get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, + "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, + "stride": dp.stride, "has_bias": dp.has_bias, + "padding": dp.padding, "dilation": dp.dilation, + "group": dp.group}, + add_dense_args=None, + add_conv_args=None): + r""" + Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. + + Args: + get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. + get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, + "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. + add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. + add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. + + Returns: + Cell, a trainable BNN model wrapped by TrainOneStepCell. + """ + +``` +参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 +在MindSpore中将整个DNN模型转换成BNN模型的代码如下: + +``` +train_bnn_network = bnn_transformer.transform_to_bnn_model() +``` +整个模型转换后的结构如下: + +``` +LeNet5 + (conv1) ConvReparam + in_channels=1, out_channels=6, kernel_size=(5, 5), stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, weight_mean=Parameter (name=conv1.weight_posterior.mean), weight_std=Parameter (name=conv1.weight_posterior.untransformed_std), has_bias=False + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (conv2) ConvReparam + in_channels=6, out_channels=16, kernel_size=(5, 5), stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, weight_mean=Parameter (name=conv2.weight_posterior.mean), weight_std=Parameter (name=conv2.weight_posterior.untransformed_std), has_bias=False + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc1) DenseReparam + in_channels=400, out_channels=120, weight_mean=Parameter (name=fc1.weight_posterior.mean), weight_std=Parameter (name=fc1.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc1.bias_posterior.mean), bias_std=Parameter (name=fc1.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc2) DenseReparam + in_channels=120, out_channels=84, weight_mean=Parameter (name=fc2.weight_posterior.mean), weight_std=Parameter (name=fc2.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc2.bias_posterior.mean), bias_std=Parameter (name=fc2.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc3) DenseReparam + in_channels=84, out_channels=10, weight_mean=Parameter (name=fc3.weight_posterior.mean), weight_std=Parameter (name=fc3.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc3.bias_posterior.mean), bias_std=Parameter (name=fc3.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (relu) ReLU + (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID + (flatten) Flatten + +``` + +#### 功能二:转换指定类型的层 +`transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(`nn.Dense`或者`nn.Conv2d`)转换为对应的贝叶斯层。其定义如下 + +``` + def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): + r""" + Transform a specific type of layers in DNN model to corresponding BNN layer. + + Args: + dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are + nn.Dense, nn.Conv2d. + bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are + DenseReparameterization, ConvReparameterization. + get_args (dict): The arguments gotten from the DNN layer. Default: None. + add_args (dict): The new arguments added to BNN layer. Default: None. + + Returns: + Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. + """ +``` +参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 +在MindSpore中将DNN模型中的Dense层转换成相应贝叶斯层`DenseReparam`的代码如下: + +``` +train_bnn_network = bnn_transformer.transform_to_bnn_layer(nn.Dense, bnn_layers.DenseReparam) +``` +转换后的结构如下: + +``` +LeNet5 + (conv1) Conv2dinput_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (conv2) Conv2dinput_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (fc1) DenseReparam + in_channels=400, out_channels=120, weight_mean=Parameter (name=fc1.weight_posterior.mean), weight_std=Parameter (name=fc1.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc1.bias_posterior.mean), bias_std=Parameter (name=fc1.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc2) DenseReparam + in_channels=120, out_channels=84, weight_mean=Parameter (name=fc2.weight_posterior.mean), weight_std=Parameter (name=fc2.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc2.bias_posterior.mean), bias_std=Parameter (name=fc2.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc3) DenseReparam + in_channels=84, out_channels=10, weight_mean=Parameter (name=fc3.weight_posterior.mean), weight_std=Parameter (name=fc3.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc3.bias_posterior.mean), bias_std=Parameter (name=fc3.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (relu) ReLU + (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID + (flatten) Flatten + +``` + +## 贝叶斯工具箱:mindspore.nn.probability.toolbox + +贝叶斯神经网络的优势之一就是可以获取不确定性,MDP在上层提供了不确定性估计的工具箱,用户可以很方便地使用该工具箱计算不确定性。不确定性意味着深度学习模型不知道什么。目前,大多数深度学习算法只能给出高置信度的预测结果,而不能判断预测结果的确定性,不确定性主要有两种类型:偶然不确定性和认知不确定性。 + +- 偶然不确定性(Aleatoric Uncertainty):描述数据中的内在噪声,即无法避免的误差,这个现象不能通过增加采样数据来削弱。 +- 认知不确定性(Epistemic Uncertainty):模型自身对输入数据的估计可能因为训练不佳、训练数据不够等原因而不准确,可以通过增加训练数据等方式来缓解。 + +不确定性评估工具箱的接口如下: +- `model`: 待评估不确定性的已训练好的模型。 +- `train_dataset`: 用于训练的数据集,迭代器类型。 +- `task_type`: 模型的类型,字符串,输入“regression”或者“classification”。 +- `num_classes`: 如果是分类模型,需要指定类别的标签数量。 +- `epochs`: 用于训练不确定模型的迭代数。 +- `epi_uncer_model_path`: 用于存储或加载计算认知不确定性的模型的路径。 +- `ale_uncer_model_path`: 用于存储或加载计算偶然不确定性的模型的路径。 +- `save_model`: 布尔类型,是否需要存储模型。 + +在使用前,需要先训练好模型,以LeNet5为例,使用方式如下: +``` +from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation +from mindspore.train.serialization import load_checkpoint, load_param_into_net + +if __name__ == '__main__': + # get trained model + network = LeNet5() + param_dict = load_checkpoint('checkpoint_lenet.ckpt') + load_param_into_net(network, param_dict) + # get train and eval dataset + ds_train = create_dataset('workspace/mnist/train') + ds_eval = create_dataset('workspace/mnist/test') + evaluation = UncertaintyEvaluation(model=network, + train_dataset=ds_train, + task_type='classification', + num_classes=10, + epochs=1, + epi_uncer_model_path=None, + ale_uncer_model_path=None, + save_model=False) + for eval_data in ds_eval.create_dict_iterator(): + eval_data = Tensor(eval_data['image'].asnumpy(), mstype.float32) + epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) + aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) + print('The shape of epistemic uncertainty is ', epistemic_uncertainty.shape) + print('The shape of epistemic uncertainty is ', aleatoric_uncertainty.shape) +``` +`eval_epistemic_uncertainty`计算的是认知不确定性,也叫模型不确定性,对于每一个样本的每个预测标签都会有一个不确定值;`eval_aleatoric_uncertainty`计算的是偶然不确定性,也叫数据不确定性,对于每一个样本都会有一个不确定值。 +所以输出为: + +``` +The shape of epistemic uncertainty is (32, 10) +The shape of epistemic uncertainty is (32,) +``` \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/run.md b/docs/programming_guide/source_zh_cn/run.md new file mode 100644 index 0000000000..fe4b30d3f4 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/run.md @@ -0,0 +1,372 @@ +# 运行方式 + + + +- [运行方式](#运行方式) + - [概述](#概述) + - [执行单算子](#执行单算子) + - [执行普通函数](#执行普通函数) + - [执行网络模型](#执行网络模型) + - [执行训练模型](#执行训练模型) + - [执行推理模型](#执行推理模型) + + + + + +## 概述 +执行主要有三种方式:单算子、普通函数和网络训练模型。 + + +## 执行单算子 + +执行单个算子,并打印相关结果。 + +代码样例如下: +```python +import numpy as np +import mindspore.nn as nn +from mindspore import context, Tensor + +context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + +conv = nn.Conv2d(3, 4, 3, bias_init='zeros') +input_data = Tensor(np.ones([1, 3, 5, 5]).astype(np.float32)) +output = conv(input_data) +print(output.asnumpy()) +``` + +输出如下: +```python +[[[[ 0.06022915 0.06149777 0.06149777 0.06149777 0.01145121] + [ 0.06402162 0.05889071 0.05889071 0.05889071 -0.00933781] + [ 0.06402162 0.05889071 0.05889071 0.05889071 -0.00933781] + [ 0.06402162 0.05889071 0.05889071 0.05889071 -0.00933781] + [ 0.02712326 0.02096302 0.02096302 0.02096302 -0.01119636]] + + [[-0.0258286 -0.03362969 -0.03362969 -0.03362969 -0.00799183] + [-0.0513729 -0.06778982 -0.06778982 -0.06778982 -0.03168458] + [-0.0513729 -0.06778982 -0.06778982 -0.06778982 -0.03168458] + [-0.0513729 -0.06778982 -0.06778982 -0.06778982 -0.03168458] + [-0.04186669 -0.07266843 -0.07266843 -0.07266843 -0.04836193]] + + [[-0.00840744 -0.03043237 -0.03043237 -0.03043237 0.00172079] + [ 0.00401019 -0.03755453 -0.03755453 -0.03755453 -0.00851137] + [ 0.00401019 -0.03755453 -0.03755453 -0.03755453 -0.00851137] + [ 0.00401019 -0.03755453 -0.03755453 -0.03755453 -0.00851137] + [ 0.00270888 -0.03718876 -0.03718876 -0.03718876 -0.03043662]] + + [[-0.00982172 0.02009856 0.02009856 0.02009856 0.03327979] + [ 0.02529106 0.04035065 0.04035065 0.04035065 0.01782833] + [ 0.02529106 0.04035065 0.04035065 0.04035065 0.01782833] + [ 0.02529106 0.04035065 0.04035065 0.04035065 0.01782833] + [ 0.01015155 0.00781826 0.00781826 0.00781826 -0.02884173]]]] +``` + + +## 执行普通函数 + +将若干算子组合成一个函数,然后直接通过函数调用的方式执行这些算子,并打印相关结果,如下例所示。 + +代码样例如下: +```python +import numpy as np +from mindspore import context, Tensor +from mindspore.ops import functional as F + +context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + +def tensor_add_func(x, y): + z = F.tensor_add(x, y) + z = F.tensor_add(z, x) + return z + +x = Tensor(np.ones([3, 3], dtype=np.float32)) +y = Tensor(np.ones([3, 3], dtype=np.float32)) +output = tensor_add_func(x, y) +print(output.asnumpy()) +``` + +输出如下: +```python +[[3. 3. 3.] + [3. 3. 3.] + [3. 3. 3.]] +``` + +## 执行网络模型 +MindSpore的Model接口是用于训练和验证的高级接口。可以将有训练或推理功能的layers组合成一个对象,通过调用train、eval、predict接口可以分别实现训练、推理和预测功能。 + +用户可以根据实际需要传入网络、损失函数和优化器等初始化Model接口,还可以通过配置amp_level实现混合精度,配置metrics实现模型评估。 + +### 执行训练模型 +通过调用Model的train接口可以实现训练。 + +代码样例如下: +```python +import os + +import mindspore.dataset.vision.c_transforms as CV +from mindspore.dataset.vision import Inter + +import mindspore.dataset as ds +import mindspore.dataset.transforms.c_transforms as CT +import mindspore.dataset.vision.c_transforms as CV +import mindspore.nn as nn +from mindspore import context +from mindspore.common import dtype as mstype +from mindspore.common.initializer import Normal +from mindspore.common.initializer import TruncatedNormal +from mindspore.dataset.vision import Inter +from mindspore.train import Model +from mindspore.train.callback import LossMonitor + + +def create_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1): + """ + create dataset for train or test + """ + # define dataset + mnist_ds = ds.MnistDataset(data_path) + + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + rescale_nml = 1 / 0.3081 + shift_nml = -1 * 0.1307 / 0.3081 + + # define map operations + resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) # Bilinear mode + rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = CT.TypeCast(mstype.int32) + + # apply map operations on images + mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) + + # apply DatasetOps + buffer_size = 10000 + mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script + mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True) + mnist_ds = mnist_ds.repeat(repeat_size) + + return mnist_ds + + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + """weight initial for conv layer""" + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + """weight initial for fc layer""" + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + """weight initial""" + return TruncatedNormal(0.02) + + +class LeNet5(nn.Cell): + """ + Lenet network + + Args: + num_class (int): Num classes. Default: 10. + num_channel (int): Num channels. Default: 1. + + Returns: + Tensor, output tensor + Examples: + >>> LeNet(num_class=10) + + """ + + def __init__(self, num_class=10, num_channel=1): + super(LeNet5, self).__init__() + self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid') + self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid') + self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02)) + self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02)) + self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02)) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.max_pool2d(self.relu(self.conv1(x))) + x = self.max_pool2d(self.relu(self.conv2(x))) + x = self.flatten(x) + x = self.relu(self.fc1(x)) + x = self.relu(self.fc2(x)) + x = self.fc3(x) + return x + + +if __name__ == "__main__": + context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + ds_train = create_dataset(os.path.join("/home/workspace/mindspore_dataset/MNIST_Data/", "train"), 32) + + network = LeNet5(10) + net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + net_opt = nn.Momentum(network.trainable_params(), 0.01, 0.9) + model = Model(network, net_loss, net_opt) + + print("============== Starting Training ==============") + model.train(1, ds_train, callbacks=[LossMonitor()], dataset_sink_mode=True) +``` + +输出如下: +```python +epoch: 1 step: 1, loss is 2.300784 +epoch: 1 step: 2, loss is 2.3076947 +epoch: 1 step: 3, loss is 2.2993166 +... +epoch: 1 step: 1873, loss is 0.13014838 +epoch: 1 step: 1874, loss is 0.0346688 +epoch: 1 step: 1875, loss is 0.017264696 +``` + +> 使用PyNative模式调试, 请参考[使用PyNative模式调试](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/debugging_in_pynative_mode.html), 包括单算子、普通函数和网络训练模型的执行。 + +### 执行推理模型 +通过调用Model的train接口可以实现推理。为了方便评估模型的好坏,可以在Model接口初始化的时候设置评估指标Metric。 + +Metric是用于评估模型好坏的指标。常见的主要有Accuracy、Fbeta、Precision、Recall和TopKCategoricalAccuracy等,通常情况下,一种模型指标无法全面的评估模型的好坏,一般会结合多个指标共同作用对模型进行评估。 + +常用的内置评估指标: +- `Accuracy`(准确率):是一个用于评估分类模型的指标。通俗来说,准确率是指我们的模型预测正确的结果所占的比例。 公式:$$Accuracy = (TP+TN)/(TP+TN+FP+FN)$$ + +- `Precision`(精确率):在被识别为正类别的样本中,确实为正类别的比例。公式:$$Precision = TP/(TP+FP)$$ + +- `Recall`(召回率):在所有正类别样本中,被正确识别为正类别的比例。 公式:$$Recall = TP/(TP+FN)$$ + +- `Fbeta`(调和均值):综合考虑precision和recall的调和均值。 +公式:$$F_\beta = (1 + \beta^2) \cdot \frac{precisiont \cdot recall}{(\beta^2 \cdot precision) + recall}$$ + +- `TopKCategoricalAccuracy`(多分类TopK准确率):计算TopK分类准确率。 + +代码样例如下: +```python +import os + +import mindspore.dataset as ds +import mindspore.dataset.transforms.c_transforms as CT +import mindspore.dataset.vision.c_transforms as CV +import mindspore.nn as nn +from mindspore import context +from mindspore.common import dtype as mstype +from mindspore.common.initializer import Normal +from mindspore.dataset.vision import Inter +from mindspore.nn.metrics import Accuracy, Precision +from mindspore.train import Model +from mindspore.train.serialization import load_checkpoint, load_param_into_net + + +class LeNet5(nn.Cell): + """ + Lenet network + + Args: + num_class (int): Num classes. Default: 10. + num_channel (int): Num channels. Default: 1. + + Returns: + Tensor, output tensor + Examples: + >>> LeNet(num_class=10) + + """ + + def __init__(self, num_class=10, num_channel=1): + super(LeNet5, self).__init__() + self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid') + self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid') + self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02)) + self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02)) + self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02)) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.max_pool2d(self.relu(self.conv1(x))) + x = self.max_pool2d(self.relu(self.conv2(x))) + x = self.flatten(x) + x = self.relu(self.fc1(x)) + x = self.relu(self.fc2(x)) + x = self.fc3(x) + return x + + +def create_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1): + """ + create dataset for train or test + """ + # define dataset + mnist_ds = ds.MnistDataset(data_path) + + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + rescale_nml = 1 / 0.3081 + shift_nml = -1 * 0.1307 / 0.3081 + + # define map operations + resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) # Bilinear mode + rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = CT.TypeCast(mstype.int32) + + # apply map operations on images + mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) + + # apply DatasetOps + buffer_size = 10000 + mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script + mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True) + mnist_ds = mnist_ds.repeat(repeat_size) + + return mnist_ds + + +if __name__ == "__main__": + context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + + network = LeNet5(10) + net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + repeat_size = 10 + net_opt = nn.Momentum(network.trainable_params(), 0.01, 0.9) + model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy(), "Precision": Precision()}) + + print("============== Starting Testing ==============") + param_dict = load_checkpoint("./ckpt/checkpoint_lenet-1_1875.ckpt") + load_param_into_net(network, param_dict) + ds_eval = create_dataset(os.path.join("/home/workspace/mindspore_dataset/MNIST_Data", "test"), 32, 1) + acc = model.eval(ds_eval, dataset_sink_mode=True) + print("============== {} ==============".format(acc)) +``` + +输出如下: +```python +============== {'Accuracy': 0.96875, 'Precision': array([0.97782258, 0.99451052, 0.98031496, 0.92723881, 0.98352214, + 0.97165533, 0.98726115, 0.9472196 , 0.9394551 , 0.98236515])} ============== +``` \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/sampler.md b/docs/programming_guide/source_zh_cn/sampler.md index acdf43341e..54f4fc50d9 100644 --- a/docs/programming_guide/source_zh_cn/sampler.md +++ b/docs/programming_guide/source_zh_cn/sampler.md @@ -5,7 +5,6 @@ - [采样器](#采样器) - [概述](#概述) - [MindSpore采样器](#mindspore采样器) - - [SequentialSampler](#sequentialsampler) - [RandomSampler](#randomsampler) - [WeightedRandomSampler](#weightedrandomsampler) - [SubsetRandomSampler](#subsetrandomsampler) @@ -15,11 +14,11 @@ - + ## 概述 -MindSpore提供了多种用途的采样器,帮助用户对数据集进行不同形式的采样,以满足训练需求,能够解决诸如数据集过大或样本类别分布不均等问题。只需在加载数据集时将采样器对象传入,即可实现数据的采样。 +MindSpore提供了多种用途的采样器,帮助用户对数据集进行不同形式的采样,以满足训练需求,能够解决诸如数据集过大或样本类别分布不均等问题。只需在加载数据集时传入采样器对象,即可实现数据的采样。 MindSpore目前提供的采样器类别如下表所示。此外,用户也可以根据需要实现自定义的采样器类。 @@ -34,124 +33,45 @@ MindSpore目前提供的采样器类别如下表所示。此外,用户也可 ## MindSpore采样器 -下面以[CIFAR10数据集](https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz)为例,介绍MindSpore采样器使用方法。 - -### SequentialSampler - -从指定的索引位置开始顺序采样指定数目的数据。 - -```python -# 通过SequentialSampler定义一个顺序采样器,并作用于数据集 - -import mindspore.dataset as ds - -# CIFAR10数据集路径 -DATA_DIR = "Cifar10Data/" - -# 1. 定义一个顺序采样器SequentialSampler,按照读取顺序获取5个样本数据 -sampler = ds.SequentialSampler(num_samples=5) -dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) - -# 启动数据管道,输出5个样本数据 -for data in dataset1.create_dict_iterator(): - print("Image shape:", data['image'].shape, ", Label:", data['label']) - -print("") - -# 2. 定义一个顺序采样器SequentialSampler,跳过前2个数据,继续按照读取顺序获取5个样本数据 -sampler = ds.SequentialSampler(start_index=2, num_samples=5) -dataset2 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) - -# 启动数据管道,输出5个样本数据 -for data in dataset2.create_dict_iterator(): - print("Image shape:", data['image'].shape, ", Label:", data['label']) - -print("") - -# 3. 同类用法,指定数据集中的num_samples参数为5,shuffle参数为False,同样可以达到1的效果 -dataset3 = ds.Cifar10Dataset(DATA_DIR, num_samples=5, shuffle=False) - -# 启动数据管道,输出5个样本数据 -for data in dataset3.create_dict_iterator(): - print("Image shape:", data['image'].shape, ", Label:", data['label']) -``` - -``` -Image shape: (32, 32, 3) , Label: 0 -Image shape: (32, 32, 3) , Label: 1 -Image shape: (32, 32, 3) , Label: 2 -Image shape: (32, 32, 3) , Label: 3 -Image shape: (32, 32, 3) , Label: 4 - -Image shape: (32, 32, 3) , Label: 2 -Image shape: (32, 32, 3) , Label: 3 -Image shape: (32, 32, 3) , Label: 4 -Image shape: (32, 32, 3) , Label: 5 -Image shape: (32, 32, 3) , Label: 6 - -Image shape: (32, 32, 3) , Label: 0 -Image shape: (32, 32, 3) , Label: 1 -Image shape: (32, 32, 3) , Label: 2 -Image shape: (32, 32, 3) , Label: 3 -Image shape: (32, 32, 3) , Label: 4 -``` +下面以[CIFAR-10数据集](https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz)为例,介绍几种常用MindSpore采样器的使用方法。 ### RandomSampler 从索引序列中随机采样指定数目的数据。 -```python -# 通过RandomSampler定义一个随机采样器,并作用于数据集 +下面的样例使用随机采样器分别从CIFAR-10数据集中有放回和无放回地随机采样5个数据,并展示已加载数据的形状和标签。 +```python import mindspore.dataset as ds -# 设置全局随机种子,确保RandomSampler的行为可预测 ds.config.set_seed(0) -# CIFAR数据集路径 DATA_DIR = "Cifar10Data/" -# 1. 定义一个随机采样器SequentialSampler,随机获取5个样本数据 sampler = ds.RandomSampler(num_samples=5) dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 启动数据管道,输出5个样本数据 for data in dataset1.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) -print("") +print("------------") -# 2. 定义一个随机采样器RandomSampler,replacement=True意味着有放回抽样 sampler = ds.RandomSampler(replacement=True, num_samples=5) dataset2 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 启动数据管道,输出5个样本数据 for data in dataset2.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) - -print("") - -# 3. 同类用法,指定数据集中的num_samples参数为5,shuffle参数为True,同样可以达到2的效果 -dataset3 = ds.Cifar10Dataset(DATA_DIR, num_samples=5, shuffle=True) - -# 启动数据管道,输出5个样本数据 -for data in dataset3.create_dict_iterator(): - print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` +输出结果如下: + ``` Image shape: (32, 32, 3) , Label: 0 Image shape: (32, 32, 3) , Label: 2 Image shape: (32, 32, 3) , Label: 6 Image shape: (32, 32, 3) , Label: 4 Image shape: (32, 32, 3) , Label: 6 - -Image shape: (32, 32, 3) , Label: 8 -Image shape: (32, 32, 3) , Label: 8 -Image shape: (32, 32, 3) , Label: 1 -Image shape: (32, 32, 3) , Label: 2 -Image shape: (32, 32, 3) , Label: 7 - +------------ Image shape: (32, 32, 3) , Label: 8 Image shape: (32, 32, 3) , Label: 8 Image shape: (32, 32, 3) , Label: 1 @@ -163,29 +83,25 @@ Image shape: (32, 32, 3) , Label: 7 指定每种类别的采样概率,按照概率在各类别中随机采样指定数目的数据。 -```python -# 通过WeightedRandomSampler定义一个带权重的随机采样器,并作用于数据集 +下面的样例使用带权随机采样器从CIFAR-10数据集的10个类别中按概率获取6个样本,并展示已读取数据的形状和标签。 +```python import mindspore.dataset as ds -# 设置全局随机种子,确保WeightedRandomSampler的行为可预测 ds.config.set_seed(1) -# CIFAR数据集路径 DATA_DIR = "Cifar10Data/" -# 定义一个带权重的随机采样器WeightedRandomSampler -# weights代表CIFAR10中10类数据的采样概率,num_samples表示随机获取6个样本数据 -# replacement参数与RandomSampler中一致 weights = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0] sampler = ds.WeightedRandomSampler(weights, num_samples=6) dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 启动数据管道,输出6个样本数据 for data in dataset1.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` +输出结果如下: + ``` Image shape: (32, 32, 3) , Label: 1 Image shape: (32, 32, 3) , Label: 1 @@ -199,28 +115,25 @@ Image shape: (32, 32, 3) , Label: 0 从指定索引子序列中随机采样指定数目的数据。 -```python -# 通过SubsetRandomSampler定义一个子集随机采样器,并作用于数据集 +下面的样例使用子序列随机采样器从CIFAR-10数据集的指定子序列中抽样3个样本,并展示已读取数据的形状和标签。 +```python import mindspore.dataset as ds -# 设置全局随机种子,确保SubsetRandomSampler的行为可预测 ds.config.set_seed(2) -# CIFAR数据集路径 DATA_DIR = "Cifar10Data/" -# 定义一个带采样集合的随机采样器SubsetRandomSampler -# indice代表可采样的集合,num_samples表示获取3个样本数据,即从可采样集合中(0~5)随机获取3个值,作为下标访问数据集的数据 indices = [0, 1, 2, 3, 4, 5] sampler = ds.SubsetRandomSampler(indices, num_samples=3) dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 启动数据管道,输出3个样本数据 for data in dataset1.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` +输出结果如下: + ``` Image shape: (32, 32, 3) , Label: 5 Image shape: (32, 32, 3) , Label: 0 @@ -231,29 +144,24 @@ Image shape: (32, 32, 3) , Label: 3 在指定的数据集类别P中,每种类别各采样K条数据。 -```python -# 通过PKSampler定义一个针对各个类别随机采样器,并作用于数据集 +下面的样例使用PK采样器从CIFAR-10数据集中每种类别抽样2个样本,最多20个样本,并展示已读取数据的形状和标签。 +```python import mindspore.dataset as ds -# 设置全局随机种子,确保PKSampler的shuffle参数行为可预测 ds.config.set_seed(3) -# CIFAR数据集路径 DATA_DIR = "Cifar10Data/" -# 定义一个针对类别采样的随机采样器PKSampler -# num_val代表从每个类别采样K个样本,class_column代表针对特定的数据列采样(一般是label) -# num_samples代表输出的样本数,设置num_samples = num_val*class_nums,确保每个类别平均采样 -# shuffle代表样本是否需要被混洗 sampler = ds.PKSampler(num_val=2, class_column='label', num_samples=20) dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 启动数据管道,输出20个样本数据 for data in dataset1.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` +输出结果如下: + ``` Image shape: (32, 32, 3) , Label: 0 Image shape: (32, 32, 3) , Label: 0 @@ -281,66 +189,53 @@ Image shape: (32, 32, 3) , Label: 9 在分布式训练中,对数据集分片进行采样。 -```python -# 通过DistributedSampler定义一个将数据集进行分片操作,并获取某个分片进行采样的采样器,并作用于数据集 +下面的样例使用分布式采样器将构建的数据集分为3片,在每个分片中采样3个数据样本,并展示已读取的数据。 +```python import numpy as np import mindspore.dataset as ds -# 构建一个list data_source = [0, 1, 2, 3, 4, 5, 6, 7, 8] -# 定义一个采样器DistributedSampler -# num_shards代表将CIFAR数据集拆分成n个分片 -# shard_id代表获取第m个分片 -# num_samples代表获取该分片的10个样本 -# shuffle代表样本是否需要被混洗 sampler = ds.DistributedSampler(num_shards=3, shard_id=0, shuffle=False, num_samples=3) - -# 从list中构建数据管道 dataset = ds.NumpySlicesDataset(data_source, column_names=["data"], sampler=sampler) -# 经过DistributedSampler分片后,数据集的内容为 -# shard_id 0: 0, 3, 6 -# shard_id 1: 1, 4, 7 -# shard_id 2: 2, 5, 8 -# 因此第0个分片拥有数据为0, 3, 6 for data in dataset.create_dict_iterator(): print(data) ``` +输出结果如下: + ``` -{'data': Tensor(shape=[], dtype=Int64, value= 0)} -{'data': Tensor(shape=[], dtype=Int64, value= 3)} -{'data': Tensor(shape=[], dtype=Int64, value= 6)} +{'data': array(0, dtype=int64)} +{'data': array(3, dtype=int64)} +{'data': array(6, dtype=int64)} ``` ## 自定义采样器 -用户可以继承Sampler基类,通过实现`__iter__`方法来自定义采样器的采样方式。 +用户可以继承`Sampler`基类,通过实现`__iter__`方法来自定义采样器的采样方式。 -```python -# 继承Sampler基类,重载__iter__成为新的采样器 +下面的样例定义了一个从下标0至下标9间隔为2采样的采样器,将其作用于CIFAR-10数据集,并展示已读取数据的形状和标签。 +```python import mindspore.dataset as ds class MySampler(ds.Sampler): def __iter__(self): - # 采样器的行为是,从下标0开始到下标9,以2为间隔采样 for i in range(0, 10, 2): yield i -# CIFAR数据集路径 DATA_DIR = "Cifar10Data/" -# 将自定义构建的采样器传入到sampler参数 dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=MySampler()) -# 启动数据管道,输出5个样本数据 for data in dataset1.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` +输出结果如下: + ``` Image shape: (32, 32, 3) , Label: 0 Image shape: (32, 32, 3) , Label: 2 diff --git a/docs/programming_guide/source_zh_cn/security_and_privacy.md b/docs/programming_guide/source_zh_cn/security_and_privacy.md index 8b6d6c20c9..7136f4ff6e 100644 --- a/docs/programming_guide/source_zh_cn/security_and_privacy.md +++ b/docs/programming_guide/source_zh_cn/security_and_privacy.md @@ -2,60 +2,60 @@ -- [AI安全与隐私保护](AI安全与隐私保护) +- [AI安全与隐私保护](#ai安全与隐私保护) - [概述](#概述) - [对抗鲁棒性](#对抗鲁棒性) - - [Attack](#Attack) - - [Defense](#Defense) - - [Detector](#Detector) + - [Attack](#attack) + - [Defense](#defense) + - [Detector](#detector) - [模型安全测试](#模型安全测试) - - [Fuzzer](#Fuzzer) + - [Fuzzer](#fuzzer) - [差分隐私训练](#差分隐私训练) - - [DPModel](#DPModel) + - [DPModel](#dpmodel) - [隐私泄露风险评估](#隐私泄露风险评估) - - [MembershipInference](#MembershipInference) + - [MembershipInference](#membershipinference) -## 概述 + -本篇是AI安全与隐私保护的编程指南。 +## 概述 -AI作为一种通用技术,在带来巨大机遇和效益的同时也面临着新的安全与隐私保护的挑战。MindArmour是MindSpore的一个子项目,为MindSpore提供安全与隐私保护能力,主要包括对抗鲁棒性、模型安全测试、差分隐私训练、隐私泄露风险评估等技术。 +本篇主要介绍AI安全与隐私保护。AI作为一种通用技术,在带来巨大机遇和效益的同时也面临着新的安全与隐私保护的挑战。MindArmour是MindSpore的一个子项目,为MindSpore提供安全与隐私保护能力,主要包括对抗鲁棒性、模型安全测试、差分隐私训练、隐私泄露风险评估等技术。 ## 对抗鲁棒性 ### Attack -Attack基类定义了对抗样本生成的使用接口,其子类实现了各种具体的生成算法,支持安全工作人员快速高效地生成对抗样本,用于攻击AI模型,以评估模型的鲁棒性。 +`Attack`基类定义了对抗样本生成的使用接口,其子类实现了各种具体的生成算法,支持安全工作人员快速高效地生成对抗样本,用于攻击AI模型,以评估模型的鲁棒性。 ### Defense -Defense基类定义了对抗训练的使用接口,其子类实现了各种具体的对抗训练算法,增强模型的对抗鲁棒性。 +`Defense`基类定义了对抗训练的使用接口,其子类实现了各种具体的对抗训练算法,增强模型的对抗鲁棒性。 ### Detector -Detector基类定义了对抗样本检测的使用借口,其子类实现了各种具体的检测算法,增强模型的对抗鲁棒性。 +`Detector`基类定义了对抗样本检测的使用借口,其子类实现了各种具体的检测算法,增强模型的对抗鲁棒性。 -详细内容,请参考[对抗鲁棒性官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/model_security.html) +详细内容,请参考[对抗鲁棒性官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/model_security.html)。 ## 模型安全测试 ### Fuzzer -Fuzzer类基于神经元覆盖率增益控制fuzzing流程,采用自然扰动和对抗样本生成方法作为变异策略,激活更多的神经元,从而探索不同类型的模型输出结果、错误行为,指导用户增强模型鲁棒性。 +`Fuzzer`类基于神经元覆盖率增益控制fuzzing流程,采用自然扰动和对抗样本生成方法作为变异策略,激活更多的神经元,从而探索不同类型的模型输出结果、错误行为,指导用户增强模型鲁棒性。 -详细内容,请参考[模型安全测试官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/fuzzer.html) +详细内容,请参考[模型安全测试官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/fuzzer.html)。 ## 差分隐私训练 ### DPModel -DPModel继承了mindspore.Model,提供了差分隐私训练的入口函数。 +`DPModel`继承了`mindspore.Model`,提供了差分隐私训练的入口函数。 -详细内容,请参考[差分隐私官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/differential_privacy.html) +详细内容,请参考[差分隐私官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/differential_privacy.html)。 ## 隐私泄露风险评估 ### MembershipInference -MembershipInference类提供了一种模型逆向分析方法,能够基于模型对样本的预测信息,推测某个样本是否在模型的训练集中,以此评估模型的隐私泄露风险。 +`MembershipInference`类提供了一种模型逆向分析方法,能够基于模型对样本的预测信息,推测某个样本是否在模型的训练集中,以此评估模型的隐私泄露风险。 -详细内容,请参考[隐私泄露风险评估官方教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/membership_inference.html) +详细内容,请参考[隐私泄露风险评估官方教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/membership_inference.html)。 diff --git a/docs/programming_guide/source_zh_cn/tensor.md b/docs/programming_guide/source_zh_cn/tensor.md index 3959362bb8..ccd3f33736 100644 --- a/docs/programming_guide/source_zh_cn/tensor.md +++ b/docs/programming_guide/source_zh_cn/tensor.md @@ -1,8 +1,8 @@ -# 张量 +# Tensor -- [张量](#张量) +- [Tensor](#tensor) - [概述](#概述) - [张量构造](#张量构造) - [张量的属性和方法](#张量的属性和方法) @@ -11,24 +11,21 @@ - + ## 概述 -张量是MindSpore网络运算中的基本数据结构,即为多维数组。张量里的数据分为不同的类型, -支持的类型有`int8`、`int16`、`int32`、`int64`、`uint8`、`uint16`、`uint32`、`uint64`、`float16`、`float32`、`float64`、`bool_`, -与NumPy里的数据类型一一对应。 +张量(Tensor)是MindSpore网络运算中的基本数据结构。张量中的数据类型可参考[dtype](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dtype.html)。 不同维度的张量分别表示不同的数据,0维张量表示标量,1维张量表示向量,2维张量表示矩阵,3维张量可以表示彩色图像的RGB三通道等等。 -> 本文档中的所有示例,都是在PyNative模式下运行的,暂不支持CPU。 +> 本文中的所有示例,支持在PyNative模式下运行,暂不支持CPU。 ## 张量构造 -构造张量时支持传入`Tensor`、`float`、`int`、`bool`、`tuple`、`list`和`NumPy.array`。 +构造张量时,支持传入`Tensor`、`float`、`int`、`bool`、`tuple`、`list`和`NumPy.array`类型。 -`Tensor`作为初始值可指定dtype,如果没有指定dtype,`int`、`float`、`bool`分别对应`int32`、`float32`、`bool_`, -`tuple`和`list`生成的1维`Tensor`数据类型与`tuple`和`list`里存放数据的类型相对应。 +`Tensor`作为初始值时,可指定dtype,如果没有指定dtype,`int`、`float`、`bool`分别对应`int32`、`float32`、`bool_`,`tuple`和`list`生成的1维`Tensor`数据类型与`tuple`和`list`里存放数据的类型相对应。 代码样例如下: @@ -65,6 +62,7 @@ True ``` ## 张量的属性和方法 + ### 属性 张量的属性包括形状(shape)和数据类型(dtype)。 @@ -94,8 +92,8 @@ print(x_shape, x_dtype) ### 方法 张量的方法包括`all`、`any`和`asnumpy`。 -- `all(axis, keep_dims)`:在指定维度上通过`and`操作进行归约,axis代表归约维度,keep_dims表示是否保留归约后的维度。 -- `any(axis, keep_dims)`:在指定维度上通过`or`操作进行归约,axis代表归约维度,keep_dims表示是否保留归约后的维度。 +- `all(axis, keep_dims)`:在指定维度上通过`and`操作进行归约,`axis`代表归约维度,`keep_dims`表示是否保留归约后的维度。 +- `any(axis, keep_dims)`:在指定维度上通过`or`操作进行归约,参数含义同`all`。 - `asnumpy()`:将`Tensor`转换为NumPy的array。 代码样例如下: diff --git a/docs/programming_guide/source_zh_cn/tokenizer.md b/docs/programming_guide/source_zh_cn/tokenizer.md index 65c73d8a7d..ef7eb64c9d 100644 --- a/docs/programming_guide/source_zh_cn/tokenizer.md +++ b/docs/programming_guide/source_zh_cn/tokenizer.md @@ -5,10 +5,16 @@ - [分词器](#分词器) - [概述](#概述) - [MindSpore分词器](#mindspore分词器) + - [BertTokenizer](#BertTokenizer) + - [JiebaTokenizer](#JiebaTokenizer) + - [SentencePieceTokenizer](#SentencePieceTokenizer) + - [UnicodeCharTokenizer](#UnicodeCharTokenizer) + - [WhitespaceTokenizer](#WhitespaceTokenizer) + - [WordpieceTokenizer](#WordpieceTokenizer) - + ## 概述 @@ -34,103 +40,46 @@ MindSpore目前提供的分词器如下表所示。此外,用户也可以根 ## MindSpore分词器 -### BasicTokenizer - -`BasicTokenizer`是通过大小写折叠、编码统一、去除重音符,按照正则匹配模式来分词的。 - -```python -import mindspore.dataset as ds -import mindspore.dataset.text as text - -# 构建输入的数据列表 -input_list = ["Welcome to Beijing北京欢迎您", "長風破浪會有時,直掛雲帆濟滄海","😀嘿嘿😃哈哈😄大笑😁嘻嘻", - "明朝(1368—1644年)和清朝(1644—1911年),是中国封建王朝史上最后两个朝代", - "明代(1368-1644)と清代(1644-1911)は、中国の封建王朝の歴史における最後の2つの王朝でした", - "명나라 (1368-1644)와 청나라 (1644-1911)는 중국 봉건 왕조의 역사에서 마지막 두 왕조였다"] - -dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) - -print("------------------------before tokenize----------------------------") - -# 输出分词之前的数据 -for data in dataset.create_dict_iterator(output_numpy=True): - print(text.to_str(data['text'])) - -#打印分词后的数据输出 -print("------------------------after tokenize-----------------------------") - -# 输出分词之后的数据 -# BasicTokenizer为分词的函数 -basic_tokenizer = text.BasicTokenizer() - -dataset = dataset.map(operations=basic_tokenizer) - -for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']) - print(token) -``` - -``` -------------------------before tokenize---------------------------- -Welcome to Beijing北京欢迎您 -長風破浪會有時,直掛雲帆濟滄海 -😀嘿嘿😃哈哈😄大笑😁嘻嘻 -明朝(1368—1644年)和清朝(1644—1911年),是中国封建王朝史上最后两个朝代 -明代(1368-1644)と清代(1644-1911)は、中国の封建王朝の歴史における最後の2つの王朝でした -명나라 (1368-1644)와 청나라 (1644-1911)는 중국 봉건 왕조의 역사에서 마지막 두 왕조였다 -------------------------after tokenize----------------------------- -['Welcome' 'to' 'Beijing' '北' '京' '欢' '迎' '您'] -['長' '風' '破' '浪' '會' '有' '時' ',' '直' '掛' '雲' '帆' '濟' '滄' '海'] -['😀' '嘿' '嘿' '😃' '哈' '哈' '😄' '大' '笑' '😁' '嘻' '嘻'] -['明' '朝' '(' '1368' '—' '1644' '年' ')' '和' '清' '朝' '(' '1644' '—' '1911' '年' ')' ',' '是' '中' '国' '封' '建' '王' '朝' '史' '上' '最' '后' '两' '个' '朝' '代'] -['明' '代' '(' '1368' '-' '1644' ')' 'と' '清' '代' '(' '1644' '-' '1911' ')' 'は' '、' '中' '国' 'の' '封' '建' '王' '朝' 'の' '歴' '史' 'における' '最' '後' 'の2つの' '王' '朝' 'でした'] -['명나라' '(' '1368' '-' '1644' ')' '와' '청나라' '(' '1644' '-' '1911' ')' '는' '중국' '봉건' '왕조의' '역사에서' '마지막' '두' '왕조였다'] -``` +下面介绍几种常用分词器的使用方法。 ### BertTokenizer `BertTokenizer`是通过调用`BasicTokenizer`和`WordpieceTokenizer`来进行分词的。 +下面的样例首先构建了一个文本数据集和字符串列表,然后通过`BertTokenizer`对数据集进行分词,并展示了分词前后的文本结果。 + ```python import mindspore.dataset as ds import mindspore.dataset.text as text -# 构建输入的数据列表 input_list = ["床前明月光", "疑是地上霜", "举头望明月", "低头思故乡", "I am making small mistakes during working hours", "😀嘿嘿😃哈哈😄大笑😁嘻嘻", "繁體字"] - dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) print("------------------------before tokenize----------------------------") -# 输出分词之前的数据 for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) -# 字符串列表,其中每个元素都是字符串类型的单词。 vocab_list = [ "床", "前", "明", "月", "光", "疑", "是", "地", "上", "霜", "举", "头", "望", "低", "思", "故", "乡", "繁", "體", "字", "嘿", "哈", "大", "笑", "嘻", "i", "am", "mak", "make", "small", "mistake", "##s", "during", "work", "##ing", "hour", "😀", "😃", "😄", "😁", "+", "/", "-", "=", "12", "28", "40", "16", " ", "I", "[CLS]", "[SEP]", "[UNK]", "[PAD]", "[MASK]", "[unused1]", "[unused10]"] -# 从单词列表中构建一个vocab对象 vocab = text.Vocab.from_list(vocab_list) - -# 输出分词之后的数据 -# BertTokenizer为分词的函数 tokenizer_op = text.BertTokenizer(vocab=vocab) +dataset = dataset.map(operations=tokenizer_op) -#打印分词后的数据输出 print("------------------------after tokenize-----------------------------") -dataset = dataset.map(operations=tokenizer_op) - for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` +输出结果如下: + ``` ------------------------before tokenize---------------------------- 床前明月光 @@ -154,38 +103,35 @@ I am making small mistakes during working hours `JiebaTokenizer`是基于jieba的中文分词。 +下面的样例首先构建了一个文本数据集,然后使用HMM与MP字典文件创建`JiebaTokenizer`对象,并对数据集进行分词,最后展示了分词前后的文本结果。 + ```python import mindspore.dataset as ds import mindspore.dataset.text as text -# 构建输入的数据列表 input_list = ["床前明月光", "疑是地上霜", "举头望明月", "低头思故乡", "I am making small mistakes during working hours", "😀嘿嘿😃哈哈😄大笑😁嘻嘻", "繁體字"] - -# 字典文件由HMMSegment算法和MPSegment算法使用,该字典可在cppjieba的官方网站上获得。 -HMM_FILE = "hmm_model.utf8" -MP_FILE = "jieba.dict.utf8" - dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) print("------------------------before tokenize----------------------------") -# 输出分词之前的数据 for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) -tokenizer_op = text.JiebaTokenizer(HMM_FILE, MP_FILE) +HMM_FILE = "hmm_model.utf8" +MP_FILE = "jieba.dict.utf8" +jieba_op = text.JiebaTokenizer(HMM_FILE, MP_FILE) +dataset = dataset.map(operations=jieba_op, input_columns=["text"], num_parallel_workers=1) -#打印分词后的数据输出 print("------------------------after tokenize-----------------------------") -dataset = dataset.map(operations=jieba_op, input_columns=["text"], num_parallel_workers=1) - for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` +输出结果如下: + ``` ------------------------before tokenize---------------------------- 今天天气太好了我们一起去外面玩吧 @@ -193,80 +139,37 @@ for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): ['今天天气' '太好了' '我们' '一起' '去' '外面' '玩吧'] ``` -### RegexTokenizer - -`RegexTokenizer`是通正则表达式匹配模式来进行分词的。 - -```python -import mindspore.dataset as ds -import mindspore.dataset.text as text - -# 构建输入的数据列表 -input_list = ["Welcome to Shenzhen!"] - -# 原始字符串将由匹配的元素分隔。 -delim_pattern = "\\s+" - -dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) - -print("------------------------before tokenize----------------------------") - -# 输出分词之前的数据 -for data in dataset.create_dict_iterator(output_numpy=True): - print(text.to_str(data['text'])) - -tokenizer_op = text.RegexTokenizer(delim_pattern) - -#打印分词后的数据输出 -print("------------------------after tokenize-----------------------------") - -dataset = dataset.map(operations=tokenizer_op) - -for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']).tolist() - print(token) -``` - -``` -------------------------before tokenize---------------------------- -Welcome to Shenzhen! -------------------------after tokenize----------------------------- -['Welcome', 'to', 'Shenzhen!'] -``` - ### SentencePieceTokenizer -`SentencePieceTokenizer`是基于SentencePiece这个开源的自然语言处理工具包。 +`SentencePieceTokenizer`是基于[SentencePiece](https://github.com/google/sentencepiece)这个开源的自然语言处理工具包。 + +下面的样例首先构建了一个文本数据集,然后从`VOCAB_FILE`文件中构建一个`vocab`对象,再通过`SentencePieceTokenizer`对数据集进行分词,并展示了分词前后的文本结果。 ```python import mindspore.dataset as ds import mindspore.dataset.text as text -# 构建输入的数据列表 input_list = ["I saw a girl with a telescope."] - dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) print("------------------------before tokenize----------------------------") -# 输出分词之前的数据 for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) -# 从文件数据中构建一个vocab对象 vocab = text.SentencePieceVocab.from_file([VOCAB_FILE], 5000, 0.9995, SentencePieceModel.UNIGRAM, {}) tokenizer_op = text.SentencePieceTokenizer(vocab, out_type=SPieceTokenizerOutType.STRING) +dataset = dataset.map(operations=tokenizer_op) -#打印分词后的数据输出 print("------------------------after tokenize-----------------------------") -dataset = dataset.map(operations=tokenizer_op) - for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` +输出结果如下: + ``` ------------------------before tokenize---------------------------- I saw a girl with a telescope. @@ -278,33 +181,32 @@ I saw a girl with a telescope. `UnicodeCharTokenizer`是根据Unicode字符集来分词的。 +下面的样例首先构建了一个文本数据集,然后通过`UnicodeCharTokenizer`对数据集进行分词,并展示了分词前后的文本结果。 + ```python import mindspore.dataset as ds import mindspore.dataset.text as text -# 构建输入的数据列表 input_list = ["Welcome to Beijing!", "北京欢迎您!", "我喜欢English!"] - dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) print("------------------------before tokenize----------------------------") -# 输出分词之前的数据 for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.UnicodeCharTokenizer() +dataset = dataset.map(operations=tokenizer_op) -#打印分词后的数据输出 print("------------------------after tokenize-----------------------------") -dataset = dataset.map(operations=tokenizer_op) - for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` +输出结果如下: + ``` ------------------------before tokenize---------------------------- Welcome to Beijing! @@ -316,79 +218,36 @@ Welcome to Beijing! ['我', '喜', '欢', 'E', 'n', 'g', 'l', 'i', 's', 'h', '!'] ``` -### UnicodeScriptTokenizer - -`UnicodeScriptTokenizer`是根据不同的Unicode的边界来进行分词的。 - -```python -import mindspore.dataset as ds -import mindspore.dataset.text as text - -# 构建输入的数据列表 -input_list = ["Welcome to Beijing!", "北京欢迎您!", "我喜欢English!"] - -dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) - -print("------------------------before tokenize----------------------------") - -# 输出分词之前的数据 -for data in dataset.create_dict_iterator(output_numpy=True): - print(text.to_str(data['text'])) - -tokenizer_op = text.UnicodeScriptTokenizer() - -#打印分词后的数据输出 -print("------------------------after tokenize-----------------------------") - -dataset = dataset.map(operations=tokenizer_op) - -for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']).tolist() - print(token) -``` - -``` -------------------------before tokenize---------------------------- -Welcome to Beijing! -北京欢迎您! -我喜欢English! -------------------------after tokenize----------------------------- -['Welcome', 'to', 'Beijing', '!'] -['北京欢迎您', '!'] -['我喜欢', 'English', '!'] -``` - ### WhitespaceTokenizer `WhitespaceTokenizer`是根据空格来进行分词的。 +下面的样例首先构建了一个文本数据集,然后通过`WhitespaceTokenizer`对数据集进行分词,并展示了分词前后的文本结果。 + ```python import mindspore.dataset as ds import mindspore.dataset.text as text -# 构建输入的数据列表 input_list = ["Welcome to Beijing!", "北京欢迎您!", "我喜欢English!"] - dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) print("------------------------before tokenize----------------------------") -# 输出分词之前的数据 for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) tokenizer_op = text.WhitespaceTokenizer() +dataset = dataset.map(operations=tokenizer_op) -#打印分词后的数据输出 print("------------------------after tokenize-----------------------------") -dataset = dataset.map(operations=tokenizer_op) - for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']).tolist() print(token) ``` +输出结果如下: + ``` >> Tokenize Result ------------------------before tokenize---------------------------- @@ -405,38 +264,33 @@ Welcome to Beijing! `WordpieceTokenizer`是基于单词集来划分的,单词集里没有的,但是有组合的也会划分出来。 +下面的样例首先构建了一个文本数据集,然后从单词列表中构建`vocab`对象,通过`WordpieceTokenizer`对数据集进行分词,并展示了分词前后的文本结果。 + ```python import mindspore.dataset as ds import mindspore.dataset.text as text -# 构建输入的数据列表 input_list = ["my", "favorite", "book", "is", "love", "during", "the", "cholera", "era", "what", "我", "最", "喜", "欢", "的", "书", "是", "霍", "乱", "时", "期", "的", "爱", "情", "您"] - dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) print("------------------------before tokenize----------------------------") -# 输出分词之前的数据 for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) -#打印分词后的数据输出 -print("------------------------after tokenize-----------------------------") - -# 从单词列表中构建一个vocab对象 vocab = text.Vocab.from_list(vocab_list) - -# 输出分词之后的数据 -# BasicTokenizer为分词的函数 tokenizer_op = text.WordpieceTokenizer(vocab=vocab) - dataset = dataset.map(operations=tokenizer_op) +print("------------------------after tokenize-----------------------------") + for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): token = text.to_str(i['text']) print(token) ``` +输出结果如下: + ``` ------------------------before tokenize---------------------------- my diff --git a/docs/programming_guide/source_zh_cn/train.md b/docs/programming_guide/source_zh_cn/train.md new file mode 100644 index 0000000000..3995af2e6e --- /dev/null +++ b/docs/programming_guide/source_zh_cn/train.md @@ -0,0 +1,442 @@ +# 训练 + + + +- [训练](#训练) + - [概述](#概述) + - [自定义训练网络](#自定义训练网络) + - [自定义训练循环](#自定义训练循环) + - [边训练边推理](#边训练边推理) + - [on-device执行](#on-device执行) + - [计算图下沉](#计算图下沉) + - [数据下沉](#数据下沉) + + + + + +## 概述 +MindSpore在Model_zoo也已经提供了大量的目标检测、自然语言处理等多种网络模型,供用户直接使用,但是对于某些高级用户而言可能想要自行设计网络或者自定义训练循环,下面就对自定义训练网络、自定义训练循环和边训练边推理三种场景进行介绍,另外对On device执行方式进行详细介绍。 + +## 自定义训练网络 +在自定义训练网络前,需要先了解下MindSpore的网络支持、Python源码构造网络约束和算子支持情况。 + +- 网络支持:当前MindSpore已经支持多种网络,按类型分为计算机视觉、自然语言处理、推荐和图神经网络,可以通过[网络支持](https://www.mindspore.cn/docs/zh-CN/master/network_list.html)查看具体支持的网络情况。如果现有网络无法满足用户需求,用户可以根据实际需要定义自己的网络。 + +- Python源码构造网络约束:MindSpore暂不支持将任意Python源码转换成计算图,所以对于用户源码支持的写法有所限制,主要包括语法约束和网络定义约束两方面。详细情况可以查看[Python源码构造网络约束](https://www.mindspore.cn/docs/zh-CN/master/constraints_on_network_construction.html)了解。随着MindSpore的演进,这些约束可能会发生变化。 + +- 算子支持:顾名思义,网络的基础是算子,所以用户自定义训练网络前要对MindSpore当前支持的算子有所了解,可以通过查看[算子支持](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html)了解不同的后端(Ascend、GPU和CPU)的算子实现情况。 + +> 当开发网络遇到内置算子不足以满足需求时,用户也可以参考[自定义算子](https://www.mindspore.cn/tutorial/zh-CN/master/use/custom_operator.html),方便快捷地扩展昇腾AI处理器的自定义算子。 + +代码样例如下: +```python +import numpy as np + +from mindspore.common.tensor import Tensor +from mindspore.nn import Cell, Dense, SoftmaxCrossEntropyWithLogits, Momentum, TrainOneStepCell, WithLossCell +from mindspore.ops import operations as P + + +class ReLUReduceMeanDense(Cell): + def __init__(self, kernel, bias, in_channel, num_class): + super().__init__() + self.relu = P.ReLU() + self.mean = P.ReduceMean(keep_dims=False) + self.dense = Dense(in_channel, num_class, kernel, bias) + + def construct(self, x): + x = self.relu(x) + x = self.mean(x, (2, 3)) + x = self.dense(x) + return x + + +if __name__ == "__main__": + weight_np = np.ones((1000, 2048)).astype(np.float32) + weight = Tensor(weight_np.copy()) + bias_np = np.ones((1000,)).astype(np.float32) + bias = Tensor(bias_np.copy()) + net = ReLUReduceMeanDense(weight, bias, 2048, 1000) + criterion = SoftmaxCrossEntropyWithLogits(sparse=False) + optimizer = Momentum(learning_rate=0.1, momentum=0.1, + params=filter(lambda x: x.requires_grad, net.get_parameters())) + net_with_criterion = WithLossCell(net, criterion) + train_network = TrainOneStepCell(net_with_criterion, optimizer) + train_network.set_train() + input_np = np.random.randn(32, 2048, 7, 7).astype(np.float32) + input = Tensor(input_np.copy()) + label_np_onehot = np.zeros(shape=(32, 1000)).astype(np.float32) + label = Tensor(label_np_onehot.copy()) + for i in range(1): + loss = train_network(input, label) + print("-------loss------", loss) +``` + +输出如下: +```python +-------loss------ [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. + 0. 0. 0. 0. 0. 0. 0. 0.] +``` + +## 自定义训练循环 +用户如果不想使用MindSpore提供的Model接口,可以将模仿Model的train接口自由控制循环的迭代次数和每个epoch的step数量。 + +代码样例如下: +```python +import os + +import mindspore.dataset as ds +import mindspore.dataset.transforms.c_transforms as CT +import mindspore.dataset.vision.c_transforms as CV +import mindspore.nn as nn +from mindspore import context +from mindspore.common import dtype as mstype +from mindspore.common.initializer import TruncatedNormal +from mindspore.common.parameter import ParameterTuple +from mindspore.dataset.vision import Inter +from mindspore.nn.wrap.cell_wrapper import WithLossCell +from mindspore.ops import composite as C +from mindspore.ops import functional as F +from mindspore.ops import operations as P +from mindspore.train.dataset_helper import DatasetHelper, connect_network_with_dataset + + +def create_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1): + """ + create dataset for train or test + """ + # define dataset + mnist_ds = ds.MnistDataset(data_path) + + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + rescale_nml = 1 / 0.3081 + shift_nml = -1 * 0.1307 / 0.3081 + + # define map operations + resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) # Bilinear mode + rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = CT.TypeCast(mstype.int32) + + # apply map operations on images + mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) + + # apply DatasetOps + buffer_size = 10000 + mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script + mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True) + mnist_ds = mnist_ds.repeat(repeat_size) + + return mnist_ds + + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + """weight initial for conv layer""" + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + """weight initial for fc layer""" + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + """weight initial""" + return TruncatedNormal(0.02) + + +class LeNet5(nn.Cell): + """ + Lenet network + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + + Examples: + >>> LeNet(num_class=10) + """ + + def __init__(self, num_class=10): + super(LeNet5, self).__init__() + self.num_class = num_class + self.batch_size = 32 + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16 * 5 * 5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.reshape(x, (self.batch_size, -1)) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x + + +class TrainOneStepCell(nn.Cell): + def __init__(self, network, optimizer, sens=1.0): + super(TrainOneStepCell, self).__init__(auto_prefix=False) + self.network = network + self.weights = ParameterTuple(network.trainable_params()) + self.optimizer = optimizer + self.grad = C.GradOperation(get_by_list=True, sens_param=True) + self.sens = sens + + def set_sens(self, value): + self.sens = value + + def construct(self, data, label): + weights = self.weights + loss = self.network(data, label) + sens = P.Fill()(P.DType()(loss), P.Shape()(loss), self.sens) + grads = self.grad(self.network, weights)(data, label, sens) + return F.depend(loss, self.optimizer(grads)) + + +if __name__ == "__main__": + context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + ds_train = create_dataset(os.path.join("/home/workspace/mindspore_dataset/MNIST_Data/", "train"), 32) + + network = LeNet5(10) + net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + net_opt = nn.Momentum(network.trainable_params(), 0.01, 0.9) + net = WithLossCell(network, net_loss) + net = TrainOneStepCell(net, net_opt) + dataset_helper = DatasetHelper(ds_train, dataset_sink_mode=True, sink_size=100, epoch_num=10) + net = connect_network_with_dataset(net, dataset_helper) + network.set_train() + print("============== Starting Training ==============") + epoch = 10 + for step in range(epoch): + for inputs in dataset_helper: + output = net(*inputs) + print("epoch: {0}/{1}, losses: {2}".format(step + 1, epoch, output.asnumpy(), flush=True)) +``` + +输出如下: +```python +epoch: 1/10, losses: 2.294034719467163 +epoch: 2/10, losses: 2.3150298595428467 +epoch: 3/10, losses: 2.3107073307037354 +epoch: 4/10, losses: 2.3155436515808105 +epoch: 5/10, losses: 2.28973388671875 +epoch: 6/10, losses: 2.3108928203582764 +epoch: 7/10, losses: 2.293713092803955 +epoch: 8/10, losses: 2.29837703704834 +epoch: 9/10, losses: 2.305952548980713 +epoch: 10/10, losses: 1.4282708168029785 +``` + +> 典型的使用场景是梯度累积,详细查看[梯度累积](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/gradient_accumulation.html)。 + +## 边训练边推理 +对于某些数据量较大、训练时间较长的复杂网络,为了能掌握训练的不同阶段模型精度的指标变化情况,可以通过边训练边推理的方式跟踪精度的变化情况。具体可以参考[同步训练和验证模型](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/synchronization_training_and_evaluation.html)。 + +## on-device执行 +当前MindSpore支持的后端包括Ascend、GPU、CPU,所谓On Device中的Device通常指Ascend(昇腾)AI处理器。 + +昇腾芯片上集成了AICORE、AICPU和CPU。其中,AICORE负责大型Tensor Vector运算,AICPU负责标量运算,CPU负责逻辑控制和任务分发。 + +Host侧CPU负责将图或算子下发到昇腾芯片。昇腾芯片由于具备了运算、逻辑控制和任务分发的功能,所以不需要与Host侧的CPU进行频繁的交互,只需要将计算完的最终结果返回给Host侧,实现整图下沉到Device执行,避免Host-Device频繁交互,减小了开销。 + +以下是Device的主要组成结构: +- 片上32G内存:5G(parameter) + 26G(feature map) + 1G(HCCL) +- 多流水线并行:6条流水线 +- AICORE&带宽:32Cores、读写带宽128GBps +- 通信协议:HCCS、PCIe4.0、RoCEv2 + +### 计算图下沉 +计算图整图下沉到Device上执行,减少Host-Device交互开销。可以结合循环下沉实现多个Step下沉,进一步减少Host和Device的交互次数。 + +循环下沉是在On Device执行的基础上的优化,目的是进一步减少Host侧和Device侧之间的交互次数。通常情况下,每个step都返回一个结果,循环下沉是控制每隔多少个step返回一次结果。 + +默认配置下是每一个epoch返回一次结果,这样每个epoch里,Host侧和Device侧只需要进行一次数据交互。 + +也可以结合`train`接口的`dataset_sink_mode`和`sink_size`控制每个epoch的下沉数据量。 + +### 数据下沉 +`Model`的`train`接口参数`dataset_sink_mode`可以控制数据是否下沉。`dataset_sink_mode`为True表示数据下沉,否则为非下沉。所谓下沉即数据通过通道直接传送到Device上。 + +dataset_sink_mode参数可以配合`sink_size`控制每个`epoch`下沉的数据量大小。当`dataset_sink_mode`设置为True,即数据下沉模式时: + +如果`sink_size`为默认值-1,则每一个`epoch`下沉的数据量为原始的整个数据集大小; + +如果`sink_size`>0,此时原始数据集可以被无限次遍历,每个`epoch`下沉`sink_size`大小的数据量,下一个`epoch`继续从上次遍历的结束位置继续遍历。 + +下沉的总数据量由`epoch`和`sink_size`两个变量共同控制,即总数据量=`epoch`*`sink_size`。 + +代码样例如下: +```python +import os + +import mindspore.dataset as ds +import mindspore.dataset.transforms.c_transforms as CT +import mindspore.dataset.vision.c_transforms as CV +import mindspore.nn as nn +from mindspore import context +from mindspore.common import dtype as mstype +from mindspore.common.initializer import TruncatedNormal +from mindspore.dataset.vision import Inter +from mindspore.nn.metrics import Accuracy +from mindspore.ops import operations as P +from mindspore.train import Model +from mindspore.train.callback import LossMonitor + + +def create_dataset(data_path, batch_size=32, repeat_size=1, + num_parallel_workers=1): + """ + create dataset for train or test + """ + # define dataset + mnist_ds = ds.MnistDataset(data_path) + + resize_height, resize_width = 32, 32 + rescale = 1.0 / 255.0 + shift = 0.0 + rescale_nml = 1 / 0.3081 + shift_nml = -1 * 0.1307 / 0.3081 + + # define map operations + resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) # Bilinear mode + rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) + rescale_op = CV.Rescale(rescale, shift) + hwc2chw_op = CV.HWC2CHW() + type_cast_op = CT.TypeCast(mstype.int32) + + # apply map operations on images + mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) + mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) + + # apply DatasetOps + buffer_size = 10000 + mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script + mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True) + mnist_ds = mnist_ds.repeat(repeat_size) + + return mnist_ds + + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + """weight initial for conv layer""" + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + """weight initial for fc layer""" + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + """weight initial""" + return TruncatedNormal(0.02) + + +class LeNet5(nn.Cell): + """ + Lenet network + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + + Examples: + >>> LeNet(num_class=10) + """ + + def __init__(self, num_class=10): + super(LeNet5, self).__init__() + self.num_class = num_class + self.batch_size = 32 + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16 * 5 * 5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.reshape(x, (self.batch_size, -1)) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x + + +if __name__ == "__main__": + context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") + ds_train = create_dataset(os.path.join("/home/workspace/mindspore_dataset/MNIST_Data/", "train"), 32) + + network = LeNet5(10) + net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + net_opt = nn.Momentum(network.trainable_params(), 0.01, 0.9) + model = Model(network, net_loss, net_opt) + + print("============== Starting Training ==============") + model.train(epoch=10, train_dataset=ds_train, callbacks=[LossMonitor()], dataset_sink_mode=True, sink_size=1000) +``` + +`batch_size`为32的情况下,数据集的大小为1875,当`sink_size`设置为1000时,表示每个`epoch`下沉1000个batch的数据,下沉次数为`epoch`=10,下沉的总数据量为:`epoch`*`sink_size`=10000。 + +输出如下: +```python +epoch: 1 step: 1000, loss is 0.5399815 +epoch: 2 step: 1000, loss is 0.033433747 +epoch: 3 step: 1000, loss is 0.054761313 +epoch: 4 step: 1000, loss is 0.007882872 +epoch: 5 step: 1000, loss is 0.00658499 +epoch: 6 step: 1000, loss is 0.0413095 +epoch: 7 step: 1000, loss is 0.13373856 +epoch: 8 step: 1000, loss is 0.015793817 +epoch: 9 step: 1000, loss is 0.00017951085 +epoch: 10 step: 1000, loss is 0.01490275 +``` + +> `dataset_sink_mode`为False时,`sink_size`参数设置无效。 \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/type.md b/docs/programming_guide/source_zh_cn/type.md deleted file mode 100644 index 3ccdb56038..0000000000 --- a/docs/programming_guide/source_zh_cn/type.md +++ /dev/null @@ -1,54 +0,0 @@ -# 数据类型 - - - -- [数据类型](#数据类型) - - [概述](#概述) - - [操作接口](#操作接口) - - - - - - -## 概述 - -MindSpore张量支持不同的数据类型,有`int8`、`int16`、`int32`、`int64`、`uint8`、`uint16`、`uint32`、`uint64`、 -`float16`、`float32`、`float64`、`bool_`, 与NumPy的数据类型一一对应,Python里的`int`数会被转换为定义的int64进行运算, -Python里的`float`数会被转换为定义的`float32`进行运算。 - -## 操作接口 -- `dtype_to_nptype` - - 可通过该接口将MindSpore的数据类型转换为NumPy对应的数据类型。 - -- `dtype_to_pytype` - - 可通过该接口将MindSpore的数据类型转换为Python对应的内置数据类型。 - - -- `pytype_to_dtype` - - 可通过该接口将Python内置的数据类型转换为MindSpore对应的数据类型。 - -示例如下: - -``` -from mindspore import dtype as mstype - -np_type = mstype.dtype_to_nptype(mstype.int32) -ms_type = mstype.pytype_to_dtype(int) -py_type = mstype.dtype_to_pytype(mstype.float64) - -print(np_type) -print(ms_type) -print(py_type) -``` - -输出如下: - -``` - -Int64 - -``` diff --git a/docs/programming_guide/source_zh_cn/user_defined.rst b/docs/programming_guide/source_zh_cn/user_defined.rst new file mode 100644 index 0000000000..b710df2302 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/user_defined.rst @@ -0,0 +1,7 @@ +自定义 +=========== + +.. toctree:: + :maxdepth: 1 + + 自定义算子 \ No newline at end of file -- Gitee From d153eaee3babe9f129bf4343185fda494e125253 Mon Sep 17 00:00:00 2001 From: liuyang_655 Date: Thu, 17 Sep 2020 15:33:15 +0800 Subject: [PATCH 055/100] checkpoint tutorial --- .../distributed_training_ascend.md | 176 +++++++++++++++++- .../distributed_training_ascend.md | 174 +++++++++++++++++ .../advanced_use/distributed_training_gpu.md | 2 +- 3 files changed, 350 insertions(+), 2 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/distributed_training_ascend.md b/tutorials/training/source_en/advanced_use/distributed_training_ascend.md index 81415d95d3..e62587c0c5 100644 --- a/tutorials/training/source_en/advanced_use/distributed_training_ascend.md +++ b/tutorials/training/source_en/advanced_use/distributed_training_ascend.md @@ -17,6 +17,11 @@ - [Defining the Optimizer](#defining-the-optimizer) - [Training the Network](#training-the-network) - [Running the Script](#running-the-script) + - [Distributed Training Model Parameters Saving and Loading](#distributed-training-model-parameters-saving-and-loading) + - [Auto Parallel Mode](#auto-parallel-mode) + - [Data Parallel Mode](#data-parallel-mode) + - [Semi Auto Parallel Mode](#semi-auto-parallel-mode) + - [Hybrid Parallel Mode](#hybrid-parallel-mode) @@ -219,7 +224,7 @@ The `Momentum` optimizer is used as the parameter update tool. The definition is > You are advised to set `device_num` and `global_rank` to their default values. The framework calls the HCCL API to obtain the values. -If multiple network cases exist in the script, call `context.reset_auto_parallel_context()` to restore all parameters to default values before executing the next case. +If multiple network cases exist in the script, call `context.reset_auto_parallel_context` to restore all parameters to default values before executing the next case. In the following sample code, the automatic parallel mode is specified. To switch to the data parallel mode, you only need to change `parallel_mode` to `DATA_PARALLEL`. @@ -334,3 +339,172 @@ epoch: 8 step: 156, loss is 1.2943741 epoch: 9 step: 156, loss is 1.2316195 epoch: 10 step: 156, loss is 1.1533381 ``` + +## Distributed Training Model Parameters Saving and Loading + +The below content introduced how to save and load models under the four distributed parallel training modes respectively. Before saving model parameters for distributed training, it is necessary to configure distributed environment variables and collective communication library in accordance with this tutorial. + +### Auto Parallel Mode + +It is convenient to save and load the model parameters in auto parallel mode. Just add configuration `CheckpointConfig` and `ModelCheckpoint` to `test_train_cifar` method in the training network steps of this tutorial, and the model parameters can be saved. The code is as follows: + +```python +def test_train_cifar(epoch_size=10): + context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL, gradients_mean=True) + loss_cb = LossMonitor() + dataset = create_dataset(data_path) + batch_size = 32 + num_classes = 10 + net = resnet50(batch_size, num_classes) + loss = SoftmaxCrossEntropyExpand(sparse=True) + opt = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), 0.01, 0.9) + save_path = '...' + ckpt_config = CheckpointConfig() + ckpt_callback = ModelCheckpoint(prefix='auto_parallel', directory=save_path, config=ckpt_config) + model = Model(net, loss_fn=loss, optimizer=opt) + model.train(epoch_size, dataset, callbacks=[loss_cb, ckpt_callback], dataset_sink_mode=True) +``` + +After saving the checkpoint file, users can easily load model parameters for reasoning or retraining. For example, the following code can be used for retraining: + +```python +net = Net() +param_dict = load_checkpoint(save_path) +load_param_into_net(net, param_dict) +``` + +For checkpoint configuration policy and saving method, please refer to [Saving and Loading Model Parameters](https://www.mindspore.cn/tutorial/en/master/use/saving_and_loading_model_parameters.html#checkpoint-configuration-policies). + +### Data Parallel Mode + +Under Data Parallel Mode, checkpoint can be used as shown in the following example: + +```python +from mindspore.train import Model +from context import set_auto_parallel_context, reset_auto_parallel_context +from mindspore.nn import Momentum, Cell, Flatten, ReLU +from mindspore.train.callback import CheckpointConfig, ModelCheckpoint, LossMonitor +from mindspore.communication.management import get_rank +from mindspore.common.parameter import Parameter +from mindspore import Tensor +import mindspore.ops.operations as P +import numpy as np +# define network +class DataParallelNet(Cell): + def __init__(self, test_size, transpose_a=False, transpose_b=False, strategy=None, layerwise_parallel=True): + super().__init__() + weight_np = np.full(test_size, 0.1, dtype=np.float32) + self.weight = Parameter(Tensor(weight_np), name="fc_weight", layerwise_parallel=layerwise_parallel) + self.relu = ReLU() + self.fc = P.MatMul(transpose_a=transpose_a, transpose_b=transpose_b) + if strategy is not None: + self.fc.set_strategy(strategy) + + def construct(self, inputs, label): + x = self.relu(inputs) + x = self.fc(x, self.weight) + return x +``` + +Assuming that the Data Parallel mode is used to train and save the model on an 8P machine, the data needs to be obtained first, and the parallel strategy and parallel mode need to be set. The code is as follows: + +```python +# create data sets +parallel_dataset = CreateData() +# set parallel strategy +strategy = ((1, 1), (1, 8)) +# create network model +net = DataParallelNet(strategy=strategy) +# reset parallel mode +context.reset_auto_parallel_context() +# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel +# mode, you can simply change the value of parallel_mode parameter to ParallelMode.AUTO_PARALLEL. +context.set_auto_parallel_context(parallel_mode=ParallelMode.DATA_PARALLEL, device_num=8) +``` + +Then set the checkpoint saving policy, optimizer and loss function as required. The code is as follows: + +```python +# config checkpoint +ckpt_config = CheckpointConfig(keep_checkpoint_max=1) +# define checkpoint save path +ckpt_path = './rank_{}_ckpt'.format(get_rank) +# create a ModelCheckpoint object +ckpt_callback = ModelCheckpoint(prefix='data_parallel', directory=ckpt_path, config=ckpt_config) +# set optimizer and loss function +opt = Momentum() +loss = SoftmaxCrossEntropyExpand() +model = Model(net, loss_fb=loss, optimizer=opt) +# After training, the system will automatically save the checkpoint file. +model.train(train_dataset=parallel_dataset, callbacks=[ckpt_callback, loss]) +# After training, reset the parallel mode to avoid unnecessary trouble when retraining. +context.reset_auto_parallel_context() +``` + +After saving the checkpoint file, users can also use `load_checkpoint` and `load_param_into_Net` to load the model parameters. + +### Semi Auto Parallel Mode + +The whole process of using checkpoint in Semi Auto parallel Mode also starts from defining a network model. + +```python +class SemiAutoParallelNet(Cell): + def __init__(self, mul_size, test_size, strategy=None, strategy2=None): + super().__init__() + mul_np = np.full(mul_size, 0.5, dtype=np.float32) + equal_np = np.full(test_size, 0.1, dtype=np.float32) + self.mul_weight = Parameter(Tensor(mul_np), name="mul_weight") + self.equal_weight = Parameter(Tensor(equal_np), name="equal_weight") + self.mul = P.Mul() + self.equal = P.Equal() + if strategy is not None: + self.mul.set_strategy(strategy) + self.equal.set_strategy(strategy2) + + def construct(self, inputs, label): + x = self.mul(inputs, self.mul_weight) + x = self.equal(x, self.equal_weight) + return x +``` + +It is assumed that Semi Auto Parallel Mode is also trained and saved on an 8p machine. The code for getting data and setting the parallel strategy and parallel mode is as follows: + +```python +# create data sets +parallel_dataset = CreateData() +# set parallel strategy +strategy = ((1, 1), (1, 8)) +# create network model +net = SemiAutoParallelNet(strategy=strategy, strategy2=strategy) +# reset parallel mode +context.reset_auto_parallel_context() +# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel +# mode, you can simply change the value of parallel_mode parameter to ParallelMode.AUTO_PARALLEL. +context.set_auto_parallel_context(parallel_mode=ParallelMode.SEMI_AUTO_PARALLEL, + strategy_ckpt_save_file='./rank_{}_ckpt/strategy.txt'.format(get_rank)) +``` + +Then set the checkpoint saving policy, optimizer and loss function as required. The code is as follows: + +```python +# config checkpoint +ckpt_config = CheckpointConfig(keep_checkpoint_max=1) +# define checkpoint save path +ckpt_path = './rank_{}_ckpt'.format(get_rank) +# create a ModelCheckpoint object +ckpt_callback = ModelCheckpoint(prefix='semi_auto_parallel', directory=ckpt_path, config=ckpt_config) +# set optimizer and loss function +opt = Momentum() +loss = SoftmaxCrossEntropyExpand() +model = Model(net, loss_fb=loss, optimizer=opt) +# After you've trained your network, the system will automatically save the checkpoint file. +model.train(train_dataset=parallel_dataset, callbacks=[ckpt_callback, loss]) +# After training, reset the parallel mode to avoid unnecessary trouble when retraining. +context.reset_auto_parallel_context() +``` + +After saving the checkpoint file, users can also use `load_checkpoint`, `load_param_into_Net` to load the model parameters。 + +### Hybrid Parallel Mode + +For model parameter saving and loading in Hybrid Parallel Mode, please refer to [Saving and Loading Model Parameters in the Hybrid Parallel Scenario](https://www.mindspore.cn/tutorial/en/master/advanced_use/checkpoint_for_hybrid_parallel.html). \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md b/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md index 570a8ea4c4..7a87a80a81 100644 --- a/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md +++ b/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md @@ -17,6 +17,11 @@ - [定义优化器](#定义优化器) - [训练网络](#训练网络) - [运行脚本](#运行脚本) + - [分布式训练模型参数保存和加载](#分布式训练模型参数保存和加载) + - [自动并行模式](#自动并行模式) + - [数据并行模式](#数据并行模式) + - [半自动并行模式](#半自动并行模式) + - [手动混合并行模式](#手动混合并行模式) @@ -338,3 +343,172 @@ epoch: 8 step: 156, loss is 1.2943741 epoch: 9 step: 156, loss is 1.2316195 epoch: 10 step: 156, loss is 1.1533381 ``` + +## 分布式训练模型参数保存和加载 + +在MindSpore中,支持四种分布式并行训练模式,即自动并行模式(Auto Parallel)、数据并行模式(Data Parallel)、半自动并行模式(Semi Auto Parallel)、手动混合并行模式(Hybrid Parallel),下面分别介绍四种分布式并行训练模式下模型的保存和加载。分布式训练进行模型参数的保存之前,需要先按照本教程配置分布式环境变量和集合通信库。 + +### 自动并行模式 + +自动并行模式(Auto Parallel)下模型参数的保存和加载非常方便,只需在本教程训练网络步骤中的`test_train_cifar`方法中添加配置`CheckpointConfig`和`ModelCheckpoint`,即可实现模型参数的保存,具体代码如下: + +```python +def test_train_cifar(epoch_size=10): + context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL, gradients_mean=True) + loss_cb = LossMonitor() + dataset = create_dataset(data_path) + batch_size = 32 + num_classes = 10 + net = resnet50(batch_size, num_classes) + loss = SoftmaxCrossEntropyExpand(sparse=True) + opt = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), 0.01, 0.9) + save_path = '...' + ckpt_config = CheckpointConfig() + ckpt_callback = ModelCheckpoint(prefix='auto_parallel', directory=save_path, config=ckpt_config) + model = Model(net, loss_fn=loss, optimizer=opt) + model.train(epoch_size, dataset, callbacks=[loss_cb, ckpt_callback], dataset_sink_mode=True) +``` + +保存好checkpoint文件后,用户可以很容易加载模型参数进行推理或再训练场景,如用于再训练场景可使用如下代码: + +```python +net = Net() +param_dict = load_checkpoint(save_path) +load_param_into_net(net, param_dict) +``` + +checkpoint配置策略和保存方法可以参考[模型参数的保存和加载](https://www.mindspore.cn/tutorial/zh-CN/master/use/saving_and_loading_model_parameters.html#checkpoint)。 + +### 数据并行模式 + +数据并行模式(Data Parallel)下checkpoint的使用方法如下,首先定义一个网络模型: + +```python +from mindspore.train import Model +from context import set_auto_parallel_context, reset_auto_parallel_context +from mindspore.nn import Momentum, Cell, Flatten, ReLU +from mindspore.train.callback import CheckpointConfig, ModelCheckpoint, LossMonitor +from mindspore.communication.management import get_rank +from mindspore.common.parameter import Parameter +from mindspore import Tensor +import mindspore.ops.operations as P +import numpy as np +# define network +class DataParallelNet(Cell): + def __init__(self, test_size, transpose_a=False, transpose_b=False, strategy=None, layerwise_parallel=True): + super().__init__() + weight_np = np.full(test_size, 0.1, dtype=np.float32) + self.weight = Parameter(Tensor(weight_np), name="fc_weight", layerwise_parallel=layerwise_parallel) + self.relu = ReLU() + self.fc = P.MatMul(transpose_a=transpose_a, transpose_b=transpose_b) + if strategy is not None: + self.fc.set_strategy(strategy) + + def construct(self, inputs, label): + x = self.relu(inputs) + x = self.fc(x, self.weight) + return x +``` + +假设在一台8P机器上使用数据并行模式进行训练和保存模型,首先需要获取数据,设置并行策略和并行模式,代码如下: + +```python +# create data sets +parallel_dataset = CreateData() +# set parallel strategy +strategy = ((1, 1), (1, 8)) +# create network model +net = DataParallelNet(strategy=strategy) +# reset parallel mode +context.reset_auto_parallel_context() +# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel +# mode, you can simply change the value of parallel_mode parameter to ParallelMode.AUTO_PARALLEL. +context.set_auto_parallel_context(parallel_mode=ParallelMode.DATA_PARALLEL, device_num=8) +``` + +然后根据需要设置checkpoint保存策略,以及设置优化器和损失函数等,代码如下: + +```python +# config checkpoint +ckpt_config = CheckpointConfig(keep_checkpoint_max=1) +# define checkpoint save path +ckpt_path = './rank_{}_ckpt'.format(get_rank) +# create a ModelCheckpoint object +ckpt_callback = ModelCheckpoint(prefix='data_parallel', directory=ckpt_path, config=ckpt_config) +# set optimizer and loss function +opt = Momentum() +loss = SoftmaxCrossEntropyExpand() +model = Model(net, loss_fb=loss, optimizer=opt) +# After training, the system will automatically save the checkpoint file. +model.train(train_dataset=parallel_dataset, callbacks=[ckpt_callback, loss]) +# After training, reset the parallel mode to avoid unnecessary trouble when retraining. +context.reset_auto_parallel_context() +``` + +保存好checkpoint文件后,用户同样可以使用`load_checkpoint`,`load_param_into_net`来加载模型参数。 + +### 半自动并行模式 + +半自动并行模式(Semi Auto Parallel)下checkpoint使用方法的完整流程,同样从定义一个网络模型开始: + +```python +class SemiAutoParallelNet(Cell): + def __init__(self, mul_size, test_size, strategy=None, strategy2=None): + super().__init__() + mul_np = np.full(mul_size, 0.5, dtype=np.float32) + equal_np = np.full(test_size, 0.1, dtype=np.float32) + self.mul_weight = Parameter(Tensor(mul_np), name="mul_weight") + self.equal_weight = Parameter(Tensor(equal_np), name="equal_weight") + self.mul = P.Mul() + self.equal = P.Equal() + if strategy is not None: + self.mul.set_strategy(strategy) + self.equal.set_strategy(strategy2) + + def construct(self, inputs, label): + x = self.mul(inputs, self.mul_weight) + x = self.equal(x, self.equal_weight) + return x +``` + +假设半自动并行模式也是在一台8P机器上进行训练和保存模型。获取数据,设置并行策略和并行模式的代码如下: + +```python +# create data sets +parallel_dataset = CreateData() +# set parallel strategy +strategy = ((1, 1), (1, 8)) +# create network model +net = SemiAutoParallelNet(strategy=strategy, strategy2=strategy) +# reset parallel mode +context.reset_auto_parallel_context() +# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel +# mode, you can simply change the value of parallel_mode parameter to ParallelMode.AUTO_PARALLEL. +context.set_auto_parallel_context(parallel_mode=ParallelMode.SEMI_AUTO_PARALLEL, + strategy_ckpt_save_file='./rank_{}_ckpt/strategy.txt'.format(get_rank)) +``` + +然后根据需要设置checkpoint保存策略,以及设置优化器和损失函数等,代码如下: + +```python +# config checkpoint +ckpt_config = CheckpointConfig(keep_checkpoint_max=1) +# define checkpoint save path +ckpt_path = './rank_{}_ckpt'.format(get_rank) +# create a ModelCheckpoint object +ckpt_callback = ModelCheckpoint(prefix='semi_auto_parallel', directory=ckpt_path, config=ckpt_config) +# set optimizer and loss function +opt = Momentum() +loss = SoftmaxCrossEntropyExpand() +model = Model(net, loss_fb=loss, optimizer=opt) +# After you've trained your network, the system will automatically save the checkpoint file. +model.train(train_dataset=parallel_dataset, callbacks=[ckpt_callback, loss]) +# After training, reset the parallel mode to avoid unnecessary trouble when retraining. +context.reset_auto_parallel_context() +``` + +保存好checkpoint文件后,用户同样可以使用`load_checkpoint`,`load_param_into_net`来加载模型参数。 + +### 手动混合并行模式 + +手动混合并行模式(Hybrid Parallel)的模型参数保存和加载请参考[手动设置并行场景模型参数的保存和加载](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/checkpoint_for_hybrid_parallel.html)。 \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md b/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md index 13cb619328..d0888857a3 100644 --- a/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md +++ b/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md @@ -10,7 +10,6 @@ - [下载数据集](#下载数据集) - [配置分布式环境](#配置分布式环境) - [调用集合通信库](#调用集合通信库) - - [数据并行模式加载数据集](#数据并行模式加载数据集) - [定义网络](#定义网络) - [运行脚本](#运行脚本) - [运行多机脚本](#运行多机脚本) @@ -146,3 +145,4 @@ echo "start training" mpirun -n 16 --hostfile $HOSTFILE -x DATA_PATH=$DATA_PATH -x PATH -mca pml ob1 pytest -s -v ./resnet50_distributed_training.py > train.log 2>&1 & ``` +在GPU上进行分布式训练时,模型参数的保存和加载可参考[分布式训练模型参数保存和加载](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_ascend.html#id12) \ No newline at end of file -- Gitee From da9f6e23a5e7efedffc9744775c15afcf0a466f1 Mon Sep 17 00:00:00 2001 From: shenwei41 Date: Thu, 17 Sep 2020 15:42:04 +0800 Subject: [PATCH 056/100] Add tutorials of lite --- docs/api_cpp/source_en/dataset.md | 34 +++- docs/api_cpp/source_zh_cn/dataset.md | 35 +++- tutorials/lite/source_en/index.rst | 1 + tutorials/lite/source_en/use/build.md | 27 +++- .../lite/source_en/use/image_processing.md | 149 ++++++++++++++++++ tutorials/lite/source_zh_cn/index.rst | 1 + tutorials/lite/source_zh_cn/use/build.md | 27 +++- .../lite/source_zh_cn/use/image_processing.md | 149 ++++++++++++++++++ 8 files changed, 419 insertions(+), 4 deletions(-) create mode 100644 tutorials/lite/source_en/use/image_processing.md create mode 100644 tutorials/lite/source_zh_cn/use/image_processing.md diff --git a/docs/api_cpp/source_en/dataset.md b/docs/api_cpp/source_en/dataset.md index 4f58dd0436..9d457bba12 100644 --- a/docs/api_cpp/source_en/dataset.md +++ b/docs/api_cpp/source_en/dataset.md @@ -6,6 +6,8 @@ ## Functions of image_process.h +### ResizeBilinear + ``` bool ResizeBilinear(LiteMat &src, LiteMat &dst, int dst_w, int dst_h) ``` @@ -22,6 +24,8 @@ Resize image by bilinear algorithm, currently the data type only supports uint8, Return True or False. +### InitFromPixel + ``` bool InitFromPixel(const unsigned char *data, LPixelType pixel_type, LDataType data_type, int w, int h, LiteMat &m) ``` @@ -40,6 +44,8 @@ Initialize LiteMat from pixel, currently the conversion supports rbgaTorgb and r Return True or False. +### ConvertTo + ``` bool ConvertTo(LiteMat &src, LiteMat &dst, double scale = 1.0) ``` @@ -56,6 +62,8 @@ Convert the data type, currently it supports converting the data type from uint8 Return True or False. +### Crop + ``` bool Crop(LiteMat &src, LiteMat &dst, int x, int y, int w, int h) ``` @@ -74,6 +82,8 @@ Crop image, the channel supports is 3 and 1. Return True or False. +### SubStractMeanNormalize + ``` bool SubStractMeanNormalize(LiteMat &src, LiteMat &dst, const float *mean, float *norm) ``` @@ -90,11 +100,13 @@ Normalize image, currently the supports data type is float. Return True or False. +### Pad + ``` bool Pad(LiteMat &src, LiteMat &dst, const int top, const int bottom, const int left, const int right, const PaddBorderType pad_type, uint8_t fill_r, uint8_t fill_g, uint8_t fill_b) ``` -Padd image, the channel supports is 3 and 1. +Pad image, the channel supports is 3 and 1. - Parameters @@ -112,6 +124,8 @@ Padd image, the channel supports is 3 and 1. Return True or False. +### Affine + ``` void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector dsize, UINT8_C1 borderValue) ``` @@ -140,6 +154,8 @@ Apply affine transformation for 3 channel image. - `dsize`: The size of the output image. - `borderValue`: The pixel value is used for filing after the image is captured. +### GetDefaultBoxes + ``` std::vector> GetDefaultBoxes(BoxesConfig config) ``` @@ -154,6 +170,8 @@ Get default anchor boxes for Faster R-CNN, SSD, YOLO etc. Return the default boxes. +### ConvertBoxes + ``` void ConvertBoxes(std::vector> &boxes, std::vector> &default_boxes, BoxesConfig config) ``` @@ -166,6 +184,8 @@ Convert the prediction boxes to the actual boxes with (y, x, h, w). - `default_boxes`: Default box. - `config`: Objects of BoxesConfig structure. +### ApplyNms + ``` std::vector ApplyNms(std::vector> &all_boxes, std::vector &all_scores, float thres, int max_boxes) ``` @@ -190,6 +210,7 @@ Class that represents a lite Mat of a Image. **Constructors & Destructors** +### LiteMat ``` LiteMat() @@ -211,6 +232,7 @@ Destructor of MindSpore dataset LiteMat. **Public Member Functions** +### Init ``` void Init(int width, LDataType data_type = LDataType::UINT8) @@ -222,6 +244,8 @@ void Init(int width, int height, int channel, LDataType data_type = LDataType::U The function to initialize the channel, width and height of the image, but the parameters are different. +### IsEmpty + ``` bool IsEmpty() const ``` @@ -232,6 +256,8 @@ A function to determine whether the object is empty. Return True or False. +### Release + ``` void Release() ``` @@ -240,6 +266,8 @@ A function to release memory. **Private Member Functions** +### AlignMalloc + ``` void *AlignMalloc(unsigned int size) ``` @@ -254,6 +282,8 @@ Apply for memory alignment. Return the size of a pointer. +### AlignFree + ``` void AlignFree(void *ptr) ``` @@ -270,6 +300,8 @@ Initialize the value of elem_size_ by data_type. - `data_type`: Type of data. +### addRef + ``` int addRef(int *p, int value) ``` diff --git a/docs/api_cpp/source_zh_cn/dataset.md b/docs/api_cpp/source_zh_cn/dataset.md index 379d3e1163..9e12aab3ad 100644 --- a/docs/api_cpp/source_zh_cn/dataset.md +++ b/docs/api_cpp/source_zh_cn/dataset.md @@ -6,6 +6,8 @@ ## image_process.h文件的函数 +### ResizeBilinear + ``` bool ResizeBilinear(LiteMat &src, LiteMat &dst, int dst_w, int dst_h) ``` @@ -22,6 +24,8 @@ bool ResizeBilinear(LiteMat &src, LiteMat &dst, int dst_w, int dst_h) 返回True或者False。 +### InitFromPixel + ``` bool InitFromPixel(const unsigned char *data, LPixelType pixel_type, LDataType data_type, int w, int h, LiteMat &m) ``` @@ -40,6 +44,8 @@ bool InitFromPixel(const unsigned char *data, LPixelType pixel_type, LDataType d 返回True或者False。 +### ConvertTo + ``` bool ConvertTo(LiteMat &src, LiteMat &dst, double scale = 1.0) ``` @@ -56,6 +62,8 @@ bool ConvertTo(LiteMat &src, LiteMat &dst, double scale = 1.0) 返回True或者False。 +### Crop + ``` bool Crop(LiteMat &src, LiteMat &dst, int x, int y, int w, int h) ``` @@ -74,6 +82,8 @@ bool Crop(LiteMat &src, LiteMat &dst, int x, int y, int w, int h) 返回True或者False。 +### SubStractMeanNormalize + ``` bool SubStractMeanNormalize(LiteMat &src, LiteMat &dst, const float *mean, float *norm) ``` @@ -90,8 +100,10 @@ bool SubStractMeanNormalize(LiteMat &src, LiteMat &dst, const float *mean, float 返回True或者False。 +### Pad + ``` -bool Padd(LiteMat &src, LiteMat &dst, const int top, const int bottom, const int left, const int right, const PaddBorderType pad_type, uint8_t fill_r, uint8_t fill_g, uint8_t fill_b) +bool Pad(LiteMat &src, LiteMat &dst, const int top, const int bottom, const int left, const int right, const PaddBorderType pad_type, uint8_t fill_r, uint8_t fill_g, uint8_t fill_b) ``` 填充图像,通道支持为3和1。 @@ -112,6 +124,8 @@ bool Padd(LiteMat &src, LiteMat &dst, const int top, const int bottom, const int 返回True或者False。 +### Affine + ``` void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector dsize, UINT8_C1 borderValue) ``` @@ -140,6 +154,8 @@ void Affine(LiteMat &src, LiteMat &out_img, double M[6], std::vector dsi - `dsize`: 输出图像的大小。 - `borderValue`: 采图之后用于填充的像素值。 +### GetDefaultBoxes + ``` std::vector> GetDefaultBoxes(BoxesConfig config) ``` @@ -154,6 +170,8 @@ std::vector> GetDefaultBoxes(BoxesConfig config) 返回默认框。 +### ConvertBoxes + ``` void ConvertBoxes(std::vector> &boxes, std::vector> &default_boxes, BoxesConfig config) ``` @@ -166,6 +184,8 @@ void ConvertBoxes(std::vector> &boxes, std::vector ApplyNms(std::vector> &all_boxes, std::vector &all_scores, float thres, int max_boxes) ``` @@ -190,6 +210,7 @@ LiteMat是一个处理图像的类。 **构造函数和析构函数** +### LiteMat ``` LiteMat() @@ -211,6 +232,7 @@ MindSpore dataset LiteMat的析构函数。 **公有成员函数** +### Init ``` void Init(int width, LDataType data_type = LDataType::UINT8) @@ -222,6 +244,8 @@ void Init(int width, int height, int channel, LDataType data_type = LDataType::U 该函数用于初始化图像的通道,宽度和高度,参数不同。 +### IsEmpty + ``` bool IsEmpty() const ``` @@ -232,6 +256,8 @@ bool IsEmpty() const 返回True或者False。 +### Release + ``` void Release() ``` @@ -240,6 +266,8 @@ void Release() **私有成员函数** +### AlignMalloc + ``` void *AlignMalloc(unsigned int size) ``` @@ -254,12 +282,17 @@ void *AlignMalloc(unsigned int size) 返回指针的大小。 +### AlignFree + ``` void AlignFree(void *ptr) ``` 释放指针内存大小的方法。 + +### InitElemSize + ``` void InitElemSize(LDataType data_type) ``` diff --git a/tutorials/lite/source_en/index.rst b/tutorials/lite/source_en/index.rst index 757fccaf22..5ddc42f053 100644 --- a/tutorials/lite/source_en/index.rst +++ b/tutorials/lite/source_en/index.rst @@ -21,4 +21,5 @@ Using MindSpore on Mobile and IoT use/build use/converter_tool use/evaluating_the_model + use/image_processing use/runtime diff --git a/tutorials/lite/source_en/use/build.md b/tutorials/lite/source_en/use/build.md index f482934a0f..12a746acd3 100644 --- a/tutorials/lite/source_en/use/build.md +++ b/tutorials/lite/source_en/use/build.md @@ -9,7 +9,8 @@ - [Compilation Example](#compilation-example) - [Output Description](#output-description) - [Description of Converter's Directory Structure](#description-of-converters-directory-structure) - - [Description of Runtime and Other tools' Directory Structure](#description-of-runtime-and-other-tools-directory-structure) + - [Description of Runtime and Other tools' Directory Structure](#description-of-runtime-and-other-tools-directory-structure) + - [Description of Imageprocess's Directory Structure](#description-of-imageprocesss-directory-structure) @@ -23,6 +24,7 @@ This chapter introduces how to quickly compile MindSpore Lite, which includes th | runtime | Linux、Android | Model Inference Framework | | benchmark | Linux、Android | Benchmarking Tool | | timeprofiler | Linux、Android | Performance Analysis Tool | +| imageprocess | Linux、Android | Image Processing Library | ## Linux Environment Compilation @@ -64,6 +66,7 @@ MindSpore Lite provides a compilation script `build.sh` for one-click compilatio | -j[n] | Sets the number of threads used during compilation. Otherwise, the number of threads is set to 8 by default. | Integer | No | | -e | In the Arm architecture, select the backend operator and set the `gpu` parameter. The built-in GPU operator of the framework is compiled at the same time. | GPU | No | | -h | Displays the compilation help information. | None | No | +| -n | Specifies to compile the lightweight image processing module. | None | No | > When the `-I` parameter changes, such as `-I x86_64` is converted to `-I arm64`, adding `-i` for parameter compilation does not take effect. @@ -97,11 +100,17 @@ Then, run the following commands in the root directory of the source code to com bash build.sh -I arm64 -e gpu ``` +- Compile ARM64 with image preprocessing module: + ```bash + bash build.sh -I arm64 -n lite_cv + ``` + ### Output Description After the compilation is complete, go to the `mindspore/output` directory of the source code to view the file generated after compilation. The file is divided into two parts. - `mindspore-lite-{version}-converter-{os}.tar.gz`:Contains model conversion tool. - `mindspore-lite-{version}-runtime-{os}-{device}.tar.gz`:Contains model inference framework、benchmarking tool and performance analysis tool. +- `mindspore-lite-{version}-minddata-{os}-{device}.tar.gz`:Contains image processing library ImageProcess. > version: version of the output, consistent with that of the MindSpore. > @@ -114,6 +123,7 @@ Execute the decompression command to obtain the compiled output: ```bash tar -xvf mindspore-lite-{version}-converter-{os}.tar.gz tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz +tar -xvf mindspore-lite-{version}-minddata-{os}-{device}.tar.gz ``` #### Description of Converter's Directory Structure @@ -178,3 +188,18 @@ The inference framework can be obtained under `-I x86_64`, `-I arm64` and `-I ar > 1. `liboptimize.so` only exists in the output package of runtime-arm64 and is only used on ARMv8.2 and CPUs that support fp16. > 2. Compile ARM64 to get the inference framework output of arm64-cpu by default, if you add `-e gpu`, you will get the inference framework output of arm64-gpu, and the package name is `mindspore-lite-{version}-runtime-arm64-gpu.tar.gz`, compiling ARM32 is in the same way. > 3. Before running the tools in the converter, benchmark or time_profiler directory, you need to configure environment variables, and configure the path where the dynamic libraries of MindSpore Lite and Protobuf are located to the path where the system searches for dynamic libraries. Take the compiled under version 0.7.0-beta as an example: configure converter: `export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`; configure benchmark and timeprofiler: `export LD_LIBRARY_PATH= ./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`. + +#### Description of Imageprocess's Directory Structure + +The image processing library is only available under the `-I arm64 -n lite_cv` compilation option, and the content includes the following parts: + +``` +| +├── mindspore-lite-{version}-minddata-{os}-{device} +│ └── include # Head file +│ ├── lite_cv # Image processing library header file +│ └── lib # Dynamic library +│ ├── libminddata-lite.so # Image processing dynamic library +│ └── third_party # Third-party Iibrary header files and libraries +│ ├── flatbuffers # Header files of FlatBuffers +``` \ No newline at end of file diff --git a/tutorials/lite/source_en/use/image_processing.md b/tutorials/lite/source_en/use/image_processing.md new file mode 100644 index 0000000000..cce6863a5b --- /dev/null +++ b/tutorials/lite/source_en/use/image_processing.md @@ -0,0 +1,149 @@ +# Preprocess image data + + + +- [Preprocess image data](#preprocess-image-data) + - [Overview](#Overview) + - [Import image preprocessing function library](#import-image-preprocessing-function-library) + - [Initialize the image](#initialize-the-image) + - [Usage example](#usage-example) + - [Optional image preprocessing operator](#optional-image-preprocessing-operator) + - [Resize image](#resize-image) + - [Usage example](#usage-example-1) + - [Convert the image data type](#convert-the-image-data-type) + - [Usage example](#usage-example-2) + - [Crop image data](#crop-image-data) + - [Usage example](#usage-example-3) + - [Normalize image data](#normalize-image-data) + - [Usage example](#usage-example-4) + + + +## Overview + +The main purpose of image preprocessing is to eliminate irrelevant information in the image, restore useful real information, enhance the detectability of related information and simplify data to the greatest extent, thereby improving the reliability of feature extraction, image segmentation, matching and recognition. Here, by creating a LiteMat object, the image data is processed before inference to meet the data format requirements for model inference. + +The process is as follows: + +## Import image preprocessing function library + +``` +#include "lite_cv/lite_mat.h" +#include "lite_cv/image_process.h" +``` + +## Initialize the image + +Here, the [InitFromPixel](https://www.mindspore.cn/lite/docs/en/master/apicc/dataset.html#initfrompixel) function in the `image_process.h` file is used to initialize the image. + +``` +bool InitFromPixel(const unsigned char *data, LPixelType pixel_type, LDataType data_type, int w, int h, LiteMat &m); +``` + +### Usage example + +``` +// Create the data object of the LiteMat object. +LiteMat lite_mat_bgr; + +// Initialize the lite_mat_bgr object. +// The image data pointer passed in by the user (The data in the Bitmap corresponding to the Android platform). +InitFromPixel(pixel_ptr, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); +``` + +## Optional image preprocessing operator + +The image processing operators here can be used in any combination according to the actual situation. + +### Resize image + +Here we use the [ResizeBilinear](https://www.mindspore.cn/lite/docs/en/master/apicc/dataset.html#resizebilinear) function in `image_process.h` to resize the image through a bilinear algorithm. Currently, the supported data type is unit8, the supported channels are 3 and 1. + +``` +bool ResizeBilinear(const LiteMat &src, LiteMat &dst, int dst_w, int dst_h); +``` + +#### Usage example + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// Create a resize image data object. +LiteMat lite_mat_resize; + +// Resize the image. +ResizeBilinear(lite_mat_bgr, lite_mat_resize, 256, 256); +``` + +### Convert the image data type + +Here we use the [ConvertTo](https://www.mindspore.cn/lite/docs/en/master/apicc/dataset.html#convertto) function in `image_process.h` to convert the image data type. Currently, the supported conversion is to convert uint8 to float. + +``` +bool ConvertTo(const LiteMat &src, LiteMat &dst, double scale = 1.0); +``` + +#### Usage example + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// Create the converted data type object. +LiteMat lite_mat_convert_float; + +// Perform conversion type operations on the object. Currently, the supported conversion is to convert uint8 to float. +ConvertTo(lite_mat_bgr, lite_mat_convert_float); +``` + +### Crop image data + +Here we use the [Crop](https://www.mindspore.cn/lite/docs/en/master/apicc/dataset.html#crop) function in `image_process.h` to crop the image. Currently, channels 3 and 1 are supported. + +``` +bool Crop(const LiteMat &src, LiteMat &dst, int x, int y, int w, int h); +``` + +#### Usage example + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// Create the cropped object. +LiteMat lite_mat_cut; + +// The image is cropped by the values of x, y, w, h. +Crop(lite_mat_bgr, lite_mat_cut, 16, 16, 224, 224); +``` + +### Normalize image data + +In order to eliminate the dimensional influence among the data indicators, and solve the comparability problem among the data indicators through standardization processing, here is the use of the [SubStractMeanNormalize](https://www.mindspore.cn/lite/docs/en/master/apicc/dataset.html#substractmeannormalize) function in `image_process.h` to normalize the image data. + +``` +bool SubStractMeanNormalize(const LiteMat &src, LiteMat &dst, float *mean, float *norm); +``` + +#### Usage example + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// The mean value of the image data. +// The variance of the image data. +float means[1] = {0.485}; +float norm[1] = {1.0 / 0.229}; + +// Create a normalized image object. +LiteMat lite_mat_bgr_norm; + +// The image data is normalized by the mean value and variance of the image data. +SubStractMeanNormalize(lite_mat_bgr, lite_mat_bgr_norm, means, norm); +``` \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/index.rst b/tutorials/lite/source_zh_cn/index.rst index 98cb3a95ac..e79b691eb8 100644 --- a/tutorials/lite/source_zh_cn/index.rst +++ b/tutorials/lite/source_zh_cn/index.rst @@ -21,4 +21,5 @@ use/build use/converter_model use/evaluating_the_model + use/image_processing use/runtime \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/use/build.md b/tutorials/lite/source_zh_cn/use/build.md index 12df7b60f4..19d5457427 100644 --- a/tutorials/lite/source_zh_cn/use/build.md +++ b/tutorials/lite/source_zh_cn/use/build.md @@ -9,7 +9,8 @@ - [编译示例](#编译示例) - [编译输出](#编译输出) - [模型转换工具converter目录结构说明](#模型转换工具converter目录结构说明) - - [模型推理框架runtime及其他工具目录结构说明](#模型推理框架runtime及其他工具目录结构说明) + - [模型推理框架runtime及其他工具目录结构说明](#模型推理框架runtime及其他工具目录结构说明) + - [图像处理库目录结构说明](#图像处理库目录结构说明) @@ -23,6 +24,7 @@ | runtime | Linux、Android | 模型推理框架 | | benchmark | Linux、Android | 基准测试工具 | | timeprofiler | Linux、Android | 性能分析工具 | +| imageprocess | Linux、Android | 图像处理库 | ## Linux环境编译 @@ -64,6 +66,7 @@ MindSpore Lite提供编译脚本`build.sh`用于一键式编译,位于MindSpor | -j[n] | 设定编译时所用的线程数,否则默认设定为8线程 | Integer | 否 | | -e | 选择除CPU之外的其他内置算子类型,仅在ARM架构下适用,当前仅支持GPU | GPU | 否 | | -h | 显示编译帮助信息 | 无 | 否 | +| -n | 指定编译轻量级图片处理模块 | 无 | 否 | > 在`-I`参数变动时,如`-I x86_64`变为`-I arm64`,添加`-i`参数进行增量编译不生效。 @@ -97,11 +100,17 @@ git clone https://gitee.com/mindspore/mindspore.git bash build.sh -I arm64 -e gpu ``` +- 编译ARM64带图像预处理模块。 + ```bash + bash build.sh -I arm64 -n lite_cv + ``` + ### 编译输出 编译完成后,进入`mindspore/output/`目录,可查看编译后生成的文件。文件分为两部分: - `mindspore-lite-{version}-converter-{os}.tar.gz`:包含模型转换工具converter。 - `mindspore-lite-{version}-runtime-{os}-{device}.tar.gz`:包含模型推理框架runtime、基准测试工具benchmark和性能分析工具timeprofiler。 +- `mindspore-lite-{version}-minddata-{os}-{device}.tar.gz`:包含图像处理库imageprocess。 > version:输出件版本号,与所编译的分支代码对应的版本一致。 > @@ -114,6 +123,7 @@ git clone https://gitee.com/mindspore/mindspore.git ```bash tar -xvf mindspore-lite-{version}-converter-{os}.tar.gz tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz +tar -xvf mindspore-lite-{version}-minddata-{os}-{device}.tar.gz ``` #### 模型转换工具converter目录结构说明 @@ -179,3 +189,18 @@ tar -xvf mindspore-lite-{version}-runtime-{os}-{device}.tar.gz > 1. `liboptimize.so`仅在runtime-arm64的输出包中存在,仅在ARMv8.2和支持fp16特性的CPU上使用。 > 2. 编译ARM64默认可获得arm64-cpu的推理框架输出件,若添加`-e gpu`则获得arm64-gpu的推理框架输出件,此时包名为`mindspore-lite-{version}-runtime-arm64-gpu.tar.gz`,编译ARM32同理。 > 3. 运行converter、benchmark或time_profiler目录下的工具前,都需配置环境变量,将MindSpore Lite和Protobuf的动态库所在的路径配置到系统搜索动态库的路径中。以0.7.0-beta版本下编译为例:配置converter:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/protobuf/lib:./output/mindspore-lite-0.7.0-converter-ubuntu/third_party/flatbuffers/lib:${LD_LIBRARY_PATH}`;配置benchmark和timeprofiler:`export LD_LIBRARY_PATH=./output/mindspore-lite-0.7.0-runtime-x86-cpu/lib:${LD_LIBRARY_PATH}`。 + +#### 图像处理库目录结构说明 + +图像处理库在`-I arm64 -n lite_cv`编译选项下获得,内容包括以下几部分: + +``` +| +├── mindspore-lite-{version}-minddata-{os}-{device} +│ └── include # 头文件 +│ ├── lite_cv # 图像处理库头文件 +│ └── lib # 动态库 +│ ├── libminddata-lite.so # 图像处理动态库 +│ └── third_party # 第三方库头文件和库 +│ ├── flatbuffers # Flatbuffers的动态库 +``` \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/use/image_processing.md b/tutorials/lite/source_zh_cn/use/image_processing.md new file mode 100644 index 0000000000..139ad867a9 --- /dev/null +++ b/tutorials/lite/source_zh_cn/use/image_processing.md @@ -0,0 +1,149 @@ +# 预处理图像数据 + + + +- [预处理图像数据](#预处理图像数据) + - [概述](#概述) + - [导入图像预处理函数的库](#导入图像预处理函数的库) + - [对图像进行初始化](#对图像进行初始化) + - [使用示例](#使用示例) + - [可选的图像预处理算子](#可选的图像预处理算子) + - [对图像进行缩放操作](#对图像进行缩放操作) + - [使用示例](#使用示例-1) + - [对图像数据类型进行转换](#对图像数据类型进行转换) + - [使用示例](#使用示例-2) + - [对图像数据进行裁剪](#对图像数据进行裁剪) + - [使用示例](#使用示例-3) + - [对图像数据进行归一化处理](#对图像数据进行归一化处理) + - [使用示例](#使用示例-4) + + + +## 概述 + +图像预处理的主要目的是消除图像中无关的信息,恢复有用的真实信息,增强有关信息的可检测性和最大限度地简化数据,从而改进特征抽取、图像分割、匹配和识别的可靠性。此处是通过创建LiteMat对象,在推理前对图像数据进行处理,达到模型推理所需要的数据格式要求。 + +流程如下: + +## 导入图像预处理函数的库 + +``` +#include "lite_cv/lite_mat.h" +#include "lite_cv/image_process.h" +``` + +## 对图像进行初始化 + +这边使用的是`image_process.h`文件中的[InitFromPixel](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/dataset.html#initfrompixel)函数对图像进行初始化操作。 + +``` +bool InitFromPixel(const unsigned char *data, LPixelType pixel_type, LDataType data_type, int w, int h, LiteMat &m); +``` + +### 使用示例 + +``` +// Create the data object of the LiteMat object. +LiteMat lite_mat_bgr; + +// Initialize the lite_mat_bgr object. +// The image data pointer passed in by the user (The data in the Bitmap corresponding to the Android platform). +InitFromPixel(pixel_ptr, LPixelType::RGBA2GRAY, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); +``` + +## 可选的图像预处理算子 + +此处的图像处理算子,用户可以根据实际情况任意搭配使用。 + +### 对图像进行缩放操作 + +这边利用的是`image_process.h`中的[ResizeBilinear](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/dataset.html#resizebilinear)函数通过双线性算法调整图像大小,当前仅支持的数据类型为uint8,当前支持的通道为3和1。 + +``` +bool ResizeBilinear(const LiteMat &src, LiteMat &dst, int dst_w, int dst_h); +``` + +#### 使用示例 + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// Create a resize image data object. +LiteMat lite_mat_resize; + +// Resize the image. +ResizeBilinear(lite_mat_bgr, lite_mat_resize, 256, 256); +``` + +### 对图像数据类型进行转换 + +这边利用的是`image_process.h`中的[ConvertTo](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/dataset.html#convertto)函数对图像数据类型进行转换,目前支持的转换是将uint8转换为float。 + +``` +bool ConvertTo(const LiteMat &src, LiteMat &dst, double scale = 1.0); +``` + +#### 使用示例 + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// Create the converted data type object. +LiteMat lite_mat_convert_float; + +// Perform conversion type operations on the object. The currently supported conversion is to convert uint8 to float. +ConvertTo(lite_mat_bgr, lite_mat_convert_float); +``` + +### 对图像数据进行裁剪 + +这边利用的是`image_process.h`中的[Crop](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/dataset.html#crop)函数对图像进行裁剪,目前支持通道3和1。 + +``` +bool Crop(const LiteMat &src, LiteMat &dst, int x, int y, int w, int h); +``` + +#### 使用示例 + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// Create the cropped object. +LiteMat lite_mat_cut; + +// The image is cropped by the values of x, y, w, h. +Crop(lite_mat_bgr, lite_mat_cut, 16, 16, 224, 224); +``` + +### 对图像数据进行归一化处理 + +为了消除数据指标之间的量纲影响,通过标准化处理来解决数据指标之间的可比性问题,这边利用的是`image_process.h`中的[SubStractMeanNormalize](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/dataset.html#substractmeannormalize)函数对图像数据进行归一化处理。 + +``` +bool SubStractMeanNormalize(const LiteMat &src, LiteMat &dst, float *mean, float *norm); +``` + +#### 使用示例 + +``` +// Initialize the image data. +LiteMat lite_mat_bgr; +InitFromPixel(rgba_mat.data, LPixelType::RGBA2BGR, LDataType::UINT8, rgba_mat.cols, rgba_mat.rows, lite_mat_bgr); + +// The mean value of the image data. +// The variance of the image data. +float means[1] = {0.485}; +float norm[1] = {1.0 / 0.229}; + +// Create a normalized image object. +LiteMat lite_mat_bgr_norm; + +// The image data is normalized by the mean value and variance of the image data. +SubStractMeanNormalize(lite_mat_bgr, lite_mat_bgr_norm, means, norm); +``` \ No newline at end of file -- Gitee From 1fd858bb4c1084d2246281aa358083eb42b6329c Mon Sep 17 00:00:00 2001 From: guohongzilong <2713219276@qq.com> Date: Wed, 16 Sep 2020 21:26:55 +0800 Subject: [PATCH 057/100] add nn and op relation --- docs/programming_guide/source_zh_cn/cell.md | 35 +++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/cell.md b/docs/programming_guide/source_zh_cn/cell.md index b1cec98e2a..792c97a2ed 100644 --- a/docs/programming_guide/source_zh_cn/cell.md +++ b/docs/programming_guide/source_zh_cn/cell.md @@ -1,14 +1,15 @@ -# Cell及其继承类 +# Cell构建及其子类 -- [Cell及其继承类](#cell及其继承类) +- [Cell构建及其子类](#cell构建及其子类) - [概述](#概述) - [关键成员函数](#关键成员函数) - [construct方法](#construct方法) - [parameters_dict](#parameters_dict) - [cells_and_names](#cells_and_names) - [set_grad](#set_grad) + - [nn模块与ops模块的关系](#nn模块与ops模块的关系) - [模型层](#模型层) - [内置模型层](#内置模型层) - [应用实例](#应用实例) @@ -148,6 +149,34 @@ class TrainOneStepCell(Cell): 若用户需要自定义此类训练功能的接口,需要在其内部调用,或者在外部设置`network.set_grad`。 +## nn模块与ops模块的关系 + +MindSpore的nn模块是Python实现的模型组件,是对低阶API的封装,主要包括各种模型层、损失函数、优化器等。 + +同时nn也提供了部分与`Primitive`算子同名的接口,主要作用是对`Primitive`算子进行进一步封装,为用户提供更友好的API。 + +重新分析上文介绍`construct`方法的用例,此用例是MindSpore的`nn.Conv2d`源码简化内容,内部会调用`P.Conv2D`。`nn.Conv2d`卷积API增加输入参数校验功能并判断是否`bias`等,是一个高级封装的模型层。 +``` +import mindspore.nn as nn +from mindspore.ops import operations as P +from mindspore.common.parameter import Parameter +from mindspore.common.initializer import initializer + +class Net(nn.Cell): + def __init__(self, in_channels=10, out_channels=20, kernel_size=3): + super(Net, self).__init__() + self.conv2d = P.Conv2D(out_channels, kernel_size) + self.bias_add = P.BiasAdd() + self.weight = Parameter( + initializer('normal', [out_channels, in_channels, kernel_size, kernel_size]), + name='conv.weight') + + def construct(self, x): + output = self.conv2d(x, self.weight) + output = self.bias_add(output, self.bias) + return output +``` + ## 模型层 在讲述了`Cell`的使用方法后可知,MindSpore能够以`Cell`为基类构造网络结构。 @@ -303,7 +332,7 @@ print(loss(input_data, target_data)) 1.5 ``` -此用例构造了两个Tensor数据,利用`nn.L1Loss()`接口定义了loss,将`input_data`和`target_data`传入loss,执行L1Loss的计算,结果为1.5。若loss = nn.L1Loss(reduction='sum'),则结果为9.0。若loss = nn.L1Loss(reduction='none'),结果为[[1. 0. 2.] [1. 2. 3.]]。 +此用例构造了两个Tensor数据,利用`nn.L1Loss`接口定义了loss,将`input_data`和`target_data`传入loss,执行L1Loss的计算,结果为1.5。若loss = nn.L1Loss(reduction='sum'),则结果为9.0。若loss = nn.L1Loss(reduction='none'),结果为[[1. 0. 2.] [1. 2. 3.]]。 ## 优化算法 -- Gitee From 2a6ceb7dc45125bc39f8f29330ffe0be2bc9627a Mon Sep 17 00:00:00 2001 From: liuxiao78 Date: Thu, 17 Sep 2020 16:05:14 +0800 Subject: [PATCH 058/100] add test result --- tutorials/lite/source_zh_cn/use/post_training_quantization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/lite/source_zh_cn/use/post_training_quantization.md b/tutorials/lite/source_zh_cn/use/post_training_quantization.md index 921b60211e..83693625e9 100644 --- a/tutorials/lite/source_zh_cn/use/post_training_quantization.md +++ b/tutorials/lite/source_zh_cn/use/post_training_quantization.md @@ -64,8 +64,8 @@ MindSpore Lite训练后量化分为两类: | 模型 | 测试数据集 | FP32模型精度 | 权重量化精度 | | -------- | ------- | ----- | ----- | - | [Inception_V3](https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz) | [ImageNet](http://image-net.org/) | 77.92% | - | - | [Mobilenet_V1_1.0_224](https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz) | [ImageNet](http://image-net.org/) | 70.96% | - | + | [Inception_V3](https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz) | [ImageNet](http://image-net.org/) | 77.92% | 77.84% | + | [Mobilenet_V1_1.0_224](https://storage.googleapis.com/download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224.tgz) | [ImageNet](http://image-net.org/) | 70.96% | 70.56% | > 以上所有结果均在x86环境上测得。 -- Gitee From 65caf754e9004cf8bca208d2cd2f8d748b4cfddd Mon Sep 17 00:00:00 2001 From: yuximiao Date: Thu, 17 Sep 2020 16:25:08 +0800 Subject: [PATCH 059/100] Add Profiler en design doc and update Profiler toturial. --- .../images/analyser_class_profiler.png | Bin 0 -> 16774 bytes .../mindinsight/images/context_profiler.png | Bin 0 -> 25808 bytes .../mindinsight/images/module_profiler.png | Bin 0 -> 57501 bytes .../images/parser_module_profiler.png | Bin 0 -> 8988 bytes .../images/proposer_class_profiler.png | Bin 0 -> 8571 bytes .../images/proposer_module_profiler.png | Bin 0 -> 6423 bytes .../images/time_order_profiler.png | Bin 0 -> 15366 bytes .../design/mindinsight/profiler_design.md | 175 ++++++++++++++++++ .../advanced_use/performance_profiling_gpu.md | 3 +- .../advanced_use/performance_profiling.md | 2 +- .../advanced_use/performance_profiling_gpu.md | 3 +- 11 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 docs/note/source_en/design/mindinsight/images/analyser_class_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/images/context_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/images/module_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/images/parser_module_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/images/proposer_class_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/images/proposer_module_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/images/time_order_profiler.png create mode 100644 docs/note/source_en/design/mindinsight/profiler_design.md diff --git a/docs/note/source_en/design/mindinsight/images/analyser_class_profiler.png b/docs/note/source_en/design/mindinsight/images/analyser_class_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..3f785786eb8652e8d1cfc09795e48895da80eef9 GIT binary patch literal 16774 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 U^dcB~uon=bEU$qmk~0qYF9AEQv;Y7A literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindinsight/images/module_profiler.png b/docs/note/source_en/design/mindinsight/images/module_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..f30582b53e046a37e5d97450b148d4e665ba174d GIT binary patch literal 57501 zcmeFZby!sG_csbWAP7iEigZYqNHc^8h#(+HcOxM&f^;Z~grsyzh)M}ary>j>Fw)&A zDa|m%yJrT}=kfWT@9&)JoO8W@y#H`*X7;}Cb+2BZwe|$7sVH2+rNTu+L%XDS`<6Ny z8YT!04I>xl0`SSRVIgZYGv10b4cC}E7uVbX#*lltCT4%Jcv+0*+(Vvg^@}eJJ z6DrL16v@6##;(p$tP-U;w~sL%AFUIVE2)|N7R>&@O66#^{-n=d%6;6va6KWprlMov zlLL5L*soCvKjE(q^aV7qzi1=12>~DWZ~rd&5Lmbd12^w2t7sKPRyV&(*ByO28pNB} z+0Wa#*HqE5-bT@4AmyMR3n!LFL&qeNHZjB4QXul}AveMArIjjC06x6N?R0!2PvdqS zBd4!~_q*8Hw@bzFWpnWM^0pPc4PNll9r+~i=M8rw-og$fonP4x|2sMc4!yrL5B+Xv zvUZw)I`r-7{SewwUa9NJ6@FG7kD<#e&Q}pTA|7VLa{pwY&Ro+-c}@Hgb2u9C=r`sc z$F5q?$m-|E8swmC#%MB$RRvx7^R1{b-9L@_M-Lf>nVS72Ukz-9hM|I?KKP;NfGw1E zD~`PIhtqWn7S#IJcoB5vqM0Y0Q1<+V_$=T;z($%S-S9n$Xfn{8tP%`A;z{5naupnU zCl!B+j>W(kzZCv3zpz#!1eF=d{(ZvPT?|sCt9B2H)*pr5;yj~0AsdZ1p_k6Bh3}X@ z8ymUA8pf8xNA-;a2PtaRs0j*q-u5Z#Dx zQ2KIh8|5_-o9r;er&ByXR)ecN*02OdB`Vh@UI?Cv8V%jNvd0{=)ISq~b0LZcxkL(S zq$ebdwKhgx;>FpDmoPL${B(-6tYVM#lU*Nt5L#(^d0b}~Q)E}9E%d_86xW=RTQV3) z?+zn9)Rh$E`PzyJ#mX=x`UAX$T~A{tHe5p3#_SVWw87nWE-L|n(o=4&mi&0D`Ub~( ziTjdTp=RUHbg^!;-fx{Ur{r*+VMHEiicPw^i8!Pmr6tlC97IQ0+qU<(#fGq643BYX z1!c+#3Y_W(F}8GcP~eqD`jvphS=pbg`Vp*X?64^xyhNTs8XtocWJZbQf>LpMnE=U9 z+HF|pU%wyx zk5r$XaUF+Ix|<1yQwAji$_D8l6deQlito!_mg#owYio6EbMm~G!(MT&dF`#D&|T=A z*D=PG4_$a$>yu-kP%bDuY^(LD872T4_&U4RMe*ijojO;NO*L=I{A~*FG>T7^_W_aS znB_;DNiY$yNr4>U%AK(1nUGBHyta;4&o1WaFwm)pr9;0GGIu`Qz@yt5i1jGoi!R`l z!~I@HmK(-B`25vqzR#PWvU*aLxl)-B!kej`?^j0nso+E=6IgUjXrd&Sk!l^FgvsV< zklBo~LL7QETui@DV>&xJ$^BbDs%Yh=r`7mci`w7%w!U+nS8#5Y9|$dn7i5O`e)`;EWO6RBZ7D`US|?t#^pIQYRJ`TTV{Ju!4oRX3ja3du;KMI;`QU_n5ZK*s`_UJrPCFl z)FdGvAwjL~sUHI|R_ifXf8~8}-f@dHY4EsDb10A8l0*8~ zMqPjc0WwaMA^Q7s1EvR_)ueR05Hw$k^%vYWVzu-J!6cfwpQQus=2j+TEJUCCDzG>PpzF<#BFs`YOEBV|u@iGodV;%w)SzXnQi~6q(4^S9;GW-y# zn^&tfKAF_r2(9v_$v<{{7+%=O7f%5S`&ewQPp8H~7pLcuKXg)C?T{<^5&coE)B&Yi zN2nFbG;J=b?R<-7CO|nt5|Z2dSm2Yg;=PK7x0h0DE$44dx$YeVll5J8#(T9+S-l%k zhGJ00(kJRO#R^cts5M#tLaxcw!uNif{t8l}XaKDk8JEv=ogL@L6Vc;)R`|VivYtpM z<)jBF=L0%g6yMMS$N?8z(a8Kr*gWBzNfZZy9BEec5Zcrs8D-Y z?kvJB-97t}Fyf5a(xE^|(KoqVoy@On^Wiobf=d}OXmSxM_BU>xML;9ITq$hIrX5Hm zEy{C~1417OQaE$&8FD}jXnvaz z$q5xawH=YQrYsaY>Ax`oQIk9&aNP=@go;ZYdAucN>Fz9&t1r(~%Vc}1Jc{JvNsb-8 zc`G4`@#X*_{0rSVj%Ul9M9qe3K4zH^6`f5)*CKR22T=ZaU z6$0h%J<*v;NjyGqw$r#m=QaMua)b`=hG^ON<1wmJp}aTnO>uG?7u%YRO2O@-&iCJa zkHWE%QbyLrA9fzumD*O*HJArn%Poh8>kFKYlQ_8$s_yD={wffPMdd1eGa0B4UT*4rM$ncrg@uo?Di(~Fj1h~_L)r~>|2Bt zNV&c4@)oTH9R?RJIiIE4vK}7{|G1YjSo)D1;r4iG)VH2Xe}1b@U!Mtyq_Y2+YoEtZ z%qMvE6R>B)KD*98*3@=zR5~vFMgi)s48|Yh0!(y{#D_td3O1%Q|Fm5H#wdU9v|R5f z#nyD0P}n!`4loro-IDa^y5ODP0!$BZK?e+VY zz#~t|LGs*xJ|blm3XsZX# zDc@O58o=HeunOB)=Ps?QHZP~EeduQFM>P|?Ka+6%!fRjVJ+8S6DlC$HZmRQN%+J>4 zqeT}@9349qD6KlgD}_e{S?$AlU&1y{sa3JRUqnec9@juhu!hw*VJ*mUzBwX@*N{ra z=Qy$~pbe<&<`g*elJmqD7S_2>dYX)@4mjzMWpctC^^09zP?Gh%;q7C6KiiJeqj)PF zGgMsU;|N$|-AG0htu;lGwE4!QpjS&3gvQsC^Ng*?xZl|)uH@c{y7&~8-#x(~KFLu~ za^5~MPFxGxFZ)c4jg(q|GoH7fgOKBChke75O{A~-&JT7o2ZA;Fgh{# zk8*NFOTVser{r;nE$Q$yZt!y=qHCk}4BQ7eY%@HqXs%Fx^cYfl91;$tjn3L6S=~P`bo5N56TJ zC*@}XGEv^sP4Mwe<(7*e=vCp+@P4j?4$N$6^A6qnYK5|NZ0S?LmPHPviqvr7wQ^r)To|T?K;z* zyDs5?@rv~1&Kln80&19E7MCXgj35f_)-^>!6!({~)DM-Q3&K)DHIsf<>ew%$GAp9G z#!}XWg))jv)n1lQfXCvw=%#D!%6Vp z!!$vzj27??Cwr?l=}wwPqVNt0Vl#RN6b(vd8aubWc%nh5C1kK}roFJamUbsC$>$n5 z>a*9Fhu%h)sU8QHF=%HeSsj=e@qS=Z=kNxof`*lA@YX`IkMQU}Rv z9_v_C0?Ux>Pvr+Ue!&Eu7qbC2NxAZMDsT(f={?3>)@v)Vy1LeEDgJLmNbmzDu+%+_ z?y^89up=)qIt4e{Mv-03o^m=67T#`tpL_H32-jlC+B4n4Iq#X0wL)?MfvhFxwil&5 z7zG&S9!9ag_Djn= z``#nb&3IbvbTd$4ltYr`m@q@YeHBmjHt`GVE%5}IC@htqe4 zH$;Q%wDNu^+_3uP#(Rg?$w>O4t`Wq&;O8#k2oNbl`$#s-Q2rjYcqxno^S31#eOPflAKJuPdW%3 zQ^!xcUwh+qoa{|IaM+c`L6=%D$63NwBdc`D9kbZi;}?%s*SPbJ)&$}3QYb8A>9yn- z=B=q$|MV-l*Dxa(h+?Ik8Si=N%lkfYsk|Y`OVpa10_`+=;G?56;2Y;>qr2xj(SIV_ zOdv;WKIc;psOdwwh*DN1U5A??te0SAW)!eFnxg#*`-LUh?krMs)0s2(_a&EPJi;); zJ)A3qc;yY){|Hvj<+KXF?=itW)7K@}zFr||+-C`t=pW|G;6M70)T9hQ)fG4_ego_b8!wKCQtLdzkb<74D%sPZ`ve>Zf5|-f8tM)4Ip*bR zjwRJ{W>m5;CVFdh9F?ona5)RyZQk$_%&PPfD^#e!he2+FE``i<&oPu8S2FfQiEUKN7BzWkq0mtCEX{Dh(ZTlhBY}OO$o)qW^sj-*-$?G{AaXFdI< z9VUKIo?E{D zc>V`BILNHygxaF~t-b#E3x6EtTfbO!?fQf73xSw=Dmu#;kmeWOFK52YI5BD%#MzP& zlxQZaDla>4ljJO41ZY*>>wmN*W7Dh(QgJ@*-T)tu8|$j4k*4Z54Ee8kHXk0zn`C1! zsNTBKrrxGe3jK0Z+Aw3c%JCHY!b$`kA{fm*RVnb>o^giRdad~CDoFOu{?ItCjYuTr zD8WvKa+gRYbQCyP(iQ5}c-|V(A1$z7|6m$NB;9!L7rE5fsr^K^uqyEc=mLrS6I_J$Doeyl2*Q=Q zP&xF?i(&H~v6%{QuiQMVo8%c$!8_bS?;ElL4~W7;-UDf650>bQQ>!8AJRL=^?BYviRS^M9cE}Si?KtC7!;>}GC58J&&9aP>McplL9OynZe zXz<8{`z#pG$l}LCC7%2df>o%LM-AtfpXPsmbXJZBFd>XZ;p%oJQ>+B2`u175<4N)> zR!+RRbQOhy(u0teMRjIbNI;0_&MytS*?IYlseBm7J0*aeUa*N64^<>6;vp#5GB5}7 zZ%J(H9xwD%WV)RYh>$??BY`m;}5%f+r(vik-V;YA3=qi9{VV zf&_K3P<+Ky!QJuh0bh?7AbdChS1N_?q(k$Yn@|h_I*TUzoz_0;$g@|Y zdE!?4bD?pl zw&A1Xpo4W;^84^v0sKNUt`@b{3oVoFJ!r>zUPM-Bk&+pJeN;1hD_*_Ab>+tSZd2C- z`cys3H%?=Recew>R7!tp+x%Ty)dx` zgaNefS&N>}0$>u^5K+!5MtE1kI*+9UlKYJ<7SU@QPb+{j@v0}(5Vf81EkJo*>U;|xybtq5y@Wc1B*nQbq5+nu;lf3aE6PWRj@pt z{S%n4#6&=4bv;ZLkQPC#rAsKbp9vhWLm*q$y$bXJx0IKkEN{^dF1i}t6x8&7uSaXCsOHDfgrQAXaYk@ti0kL|-W&wRosPhkMr zL_rC}`QU$n7u~VkCcUl7H|i+45YWRXPdSq_&wGw*U=qDBGJzkY4NH0o=%kT?o^)US z6ZcfPXt99?^YpPLD}u0jx^H&>c}q2py_CnKJzafY&O7kc5ZbQ$`RCpIUp(i)m^4P9 zTpAZ$IdJ46G{hwS*?vL8SjIpMYq%NvLq!+%lz-@tuoTnuPh!nkny zrKAV1mp3;rg@2!eXvh0T3VcufXZDeD1^9$6QYBc_%~8b_>SiOMMOi=C9(>Plv$# z^RA{=znm;?WG^~2hZH3Gxn^lp04)NMc}>67%3T-&WrF-fhep9D2(*HLW%RLGZ0FK)tKyo4N#~tSmKXA?O z?o(4K--n5N5RAo+RY-(>a{Iy1iV&i)b=HYGsL&N0kC-f$j?ozPK`5<**4=$T$G^?> zxlJN;JXy2%_<-iD?Ue)@wCaB( z@#%?AJfawd?oBIMfp?WkkAHBNdTl)eBAvNXl=mOppL*4}+q)`QS6fau!`hw+0pRas z09+@W{v`CL^I*ofM-Bo8!{k3J3IDN@30r_jD6Q;+e`$a%$(d|-@gnksrw>Cj71WHL zoB`;+lvFya@i8>ayH>6hD9IRHgHdxqzrIHUK(8&2v@N-7uYE7@dRiDO0VlqH`r;h2 z{$&Zoc&)+}cO2-yK&Rv)*077Ljg_uug1?-j#6J}?pc1P*Vj~%d#ZQ<;y}M_ZRrXTr zWIPqre%^7e#4q$r_SY7zw%0>tT&Qc$@#UwF!ZUvDdUi!rbp~GpYr1!vZ%?^Jh7*&X zFZ9!o^bp}_UZt#EVz~I@ywUJ$sa`VROTZ(Ii^@U&DT5b?$V}QKefihzXIB}(fP$?4 zEB8OX;Il=an7FoSIXLe89#!grTtSHe6|6fLTR%G{(OXa({6BwxY>LM3JKOz^M&6U-2_N z0cLpE@dDppx;>`*c8cdOp}z9R|6+^=2NV%9Lf0NUCa(3T+UHwzJckb_j$5Ca37zf? zT7fr!E`#Ig3(=;N&znzvAIy~I1=AO9o1F@{7=<=(C*^(L-B8=+zV9GCqf)q3{6~9O z;}jH+V~SarZe`AF9!n-gTTf~w&YIaS;{iT}b}TFdYA;2bG``VrW1-=6`xYK8qA;qy z80cBD5qGJe8i((>VV@141S%NBDHP)K9#$+yp{eL0^V8@H`fnG%DUt!6#>f7lk zF-XO|yG2WZ+d4E}yOk1EygJKTL$y>OCAi>sk{8ig43xGBmC|on;lZVQBR(x3v>ysR zZ_EaY72dt(g|dXAsSj)L1jpBDvaA|AL%y)6;o4&Xb0FnjwKrWk0g?@Cb9Qs8E$g#R zne4+S2w_Ug(f7spSTc>_a5Pe0m}e2e!0E&C6yq&)-0K;wC9k>9)wBB-v_cK~I)=^j zwkAKP`z^7@xAT(y!ydfllq_%X8MZ%NqpN0-M~q`;WFg24|NbriDVq5Z`pav;@FO?T zR_&0ms8J{kw`EYW&l_)-S}Zs-s5a*rr^L*tZmq!Ky6&DE%Z5l9T8*P`ypPUES1pW7J_AO+Ec$3iju4hXE!o6Wl6s4u z=8FCm^G-UL8#%i-()M<^iI&^yH++>nyuzkmDWumk@#Rau*fyJ_-PG&Q=9}1KK*|B| z_$5U*tE)*ilo<= zhtX>CrJ`nUtXW68UT^Un!R5>#@9pQ_{p?b+9^e!fhnU7(G7KVf0?T^Pg==((G_sn(11`_WzvXj~tKb}o!lXnK}- zZ18rj_xfoC%Mk&ro>B*Yg zqlR66+02)9IbR%lqFm{>=4wVxt)T?6JKkjpiNne#+#R+rFg?et-tw;&kSLNDMQhB9njP6oyQ=%t}t8H5N9zSVyOe zzY;f_C%$CaZNRjzF%!*IWj{6M@_2MR^%?~ZlC&DU%a6ZhD!dI>WR-0xC)TAkl17k* z&wKL%4t->%^b7NEo}!b+mc{?2^=$+X;hZwn7*)z(X+B7R(j>;yMHgQ5fHviVn1&msDEXr-pMpq={cY6Aq^bqN? zo(?L%)!Gp$P4!-Z8zgBws22_$J^GfjzZ@~0bLE3129B~JecY@Xmxr>CWZ-%OauYcB zzi+Z@{>|3;fa}tV1J7Lwulsl;cBLs4=}l1$+*bFzj5|EbK1>Li7l<2E*FAefrJt~N zu*(>>JLH|{_v68A`GQq(3GVfk9NqgaX^F$$rmLD3U;7R69Ry!LN+4b~A7a1;dee;` zvCKpXnxi2ftz{1;kYcD=yd0ky#QoVN8beR~g;okPu_6^Z<^_sxk{4omf0R<}4B#DQ zCYbD28ax&f*!J1XI7s!wd9b!E-TtI~tW}dacL4N7l2l~1V*LK{B`s&GG%`H`?Y!H> z=EaeIF8v{~5&iP(@va2v<}O2T9u0O`-t%o-?wA`bkrv~zjWC7WumK7$5^|Jskfh<( zJu(ER2$~P4##fSp?1|%INWYE9e4JqpzTJaE&sXWc%-_m^NhCCER1y8J>`YTwieRf(;aysmza>5^SzLX<>*z zCga*wlCd?c-g&c3X;kfutb`d44P?WEdK1EvX7jIn9rzCvEbuR>O*ygM=qvPp>)rQG zQ=&K&yHh9VW>W`;1vTy^H=h1Ho)Cw)74l~kcJN_M>aUt7aq*1kE1NL0vQzsgU^+Ce zIhI;3|BlpX2%Fs0!v;af2mK2lZvy>kJfz)4yn_aPJ07IA?$mK>VBwJ?)DN6z#`@?+ zR3M_r7<~f+2cIY7F@8y*ZzQx#r(o}N6vUXtn2)8C=s!h=WN}Q zvt(*47d?2JK#ruQvBY*rMQbV&v*2i}V*18hug=cfJ!88cyDe&*Of!IT^kJfuqpzi5 zNFvmLUaq)|`P%#lESsom4{Adb9kvK?AqJ@+Dqj#N1t~xF5ojIBWrgDrb5~WhxDF>4h%)dk>$C2h4g<+Iylj~!pk{wzewzz_sfF( z21$eYD96Ie!<+$V3%8+fZWpCdy`df=AUs3u&t`ByBTxU#IgXm$Gw_OE<{n!{S?Po3 z@5L(!p9;hQXM8bl|L>dnx9)J{eN!X7-hT7uF*n;?IYPJt`JJt7NY%4-%zU^V?4%;1#Kvc(o~H^aF(GmsQk0`$!N-#ULYsA4RHj1YG^T8rvqVrgkblW0iB?$(dJxESqR zHU?}0fi`}8`#bKKM3u@Y|8DRGG7^uA3Q2VT?ot!F_}NZB^n0wWv8`!);7i`v?V;xTp(y$^&uGPe`s-nmAaeAO+^*a3uta}szkqF1}e9wc*+Zu7Cw=-d%Cp4 zivjpuMbV8GEoyS1^gtlKi6SMC@7jWlG{TM2T)!bdgOFE0|96YlAtA=EO?Wmh%d}Fa zn>gdv^EW8vrREE3)Yx7Ai4r^spVe)7Zmy-CEI_1Ad`$$@m91vTEHhPkqeh3 zF()qaJ)a1~1WGqmlnkcZ6t@L1kf&GC|98(r{qzDI#s(&(tm91#dVl|1l%4#T%Z6P+ z?{pprv&{Vu!8KgwDPh24jIh_j41m-dHBhW_cj-9_Lxuj{xPOf}jSHXFR%I*ab-py* zxMYEk9FBYrsG+w|oWyhLPuqm$iQ(k7pJ0FPi}z zL{@lhKpc>~szlpHXfsFi4G{-~lK+K`=cVs$Bl@`QVV$kpzS2w^(g+Jx-+AH97&YO6 zUXXg1vkMlc``7us0Iz*e#K;;ayeL1r`-8$uWP|}+8!Ez_flty~7{w{jmS}~ozoImrADRyMRCu;7G_?euP}Qq4`!*1sK-bP9k&1fQE`Z^_jhxxfB|Hn2?IgQ3=0uH zv`*(`DuxBg0B=if&msp@V>+)UN-_8)q<4Heq_(da-yh3|!q->{I~Ue~xkE=^pkh9G zUFET@KrQP*`ylPF>%vASrb606rw3pra4wWCJdav?G(2k;4i_tIcQZc-W{IHWYDsyD z%zZn5PiQ7Z{(K$tZcj|M7kQ;`QYS^Cu^ZfEm+YwgEv$=7E+~z zf%c$C+<FdEIO{wE=2*Wg^f+H^m8kZZ7iHSMGaCeZ_xd(I@wc>O*Zwtyjf7<5Q-AXZ zG|xvV@GQW)^K_Jn8VtT7h0oPetvZMx{e_FABTPg}v?IriMw%$u>fSL3p)JSxs)%c| zMsGL+48ykCPn;z3PlA+s!n2tWeY#}r>kZz%3F(raA00^5l9G3agilWz?bnZAA-5XG zvM8K5eHT@g18Z{D)QHhZ^xtwW19a#`)C-mfA|Iw-j(%95=~wAuK&5cf6GJ8ueV^$& zDW-+5Yu(IKSmI}#+~h3iSpL4=2^BA|3QUGR(4VyTW8uM6C6!s=3tb!=8f{)sI(K=| zv3Q)sN4Q+=`!f&mHvDSEWgrzF=6T8F_+T100+Utw4!hqzm)FYu_*aSP0MIhaHN`Ky zG8$R&(TS@d&q@ET^uqfN{%3$X;Jyg7p->YmH1d=jO^cjl0&3GiJiT<1v&3pqJ{pom zfml13iO%TSM$;U2z&DKRP>XuQt)`>eTcNHsxQ`N(cOBZWRa}ru>q{>rYy>5{81&PU z%>X4TwKlJ4xs)5ZcX)H5*T$CTPrZCfZ5&c z(h5^k*%pgQop~|g6%$}EzkWOPaC}Uj{)P13OKF;huDDs-NCsejw~+-3yUSnzwN4(f zouE*nP4ZzJC_dwk2(9?KqO!D|HTY%e@zgHxk}Qci<9OgX2%6&Ac=X83jD;mYX~D`T zCfV=E1DN{Vg;%|l#tB$!m=FN!dhurql_S9~K4bG z?Xz^F_C|;zY9C;b8~`d_1p6Dv^L&8sflEF1<#LU#OQk00C@M}xSLsg90TaLrI(iDz zZhQgug(u^5k3*o&Wx)GOVz>v?+LkeZ!qW7DACfE4c3mtrV?~9}$MV0qFXxwF)WC1d zN5=2Bu+l*M!bNpcuOzm6gM(u~V)7&;@7|rLJ(3O2aV32iL=stbxFWSmnm%g_yl3S~ z_Cutw{o2Z6X$@48FWF1#`?0$|G>a2^ZH62f)5?>6v&0#y+?Dxa#hK_wH!upfyIkvR z#N-*<@E)atg&j}WVD-HLA2F-DstUmp+%zRG6&tO)$bf}&jVynyC&wDTdXcu8V(r?BKwgD?s0>w0#oejs|U$ae8PU)ehHm5$9`xHs&vo$tykjD z;0MCr{kI+U;BNF6=I=IG28*dHp51P*zC@FtRwZ~5m_>}d41F`p9G&71O^GQNZa9?M z$BF=!=RGwJn$O2!d`48^N2Q&@9Hjc0;^IL^|Kal+=EKFmJIz6n!WEWa#hz~5$}aK2 z-OM$%U>4SIu3fGU@zg{Y6_}8h6n7zt%%bS&qO1;Og*!hwnMB<$*XuM|hxZA;x$-sq z_Z+Db;0mvza&)*>qw7RfA%%m2B9|zND|7z0MW|4hHexD_Z2&=4nFTG@o}|UqXonxy zN(eK z_XOkro|qPU%L(R5zUDfB2p>W?QEcS@f6hkO#{yZ{m#qi-(5IuDxY>MN(M)m??u$f; zqCh0FFLX8-1S_Za6FFUWN_||oBI@uemdJ?+shr^3!J0%iq{wSKzB03WS%xsBH#aWq2-c#c>)m2+%7GH8hI3B(A?orFL_c#MC64N% zpW--kmoFX@L?veV4|FY1L0mzQ9or#B@2*c_z;6cod3MF-(QrR{ zuqf#V07*1>i*JIOGzThX&9x##`RF1Rw0mg`7gD}BKdhh&8n!o88K4?a5`cz3-8;IU z#tU~y0i{(J4r0D{rUO^p>-Ojp{J8f(pK$TNDYlP!VLU8!xVDi&+hg^#fE*r^_sn`a zON3!1m(uwNBh#_FvV2i&L!}_T!Q@rL(eSqU19GL69SL#ta@8-cGy|Nl6|YTRsZHpD zy@#C^S-1x(qN~fq--Jwgo8$~A_JH{xuCe43qt;Jl67dVMwP|4Snn4zvUpf9^R zM@HVfy=$)}K49BLF=+OD#naUyb`f{sVQN|Bn#5wrg#pL(a;*gWZq_)}QBT^jaBWn2 zXZA11vmxL`2J-l#H)%)XoNWFivx~pbycT3c1 zk0aHd=NaAP*f@Xg(1l>1*Vh@>z=b6v-7gE*2m)r3q@L20CPW0WJ6pY5NdZ5Mr;(zt za^AYrd|aFQm5u|0)-Ke;wEyE(4}-xx;Q{wTw(?F7Im5vf*RXAG(8%&84Z`8kT7L!= zqx|Qn(m(yDUqZ9-9Tj7hSMfc7kGpn>R*X`Bv~qDVSO=WbOBWZF zHp^vJh|-Gt7M*83cW14SMXO!HCZ#6HuZj&0P*E=wKD(#?C=FcZ=F$te<&>Y!;6M2K z-JtJ3%(SA1PvvqBl>B^MShW3ao6`H$$ZmQNHdlRpP1sLC;qiL9vNal#Vy*pz)bX_r znPW|HC_7xqozU^qa6`lJ$d73Yn{>HZ#cWOdce~JpvNoP)lft|_tZ}s^>Bom|#PpMI zy#3$TszE28++!bDHNUj^)pa6OuZVKHoI)T2P97!Fi2y)?h(d(mIb4X-OReKHJlE)%2QR}SS0y)WZ}NmAm1CWUT?|DmvXM_Danox zeIC$^97>oQFCA$&_kzn@G4ruU79;ZSr&0{8wWml4(uGiD=MKE1k+R*MDD5^){-a0KM1dii7sfZ|i>DEaIA&Fj&16! zAcqEBcx=s*J!5Yw_um#sG>&n*Q~8NQtDX-4xy-b;84%?cKdrf=3R~`LzcrN*IbD%( zM;wKr!e~)Jd}?5y%D0@(%{Im3K#7R4zWVR=vm`e-OOK7G=Zh3!WDN0j{%_OnuN$*< z%<-1P8_dX(IS%XDB&ETp;+&q;DkDkTyif4qqplO81*{YE6_s;z_Ii7TzKk4%?uRtc zcV>351Tt+pvi`<{kWnAFOI;H|obknybiCcgrL4?n z<0^5g9j~(_S4T%Atmk;bfYZP8` zs-WZWh5N+&tE2kw9m!ggQj^8YJd7T`*Kt}^D)yY;KWRpX-;`r1-~@#mNsEz!s27!c zH<@ano-+L(ySnj2AZuj2?-L{XVeZQVau5a1NN|n)s$Lqzwi&A|6XIJx1Z~z`E?d(~ zmn!J$AB+j=qOsmzv2b*JXCOL16leZU5Un#5u*=s~K-3dS*8!By!%5r-RVRij{swIz z63P`q@afE?Sn;0{mc%&OZOex}|+TD`$~ z!<#ehQHgCQ?_FKSOS)lscm#QS^>c{an^Rm(%CzetU7>H=!1m79mJ(;*^4ckTn4QaJ z{P7`tjuX6SP`F6TYZ^|m<@_xey0Ah=&(2Nb8*>SzX3#afwU>m61{V0v z8-bN8NItg2Fs@)0S9i*txFtM?gzmog1A)dPGVg*E1wgc-dcw+*GDdCj`d=|%fqSzQv2>XN&_!@*OqxrsJ3|}C$pU% zEkjS5y_yVo;oOeBw(dufwRMDP>k8d(L{DeBmp4Ke$Lc)>-GT}heI6u9m8cA0=M4>v z<;GFQ9%s}f>J#i8SR{(CI_83tw!9@eB4*DSm!GLn1?4TxTVAcwqhs0^)lcSy&%U4$ zU-39TaGCaOHhr(g6(QVA6YFE)XYG?bKfbqU&HothvqnSeqJbH<*vi)> z)o<5s(}4?SZMoX8_hB!S%@5tgPddrFOZKF!Y+nCqvWo3$c)v>KR>E!tGvMCxDNKzY6B{Z^7UhK&u=RDdeYZ%AC>jL7?>`T1Jt=kN zB4GWxxY)%7Kb$uM!LFry4;S#p-k84t|4gjttN>5p9I!bV2ND)NM8eW;-dZoSeKLMI zOK75N+c<=4z_}F&4E#N&;R9RZ39IoULUd8BG{|6TZ$JPwFX=Q}AEHb0sci7fxituj zt`PT@?9~fjgBLxk2&H(qQbl7Onx_+DrgUO3{VlF)R77~?u^6<G7h&T*E%^BRl;zRp0DZ)6-Jb z#y!@VJ-it`{Hh1(*_K}wR)kZ(QOJdRj}Bu;45$XS?~~HuQZz4wl2nw4#ITl}8br$a zF&7?#4}PfF(Qr;K9IfFrao2R!4D8Nri|0ed*;{-hrM%xLPSh+fW)86~tN6ykn7j5; z-owjkr??hk1%>3ky6V!4^FIzdmMLh~(cTsrj5qVj39j|GX@wX$zK7pjNhx)vimNFX z5425}DhUVC&aY+h+Xvs1qP5(dE9!6d9)U`U8#VEN4b#pCW#=&|PQ(O|oqmQeO>Eo)VdeUb%Uzi&^C4(X0cXlm>C9vo{G9ubq@-wU<>tba4*85lc7J-WK?(x5^m3|4*6>nJOeE`w+ z8_ElF9!A1JpV@{*$uP1a5~5b|kl2dPx006x7*QP%jl{<&Ql3E=FTZd)D^%}o{w!3_ z@ZHTWhU;Jic8ow+786cP@^W@DG$)c6CMio#ZAV8&wJyl6IyWIAD(o$>)kz27=oUhbBsPUtuAT);0BV#(h&PB+}(s@*hwL+mpeN=voHVIy ziWa(=W!=+8kC=UL-?QsIzyd-@+|b25RRlE`P{8!JYGv4HoFDid8|DXcJr8h!m+m_3 zC%wAaJr;6FNI2Oq8eA7%Ngg{Hj}VO;xK~M|EWNP2uyIfcXRm@hVj3!l%<^(qvRmgY<_e(9?lxBceoh-`J zYo%DM4#gtm*3~&kKvykTmkt2otWK_ug?9U5iQ{u zRFHn9E^BBG0(xGns&$v3J?9%Vg&`&!n5r4gaeipz(Uq`KByM$A0FxTCzCmbM0<2S3 zkGoyU^VvZYJ)%k%I=e7W2Xy_iob*-yQ`b+EDaj+HJqq%i>?|xab&-@8(gX8MhE&%3 z{SYhQbw^T9X&lTXEDPT@i4~yrw+j3qr8asxpkgh1S&wT^ag8I|958VMI*-$-63wZk zsI>)2gS)R~xEj>$c$ah2RZSusfrjX&jsXha*NXma%A)$qurKVM(ZRvGZnPUS&AZ0^ z!Qt9y*!*_W(N1@kLzaKfSU#j4wvR1ultKk`w5T3FCX1}{+{l$*h+80pXx_bRW{J@b z>E~H2bzquCK$`lJV|3{#o5}gjW+Drn=Xj-n_rIXtB+{;MF+ba9GagFig^7DdPOsq;N==8H2I)o`>F$tDQBsf;5s>Z%>2BCcBM3-KmxPq0bk|*bZ#c(uzVH9P z-{XC_FY@4CYtA|57{AeDnUUp`=PrPs)nxQpe1`|oU9N+FWDXfk*&_L%hz>mT|5p0`{1r% z@=HD}5h61n;M;&x&fRjQvF03nHQZ9@kaQRSCeK4%s<~nhP?fY`Z;SbWxT(!^tiKRFp=ptqegg;+i!~N1!^; zH}Wb&)vmuX{%znR;nP1_@W_$;cFOzv83zmVHy{LSqJl%Ay<1rU2KI#JV^g)g&qdYL z^^C}2obb#a4}Yv~1?pguX0^!NUd)ew|3y4=3j}vbCx_pWLjkZ9uAuD;A9E1dTnihv z<{$mJAL)R_!yXBOjJzM2`3wJ=6t?$we*f_)R4>lz+$H_|lm)&)hB-oeP#9(LfXcbM zE630G^?VPsanO9lAq_|z`KV0Smm03BNySUQ3 z>8H_O$^YIY4BR6)&w)y>X@(rdp!8dEc|pjfqGyuV9T{7?r19fAoH z#Q{l!78aUkJUk&QMXK7nKSFg6#!M_Mq$MMkE=IZWA1fD-P%GEJ`@5`7l-vUb!jfN% zHAA*sraj%CJ~e6TGn@xPz2g>q2^0QKPTdx7kN931Ln;>Cprww2@hiwk^saq)#g`1| zb;G7j+{G)D4TDt9Z$|9swwlFN4z2Q6F#ozUVBkE{!U5%IzCHdy7XGWBWUpCSJn&65 zd$%Iyo}XiCsYBk)2no~4OsueIw3p3P&6v;Ru3_3BR2Kd{OdcqheFh8VLwvlBkX-$` zS6?>svu0@=9FT_nc>N)T;Cj%+5kK=z@%!3O!8HN8w!+Lw)30;tqmky*d(;ZTTC6m7rr}K^a#ndYXiV#Mzo=>eM zg!2b+JC6@akn4aATGB6py*?S1slnz& z>k~c)I*#dHFYv>7k5NH8#2AAFPsFiV>xNyO30h1?APyn-E2Q&E3bW)@%{m{oRtA$ zC>z8_&^qcxf{GSj4dwh$>0x;P)y~StCZF-7k1`{EJC)gk_)~9HcTrNHzhru~i|AwS znf4uktmuW+NPn+Io*(dm! zXZ}1gI6mFmET=HC)le;)4YEnKt;68~7s3ZfP0WW0D2P`~4;YuLOtDvaWv}0NC3O9e zm-fv`K!?SZB4=%0tl6Xc+|rKDkg~w)baD`{6-DDeNAgCM0zGYiVnV&bm7wV+udgcW# zYj7p|Bz+t+=3Ojp+Fl|$bAHaU3}KYgnQ)EyMJXRy-kSO z_9Lln05|W~?XYhM29k&Rf?-r|Z0=F{Sk797&l{QJH#Y=CD>%gV<(bLI*l{9)WGzy~ zcuZA{{KxZ$I^Hw+&QeTd5@`+Lt)jpflp zf%sQ1dP+Yl0k!NZRcB;ry?$EB+VbA zzBwp&{Y|p%g{&M*X67120LJFk^XmQkPRm}#wfd_M)#k$+h4M}Z)=au=8(A6OFB>K4 zd1|?U{Pi^YSH;5c3Y?ad1%jMl{~SQk`VD%w8*HRT%tMbpseXKX{jJdll_#Z}EbpM0 z{e#F8GLuI>hh^7$x}@b_YYZK5%ClEj9+nFx_ilm!X(T!KY|MdJhVl^OPQu>ZCl?44 zI?{YA>|*th2TcsOJ{M51Px;*oiZu8#Tvh7#8?Dx#xW1aB0mum0U9Xq-ug)p;_0L~N zfu~29HC(p;>+>n(%f#OX1a{`0famjo%Y}im;lPnmU%BD@G7(|>h8Jq(v%wRZ20T?h zc&**5Xyr4CAhLz05WrHC`2o17nf$bAC3B2Af<7*Z~LEV#9Np1a=ceFp{$ z<+9&gWwg5`qX62+8I~f#JiGlvjdFu!n(6hgmS|@Rz+{k-BOk3~Vh*UOHiv%6g`DQkxwdHW zph5QjeESMCOlBXx#6D@ieGW zFZV;AxA{wNAm%UubE?4~q}dSK<;y#((bz$R@xP@~`(Im076|eb2)Q+c&%y6FN)wpr zeSj}+0ZgGlp&`%MtJJuDsg_}ytTdB}GWB}}>O=ny{-e;S3P@)Fvx>B22_u0%v>eut zE=+Ppl(VG3H2-jtBq}y|KVX`YM$5qXuf)|6R}@qBIAMrmHDmOLCpHCb%#|7T1$ryV zy`WhW%QndX&U~VDQ_47!c`Y?cV;0_Nu6?XJ-j7+^$Y3* z4dZ?1kI!X|dV!AL?%WmLhl%fh*SI@Yzvv`?@PF`1?7a_6t1qq+GDm2DHcj&HkAcJ3 zq70-p0e$05Y}J6JWrYpx*A<(|#+%;(zv<1ZEKYp++kg)Wx8!6+JdjiYxxdt7qyakU z?!n?cv?A$cnPWp81zJ?Np21T1ib})uALu}+8g7t3bq|(4w0fBrh{-O0&SASpaUqgB zscTw_WBKg(5NO3egyV%@*FnPxW+#4@zD?;XO7YR17!r_Nd)Tsc=UMFy(mWBQg0zD1 z#jv1*m1-EQKe7L~ZMAM`_;u+-7`@{!0>7u7yYh;HK&$Hr)^|ZPa6&_%6jQF@6L<$Q zLsZ-DQpcV6;1&@ye{herGba8revNM8l->Bg!wX!-BC>?g6>`(pvTsX(Q4m0d_U${) zpAxDdaDlsf6qx>q;{Dw%>j$*(Y7UtK(_1^luKO7!BRgzfCYxd5o1w%EQK-OStci;r z@GgU0Z!$$YacQUkHvL(P`FF!-D|r`r@tO+#3*d7(hWaq7?&OxbmF(+N$OaA z3n9(ZcYCqwbf)!)d-)>Tx`;LopW5W!TeBHqTF!0De$Y-_o0#;&*p`5d^~gqV6E|A1%DVjee}U_uQ!V zIrGl^^l&(^L?4<4cJbPf@??QgM`bKetG3Aa(gET=tT_3~eKNHB1n z)NJ2?E@cmGt`K<53uZc144vdL8*@#$&31*-dx6EQ(+@E>HQEv4o}n=2I|@{l_O!UT zy9D)u2>Bl^mjNV|Q9=YhSyG5>MH&bW{wj=le{hHN7QJDjW^r(+l>CpLc|i6{VEr|! zc|jH9)gnsmiB1j<)~p_}L^|bY^TU)5dX?peyh-Y$ep%A=-Qb}^82v_b2=0oemv5kf zBJOv8p!^?wdH~^cIznTP9@q*stf`z4>M^$F1_U`?ZB_FZX~n4v!)ZuadwuQ^e-Urb zNan%c_Y#o6cIUWK0J(DRSdc20rW79P-RDESnSZy}LjZ%ly-0^sTU*Q7ETfQ}C$Kzn z)@Qd6XTgjj>vObex)08F+xf;!)kl++IG-}wj{H96!Lj*ocUkDUw3*wvA**nPcPzZ4m+P06}YcT&6y@zY5o-^ZxBQTtE|p4pIRrep+kp(^>BMy9VQN8z_;E>8ioB_G|9 zIHY-3!22$Af1^*?&H+6%$ND~an#}jdt?UI+G=%~L?K$s5%rNnDeOF(70|(1h(E4Nq z;-EzWQv5Laqs)+&L1<6k8q!OY;c8+AEK}ZC!5LsGtk@lH58-)tu|liV`R)Q%|Ljuz zkIv9rJQ6~(n#+d9PLcjwuoZ=+mECHWVpq|Z{g9R#&`PiG#NY^kmFq5 zBF|6o1Qhmde-{>_LSJJ(0bt<~&|I3!YcrNg&|ZY_3FsLHB1=%Yy(+HkD7&?4BK|wS z|GO{s?olA#w4(x5RB-kVV*wte;2rvVV0~`{OaO3eD)wKoEx?HR zV-N?>kZ?RM&xgCms&Jn`96a99kKzI6pd~ozN-`W_Z$t|r^_Jm(d;Ttjw|w`6f;R^3 zD0D$|zyET|J2z9tQ1rla9LxmE2+zf!eWu44|DRgomZRA-W%gnG&yh zb^dMts|?*jY(1p^mCw8doEp4ZaH+1VH+}JY?g@}03A0P^*~2$8bv%g&@}S+F&pMe# z2O;^v@NI6yL(0YI;{>OM0lP61?Id`U!9n&1XxboLnG@t zQ;ikb&=)iAJ2tLeOnyJsr>?WQ0)t|4oXD%ThtTHqf6e>g{t86VfniDs78gJDfMKi; zP0KPsr9D^T5A{X*J7qc5+e%{us{+R`~ z>L{f8-F!azqw&0P%6s4YisA(wCAp~^(B380IecPyF$8?eWJ1JP_*4vSQaA;j^``Zk zw$0_s(C^B`-0xS}#XQ~<(&?k}y;Z!fT^X0Svg6^cBP|D`$1 zwxd!Kh{>CQzgm*GlRo8Eotgzs5o-4&x?a@*X+dDFReoP!nJ;^7%-PGEe5uaSUxB9Y zA`H#!al$c&sa7S-mNsI-yHbrwPg|wO$4yC{*Mo15Y;dlS^87aOP4N$tnI2<>l~dY_uxXPwO=`!R|)a#bjTgAu9}^JOYY>l zmULiALy&Bc^Rb2U+#Bl*9Uoq(BW*z9)43%+6W$iv4HhuTiLQ$VG zb*{e5>8*R@+@xW2<)+|gY6~v|u&)G|t(#tp|Fuc0X3@-u^|cF~tX#A!UZevsf}4K^ zXt$g{3wUEZF0V>{K}*_IUcG`JwTxkuS_9AwmV=IERiWxj9p4v08Aoka#q%G6pLvZ- z{l?Eq-hrV5G*0tEiV3RAp8P|XfeQwz%X1ZgT9mZAR?dO4mb0!5VD8-;S4mA7UE_=L z6Y$4q^MzlAzBGB}O*3Ko&N-GZ>hh(4%fb(U6?oZcTZZf07iON89_VzpgUb_)?oXf4 zLDz%%*LpxYOz4afa<<#gJ1tJZ1EZpDwwprci6!H9Z!Qf6jea(7qRtw4>3DfJ)H7{* z=or1yGBD8pI)>ozlNOU&6cIo4356)eQ;N6xkCvkmV1HJ1V!Sn`{JQ@8;6nXmR9->J zO{w2m!%getXZ~{(5EFA}O_9XgZbg(&k=zM1R~*IUl6S^J&@_=W^EC%+*J=r9Udxj;d=l zn#=gdl?dDIN7Ov3bTt9r+!LFy=F%LGT0*(P5QF~7xx$9=M6i9kr-QABLSIK zS_?Zf{z*=GU4P%wa{HBWHa|)dD&tLCy}EENbf3IaR@qI*;RsHcrI(LU0U_uw>WAb zt(8{Q9u~T*OZqk=F07PR$g`dc4&l`9CepcK-(}(ur8_VaGzQ+In7xSWAa(`#MUAe_ zb(Cz=)3N>i%mj6++L>MB6Cg(%4Q8R5>S`(h0l5y0UHOka6B=EDDdy$gmeko%*`m`^ z@umF=Q@Y~>_A6U@L-jcTiJX}=k3M4A%pJCmWg|#bWYaxE?Oud^9jb6Cz1Quj zO#Eqjyt&gsO+%F7RKPBmH*7b2rcb@awq*KOjvmglVm!V>7yoJH5IFa$Jon<_c* zil-JloNV8)yw6|SveEcLQo3=Y(Ur>OoP0Q0kovr`x-`bTZt`1~5=pyV3<1c|T~9Y? zyAjEJ-s^li_cxebnU^}Rf8VmJ>YwadpGPNSiPC44l2{oUZVR^rxJq)Iq^ zX%Q4ONy}lkvJa{yopJZK_>IMS#pXu7uz8iC#^=xNd9K=8n;bkS=IR z+b->Xbh=2tBS3X<`o52}I8i=k5WSw(KPAA=qbyCpeTL^#DE%oxo#agQ7d@3>stb*o ztAzo`Ioa89df>~5GzQU@FJpvtO}-^uuy(yxj7WAjlNuWR7#+5sBb|g!v*Q!@qr0Q5 z$c|l++k8e_#6;)f8A@4g1DI)TG;DCwsfDEKgv~$51jskvFrCX}P^}KqJo8C+o645g zbnG=TW}&6~#Y-~N+cWTG_n;%c++d>&kaZoA(V-20UpbM6QFD;Sx;@wW&*JArQNk`M z7*j7Yd>M`06qJBWCGg!S@b&0uqIb1J8K_uO3ss*Mx$0@KZllvNzC1s5n!Fkh*&CUR zpA+}*V|K&yrc~9jzmYKEOgb(*%#EPViBOP-pOnH9SBlVz(9H3PdH0_5on@EPCUVZU z&LuGGu|o9&@Z}0vb5*w?{`=7R&b zm6wP=Qwp}eBC>ft*}cT!fr?2Lx*xaN%qr(mg4Yo8s){Om+de74^!QXt$8$B*`M4HL ztW<)J*o3O_k5Z_q$Ld+FjWU$rS1*)~o0f^6)3&Uhm-hIYRpt-yIaQi4CkW+fcwaL_ z*vE0IMZm=;xJWgqNBxBYxeL7C`CwVDwp0_4o~_fYKgW75AOiq_%)}wwdZ-_PJvImT zll$%CGpp0*)0zXwqh`JpnOGQ3Hx~XLLTqV7+OdyWNxv7sl)SkSH<*DAzaJ>DpA#6{wKNSISP50^jn@xP1a!*4?gexaX0JX zhSs1RuJjAhYGsgFqzxJytv>LfE;=1Xo(ue$P@?a6L!b z@47I(YI5v2CHu%a^RTYuu(D+1l=I=|nX-Ks08VgouG3HRd}F2@N@7SK3iljszx5bC zmOoays4h)K%4UL(l~=KwiRW4ow7WR0m78^O9;4rc;bRbj;#%J-!yg)dJvp5`jh!t! zmtj%jt`@)^z+emGNsk$Q@Sb)2bY0bqxL&3TACy@H+jYk$(?>UFIdW@rA&7Fkc?MsY z$GmV*@_W8%?_}>~&uIC8fka+iX`Y2N(c->BQ}g>W zMiK2&27$ET%!etUN2sbbsb@(&=EwOi>q7(1#_=gfDw#aY85yqSF*H(XN&1?W`*svpX-Jfhi%>=_{!!XCNuj(%m%gPN*T?rg$?0l{N`S- zq|4tx1$#<0Hz6lb_T4r)(&r6wgAwc;4tR?ig}%veC@6XkDYg(*svN*`bU^bEA@8Ao zP)R62zV23&xhF>obX=g3iQ~CMK7K-u(+vOn&v*q0Gn;A zebJ-y7GlptK2)U*z&?pdDvKe_`&}dCZlu^e)6+ljkRa{yte9;*s@w_IHM4|cq2q(+ zU%EK2bB+ZIYC3BEFEWdaP;x*Mf^bv))ChF_QFlk6ueQc`!$x5wLcEY?~|$uyH$Ce;mL~+<=j+ zZj4FAe`+gCXylXnmRUCq2VX2IN?ZnQR0YS`sKa{Uu2JWt{+ebfNfs$d@`+^aEP;g;X~q$~lb@=F(fGuwSJIiA zX7i*pf7FxBO@5Zc8An%jCPl*}ds^15wsyddV@|Czh%S3|e*>TES@Z6m;ZaO%*Z zcx)qlgM(TR50U9FeKdq0dLE%a8}*f<vOi4&890-k9GXovM_#@Q&2CnLiW-0PbsoN(PGwc7x6Fpvh(b4Cu9fsd%-J z!tnaJzPBbs7>I_wxei|Cxy2*0ZN5r6OdRM;?u_1-jM||?ilK1?v9rx1RJqQ?amjw3 zKfW{G$Aw;To>MLi53;x>BO2bJQUs3m{B!fy-V*AUy5iYcRbO%`o&-T4p6h`E4QJC$u7mcja>(%J(^AGb zP%|h_Z@!FaPshNpJ60z4)S+xA;ajYgbJYyD>qw55Mi}Ze1mHAQ16@ief$_atS<>)d))lhr*@^8#JcMX{D8WvR+Q9H>NAcD~m#3$E z?79)#2%Lt8c*Yr<*Sn_(5i9~n<$Jvq@kxrWSQKjtH&)?=SHjk>Fu`1OL^^qo&KK$}to!zU7ZWI5GYDAzm2_B!EQ~?6es@O+wZP!i0J2+lHY55hN%g*seszv=q z%+5Sor^+^d`Fr)d9#sPr&nGXylx934LU>C7arMf$Qkz@qrHcT0vpY(DJY)|0mqFk< zA+*?#Y3ZQZ_$t;aL?bhQXvV%GYh)ZdJeti<^FIO;Uq z&!QRC+Ix89^|-@+IgY(`bn?lzpGsvi%Ok5)u2z&UEMz&_a$rb7-8~pwF0wrD&wsKX z;kr!LO+O-FIUmgmA+~1!XlFMO3+}j}@&mj}p(K)MB~KiUDrHy7*qI&5b$0vSA5=UW zDnuhQMM6J2-+_J25Bi(JV@3TmRB{T$QRN z4`3-yb*5y7vjY}BKKleE_cDCqLucf0OMm5qi7UI0DgBe*qH#J$kZ>Z%)MdAm7^aFY zJ!r)`Elok(9TIc$gpW21e2tpg!OqDC+oTf(>&533!kRLg%(4AU-4k&)>7U$^zkefR zYeuJ_g(%4dQx0WV@SQz;bl-vq4t!62%3mzd5l`>zmYMr_=y^!c@rP zmqkcl6^oIav3N^mVD{Ymdj{G@ZJ*s$c;DvPjs;U6dPzT3eTgBFSpU~=U+V){FwCc7sBrV4+SpV8OY^mYY0d(EQ5$In z#3x&4Vrjzf3N|zrnfMIK;q)FdLiWz16zM>L1@_zZgHS5m(?#RTi^KbEf9kEl{iVQA zXIsRp<{?oQuaAFPA6!B)e)-9JY>A_BnQkaAr2>Ol4GuW_p}CylV~{eR#tJR)wk2SA8jU6b8~a!VYBn|RhYA> zhkRP)#obKPHLHCNw(LXV`Y*J|SZnw)K7ZdH6yeT_OU$sIV(QMb7+#Z(+K<5R?}*Xy zt}?LFQY@3Fopm^Uqs!Eq2nk2TJ|Ox6Jzxbno98n~;2{rra_s@kUpB~_pUZxnZIA=* zG5%pxS}Q1de@{LU>)x9Ztugksqvp48bnn<`Fdr7jn2_3IJ{8oc|qWCNbh03@^)UH1V@%dtt9m1?QdVxHn6Iq z6#=zVL!g0;-ndp4awd5ayFjJC1!z}DFctUnVYQq=9zyJ#W(;XFVIJYS+9#x_?PH|R zU~Jg;9~T_1T3Yw!x;KD@cVPNMhcd^mB1xm#WLO+0c|3*3`M9ZM!1?A->#Ex>%)K3G z8DJUVDz>+L5@K4_85p&j)XnsQd7?p^wxtU!EBhWCiYayP6yjUEMLZVGDMnJCCMoS# zhgpbmGxeHPfi|eMCfT2ZVV2-INQ?%uePur5lTawnaaN2W{EchJU%JGt{UM(6zScjr zU{%ihW2yB$*)|iW>sJ^COe6)076^T~m!r~0mNBvsKYT&de3c%<;js0%KP(kY8)7P@fh5{W06ipn2?P|Xm<=1%g{*(+e%88x!)9A$Ru-h^jBi7qy^ zL$6(HN>hz`|KwzH31gch!fJ= z!VssY420~H?|23$k$Fjt6w4x9OuF7Z_c5lKM!Jbzx&`-h#a1fU2rK_McmJpDWkV`K z9F|FZF?k3w-=k`Pg$5W~lOyULK)|d-6sG}}cHytkS8Ewb>N@1G>xh4v?4|2E+`A>b z!bCqTt^M5*6r+(xx@1=)Ean-aNo}ssO#4x4Ur5!vcCOkPgi?mtWRQ|?KAHMuvTtsg zyqvf;N7$`c))dekyk3v4Q#Z zBa*1D?Sp*MtyRYn>x{Bg*~t&JY2~*E#{XXr41^5j zLrL52X>mbgy~nks+qVars&b*{IU4yvWoBcaaT(;M$2~HkHAwnqa@4j%9wm9Br}Qe? zr^KG>Bq-M7E3=nely{Dz(6I$)m3%qHa1zAQtR1e1{_?vmC0pw2yD%S!@|60dMX=aP zZ}=BNr?p8XY2A8>R)4Y_#7m@=iU83){P_L{;=>s*|955;El9q{z=oW@ecf8@DGkxE zgv2qgzag3BZ&~g$F%W)&%CHlVc{3~bFUi2w7fPKg58s=@!b)qgv*b=;x~mMVQ3 z&7H6foo_p(NF_=g_4lL-r-;(}HV*u4(-MZx-U6tT93Y$xrr;;yt z-e|Zch1u`wYUYCp7(e!F<wIbO0>;a+srtNpB-c@u2nhF#R=*uKfI2DM({VJ9KxUi< zwx-g@qwmYM;lhFU9*Ky?rtxUU|+@C~X}2aEV>b@TG(OX%)4){7jXJ#(@E*J!c30G&KJfNt*m|=`DTq5m$@#XtUhGm z#49?Sx}g4^ck%mB0nhM6IS=hx_)JyU_+N+`&Asd@)52&aipH`4!W2`XR(%DhMQQ(+ zv}iE8A!Tg1v4@=+K z4PrjiNic0IszlVm)W*gB>W9<05D?$-bQZoI$d;?HdS3CdYFAfx7W_Y8YfO}2fHWEBU^KGpc%Hd&nMO-=Gv<* zFb}4(LYpw5Tg*XiRbAImWYd1q#(NoAIys0is?*?)lLf* zI;a9RR&5Vs`)c`Fyi>R~lGe+%;&dwY`@z8rKN_RIfY_fBm%QWReLllmFv6B_QVou( z>*Zg?+Q&nws`^i=M!e^3-WQB=vOLlfz7SjZp(E?nVDhFjp(Ww9c9agrA_Hlx!^G(l zaV2~W#)lI3aAgH5TCtbAgxqEL*k8X8hKfI~G9fORp}t+I;l&L7gdjAMO`Z9NFZnf& z6qVimj0bD>T<0ooFdai#SfknCh}C-w6lZzAL>FPdA3Ny9b>}&M zBHKx2cdI6$^mDRQGh)anyWsJ5ZYg+Lg@L|FxuwX5gZ@T@z9--1npb)>bE2{eZ2+@K z@~cGGrEXU$AwbGenEA>ou0`Xt_|J_QrQmeF%d|q0D(uh{ zIQn49og> zc1%N*WoB1Q?5|JLZC=kCeEm{X>Uw+1Vi3XEF(NcW9&v2)E|~-qz-j$;dRxtU-l;Eg z!xIU#}#d?xf4G#7-OJAMaVOSWCLpI!=6hwYD>w%hPms zwnhXFQvpzkVd<0$RAq0tIPXPm(ljrr66^>YWnJOrmfu%%IVdMWQO(#AHd+)wIYL*>Pds_{;R`(~0x9``tJ@38#4vX{K-7gEQ*$dva?d zUWKo9x_{j8{ISd@_TUlwQ$UVpBVb$xtj>QZyM9pteLgP+r(LyOjvx@F z?2k(yxZf`N*YEH78DhP>y@w`ec_ktosIlci=qqj$Up%n-Y%p?iMDvf||Hioc{cL71 zO)r#H@@D_Zok&=eQsTE;x(9;@r_{P~Wd}|G!tcC;;euAY82lNF`5Ko_PGQ0cM-KcN zau(5DIQ_Z7aWH1?D&i~Ohh*VL9{e}$5SM-&Yz*`FqpcW7cic>I&OFN90FENiD*cn0 z;gB%1Dee}#2ltk4Vc#1BwmJRX+I$J2YMJGqSfUh(!A=MzGx$OB*LS4meoco`00VU> zVRJuyl8vysk+jg8`ppib)$E#^-&J5u`1kfi10mbvKye(MCIgnmvBhqy)y3j`tu-m+>Tow^aU37AA_O2P;W2WU9Z>xdJcYbCt+? zfb}vY-bjtOp#!I5$7gr@h zIMn{+A3cjaHN)~#oW=fTdC^vS7^9O8mT1z@j#S_yjXj4&>x z6^(PJr=~iKOKBWu;-2VXt##FftZ_^nw5eZuPm-H z=KtVy^6!Lxw7)|PXoMb7cbb$2e2Dpw62wFI9``YU`mp#X5d-C43p81VO396`^2>en zUO|Ipm;mGspNIe~K)J%v6%s$qsZ}Z{)OAU-HGz~YDYnWT7 ziCR8G7|xM%KA>X9QhZri7!4md=L!e4`Hw$=y!-0wGe)Yi)o1l*Xp)jVSjc{WZ=WR5hH>q+A8E1`P*;ylQ41E zDLt{#(HB*ty}UzEGWe#HQ%Q9%vNuI&yDOv1sYHQ2H3mM^4BdAZu-$eb6LV;Crue^ zAA%=g{0uP=&qzPxp;g$yc~`*&Bx1uhFDd}m-OsO*oAi4tlSd^wP3n$|1O!G$Fj3VG zC5DMu5Y2SYuMCsTP*&J2jQiNF-)zfIGzf0>Tq_6_KdArInmqis42M?- z3Ld{gL(9)1smq0@tZLQap?YCg_9NbeRfg|(R6jzvH6yMCF6~DmT!<+}!vyidYz4fu z>p%TVatDOdWU|P-6c_1sD(v`7Zr6W-y*9#CKa*4WA_#c&`D+r9fS>uz+UtySv4+v4 z%u>OuU7)d?Q_K07)9d1yqI8d2sTn{#+$P*cLHR(w;Ct_?7v?Lx`a(WDxmri8Z~1FA zz=)S;=V|%bTiO4~Ow;u86ebwW(;DQ@e5=QN;m%)&p?yb9{GkSWSk6WqlF_z{t*MEv z{7QZ}J2`41+e;{lx{EAoua*oa_niZK+wRq6RD z5@Rt^0q+a0brpNVn+UX@5?Hg&nbgudJ1rd66cF`v_@Nb}Y^cc*KMd&u@ED34m=)i} zjX~Bcuvk7?Q&yxN%9Nw=UXvZxw`{LFVfQ)?iC zWeAt``24&sKAs{?X3=Q&@la-Yc}K9=?S14Sp{x_ma_VjP|Fy?LR?YJdJb-VxD1LJVib_&rOY!yV<#*ps40UUgUM`K1Gsgs5N5I21lEy(3Yang4on6H5Ep5Ae-pK7rUX{aO zsQ?#rsY!LkWj7&?R$~<5KDl^Ytd>~dl&Lo zlhEs=?)F^;*>|bFi|5T4)_jBQisPf(O`lS?a!u12IHRY5DTN5W&Htd3b!pKO9on;+ zo2=R%RYWKsEcoA>up(0*Lh=g*KPdCxAKWgA(Mpfp<08Z5b91#Pd2~zW&y>KTII@SL z#!>gKY@=lHP8RZ6JaSvO&u(w%)e_`}496^$dQW=}sQLEngoI+>L+LyUY`LCR^n>`v zxA(4!VHE?>e&(a`ncmAgy?q*H8T@p&>=>Y>Q^vKC!^|S9g;^x6i`(ER`@7-0y z_udGJ13YdI>kl86fJfKc;w+WkSnDG`uBCQcT(+*FyZ#@JMEokzvXVOm?r{fdN17dkmjfVYTBZah946f1n-R;Jr7Iu z%TWU?vTM*M*FrE@qwY9%q{_r|FvJ992r~^e55|&Mh(H8Y^dqicX3O(3TtQ@UVFA(a`gSU~K%BZAYF zChJkqS;Q1^zG5ge!SPN+k@|Nd@zt6WmWX?xK!DX-@Rt0ZVlNO1S)Gi$9t5~M9Y#Pk zB7@jZLZKKySvQ9DOzVOG`BCIDAm$^tKg}M+k$;$J=;cWHYIERLGtDwc5ZS zM=g{#=ZXE6cs+~){USsSwV^tS4x6Uj8TFxO)@q8qi7SU7VT*&p-oy;`j_f`Oo!$3I_A?g`I5m-{BkYc zrN&zeh^VbG1CZC`!i>6k4?qiqRO9Ec-c`QuWPSn4o_2jGD}^`eG>{Cc>Q9U?xuD*4 zIk4LAI00+ zzY1PHdY@5ImFx?~kg?E4(iMqCoSnD(w~GGZ#S{z_2)_YOrqQ*zA$|tL&9Q4ZpZ0P& zhNV7*^5bG+j`f^e;2dZE0%0YpXgGX^1K?{th5H`t%j&90$yKf@N#?=n|bYxylFw z3>Y+Zonh#raes!$I4^`?iFkiBpei7NXj^_TY}3uYRS|+%B~f6j2Z2;{`9)HBnRJ4w#3lN#$x(-nxN==Jit0n`mka&XGKo8r#E0 zpqciGstio`{zjTUo>8JgG5H*pVZJg-ab4t1eY?f+1g9eP?2*0m zi8+?YO9MC5uTLN+-F@b3Tcg$Zn2Zy)Px3GQUtn?)yW?NnCGfxuv~elnFI_$Y73Qij*gBV--7f_SbTL(D3_-xv#ovm{2wvNyopwe8Y_ zjaO|QdC?Uf^>p#8Tv_zmOv5qyUjw)a#^re6!x$eGan@g%0P%@2Taw3t5C%8~_VHpK zLHoNAWFJt61Q&zXjl0)D9!(*Jw7a(@3Q&)@vBn9kz)L)%j*5A_7j%Pnn)@7Rte`K^ z1iu7FB<>^?3|9zHxC((&HxystIh+UD1zf-0#;1q6&JJaKv4f>Qr)zX6k;PlhTMACR z^?+QiRS2NMK;P7MFd*l70y&R0cq{#u1&!~|coGhk5!9v3JjW2Um)didty8dr=_*hQ z6%++yj&b-dq{O*YQ6b8ZQxcFqwVXoBzkNHpl0L)&F2T`gl2sJ+ehVPQik=gaLfR;? z80Y{%s41nT;<~seKP7NunBTa^8i9V<2~U}5tqi*nJ~)*muWM{l))Vl~Gp1 z-q&6s3dzX0*A|&sA$yb+;*unri^vY4>{*DbGD7wy6v`&L)-~?$ysyva_nnX5L(Vf-4uFBVSHrRrB6eoB z(Pw}iT5KRMC>=Ig3j$qfb)%@a#{!8m&NXgw3Ds~Z41S4Cq~q6ySycFFJLVf+4q9sO zod{FJdwgAOpaIfMu?jgNz*Cq%?Mdp;>G3GIf&;Vd+ut)K=0)AP)+9@fTTzXm3~cgU z&&7|!0{`M=DW}ocpa25J8BwA4g!01n&y?xGu$m=a$d9_e{%X z=ff4*1!~O@;8xf<@8yvZ|F^_=5~eVir-IFZn?9SZ{7+S8oy|*YN+=h$hGLN>dT8YV z6pMb|dw=D~Acg%`qf#(H0J4544{{!f7zXavM3>*xL0#tUzWR3SeBJqcW7k(5wew4Ad*Kr3x++hmcVhkWt zQFsg#Fnm!$h!Vnv&Rd@5Mcria7~|fr=_I_g?hXOPH%@~_?fdmSYiM~5N?>_LH$zwg zVG!g}j8ATUJp$9bl-TC^1Y+K#g!27hMLaxf4+WZ!r-4QU z=&Ox1mpd&KYS)|Q_LslVt{-Y{P9caPeXW7~xY@#6Us7OK){hwgM#o!nPdhlj_)=l+p?r>oe}m>NKo!=7JIQf2#0i53uw|b%yos45u6h}YX=_iN&!b(nUQdvOdB@S zPpP&g3x@TC!~AwSf7ZNu3CYhP7|0L8@~j}g=ppw%&BMndGVc^hq`%kbcohmZmOy}q zoKY5}FTj`=MEG>}ku)KSwVS~&@rUxvO3Zza2 zz(kL+mmh_^_k`?t9XS|Q-2X_ZJEB!gcNlRBACjG73c874aiF531h$VUC%?fW^DJ9t z;k@Qs6<{91Pj<*XIp21~4YrY>=HtHZPsT+mBl)jbiQ?m-5I3-4eohkh3Mo*)PcAVE zzsP26)3Rd)=lqA%_mz`2tef=V6LX?YGi3Z$nJ*|dDOTU*;Li=p*zpxA8%b|gmQ&`c zW&6on0;Wv%tBZx&#?NS|jpIPz*!dvM-xkpdLXQFU3%3ScRNkHu9JnV)T_QnwA(H#~ z7HNqN`{W@RgXNY*gsP<$ow$}fgd`hV@^d%Q{GuU6;5NV-UsuOkIAf4#=0U<;f7j+sLt zW|c|EECy_BeBTHesU69s%>qO}1 z!?r_}z{T=Lk{eV$W7m!A7@-s0dL+;j(aNu#WI_$MkbSAmpZs3i6wU=9Tvi`|`cRGS z)qEEX+23&Qd^~0ugZWITYurW(l=Ge(B-76RWr^6pK3DdAqLrH+q>{^qRLo^NmXFvCRL^A+ zO{8-i#KoNEt^#gN|H9?e3u_`(@pR9Ehim8&$@dNgsy>*cbk#+M%FKLEAL^Vw>UdjMI&GceXqCnOTcB_jtlPEl`wqU`sGtFX*|YZzyykZIwSlc z#?vmdjTDTK8cp(g?AE}_j|}H#XR>-<>LNla)2tuvoa2@`5{{s>K=n+*?RCF%N2p6> zJkbVCxCEHnY>*kn%t0co(DLO%GVh>KWbuM0#27MkJ?cz>HT;^jJ(~7KK%Sn_JcCsu z>%e4mbW66bmi=4^C@e*>V^5Tg18qv~hmpM|z^@B&x-NYpP+1OHG8f8@gN3pGNDO9t z!h$rI>p%)^$<1EgNqv!ae6{&E@X@%Bt@3Ejbm6V8ixcN5vg^Ez-<$r>Yns#VAp$B_ zpzLJW{cE#_wOUVN$6yfa8?M}QBVp-YxY<+37}^}9$O&ds$8R83ic3YjZ9S za6WmL#g!BE(11ABi*fHeO*8P6)J2FNYfKZ-&jWn5SXcKm^5e#)amN!m$C>gYCAJD} zvog{MMwV3W7@sCy^K4kqk8`Mx`_2jIk80YCNJJY87qoIAX@o}^qbPz6N3umpJ9`<{!NAgk@#CeauQ*@IgatcK4C$J$fiMXV# z%bSTyzjf4)qMQdMHQ^5B?NvjApoaY}F?`Zy{3h8W575ux{*Qy5icuFMg!vcJVASh} zH834Ew<`4&kgE{!QltOqHr$Fg%}Io*UC(%RWUV&W;ifTbm^Y(vas5~s3y(H!O-5IM z1gK%L{53|jU0^y&PRR7Xy4c6;)YE~lTB+_WDoO}&5QH>S>pCM^L5u+;xHx6>esj@I z$S_gnk$0lPqwNDsj5#a zw=Ciwac)J@{gNaD05GaqI;Vg!5~Tieobez1l;*zj)vw5_H(( z#WAr|fJ9jSEoO~Ms4fh3R-HXxfZS=#lUuQjzUxn$c-#D-7H6`u%i(Sj4=2-X{Nu1R`B^9;l`Jz>NWDsd9)n+oDq-HyuzcO~LG*`a?3TP~I>>19 z{C*FU;z1HhG7tUVlm(_422Cs18djM&-O<0a#nL{*JbouBpA$`3dWpQa)1`f~0`h>7 z`LV`9LX2oxc~exwC#e_t9aiQ#U!XJy6H0L1j`FC;z1jV^q{v8Y`y64S!uDYy_v9Ww zs9wwg#{HY4&J`$)3*QC9g6`v})m5u6RlXN^mj`512Jv;&7tR(f6FDR=Xf8TnEN`~! zQq8lg^Qr-bF0@Pl-tz2#1zk)&vOed=c^30E%X^mLGy%6AxDjz2k6%ea$wRhmKymTt^w{qn8bKoVSDRQDkS zKP2Shj{=t_0=UIdZL8Bd&vZFaCLhAJz`7qG?C&J4s z1n9EJV?z8fDp_2IUpGGwPo$K^?0C`vB|r!OdY;2Gf_E z62VxhW&P{;ylI%HMQg%|H1CviQ+!#8k%*fFHD(dNR6wB-OX+_7*!l6Ty@|QHL$KxS z85Q3|VE)$-=?#zqDYQrfiLE8@^vUxLEEVsbiGLP+CIk~BB6`!7W5S&VYlJ?YGF+X6 zggvz_vjZArgI^@|FsJxX9tpVO)4?*kqlJh)?rJ7LQCG0XGs|*rO;25+c$hfyFBbrH zeC0KAXA13FTh?>Zwo@xyu3zp9@}7GaRoL)*xTYSQE*|iGAS+Je5!UXI2(HxfG}!;1 zy4hvq4^;l#^mIDy`hg}Ee|5NY^9kE}Si-Xwa*`LqH1s9Z zS6`GV=ai1mVH;5C)EiephQs1RS%6=5%OfCcVf%dUT*28sO{xo_I`$;Pq671SeVzrP z1}d0xUAZyWM*MV*EKL8VH!w)a6>>tM>3r3_M$W-NHgURA1*o%DhRq4HMXM}X9`CxF zl{#00b9U`s9bN@Ki)u`H;1rLHq5VdChv^8u^I0Vw@^UUv$O%i4tfy0Xh+_`Cng{oGl6i z%rlagyzinzBbYpM@7(NXZlK-wX04_1Le@OX7+k@X<7PEK8=Jar9Ztbd0c-?$76NWt^)JN3$>J> zs=N@AOs1Syu732_+)1#u1h|>WNDa3-i~Mo8UVN z%$pxxnXgzLr22d}7*@;?1EOWTt)&8OiygF_uiNb!L>afm%?Qk!$#Zq~imqMe0FI+` z;L!Ht<`AvC&y><()O}~gqD9$A`hK+khF5sc>V2F*q+__2>SYo}sE8LEHaP7b+#>bR zf1p#FG~(RXx&NF3HhEZ%I{I1Eqy#&s$bK+e2y56>F2JKVP%6opOis`;zT;-udDPjXk?1(&bNiKkd2^E;XR-htz0<7m}`c*7m zom&JU>))EJirj28Z8!R;Gk3167Wzd7QW)*5@0;lIlblv63;Pj~sqv~iSBm0=iLpjG zls*r9ZX9<@6=c3vq#?NpFoK_CLQbdV!2nEa!qX!8E+!GsjgC9Gn^)6OAF=s?D)6%i zcIgv{v&}QG!O1?|3O?7rkJ-hrR)2(NX3`+>R`K-nnylk&hfaGx}VM=NI{ko9IzL$zK02nVW* zU(OSahAyRd^?fNy+kje{hs#t5VNPldHD!N1Cnx>zzc@4V^pVZ%gr(hbIOZ6g?6AoT z3!2OMx}VWR2=@tX$)44mZJ}L1NL6mcxl0w#V>D`AidoERoiQcr2Z*Iu}4US`B-f{UwLXWhxWd^Iky=Fzey%}?#^ zsuLVh$0q3po+UV+x}n`MM>Cpq|MiMGRz=bh6==0C&BiKJCs#8MXv~k_L!~SzihEG( zG946w!OSK&v<7p3aB^7xiZ}z zU2IBuss*8BF0}_h%)&25^O`UERaMr@Y1yv1xOcU; zzqCDg3RdsJh@jdDyltq?Q(~*hb5C9`Ud*&jdt^gPqOrPa`j^YfdwV+@&^8wYI%s08 z9>!?xjpdHmM62eS-Abga=`hklv7?*JK^;296t$pEf|`{V26R#AeuDVPjHQOx`fTCU zR=FFs^dVNgVU)%VRyQhE@<}}ADvy|OCnDY{5)PGdL;;+~6mGQ)1Sn474 zPb<1gOE>asF|NQ)qnh|2zvGFCZojs^Rq| zO#EcS5>az_B-FX}=T?Fz(ka7GuyW+FV6mV}7?ANKzaZ-yWDl`3cfq3843cQD&+H>jpjDx1`etR?Kte4^c;ee7b6=CjVpsXDVXcN&2kJC%_`Pdnf0-GtTvxZ<wuSRZsQc%Lmza*V9rK zm`KvNpuMeXSKk@h9Z>==sm1}SqOeW!`TDuQiQM#aXn_HpW}&U7Mp)3}@>X=CJ{}67 zQd2p>q`|M%h4D=mDXyYHVt84oKc!=|3d&2K;GW{qv zVb0T&3boPinSs;&{~p2&9n`fGRB0$v_*$K#u>?W{;1bvk%l5ONhQidEQovV_@b{w>k+gr(T> zH*p?CW4~g{acU7hxTffGY;ZJs&&ctqau1^(S)v1G7KE6)*!^hr{8pVAj?STQZfSos ztRoiw=tvK6SndG$TpeJ1xj{Psih3ZS(VGeAhA73m*(;4{54T4<4Mf0Wx7P%5gElDU z!(^B&I)33*0PJL%BLewX9}xupU1abLx}7^Ef^z7S?=%+P#!ma%Au^m#wA;trwAgkc zg0{IMD3Ka-;k)Wj);MS))-xw*I@xWy#Twax1ew)B*t}ia49#}1uV0LEfVe4UyZL@{ z7qM;SY*zRFy=}mTt3VX7yTm6k$tgJPH*SHX7BA}TAb#Vo2E3%|D`~cjS5`~2G4#vt zzvahu*~YCD@p^Yb;;eeaK(%8W8I)mPRhXaE_DYneT!r;j-5L_b%5$L(^b&wLbueio z=^*-S{dD==8ff&uJ-+@}(1cc*8v&5Z_Ujhx^Kxt{TRXV;TZR{pe{6D39$O=3W%5wG zP7gZEd<)Be-mMlIUVS{Y>4dw>2LE;EfGtCGz}sxuhUaaDKW3qwg1ce);G!PI>`0)D#J{umy98~e8L)xp_Drho4x22N)*Qmtgr%T;Y7@=2Gd z@G2r+L$yd!ZrDc7u{k%tEH}U7Uj4O2>+zzsx9{w&V=fNSsjO9>y;4`0zrOZdArVSR z3oi%;7{bd`gU30SD@|M3o5(}zutsJ(WuMQQkd6aSYJHoGfr{i?h>t~JXN#;Bx#moc z_+EQLXC4Pun);2KTYvV*o0)x-*7K`7=~J&*4oK9o=IDAmXTiYv2(7`}j%J#dzPU_% zH*n9H$O^!yjwLrw+j(l#6+~pdd-U!?{qE5vE{vTwLmJWF0C*;sS883ecJBApJHIH2Bfl zWc$;%@)G+m4X%8Ag|s){oW1-tT|zGUdS}TPrMhBHAe5{f5*Y55#NUe{s8kuWsePg7 zf0@X2r@U^(JnTXhbp@2TKc^KB<*CTKVv@N)xgD46MHub>t?=5So`cnvORSQfj}kip z^dVWY|Bnw5^HhLm3rjIHG&`wZfBzm`pm{~fF~Gp!oH(3rAu~?td`R=GsRc}69}p9j;^6L%u& zZ1W#1tVi1>x!Gz~83p#Cdu2s!bf`K7h?*ix-#s^E4pltE9Oz&#yZ*koM|UJF{ZQzp z?=_=iB`v(cix60yBXNQP#zpqF)6CW!n&R(XuX?H2H4{ER?At4@QnWO?qlSo;woKp) z@@ZMPCd96IjJp3ZjKkTL&yO~ENjFv0&TJl3zv#9Vb8IVc*x~NGB5kxOSC?V7W?`Lo zKJtE-hNb5>$11+Sy+qan&u|+`!FSHr>dsG1z8kw5qV>NPPMeu`WvHi;TqWaY^>C_H zP02m&e3l*)GbgWXcdxuVO0V%zovL~x!MYsvk^HR4+iwm9?;=Xih{%dFy7rB`{GM&G zvo<)9T)d+4B=T{baCW=w;51)oSnBr381ttACnatFn(;-(7~yrnp9#XmXVOD}-=q0J zECx~cTl&dryd~&4eK$)m3PRVtIWiws{&8BDA&E+4^^1v;klUuc5GeW+HF}GIq_+=V zSy8NBsPb@(bH=8-_7f{cvMZ+*w{e(eqszf7r=BXyV^CB!FfK0SP;BvqM2h3bGf*n? z((9d)YF%kSshsuE*U&EX>Gu;yaZd9To7+-S58~2`CK%Jxon{v-gMR)>FugZ~#XEnNi3;JTF16-u5h6>YE8Isxzf^b#FgMs%wWiwyZChwLCUGW`O z+IW!hmI0xvBoUA|T_Wn{_O|2OZ``(cgQaM|N4rYPUaXphee=wtM&7vh!UoN$%9*3( z>G~s!HPIb?sy5vYYGyl(JQZYwyg++ze0o89THHiIhP}{K-9`0*r@$^0JHf>~5v*~u-{J3EO}eeq89*I}Ca)3>(_Sv3-GB{aY8U5YzM z)wFSgVLw%rWW`MQ%lWsXCK$Z35r=>C`!rGK3XBsZs+t=g#~PcuznPXqvEB_VD=0IDA(;e@C68re`1B%REa^3weh*tuGpCQ$0`xD0DaXC%6fdM|(vA?* z%B6D&R_=F~OlIpmT0raAT|u$_MO#H#T=I7M(JHm$yr0oIwJiEmU+iycy?IO9O(6>6 z+WNfZ6d`E|4dzbq%;%9|RqbL%=|BgQU$gF9>&j`tsRWi5)gL_m+PsLh2|0OHR)Xu< z>wNP0jYT$p4MJ$8w5AcuETJWHB|~Gd&S)iTV5@S(!R5e#K!&4V9E2fZ+2EB^r@%_+ zc6R;1&pw%woF^{4$TF5!e}0j*hmT2D^X!QV*|Q^dEuK&|&-h%v{70(yIdOpki8}uD zcH(LEpY%-by{roUNT8EIXNbU z*jc7aec)t`#71n`tW*|bwrC`#3g^8A)8D+A$x1qrU>h0~|LwwW7i|Y^VYTF)5wB__ z_#KG{PBKx5;m_EV9h=hLFZOwrzdi*SDCM|$K+9wJLhqZp3=&N?<<@^rY;QILZO6C^f%;bbId2@LMt<70fsUuM*{9e+9 z7MHHc@aWq7z45BLe7R4m492^Xmjg_;D{sCeKeUN_XutdXwU_y;&NP<9$67X?r*AXa zuLdpHm^QXm^EU;x1#uu$Q?MGyQ}=dZ|rZ#)iIARnW^NRCqK@1 ze{FvA(r$D4K|n$D^<&AYvBC{~GUE{axGP^$dx=QTPA zshWlKl9V~i*U*r-vaLf`yrhk|W*N)q8JA;QrNt|^y)&UbBC4%xTbd>O?FLyHDrEYz zOA6;`ot<23<=*(VRkd?+j5yymvRU!vmTs!m*VQx)`lOw^dHwkt-iMl%T33KOuucCP z_wMepq^odJwRN*DI-Mn^{UuZ408xlGM8DwowK|W7?@9nhsu*y8#>9k@oc!FSq3b&I z?r@r8jrBF}WD{p2xPKADrFID^$LS%H%XVa`2O+3;5`rmBKUD&aqEsK0?+FFL?0W^% zqJoCH03t9|z5Uxtqwl_6l=1_ev;1eVG+{^c!qwNm6}|T~PRW$$?V;PO{MD{mZpvtv zWApCER;3A-J>uy*V}Z4}6=79X^gvYp%7nIzNlLS#;~i`4@4NvQ@42vB)e=#DrS=b2 zj|^XHg)NfqaK6d((n>H0eKT#g+~~{euA26dXlgC|)%xGXSRubxo1TAt4zZ)ax|~S- zIr=#v>-t>ig!hX@I?#rngAHG3?V`P4B0KDCwL?_IxE) zb7T?lGx_eT)#TLJUl5^d*QBw|s+E|GJ<3JNP6=#T*Y)*FOqqXQ+^##^pZR}zj5BTO zO|GAt9g|V*RHMm{e9nz9>G7br2%Ksu7~cvCIG3iA0qRIZu#PO!_|kH1-pxdM~mGTe#t^@F<&{rQzjlEZyC7E{0k~EI_(}?&De<~Z3Vmhd<7Gf!02iMh)+)ho z=R5(_8IwfPP{lS;$jEx-J&@4GUDeln=C7Y{j8)O$xkpaLPRKp!d_^ydpVQ2QdI zR>qmk+?qrKnX^#g{LS1Yiu5?@s)u6m$*-rJGVJkSQbicF%V33mDBE6aUf9p0ojs6W zy<9N-gA81>6ac(ihMVEy1ekJh@wNAWMGkm@=SkK;-=M-i42IV_uXwQ2olHPHR{-1& z>%cQf%>TU2@m`+AcFM@{+OhLx)2~jT<*)Tr2O`c7eqqtLcG_T~0P_xqW_`q@D(B%) zwu^K-m-HI;NC0sMff*{l`o-pq&Jfx#SkgleGz*A>e+O_^(5$23!xy;zquqKR-)@y8 z%aG>&r&Ex)K&9p^koS0&6oxxY0=yb^aMPR)aC2wV7SVDTQCu`}S;)!dioaLo=!uv< z8AraxHwr-i=P`Hu(aExlNAW0j|1Vq9XxKIZ=|}H7xdVW5vTBcbF6}`FUAMgT7IbYp z(`(+$gY|oTS4=(a{!lxlDQvIx*&Q9D6Zb!{NtsLTct2I(1YE{$z=eWu9}#C(6zQk} zbzA81o>am?ta^6ca3DV!3?Bu)R|`6vA^T&8Fz87JDx?{p{;oaLa7^ROnYoc`k@%LC zK|ji4docwt>_unG91D@&JzV1wFksNn7hL~+b-_4Uff)f^Y6ACsmPK(}338~TEu_)N z(O~#8O*R_+S9-zcOB8f+@FXOld!(42)Ev_pWnnK{gmkdCI*93daWnVrGcgoW|b{9uRHL=1~Cmm+88ysskYw{E(XA zTtGAT{3fon75zaKG&>z;uL|)2qMtzP;6x^-ytm=(7xs9d?TYMp1qN*%-6(}8YetSl zu*tt$Yhn?y%`dqXEs$?tT9B9PuuDHQm{UW-26WIu;9U^Wff=3rs6-x7xw_^%>UBz> zb3ne^rM_&L{P+fGNH65!q*JV@@#?L>ZbgJV$ph%qR}}m8BYl}-_B)99*%^_})ed4e za6>YJ8gU0nk-zBLo+q&ai-^Iuu+>x=dIm-NpP!uSc-n6yWlzT|sw~dT9fKX(#_>?x3y`LGl z?4HU3o>TQDATi|rvzx6Pgo}pt9gAlYf=7(F02L(xq8tDoP3QhOq$qUr9z0sW=fp7r z-pQb4!TL8i*rzG@9R>ean?ETZuL!zletYmTLspRXn7jH;;JZzy z_D;~MJNDkMrBfEZpZXHH46Z>Q3j{vl_4~~lf%N6e{Ddkp5fVsvxMw$^;Jk^3-Wz~0 z|IYmtbi&eeqJI&1^IoBMTjU%{nT@IKUXNhG+} z-TC0>3D(b7mmOaS0cbMR^8-|+Qds}h@2o(eCIBuucqf2G35t|2Yb%veb zp{EjB27!TGS_a;1@bry3EP_JIo|i;MC-}t4csP}SfPfmItY|ReM`z6r%u)LX?%ctR WY;W{h_96H`0)&dTa+#9V)BghkI`yCc literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindinsight/images/parser_module_profiler.png b/docs/note/source_en/design/mindinsight/images/parser_module_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..8ef3c927013517e341fbe44c7f96f0be05536b80 GIT binary patch literal 8988 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 literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindinsight/images/proposer_class_profiler.png b/docs/note/source_en/design/mindinsight/images/proposer_class_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..3e2d4363e92821b05cafc330573c981a1ab99bbf GIT binary patch literal 8571 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 literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindinsight/images/proposer_module_profiler.png b/docs/note/source_en/design/mindinsight/images/proposer_module_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..909dd42c89715d49a11c35764d84aab231b91fb4 GIT binary patch literal 6423 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 ZrO$KER(rk-{HFtgUopR2Y2f_RKLFmb7i$0j literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindinsight/images/time_order_profiler.png b/docs/note/source_en/design/mindinsight/images/time_order_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..35eef99934ce9d743ebe0294e18ff0b5ea40abab GIT binary patch literal 15366 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 H=Dq&`b8@~q literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindinsight/profiler_design.md b/docs/note/source_en/design/mindinsight/profiler_design.md new file mode 100644 index 0000000000..e184972373 --- /dev/null +++ b/docs/note/source_en/design/mindinsight/profiler_design.md @@ -0,0 +1,175 @@ +# Profiler Design Document + +`Ascend` `GPU` `Model Development` `Model Optimization` `Framework Development` `Intermediate` `Expert` `Contributor` + + + +- [Profiler Design Document](#profiler-design-document) + - [Background](#background) + - [Profiler Architecture Design](#profiler-architecture-design) + - [Context](#context) + - [Module Structure](#module-structure) + - [Internal Module Interaction](#internal-module-interaction) + - [Sub-Module Design](#sub-module-design) + - [ProfilerAPI and Controller](#profilerapi-and-controller) + - [Description](#description) + - [Design](#design) + - [Parser](#parser) + - [Description](#description-1) + - [Design](#design-1) + - [Analyser](#analyser) + - [Description](#description-2) + - [Design](#design-2) + - [Proposer](#proposer) + - [Description](#description-3) + - [Design](#design-3) + + + + + +## Background + +To support model development and performance debugging in MindSpore, an easy-to-use profile tool is required to intuitively display the performance information of each dimension of a network model, provide users with easy-to-use and abundant profiling functions, and help users quickly locate network performance faults. + +## Profiler Architecture Design +The Profiler architecture design is introduced from the following three aspects: the overall context interaction relationship of Profiler; the internal structure of Profiler, including the module structure and module layers; the interactive calling relationship between modules. + +### Context + +Profiler is a part of the MindSpore debugging and optimization tool. The following figure shows the tool context. + +![context_profiler.png](./images/context_profiler.png) + +Figure 1 Context relationship + +As shown in the preceding figure, the interaction between the Profiler and other components is as follows: + +1. In the training script, MindSpore Profiler is called to send the command to the MindSpore ada communication module for starting performance data collection. Finally, the ada generates original performance data. + +2. MindSpore Profiler parses the original data in the user script and generates the intermediate data results in the specified folder. + +3. MindInsight Profiler connects to the intermediate data and provides the visualized Profiler function for users. +### Module Structure + +Modules are classified into the following layers: + +![module_profiler.png](./images/module_profiler.png) + +Figure 2 Relationships between modules at different layers + + +Module functions are as follows: +1. ProfilerAPI is a calling entry provided by code, including the performance collection startup API and analysis API. +2. Controller is a module at a layer lower than that of ProfilerAPI. It is called by the startup API of ProfilerAPI to start or stop the performance collection function. The original data is written to a fixed position by ada. +3. Parser is a module for parsing original performance data which is collected on the device and cannot be directly understood by users. Parser parses, combines, and converts the data to generate intermediate results that can be understood by users and analyzed by upper layers. +4. Analyser obtains the intermediate results parsed by the lower-layer Parser, encapsulates, filters, and sorts the intermediate results, and returns the various information to the upper-layer Profiler API and RESTful. +5. RESTful is used to call the common API provided by the backend Analyser to obtain objective data and use RESTful to connect to the frontend. + +### Internal Module Interaction +Users can use API or RESTful to complete internal module interaction process. The following uses the API as an example: + +![time_order_profiler.png](./images/time_order_profiler.png) + +Figure 3 Module interaction + +The interaction process of each module is as follows: + +1. ProfilerAPI calls the control function of the lower-layer Controller to control the lower-layer collection module to collect performance information. Currently, the collection module (ada) receives commands in resident process mode and independently collects performance information. + +2. After the training is complete, users call the analysis API of ProfilerAPI. + +3. Profiler API analysis API uses the Parser module to parse performance data, generates intermediate results, calls the Aalayser module to analyze the results, and returns various information to users. + +## Sub-Module Design +### ProfilerAPI and Controller + +#### Description +ProfilerAPI provides an entry API in the training script for users to start performance collection and analyze performance data. +ProfilerAPI delivers commands through Controller to control the startup of ada. + +#### Design +ProfilerAPI belongs to the API layer of upper-layer application and is integrated by the training script. The function is divided into two parts: + +- Before training, call the bottom-layer Controller API to deliver a command to start a profiling task. + +- After training, call the bottom-layer Controller API to deliver commands to stop the profiling task, call the Analyser and Parser APIs to parse data files and generate result data such as operator performance statistics and training trace statistics. + + +Controller provides an API for the upper layer, calls API of the lower-layer performance collection module, and delivers commands for starting and stopping performance collection. + +The generated original performance data includes: + +- `hwts.log.data.45.dev.profiler_default_tag` file: stores operator execution information, including the start and end of a task and stream ID. +- `DATA_PREPROCESS.dev.AICPU` file: specifies AI CPU operator execution time at each stage. +- `Framework.host.task_desc_info` file: stores the mapping between operator IDs and operator names and the input and output information of each operator. +- `training_trace.46.dev.profiler_default_tag` file: stores the start and end time of each step and time of step interval, forward and backward propagation, and step tail. + +### Parser +#### Description +Parser is a module for parsing original performance data which is collected on the device and cannot be directly understood by users. Parser parses, combines, and converts the data to generate intermediate results that can be understood by users and analyzed by upper layers. +#### Design +![parser_module_profiler.png](./images/parser_module_profiler.png) + +Figure 4 Parser module + +As shown in the preceding figure, there are HWTS Parser, AI CPU Parser, Framework Parser, and Training Trace Parser modules. Each module parses a type of original data to obtain the intermediate file that can be read by users. + +- HWTS Parser: parses the `hwts.log.data.45.dev.profiler_default_tag` file to obtain the task-based statistics of the device, such as the start and end of each task and stream ID, which are used to compute the operator execution time. +- AI CPU Parser: parses the `DATA_PREPROCESS.dev.AICPU` file to obtain the AI CPU operator execution time at each stage. +- Framework Parser: parses the `Framework.host.task_desc_info` file to obtain the mapping between AI Core operator and task, and key operator information. +- Training Trace Parser: parses the `training_trace.46.dev.profiler_default_tag` file to analyze the time at each training stage. + +### Analyser + +#### Description +Analyzer is used to filter, sort, query, and page the intermediate results generated at the parsing stage. + +#### Design + +This module parses the intermediate files generated by Parser, provides a general API for upper-layer data analysis, and returns the analyzed data to the upper layer for display. Various intermediate files have certain common points which can be abstracted. Therefore, following figure shows the design of the Analyser class. + +![analyser_class_profiler.png](./images/analyser_class_profiler.png) + +Figure 5 Analyser class + +As shown in the preceding figure, multiple Analysers are implemented for different contents to be queried. Filter, sorting, and pagination conditions can be defined for each Analyser. Each Analyser knows which intermediate files are required to merge, filter, and sort data. Analyser is associated with Parser through the intermediate files generated by Parser, and no function is called. In this way, Analyser and Parser are decoupled. + +Currently, there are two types of analyzers for operator information: + +- Filter the average information of operator types. +- Filter the detailed average information of each operator in two Analysers (AicoreTypeAnalyser and AicoreDetailAnalyser). + +To hide the internal implementation of Analyser and facilitate calling, the simple factory mode is used to obtain the specified Analyser through AnalyserFactory. + + +### Proposer +#### Description +Proposer is a Profiler performance optimization suggestion module. Proposer calls the Analyser module to obtain performance data, analyzes the performance data based on optimization rules, and displays optimization suggestions for users through the UI and API. + +#### Design + +Modules are classified into the following layers: + +![proposer_module_profiler.png](./images/proposer_module_profiler.png) + +Figure 6 Proposer module + +As shown in the preceding figure: + +- Proposer provides API for calling the API and RESTful to obtain optimization suggestions. +- Proposer calls the Analyser API to obtain performance data and obtain optimization suggestions based on optimization rules. +- Proposer calls Analyser factory to obtain the Analyser object. + +You can call the query API of the Analyser object to obtain information, including the top N AICore, AICoreType, and AICpu operators that are sorted by time and the time information of each traning trace stage. + +The following figure shows the module class design: + +![proposer_class_profiler.png](./images/proposer_class_profiler.png) + +Figure 7 Proposer class + +As shown in the preceding figure: + +- Proposers of various types inherit the abstract class Proposer and implement the analyze methods. +- API and CLI call the ProposerFactory to obtain the Proposer and call the Proposer.analyze function to obtain the optimization suggestions of each type of Proposer. \ No newline at end of file diff --git a/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md b/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md index 7c51ece76a..504452646d 100644 --- a/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md +++ b/tutorials/training/source_en/advanced_use/performance_profiling_gpu.md @@ -77,8 +77,9 @@ Users can access the Performance Profiler by selecting a specific training from Figure 1:Overall Performance -Figure 1 displays the overall performance of the training, including the overall data of Step Trace, Operator Performance, MindData Performance and Timeline. Operator Performance Analysis is supportted only: +Figure 1 displays the overall performance of the training, including the overall data of Step Trace, Operator Performance, MindData Performance and Timeline: - Operator Performance: It will collect the average execution time of operators and operator types. The overall performance page will show the pie graph for different operator types. +- Timeline: It will collect execution time for operations and CUDA activity. The tasks will be shown on the time axis. The overall performance page will show the statistics for tasks. Users can click the detail link to see the details of each components. diff --git a/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md b/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md index c94106f8f7..d3ed71c1ec 100644 --- a/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md +++ b/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md @@ -194,6 +194,6 @@ Timeline主要包含如下几个部分: > 如何控制step数目请参考数据准备教程: > - > + > - Timeline数据的解析比较耗时,且一般几个step的数据即足够分析出结果。出于数据解析和UI展示性能的考虑,Profiler最多展示20M数据(对大型网络20M可以显示10+条step的信息)。 diff --git a/tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md b/tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md index bc7002b089..42aad225ea 100644 --- a/tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md +++ b/tutorials/training/source_zh_cn/advanced_use/performance_profiling_gpu.md @@ -79,8 +79,9 @@ class StopAtStep(Callback): 图1:性能数据总览 -图1展示了性能数据总览页面,包含了迭代轨迹(Step Trace)、算子性能、MindData性能和Timeline等组件的数据总体呈现。目前GPU场景下只支持算子性能统计功能: +图1展示了性能数据总览页面,包含了迭代轨迹(Step Trace)、算子性能、MindData性能和Timeline等组件的数据总体呈现: - 算子性能:统计单算子以及各算子类型的执行时间,进行排序展示;总览页中展示了各算子类型平均执行时间占比的饼状图。 +- Timeline:统计了算子以及CUDA activity,在时间轴排列展示;总览页展示了Timeline中执行情况汇总。 用户可以点击查看详情链接,进入组件页面进行详细分析。 -- Gitee From 944d30482a90fb311a09f3c83858bf39f683005c Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Thu, 17 Sep 2020 16:29:02 +0800 Subject: [PATCH 060/100] Modify the programming guide for r1.0 --- .../source_zh_cn/dataset_conversion.md | 4 +- .../source_zh_cn/pipeline.md | 76 +++++++++---------- .../programming_guide/source_zh_cn/sampler.md | 6 +- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index 702ecf4686..5c5dd760aa 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -79,7 +79,7 @@ data_set = ds.MindDataset(dataset_file=mindrecord_filename) decode_op = vision.Decode() data_set = data_set.map(operations=decode_op, input_columns=["data"], num_parallel_workers=2) count = 0 -for item in data_set.create_dict_iterator(): +for item in data_set.create_dict_iterator(output_numpy=True): print("sample: {}".format(item)) count += 1 print("Got {} samples".format(count)) @@ -379,7 +379,7 @@ data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) decode_op = vision.Decode() data_set = data_set.map(operations=decode_op, input_columns=["image_bytes"], num_parallel_workers=2) count = 0 -for item in data_set.create_dict_iterator(): +for item in data_set.create_dict_iterator(output_numpy=True): print("sample: {}".format(item)) count += 1 print("Got {} samples".format(count)) diff --git a/docs/programming_guide/source_zh_cn/pipeline.md b/docs/programming_guide/source_zh_cn/pipeline.md index a3aeed918e..14d680da8a 100644 --- a/docs/programming_guide/source_zh_cn/pipeline.md +++ b/docs/programming_guide/source_zh_cn/pipeline.md @@ -66,11 +66,11 @@ for data in dataset1.create_dict_iterator(): 输出结果如下: ``` -{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} -{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} -{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} -{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} -{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value=[4, 5, 6])} ``` ### map @@ -110,17 +110,17 @@ for data in dataset.create_dict_iterator(): 输出结果如下: ``` -{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} -{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} -{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} -{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} -{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value=[4, 5, 6])} ------ after processing ------ -{'data': Tensor(shape=[3], dtype=int64, value=[0, 2, 4])} -{'data': Tensor(shape=[3], dtype=int64, value=[2, 4, 6])} -{'data': Tensor(shape=[3], dtype=int64, value=[4, 6, 8])} -{'data': Tensor(shape=[3], dtype=int64, value=[ 6, 8, 10])} -{'data': Tensor(shape=[3], dtype=int64, value=[ 8, 10, 12])} +{'data': Tensor(shape=[3], dtype=Int64, value=[0, 2, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value=[2, 4, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value=[4, 6, 8])} +{'data': Tensor(shape=[3], dtype=Int64, value=[ 6, 8, 10])} +{'data': Tensor(shape=[3], dtype=Int64, value=[ 8, 10, 12])} ``` ### batch @@ -157,12 +157,12 @@ for data in dataset2.create_dict_iterator(): 输出结果如下: ``` -{'data': Tensor(shape=[2, 3], dtype=int64, value=[[0, 1, 2], [1, 2, 3]])} -{'data': Tensor(shape=[2, 3], dtype=int64, value=[[2, 3, 4], [3, 4, 5]])} -{'data': Tensor(shape=[1, 3], dtype=int64, value=[[4, 5, 6]])} +{'data': Tensor(shape=[2, 3], dtype=Int64, value=[[0, 1, 2], [1, 2, 3]])} +{'data': Tensor(shape=[2, 3], dtype=Int64, value=[[2, 3, 4], [3, 4, 5]])} +{'data': Tensor(shape=[1, 3], dtype=Int64, value=[[4, 5, 6]])} ------ drop remainder ------ -{'data': Tensor(shape=[2, 3], dtype=int64, value=[[0, 1, 2], [1, 2, 3]])} -{'data': Tensor(shape=[2, 3], dtype=int64, value=[[2, 3, 4], [3, 4, 5]])} +{'data': Tensor(shape=[2, 3], dtype=Int64, value=[[0, 1, 2], [1, 2, 3]])} +{'data': Tensor(shape=[2, 3], dtype=Int64, value=[[2, 3, 4], [3, 4, 5]])} ``` ### repeat @@ -193,16 +193,16 @@ for data in dataset1.create_dict_iterator(): 输出结果如下: ``` -{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} -{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} -{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} -{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} -{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} -{'data': Tensor(shape=[3], dtype=int64, value=[0, 1, 2])} -{'data': Tensor(shape=[3], dtype=int64, value=[1, 2, 3])} -{'data': Tensor(shape=[3], dtype=int64, value=[2, 3, 4])} -{'data': Tensor(shape=[3], dtype=int64, value=[3, 4, 5])} -{'data': Tensor(shape=[3], dtype=int64, value=[4, 5, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value=[4, 5, 6])} +{'data': Tensor(shape=[3], dtype=Int64, value=[0, 1, 2])} +{'data': Tensor(shape=[3], dtype=Int64, value=[1, 2, 3])} +{'data': Tensor(shape=[3], dtype=Int64, value=[2, 3, 4])} +{'data': Tensor(shape=[3], dtype=Int64, value=[3, 4, 5])} +{'data': Tensor(shape=[3], dtype=Int64, value=[4, 5, 6])} ``` ### zip @@ -240,10 +240,10 @@ for data in dataset3.create_dict_iterator(): 输出结果如下: ``` -{'data1': Tensor(shape=[3], dtype=int64, value= [0, 1, 2]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} -{'data1': Tensor(shape=[3], dtype=int64, value= [1, 2, 3]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} -{'data1': Tensor(shape=[3], dtype=int64, value= [2, 3, 4]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} -{'data1': Tensor(shape=[3], dtype=int64, value= [3, 4, 5]), 'data2': Tensor(shape=[2], dtype=int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 1, 2]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [2, 3, 4]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [3, 4, 5]), 'data2': Tensor(shape=[2], dtype=Int64, value= [1, 2])} ``` ### concat @@ -280,8 +280,8 @@ for data in dataset3.create_dict_iterator(): 输出结果如下: ``` -{'data1': Tensor(shape=[3], dtype=int64, value= [0, 0, 0])} -{'data1': Tensor(shape=[3], dtype=int64, value= [0, 0, 0])} -{'data1': Tensor(shape=[3], dtype=int64, value= [1, 2, 3])} -{'data1': Tensor(shape=[3], dtype=int64, value= [1, 2, 3])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [0, 0, 0])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} +{'data1': Tensor(shape=[3], dtype=Int64, value= [1, 2, 3])} ``` diff --git a/docs/programming_guide/source_zh_cn/sampler.md b/docs/programming_guide/source_zh_cn/sampler.md index 54f4fc50d9..4c6ccbca2f 100644 --- a/docs/programming_guide/source_zh_cn/sampler.md +++ b/docs/programming_guide/source_zh_cn/sampler.md @@ -207,9 +207,9 @@ for data in dataset.create_dict_iterator(): 输出结果如下: ``` -{'data': array(0, dtype=int64)} -{'data': array(3, dtype=int64)} -{'data': array(6, dtype=int64)} +{'data': Tensor(shape=[], dtype=Int64, value= 0)} +{'data': Tensor(shape=[], dtype=Int64, value= 3)} +{'data': Tensor(shape=[], dtype=Int64, value= 6)} ``` ## 自定义采样器 -- Gitee From 08cff83e292216d2b3516ba702eb9af3fc2d41c2 Mon Sep 17 00:00:00 2001 From: wangmin Date: Thu, 17 Sep 2020 16:05:48 +0800 Subject: [PATCH 061/100] update second order optimizer tutorial --- .../training/source_en/advanced_use/cv.rst | 3 +- .../cv_resnet50_second_order_optimizer.md | 474 ++++++++++++++++++ .../cv_resnet50_second_order_optimizer.md | 21 +- 3 files changed, 488 insertions(+), 10 deletions(-) create mode 100644 tutorials/training/source_en/advanced_use/cv_resnet50_second_order_optimizer.md diff --git a/tutorials/training/source_en/advanced_use/cv.rst b/tutorials/training/source_en/advanced_use/cv.rst index 3a00c3a8b2..868eaec5c6 100644 --- a/tutorials/training/source_en/advanced_use/cv.rst +++ b/tutorials/training/source_en/advanced_use/cv.rst @@ -4,4 +4,5 @@ Computer Vision .. toctree:: :maxdepth: 1 - cv_resnet50 \ No newline at end of file + cv_resnet50 + cv_resnet50_second_order_optimizer \ No newline at end of file diff --git a/tutorials/training/source_en/advanced_use/cv_resnet50_second_order_optimizer.md b/tutorials/training/source_en/advanced_use/cv_resnet50_second_order_optimizer.md new file mode 100644 index 0000000000..985f158963 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/cv_resnet50_second_order_optimizer.md @@ -0,0 +1,474 @@ +# ResNet-50 Second-Order Optimization Practice + +`Linux` `Ascend` `GPU` `Model Development` `Model Optimization` `Expert` + + + +- [ResNet-50 Second-Order Optimization Practice](#resnet-50-second-order-optimization-practice) + - [Overview](#overview) + - [Preparation](#preparation) + - [Preparing the Dataset](#preparing-the-dataset) + - [Configuring Distributed Environment Variables](#configuring-distributed-environment-variables) + - [Ascend 910](#ascend-910) + - [GPU](#gpu) + - [Loading the Dataset](#loading-the-dataset) + - [Defining the Network](#defining-the-network) + - [Defining the Loss Function and Optimizer THOR](#defining-the-loss-function-and-optimizer-thor) + - [Defining the Loss Function](#defining-the-loss-function) + - [Defining the Optimizer](#defining-the-optimizer) + - [Training the Network](#training-the-network) + - [Saving the Configured Model](#saving-the-configured-model) + - [Configuring the Network Training](#configuring-the-network-training) + - [Running the Script](#running-the-script) + - [Ascend 910](#ascend-910-1) + - [GPU](#gpu-1) + - [Model Inference](#model-inference) + - [Defining the Inference Network](#defining-the-inference-network) + - [Inference](#inference) + - [Ascend 910](#ascend-910-2) + - [GPU](#gpu-2) + + +   + +## Overview + +Common optimization algorithms are classified into the first-order and the second-order optimization algorithms. Typical first-order optimization algorithms, such as stochastic gradient descent (SGD), support a small amount of computation with high computation speed but a low convergence speed and require a large number of training steps. The second-order optimization algorithms use the second-order derivative of the objective function to accelerate convergence to the optimal value of a model, and require a small quantity of training steps. However, the second-order optimization algorithms have excessively high computation costs, an overall execution time of the second-order optimization algorithms is still slower than that of the first-order optimization algorithms. As a result, the second-order optimization algorithms are not widely used in deep neural network training. The main computation costs of the second-order optimization algorithms lie in the inverse operation of the second-order information matrices such as the Hessian matrix and the [Fisher information matrix (FIM)](https://arxiv.org/pdf/1808.07172.pdf). The time complexity is about $O(n^3)$. + +Based on the existing natural gradient algorithm, MindSpore development team uses optimized acceleration methods such as approximation and sharding for the FIM, greatly reducing the computation complexity of the inverse matrix and developing the available second-order optimizer THOR. With eight Ascend 910 AI processors, THOR can complete the training of ResNet-50 v1.5 network and ImageNet dataset within 72 minutes, which is nearly twice the speed of SGD+Momentum. + + +This tutorial describes how to use the second-order optimizer THOR provided by MindSpore to train the ResNet-50 v1.5 network and ImageNet dataset on Ascend 910 and GPU. +> Download address of the complete code example: + + +Directory Structure of Code Examples + +```shell +├── resnet_thor + ├── README.md + ├── scripts + ├── run_distribute_train.sh # launch distributed training for Ascend 910 + └── run_eval.sh # launch inference for Ascend 910 + ├── run_distribute_train_gpu.sh # launch distributed training for GPU + └── run_eval_gpu.sh # launch inference for GPU + ├── src + ├── crossentropy.py # CrossEntropy loss function + ├── config.py # parameter configuration + ├── dataset_helper.py # dataset helper for minddata dataset + ├── grad_reducer_thor.py # grad reduce for thor + ├── model_thor.py # model for train + ├── resnet_thor.py # resnet50_thor backone + ├── thor.py # thor optimizer + ├── thor_layer.py # thor layer + └── dataset.py # data preprocessing + ├── eval.py # infer script + └── train.py # train script + +``` + +The overall execution process is as follows: +1. Prepare the ImageNet dataset and process the required dataset. +2. Define the ResNet-50 network. +3. Define the loss function and the optimizer THOR. +4. Load the dataset and perform training. After the training is complete, check the result and save the model file. +5. Load the saved model for inference. + + +## Preparation + +Ensure that MindSpore has been correctly installed. If not, install it by referring to [Install](https://www.mindspore.cn/install/en). + +### Preparing the Dataset + +Download the complete ImageNet2012 dataset, decompress the dataset, and save it to the `ImageNet2012/ilsvrc` and `ImageNet2012/ilsvrc_eval` directories in the local workspace. + +The directory structure is as follows: + +``` +└─ImageNet2012 + ├─ilsvrc + │ n03676483 + │ n04067472 + │ n01622779 + │ ...... + └─ilsvrc_eval + │ n03018349 + │ n02504013 + │ n07871810 + │ ...... + +``` +### Configuring Distributed Environment Variables +#### Ascend 910 +For details about how to configure the distributed environment variables of Ascend 910 AI processors, see [Parallel Distributed Training (Ascend)](https://www.mindspore.cn/tutorial/en/master/advanced_use/distributed_training_ascend.html#id4). + +#### GPU +For details about how to configure the distributed environment of GPUs, see [Parallel Distributed Training (GPU)](https://www.mindspore.cn/tutorial/en/master/advanced_use/distributed_training_gpu.html#id4). + + +## Loading the Dataset + +During distributed training, load the dataset in parallel mode and process it through the data argumentation API provided by MindSpore. The `src/dataset.py` script in the source code is for loading and processing the dataset. +```python +import os +import mindspore.common.dtype as mstype +import mindspore.dataset.engine as de +import mindspore.dataset.transforms.vision.c_transforms as C +import mindspore.dataset.transforms.c_transforms as C2 +from mindspore.communication.management import init, get_rank, get_group_size + +def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, target="Ascend"): + if target == "Ascend": + device_num, rank_id = _get_rank_info() + else: + init() + rank_id = get_rank() + device_num = get_group_size() + if device_num == 1: + ds = de.ImageFolderDatasetV2(dataset_path, num_parallel_workers=8, shuffle=True) + else: + ds = de.ImageFolderDatasetV2(dataset_path, num_parallel_workers=8, shuffle=True, + num_shards=device_num, shard_id=rank_id) + + image_size = 224 + mean = [0.485 * 255, 0.456 * 255, 0.406 * 255] + std = [0.229 * 255, 0.224 * 255, 0.225 * 255] + # define map operations + if do_train: + trans = [ + C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)), + C.RandomHorizontalFlip(prob=0.5), + C.Normalize(mean=mean, std=std), + C.HWC2CHW() + ] + else: + trans = [ + C.Decode(), + C.Resize(256), + C.CenterCrop(image_size), + C.Normalize(mean=mean, std=std), + C.HWC2CHW() + ] + type_cast_op = C2.TypeCast(mstype.int32) + ds = ds.map(input_columns="image", num_parallel_workers=8, operations=trans) + ds = ds.map(input_columns="label", num_parallel_workers=8, operations=type_cast_op) + + # apply batch operations + ds = ds.batch(batch_size, drop_remainder=True) + + # apply dataset repeat operation + ds = ds.repeat(repeat_num) + + return ds +``` + +> MindSpore supports multiple data processing and augmentation operations, which are usually combined. For details, see [Data Processing and Augmentation](https://www.mindspore.cn/tutorial/en/master/use/data_preparation/data_processing_and_augmentation.html). + + +## Defining the Network +Use the ResNet-50 v1.5 network model as an example. Define the [ResNet-50 network](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/resnet/src/resnet.py), and replace the `Conv2d` and `Dense` operators with the operators customized by the second-order optimizer. + The defined network model stores in the `src/resnet_thor.py` script in the source code, and the customized operators `Conv2d_thor` and `Dense_thor` store in the `src/thor_layer.py` script. + +- Use `Conv2d_thor` to replace `Conv2d` in the original network model. +- Use `Dense_thor` to replace `Dense` in the original network model. + +> The `Conv2d_thor` and `Dense_thor` operators customized by THOR are used to save the second-order matrix information in model training. The backbone of the newly defined network is the same as that of the original network model. + +After the network is built, call the defined ResNet-50 in the `__main__` function. +```python +... +from src.resnet_thor import resnet50 +... +if __name__ == "__main__": + ... + # define the net + net = resnet50(class_num=config.class_num, damping=damping, loss_scale=config.loss_scale, + frequency=config.frequency, batch_size=config.batch_size) + ... +``` + + +## Defining the Loss Function and Optimizer THOR + + +### Defining the Loss Function + +Loss functions supported by MindSpore include `SoftmaxCrossEntropyWithLogits`, `L1Loss`, and `MSELoss`. The `SoftmaxCrossEntropyWithLogits` loss function is required by THOR. + +The implementation procedure of the loss function is in the `src/crossentropy.py` script. A common trick in deep network model training, label smoothing, is used to improve the model tolerance to error label classification by smoothing real labels, thereby improving the model generalization capability. +```python +class CrossEntropy(_Loss): + """CrossEntropy""" + def __init__(self, smooth_factor=0., num_classes=1000): + super(CrossEntropy, self).__init__() + self.onehot = P.OneHot() + self.on_value = Tensor(1.0 - smooth_factor, mstype.float32) + self.off_value = Tensor(1.0 * smooth_factor / (num_classes - 1), mstype.float32) + self.ce = nn.SoftmaxCrossEntropyWithLogits() + self.mean = P.ReduceMean(False) + + def construct(self, logit, label): + one_hot_label = self.onehot(label, F.shape(logit)[1], self.on_value, self.off_value) + loss = self.ce(logit, one_hot_label) + loss = self.mean(loss, 0) + return loss +``` +Call the defined loss function in the `__main__` function. + +```python +... +from src.crossentropy import CrossEntropy +... +if __name__ == "__main__": + ... + # define the loss function + if not config.use_label_smooth: + config.label_smooth_factor = 0.0 + loss = CrossEntropy(smooth_factor=config.label_smooth_factor, num_classes=config.class_num) + ... +``` + +### Defining the Optimizer + +The parameter update formula of THOR is as follows: + +$$ \theta^{t+1} = \theta^t + \alpha F^{-1}\nabla E$$ + +The meanings of parameters in the formula are as follows: +- $\theta$: trainable parameters on the network +- $t$: number of training steps +- $\alpha$: learning rate, which is the parameter update value per step +- $F^{-1}$: FIM obtained from the network computation +- $\nabla E$: the first-order gradient value + +As shown in the parameter update formula, THOR needs to additionally compute an FIM of each layer, and the FIM of each layer is obtained through computation in the customized network model. The FIM can adaptively adjust the parameter update step and direction of each layer, accelerating convergence and reducing parameter optimization complexity. + +```python +... +if args_opt.device_target == "Ascend": + from src.thor import THOR +else: + from src.thor import THOR_GPU as THOR +... + +if __name__ == "__main__": + ... + # learning rate setting + lr = get_model_lr(0, config.lr_init, config.lr_decay, config.lr_end_epoch, step_size, decay_epochs=39) + # define the optimizer + opt = THOR(filter(lambda x: x.requires_grad, net.get_parameters()), Tensor(lr), config.momentum, + filter(lambda x: 'matrix_A' in x.name, net.get_parameters()), + filter(lambda x: 'matrix_G' in x.name, net.get_parameters()), + filter(lambda x: 'A_inv_max' in x.name, net.get_parameters()), + filter(lambda x: 'G_inv_max' in x.name, net.get_parameters()), + config.weight_decay, config.loss_scale) + ... +``` + +## Training the Network + +### Saving the Configured Model + +MindSpore provides the callback mechanism to execute customized logic during training. The `ModelCheckpoint` function provided by the framework is used in this example. +`ModelCheckpoint` can save the network model and parameters for subsequent fine-tuning. +`TimeMonitor` and `LossMonitor` are callback functions provided by MindSpore. They can be used to monitor the single training step time and `loss` value changes during training, respectively. + +```python +... +from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, TimeMonitor, LossMonitor +... +if __name__ == "__main__": + ... + # define callbacks + time_cb = TimeMonitor(data_size=step_size) + loss_cb = LossMonitor() + cb = [time_cb, loss_cb] + if config.save_checkpoint: + config_ck = CheckpointConfig(save_checkpoint_steps=config.save_checkpoint_epochs * step_size, + keep_checkpoint_max=config.keep_checkpoint_max) + ckpt_cb = ModelCheckpoint(prefix="resnet", directory=ckpt_save_dir, config=config_ck) + cb += [ckpt_cb] + ... +``` + +### Configuring the Network Training + +Use the `model.train` API provided by MindSpore to easily train the network. THOR reduces the computation workload and improves the computation speed by reducing the frequency of updating the second-order matrix. Therefore, the Model_Thor class is redefined to inherit the Model class provided by MindSpore. The parameter for controlling the frequency of updating the second-order matrix is added to the Model_Thor class. You can adjust this parameter to optimize the overall performance. + + +```python +... +from mindspore.train.loss_scale_manager import FixedLossScaleManager +from src.model_thor import Model_Thor as Model +... + +if __name__ == "__main__": + ... + loss_scale = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False) + if target == "Ascend": + model = Model(net, loss_fn=loss, optimizer=opt, amp_level='O2', loss_scale_manager=loss_scale, + keep_batchnorm_fp32=False, metrics={'acc'}, frequency=config.frequency) + else: + model = Model(net, loss_fn=loss, optimizer=opt, loss_scale_manager=loss_scale, metrics={'acc'}, + amp_level="O2", keep_batchnorm_fp32=True, frequency=config.frequency) + ... +``` + +### Running the Script +After the training script is defined, call the shell script in the `scripts` directory to start the distributed training process. +#### Ascend 910 +Currently, MindSpore distributed execution on Ascend uses the single-device single-process running mode. That is, one process runs on a device, and the number of total processes is the same as the number of devices that are being used. For device 0, the corresponding process is executed in the foreground. For other devices, the corresponding processes are executed in the background. Create a directory named `train_parallel`+`device_id` for each process to store log information, operator compilation information, and training checkpoint files. The following takes the distributed training script for eight devices as an example to describe how to run the script: + +Run the script. +``` +sh run_distribute_train.sh [RANK_TABLE_FILE] [DATASET_PATH] [DEVICE_NUM] +``` +Variables `RANK_TABLE_FILE`, `DATASET_PATH`, and `DEVICE_NUM` need to be transferred to the script. The meanings of variables are as follows: +- `RANK_TABLE_FILE`: path for storing the networking information file +- `DATASET_PATH`: training dataset path +- `DEVICE_NUM`: the actual number of running devices. +For details about other environment variables, see configuration items in the installation guide. + +The following is an example of loss values output during training: + +```bash +... +epoch: 1 step: 5004, loss is 4.4182425 +epoch: 2 step: 5004, loss is 3.740064 +epoch: 3 step: 5004, loss is 4.0546017 +epoch: 4 step: 5004, loss is 3.7598825 +epoch: 5 step: 5004, loss is 3.3744206 +... +epoch: 40 step: 5004, loss is 1.6907625 +epoch: 41 step: 5004, loss is 1.8217756 +epoch: 42 step: 5004, loss is 1.6453942 +... +``` + +After the training is complete, the checkpoint file generated by each device is stored in the training directory. The following is an example of the checkpoint file generated by `device_0`: + +```bash +└─train_parallel0 + ├─resnet-1_5004.ckpt + ├─resnet-2_5004.ckpt + │ ...... + ├─resnet-42_5004.ckpt + │ ...... +``` + +In the preceding information, +`*.ckpt` indicates the saved model parameter file. The name of a checkpoint file is in the following format: *Network name*-*Number of epochs*_*Number of steps*.ckpt. + +#### GPU +On the GPU hardware platform, MindSpore uses `mpirun` of OpenMPI to perform distributed training. The process creates a directory named `train_parallel` to store log information and training checkpoint files. The following takes the distributed training script for eight devices as an example to describe how to run the script: +``` +sh run_distribute_train_gpu.sh [DATASET_PATH] [DEVICE_NUM] +``` +Variables `DATASET_PATH` and `DEVICE_NUM` need to be transferred to the script. The meanings of variables are as follows: +- `DATASET_PATH`: training dataset path +- `DEVICE_NUM`: the actual number of running devices + +During GPU-based training, the `DEVICE_ID` environment variable is not required. Therefore, you do not need to call `int(os.getenv('DEVICE_ID'))` in the main training script to obtain the device ID or transfer `device_id` to `context`. You need to set `device_target` to `GPU` and call `init()` to enable the NCCL. + +The following is an example of loss values output during training: +```bash +... +epoch: 1 step: 5004, loss is 4.2546034 +epoch: 2 step: 5004, loss is 4.0819564 +epoch: 3 step: 5004, loss is 3.7005644 +epoch: 4 step: 5004, loss is 3.2668946 +epoch: 5 step: 5004, loss is 3.023509 +... +epoch: 36 step: 5004, loss is 1.645802 +... +``` + +The following is an example of model files saved after training: + +```bash +└─train_parallel + ├─ckpt_0 + ├─resnet-1_5004.ckpt + ├─resnet-2_5004.ckpt + │ ...... + ├─resnet-36_5004.ckpt + │ ...... + ...... + ├─ckpt_7 + ├─resnet-1_5004.ckpt + ├─resnet-2_5004.ckpt + │ ...... + ├─resnet-36_5004.ckpt + │ ...... +``` + +## Model Inference + +Use the checkpoint files saved during training to perform inference and validate the model generalization capability. Load the model file using the `load_checkpoint` API, call the `eval` API of the `Model` to predict the input image class, and compare the predicted class with the actual class of the input image to obtain the final prediction accuracy. + +### Defining the Inference Network + +1. Use the `load_checkpoint` API to load the model file. +2. Use the `model.eval` API to read the test dataset for inference. +3. Compute the prediction accuracy. + +```python +... +from mindspore.train.serialization import load_checkpoint, load_param_into_net +... + +if __name__ == "__main__": + ... + # define net + net = resnet(class_num=config.class_num) + net.add_flags_recursive(thor=False) + + # load checkpoint + param_dict = load_checkpoint(args_opt.checkpoint_path) + keys = list(param_dict.keys()) + for key in keys: + if "damping" in key: + param_dict.pop(key) + load_param_into_net(net, param_dict) + net.set_train(False) + + # define model + model = Model(net, loss_fn=loss, metrics={'top_1_accuracy', 'top_5_accuracy'}) + + # eval model + res = model.eval(dataset) + print("result:", res, "ckpt=", args_opt.checkpoint_path) +``` + +### Inference +After the inference network is defined, the shell script in the `scripts` directory is called for inference. +#### Ascend 910 +On the Ascend 910 hardware platform, run the following inference command: +``` +sh run_eval.sh [DATASET_PATH] [CHECKPOINT_PATH] +``` +Variables `DATASET_PATH` and `CHECKPOINT_PATH` need to be transferred to the script. The meanings of variables are as follows: +- `DATASET_PATH`: inference dataset path +- `CHECKPOINT_PATH`: path for storing the checkpoint file + +Currently, a single device (device 0 by default) is used for inference. The inference result is as follows: +``` +result: {'top_5_accuracy': 0.9295574583866837, 'top_1_accuracy': 0.761443661971831} ckpt=train_parallel0/resnet-42_5004.ckpt +``` +- `top_5_accuracy`: For an input image, if the labels whose prediction probability ranks top 5 contain actual labels, the classification is correct. +- `top_1_accuracy`: For an input image, if the label with the highest prediction probability is the same as the actual label, the classification is correct. +#### GPU + +On the GPU hardware platform, run the following inference command: +``` +sh run_eval_gpu.sh [DATASET_PATH] [CHECKPOINT_PATH] +``` +Variables `DATASET_PATH` and `CHECKPOINT_PATH` need to be transferred to the script. The meanings of variables are as follows: +- `DATASET_PATH`: inference dataset path +- `CHECKPOINT_PATH`: path for storing the checkpoint file + +The inference result is as follows: +``` +result: {'top_5_accuracy': 0.9287972151088348, 'top_1_accuracy': 0.7597031049935979} ckpt=train_parallel/resnet-36_5004.ckpt +``` \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md b/tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md index 0d2dfcd4b2..9d8229463f 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md +++ b/tutorials/training/source_zh_cn/advanced_use/cv_resnet50_second_order_optimizer.md @@ -43,7 +43,7 @@ MindSpore开发团队在现有的自然梯度算法的基础上,对FIM矩阵 > 你可以在这里下载完整的示例代码: 。 -### 示例代码目录结构 +示例代码目录结构 ```shell ├── resnet_thor @@ -89,12 +89,12 @@ MindSpore开发团队在现有的自然梯度算法的基础上,对FIM矩阵 ``` └─ImageNet2012 ├─ilsvrc - │ n03676483/ - │ n04067472/ - │ n01622779/ + │ n03676483 + │ n04067472 + │ n01622779 │ ...... └─ilsvrc_eval - │ n03018349/ + │ n03018349 │ n02504013 │ n07871810 │ ...... @@ -181,7 +181,7 @@ def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, target=" ... from src.resnet_thor import resnet50 ... -f __name__ == "__main__": +if __name__ == "__main__": ... # define the net net = resnet50(class_num=config.class_num, damping=damping, loss_scale=config.loss_scale, @@ -340,7 +340,7 @@ epoch: 2 step: 5004, loss is 3.740064 epoch: 3 step: 5004, loss is 4.0546017 epoch: 4 step: 5004, loss is 3.7598825 epoch: 5 step: 5004, loss is 3.3744206 -...... +... epoch: 40 step: 5004, loss is 1.6907625 epoch: 41 step: 5004, loss is 1.8217756 epoch: 42 step: 5004, loss is 1.6453942 @@ -355,6 +355,7 @@ epoch: 42 step: 5004, loss is 1.6453942 ├─resnet-2_5004.ckpt │ ...... ├─resnet-42_5004.ckpt + │ ...... ``` 其中, @@ -379,7 +380,7 @@ epoch: 2 step: 5004, loss is 4.0819564 epoch: 3 step: 5004, loss is 3.7005644 epoch: 4 step: 5004, loss is 3.2668946 epoch: 5 step: 5004, loss is 3.023509 -...... +... epoch: 36 step: 5004, loss is 1.645802 ... ``` @@ -393,12 +394,14 @@ epoch: 36 step: 5004, loss is 1.645802 ├─resnet-2_5004.ckpt │ ...... ├─resnet-36_5004.ckpt - ...... + │ ...... + ...... ├─ckpt_7 ├─resnet-1_5004.ckpt ├─resnet-2_5004.ckpt │ ...... ├─resnet-36_5004.ckpt + │ ...... ``` -- Gitee From cba2d74a3b6a0fc0de9c36cfa74e4ddd0b6d6961 Mon Sep 17 00:00:00 2001 From: cjh9368 Date: Thu, 17 Sep 2020 17:08:07 +0800 Subject: [PATCH 062/100] bug fix --- tutorials/lite/source_en/use/benchmark_tool.md | 8 +------- tutorials/lite/source_en/use/converter_tool.md | 6 +++--- tutorials/lite/source_zh_cn/use/benchmark_tool.md | 8 +------- tutorials/lite/source_zh_cn/use/converter_tool.md | 6 +++--- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/tutorials/lite/source_en/use/benchmark_tool.md b/tutorials/lite/source_en/use/benchmark_tool.md index 000e270c60..0dff307989 100644 --- a/tutorials/lite/source_en/use/benchmark_tool.md +++ b/tutorials/lite/source_en/use/benchmark_tool.md @@ -64,12 +64,6 @@ Mean bias of all nodes: 0% ``` -When the origin model's input or output data type is uint8, they needs to be reduced by 128 and converted to int8 type before it can be used as benchmark data to verify accuracy. And when the output data type is INT8, you need to specify calibDataType as INT8 in the parameter. - -```bash -./benchmark --modelPath=./models/test_benchmark_int8.ms --inDataPath=./input/test_benchmark_int8.bin --device=CPU --accuracyThreshold=3 --calibDataPath=./output/test_benchmark_int8.out --calibDataType=INT8 -``` - ## Parameter Description The command used for benchmark testing based on the compiled Benchmark tool is as follows: @@ -90,7 +84,7 @@ The following describes the parameters in detail. | `--modelPath=` | Mandatory | Specifies the file path of the MindSpore Lite model for benchmark testing. | String | Null | - | | `--accuracyThreshold=` | Optional | Specifies the accuracy threshold. | Float | 0.5 | - | | `--calibDataPath=` | Optional | Specifies the file path of the benchmark data. The benchmark data, as the comparison output of the tested model, is output from the forward inference of the tested model under other deep learning frameworks using the same input. | String | Null | - | -| `--calibDataType=` | Optional | Specifies the calibration data type. | String | FLOAT | FLOAT or INT8 | +| `--calibDataType=` | Optional | Specifies the calibration data type. | String | FLOAT | UINT8, FLOAT or INT8 | | `--cpuBindMode=` | Optional | Specifies the type of the CPU core bound to the model inference program. | Integer | 1 | −1: medium core
      1: large core
      0: not bound | | `--device=` | Optional | Specifies the type of the device on which the model inference program runs. | String | CPU | CPU or GPU | | `--help` | Optional | Displays the help information about the `benchmark` command. | - | - | - | diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index 9075adc364..5b157ed55f 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -101,12 +101,12 @@ The following describes the parameters in detail. | Parameter | Mandatory or Not | Parameter Description | Value Range | Default Value | | -------- | ------- | ----- | --- | ---- | | `--help` | No | Prints all help information. | - | - | -| `--fmk=` | Yes | Original format of the input model. | MS, CAFFE, TFLITE, or ONNX | - | +| `--fmk=` | Yes | Original format of the input model. | MINDIR, CAFFE, TFLITE, or ONNX | - | | `--modelFile=` | Yes | Path of the input model. | - | - | | `--outputFile=` | Yes | Path of the output model. (If the path does not exist, a directory will be automatically created.) The suffix `.ms` can be automatically generated. | - | - | | `--weightFile=` | Yes (for Caffe models only) | Path of the weight file of the input model. | - | - | | `--quantType=` | No | Sets the quant type of the model. | PostTraining: quantization after training
      AwareTraining: perceptual quantization | - | -|`--inferenceType= `| No(supported by aware quant models only) | Sets the input and output data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the output data type is same as the input of origin model. | SAME FLOAT or INT8 | SAME | +|`--inferenceType= `| No(supported by aware quant models only) | Sets the input and output data type of the converted model. If the type is different from the origin model, the convert tool will insert data type convert op before the model to make sure the output data type is same as the input of origin model. | UINT8, FLOAT or INT8 | FLOAT | |`--stdDev=`| No(supported by aware quant models only) | Sets the standard deviation of the input data. | (0,+∞) | 128 | |`--mean=`| No(supported by aware quant models only) | Sets the mean value of the input data. | [-128, 127] | -0.5 | @@ -152,7 +152,7 @@ Several common examples are selected below to illustrate the use of conversion c - MindSpore model `model.mindir` ```bash - call converter_lite --fmk=MS --modelFile=model.mindir --outputFile=model + call converter_lite --fmk=MINDIR --modelFile=model.mindir --outputFile=model ``` - TensorFlow Lite model`model.tflite` diff --git a/tutorials/lite/source_zh_cn/use/benchmark_tool.md b/tutorials/lite/source_zh_cn/use/benchmark_tool.md index 7caaad2e63..69d329a086 100644 --- a/tutorials/lite/source_zh_cn/use/benchmark_tool.md +++ b/tutorials/lite/source_zh_cn/use/benchmark_tool.md @@ -63,12 +63,6 @@ Mean bias of all nodes: 0% ======================================================= ``` -原模型输入输出数据类型为uint8时,需要将其减去128再转换为int8类型后才能作为标杆数据验证精度,输出数据类型为int8时需要在参数中指定calibDataType为INT8。 - -```bash -./benchmark --modelPath=./models/test_benchmark_int8.ms --inDataPath=./input/test_benchmark_int8.bin --device=CPU --accuracyThreshold=3 --calibDataPath=./output/test_benchmark_int8.out --calibDataType=INT8 -``` - ## 参数说明 @@ -90,7 +84,7 @@ Mean bias of all nodes: 0% | `--modelPath=` | 必选 | 指定需要进行基准测试的MindSpore Lite模型文件路径。 | String | null | - | | `--accuracyThreshold=` | 可选 | 指定准确度阈值。 | Float | 0.5 | - | | `--calibDataPath=` | 可选 | 指定标杆数据的文件路径。标杆数据作为该测试模型的对比输出,是该测试模型使用相同输入并由其它深度学习框架前向推理而来。 | String | null | - | -| `--calibDataType=` | 可选 | 指定标杆数据类型。 | String | FLOAT | FLOAT、INT8 | +| `--calibDataType=` | 可选 | 指定标杆数据类型。 | String | FLOAT | FLOAT、INT8、UINT8 | | `--cpuBindMode=` | 可选 | 指定模型推理程序运行时绑定的CPU核类型。 | Integer | 1 | -1:表示中核
      1:表示大核
      0:表示不绑定 | | `--device=` | 可选 | 指定模型推理程序运行的设备类型。 | String | CPU | CPU、GPU | | `--help` | 可选 | 显示`benchmark`命令的帮助信息。 | - | - | - | diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index ba77498100..682e996fe7 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -61,7 +61,7 @@ bash build.sh -I x86_64 - MindSpore模型`model.mindir` ```bash - ./converter_lite --fmk=MS --modelFile=model.mindir --outputFile=model + ./converter_lite --fmk=MINDIR --modelFile=model.mindir --outputFile=model ``` - TensorFlow Lite模型`model.tflite` @@ -102,12 +102,12 @@ MindSpore Lite模型转换工具提供了多种参数设置,用户可根据需 | 参数 | 是否必选 | 参数说明 | 取值范围 | 默认值 | | -------- | ------- | ----- | --- | ---- | | `--help` | 否 | 打印全部帮助信息。 | - | - | -| `--fmk=` | 是 | 输入模型的原始格式。 | MS、CAFFE、TFLITE、ONNX | - | +| `--fmk=` | 是 | 输入模型的原始格式。 | MINDIR、CAFFE、TFLITE、ONNX | - | | `--modelFile=` | 是 | 输入模型的路径。 | - | - | | `--outputFile=` | 是 | 输出模型的路径(不存在时将自动创建目录),不需加后缀,可自动生成`.ms`后缀。 | - | - | | `--weightFile=` | 转换Caffe模型时必选 | 输入模型weight文件的路径。 | - | - | | `--quantType=` | 否 | 设置模型的量化类型。 | PostTraining:训练后量化
      AwareTraining:感知量化。 | - | -|` --inferenceType=` | 否 | 设置感知量化模型输入输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inferenceType保持一致。 |SAME、 FLOAT、INT8 | SAME | +|` --inferenceType=` | 否 | 设置感知量化模型输入输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inferenceType保持一致。 | UINT8、FLOAT、INT8 | FLOAT | | `--stdDev= `| 否 | 感知量化模型转换时用于设置输入数据的标准差。 | (0,+∞) | 128 | | `--mean=` | 否 | 感知量化模型转换时用于设置输入数据的均值。 | [-128, 127] | -0.5 | -- Gitee From 25d439cfb3c8f3ea888f31109ba9241bd403c772 Mon Sep 17 00:00:00 2001 From: liyanliu Date: Thu, 17 Sep 2020 17:58:24 +0800 Subject: [PATCH 063/100] update hub tutorial readme --- .../source_en/advanced_use/hub_tutorial.md | 397 ++++++++++-------- .../source_zh_cn/advanced_use/hub_tutorial.md | 397 ++++++++++-------- 2 files changed, 433 insertions(+), 361 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/hub_tutorial.md b/tutorials/training/source_en/advanced_use/hub_tutorial.md index 963e0505d1..cbee7aced7 100644 --- a/tutorials/training/source_en/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_en/advanced_use/hub_tutorial.md @@ -1,181 +1,216 @@ -## Submitting, Loading and Fine-tuning Models using MindSpore Hub - -`Linux` `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 Compose -from PIL import Image -import mindspore.dataset.vision.py_transforms as py_transforms -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 = Compose([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) - ``` +## Submitting, Loading and Fine-tuning Models using MindSpore Hub + +`Linux` `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 + +MindSpore Hub is a pre-trained model application tool of the MindSpore ecosystem, which serves as a channel for model developers and application developers. It not only provides model developers with a convenient and fast channel for model submission, but also provides application developers with simple model loading and fine-tuning APIs. For model 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 model 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](https://gitee.com/mindspore/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). The location of the `mindspore_hub_conf.py` file is shown below: + + ```shell script + googlenet + ├── src + │   ├── googlenet.py + ├── script + │   ├── run_train.sh + ├── train.py + ├── test.py + ├── mindspore_hub_conf.py + ``` + +3. Create a `{model_name}_{model_version}_{dataset}.md` file in `hub/mshub_res/assets/mindspore/ascend/0.7` using this [template](https://gitee.com/mindspore/hub/blob/master/mshub_res/assets/mindspore/ascend/0.7/googlenet_v1_cifar10.md). Here `ascend` refers to the hardware platform for the pre-trained model, and `0.7` indicates the MindSpore version. The structure of the `hub/mshub_res` folder is as follows: + + ```shell script + hub + ├── mshub_res + │   ├── assets + │   ├── mindspore + | ├── gpu + | ├── 0.7 + | ├── ascend + | ├── 0.7 + | ├── googlenet_v1_cifar10.md + │   ├── tools + | ├── md_validator.py + | └── md_validator.py + ``` + + Note that it is required to fill in the `{model_name}_{model_version}_{dataset}.md` template by providing `file-format`、`asset-link` and `asset-sha256` below, which refers to the model file format, model storage location from step 1 and model hash value, respectively. The MindSpore Hub supports multiple model file formats including [MindSpore CKPT](https://www.mindspore.cn/tutorial/en/master/use/saving_and_loading_model_parameters.html#checkpoint-configuration-policies), [AIR](https://www.mindspore.cn/tutorial/en/master/use/multi_platform_inference.html), [MindIR](https://www.mindspore.cn/tutorial/en/master/use/saving_and_loading_model_parameters.html#export-mindir-model), [ONNX](https://www.mindspore.cn/tutorial/en/master/use/multi_platform_inference.html) and [MSLite](https://www.mindspore.cn/lite/tutorial/en/master/use/converter_tool.html). + + ```shell script + file-format: ckpt + asset-link: https://download.mindspore.cn/model_zoo/official/cv/googlenet/goolenet_ascend_0.2.0_cifar10_official_classification_20200713/googlenet.ckpt + asset-sha256: 114e5acc31dad444fa8ed2aafa02ca34734419f602b9299f3b53013dfc71b0f7 + ``` + For each pre-trained model, please run the following command to obtain a hash value required at `asset-sha256` of this `.md` file. Here the pre-trained model `googlenet.ckpt` is accessed from the storage location in step 1 and then saved in `tools` folder. The output hash value is: `114e5acc31dad444fa8ed2aafa02ca34734419f602b9299f3b53013dfc71b0f7`. + + ```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. The output is `All Passed`,which indicates that the format and content of the `.md` file meets the requirements. + + ```python + python md_validator.py ../assets/mindspore/ascend/0.7/googlenet_v1_cifar10.md + ``` + +5. Create a PR in `mindspore/hub` repo. See our [Contributor Wiki](https://gitee.com/mindspore/mindspore/blob/master/CONTRIBUTING.md) for more information about creating a PR. + +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. Please refer to [README](https://gitee.com/mindspore/hub/blob/master/mshub_res/README.md) for more information about model submission. + +### 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 model developer. The value of `include_top` is True or False, indicating whether to keep the top layer in the fully-connected network. + +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 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 + from mindspore import nn + + # 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. As is shown below, the new dataset used for fine-tuning is the garbage classification data located at `/ssd/data/garbage/train` folder. + + ```python + from src.dataset import create_dataset + from mindspore.train.serialization import 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" + 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) + ``` \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md index 0be1d8efee..65744ed3fc 100644 --- a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md @@ -1,180 +1,217 @@ -## 使用MindSpore Hub提交、加载和微调模型 - -`Linux` `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.py_transforms import Compose - from PIL import Image - import cv2 - import mindspore.dataset.vision.py_transforms as py_transforms - - 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 = Compose([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) - ``` +## 使用MindSpore Hub提交、加载和微调模型 + +`Linux` `Ascend` `GPU` `MindSpore Hub` `模型上传` `模型加载` `模型微调` `初级` `中级` `高级` + + + +- [使用MindSpore Hub提交、加载和微调模型](#使用MindSporeHub提交加载和微调模型) + - [概述](#概述) + - [模型上传](#模型上传) + - [步骤](#步骤) + - [模型加载](#模型加载) + - [模型微调](#模型微调) + + + + + +### 概述 + +MindSpore Hub是MindSpore生态的预训练模型应用工具,作为模型开发者和应用开发者的管道,它不仅向模型开发者提供了方便快捷的模型发布通道,而且向应用开发者提供了简单易用的模型加载和微调API。本教程以GoogleNet为例,对想要将模型发布到MindSpore Hub的模型开发者介绍了模型上传步骤,也对想要使用MindSpore Hub模型进行推理或者微调的应用开发者描述了具体操作流程。总之,本教程可以帮助模型开发者有效地提交模型,并使得应用开发者利用MindSpore Hub的接口快速实现模型推理或微调。 + +### 模型上传 + +我们接收用户通过向 [hub](https://gitee.com/mindspore/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`,文件放置的位置如下: + + ```shell script + googlenet + ├── src + │   ├── googlenet.py + ├── script + │   ├── run_train.sh + ├── train.py + ├── test.py + ├── mindspore_hub_conf.py + ``` + +3. 按照 [模板](https://gitee.com/mindspore/hub/blob/master/mshub_res/assets/mindspore/ascend/0.7/googlenet_v1_cifar10.md) 在 `hub/mshub_res/assets/mindspore/ascend/0.7` 文件夹下创建`{model_name}_{model_version}_{dataset}.md` 文件,其中 `ascend` 为模型运行的硬件平台,`0.7` 为MindSpore的版本号,`hub/mshub_res`的目录结构为: + + ```shell script + hub + ├── mshub_res + │   ├── assets + │   ├── mindspore + | ├── gpu + | ├── 0.7 + | ├── ascend + | ├── 0.7 + | ├── googlenet_v1_cifar10.md + │   ├── tools + | ├── md_validator.py + | └── md_validator.py + ``` + 注意,`{model_name}_{model_version}_{dataset}.md` 文件中需要补充如下所示的 `file-format`、`asset-link` 和 `asset-sha256` 信息,它们分别表示模型文件格式、模型存储位置(步骤1所得)和模型哈希值,其中MindSpore Hub支持的模型文件格式有 [MindSpore CKPT](https://www.mindspore.cn/tutorial/zh-CN/master/use/saving_and_loading_model_parameters.html#checkpoint-configuration-policies),[AIR](https://www.mindspore.cn/tutorial/zh-CN/master/use/multi_platform_inference.html),[MindIR](https://www.mindspore.cn/tutorial/zh-CN/master/use/saving_and_loading_model_parameters.html#export-mindir-model),[ONNX](https://www.mindspore.cn/tutorial/zh-CN/master/use/multi_platform_inference.html) 和 [MSLite](https://www.mindspore.cn/lite/tutorial/zh-CN/master/use/converter_tool.html)。 + + ```shell script + file-format: ckpt + asset-link: https://download.mindspore.cn/model_zoo/official/cv/googlenet/goolenet_ascend_0.2.0_cifar10_official_classification_20200713/googlenet.ckpt + asset-sha256: 114e5acc31dad444fa8ed2aafa02ca34734419f602b9299f3b53013dfc71b0f7 + ``` + + 对于每个预训练模型,执行以下命令,用来获得`.md` 文件 `asset-sha256` 处所需的哈希值,其中 `googlenet.ckpt` 是从步骤1的存储位置处下载并保存到 `tools` 文件夹的预训练模型,运行后输出的哈希值为 `114e5acc31dad444fa8ed2aafa02ca34734419f602b9299f3b53013dfc71b0f7`。 + + ```python + cd /hub/mshub_res/tools + python get_sha256.py ../googlenet.ckpt + ``` + +4. 使用 `hub/mshub_res/tools/md_validator.py` 在本地核对`.md`文件的格式,执行以下命令,输出结果为 `All Passed`,表示 `.md` 文件的格式和内容均符合要求。 + + ```python + python md_validator.py ../assets/mindspore/ascend/0.7/googlenet_v1_cifar10.md + ``` + +5. 在 `mindspore/hub` 仓创建PR,详细创建方式可以参考[贡献者Wiki](https://gitee.com/mindspore/mindspore/blob/master/CONTRIBUTING.md)。 + +一旦你的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.py_transforms import Compose + from PIL import Image + import cv2 + import mindspore.dataset.vision.py_transforms as py_transforms + + context.set_context(mode=context.GRAPH_MODE, + device_target="Ascend", + device_id=0) + + model = "mindspore/ascend/0.7/googlenet_v1_cifar10" + + # Test an image from CIFAR-10 dataset + image = Image.open('cifar10/a.jpg') + transforms = Compose([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)添加到模型构造中时,可以在模型的详情页中找到这个功能。`include_top` 取值为True或者False,表示是否保留顶层的全连接网络。* + +下面我们以GoogleNet为例,说明如何加载一个基于ImageNet的预训练模型,并在特定的子任务数据集上进行迁移学习(重训练)。主要的步骤如下: + +1. 在MindSpore Hub的官网上搜索感兴趣的模型,并从网站上获取特定的 `url`。 + +2. 使用 `url`进行MindSpore Hub模型的加载,*注意:`include_top` 参数需要模型开发者提供*。 + + ```python + import mindspore + 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 + from mindspore import nn + + # 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 = 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. 构建数据集,开始重训练。如下所示,进行微调任务的数据集为垃圾分类数据集,存储位置为 `/ssd/data/garbage/train`。 + + ```python + from src.dataset import create_dataset + from mindspore.train.serialization import 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" + 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) + ``` \ No newline at end of file -- Gitee From 79207884ba0375650c9fa1b55efb058fb0f4a55f Mon Sep 17 00:00:00 2001 From: hukang hwx963878 Date: Thu, 17 Sep 2020 18:52:22 +0800 Subject: [PATCH 064/100] =?UTF-8?q?=E4=BF=AE=E6=94=B9r1.0=E5=88=86?= =?UTF-8?q?=E6=94=AF=E7=9A=84quick=5Fstart,=E8=BF=9E=E6=8E=A5=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=94=B1=E5=8E=9F=E6=9D=A50.7=E6=94=B9=E4=B8=BA1.0?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tutorials/lite/source_en/quick_start/quick_start.md | 4 ++-- tutorials/lite/source_zh_cn/quick_start/quick_start.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tutorials/lite/source_en/quick_start/quick_start.md b/tutorials/lite/source_en/quick_start/quick_start.md index f76a8f21a0..7e2f918c11 100644 --- a/tutorials/lite/source_en/quick_start/quick_start.md +++ b/tutorials/lite/source_en/quick_start/quick_start.md @@ -109,7 +109,7 @@ app │ | └── MindSporeNetnative.h # header file │ | │ ├── java # application code at the Java layer -│ │ └── com.huawei.himindsporedemo +│ │ └── com.mindspore.himindsporedemo │ │ ├── gallery.classify # implementation related to image processing and MindSpore JNI calling │ │ │ └── ... │ │ └── widget # implementation related to camera enabling and drawing @@ -183,7 +183,7 @@ In this example, the download.gradle File configuration auto download MindSpor Note: if the automatic download fails, please manually download the relevant library files and put them in the corresponding location. -MindSpore Lite version [MindSpore Lite version]( https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/libmindspore-lite.so) +MindSpore Lite version [MindSpore Lite version](https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%201.0/mindspore-lite-1.0.0-minddata-arm64-cpu.tar.gz) ### Downloading and Deploying a Model File diff --git a/tutorials/lite/source_zh_cn/quick_start/quick_start.md b/tutorials/lite/source_zh_cn/quick_start/quick_start.md index 974d38de10..933bb46528 100644 --- a/tutorials/lite/source_zh_cn/quick_start/quick_start.md +++ b/tutorials/lite/source_zh_cn/quick_start/quick_start.md @@ -114,7 +114,7 @@ app | | └── MsNetWork.cpp # MindSpore接口封装 │ | │ ├── java # java层应用代码 -│ │ └── com.huawei.himindsporedemo +│ │ └── com.mindspore.himindsporedemo │ │ ├── gallery.classify # 图像处理及MindSpore JNI调用相关实现 │ │ │ └── ... │ │ └── widget # 开启摄像头及绘制相关实现 @@ -138,7 +138,7 @@ Android JNI层调用MindSpore C++ API时,需要相关库文件支持。可通 注: 若自动下载失败,请手动下载相关库文件并将其放在对应位置: -MindSpore Lite版本 [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%200.7/libmindspore-lite.so) +MindSpore Lite版本 [下载链接](https://download.mindspore.cn/model_zoo/official/lite/lib/mindspore%20version%201.0/mindspore-lite-1.0.0-minddata-arm64-cpu.tar.gz) ``` android{ -- Gitee From d860c7d25c1ac577b6e46a692a429e6d401d68be Mon Sep 17 00:00:00 2001 From: xiefangqi Date: Thu, 17 Sep 2020 19:20:10 +0800 Subject: [PATCH 065/100] minddata interface change r1.0 --- docs/programming_guide/source_zh_cn/dataset_conversion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index 5c5dd760aa..dd0a6e097e 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -278,7 +278,7 @@ assert os.path.exists(MINDRECORD_FILE_NAME + ".db") data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) count = 0 -for item in data_set.create_dict_iterator(): +for item in data_set.create_dict_iterator(output_numpy=True): print("sample: {}".format(item)) count += 1 print("Got {} samples".format(count)) -- Gitee From 824d5a58328ccb08b0e1a2a2ff21e4f210110ed2 Mon Sep 17 00:00:00 2001 From: yingchen Date: Thu, 17 Sep 2020 19:43:19 +0800 Subject: [PATCH 066/100] update tutorial(a) links for r1.0 --- .../advanced_use/apply_gradient_accumulation.md | 10 +++++----- .../advanced_use/apply_host_device_training.md | 6 +++--- .../advanced_use/apply_parameter_server_training.md | 8 ++++---- .../apply_quantization_aware_training.md | 10 +++++----- .../advanced_use/accelerate_data_processing.md | 2 +- .../advanced_use/apply_gradient_accumulation.md | 10 +++++----- .../advanced_use/apply_host_device_training.md | 6 +++--- .../advanced_use/apply_parameter_server_training.md | 8 ++++---- .../apply_quantization_aware_training.md | 12 ++++++------ 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md b/tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md index 73724e1b4a..986a97c05f 100644 --- a/tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md +++ b/tutorials/training/source_en/advanced_use/apply_gradient_accumulation.md @@ -17,7 +17,7 @@ - + ## Overview @@ -29,7 +29,7 @@ Different from the traditional training method, the concept of mini-batch is int The ultimate objective is to achieve the same effect as training with N x mini-batch data. -> This tutorial is applicable to GPUs and Ascend 910 AI Processors. You can download the main training sample code from . +> This tutorial is applicable to GPUs and Ascend 910 AI Processors. You can download the main training sample code from . ## Creating a Gradient Accumulation Model @@ -58,11 +58,11 @@ from model_zoo.official.cv.lenet.src.lenet import LeNet5 ### Loading the Dataset -Use the `MnistDataset` API provided by the dataset of MindSpore to load the MNIST dataset. The code is imported from [dataset.py]() in the lenet directory of model_zoo. +Use the `MnistDataset` API provided by the dataset of MindSpore to load the MNIST dataset. The code is imported from [dataset.py]() in the lenet directory of model_zoo. ### Defining the Network -The following uses the LeNet network as an example. You can also use other networks, such as ResNet-50 and BERT. The code is imported from [lenet.py]() in the lenet directory of model_zoo. +The following uses the LeNet network as an example. You can also use other networks, such as ResNet-50 and BERT. The code is imported from [lenet.py]() in the lenet directory of model_zoo. ### Defining the Training Model The training process is divided into three parts: forward and backward training, parameter update, and accumulated gradient clearance. @@ -252,7 +252,7 @@ After 10 epochs, the accuracy on the test set is about 96.31%. **Model Validation** -Use the saved checkpoint file to load the validation dataset through [eval.py]() in the lenet directory of model_zoo. +Use the saved checkpoint file to load the validation dataset through [eval.py]() in the lenet directory of model_zoo. ```shell $ python eval.py --data_path=./MNIST_Data --ckpt_path=./gradient_accumulation.ckpt diff --git a/tutorials/training/source_en/advanced_use/apply_host_device_training.md b/tutorials/training/source_en/advanced_use/apply_host_device_training.md index 23ab2d078f..b36d29c587 100644 --- a/tutorials/training/source_en/advanced_use/apply_host_device_training.md +++ b/tutorials/training/source_en/advanced_use/apply_host_device_training.md @@ -12,7 +12,7 @@ - + ## Overview @@ -21,10 +21,10 @@ the number of required accelerators is too overwhelming for people to access, re efficient method for addressing huge model problem. In MindSpore, users can easily implement hybrid training by configuring trainable parameters and necessary operators to run on hosts, and other operators to run on accelerators. -This tutorial introduces how to train [Wide&Deep](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/recommend/wide_and_deep) in the Host+Ascend 910 AI Accelerator mode. +This tutorial introduces how to train [Wide&Deep](https://gitee.com/mindspore/mindspore/tree/r1.0/model_zoo/official/recommend/wide_and_deep) in the Host+Ascend 910 AI Accelerator mode. ## Preliminaries -1. Prepare the model. The Wide&Deep code can be found at: , in which `train_and_eval_auto_parallel.py` is the main function for training, +1. Prepare the model. The Wide&Deep code can be found at: , in which `train_and_eval_auto_parallel.py` is the main function for training, `src/` directory contains the model definition, data processing and configuration files, `script/` directory contains the launch scripts in different modes. 2. Prepare the dataset. The dataset can be found at: . Use the script `src/preprocess_data.py` to transform dataset into MindRecord format. diff --git a/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md b/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md index 2edd972542..04899d9c37 100644 --- a/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md +++ b/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md @@ -14,7 +14,7 @@ - + ## Overview A parameter server is a widely used architecture in distributed training. Compared with the synchronous AllReduce training method, a parameter server has better flexibility, scalability, and node failover capabilities. Specifically, the parameter server supports both synchronous and asynchronous SGD training algorithms. In terms of scalability, model computing and update are separately deployed in the worker and server processes, so that resources of the worker and server can be independently scaled out and in horizontally. In addition, in an environment of a large-scale data center, various failures often occur in a computing device, a network, and a storage device, and consequently some nodes are abnormal. However, in an architecture of a parameter server, such a failure can be relatively easily handled without affecting a training job. @@ -35,14 +35,14 @@ The following describes how to use parameter server to train LeNet on Ascend 910 ### Training Script Preparation -Learn how to train a LeNet using the [MNIST dataset](http://yann.lecun.com/exdb/mnist/) by referring to . +Learn how to train a LeNet using the [MNIST dataset](http://yann.lecun.com/exdb/mnist/) by referring to . ### Parameter Setting 1. First of all, Use `mindspore.context.set_ps_context(enable_ps=True)` to enable Parameter Server training mode. - This method should be called before `mindspore.communication.management.init()`. -- If you don't call this method, the [Environment Variable Setting](https://www.mindspore.cn/tutorial/en/master/advanced_use/parameter_server_training.html#environment-variable-setting) below will not take effect. +- If you don't call this method, the [Environment Variable Setting](https://www.mindspore.cn/tutorial/training/en/r1.0/advanced_use/apply_parameter_server_training.html#environment-variable-setting) below will not take effect. - Use `mindspore.context.reset_ps_context()` to disable Parameter Server training mode. 2. In this training mode, you can use either of the following methods to control whether the training parameters are updated through the parameter server: @@ -50,7 +50,7 @@ Learn how to train a LeNet using the [MNIST dataset](http://yann.lecun.com/exdb/ - Use `mindspore.nn.Cell.set_param_ps()` to set all weight recursions of `nn.Cell`. - Use `mindspore.common.Parameter.set_param_ps()` to set the weight. -3. On the basis of the [original training script](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/train.py), set all LeNet model weights to be trained on the parameter server: +3. On the basis of the [original training script](https://gitee.com/mindspore/mindspore/blob/r1.0/model_zoo/official/cv/lenet/train.py), set all LeNet model weights to be trained on the parameter server: ```python context.set_ps_context(enable_ps=True) network = LeNet5(cfg.num_classes) diff --git a/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md index 83bef466d0..1e7782a167 100644 --- a/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md +++ b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md @@ -20,7 +20,7 @@ - + ## Background @@ -51,7 +51,7 @@ Aware quantization training specifications | Specification | Description | | ------------- | ---------------------------------------- | | Hardware | Supports hardware platforms based on the GPU or Ascend AI 910 processor. | -| Network | Supports networks such as LeNet and ResNet50. For details, see . | +| Network | Supports networks such as LeNet and ResNet50. For details, see . | | Algorithm | Supports symmetric and asymmetric quantization algorithms in MindSpore fake quantization training. | | Solution | Supports 4-, 7-, and 8-bit quantization solutions. | @@ -76,7 +76,7 @@ Compared with common training, the quantization aware training requires addition Next, the LeNet network is used as an example to describe steps 3 and 6. -> You can obtain the complete executable sample code at . +> You can obtain the complete executable sample code at . ### Defining a Fusion Network @@ -170,7 +170,7 @@ The preceding describes the quantization aware training from scratch. A more com 2. Define a network. 3. Define a fusion network. 4. Define an optimizer and loss function. - 5. Load a model file and retrain the model. Load an existing model file and retrain the model based on the fusion network to generate a fusion model. For details, see . + 5. Load a model file and retrain the model. Load an existing model file and retrain the model based on the fusion network to generate a fusion model. For details, see . 6. Generate a quantization network. 7. Perform quantization training. @@ -178,7 +178,7 @@ The preceding describes the quantization aware training from scratch. A more com The inference using a quantization model is the same as common model inference. The inference can be performed by directly using the checkpoint file or converting the checkpoint file into a common model format (such as ONNX or AIR). -For details, see . +For details, see . - To use a checkpoint file obtained after quantization aware training for inference, perform the following steps: diff --git a/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md index ccdd08fecc..66f46b093b 100644 --- a/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md +++ b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md @@ -11,7 +11,7 @@ - + ## 概述 diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md b/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md index 2c66ade5f7..179c18780e 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_gradient_accumulation.md @@ -17,7 +17,7 @@ - + ## 概述 @@ -29,7 +29,7 @@ 最终目的是为了达到跟直接用N*Mini-batch数据训练几乎同样的效果。 -> 本教程用于GPU、Ascend 910 AI处理器, 你可以在这里下载主要的训练样例代码: +> 本教程用于GPU、Ascend 910 AI处理器, 你可以在这里下载主要的训练样例代码: ## 创建梯度累积模型 @@ -58,11 +58,11 @@ from model_zoo.official.cv.lenet.src.lenet import LeNet5 ### 加载数据集 -利用MindSpore的`dataset`提供的`MnistDataset`接口加载MNIST数据集,此部分代码由`model_zoo`中`lenet`目录下的[dataset.py]()导入。 +利用MindSpore的`dataset`提供的`MnistDataset`接口加载MNIST数据集,此部分代码由`model_zoo`中`lenet`目录下的[dataset.py]()导入。 ### 定义网络 -这里以LeNet网络为例进行介绍,当然也可以使用其它的网络,如ResNet-50、BERT等, 此部分代码由`model_zoo`中`lenet`目录下的[lenet.py]()导入。 +这里以LeNet网络为例进行介绍,当然也可以使用其它的网络,如ResNet-50、BERT等, 此部分代码由`model_zoo`中`lenet`目录下的[lenet.py]()导入。 ### 定义训练模型 将训练流程拆分为正向反向训练、参数更新和累积梯度清理三个部分: @@ -252,7 +252,7 @@ if __name__ == "__main__": **验证模型** -通过`model_zoo`中`lenet`目录下的[eval.py](),使用保存的CheckPoint文件,加载验证数据集,进行验证。 +通过`model_zoo`中`lenet`目录下的[eval.py](),使用保存的CheckPoint文件,加载验证数据集,进行验证。 ```shell $ python eval.py --data_path=./MNIST_Data --ckpt_path=./gradient_accumulation.ckpt diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md index c20f533db6..82b9218891 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_host_device_training.md @@ -12,17 +12,17 @@ - + ## 概述 在深度学习中,工作人员时常会遇到超大模型的训练问题,即模型参数所占内存超过了设备内存上限。为高效地训练超大模型,一种方案便是分布式并行训练,也就是将工作交由同构的多个加速器(如Ascend 910 AI处理器,GPU等)共同完成。但是这种方式在面对几百GB甚至几TB级别的模型时,所需的加速器过多。而当从业者实际难以获取大规模集群时,这种方式难以应用。另一种可行的方案是使用主机端(Host)和加速器(Device)的混合训练模式。此方案同时发挥了主机端内存大和加速器端计算快的优势,是一种解决超大模型训练较有效的方式。 -在MindSpore中,用户可以将待训练的参数放在主机,同时将必要算子的执行位置配置为主机,其余算子的执行位置配置为加速器,从而方便地实现混合训练。此教程以推荐模型[Wide&Deep](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/recommend/wide_and_deep)为例,讲解MindSpore在主机和Ascend 910 AI处理器的混合训练。 +在MindSpore中,用户可以将待训练的参数放在主机,同时将必要算子的执行位置配置为主机,其余算子的执行位置配置为加速器,从而方便地实现混合训练。此教程以推荐模型[Wide&Deep](https://gitee.com/mindspore/mindspore/tree/r1.0/model_zoo/official/recommend/wide_and_deep)为例,讲解MindSpore在主机和Ascend 910 AI处理器的混合训练。 ## 准备工作 -1. 准备模型代码。Wide&Deep的代码可参见:,其中,`train_and_eval_auto_parallel.py`为训练的主函数所在,`src/`目录中包含Wide&Deep模型的定义、数据处理和配置信息等,`script/`目录中包含不同配置下的训练脚本。 +1. 准备模型代码。Wide&Deep的代码可参见:,其中,`train_and_eval_auto_parallel.py`为训练的主函数所在,`src/`目录中包含Wide&Deep模型的定义、数据处理和配置信息等,`script/`目录中包含不同配置下的训练脚本。 2. 准备数据集。数据集下载链接:。利用脚本`src/preprocess_data.py`将数据集转换为MindRecord格式。 diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md index 83e6df2654..7fe27367e2 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md @@ -14,7 +14,7 @@ - + ## 概述 Parameter Server(参数服务器)是分布式训练中一种广泛使用的架构,相较于同步的AllReduce训练方法,Parameter Server具有更好的灵活性、可扩展性以及节点容灾的能力。具体来讲,参数服务器既支持同步SGD,也支持异步SGD的训练算法;在扩展性上,将模型的计算与模型的更新分别部署在Worker和Server两类进程中,使得Worker和Server的资源可以独立地横向扩缩;另外,在大规模数据中心的环境下,计算设备、网络以及存储经常会出现各种故障而导致部分节点异常,而在参数服务器的架构下,能够较为容易地处理此类的故障而不会对训练中的任务产生影响。 @@ -34,14 +34,14 @@ Parameter Server(参数服务器)是分布式训练中一种广泛使用的架 ### 训练脚本准备 -参考,使用[MNIST数据集](http://yann.lecun.com/exdb/mnist/),了解如何训练一个LeNet网络。 +参考,使用[MNIST数据集](http://yann.lecun.com/exdb/mnist/),了解如何训练一个LeNet网络。 ### 参数设置 1. 首先调用`mindspore.context.set_ps_context(enable_ps=True)`开启Parameter Server训练模式. - 此接口需在`mindspore.communication.management.init()`之前调用。 - - 若没有调用此接口,下面的[环境变量设置](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/parameter_server_training.html#id5)则不会生效。 + - 若没有调用此接口,下面的[环境变量设置](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/apply_parameter_server_training.html#id5)则不会生效。 - 调用`mindspore.context.reset_ps_context()`可以关闭Parameter Server训练模式。 2. 在本训练模式下,有以下两种调用接口方式以控制训练参数是否通过Parameter Server进行更新: @@ -49,7 +49,7 @@ Parameter Server(参数服务器)是分布式训练中一种广泛使用的架 - 通过`mindspore.nn.Cell.set_param_ps()`对`nn.Cell`中所有权重递归设置。 - 通过`mindspore.common.Parameter.set_param_ps()`对此权重进行设置。 -3. 在[原训练脚本](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/lenet/train.py)基础上,设置LeNet模型所有权重通过Parameter Server训练: +3. 在[原训练脚本](https://gitee.com/mindspore/mindspore/blob/r1.0/model_zoo/official/cv/lenet/train.py)基础上,设置LeNet模型所有权重通过Parameter Server训练: ```python context.set_ps_context(enable_ps=True) network = LeNet5(cfg.num_classes) diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md index fc7a7b9182..283146a888 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md @@ -9,7 +9,7 @@ - [概念](#概念) - [量化](#量化) - [伪量化节点](#伪量化节点) - - [感知量化训练](#感知量化训练-1) + - [感知量化训练](#感知量化训练) - [感知量化训练示例](#感知量化训练示例) - [定义融合网络](#定义融合网络) - [转化为量化网络](#转化为量化网络) @@ -20,7 +20,7 @@ - + ## 背景 @@ -51,7 +51,7 @@ MindSpore的感知量化训练是在训练基础上,使用低精度数据替 | 规格 | 规格说明 | | --- | --- | | 硬件支持 | GPU、Ascend AI 910处理器的硬件平台 | -| 网络支持 | 已实现的网络包括LeNet、ResNet50等网络,具体请参见。 | +| 网络支持 | 已实现的网络包括LeNet、ResNet50等网络,具体请参见。 | | 算法支持 | 在MindSpore的伪量化训练中,支持非对称和对称的量化算法。 | | 方案支持 | 支持4、7和8比特的量化方案。 | @@ -76,7 +76,7 @@ MindSpore的感知量化训练是在训练基础上,使用低精度数据替 接下来,以LeNet网络为例,展开叙述3、6两个步骤。 -> 你可以在这里找到完整可运行的样例代码: 。 +> 你可以在这里找到完整可运行的样例代码: 。 ### 定义融合网络 @@ -170,7 +170,7 @@ net = qat.convert_quant_network(net, quant_delay=0, bn_fold=False, freeze_bn=100 2. 定义网络。 3. 定义融合网络。 4. 定义优化器和损失函数。 - 5. 加载模型文件模型重训。加载已有模型文件,基于融合网络重新训练生成融合模型。详细模型重载训练,请参见 + 5. 加载模型文件模型重训。加载已有模型文件,基于融合网络重新训练生成融合模型。详细模型重载训练,请参见 6. 转化量化网络。 7. 进行量化训练。 @@ -178,7 +178,7 @@ net = qat.convert_quant_network(net, quant_delay=0, bn_fold=False, freeze_bn=100 使用量化模型进行推理,与普通模型推理一致,分为直接checkpoint文件推理及转化为通用模型格式(ONNX、AIR等)进行推理。 -> 推理详细说明请参见。 +> 推理详细说明请参见 - 使用感知量化训练后得到的checkpoint文件进行推理: -- Gitee From ce6f23677693f153add5fd9503c6ee7e3628f203 Mon Sep 17 00:00:00 2001 From: lichenever Date: Thu, 17 Sep 2020 19:37:35 +0800 Subject: [PATCH 067/100] add_distributed_gpu_doc --- .../source_zh_cn/auto_parallel.md | 68 +++++--- .../advanced_use/distributed_training_gpu.md | 148 ++++++++++++++++++ .../distributed_training_tutorials.rst | 1 + 3 files changed, 194 insertions(+), 23 deletions(-) create mode 100644 tutorials/training/source_en/advanced_use/distributed_training_gpu.md diff --git a/docs/programming_guide/source_zh_cn/auto_parallel.md b/docs/programming_guide/source_zh_cn/auto_parallel.md index cc8cee2f71..a0c514462f 100644 --- a/docs/programming_guide/source_zh_cn/auto_parallel.md +++ b/docs/programming_guide/source_zh_cn/auto_parallel.md @@ -13,7 +13,6 @@ - [all_reduce_fusion_config](#all_reduce_fusion_config) - [自动并行配置](#自动并行配置) - [gradient_fp32_sync](#gradient_fp32_sync) - - [loss_repeated_mean](#loss_repeated_mean) - [auto_parallel_search_mode](#auto_parallel_search_mode) - [strategy_ckpt_load_file](#strategy_ckpt_load_file) - [strategy_ckpt_save_file](#strategy_ckpt_save_file) @@ -26,8 +25,11 @@ - [init](#init) - [get_group_size](#get_group_size) - [get_rank](#get_rank) - - [数据并行](#数据并行) - - [自动并行](#自动并行) + - [分布式属性配置](#分布式属性配置) + - [cross_batch](#cross_batch) + - [fusion](#fusion) + - [数据并行](#数据并行) + - [自动并行](#自动并行) @@ -44,7 +46,7 @@ MindSpore提供了分布式并行训练的功能,它支持了包括数据并 MindSpore的分布式并行配置通过`auto_parallel_context`来进行集中管理,用户可根据自身需求和实际情况来进行个性化的配置。这些配置可分为四大类: - 通用配置:对数据并行和自动并行均起作用的配置,如:`device_num`、`global_rank`。 -- 自动并行配置:仅在自动并行模式下起作用的配置,如:`gradient_fp32_sync`、`loss_repeated_mean`。 +- 自动并行配置:仅在自动并行模式下起作用的配置,如:`gradient_fp32_sync`。 - 数据并行配置:仅在数据并行模式下起作用的配置,如:`enable_parallel_optimizer`。 - 混合并行配置:仅在混合并行模式下起作用的配置,如:`layerwise_parallel`。 @@ -98,15 +100,21 @@ context.get_auto_parallel_context("gradients_mean") - `stand_alone`:单机模式。 - `data_parallel`:数据并行模式。 - `hybrid_parallel`:混合并行模式。 -- `semi_auto_parallel`:半自动并行模式,即用户可通过`set_strategy`方法给算子配置切分策略,若不配置策略,则默认是数据并行策略。 +- `semi_auto_parallel`:半自动并行模式,即用户可通过`shard`方法给算子配置切分策略,若不配置策略,则默认是数据并行策略。 - `auto_parallel`:自动并行模式,即框架会自动建立代价模型,为用户选择最优的切分策略。 +其中`auto_parallel`和`data_parallel`在MindSpore教程中有完整样例: + +。 + 代码样例如下: ```python -from mindspore import context +from mindspore import context +from mindspore.ops import operations as P -context.set_auto_parallel_context(parallel_mode="auto_parallel") +context.set_auto_parallel_context(parallel_mode="semi_auto_parallel") +mul = P.Mul().shard(((2, 1), (2, 1))) context.get_auto_parallel_context("parallel_mode") ``` @@ -141,22 +149,9 @@ context.set_auto_parallel_context(gradient_fp32_sync=False) context.get_auto_parallel_context("gradient_fp32_sync") ``` -#### loss_repeated_mean - -`loss_repeated_mean`表示在loss重复计算的场景下,反向是否进行均值操作,其值为bool类型,默认为True。loss存在重复计算的场景下,反向进行均值操作能使分布式逻辑和单机保持一致。但在某些场景下,不进行均值操作可能会使网络收敛的速度更快。因此,MindSpore提供`loss_repeated_mean`接口,让用户自由配置。 - -代码样例如下: - -```python -from mindspore import context - -context.set_auto_parallel_context(loss_repeated_mean=False) -context.get_auto_parallel_context("loss_repeated_mean") -``` - #### auto_parallel_search_mode -MindSpore提供了`dynamic_programming`和`recursive_programming`两种搜索策略的算法。`dynamic_programming`能够搜索出代价模型刻画的最优策略,但在搜索巨大网络模型的并行策略时耗时较长;而`recursive_programming`能较快搜索出并行策略,但搜索出来的策略可能不是运行性能最优的。为此,MindSpore提供了参数,让用户自由选择搜索算法。 +MindSpore提供了`dynamic_programming`和`recursive_programming`两种搜索策略的算法。`dynamic_programming`能够搜索出代价模型刻画的最优策略,但在搜索巨大网络模型的并行策略时耗时较长;而`recursive_programming`能较快搜索出并行策略,但搜索出来的策略可能不是运行性能最优的。为此,MindSpore提供了参数,让用户自由选择搜索算法,默认是`dynamic_programming`。 代码样例如下: @@ -286,7 +281,33 @@ init() rank_id = get_rank() ``` -### 数据并行 +## 分布式属性配置 + +### cross_batch + +在特定场景下,`data_parallel`的计算逻辑和`stand_alone`是不一样的,`auto_parallel`在任何场景下都是和`stand_alone`的计算逻辑保持一致。而`data_parallel`的收敛效果可能更好,因此MindSpore提供了`cross_barch`这个参数,可以使`auto_parallel`的计算逻辑和`data_parallel`保持一致,用户可通过`add_prim_attr`方法进行配置,默认值是False。 + +代码样例如下: + +```python +from mindspore.ops import operations as P + +mul = P.Mul().set_prim_attr("cross_batch", True) +``` + +### fusion + +出于性能考虑,MindSpore提供了通信算子融合功能,`fusion`值相同的同类通信算子会融合在一起,`fusion`值为0时,表示不融合。 + +代码样例如下: + +```python +from mindspore.ops import operations as P + +allreduce = P.AllReduce().set_prim_attr("fusion", 1) +``` + +## 数据并行 数据并行是对数据进行切分的并行模式,一般按照batch维度切分,将数据分配到各个计算单元(worker)中,进行模型计算。在数据并行模式下,数据集要以数据并行的方式导入,并且`parallel_mode`要设置为`data_parallel`。 @@ -294,10 +315,11 @@ rank_id = get_rank() 。 -### 自动并行 +## 自动并行 自动并行是融合了数据并行、模型并行及混合并行的一种分布式并行模式,可以自动建立代价模型,为用户选择一种并行模式。其中,代价模型指基于内存的计算开销和通信开销对训练时间建模,并设计高效的算法找到训练时间较短的并行策略。在自动并行模式下,数据集也要以数据并行的方式导入,并且`parallel_mode`要设置为`auto_parallel`。 具体用例请参考MindSpore分布式并行训练教程: 。 + diff --git a/tutorials/training/source_en/advanced_use/distributed_training_gpu.md b/tutorials/training/source_en/advanced_use/distributed_training_gpu.md new file mode 100644 index 0000000000..66e074e179 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/distributed_training_gpu.md @@ -0,0 +1,148 @@ +# Distributed Parallel Training (GPU) + +`Linux` `GPU` `Model Training` `Intermediate` `Expert` + + + +- [Distributed Parallel Training (GPU)](#distributed-parallel-training-gpu) + - [Overview](#overview) + - [Preparation](#preparation) + - [Downloading the Dataset](#downloading-the-dataset) + - [Configuring Distributed Environment](#configuring-distributed-environment) + - [Calling the Collective Communication Library](#calling-the-collective-communication-library) + - [Defining the Network](#defining-the-network) + - [Running the Script](#running-the-script) + - [Running the Multi-Host Script](#running-the-multi-host-script) + + + + + +## Overview + +This tutorial describes how to train the ResNet-50 network using MindSpore data parallelism and automatic parallelism on GPU hardware platform. + +## Preparation + +### Downloading the Dataset + +The `CIFAR-10` dataset is used as an example. The method of downloading and loading the dataset is the same as that for the Ascend 910 AI processor. + +> The method of downloading and loading the dataset: +> +> + +### Configuring Distributed Environment + +- `OpenMPI-3.1.5`: multi-process communication library used by MindSpore. + + > Download the OpenMPI-3.1.5 source code package `openmpi-3.1.5.tar.gz` from . + > + > For details about how to install OpenMPI, see the official tutorial: . + +- `NCCL-2.4.8`: Nvidia collective communication library. + + > Download NCCL-2.4.8 from . + > + > For details about how to install NCCL, see the official tutorial: . + +- Password-free login between hosts (required for multi-host training). If multiple hosts are involved in the training, you need to configure password-free login between them. The procedure is as follows: + 1. Ensure that the same user is used to log in to each host. (The root user is not recommended.) + 2. Run the `ssh-keygen -t rsa -P ""` command to generate a key. + 3. Run the `ssh-copy-id DEVICE-IP` command to set the IP address of the host that requires password-free login. + 4. Run the`ssh DEVICE-IP` command. If you can log in without entering the password, the configuration is successful. + 5. Run the preceding command on all hosts to ensure that every two hosts can communicate with each other. + +### Calling the Collective Communication Library + +On the GPU hardware platform, MindSpore parallel distributed training uses NCCL for communication. + +> On the GPU platform, MindSpore does not support the following operations: +> +> `get_local_rank`, `get_local_size`, `get_world_rank_from_group_rank`, `get_group_rank_from_world_rank` and `create_group` + +The sample code for calling the HCCL is as follows: + +```python +from mindspore import context +from mindspore.communication.management import init + +if __name__ == "__main__": + context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + init("nccl") + ... +``` + +In the preceding information, + +- `mode=context.GRAPH_MODE`: sets the running mode to graph mode for distributed training. (The PyNative mode does not support parallel running.) +- `init("nccl")`: enables NCCL communication and completes the distributed training initialization. + +## Defining the Network + +On the GPU hardware platform, the network definition is the same as that for the Ascend 910 AI processor. + +> For details about the definitions of the network, optimizer, and loss function, see . + +## Running the Script + +On the GPU hardware platform, MindSpore uses OpenMPI `mpirun` for distributed training. The following takes the distributed training script for eight devices as an example to describe how to run the script: + +> Obtain the running script of the example from: +> +> +> +> If the script is executed by the root user, the `--allow-run-as-root` parameter must be added to `mpirun`. + +```bash +#!/bin/bash + +DATA_PATH=$1 +export DATA_PATH=${DATA_PATH} + +rm -rf device +mkdir device +cp ./resnet50_distributed_training.py ./resnet.py ./device +cd ./device +echo "start training" +mpirun -n 8 pytest -s -v ./resnet50_distributed_training.py > train.log 2>&1 & +``` + +The script requires the variable `DATA_PATH`, which indicates the path of the dataset. In addition, you need to modify the `resnet50_distributed_training.py` file. Since the `DEVICE_ID` environment variable does not need to be set on the GPU, you do not need to call `int(os.getenv('DEVICE_ID'))` in the script to obtain the physical sequence number of the device, and `context` does not require `device_id`. You need to set `device_target` to `GPU` and call `init("nccl")` to enable the NCCL. The log file is saved in the device directory, and the loss result is saved in train.log. The output loss values of the grep command are as follows: + +``` +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +epoch: 1 step: 1, loss is 2.3025854 +``` + +## Running the Multi-Host Script + +If multiple hosts are involved in the training, you need to set the multi-host configuration in the `mpirun` command. You can use the `-H` option in the `mpirun` command. For example, `mpirun -n 16 -H DEVICE1_IP:8,DEVICE2_IP:8 python hello.py` indicates that eight processes are started on the host whose IP addresses are DEVICE1_IP and DEVICE2_IP, respectively. Alternatively, you can create a hostfile similar to the following and transfer its path to the `--hostfile` option of `mpirun`. Each line in the hostfile is in the format of `[hostname] slots=[slotnum]`, where hostname can be an IP address or a host name. +```bash +DEVICE1 slots=8 +DEVICE2 slots=8 +``` + +The following is the execution script of the 16-device two-host cluster. The variables `DATA_PATH` and `HOSTFILE` need to be transferred, indicating the dataset path and hostfile path. For details about more mpirun options, see the OpenMPI official website. + +```bash +#!/bin/bash + +DATA_PATH=$1 +HOSTFILE=$2 + +rm -rf device +mkdir device +cp ./resnet50_distributed_training.py ./resnet.py ./device +cd ./device +echo "start training" +mpirun -n 16 --hostfile $HOSTFILE -x DATA_PATH=$DATA_PATH -x PATH -mca pml ob1 pytest -s -v ./resnet50_distributed_training.py > train.log 2>&1 & +``` + +Run running on GPU, the model parameters can be saved and loaded for reference[Distributed Training Model Parameters Saving and Loading](https://www.mindspore.cn/tutorial/en/master/advanced_use/distributed_training_ascend.html#id12) diff --git a/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst b/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst index 84fcdf2fc5..ce35667fe2 100644 --- a/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst +++ b/tutorials/training/source_en/advanced_use/distributed_training_tutorials.rst @@ -17,6 +17,7 @@ MindSpore also provides the parallel distributed training function. It supports :maxdepth: 1 distributed_training_ascend + distributed_training_gpu apply_host_device_training apply_parameter_server_training save_load_model_hybrid_parallel -- Gitee From d72e7929e0c97c0c6e4829e8f8abc64a59f54432 Mon Sep 17 00:00:00 2001 From: xuanyue Date: Thu, 17 Sep 2020 20:17:56 +0800 Subject: [PATCH 068/100] update interface and out information --- .../lite/source_en/use/converter_tool.md | 8 +++---- tutorials/lite/source_en/use/runtime.md | 21 ++++--------------- .../lite/source_zh_cn/use/converter_tool.md | 8 +++---- tutorials/lite/source_zh_cn/use/runtime.md | 21 ++++--------------- 4 files changed, 16 insertions(+), 42 deletions(-) diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index 99f3d5464f..62de8b5dcf 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -53,7 +53,7 @@ The following describes how to use the conversion command by using several commo The output is as follows: ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` This indicates that the Caffe model is successfully converted into the MindSpore Lite model and the new file `lenet.ms` is generated. @@ -86,7 +86,7 @@ The following describes how to use the conversion command by using several commo In the preceding scenarios, the following information is displayed, indicating that the conversion is successful. In addition, the target file `model.ms` is obtained. ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` - If fail to run the conversion command, an [errorcode](https://www.mindspore.cn/lite/docs/en/master/apicc/errorcode_and_metatype.html) will be output. @@ -144,7 +144,7 @@ Several common examples are selected below to illustrate the use of conversion c The result is shown as: ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` This means that the Caffe model has been successfully converted to the MindSpore Lite model and the new file `lenet.ms` has been obtained. @@ -172,6 +172,6 @@ Several common examples are selected below to illustrate the use of conversion c In the above cases, the following conversion success prompt is displayed, and the `model.ms` target file is obtained at the same time. ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` - If fail to run the conversion command, an [errorcode](https://www.mindspore.cn/lite/docs/en/master/apicc/errorcode_and_metatype.html) will be output. diff --git a/tutorials/lite/source_en/use/runtime.md b/tutorials/lite/source_en/use/runtime.md index eca4461031..c47e85dfb8 100644 --- a/tutorials/lite/source_en/use/runtime.md +++ b/tutorials/lite/source_en/use/runtime.md @@ -508,16 +508,16 @@ virtual void *MutableData() const = 0; ### Example -The following sample code shows how to obtain the output `MSTensor` from `LiteSession` using the `GetOutputMapByNode` method and print the first ten data or all data records of each output `MSTensor`. +The following sample code shows how to obtain the output `MSTensor` from `LiteSession` using the `GetOutputs` method and print the first ten data or all data records of each output `MSTensor`. ```cpp // Assume we have created a LiteSession instance named session before. -auto output_map = session->GetOutputMapByNode(); +auto output_map = session->GetOutputs(); // Assume that the model has only one output node. auto out_node_iter = output_map.begin(); std::string name = out_node_iter->first; // Assume that the unique output node has only one output tensor. -auto out_tensor = out_node_iter->second.front(); +auto out_tensor = out_node_iter->second; if (out_tensor == nullptr) { std::cerr << "Output tensor is nullptr" << std::endl; return -1; @@ -541,7 +541,7 @@ std::cout << std::endl; // The elements in outputs do not need to be free by users, because outputs are managed by the MindSpore Lite. ``` -Note that the vectors or map returned by the `GetOutputsByNodeName`, `GetOutputMapByNode`, `GetOutputByTensorName` and `GetOutputMapByTensor` methods do not need to be released by users. +Note that the vectors or map returned by the `GetOutputsByNodeName`, `GetOutputByTensorName` and `GetOutputs` methods do not need to be released by users. The following sample code shows how to obtain the output `MSTensor` from `LiteSession` using the `GetOutputsByNodeName` method. @@ -557,19 +557,6 @@ if (out_tensor == nullptr) { } ``` -The following sample code shows how to obtain the output `MSTensor` from `LiteSession` using the `GetOutputMapByTensor` method. - -```cpp -// Assume we have created a LiteSession instance named session before. -auto output_map = session->GetOutputMapByTensor(); -// Assume that output node named output_node_name_0 has only one output tensor. -auto out_tensor = output_vec.front(); -if (out_tensor == nullptr) { - std::cerr << "Output tensor is nullptr" << std::endl; - return -1; -} -``` - The following sample code shows how to obtain the output `MSTensor` from `LiteSession` using the `GetOutputByTensorName` method. ```cpp diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index ba77498100..0ea0cb5a2e 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -53,7 +53,7 @@ bash build.sh -I x86_64 结果显示为: ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` 这表示已经成功将Caffe模型转化为MindSpore Lite模型,获得新文件`lenet.ms`。 @@ -87,7 +87,7 @@ bash build.sh -I x86_64 以上几种情况下,均显示如下转换成功提示,且同时获得`model.ms`目标文件。 ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` - 如果转换命令执行失败,程序会返回一个[错误码](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/errorcode_and_metatype.html)。 @@ -145,7 +145,7 @@ set MSLOG=INFO 结果显示为: ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` 这表示已经成功将Caffe模型转化为MindSpore Lite模型,获得新文件`lenet.ms`。 @@ -173,6 +173,6 @@ set MSLOG=INFO 以上几种情况下,均显示如下转换成功提示,且同时获得`model.ms`目标文件。 ``` - INFO [converter/converter.cc:190] Runconverter] CONVERTER RESULT: SUCCESS! + CONVERTER RESULT SUCCESS:0 ``` - 如果转换命令执行失败,程序会返回一个[错误码](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/errorcode_and_metatype.html)。 diff --git a/tutorials/lite/source_zh_cn/use/runtime.md b/tutorials/lite/source_zh_cn/use/runtime.md index 285c6719ce..364229b92e 100644 --- a/tutorials/lite/source_zh_cn/use/runtime.md +++ b/tutorials/lite/source_zh_cn/use/runtime.md @@ -505,16 +505,16 @@ virtual void *MutableData() const = 0; ### 使用示例 -下面示例代码演示了使用`GetOutputMapByNode`接口获取输出`MSTensor`,并打印了每个输出`MSTensor`的前十个数据或所有数据: +下面示例代码演示了使用`GetOutputs`接口获取输出`MSTensor`,并打印了每个输出`MSTensor`的前十个数据或所有数据: ```cpp // Assume we have created a LiteSession instance named session before. -auto output_map = session->GetOutputMapByNode(); +auto output_map = session->GetOutputs(); // Assume that the model has only one output node. auto out_node_iter = output_map.begin(); std::string name = out_node_iter->first; // Assume that the unique output node has only one output tensor. -auto out_tensor = out_node_iter->second.front(); +auto out_tensor = out_node_iter->second; if (out_tensor == nullptr) { std::cerr << "Output tensor is nullptr" << std::endl; return -1; @@ -538,7 +538,7 @@ std::cout << std::endl; // The elements in outputs do not need to be free by users, because outputs are managed by the MindSpore Lite. ``` -需要注意的是,`GetOutputsByNodeName`、`GetOutputMapByNode`、`GetOutputByTensorName`和`GetOutputMapByTensor`方法返回的vector或map不需要用户释放。 +需要注意的是,`GetOutputsByNodeName`、`GetOutputByTensorName`和`GetOutputs`方法返回的vector或map不需要用户释放。 下面示例代码演示了使用`GetOutputsByNodeName`接口获取输出`MSTensor`的方法: @@ -554,19 +554,6 @@ if (out_tensor == nullptr) { } ``` -下面示例代码演示了使用`GetOutputMapByTensor`接口获取输出`MSTensor`的方法: - -```cpp -// Assume we have created a LiteSession instance named session before. -auto output_map = session->GetOutputMapByTensor(); -// Assume that output node named output_node_name_0 has only one output tensor. -auto out_tensor = output_vec.front(); -if (out_tensor == nullptr) { - std::cerr << "Output tensor is nullptr" << std::endl; - return -1; -} -``` - 下面示例代码演示了使用`GetOutputByTensorName`接口获取输出`MSTensor`的方法: ```cpp -- Gitee From 6157813602e6b9e381545d33cb3062d3733e97b6 Mon Sep 17 00:00:00 2001 From: hangq Date: Thu, 17 Sep 2020 20:16:09 +0800 Subject: [PATCH 069/100] add multi-thread usage in runtime.md & fix bug --- docs/api_cpp/source_en/lite.md | 2 + docs/api_cpp/source_zh_cn/lite.md | 2 + tutorials/lite/source_en/use/runtime.md | 128 ++++++++++++++++++--- tutorials/lite/source_zh_cn/use/runtime.md | 128 ++++++++++++++++++--- 4 files changed, 232 insertions(+), 28 deletions(-) diff --git a/docs/api_cpp/source_en/lite.md b/docs/api_cpp/source_en/lite.md index 19b6a2cc8e..98efcdd6d6 100644 --- a/docs/api_cpp/source_en/lite.md +++ b/docs/api_cpp/source_en/lite.md @@ -35,6 +35,8 @@ float16_priority ``` A **bool** value. Defaults to **false**. Prior enable float16 inference. +> Enabling float16 inference may cause low precision inference,because some variables may exceed the range of float16 during forwarding. + ``` device_type ``` diff --git a/docs/api_cpp/source_zh_cn/lite.md b/docs/api_cpp/source_zh_cn/lite.md index 13931a5cc0..11d7f664a3 100644 --- a/docs/api_cpp/source_zh_cn/lite.md +++ b/docs/api_cpp/source_zh_cn/lite.md @@ -37,6 +37,8 @@ float16_priority **bool**值,默认为**false**,用于使能float16 推理。 +> 使能float16推理可能会导致模型推理精度下降,因为在模型推理的中间过程中,有些变量可能会超出float16的数值范围。 + ``` device_type ``` diff --git a/tutorials/lite/source_en/use/runtime.md b/tutorials/lite/source_en/use/runtime.md index eca4461031..4dd0b09214 100644 --- a/tutorials/lite/source_en/use/runtime.md +++ b/tutorials/lite/source_en/use/runtime.md @@ -28,6 +28,10 @@ - [Example](#example-5) - [Obtaining Version String](#obtaining-version-string) - [Example](#example-6) + - [Session parallel launch](#session-parallel-launch) + - [Single Session parallel launch](#single-session-parallel-launch) + - [Multiple Session parallel launch](#multiple-session-parallel-launch) + - [Example](#example-7) @@ -179,20 +183,7 @@ if (session == nullptr) { When using MindSpore Lite for inference, after the session creation and graph compilation have been completed, if you need to resize the input shape, you can reset the shape of the input tensor, and then call the session's Resize() interface. -```cpp -/// \brief Get input MindSpore Lite MSTensors of model. -/// -/// \return The vector of MindSpore Lite MSTensor. -virtual std::vector GetInputs() const = 0; - -/// \brief Resize inputs shape. -/// -/// \param[in] inputs Define Model inputs. -/// \param[in] dims Define All inputs new shape. -/// -/// \return STATUS as an error code of resize inputs, STATUS is defined in errorcode.h. -virtual int Resize(const std::vector &inputs, const std::vector> &dims) = 0; -``` +> Not all models support variable dimensions. For example, when there is a MatMul operator in the model whose input Tensor is a weight tensor and an input tensor, calling the variable dimension interface will cause the shape of the input tensor and the weight tensor being unmatched. ### Example @@ -596,3 +587,112 @@ The following sample code shows how to obtain version string using `Version` met #include "include/version.h" std::string version = mindspore::lite::Version(); ``` + +## Session parallel launch +MindSpore Lite supports multiple `LiteSession` parallel inferences, but does not support multiple threads calling the `RunGraph` interface of a single `LiteSession` at the same time. + +### Single Session parallel launch + +MindSpore Lite does not support multi-threaded parallel calling of the inference interface of a single `LiteSession`, otherwise we will get the following error message: +```cpp +ERROR [mindspore/lite/src/lite_session.cc:297] RunGraph] 10 Not support multi-threading +``` + +### Multiple Session parallel launch + +MindSpore Lite supports multiple `LiteSession` in doing inference in parallel. The thread pool and memory pool of each `LiteSession` are independent. + +### Example + +The following code shows how to create multiple `LiteSession` and do inference in parallel: +```cpp +#include +#include "src/common/file_utils.h" +#include "include/model.h" +#include "include/version.h" +#include "include/context.h" +#include "include/lite_session.h" + +mindspore::session::LiteSession *GenerateSession(mindspore::lite::Model *model) { + if (model == nullptr) { + std::cerr << "Read model file failed while running" << std::endl; + return nullptr; + } + auto context = new (std::nothrow) mindspore::lite::Context; + if (context == nullptr) { + std::cerr << "New context failed while running" << std::endl; + return nullptr; + } + + auto session = mindspore::session::LiteSession::CreateSession(context); + delete (context); + if (session == nullptr) { + std::cerr << "CreateSession failed while running" << std::endl; + return nullptr; + } + auto ret = session->CompileGraph(model); + if (ret != mindspore::lite::RET_OK) { + std::cout << "CompileGraph failed while running" << std::endl; + delete (session); + return nullptr; + } + auto msInputs = session->GetInputs(); + for (auto msInput : msInputs) { + (void)msInput->MutableData(); + } + return session; +} + +int main(int argc, const char **argv) { + size_t size = 0; + char *graphBuf = mindspore::lite::ReadFile("test.ms", &size); + if (graphBuf == nullptr) { + std::cerr << "Read model file failed while running" << std::endl; + return -1; + } + auto model = mindspore::lite::Model::Import(graphBuf, size); + if (model == nullptr) { + std::cerr << "Import model file failed while running" << std::endl; + delete[](graphBuf); + return -1; + } + delete[](graphBuf); + auto session1 = GenerateSession(model); + if (session1 == nullptr) { + std::cerr << "GenerateSession failed" << std::endl; + delete(model); + return -1; + } + auto session2 = GenerateSession(model); + if (session2 == nullptr) { + std::cerr << "GenerateSession failed" << std::endl; + delete(model); + return -1; + } + + std::thread thread1([&](){ + auto status = session1->RunGraph(); + if (status != 0) { + std::cerr << "Inference error " << status << std::endl; + return; + } + std::cout << "Session1 inference success" << std::endl; + }); + + std::thread thread2([&](){ + auto status = session2->RunGraph(); + if (status != 0) { + std::cerr << "Inference error " << status << std::endl; + return; + } + std::cout << "Session2 inference success" << std::endl; + }); + + thread1.join(); + thread2.join(); + delete (session1); + delete (session2); + delete (model); + return 0; +} +``` diff --git a/tutorials/lite/source_zh_cn/use/runtime.md b/tutorials/lite/source_zh_cn/use/runtime.md index 285c6719ce..9f48f89360 100644 --- a/tutorials/lite/source_zh_cn/use/runtime.md +++ b/tutorials/lite/source_zh_cn/use/runtime.md @@ -28,6 +28,10 @@ - [使用示例](#使用示例-5) - [获取版本号](#获取版本号) - [使用示例](#使用示例-6) + - [Session并行](#Session并行) + - [单Session并行](#单session并行) + - [多Session并行](#多session并行) + - [使用示例](#使用示例-7) @@ -178,20 +182,7 @@ if (session == nullptr) { 使用MindSpore Lite进行推理时,在已完成会话创建与图编译之后,如果需要对输入的shape进行Resize,则可以通过对输入的tensor重新设置shape,然后调用session的Resize()接口。 -```cpp -/// \brief Get input MindSpore Lite MSTensors of model. -/// -/// \return The vector of MindSpore Lite MSTensor. -virtual std::vector GetInputs() const = 0; - -/// \brief Resize inputs shape. -/// -/// \param[in] inputs Define Model inputs. -/// \param[in] dims Define All inputs new shape. -/// -/// \return STATUS as an error code of resize inputs, STATUS is defined in errorcode.h. -virtual int Resize(const std::vector &inputs, const std::vector> &dims) = 0; -``` +> 某些网络是不支持可变维度,会提示错误信息后异常退出,比如,模型中有MatMul算子,并且MatMul的一个输入Tensor是权重,另一个输入Tensor是输入时,调用可变维度接口会导致输入Tensor和权重Tensor的Shape不匹配,最终导致推理失败。 ### 使用示例 @@ -593,3 +584,112 @@ MindSpore Lite提供了`Version`方法可以获取版本号,包含在`include/ #include "include/version.h" std::string version = mindspore::lite::Version(); ``` + +## Session并行 +MindSpore Lite支持多个`LiteSession`并行推理,但不支持多个线程同时调用单个`LiteSession`的`RunGraph`接口。 + +### 单Session并行 + +MindSpore Lite不支持多线程并行执行单个`LiteSession`的推理,否则会得到以下错误信息: +```cpp +ERROR [mindspore/lite/src/lite_session.cc:297] RunGraph] 10 Not support multi-threading +``` + +### 多Session并行 + +MindSpore Lite支持多个`LiteSession`同时进行推理的场景,每个`LiteSession`的线程池和内存池都是独立的。 + +### 使用示例 + +下面代码演示了如何创建多个`LiteSession`,并且并行执行推理的过程: +```cpp +#include +#include "src/common/file_utils.h" +#include "include/model.h" +#include "include/version.h" +#include "include/context.h" +#include "include/lite_session.h" + +mindspore::session::LiteSession *GenerateSession(mindspore::lite::Model *model) { + if (model == nullptr) { + std::cerr << "Read model file failed while running" << std::endl; + return nullptr; + } + auto context = new (std::nothrow) mindspore::lite::Context; + if (context == nullptr) { + std::cerr << "New context failed while running" << std::endl; + return nullptr; + } + + auto session = mindspore::session::LiteSession::CreateSession(context); + delete (context); + if (session == nullptr) { + std::cerr << "CreateSession failed while running" << std::endl; + return nullptr; + } + auto ret = session->CompileGraph(model); + if (ret != mindspore::lite::RET_OK) { + std::cout << "CompileGraph failed while running" << std::endl; + delete (session); + return nullptr; + } + auto msInputs = session->GetInputs(); + for (auto msInput : msInputs) { + (void)msInput->MutableData(); + } + return session; +} + +int main(int argc, const char **argv) { + size_t size = 0; + char *graphBuf = mindspore::lite::ReadFile("test.ms", &size); + if (graphBuf == nullptr) { + std::cerr << "Read model file failed while running" << std::endl; + return -1; + } + auto model = mindspore::lite::Model::Import(graphBuf, size); + if (model == nullptr) { + std::cerr << "Import model file failed while running" << std::endl; + delete[](graphBuf); + return -1; + } + delete[](graphBuf); + auto session1 = GenerateSession(model); + if (session1 == nullptr) { + std::cerr << "GenerateSession failed" << std::endl; + delete(model); + return -1; + } + auto session2 = GenerateSession(model); + if (session2 == nullptr) { + std::cerr << "GenerateSession failed" << std::endl; + delete(model); + return -1; + } + + std::thread thread1([&](){ + auto status = session1->RunGraph(); + if (status != 0) { + std::cerr << "Inference error " << status << std::endl; + return; + } + std::cout << "Session1 inference success" << std::endl; + }); + + std::thread thread2([&](){ + auto status = session2->RunGraph(); + if (status != 0) { + std::cerr << "Inference error " << status << std::endl; + return; + } + std::cout << "Session2 inference success" << std::endl; + }); + + thread1.join(); + thread2.join(); + delete (session1); + delete (session2); + delete (model); + return 0; +} +``` -- Gitee From e8c40c7e4982aa45d4624263a58b462e530db3ba Mon Sep 17 00:00:00 2001 From: liangts Date: Thu, 17 Sep 2020 20:33:19 +0800 Subject: [PATCH 070/100] Add english version tutorial for MindConverter --- .../migrate_3rd_scripts_mindconverter.md | 207 ++++++++++++++++++ tutorials/training/source_en/index.rst | 4 +- 2 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 tutorials/training/source_en/advanced_use/migrate_3rd_scripts_mindconverter.md diff --git a/tutorials/training/source_en/advanced_use/migrate_3rd_scripts_mindconverter.md b/tutorials/training/source_en/advanced_use/migrate_3rd_scripts_mindconverter.md new file mode 100644 index 0000000000..9e3c376ba7 --- /dev/null +++ b/tutorials/training/source_en/advanced_use/migrate_3rd_scripts_mindconverter.md @@ -0,0 +1,207 @@ +# Migrate From Third Party Framework + +`Linux` `Ascend` `Model Development` `Beginner` + + + +- [Model Scripts Transformation](#Model-Scripts-Transformation) + - [Overview](#Overview) + - [Installation](#Installation) + - [Usage](#Usage) + - [Scenario](#Scenario) + - [Example](#Example) + - [AST-Based Conversion](#AST-Based-Conversion) + - [Graph-Based Conversion](#Graph-Based-Conversion) + - [Caution](#Caution) + + + + + +## Overview + +MindConverter is a migration tool to transform the model scripts from PyTorch to Mindspore. Users can migrate their PyTorch models to Mindspore rapidly with minor changes according to the conversion report. + + +## Installation + +Mindconverter is a submodule in MindInsight. Please follow the [Guide](https://www.mindspore.cn/install/en) here to install MindInsight. + + +## Usage + +MindConverter currently only provides command-line interface. Here is the manual page. + +```bash +usage: mindconverter [-h] [--version] [--in_file IN_FILE] + [--model_file MODEL_FILE] [--shape SHAPE] + [--output OUTPUT] [--report REPORT] + [--project_path PROJECT_PATH] + +optional arguments: + -h, --help show this help message and exit + --version show program version number and exit + --in_file IN_FILE Specify path for script file to use AST schema to do + script conversation. + --model_file MODEL_FILE + PyTorch .pth model file path to use graph based schema + to do script generation. When `--in_file` and + `--model_file` are both provided, use AST schema as + default. + --shape SHAPE Optional, excepted input tensor shape of + `--model_file`. It is required when use graph based + schema. Usage: --shape 3,244,244 + --output OUTPUT Optional, specify path for converted script file + directory. Default output directory is `output` folder + in the current working directory. + --report REPORT Optional, specify report directory. Default is + converted script directory. + --project_path PROJECT_PATH + Optional, PyTorch scripts project path. If PyTorch + project is not in PYTHONPATH, please assign + `--project_path` when use graph based schema. Usage: + --project_path ~/script_file/ + +``` + +**MindConverter provides two modes:** + +1. **Abstract Syntax Tree (AST) based conversion**:Use the argument `--in_file` will enable the AST mode. +2. **Computational Graph basedconversion**:Use `--model_file` and `--shape` arguments will enable the Graph mode. + +> The AST mode will be enabled, if both `--in_file` and `--model_file` are specified. + +For the Grapa mode, `--shape` is mandatory. + +For the AST mode, `--shape` is ignored. + +`--output` and `--report` is optional. MindConverter creates an `output` folder under the current working directory, and outputs generated scripts and conversion reports to it. + +Please note that your original PyTorch project is included in the module search path (PYTHONPATH). Use the python interpreter and test your module can be successfully loaded by `import` command. Use `--project_path` instead if your project is not in the PYTHONPATH to ensure MindConverter can load it. + +> Assume the project is located at `/home/user/project/model_training`, users can use this command to add the project to `PYTHONPATH` : `export PYTHONPATH=/home/user/project/model_training:$PYTHONPATH` + +> MindConverter needs the original PyTourch scripts because of the reverse serialization. + + + +## Scenario + +MindConverter provides two modes for different migration demands. + +1. Keep original scripts' structures, including variables, functions, and libraries. +2. Keep extra modifications as few as possible, or no modifications are required after conversion. + +The AST mode is recommended for the first demand. It parses and analyzes PyTorch scripts, then replace them with the MindSpore AST to generate codes. Theoretically, The AST mode supports any model script. However, the conversion may differ due to the coding style of original scripts. + +For the second demand, the Graph mode is recommended. As the computational graph is a standard descriptive language, it is not affected by user's coding style. This mode may have more operators converted as long as these operators are supported by MindConverter. + +Some typical image classification networks such as ResNet and VGG have been tested for the Graph mode. Note that: + +> 1. Currently, the Graph mode does not support models with multiple inputs. Only models with a single input and single output are supported. + +> 2. The Dropout operator will be lost after conversion because the inference mode is used to load the PyTorch model. Manually re-implement is necessary. + +> 3. The Graph-based mode will be continuously developed and optimized with further updates. + + +## Example + +### AST-Based Conversion + +Assume the PyTorch script is located at `/home/user/model.py`, and outputs the transformed MindSpore script to `/home/user/output`, with the conversion report to `/home/user/output/report`. Use the following command: + +```bash +mindconverter --in_file /home/user/model.py \ + --output /home/user/output \ + --report /home/user/output/report +``` + +In the conversion report, non-transformed code is listed as follows: + +```text +line : [UnConvert] 'operator' didn't convert. ... +``` + +For non-transformed operators, the original code keeps. Please manually migrate them. [Click here](https://www.mindspore.cn/docs/en/master/index.html#operator_api) for more information about operator mapping. + + +Here is an example of the conversion report: +```text + [Start Convert] + [Insert] 'import mindspore.ops.operations as P' is inserted to the converted file. + line 1:0: [Convert] 'import torch' is converted to 'import mindspore'. + ... + line 157:23: [UnConvert] 'nn.AdaptiveAvgPool2d' didn't convert. Maybe could convert to mindspore.ops.operations.ReduceMean. + ... + [Convert Over] +``` + +For non-transformed operators, suggestions are provided in the report. For instance, MindConverter suggests that replace `torch.nn.AdaptiveAvgPool2d` with `mindspore.ops.operations.ReduceMean`. + + +### Graph-Based Conversion + +Assume the PyTorch model (.pth file) is located at `/home/user/model.pth`, with input shape (3, 224, 224) and the original PyTorch script is at `/home/user/project/model_training`. Output the transformed MindSpore script to `/home/user/output`, with the conversion report to `/home/user/output/report`. Use the following command: + +```bash +mindconverter --model_file /home/user/model.pth --shape 3,224,224 \ + --output /home/user/output \ + --report /home/user/output/report \ + --project_path /home/user/project/model_training +``` + +The Graph mode has the same conversion report as the AST mode. However, the line number and column number refer to the transformed scripts since no original scripts are used in the process. + +In addition, input and output Tensor shape of unconverted operators shows explicitly (`input_shape` and `output_shape`) as comments in converted scripts to help further manual modifications. Here is an example of the `Reshape` operator (Not supported in current version): + +```python +class Classifier(nn.Cell): + + def __init__(self): + super(Classifier, self).__init__() + ... + self.reshape = onnx.Reshape(input_shape=(1, 1280, 1, 1), + output_shape=(1, 1280)) + ... + + def construct(self, x): + ... + # Suppose input of `reshape` is x. + reshape_output = self.reshape(x) + ... + +``` + +It is convenient to replace the operators according to the `input_shape` and `output_shape` parameters. The replacement is like this: + +```python +from mindspore.ops import operations as P +... + +class Classifier(nn.Cell): + + def __init__(self): + super(Classifier, self).__init__() + ... + self.reshape = P.Reshape(input_shape=(1, 1280, 1, 1), + output_shape=(1, 1280)) + ... + + def construct(self, x): + ... + # Suppose input of `reshape` is x. + reshape_output = self.reshape(x, (1, 1280)) + ... + +``` + +> Note: `--output` and `--report` are optional. MindConverter creates an `output` folder under the current working directory, and outputs generated scripts and conversion reports to it. + + +## Caution + +1. PyTorch is not an explicitly stated dependency library in MindInsight. The Graph conversion requires the consistent PyTorch version as the model is trained. (MindConverter recommends PyTorch 1.4.0 or 1.6.0) +2. This script conversion tool relies on operators which supported by MindConverter and MindSpore. Unsupported operators may not successfully mapped to MindSpore operators. You can manually edit, or implement the mapping based on MindConverter, and contribute to our MindInsight repository. We appreciate your support for the MindSpore community. + + diff --git a/tutorials/training/source_en/index.rst b/tutorials/training/source_en/index.rst index fc6aa64a29..ab5b5182ec 100644 --- a/tutorials/training/source_en/index.rst +++ b/tutorials/training/source_en/index.rst @@ -36,7 +36,7 @@ Train with MindSpore .. toctree:: :glob: :maxdepth: 1 - :caption: + :caption: advanced_use/custom_operator advanced_use/migrate_script @@ -67,6 +67,8 @@ Train with MindSpore :caption: Network Migration advanced_use/network_migration + advanced_use/migrate_3rd_scripts_mindconverter + .. toctree:: :glob: -- Gitee From ba685b536dbd7b2b0b40d5bcdaa261e2c4981f49 Mon Sep 17 00:00:00 2001 From: chenfei Date: Thu, 17 Sep 2020 20:49:00 +0800 Subject: [PATCH 071/100] change discription of readme of quant --- .../source_en/operator_list.md | 11 ++++++ .../source_zh_cn/operator_list_ms.md | 15 ++++++-- .../apply_quantization_aware_training.md | 36 +++++++++---------- .../apply_quantization_aware_training.md | 36 +++++++++---------- 4 files changed, 58 insertions(+), 40 deletions(-) diff --git a/docs/programming_guide/source_en/operator_list.md b/docs/programming_guide/source_en/operator_list.md index 680dc94188..b50fdcb41f 100644 --- a/docs/programming_guide/source_en/operator_list.md +++ b/docs/programming_guide/source_en/operator_list.md @@ -65,6 +65,17 @@ | [mindspore.nn.AvgPool2d](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.AvgPool2d) | Supported | Supported | Doing |layer/pooling | [mindspore.nn.DenseBnAct](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DenseBnAct) |Supported | Doing | Doing |layer/quant | [mindspore.nn.Conv2dBnAct](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnAct) | Supported | Supported | Doing |layer/quant +| [mindspore.nn.FakeQuantWithMinMax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.FakeQuantWithMinMax) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dBnFoldQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnFoldQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dBnWithoutFoldQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnWithoutFoldQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.DenseQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DenseQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.ActQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.ActQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.LeakyReLUQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.LeakyReLUQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.HSwishQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.HSwishQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.HSigmoidQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.HSigmoidQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.TensorAddQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.TensorAddQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.MulQuant](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.MulQuant) | Supported | Supported | Supported |layer/quant | [mindspore.nn.L1Loss](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.L1Loss) |Supported |Supported | Doing |loss/loss | [mindspore.nn.MSELoss](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.MSELoss) | Supported |Doing | Doing |loss/loss | [mindspore.nn.SmoothL1Loss](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.SmoothL1Loss) |Supported |Doing | Doing |loss/loss diff --git a/docs/programming_guide/source_zh_cn/operator_list_ms.md b/docs/programming_guide/source_zh_cn/operator_list_ms.md index 66b700633c..8ae072ecd4 100644 --- a/docs/programming_guide/source_zh_cn/operator_list_ms.md +++ b/docs/programming_guide/source_zh_cn/operator_list_ms.md @@ -63,8 +63,19 @@ | [mindspore.nn.LinSpace](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.LinSpace) | Supported | Doing | Doing | layer/normalization | [mindspore.nn.MaxPool2d](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.MaxPool2d) | Supported | Supported | Supported |layer/pooling | [mindspore.nn.AvgPool2d](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.AvgPool2d) | Supported | Supported | Doing |layer/pooling -| [mindspore.nn.DenseBnAct](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DenseBnAct) |Supported | Doing | Doing |layer/quant -| [mindspore.nn.Conv2dBnAct](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnAct) | Supported | Supported | Doing |layer/quant +| [mindspore.nn.DenseBnAct](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DenseBnAct) |Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dBnAct](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnAct) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.FakeQuantWithMinMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.FakeQuantWithMinMax) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dBnFoldQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnFoldQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dBnWithoutFoldQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dBnWithoutFoldQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.Conv2dQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2dQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.DenseQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.DenseQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.ActQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.ActQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.LeakyReLUQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.LeakyReLUQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.HSwishQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.HSwishQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.HSigmoidQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.HSigmoidQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.TensorAddQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.TensorAddQuant) | Supported | Supported | Supported |layer/quant +| [mindspore.nn.MulQuant](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.MulQuant) | Supported | Supported | Supported |layer/quant | [mindspore.nn.L1Loss](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.L1Loss) |Supported |Supported | Doing |loss/loss | [mindspore.nn.MSELoss](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.MSELoss) | Supported |Doing | Doing |loss/loss | [mindspore.nn.SmoothL1Loss](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.SmoothL1Loss) | Supported |Doing | Doing |loss/loss diff --git a/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md index 1e7782a167..515ec8631b 100644 --- a/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md +++ b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md @@ -60,21 +60,19 @@ Aware quantization training specifications The procedure for the quantization aware training model is the same as that for the common training. After the network is defined and the model is generated, additional operations need to be performed. The complete process is as follows: 1. Process data and load datasets. -2. Define a network. -3. Define a fusion network. After a network is defined, replace the specified operators to define a fusion network. +2. Define an original unquantative network. +3. Define a fusion network. After defining a original unquantative network, replace the specified operators to define a fusion network. 4. Define an optimizer and loss function. -5. Perform model training. Generate a fusion model based on the fusion network training. -6. Generate a quantization network. After the fusion model is obtained based on the fusion network training, insert a fake quantization node into the fusion model by using a conversion API to generate a quantization network. -7. Perform quantization training. Generate a quantization model based on the quantization network training. +5. Generate a quantization network. Insert a fake quantization node into the fusion network by using a conversion API, a quantization network will be generated based on the fusion network. +6. Perform quantization training. Generate a quantization model based on the quantization network training. -Compared with common training, the quantization aware training requires additional steps which are steps 3, 6, and 7 in the preceding process. +Compared with common training, the quantization aware training requires additional steps which are steps 3, 5, and 6 in the preceding process. > - Fusion network: network after the specified operators (`nn.Conv2dBnAct` and `nn.DenseBnAct`) are used for replacement. -> - Fusion model: model in the checkpoint format generated by the fusion network training. > - Quantization network: network obtained after the fusion model uses a conversion API (`convert_quant_network`) to insert a fake quantization node. > - Quantization model: model in the checkpoint format obtained after the quantization network training. -Next, the LeNet network is used as an example to describe steps 3 and 6. +Next, the LeNet network is used as an example to describe steps 2 and 3. > You can obtain the complete executable sample code at . @@ -132,8 +130,8 @@ class LeNet5(nn.Cell): super(LeNet5, self).__init__() self.num_class = num_class - self.conv1 = nn.Conv2dBnAct(1, 6, kernel_size=5, batchnorm=True, activation='relu') - self.conv2 = nn.Conv2dBnAct(6, 16, kernel_size=5, batchnorm=True, activation='relu') + self.conv1 = nn.Conv2dBnAct(1, 6, kernel_size=5, activation='relu') + self.conv2 = nn.Conv2dBnAct(6, 16, kernel_size=5, activation='relu') self.fc1 = nn.DenseBnAct(16 * 5 * 5, 120, activation='relu') self.fc2 = nn.DenseBnAct(120, 84, activation='relu') @@ -155,9 +153,9 @@ class LeNet5(nn.Cell): Use the `convert_quant_network` API to automatically insert a fake quantization node into the fusion model to convert the fusion model into a quantization network. ```python -from mindspore.train.quant import quant as qat +from mindspore.train.quant import quant -net = qat.convert_quant_network(net, quant_delay=0, bn_fold=False, freeze_bn=10000, weight_bits=8, act_bits=8) +net = quant.convert_quant_network(network, quant_delay=900, bn_fold=False, per_channel=[True, False], symmetric=[False, False]) ``` ## Retraining and Inference @@ -167,16 +165,16 @@ net = qat.convert_quant_network(net, quant_delay=0, bn_fold=False, freeze_bn=100 The preceding describes the quantization aware training from scratch. A more common case is that an existing model file needs to be converted to a quantization model. The model file and training script obtained through common network model training are available for quantization aware training. To use a checkpoint file for retraining, perform the following steps: 1. Process data and load datasets. - 2. Define a network. - 3. Define a fusion network. - 4. Define an optimizer and loss function. - 5. Load a model file and retrain the model. Load an existing model file and retrain the model based on the fusion network to generate a fusion model. For details, see . - 6. Generate a quantization network. - 7. Perform quantization training. + 2. Define an original unquantative network. + 3. Train the original network to generate a unquantative model. + 4. Define a fusion network. + 5. Define an optimizer and loss function. + 6. Generate a quantative network based on the fusion network. + 7. Load a model file and retrain the model. Load the unquantative model file generated in step 3 and retrain the quantative model based on the quantative network to generate a quantative model. For details, see . ### Inference -The inference using a quantization model is the same as common model inference. The inference can be performed by directly using the checkpoint file or converting the checkpoint file into a common model format (such as ONNX or AIR). +The inference using a quantization model is the same the common model inference. The inference can be performed by directly using the checkpoint file or converting the checkpoint file into a common model format (such as ONNX or MINDIR). For details, see . diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md index 283146a888..d86d2360da 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_quantization_aware_training.md @@ -60,21 +60,19 @@ MindSpore的感知量化训练是在训练基础上,使用低精度数据替 感知量化训练模型与一般训练步骤一致,在定义网络和最后生成模型阶段后,需要进行额外的操作,完整流程如下: 1. 数据处理加载数据集。 -2. 定义网络。 -3. 定义融合网络。在完成定义网络后,替换指定的算子,完成融合网络的定义。 +2. 定义原始非量化网络。 +3. 定义融合网络。在完成定义原始非量化网络后,替换指定的算子,完成融合网络的定义。 4. 定义优化器和损失函数。 -5. 进行模型训练。基于融合网络训练生成融合模型。 -6. 转化量化网络。基于融合网络训练后得到的融合模型,使用转化接口在融合模型中插入伪量化节点,生成的量化网络。 -7. 进行量化训练。基于量化网络训练,生成量化模型。 +5. 转化量化网络。基于融合网络,使用转化接口在融合网络中插入伪量化节点,生成量化网络。 +6. 进行量化训练。基于量化网络训练,生成量化模型。 -在上面流程中,第3、6、7步是感知量化训练区别普通训练需要额外进行的步骤。 +在上面流程中,第3、5、6步是感知量化训练区别普通训练需要额外进行的步骤。 > - 融合网络:使用指定算子(`nn.Conv2dBnAct`、`nn.DenseBnAct`)替换后的网络。 -> - 融合模型:使用融合网络训练生成的checkpoint格式的模型。 > - 量化网络:融合模型使用转换接口(`convert_quant_network`)插入伪量化节点后得到的网络。 > - 量化模型:量化网络训练后得到的checkpoint格式的模型。 -接下来,以LeNet网络为例,展开叙述3、6两个步骤。 +接下来,以LeNet网络为例,展开叙述2、3两个步骤。 > 你可以在这里找到完整可运行的样例代码: 。 @@ -132,8 +130,8 @@ class LeNet5(nn.Cell): super(LeNet5, self).__init__() self.num_class = num_class - self.conv1 = nn.Conv2dBnAct(1, 6, kernel_size=5, batchnorm=True, activation='relu') - self.conv2 = nn.Conv2dBnAct(6, 16, kernel_size=5, batchnorm=True, activation='relu') + self.conv1 = nn.Conv2dBnAct(1, 6, kernel_size=5, activation='relu') + self.conv2 = nn.Conv2dBnAct(6, 16, kernel_size=5, activation='relu') self.fc1 = nn.DenseBnAct(16 * 5 * 5, 120, activation='relu') self.fc2 = nn.DenseBnAct(120, 84, activation='relu') @@ -155,9 +153,9 @@ class LeNet5(nn.Cell): 使用`convert_quant_network`接口自动在融合模型中插入伪量化节点,将融合模型转化为量化网络。 ```python -from mindspore.train.quant import quant as qat +from mindspore.train.quant import quant -net = qat.convert_quant_network(net, quant_delay=0, bn_fold=False, freeze_bn=10000, weight_bits=8, act_bits=8) +net = quant.convert_quant_network(network, quant_delay=900, bn_fold=False, per_channel=[True, False], symmetric=[False, False]) ``` ## 重训和推理 @@ -167,16 +165,16 @@ net = qat.convert_quant_network(net, quant_delay=0, bn_fold=False, freeze_bn=100 上面介绍了从零开始进行感知量化训练。更常见情况是已有一个模型文件,希望生成量化模型,这时已有正常网络模型训练得到的模型文件及训练脚本,进行感知量化训练。这里使用checkpoint文件重新训练的功能,详细步骤为: 1. 数据处理加载数据集。 - 2. 定义网络。 - 3. 定义融合网络。 - 4. 定义优化器和损失函数。 - 5. 加载模型文件模型重训。加载已有模型文件,基于融合网络重新训练生成融合模型。详细模型重载训练,请参见 - 6. 转化量化网络。 - 7. 进行量化训练。 + 2. 定义原始非量化网络。 + 3. 训练原始网络生成非量化模型。 + 4. 定义融合网络。 + 5. 定义优化器和损失函数。 + 6. 基于融合网络转化生成量化网络。 + 7. 加载模型文件重训。加载已有非量化模型文件,基于量化网络重新训练生成量化模型。详细模型重载训练,请参见。 ### 进行推理 -使用量化模型进行推理,与普通模型推理一致,分为直接checkpoint文件推理及转化为通用模型格式(ONNX、AIR等)进行推理。 +使用量化模型进行推理,与普通模型推理一致,分为直接checkpoint文件推理及转化为通用模型格式(ONNX、MINDIR等)进行推理。 > 推理详细说明请参见 -- Gitee From c15caf70fb58f7a2f597ac9db616b8742b20cb92 Mon Sep 17 00:00:00 2001 From: yepei6 Date: Thu, 17 Sep 2020 19:44:48 +0800 Subject: [PATCH 072/100] mobilenetv2 update checkpoint download link --- .../cv_mobilenetv2_incremental_learning.md | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md b/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md index ef0e0843e7..704cae1b31 100644 --- a/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md +++ b/tutorials/training/source_zh_cn/advanced_use/cv_mobilenetv2_incremental_learning.md @@ -1,4 +1,5 @@ # 使用MobileNetV2网络实现增量学习 + `Windows` `Linux` `CPU` `Ascend` `GPU` `模型开发` `中级` `高级` @@ -147,13 +148,22 @@ cd ./mindspore/model_zoo/official/cv/mobilenetv2 ### 准备预训练模型 -[下载预训练模型](https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ckpt)到以下目录: +用户需要根据不同处理器种类[下载CPU/GPU预训练模型](https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2_cpu_gpu.ckpt)或[下载Ascend预训练模型](https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2_ascend.ckpt)到以下目录: `./pretrain_checkpoint/` -```bash -mkdir pretrain_checkpoint -wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2.ckpt -``` +- CPU/GPU 处理器 + + ```bash + mkdir pretrain_checkpoint + wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2_cpu_gpu.ckpt + ``` + +- Ascend AI处理器 + + ```bash + mkdir pretrain_checkpoint + wget -P ./pretrain_checkpoint https://download.mindspore.cn/model_zoo/official/lite/mobilenetv2_openimage_lite/mobilenetv2_ascend.ckpt + ``` ### 准备数据 -- Gitee From f1cdb38185d12d32f20ee160ca343914f8882b3b Mon Sep 17 00:00:00 2001 From: liuxiao78 Date: Thu, 17 Sep 2020 20:20:37 +0800 Subject: [PATCH 073/100] fix converter tool --- tutorials/lite/source_zh_cn/use/converter_tool.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tutorials/lite/source_zh_cn/use/converter_tool.md b/tutorials/lite/source_zh_cn/use/converter_tool.md index 682e996fe7..16f3a4f0a8 100644 --- a/tutorials/lite/source_zh_cn/use/converter_tool.md +++ b/tutorials/lite/source_zh_cn/use/converter_tool.md @@ -106,10 +106,15 @@ MindSpore Lite模型转换工具提供了多种参数设置,用户可根据需 | `--modelFile=` | 是 | 输入模型的路径。 | - | - | | `--outputFile=` | 是 | 输出模型的路径(不存在时将自动创建目录),不需加后缀,可自动生成`.ms`后缀。 | - | - | | `--weightFile=` | 转换Caffe模型时必选 | 输入模型weight文件的路径。 | - | - | -| `--quantType=` | 否 | 设置模型的量化类型。 | PostTraining:训练后量化
      AwareTraining:感知量化。 | - | +| `--quantType=` | 否 | 设置模型的量化类型。 | WeightQuant:训练后量化(权重量化)
      PostTraining:训练后量化(全量化)
      AwareTraining:感知量化 | - | |` --inferenceType=` | 否 | 设置感知量化模型输入输出数据类型,如果和原模型不一致则转换工具会在模型前插转换算子,使得转换后的模型输入类型和inferenceType保持一致。 | UINT8、FLOAT、INT8 | FLOAT | | `--stdDev= `| 否 | 感知量化模型转换时用于设置输入数据的标准差。 | (0,+∞) | 128 | | `--mean=` | 否 | 感知量化模型转换时用于设置输入数据的均值。 | [-128, 127] | -0.5 | +| `--bitNum=` | 否 | 设定训练后量化(权重量化)的比特数,目前仅支持8bit量化 | 8 | 8 | +| `--quantSize=` | 否 | 设定参与训练后量化(权重量化)的卷积核尺寸阈值,若卷积核尺寸大于该值,则对此权重进行量化 | (0,+∞) | 0 | +| `--convWeightQuantChannelThreshold=` | 否 | 设定参与训练后量化(权重量化)的卷积通道数阈值,若卷积通道数大于该值,则对此权重进行量化 | (0,+∞) | 16 | +| `--config_file=` | 否 | 训练后量化(全量化)校准数据集配置文件路径 | - | - | + > - 参数名和参数值之间用等号连接,中间不能有空格。 > - Caffe模型一般分为两个文件:`*.prototxt`模型结构,对应`--modelFile`参数;`*.caffemodel`模型权值,对应`--weightFile`参数。 -- Gitee From bef2c529adf288c02b00b668dfe677f1e5a63bc2 Mon Sep 17 00:00:00 2001 From: jin-xiulang Date: Fri, 18 Sep 2020 10:24:48 +0800 Subject: [PATCH 074/100] Modify some inference invokings for mindamour/improve_model_security_nad.md. --- tutorials/notebook/model_security.ipynb | 6 +- .../improve_model_security_nad.md | 13 +-- .../improve_model_security_nad.md | 15 +-- .../model_safety/mnist_attack_fgsm.py | 48 ++++----- .../model_safety/mnist_defense_nad.py | 99 +++++++++---------- 5 files changed, 84 insertions(+), 97 deletions(-) diff --git a/tutorials/notebook/model_security.ipynb b/tutorials/notebook/model_security.ipynb index bac7061f0b..e63f9c1f37 100644 --- a/tutorials/notebook/model_security.ipynb +++ b/tutorials/notebook/model_security.ipynb @@ -589,7 +589,7 @@ "outputs": [], "source": [ "import time\n", - "from mindarmour.attacks.gradient_method import FastGradientSignMethod\n", + "from mindarmour.adv_robustness.attacks import FastGradientSignMethod\n", "\n", "\n", "# attacking\n", @@ -635,7 +635,7 @@ ], "source": [ "from scipy.special import softmax\n", - "from mindarmour.evaluations.attack_evaluation import AttackEvaluate\n", + "from mindarmour.adv_robustness.evaluations import AttackEvaluate\n", "\n", "\n", "pred_logits_adv = model.predict(Tensor(adv_data)).asnumpy()\n", @@ -749,7 +749,7 @@ ], "source": [ "from mindspore.nn import SoftmaxCrossEntropyWithLogits\n", - "from mindarmour.defenses import NaturalAdversarialDefense\n", + "from mindarmour.adv_robustness.defenses import NaturalAdversarialDefense\n", "\n", "\n", "loss = SoftmaxCrossEntropyWithLogits(sparse=False, reduction='mean')\n", diff --git a/tutorials/training/source_en/advanced_use/improve_model_security_nad.md b/tutorials/training/source_en/advanced_use/improve_model_security_nad.md index d6e6415b31..b74fbcf918 100644 --- a/tutorials/training/source_en/advanced_use/improve_model_security_nad.md +++ b/tutorials/training/source_en/advanced_use/improve_model_security_nad.md @@ -17,7 +17,7 @@ - + ## Overview @@ -31,7 +31,8 @@ At the beginning of AI algorithm design, related security threats are sometimes This section describes how to use MindArmour in adversarial attack and defense by taking the Fast Gradient Sign Method (FGSM) attack algorithm and Natural Adversarial Defense (NAD) algorithm as examples. -> The current sample is for CPU, GPU and Ascend 910 AI processor. You can find the complete executable sample code at: +> The current sample is for CPU, GPU and Ascend 910 AI processor. You can find the complete executable sample code at +>: > - `mnist_attack_fgsm.py`: contains attack code. > - `mnist_defense_nad.py`: contains defense code. @@ -59,9 +60,9 @@ from mindspore import Tensor from mindspore import context from mindspore.train.callback import LossMonitor -from mindarmour.attacks.gradient_method import FastGradientSignMethod +from mindarmour.adv_robustness.attacks import FastGradientSignMethod from mindarmour.utils.logger import LogUtil -from mindarmour.evaluations.attack_evaluation import AttackEvaluate +from mindarmour.adv_robustness.evaluations import AttackEvaluate context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") @@ -178,7 +179,7 @@ The LeNet model is used as an example. You can also create and train your own mo 2. Train LeNet model. Use the defined data loading function `generate_mnist_dataset` to load data. ```python - mnist_path = "./MNIST_unzip/" + mnist_path = "./MNIST/" batch_size = 32 # train original model ds_train = generate_mnist_dataset(os.path.join(mnist_path, "train"), @@ -297,7 +298,7 @@ Natural Adversarial Defense (NAD) is a simple and effective adversarial example Call the NAD API provided by MindArmour. ```python -from mindarmour.defenses import NaturalAdversarialDefense +from mindarmour.adv_robustness.defenses import NaturalAdversarialDefense # defense diff --git a/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md index 9d101729a3..0b26229cbb 100644 --- a/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md +++ b/tutorials/training/source_zh_cn/advanced_use/improve_model_security_nad.md @@ -17,8 +17,8 @@ -   - +   + ## 概述 @@ -31,7 +31,8 @@ AI算法设计之初普遍未考虑相关的安全威胁,使得AI算法的判 这里通过图像分类任务上的对抗性攻防,以攻击算法FGSM和防御算法NAD为例,介绍MindArmour在对抗攻防上的使用方法。 -> 本例面向CPU、GPU、Ascend 910 AI处理器,你可以在这里下载完整的样例代码: +> 本例面向CPU、GPU、Ascend 910 AI处理器,你可以在这里下载完整的样例代码:/model_safety> > - `mnist_attack_fgsm.py`:包含攻击代码。 > - `mnist_defense_nad.py`:包含防御代码。 @@ -59,9 +60,9 @@ from mindspore import Tensor from mindspore import context from mindspore.train.callback import LossMonitor -from mindarmour.attacks.gradient_method import FastGradientSignMethod +from mindarmour.adv_robustness.attacks import FastGradientSignMethod from mindarmour.utils.logger import LogUtil -from mindarmour.evaluations.attack_evaluation import AttackEvaluate +from mindarmour.adv_robustness.evaluations import AttackEvaluate context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") @@ -178,7 +179,7 @@ def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1, 2. 训练LeNet模型。利用上面定义的数据加载函数`generate_mnist_dataset`载入数据。 ```python - mnist_path = "./MNIST_unzip/" + mnist_path = "./MNIST/" batch_size = 32 # train original model ds_train = generate_mnist_dataset(os.path.join(mnist_path, "train"), @@ -296,7 +297,7 @@ NaturalAdversarialDefense(NAD)是一种简单有效的对抗样本防御方 调用MindArmour提供的NAD防御接口(NaturalAdversarialDefense)。 ```python -from mindarmour.defenses import NaturalAdversarialDefense +from mindarmour.adv_robustness.defenses import NaturalAdversarialDefense # defense diff --git a/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py b/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py index 743b083ace..7c8517dd07 100644 --- a/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py +++ b/tutorials/tutorial_code/model_safety/mnist_attack_fgsm.py @@ -11,57 +11,42 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -""" -mnist_attack_fgsm -The sample can be run on Ascend 910 AI processor. -""" -import sys import time import numpy as np -import pytest from scipy.special import softmax from mindspore import Model from mindspore import Tensor from mindspore import context from mindspore.train.serialization import load_checkpoint, load_param_into_net +from mindspore.nn import SoftmaxCrossEntropyWithLogits -from mindarmour.attacks.gradient_method import FastGradientSignMethod - +from mindarmour.adv_robustness.attacks import FastGradientSignMethod +from mindarmour.adv_robustness.evaluations import AttackEvaluate from mindarmour.utils.logger import LogUtil -from mindarmour.evaluations.attack_evaluation import AttackEvaluate - -from lenet5_net import LeNet5 - -context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") - -sys.path.append("..") -from data_processing import generate_mnist_dataset +from examples.common.networks.lenet5.lenet5_net import LeNet5 +from examples.common.dataset.data_processing import generate_mnist_dataset LOGGER = LogUtil.get_instance() +LOGGER.set_level('INFO') TAG = 'FGSM_Test' -@pytest.mark.level1 -@pytest.mark.platform_arm_ascend_training -@pytest.mark.platform_x86_ascend_training -@pytest.mark.env_card -@pytest.mark.component_mindarmour def test_fast_gradient_sign_method(): """ - FGSM-Attack test + FGSM-Attack test for CPU device. """ # upload trained network - ckpt_name = './trained_ckpt_file/checkpoint_lenet-10_1875.ckpt' + ckpt_path = '../../../common/networks/lenet5/trained_ckpt_file/checkpoint_lenet-10_1875.ckpt' net = LeNet5() - load_dict = load_checkpoint(ckpt_name) + load_dict = load_checkpoint(ckpt_path) load_param_into_net(net, load_dict) # get test data - data_list = "./MNIST_unzip/test" + data_list = "../../../common/dataset/MNIST/test" batch_size = 32 - ds = generate_mnist_dataset(data_list, batch_size, sparse=False) + ds = generate_mnist_dataset(data_list, batch_size) # prediction accuracy before attack model = Model(net) @@ -82,15 +67,16 @@ def test_fast_gradient_sign_method(): if i >= batch_num: break predict_labels = np.concatenate(predict_labels) - true_labels = np.argmax(np.concatenate(test_labels), axis=1) + true_labels = np.concatenate(test_labels) accuracy = np.mean(np.equal(predict_labels, true_labels)) LOGGER.info(TAG, "prediction accuracy before attacking is : %s", accuracy) # attacking - attack = FastGradientSignMethod(net, eps=0.3) + loss = SoftmaxCrossEntropyWithLogits(sparse=True) + attack = FastGradientSignMethod(net, eps=0.3, loss_fn=loss) start_time = time.clock() adv_data = attack.batch_generate(np.concatenate(test_images), - np.concatenate(test_labels), batch_size=32) + true_labels, batch_size=32) stop_time = time.clock() np.save('./adv_data', adv_data) pred_logits_adv = model.predict(Tensor(adv_data)).asnumpy() @@ -100,7 +86,7 @@ def test_fast_gradient_sign_method(): accuracy_adv = np.mean(np.equal(pred_labels_adv, true_labels)) LOGGER.info(TAG, "prediction accuracy after attacking is : %s", accuracy_adv) attack_evaluate = AttackEvaluate(np.concatenate(test_images).transpose(0, 2, 3, 1), - np.concatenate(test_labels), + np.eye(10)[true_labels], adv_data.transpose(0, 2, 3, 1), pred_logits_adv) LOGGER.info(TAG, 'mis-classification rate of adversaries is : %s', @@ -120,4 +106,6 @@ def test_fast_gradient_sign_method(): if __name__ == '__main__': + # device_target can be "CPU", "GPU" or "Ascend" + context.set_context(mode=context.GRAPH_MODE, device_target="CPU") test_fast_gradient_sign_method() diff --git a/tutorials/tutorial_code/model_safety/mnist_defense_nad.py b/tutorials/tutorial_code/model_safety/mnist_defense_nad.py index 3c19eeed38..3871e0f9fc 100644 --- a/tutorials/tutorial_code/model_safety/mnist_defense_nad.py +++ b/tutorials/tutorial_code/model_safety/mnist_defense_nad.py @@ -11,63 +11,49 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Defense example using nad -The sample can be run on CPU, GPU and Ascend 910 AI processor. -""" -import sys - -import logging +"""defense example using nad""" +import os import numpy as np -import pytest - from mindspore import Tensor from mindspore import context from mindspore import nn from mindspore.nn import SoftmaxCrossEntropyWithLogits -from mindspore.train.serialization import load_checkpoint, load_param_into_net +from mindspore.train import Model +from mindspore.train.callback import LossMonitor -from mindarmour.attacks import FastGradientSignMethod -from mindarmour.defenses import NaturalAdversarialDefense +from mindarmour.adv_robustness.attacks import FastGradientSignMethod +from mindarmour.adv_robustness.defenses import NaturalAdversarialDefense from mindarmour.utils.logger import LogUtil -from lenet5_net import LeNet5 - -sys.path.append("..") -from data_processing import generate_mnist_dataset +from examples.common.networks.lenet5.lenet5_net import LeNet5 +from examples.common.dataset.data_processing import generate_mnist_dataset -context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") LOGGER = LogUtil.get_instance() +LOGGER.set_level("INFO") TAG = 'Nad_Example' -@pytest.mark.level1 -@pytest.mark.platform_arm_ascend_training -@pytest.mark.platform_x86_ascend_training -@pytest.mark.env_card -@pytest.mark.component_mindarmour def test_nad_method(): """ NAD-Defense test. """ - # 1. load trained network - ckpt_name = './trained_ckpt_file/checkpoint_lenet-10_1875.ckpt' + mnist_path = "../../common/dataset/MNIST" + batch_size = 32 + # 1. train original model + ds_train = generate_mnist_dataset(os.path.join(mnist_path, "train"), + batch_size=batch_size, repeat_size=1) net = LeNet5() - load_dict = load_checkpoint(ckpt_name) - load_param_into_net(net, load_dict) - - loss = SoftmaxCrossEntropyWithLogits(sparse=False) + loss = SoftmaxCrossEntropyWithLogits(sparse=True) opt = nn.Momentum(net.trainable_params(), 0.01, 0.09) - - nad = NaturalAdversarialDefense(net, loss_fn=loss, optimizer=opt, - bounds=(0.0, 1.0), eps=0.3) + model = Model(net, loss, opt, metrics=None) + model.train(10, ds_train, callbacks=[LossMonitor()], + dataset_sink_mode=False) # 2. get test data - data_list = "./MNIST_unzip/test" - batch_size = 32 - ds_test = generate_mnist_dataset(data_list, batch_size=batch_size, - sparse=False) + ds_test = generate_mnist_dataset(os.path.join(mnist_path, "test"), + batch_size=batch_size, repeat_size=1) inputs = [] labels = [] for data in ds_test.create_tuple_iterator(): @@ -82,36 +68,46 @@ def test_nad_method(): batchs = inputs.shape[0] // batch_size for i in range(batchs): batch_inputs = inputs[i*batch_size : (i + 1)*batch_size] - batch_labels = np.argmax(labels[i*batch_size : (i + 1)*batch_size], axis=1) + batch_labels = labels[i*batch_size : (i + 1)*batch_size] logits = net(Tensor(batch_inputs)).asnumpy() label_pred = np.argmax(logits, axis=1) acc_list.append(np.mean(batch_labels == label_pred)) - LOGGER.debug(TAG, 'accuracy of TEST data on original model is : %s', - np.mean(acc_list)) + LOGGER.info(TAG, 'accuracy of TEST data on original model is : %s', + np.mean(acc_list)) # 4. get adv of test data - attack = FastGradientSignMethod(net, eps=0.3) + attack = FastGradientSignMethod(net, eps=0.3, loss_fn=loss) adv_data = attack.batch_generate(inputs, labels) - LOGGER.debug(TAG, 'adv_data.shape is : %s', adv_data.shape) + LOGGER.info(TAG, 'adv_data.shape is : %s', adv_data.shape) # 5. get accuracy of adv data on original model - net.set_train(False) acc_list = [] batchs = adv_data.shape[0] // batch_size for i in range(batchs): batch_inputs = adv_data[i*batch_size : (i + 1)*batch_size] - batch_labels = np.argmax(labels[i*batch_size : (i + 1)*batch_size], axis=1) + batch_labels = labels[i*batch_size : (i + 1)*batch_size] logits = net(Tensor(batch_inputs)).asnumpy() label_pred = np.argmax(logits, axis=1) acc_list.append(np.mean(batch_labels == label_pred)) - LOGGER.debug(TAG, 'accuracy of adv data on original model is : %s', - np.mean(acc_list)) + LOGGER.info(TAG, 'accuracy of adv data on original model is : %s', + np.mean(acc_list)) # 6. defense + ds_train = generate_mnist_dataset(os.path.join(mnist_path, "train"), + batch_size=batch_size, repeat_size=1) + inputs_train = [] + labels_train = [] + for data in ds_train.create_tuple_iterator(): + inputs_train.append(data[0].asnumpy().astype(np.float32)) + labels_train.append(data[1].asnumpy()) + inputs_train = np.concatenate(inputs_train) + labels_train = np.concatenate(labels_train) net.set_train() - nad.batch_defense(inputs, labels, batch_size=32, epochs=10) + nad = NaturalAdversarialDefense(net, loss_fn=loss, optimizer=opt, + bounds=(0.0, 1.0), eps=0.3) + nad.batch_defense(inputs_train, labels_train, batch_size=32, epochs=10) # 7. get accuracy of test data on defensed model net.set_train(False) @@ -119,28 +115,29 @@ def test_nad_method(): batchs = inputs.shape[0] // batch_size for i in range(batchs): batch_inputs = inputs[i*batch_size : (i + 1)*batch_size] - batch_labels = np.argmax(labels[i*batch_size : (i + 1)*batch_size], axis=1) + batch_labels = labels[i*batch_size : (i + 1)*batch_size] logits = net(Tensor(batch_inputs)).asnumpy() label_pred = np.argmax(logits, axis=1) acc_list.append(np.mean(batch_labels == label_pred)) - LOGGER.debug(TAG, 'accuracy of TEST data on defensed model is : %s', - np.mean(acc_list)) + LOGGER.info(TAG, 'accuracy of TEST data on defensed model is : %s', + np.mean(acc_list)) # 8. get accuracy of adv data on defensed model acc_list = [] batchs = adv_data.shape[0] // batch_size for i in range(batchs): batch_inputs = adv_data[i*batch_size : (i + 1)*batch_size] - batch_labels = np.argmax(labels[i*batch_size : (i + 1)*batch_size], axis=1) + batch_labels = labels[i*batch_size : (i + 1)*batch_size] logits = net(Tensor(batch_inputs)).asnumpy() label_pred = np.argmax(logits, axis=1) acc_list.append(np.mean(batch_labels == label_pred)) - LOGGER.debug(TAG, 'accuracy of adv data on defensed model is : %s', - np.mean(acc_list)) + LOGGER.info(TAG, 'accuracy of adv data on defensed model is : %s', + np.mean(acc_list)) if __name__ == '__main__': - LOGGER.set_level(logging.DEBUG) + # device_target can be "CPU", "GPU" or "Ascend" + context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") test_nad_method() -- Gitee From 83134c50743d3a0e15206ec5b33a6f6083734b74 Mon Sep 17 00:00:00 2001 From: cj Date: Thu, 17 Sep 2020 14:25:23 +0800 Subject: [PATCH 075/100] LSTM API optimation --- tutorials/notebook/nlp_application.ipynb | 215 +++++++++++++++++++---- 1 file changed, 179 insertions(+), 36 deletions(-) diff --git a/tutorials/notebook/nlp_application.ipynb b/tutorials/notebook/nlp_application.ipynb index 47fa6ebe6d..d2df6a718d 100644 --- a/tutorials/notebook/nlp_application.ipynb +++ b/tutorials/notebook/nlp_application.ipynb @@ -673,17 +673,43 @@ "metadata": {}, "outputs": [], "source": [ + "import math\n", + "\n", "import numpy as np\n", - "from mindspore import Tensor, nn, context\n", - "from mindspore.ops import operations as P\n", - "from mindspore.train.serialization import load_param_into_net, load_checkpoint" + "\n", + "from mindspore import Tensor, nn, context, Parameter, ParameterTuple\n", + "from mindspore.common.initializer import initializer\n", + "from mindspore.ops import operations as P" ] }, + { + "cell_type": "markdown", + "source": [ + "2. 定义需要单层LSTM小算子堆叠的设备类型。" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "STACK_LSTM_DEVICE = [\"CPU\"]" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "2. 定义`lstm_default_state`函数来初始化网络参数及网络状态。" + "3. 定义`lstm_default_state`函数来初始化网络参数及网络状态。" ] }, { @@ -695,38 +721,144 @@ "# Initialize short-term memory (h) and long-term memory (c) to 0\n", "def lstm_default_state(batch_size, hidden_size, num_layers, bidirectional):\n", " \"\"\"init default input.\"\"\"\n", - " num_directions = 1\n", - " if bidirectional:\n", - " num_directions = 2\n", - "\n", - " if context.get_context(\"device_target\") == \"CPU\":\n", - " h_list = []\n", - " c_list = []\n", - " i = 0\n", - " while i < num_layers:\n", - " hi = Tensor(np.zeros((num_directions, batch_size, hidden_size)).astype(np.float32))\n", - " h_list.append(hi)\n", - " ci = Tensor(np.zeros((num_directions, batch_size, hidden_size)).astype(np.float32))\n", - " c_list.append(ci)\n", - " i = i + 1\n", - " h = tuple(h_list)\n", - " c = tuple(c_list)\n", - " return h, c\n", - "\n", - " h = Tensor(\n", - " np.zeros((num_layers * num_directions, batch_size, hidden_size)).astype(np.float32))\n", - " c = Tensor(\n", - " np.zeros((num_layers * num_directions, batch_size, hidden_size)).astype(np.float32))\n", + " num_directions = 2 if bidirectional else 1\n", + " h = Tensor(np.zeros((num_layers * num_directions, batch_size, hidden_size)).astype(np.float32))\n", + " c = Tensor(np.zeros((num_layers * num_directions, batch_size, hidden_size)).astype(np.float32))\n", " return h, c" ] }, + { + "cell_type": "markdown", + "source": [ + "4. 定义`stack_lstm_default_state`函数来初始化小算子堆叠需要的初始化网络参数及网络状态。" + ], + "metadata": { + "collapsed": false + } + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "def stack_lstm_default_state(batch_size, hidden_size, num_layers, bidirectional):\n", + " \"\"\"init default input.\"\"\"\n", + " num_directions = 2 if bidirectional else 1\n", + "\n", + " h_list = c_list = []\n", + " for _ in range(num_layers):\n", + " h_list.append(Tensor(np.zeros((num_directions, batch_size, hidden_size)).astype(np.float32)))\n", + " c_list.append(Tensor(np.zeros((num_directions, batch_size, hidden_size)).astype(np.float32)))\n", + " h, c = tuple(h_list), tuple(c_list)\n", + " return h, c\n" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "3. 使用`Cell`方法,定义网络结构(`SentimentNet`网络)。" + "5. 针对CPU场景,自定义单层LSTM小算子堆叠,来实现多层LSTM大算子功能。、" ] }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [ + "class StackLSTM(nn.Cell):\n", + " \"\"\"\n", + " Stack multi-layers LSTM together.\n", + " \"\"\"\n", + "\n", + " def __init__(self,\n", + " input_size,\n", + " hidden_size,\n", + " num_layers=1,\n", + " has_bias=True,\n", + " batch_first=False,\n", + " dropout=0.0,\n", + " bidirectional=False):\n", + " super(StackLSTM, self).__init__()\n", + " self.num_layers = num_layers\n", + " self.batch_first = batch_first\n", + " self.transpose = P.Transpose()\n", + "\n", + " # direction number\n", + " num_directions = 2 if bidirectional else 1\n", + "\n", + " # input_size list\n", + " input_size_list = [input_size]\n", + " for i in range(num_layers - 1):\n", + " input_size_list.append(hidden_size * num_directions)\n", + "\n", + " # layers\n", + " layers = []\n", + " for i in range(num_layers):\n", + " layers.append(nn.LSTMCell(input_size=input_size_list[i],\n", + " hidden_size=hidden_size,\n", + " has_bias=has_bias,\n", + " batch_first=batch_first,\n", + " bidirectional=bidirectional,\n", + " dropout=dropout))\n", + "\n", + " # weights\n", + " weights = []\n", + " for i in range(num_layers):\n", + " # weight size\n", + " weight_size = (input_size_list[i] + hidden_size) * num_directions * hidden_size * 4\n", + " if has_bias:\n", + " bias_size = num_directions * hidden_size * 4\n", + " weight_size = weight_size + bias_size\n", + "\n", + " # numpy weight\n", + " stdv = 1 / math.sqrt(hidden_size)\n", + " w_np = np.random.uniform(-stdv, stdv, (weight_size, 1, 1)).astype(np.float32)\n", + "\n", + " # lstm weight\n", + " weights.append(Parameter(initializer(Tensor(w_np), w_np.shape), name=\"weight\" + str(i)))\n", + "\n", + " #\n", + " self.lstms = layers\n", + " self.weight = ParameterTuple(tuple(weights))\n", + "\n", + " def construct(self, x, hx):\n", + " \"\"\"construct\"\"\"\n", + " if self.batch_first:\n", + " x = self.transpose(x, (1, 0, 2))\n", + " # stack lstm\n", + " h, c = hx\n", + " hn = cn = None\n", + " for i in range(self.num_layers):\n", + " x, hn, cn, _, _ = self.lstms[i](x, h[i], c[i], self.weight[i])\n", + " if self.batch_first:\n", + " x = self.transpose(x, (1, 0, 2))\n", + " return x, (hn, cn)" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + }, + { + "cell_type": "markdown", + "source": [ + "6. 使用`Cell`方法,定义网络结构(`SentimentNet`网络)。" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%% md\n" + } + } + }, { "cell_type": "code", "execution_count": 11, @@ -753,14 +885,25 @@ " self.embedding.embedding_table.requires_grad = False\n", " self.trans = P.Transpose()\n", " self.perm = (1, 0, 2)\n", - " self.encoder = nn.LSTM(input_size=embed_size,\n", - " hidden_size=num_hiddens,\n", - " num_layers=num_layers,\n", - " has_bias=True,\n", - " bidirectional=bidirectional,\n", - " dropout=0.0)\n", "\n", - " self.h, self.c = lstm_default_state(batch_size, num_hiddens, num_layers, bidirectional)\n", + " if context.get_context(\"device_target\") in STACK_LSTM_DEVICE:\n", + " # stack lstm by user\n", + " self.encoder = StackLSTM(input_size=embed_size,\n", + " hidden_size=num_hiddens,\n", + " num_layers=num_layers,\n", + " has_bias=True,\n", + " bidirectional=bidirectional,\n", + " dropout=0.0)\n", + " self.h, self.c = stack_lstm_default_state(batch_size, num_hiddens, num_layers, bidirectional)\n", + " else:\n", + " # standard lstm\n", + " self.encoder = nn.LSTM(input_size=embed_size,\n", + " hidden_size=num_hiddens,\n", + " num_layers=num_layers,\n", + " has_bias=True,\n", + " bidirectional=bidirectional,\n", + " dropout=0.0)\n", + " self.h, self.c = lstm_default_state(batch_size, num_hiddens, num_layers, bidirectional)\n", "\n", " self.concat = P.Concat(1)\n", " if bidirectional:\n", @@ -783,7 +926,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "4. 实例化`SentimentNet`,创建网络,此步骤用时约1分钟。" + "7. 实例化`SentimentNet`,创建网络,此步骤用时约1分钟。" ] }, { @@ -976,4 +1119,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file -- Gitee From 4e502c3f51a1fd30c020f0dba83792db6262fb59 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Fri, 18 Sep 2020 11:07:58 +0800 Subject: [PATCH 076/100] Fix the link for markdown --- .../advanced_use/apply_quantization_aware_training.md | 4 ++-- .../source_en/advanced_use/custom_debugging_info.md | 2 +- .../training/source_en/advanced_use/custom_operator.rst | 4 ++-- .../source_en/advanced_use/custom_operator_ascend.md | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md index 515ec8631b..d4c00e2f66 100644 --- a/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md +++ b/tutorials/training/source_en/advanced_use/apply_quantization_aware_training.md @@ -170,13 +170,13 @@ The preceding describes the quantization aware training from scratch. A more com 4. Define a fusion network. 5. Define an optimizer and loss function. 6. Generate a quantative network based on the fusion network. - 7. Load a model file and retrain the model. Load the unquantative model file generated in step 3 and retrain the quantative model based on the quantative network to generate a quantative model. For details, see . + 7. Load a model file and retrain the model. Load the unquantative model file generated in step 3 and retrain the quantative model based on the quantative network to generate a quantative model. For details, see . ### Inference The inference using a quantization model is the same the common model inference. The inference can be performed by directly using the checkpoint file or converting the checkpoint file into a common model format (such as ONNX or MINDIR). -For details, see . +For details, see . - To use a checkpoint file obtained after quantization aware training for inference, perform the following steps: diff --git a/tutorials/training/source_en/advanced_use/custom_debugging_info.md b/tutorials/training/source_en/advanced_use/custom_debugging_info.md index 0e580b00fb..8417be92e5 100644 --- a/tutorials/training/source_en/advanced_use/custom_debugging_info.md +++ b/tutorials/training/source_en/advanced_use/custom_debugging_info.md @@ -18,7 +18,7 @@ - + ## Overview diff --git a/tutorials/training/source_en/advanced_use/custom_operator.rst b/tutorials/training/source_en/advanced_use/custom_operator.rst index a2889e7882..f8fd7a9dd2 100644 --- a/tutorials/training/source_en/advanced_use/custom_operator.rst +++ b/tutorials/training/source_en/advanced_use/custom_operator.rst @@ -2,5 +2,5 @@ :maxdepth: 1 custom_operator_ascend - Custom Operator(GPU) - Custom Operator(CPU) \ No newline at end of file + Custom Operator(GPU) + Custom Operator(CPU) \ No newline at end of file diff --git a/tutorials/training/source_en/advanced_use/custom_operator_ascend.md b/tutorials/training/source_en/advanced_use/custom_operator_ascend.md index e1243ebaa1..f312d8fe66 100644 --- a/tutorials/training/source_en/advanced_use/custom_operator_ascend.md +++ b/tutorials/training/source_en/advanced_use/custom_operator_ascend.md @@ -16,7 +16,7 @@ - + ## Overview @@ -31,14 +31,14 @@ The related concepts are as follows: This section takes a Square operator as an example to describe how to customize an operator. -> For details, see cases in [tests/st/ops/custom_ops_tbe](https://gitee.com/mindspore/mindspore/tree/master/tests/st/ops/custom_ops_tbe) in the MindSpore source code. +> For details, see cases in [tests/st/ops/custom_ops_tbe](https://gitee.com/mindspore/mindspore/tree/r1.0/tests/st/ops/custom_ops_tbe) in the MindSpore source code. ## Registering the Operator Primitive The primitive of an operator is a subclass inherited from `PrimitiveWithInfer`. The type name of the subclass is the operator name. The definition of the custom operator primitive is the same as that of the built-in operator primitive. -- The attribute is defined by the input parameter of the constructor function `__init__`. The operator in this test case has no attribute. Therefore, `__init__` has only one input parameter. For details about test cases in which operators have attributes, see [custom add3](https://gitee.com/mindspore/mindspore/blob/master/tests/st/ops/custom_ops_tbe/cus_add3.py) in the MindSpore source code. +- The attribute is defined by the input parameter of the constructor function `__init__`. The operator in this test case has no attribute. Therefore, `__init__` has only one input parameter. For details about test cases in which operators have attributes, see [custom add3](https://gitee.com/mindspore/mindspore/blob/r1.0/tests/st/ops/custom_ops_tbe/cus_add3.py) in the MindSpore source code. - The input and output names are defined by the `init_prim_io_names` function. - The shape inference method of the output tensor is defined in the `infer_shape` function, and the dtype inference method of the output tensor is defined in the `infer_dtype` function. -- Gitee From b5cb22374af2a79af15a21363ab8fe1d888041ae Mon Sep 17 00:00:00 2001 From: Xiao Tianci Date: Thu, 17 Sep 2020 22:05:23 +0800 Subject: [PATCH 077/100] update_r1.0_to_master --- .../source_zh_cn/dataset_conversion.md | 8 +- tutorials/notebook/loading_dataset.ipynb | 8 +- ..._the_performance_of_data_preparation.ipynb | 2 +- .../advanced_use/converse_dataset.md | 29 +-- .../distributed_training_ascend.md | 14 +- .../advanced_use/enable_auto_augmentation.md | 4 +- .../source_zh_cn/advanced_use/enable_cache.md | 237 ------------------ .../images/data_conversion_concept.png | Bin 68261 -> 16993 bytes .../advanced_use/images/mindrecord.png | Bin 76130 -> 16840 bytes tutorials/training/source_zh_cn/index.rst | 5 +- .../source_zh_cn/use/load_dataset_image.md | 22 +- .../source_zh_cn/use/load_dataset_text.md | 19 +- 12 files changed, 45 insertions(+), 303 deletions(-) delete mode 100644 tutorials/training/source_zh_cn/advanced_use/enable_cache.md diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index dd0a6e097e..2e21a74b41 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -23,7 +23,7 @@ ## 非标准数据集转换MindRecord -下面主要介绍如何将CV类数据和NLP类数据转换为MindRecord,并通过`MindDataset`实现MindRecoed文件的读取。 +下面主要介绍如何将CV类数据和NLP类数据转换为MindRecord,并通过`MindDataset`实现MindRecord文件的读取。 ### 转换CV类数据集 @@ -87,9 +87,7 @@ print("Got {} samples".format(count)) ### 转换NLP类数据集 -> NLP类数据一般会先经过预处理转换为字典序,本示例只演示转换后的字典序数据如何写入MindRecord文件,而不包括预处理过程。 - -本示例主要介绍用户如何将自己的NLP类数据集转换成MindRecord,并使用`MindDataset`读取。 +本示例主要介绍用户如何将自己的NLP类数据集转换成MindRecord,并使用`MindDataset`读取。为了方便展示,此处略去了将文本转换成字典序的预处理过程。 本示例首先创建一个包含100条记录的MindRecord文件,其样本包含八个字段,均为整形数组,然后使用`MindDataset`读取该MindRecord文件。 @@ -120,7 +118,7 @@ writer.add_schema(nlp_schema, "it is a preprocessed nlp dataset") data = [] for i in range(100): i += 1 - + sample = {"source_sos_ids": np.array([i, i+1, i+2, i+3, i+4], dtype=np.int64), "source_sos_mask": np.array([i*1, i*2, i*3, i*4, i*5, i*6, i*7], dtype=np.int64), "source_eos_ids": np.array([i+5, i+6, i+7, i+8, i+9, i+10], dtype=np.int64), diff --git a/tutorials/notebook/loading_dataset.ipynb b/tutorials/notebook/loading_dataset.ipynb index 5fbe6d57b4..59161e12d1 100644 --- a/tutorials/notebook/loading_dataset.ipynb +++ b/tutorials/notebook/loading_dataset.ipynb @@ -8,7 +8,7 @@ "\n", "## 概述\n", "\n", - "MindSpore可以帮助你加载常见的数据集、特定数据格式的数据集或自定义的数据集。加载数据集时,需先导入所需要依赖的库`mindspore.dataset`。\n", + "MindSpore可以帮助你加载常用的数据集、特定数据格式的数据集或自定义的数据集。加载数据集时,需先导入所需要依赖的库`mindspore.dataset`。\n", "\n", "接下来,以加载数常用数据集(CIFAR-10数据集)、特定格式数据集以及自定义数据集为例来体验MindSpore加载数据集操作。" ] @@ -90,9 +90,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 加载常见的数据集\n", + "## 加载常用的数据集\n", "\n", - "MindSpore可以加载常见的标准数据集。支持的数据集如下表:\n", + "MindSpore可以加载常用的标准数据集。支持的数据集如下表:\n", "\n", "| 数据集: | 简要说明 |\n", "| :---------: | :-------------:|\n", @@ -103,7 +103,7 @@ "| PASCAL-VOC | 数据内容多样,可用于训练计算机视觉模型(分类、定位、检测、分割、动作识别等)。|\n", "| CelebA | CelebA人脸数据集包含上万个名人身份的人脸图片,每张图片有40个特征标记,常用于人脸相关的训练任务。 |\n", "\n", - "加载常见数据集的详细步骤如下,以创建`CIFAR-10`对象为例,用于加载支持的数据集。\n", + "加载常用数据集的详细步骤如下,以创建`CIFAR-10`对象为例,用于加载支持的数据集。\n", "\n", "1. 使用二进制格式的数据集(CIFAR-10 binary version),配置数据集目录,定义需要加载的数据集实例。" ] diff --git a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb index 11fc98b8c8..989d18b7f6 100644 --- a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb +++ b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb @@ -739,7 +739,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "提供某些融合算子,这些算子将两个或多个算子的功能聚合到一个算子中。具体内容请参考[数据增强算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.transforms.vision.html),与它们各自组件的流水线相比,这种融合算子提供了更好的性能。如图所示:" + "提供某些融合算子,这些算子将两个或多个算子的功能聚合到一个算子中。具体内容请参考[数据增强算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html),与它们各自组件的流水线相比,这种融合算子提供了更好的性能。如图所示:" ] }, { diff --git a/tutorials/training/source_zh_cn/advanced_use/converse_dataset.md b/tutorials/training/source_zh_cn/advanced_use/converse_dataset.md index 089f3b0d96..dfa913d51f 100644 --- a/tutorials/training/source_zh_cn/advanced_use/converse_dataset.md +++ b/tutorials/training/source_zh_cn/advanced_use/converse_dataset.md @@ -8,7 +8,6 @@ - [转换数据集为MindRecord](#转换数据集为mindrecord) - [概述](#概述) - [基本概念](#基本概念) - - [相关接口说明](#相关接口说明) - [将数据集转换为MindRecord](#将数据集转换为mindrecord) @@ -17,7 +16,7 @@ ## 概述 -用户可以将非标准的数据集和常见的经典数据集转换为MindSpore数据格式即MindRecord,从而方便地加载到MindSpore中进行训练。同时,MindSpore在部分场景做了性能优化,使用MindSpore数据格式可以获得更好的性能体验。 +用户可以将非标准的数据集和常用的数据集转换为MindSpore数据格式即MindRecord,从而方便地加载到MindSpore中进行训练。同时,MindSpore在部分场景做了性能优化,使用MindSpore数据格式可以获得更好的性能体验。 MindSpore数据格式具备的特征如下: 1. 实现多变的用户数据统一存储、访问,训练数据读取更简便; @@ -25,17 +24,17 @@ MindSpore数据格式具备的特征如下: 3. 高效数据编解码操作,对用户透明、无感知; 4. 灵活控制分区大小,实现分布式训练。 -MindSpore的目标是将用户的数据集通过归一化操作生成MindSpore数据格式,进一步通过MindDataset实现数据的读取,并用于训练过程。 +MindSpore数据格式的目标是归一化用户的数据集,并进一步通过MindDataset实现数据的读取,并用于训练过程。 ![data_conversion_concept](./images/data_conversion_concept.png) ## 基本概念 -一个MindRecord文件由数据文件和索引文件组成: +一个MindRecord文件由数据文件和索引文件组成,且数据文件及索引文件暂不支持重命名操作: - 数据文件 - 包含文件头、标量数据页、块数据页,用于存储用户归一化后的训练数据。 + 包含文件头、标量数据页、块数据页,用于存储用户归一化后的训练数据,且单个MindRecord文件建议小于20G,用户可将大数据集进行分片存储为多个MindRecord文件。 - 索引文件 @@ -49,31 +48,13 @@ MindSpore的目标是将用户的数据集通过归一化操作生成MindSpore 文件头主要用来存储文件头大小、标量数据页大小、块数据页大小、Schema信息、索引字段、统计信息、文件分区信息、标量数据与块数据对应关系等,是MindRecord文件的元信息。 - > Schema为数据集结构定义文件,用于定义数据集包含哪些字段以及字段的类型。更多说明及介绍可参考[Schema相关规范](#将数据集转换为mindrecord)。 - - 标量数据页 标量数据页主要用来存储整型、字符串、浮点型数据,如图像的Label、图像的文件名、图像的长宽等信息,即适合用标量来存储的信息会保存在这里。 - 块数据页 - 块数据页主要用来存储二进制串、Numpy数组等数据,如二进制图像文件本身、文本转换成的字典等。 - -## 相关接口说明 - -| 接口名 | 接口说明 | -| --- | --- | -| FileWriter | 用于将用户定义的原始数据写为MindRecord文件。 | -| FileReader | 用于读取MindRecord文件。 | -| MindPage | 用于实现MindSpore数据格式的检索及统计功能。 | -| Cifar10ToMR | 用于将CIFAR-10数据集转换为MindRecord格式。 | -| Cifar100ToMR | 用于将CIFAR-100数据集转换为MindRecord格式。 | -| ImageNetToMR | 用于将ImageNet数据集转换为MindRecord格式。 | -| MnistToMR | 用于将MNIST数据集转换为MindRecord格式。 | -| TFRecordToMR | 用于将TFRecord格式数据集文件转换为MindRecord格式。 | -| CsvToMR | 用于将CSV格式数据集文件转换为MindRecord格式。 | - -更多详细接口说明,请参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.mindrecord.html)。 + 块数据页主要用来存储二进制串、NumPy数组等数据,如二进制图像文件本身、文本转换成的字典等。 ## 将数据集转换为MindRecord diff --git a/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md b/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md index 7a87a80a81..835052e5b3 100644 --- a/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md +++ b/tutorials/training/source_zh_cn/advanced_use/distributed_training_ascend.md @@ -125,12 +125,12 @@ def create_dataset(data_path, repeat_num=1, batch_size=32, rank_id=0, rank_size= resize_width = 224 rescale = 1.0 / 255.0 shift = 0.0 - + # get rank_id and rank_size rank_id = get_rank() rank_size = get_group_size() data_set = ds.Cifar10Dataset(data_path, num_shards=rank_size, shard_id=rank_id) - + # define map operations random_crop_op = vision.RandomCrop((32, 32), (4, 4, 4, 4)) random_horizontal_op = vision.RandomHorizontalFlip() @@ -144,7 +144,7 @@ def create_dataset(data_path, repeat_num=1, batch_size=32, rank_id=0, rank_size= c_trans += [resize_op, rescale_op, normalize_op, changeswap_op] # apply map operations on images - data_set = data_set.map(operations=type_cast_op, operations=type_cast_op, input_columns="label") + data_set = data_set.map(operations=type_cast_op, input_columns="label") data_set = data_set.map(operations=c_trans, input_columns="image") # apply shuffle operations @@ -198,7 +198,7 @@ class SoftmaxCrossEntropyExpand(nn.Cell): self.sparse = sparse self.max = P.ReduceMax(keep_dims=True) self.sub = P.Sub() - + def construct(self, logit, label): logit_max = self.max(logit, -1) exp = self.exp(self.sub(logit, logit_max)) @@ -421,7 +421,7 @@ strategy = ((1, 1), (1, 8)) net = DataParallelNet(strategy=strategy) # reset parallel mode context.reset_auto_parallel_context() -# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel +# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel # mode, you can simply change the value of parallel_mode parameter to ParallelMode.AUTO_PARALLEL. context.set_auto_parallel_context(parallel_mode=ParallelMode.DATA_PARALLEL, device_num=8) ``` @@ -482,7 +482,7 @@ strategy = ((1, 1), (1, 8)) net = SemiAutoParallelNet(strategy=strategy, strategy2=strategy) # reset parallel mode context.reset_auto_parallel_context() -# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel +# set parallel mode, data parallel mode is selected for training and model saving. If you want to choose auto parallel # mode, you can simply change the value of parallel_mode parameter to ParallelMode.AUTO_PARALLEL. context.set_auto_parallel_context(parallel_mode=ParallelMode.SEMI_AUTO_PARALLEL, strategy_ckpt_save_file='./rank_{}_ckpt/strategy.txt'.format(get_rank)) @@ -511,4 +511,4 @@ context.reset_auto_parallel_context() ### 手动混合并行模式 -手动混合并行模式(Hybrid Parallel)的模型参数保存和加载请参考[手动设置并行场景模型参数的保存和加载](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/checkpoint_for_hybrid_parallel.html)。 \ No newline at end of file +手动混合并行模式(Hybrid Parallel)的模型参数保存和加载请参考[手动设置并行场景模型参数的保存和加载](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/checkpoint_for_hybrid_parallel.html)。 diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md index ad6191be8e..fe392504eb 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md @@ -187,8 +187,6 @@ MindSpore算子和AutoAugment中的算子的对应关系如下: post_trans = [ c_vision.RandomHorizontalFlip(prob=0.5), - #c_vision.Normalize(mean=mean, std=std), - #c_vision.HWC2CHW() ] else: trans = [ @@ -238,10 +236,10 @@ MindSpore算子和AutoAugment中的算子的对应关系如下: >为了更好演示效果,从数据集中只读取5张图片并且不进行`shuffle`且不进行`Normalize`和`HWC2CHW`操作。 - ![augment](./images/auto_augmentation.png) 运行结果可以看到,batch中每张图像的增强效果,X方向表示1个batch的5张图像,Y方向表示5个bacth。 + ## 参考文献 [1] [AutoAugment: Learning Augmentation Policies from Data](https://arxiv.org/abs/1805.09501) diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_cache.md b/tutorials/training/source_zh_cn/advanced_use/enable_cache.md deleted file mode 100644 index 463df2f550..0000000000 --- a/tutorials/training/source_zh_cn/advanced_use/enable_cache.md +++ /dev/null @@ -1,237 +0,0 @@ -# 应用单节点缓存加速数据集读取 - -`Linux` `Ascend` `GPU` `CPU` `中级` `高级` - - - -- [应用单节点缓存加速数据集读取](#应用单节点缓存加速数据集读取) - - [概述](#概述) - - [缓存基础使用](#缓存基础使用) - - [缓存经过数据增强的数据](#缓存经过数据增强的数据) - - [缓存共享](#缓存共享) - - - - - -## 概述 - -对于需要重复访问远程的数据集或从需要重复从磁盘中读取数据集的情况,可以使用单节点缓存算子将数据集缓存于本地内存中,以加速数据集的读取。 - -缓存算子依赖于在当前节点启动的缓存服务器,缓存服务器作为守护进程独立于用户的训练脚本而存在,主要用于提供缓存数据的管理,支持包括存储、查找、读取,以及发生缓存未命中时对于缓存数据的写入等操作。 - -若用户的内存空间不足以缓存所有数据集,则用户可以配置缓存算子使其将剩余数据缓存至磁盘。 - -## 缓存基础使用 - -- **Step 1:** - - 在使用单节点缓存服务之前,首先需要启动缓存服务器: - - ```shell - cache_admin --start - ``` - - **cache_admin命令支持以下参数:** - - `-w`:设置缓存服务器的工作线程数量,默认情况下工作线程数量为32。 - - `-s`:设置若缓存数据的大小超过内存空间,则溢出至磁盘的数据文件路径,默认为`/tmp`路径。 - - `-h`:缓存服务器的ip地址,默认为127.0.0.1。 - - `-p`:缓存服务器的端口号。 - - `-g`: 生成一个缓存会话。 - - `-d`:删除一个缓存会话。 - - `-l`:设置日志等级。 - -- **Step 2:** - - 随后,在Python训练脚本中使用`DatasetCache` API来定义一个名为`test_cache`的缓存实例: - - ```python - import mindspore.dataset as ds - import mindspore.common.dtype as mstype - - test_cache = ds.DatasetCache(session_id=1, size=0, spilling=True) - ``` - - **DatasetCache支持以下参数:** - - `session_id`: 缓存会话的id。 - - `size`:缓存最大内存空间占用,该参数以MB为单位,例如512GB的缓存空间应设置size=524288。 - - `spilling`:当内存空间超出所设置的最大内存空间占用时,是否允许将剩余的数据溢出至磁盘,默认为False。 - - `hostname`:连接至缓存服务器的ip地址,默认为127.0.0.1。 - - `port`:连接至缓存服务器的端口号。 - - > - 在实际使用中,通常应当首先使用`cache_admin -g`命令从缓存服务器处获得一个缓存会话id并作为`session_id`参数,防止发生缓存会话冲突的状况。 - > - 设置`size=0`代表不限制缓存所使用的内存空间。使用此设置的用户需自行注意缓存的内存使用状况,防止因机器内存耗尽而导致缓存服务器进程被杀或机器重启的状况。 - > - 若设置`spilling=True`,则用户需确保所设置的磁盘路径具有写入权限以及足够的磁盘空间,以存储溢出至磁盘的缓存数据。 - > - 若设置`spilling=False`,则缓存服务器在耗尽所设置的内存空间后将不再写入新的数据。 - -- **Step 3:** - - 最后,在创建数据集算子时将所创建的`test_cache`作为其`cache`参数传入: - - ```python - schema = ds.Schema() - schema.add_column('image', de_type=mstype.uint8, shape=[2]) - schema.add_column('label', de_type=mstype.uint8, shape=[1]) - - # apply cache to dataset - data = ds.RandomDataset(schema=schema, total_rows=4, num_parallel_workers=1, cache=test_cache) - - num_iter = 0 - for item in data.create_dict_iterator(num_epochs=1): # each data is a dictionary - # in this example, each dictionary has keys "image" and "label" - print("{} image: {} label: {}".format(num_iter, item["image"], item["label"])) - num_iter += 1 - ``` - - ``` - 0 image: [135 135] label: [59] - 1 image: [53 53] label: [146] - 2 image: [99 99] label: [27] - 3 image: [208 208] label: [169] - ``` - -- **Step 4:** - - 在训练结束后,可以选择将当前的缓存销毁并释放内存: - - ```shell - # Destroy the session - cache_admin –-destroy_session $session_id - ``` - - 以上命令将销毁缓存会话id为`session_id`的缓存。 - - 若选择不销毁缓存,则该缓存会话中的缓存数据将继续存在,用户下次启动训练脚本时可以继续使用该缓存。 - -## 缓存经过数据增强的数据 - -缓存算子既支持对于原始数据集的缓存,也可以被应用于缓存经过数据增强处理后的数据。 - -直接缓存经过数据增强处理后的数据通常会带来更大的性能收益,因为被缓存的数据仅需要进行一次所需的数据增强处理,随后用户即可通过缓存直接获取经过增强处理后的数据。 - -- **Step 1:** - - 同样,缓存经过数据增强处理的数据也需要首先启动缓存服务器: - - ```shell - cache_admin --start - ``` - -- **Step 2:** - - 并在Python脚本中定义缓存实例: - - ```python - import mindspore.dataset as ds - import mindspore.common.dtype as mstype - import mindspore.dataset.vision.c_transforms as c_vision - - test_cache = ds.DatasetCache(session_id=1, size=0, spilling=True) - ``` - -- **Step 3:** - - 最后,在创建用于数据增强的`Map`算子是将所创建的缓存实例传入: - - ```python - schema = ds.Schema() - schema.add_column('image', de_type=mstype.uint8, shape=[640, 480, 3]) - schema.add_column('label', de_type=mstype.uint8, shape=[1]) - - data = ds.RandomDataset(schema=schema, total_rows=4, num_parallel_workers=1) - - # apply cache to map - rescale_op = c_vision.Rescale(1.0 / 255.0, -1.0) - data = data.map(operations=rescale_op, input_columns=["image"], cache=test_cache) - - num_iter = 0 - for item in data.create_dict_iterator(num_epochs=1): # each data is a dictionary - # in this example, each dictionary has keys "image" and "label" - print("{} image shape: {} label: {}".format(num_iter, item["image"].shape, item["label"])) - num_iter += 1 - ``` - - ``` - 0 image shape: (640, 480, 3) label: [99] - 1 image shape: (640, 480, 3) label: [203] - 2 image shape: (640, 480, 3) label: [37] - 3 image shape: (640, 480, 3) label: [242] - ``` - -- **Step 4:** - - 在训练结束后,可以选择将当前的缓存销毁并释放内存: - - ```shell - # Destroy the session - cache_admin –-destroy_session $session_id - ``` - -## 缓存共享 - -对于分布式训练的场景,缓存算子还允许多个相同的训练脚本共享同一个缓存,共同从缓存中读写数据。 - -- **Step 1:** - - 首先启动缓存服务器: - - ```shell - cache_admin --start - ``` - -- **Step 2:** - - 在启动训练脚本的shell脚本中,生成一个缓存会话id: - - ```shell - #!/bin/bash - # This shell script will launch parallel pipelines - - # generate a session id that these parallel pipelines can share - result=$(cache_admin -g 2>&1) - rc=$? - if [ $rc -ne 0 ]; then - echo "some error" - exit 1 - fi - - # grab the session id from the result string - session_id=$(echo $result | awk ‘{print $NF}’) - ``` - -- **Step 3:** - - 在启动训练脚本时将`session_id`以及其他参数传入: - - ```shell - # make the session_id available to the python scripts - num_devices=4 - - for p in $(seq 0 $((${num_devices}-1))); do - python my_training_script.py -–num_devices “$num_devices” –-device “$p” –-session_id $session_id & - done - ``` - -- **Step 4:** - - 在python脚本内部接收传入的`session_id`,并在定义缓存实例时将其作为参数传入: - - ```python - import mindspore.dataset as msds - import mindspore.dataset.engine as de - - parser.add_argument('--session_id', type=int, default=1, help='Device num.') - - # use the session id passed in from the outside script when defining the cache - test_cache = msds.DatasetCache(session_id = session_id, size = 0, spilling=False) - ds = de.ImageFolderDataset(data_dir, num_samples=num_samples, cache = test_cache) - ``` - -- **Step 5:** - - 在训练结束后,可以选择将当前的缓存销毁并释放内存: - - ```shell - # Destroy the session - cache_admin –-destroy_session $session_id - ``` diff --git a/tutorials/training/source_zh_cn/advanced_use/images/data_conversion_concept.png b/tutorials/training/source_zh_cn/advanced_use/images/data_conversion_concept.png index 33e838ae3005814c97e308df12209cc163db6e5d..0bd540cac3e3570773171d8c1c336053d5d629d0 100644 GIT binary patch literal 16993 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 literal 68261 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 By^#O_ diff --git a/tutorials/training/source_zh_cn/advanced_use/images/mindrecord.png b/tutorials/training/source_zh_cn/advanced_use/images/mindrecord.png index d1d426776605f26cd1d8972b77989c223cf67807..b06cad25025a7d45c826e37cc7490fa8b05980e9 100644 GIT binary patch literal 16840 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 L`njxgN@xNAM@R^o diff --git a/tutorials/training/source_zh_cn/index.rst b/tutorials/training/source_zh_cn/index.rst index ef19168bcd..d068aec925 100644 --- a/tutorials/training/source_zh_cn/index.rst +++ b/tutorials/training/source_zh_cn/index.rst @@ -30,9 +30,8 @@ :caption: 处理数据 advanced_use/converse_dataset - advanced_use/enable_cache advanced_use/optimize_data_processing - + .. toctree:: :glob: @@ -87,5 +86,5 @@ :caption: 应用实践 advanced_use/cv - advanced_use/nlp + advanced_use/nlp advanced_use/use_on_the_cloud diff --git a/tutorials/training/source_zh_cn/use/load_dataset_image.md b/tutorials/training/source_zh_cn/use/load_dataset_image.md index e77f68363f..540da9ab61 100644 --- a/tutorials/training/source_zh_cn/use/load_dataset_image.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_image.md @@ -19,12 +19,6 @@ 在计算机视觉任务中,图像数据往往因为容量限制难以直接全部读入内存。MindSpore提供的`mindspore.dataset`库可以帮助用户构建数据集对象,分批次地读取图像数据。同时,在各个数据集类中还内置了数据处理和数据增强算子,使得数据在训练过程中能够像经过pipeline管道的水一样源源不断地流向训练系统,提升数据训练效果。此外,MindSpore还支持分布式场景数据加载。 -MindSpore目前支持加载图像领域常用的经典数据集和多种数据存储格式下的数据集,用户也可以通过构建自定义数据集类实现自定义方式的数据加载。各种数据集的详细加载方法,可参考编程指南中[数据集加载](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dataset_loading.html)章节。 - -MindSpore目前支持的数据处理和数据增强算子及其详细使用方法,可参考编程指南中[数据处理](https://www.mindspore.cn/api/zh-CN/master/programming_guide/pipeline.html)与[数据增强](https://www.mindspore.cn/api/zh-CN/master/programming_guide/augmentation.html)章节。 - -MindSpore目前支持的数据采样器及其详细使用方法,可参考编程指南中[采样器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/sampler.html)章节。 - 下面,本教程将以加载MNIST数据集为例,演示如何使用MindSpore加载和处理图像数据。 ## 准备 @@ -45,7 +39,9 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 ## 加载数据集 -使用`mindspore.dataset`库中的`MnistDataset`类加载MNIST数据集。 +MindSpore目前支持加载图像领域常用的经典数据集和多种数据存储格式下的数据集,用户也可以通过构建自定义数据集类实现自定义方式的数据加载。各种数据集的详细加载方法,可参考编程指南中[数据集加载](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dataset_loading.html)章节。 + +下面演示使用`mindspore.dataset`库中的`MnistDataset`类加载MNIST数据集。 1. 配置数据集目录,创建MNIST数据集对象。 @@ -70,9 +66,13 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 ![mnist_5](./images/mnist_5.png) +此外,用户还可以在数据集加载时传入sampler指定数据采样方式。MindSpore目前支持的数据采样器及其详细使用方法,可参考编程指南中[采样器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/sampler.html)章节。 + ## 数据处理 -构建pipeline,对MNIST数据集进行`shuffle`、`batch`、`repeat`等操作。 +MindSpore目前支持的数据处理算子及其详细使用方法,可参考编程指南中[数据处理](https://www.mindspore.cn/api/zh-CN/master/programming_guide/pipeline.html)章节。 + +下面演示构建pipeline,对MNIST数据集进行`shuffle`、`batch`、`repeat`等操作。 ```python # 查看原始数据label @@ -149,7 +149,9 @@ for data in mnist_dataset.create_dict_iterator(): ## 数据增强 -使用`c_transforms`模块对MNIST数据集进行数据增强。 +MindSpore目前支持的数据增强算子及其详细使用方法,可参考编程指南中[数据增强](https://www.mindspore.cn/api/zh-CN/master/programming_guide/augmentation.html)章节。 + +下面演示使用`c_transforms`模块对MNIST数据集进行数据增强。 1. 导入相关模块,重新加载数据集。 @@ -161,7 +163,7 @@ for data in mnist_dataset.create_dict_iterator(): mnist_dataset = ds.MnistDataset(DATA_DIR, num_samples=6, shuffle=False) ``` -2. 定义数据增强算子,对数据集执行`Resize`操作。 +2. 定义数据增强算子,对数据集执行`Resize`和`RandomCrop`操作。 ```python resize_op = transforms.Resize(size=(200,200), interpolation=Inter.LINEAR) diff --git a/tutorials/training/source_zh_cn/use/load_dataset_text.md b/tutorials/training/source_zh_cn/use/load_dataset_text.md index 55372ccdfb..824b236734 100644 --- a/tutorials/training/source_zh_cn/use/load_dataset_text.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_text.md @@ -19,12 +19,6 @@ MindSpore提供的`mindspore.dataset`库可以帮助用户构建数据集对象,分批次地读取文本数据。同时,在各个数据集类中还内置了数据处理和数据分词算子,使得数据在训练过程中能够像经过pipeline管道的水一样源源不断地流向训练系统,提升数据训练效果。此外,MindSpore还支持分布式场景数据加载。 -MindSpore目前支持加载文本领域常用的经典数据集和多种数据存储格式下的数据集,用户也可以通过构建自定义数据集类实现自定义方式的数据加载。各种数据集的详细加载方法,可参考编程指南中[数据集加载](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dataset_loading.html)章节。 - -MindSpore目前支持的数据处理和数据分词算子及其详细使用方法,可参考编程指南中[数据处理](https://www.mindspore.cn/api/zh-CN/master/programming_guide/pipeline.html)与[分词器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/tokenizer.html)章节。 - -MindSpore目前支持的数据采样器及其详细使用方法,可参考编程指南中[采样器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/sampler.html)章节。 - 下面,本教程将简要演示如何使用MindSpore加载和处理文本数据。 ## 准备 @@ -44,15 +38,18 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 └─tokenizer.txt ``` -3. 导入`mindspore.dataset`库。 +3. 导入`mindspore.dataset`和`mindspore.dataset.text`库。 ```python import mindspore.dataset as ds + import mindspore.dataset.text as text ``` ## 加载数据集 -使用`mindspore.dataset`中的`TextFileDataset`类加载数据集。 +MindSpore目前支持加载文本领域常用的经典数据集和多种数据存储格式下的数据集,用户也可以通过构建自定义数据集类实现自定义方式的数据加载。各种数据集的详细加载方法,可参考编程指南中[数据集加载](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dataset_loading.html)章节。 + +下面演示使用`mindspore.dataset`中的`TextFileDataset`类加载数据集。 1. 配置数据集目录,创建数据集对象。 @@ -78,6 +75,8 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 ## 数据处理 +MindSpore目前支持的数据处理算子及其详细使用方法,可参考编程指南中[数据处理](https://www.mindspore.cn/api/zh-CN/master/programming_guide/pipeline.html)章节。 + 在生成`dataset`对象后可对其进行数据处理操作,比如`SlidingWindow`、`shuffle`等。 - **SlidingWindow** @@ -160,7 +159,9 @@ MindSpore目前支持的数据采样器及其详细使用方法,可参考编 ## 数据分词 -使用`WhitespaceTokenizer`分词器来分词,该分词是按照空格来进行分词。 +MindSpore目前支持的数据分词算子及其详细使用方法,可参考编程指南中[分词器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/tokenizer.html)章节。 + +下面演示使用`WhitespaceTokenizer`分词器来分词,该分词是按照空格来进行分词。 1. 创建`tokenizer`。 -- Gitee From bcab2d2943734d84faac06da9b9c48ced08fe750 Mon Sep 17 00:00:00 2001 From: yingchen Date: Fri, 18 Sep 2020 10:40:42 +0800 Subject: [PATCH 078/100] update tutorial links for api_cpp --- docs/api_cpp/source_en/class_list.md | 18 +++++++++--------- docs/api_cpp/source_en/dataset.md | 4 ++-- docs/api_cpp/source_en/lite.md | 6 +++--- docs/api_cpp/source_en/session.md | 4 ++-- docs/api_cpp/source_zh_cn/class_list.md | 18 +++++++++--------- docs/api_cpp/source_zh_cn/dataset.md | 4 ++-- docs/api_cpp/source_zh_cn/lite.md | 6 +++--- docs/api_cpp/source_zh_cn/session.md | 4 ++-- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/api_cpp/source_en/class_list.md b/docs/api_cpp/source_en/class_list.md index bf0acb8f57..236b192159 100644 --- a/docs/api_cpp/source_en/class_list.md +++ b/docs/api_cpp/source_en/class_list.md @@ -4,13 +4,13 @@ Here is a list of all classes with links to the namespace documentation for each | Namespace | Class Name | Description | | --- | --- | --- | -| mindspore::lite | [Allocator](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#allocator) | Allocator defines a memory pool for dynamic memory malloc and memory free. | -| mindspore::lite | [Context](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#context) | Context defines for holding environment variables during runtime. | -| mindspore::lite | [ModelImpl](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#modelimpl) | ModelImpl defines the implement class of Model in MindSpore Lite. | -| mindspore::lite | [PrimitiveC](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#primitivec) | Primitive defines as prototype of operator. | -| mindspore::lite | [Model](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#model) | Model defines model in MindSpore Lite for managing graph. | -| mindspore::lite | [ModelBuilder](https://www.mindspore.cn/lite/docs/en/master/apicc/lite.html#modelbuilder) | ModelBuilder is defined to build the model. | -| mindspore::session | [LiteSession](https://www.mindspore.cn/lite/docs/en/master/apicc/session.html#litesession) | LiteSession defines session in MindSpore Lite for compiling Model and forwarding model. | -| mindspore::tensor | [MSTensor](https://www.mindspore.cn/lite/docs/en/master/apicc/tensor.html#mstensor) | MSTensor defines tensor in MindSpore Lite. | -| mindspore::dataset | [LiteMat](https://www.mindspore.cn/lite/docs/en/master/apicc/dataset.html#litemat) |Class that represents a LiteMat of a Image. | +| mindspore::lite | [Allocator](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#allocator) | Allocator defines a memory pool for dynamic memory malloc and memory free. | +| mindspore::lite | [Context](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#context) | Context defines for holding environment variables during runtime. | +| mindspore::lite | [ModelImpl](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#modelimpl) | ModelImpl defines the implement class of Model in MindSpore Lite. | +| mindspore::lite | [PrimitiveC](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#primitivec) | Primitive defines as prototype of operator. | +| mindspore::lite | [Model](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#model) | Model defines model in MindSpore Lite for managing graph. | +| mindspore::lite | [ModelBuilder](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#modelbuilder) | ModelBuilder is defined to build the model. | +| mindspore::session | [LiteSession](https://www.mindspore.cn/doc/api_cpp/en/r1.0/session.html#litesession) | LiteSession defines session in MindSpore Lite for compiling Model and forwarding model. | +| mindspore::tensor | [MSTensor](https://www.mindspore.cn/doc/api_cpp/en/r1.0/tensor.html#mstensor) | MSTensor defines tensor in MindSpore Lite. | +| mindspore::dataset | [LiteMat](https://www.mindspore.cn/doc/api_cpp/en/r1.0/dataset.html#litemat) |Class that represents a LiteMat of a Image. | diff --git a/docs/api_cpp/source_en/dataset.md b/docs/api_cpp/source_en/dataset.md index 9d457bba12..47d29e5406 100644 --- a/docs/api_cpp/source_en/dataset.md +++ b/docs/api_cpp/source_en/dataset.md @@ -1,7 +1,7 @@ # mindspore::dataset -#include <[lite_mat.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h)> -#include <[image_process.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h)> +#include <[lite_mat.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h)> +#include <[image_process.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h)> ## Functions of image_process.h diff --git a/docs/api_cpp/source_en/lite.md b/docs/api_cpp/source_en/lite.md index 98efcdd6d6..6e2c33eeb2 100644 --- a/docs/api_cpp/source_en/lite.md +++ b/docs/api_cpp/source_en/lite.md @@ -40,7 +40,7 @@ A **bool** value. Defaults to **false**. Prior enable float16 inference. ``` device_type ``` -A [**DeviceType**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/lite.html#devicetype) **enum** type. Defaults to **DT_CPU**. Using to specify the device. +A [**DeviceType**](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#devicetype) **enum** type. Defaults to **DT_CPU**. Using to specify the device. ``` thread_num_ @@ -52,13 +52,13 @@ An **int** value. Defaults to **2**. Thread number config for thread pool. allocator ``` -A **pointer** pointing to [**Allocator**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/lite.html#allocator). +A **pointer** pointing to [**Allocator**](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#allocator). ``` cpu_bind_mode_ ``` -A [**CpuBindMode**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/lite.html#cpubindmode) **enum** variable. Defaults to **MID_CPU**. +A [**CpuBindMode**](https://www.mindspore.cn/doc/api_cpp/en/r1.0/lite.html#cpubindmode) **enum** variable. Defaults to **MID_CPU**. ## PrimitiveC Primitive is defined as prototype of operator. diff --git a/docs/api_cpp/source_en/session.md b/docs/api_cpp/source_en/session.md index 1dc5700146..63aa4aea19 100644 --- a/docs/api_cpp/source_en/session.md +++ b/docs/api_cpp/source_en/session.md @@ -73,9 +73,9 @@ Run session with callback. - Parameters - - `before`: A [**KernelCallBack**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/session.html#kernelcallback) function. Define a callback function to be called before running each node. + - `before`: A [**KernelCallBack**](https://www.mindspore.cn/doc/api_cpp/en/r1.0/session.html#kernelcallback) function. Define a callback function to be called before running each node. - - `after`: A [**KernelCallBack**](https://www.mindspore.cn/lite/docs/en/r1.0/apicc/session.html#kernelcallback) function. Define a callback function to be called after running each node. + - `after`: A [**KernelCallBack**](https://www.mindspore.cn/doc/api_cpp/en/r1.0/session.html#kernelcallback) function. Define a callback function to be called after running each node. - Returns diff --git a/docs/api_cpp/source_zh_cn/class_list.md b/docs/api_cpp/source_zh_cn/class_list.md index 3eddc86467..2999e89bd3 100644 --- a/docs/api_cpp/source_zh_cn/class_list.md +++ b/docs/api_cpp/source_zh_cn/class_list.md @@ -4,12 +4,12 @@ MindSpore Lite中的类定义及其所属命名空间和描述: | 命名空间 | 类 | 描述 | | --- | --- | --- | -| mindspore::lite | [Allocator](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#allocator) | Allocator定义了一个内存池,用于动态地分配和释放内存。 | -| mindspore::lite | [Context](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#context) | Context用于保存执行期间的环境变量。 | -| mindspore::lite | [ModelImpl](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#modelimpl) | ModelImpl定义了MindSpore Lite中的Model的实现类。 | -| mindspore::lite | [PrimitiveC](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#primitivec) | PrimitiveC定义为算子的原型。 | -| mindspore::lite | [Model](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#model) | Model定义了MindSpore Lite中的模型,便于计算图管理。 | -| mindspore::lite | [ModelBuilder](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/lite.html#modelbuilder) | ModelBuilder定义了MindSpore Lite中的模型构建器。 | -| mindspore::session | [LiteSession](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/session.html#litesession) | LiteSession定义了MindSpore Lite中的会话,用于进行Model的编译和前向推理。 | -| mindspore::tensor | [MSTensor](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/tensor.html#mstensor) | MSTensor定义了MindSpore Lite中的张量。 | -| mindspore::dataset | [LiteMat](https://www.mindspore.cn/lite/docs/zh-CN/master/apicc/dataset.html#litemat) |LiteMat是一个处理图像的类。 | +| mindspore::lite | [Allocator](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#allocator) | Allocator定义了一个内存池,用于动态地分配和释放内存。 | +| mindspore::lite | [Context](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#context) | Context用于保存执行期间的环境变量。 | +| mindspore::lite | [ModelImpl](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#modelimpl) | ModelImpl定义了MindSpore Lite中的Model的实现类。 | +| mindspore::lite | [PrimitiveC](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#primitivec) | PrimitiveC定义为算子的原型。 | +| mindspore::lite | [Model](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#model) | Model定义了MindSpore Lite中的模型,便于计算图管理。 | +| mindspore::lite | [ModelBuilder](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#modelbuilder) | ModelBuilder定义了MindSpore Lite中的模型构建器。 | +| mindspore::session | [LiteSession](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/session.html#litesession) | LiteSession定义了MindSpore Lite中的会话,用于进行Model的编译和前向推理。 | +| mindspore::tensor | [MSTensor](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/tensor.html#mstensor) | MSTensor定义了MindSpore Lite中的张量。 | +| mindspore::dataset | [LiteMat](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/dataset.html#litemat) |LiteMat是一个处理图像的类。 | diff --git a/docs/api_cpp/source_zh_cn/dataset.md b/docs/api_cpp/source_zh_cn/dataset.md index 9e12aab3ad..92db1aefdf 100644 --- a/docs/api_cpp/source_zh_cn/dataset.md +++ b/docs/api_cpp/source_zh_cn/dataset.md @@ -1,7 +1,7 @@ # mindspore::dataset -#include <[lite_mat.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h)> -#include <[image_process.h](https://gitee.com/mindspore/mindspore/blob/master/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h)> +#include <[lite_mat.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/lite_mat.h)> +#include <[image_process.h](https://gitee.com/mindspore/mindspore/blob/r1.0/mindspore/ccsrc/minddata/dataset/kernels/image/lite_cv/image_process.h)> ## image_process.h文件的函数 diff --git a/docs/api_cpp/source_zh_cn/lite.md b/docs/api_cpp/source_zh_cn/lite.md index 11d7f664a3..f0797d6a7e 100644 --- a/docs/api_cpp/source_zh_cn/lite.md +++ b/docs/api_cpp/source_zh_cn/lite.md @@ -43,7 +43,7 @@ float16_priority device_type ``` -[**DeviceType**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/lite.html#devicetype)枚举类型。默认为**DT_CPU**,用于设置设备信息。 +[**DeviceType**](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#devicetype)枚举类型。默认为**DT_CPU**,用于设置设备信息。 ``` thread_num_ @@ -55,13 +55,13 @@ thread_num_ allocator ``` -指针类型,指向内存分配器[**Allocator**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/lite.html#allocator)的指针。 +指针类型,指向内存分配器[**Allocator**](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#allocator)的指针。 ``` cpu_bind_mode_ ``` -[**CpuBindMode**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/lite.html#cpubindmode)枚举类型,默认为**MID_CPU**。 +[**CpuBindMode**](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/lite.html#cpubindmode)枚举类型,默认为**MID_CPU**。 ## PrimitiveC diff --git a/docs/api_cpp/source_zh_cn/session.md b/docs/api_cpp/source_zh_cn/session.md index 31f231714f..f83b7a467a 100644 --- a/docs/api_cpp/source_zh_cn/session.md +++ b/docs/api_cpp/source_zh_cn/session.md @@ -73,9 +73,9 @@ virtual int RunGraph(const KernelCallBack &before = nullptr, const KernelCallBac - 参数 - - `before`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之前调用的回调函数。 + - `before`: 一个[**KernelCallBack**](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/session.html#kernelcallback) 结构体。定义了运行每个节点之前调用的回调函数。 - - `after`: 一个[**KernelCallBack**](https://www.mindspore.cn/lite/docs/zh-CN/r1.0/apicc/session.html#kernelcallback) 结构体。定义了运行每个节点之后调用的回调函数。 + - `after`: 一个[**KernelCallBack**](https://www.mindspore.cn/doc/api_cpp/zh-CN/r1.0/session.html#kernelcallback) 结构体。定义了运行每个节点之后调用的回调函数。 - 返回值 -- Gitee From fc7ee7816c8d0eb7cafada4cad7f5fc43e5ef1b3 Mon Sep 17 00:00:00 2001 From: ZhidanLiu Date: Thu, 17 Sep 2020 20:42:48 +0800 Subject: [PATCH 079/100] fuzzer design and tutorial for r1.0 --- docs/note/source_en/design.rst | 3 +- .../design/mindarmour/fuzzer_design.md | 74 ++++++ .../mindarmour/images/fuzz_architecture.png | Bin 0 -> 20564 bytes .../design/mindarmour/images/fuzz_process.png | Bin 0 -> 28647 bytes .../design/mindarmour/fuzzer_design.md | 18 +- .../advanced_use/images/fuzz_res.png | Bin 0 -> 89399 bytes .../advanced_use/images/fuzz_seed.png | Bin 0 -> 6175 bytes .../test_model_security_fuzzing.md | 211 ++++++++++++++++++ tutorials/training/source_en/index.rst | 3 +- .../test_model_security_fuzzing.md | 73 +++--- 10 files changed, 338 insertions(+), 44 deletions(-) create mode 100644 docs/note/source_en/design/mindarmour/fuzzer_design.md create mode 100644 docs/note/source_en/design/mindarmour/images/fuzz_architecture.png create mode 100644 docs/note/source_en/design/mindarmour/images/fuzz_process.png create mode 100644 tutorials/training/source_en/advanced_use/images/fuzz_res.png create mode 100644 tutorials/training/source_en/advanced_use/images/fuzz_seed.png create mode 100644 tutorials/training/source_en/advanced_use/test_model_security_fuzzing.md diff --git a/docs/note/source_en/design.rst b/docs/note/source_en/design.rst index 9373ac6ee0..47a8c3c104 100644 --- a/docs/note/source_en/design.rst +++ b/docs/note/source_en/design.rst @@ -11,4 +11,5 @@ Design design/mindinsight/training_visual_design design/mindinsight/graph_visual_design design/mindinsight/tensor_visual_design - design/mindarmour/differential_privacy_design.md + design/mindarmour/differential_privacy_design + design/mindarmour/fuzzer_design diff --git a/docs/note/source_en/design/mindarmour/fuzzer_design.md b/docs/note/source_en/design/mindarmour/fuzzer_design.md new file mode 100644 index 0000000000..2a41c2342e --- /dev/null +++ b/docs/note/source_en/design/mindarmour/fuzzer_design.md @@ -0,0 +1,74 @@ +# AI Model Security Test + +`Linux` `Ascend` `GPU` `CPU` `Data Preparation` `Model Development` `Model Training` `Model Optimization` `Enterprise` `Expert` + + + + +- [AI Model Security Test](#ai-model-security-test) + - [Background](#background) + - [Fuzz Testing Design](#fuzz-testing-design) + - [Fuzz Testing Process](#fuzz-testing-process) + - [Code Implementation](#code-implementation) + - [References](#references) + + + + + +## Background + +Different from [fuzzing security test for traditional programs](https://zhuanlan.zhihu.com/p/43432370), MindArmour provides the AI model security test module fuzz_testing for deep neural network. Based on the neural network features, the concept of neuron coverage rate [1] is introduced to guide the fuzz testing. Fuzz testing is guided to generate samples in the direction of increasing neuron coverage rate so that more neurons can be activated by inputs. The distribution range of neuron values is wider to fully test DNN and explore the output results of different types of models and model error behavior. + +## Fuzz Testing Design + +The following figure shows the security test design of the AI model. + +![fuzz_architecture](./images/fuzz_architecture.png) + +At the user interface layer, users need to provide the original dataset `DataSet`, tested model `Model`, and Fuzzer parameter `Fuzzer configuration`. After fuzzing the model and data, Fuzzer module returns the security report `Security Report`. + +Fuzz testting architecture consists of three modules: + +1. Natural Threat/Adversarial Example Generator: + + Randomly select a mutation method to mutate seed data and generate multiple variants. Mutation policies supporting multiple samples include: + + - Image affine transformation methods: Translate, Rotate, Scale, and Shear. + - Methods based on image pixel value changes: Contrast, Brightness, Blur, and Noise. + - Methods for generating adversarial examples based on white-box and black-box attacks: FGSM, PGD, and MDIIM. + +2. Fuzzer Moduler: + + Perform fuzz testing on the mutated data to observe the change of the neuron coverage rate. If the generated data increases the neuron coverage rate, add the data to the mutated seed queue for the next round of data mutation. Currently, the following neuron coverage metrics are supported: KMNC, NBC, and SNAC [2]. + +3. Evaluation: + + Evaluate the fuzz testing effect, quality of generated data, and strength of mutation methods. Five metrics of three types are supported, including the general evaluation metric (accuracy), neuron coverage rate metrics (kmnc, nbc, and snac), and adversarial attack evaluation metric (attack_success_rate). + +## Fuzz Testing Process + +![fuzz_process](./images/fuzz_process.png) + +The fuzz testing process is as follows: + +1. Select seed A from the seed queue according to the policy. +2. Randomly select a mutation policy to mutate seed A and generate multiple variants A1, A2, ... +3. Use the target model to predict the variants. If the semantics of variant is consistent with the seed, the variant enters the Fuzzed Tests. +4. If the prediction is correct, use the neuron coverage metric for analysis. +5. If a variant increases the coverage rate, place the variant in the seed queue for the next round of mutation. + +Through multiple rounds of mutations, you can obtain a series of variant data in the Fuzzed Tests, perform further analysis, and provide security reports from multiple perspectives. You can use them to deeply analyze defects of the neural network model and enhance the model to improve its universality and robustness. + +## Code Implementation + +1. [fuzzing.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/fuzzing.py): overall fuzz testing process. +2. [model_coverage_metrics.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/model_coverage_metrics.py): neuron coverage rate metrics, including KMNC, NBC, and SNAC. +3. [image_transform.py](https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/image_transform.py): image mutation methods, including methods based on image pixel value changes and affine transformation methods. +4. [adversarial attacks](https://gitee.com/mindspore/mindarmour/tree/master/mindarmour/adv_robustness/attacks): methods for generating adversarial examples based on white-box and black-box attacks. + +## References + +[1] Pei K, Cao Y, Yang J, et al. Deepxplore: Automated whitebox testing of deep learning systems[C]//Proceedings of the 26th Symposium on Operating Systems Principles. ACM, 2017: 1-18. + +[2] Ma L, Juefei-Xu F, Zhang F, et al. Deepgauge: Multi-granularity testing criteria for deep learning systems[C]//Proceedings of the 33rd ACM/IEEE International Conference on Automated Software Engineering. ACM, 2018: 120-131. \ No newline at end of file diff --git a/docs/note/source_en/design/mindarmour/images/fuzz_architecture.png b/docs/note/source_en/design/mindarmour/images/fuzz_architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..d4e8b89bd9a9f4844c59790f5b2114d1d477f927 GIT binary patch literal 20564 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 literal 0 HcmV?d00001 diff --git a/docs/note/source_en/design/mindarmour/images/fuzz_process.png b/docs/note/source_en/design/mindarmour/images/fuzz_process.png new file mode 100644 index 0000000000000000000000000000000000000000..2e04347f7cfb0819562578a6be1e91b5cc7ce9d5 GIT binary patch literal 28647 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 literal 0 HcmV?d00001 diff --git a/docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md b/docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md index f7554141b1..bbf75dd2d8 100644 --- a/docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md +++ b/docs/note/source_zh_cn/design/mindarmour/fuzzer_design.md @@ -6,8 +6,8 @@ - [AI模型安全测试](#ai模型安全测试) - [背景](#背景) - - [Fuzzer设计图](#Fuzzer设计图) - - [Fuzzer流程](#Fuzzer流程) + - [Fuzz Testing设计图](#fuzz-testing设计图) + - [Fuzz Testing流程](#fuzz-testing流程) - [代码实现](#代码实现) - [参考文献](#参考文献) @@ -17,9 +17,9 @@ ## 背景 -不同于[传统程序的Fuzz安全测试](https://zhuanlan.zhihu.com/p/43432370),MindArmour针对深度神经网络,提供AI模型安全测试模块Fuzzer。根据神经网络的特点,引入神经元覆盖率[1]的概念,作为Fuzz的测试指导,引导Fuzz朝神经元覆盖率增加的方向生成样本,让输入能够激活更多的神经元,神经元值的分布范围更广,以充分测试DNN,探索不同类型的模型输出结果、模型错误行为。 +不同于[传统程序的Fuzz安全测试](https://zhuanlan.zhihu.com/p/43432370),MindArmour针对深度神经网络,提供AI模型安全测试模块fuzz_testing。根据神经网络的特点,引入神经元覆盖率[1]的概念,作为Fuzz的测试指导,引导Fuzz朝神经元覆盖率增加的方向生成样本,让输入能够激活更多的神经元,神经元值的分布范围更广,以充分测试DNN,探索不同类型的模型输出结果、模型错误行为。 -## Fuzzer设计图 +## Fuzz Testing设计图 AI模型安全测试设计图如下。 @@ -27,7 +27,7 @@ AI模型安全测试设计图如下。 在用户接口层,需要用户提供原始数据集`DataSet`、被测试模型`Model`和配置Fuzzer参数`Fuzzer configuration`。Fuzzer模块对模型和数据进行Fuzz测试后,返回安全评估报告`Security Report`。 -Fuzzer架构主要包括三个模块: +Fuzz Testing架构主要包括三个模块: 1. Natural Threat/Adversarial Example Generator(数据变异模块): @@ -43,17 +43,17 @@ Fuzzer架构主要包括三个模块: 3. Evaluation(评估模块): - 评估Fuzzer效果,生成数据的质量,变异方法的强度。支持3个类型5种指标,包括通用评价指标:accuracy,神经元覆盖率指标:kmnc, nbc,snac,对抗攻击评价指标:attack_success_rate。 + 评估Fuzz Testing的效果,生成数据的质量,变异方法的强度。支持3个类型5种指标,包括通用评价指标:accuracy,神经元覆盖率指标:kmnc, nbc,snac,对抗攻击评价指标:attack_success_rate。 -## Fuzzer流程 +## Fuzz Testing流程 ![fuzz_process](./images/fuzz_process.png) -具体的Fuzzer流程如下: +具体的Fuzz Testing流程如下: 1. 根据策略从种子队列中选择一个种子A。 2. 随机选择变异策略,对种子A进行变异,生成多个变种数据A1,A2... -3. 用目标模型对变种A1,A2...进行预测,如果变种使得目标模型预测错误,则改变种进入Failed tests。 +3. 用目标模型对变种A1,A2...进行预测,如果变种的语意与种子保持一致,则进入Fuzzed Tests。 4. 若目标模型对于变种的预测结果是正确的,用神经元覆盖率指标进行分析。 5. 如果变种使得覆盖率增加,那么将该变种放入种子队列,用于下一轮变异。 diff --git a/tutorials/training/source_en/advanced_use/images/fuzz_res.png b/tutorials/training/source_en/advanced_use/images/fuzz_res.png new file mode 100644 index 0000000000000000000000000000000000000000..be6d022850438ff4b9c070f7225cbd950e1e3686 GIT binary patch literal 89399 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

      WbGlXLl-;Llx6Z-mVFCl(;+V3VG2G9{{U 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ïzIY)ynu1}!7I z57w51!$Jg7Z4aWRg}V`oy=7q5c$VFzRyImh>X2BgtMD545YhVScEs zK=|+;9#t2?Bk+enM^}D-)e!C8TiyMd%SZf$Cu^&9Prr@z#l9K1BK=+l^9#8``e_*) zKb|!IS>p>?uHl$IfDmPYC?b z1R3swAv&iG+;005plgtjtTNj3w^|!J#RoB7`HfP>DkJg}Ia$?Ux&c&@nH-u07)$Zm zh4c{<7OmmxorfP=uX-aAi{ZWLtMge{e7yH^dl7|dqCrgW)aU1F$Jw#WVL7(Y(K?He*RdC8&kNwn<4l>RE!Kim*pB4^Zo;(r886i)r)#o zY_ms5i3jP0;(?nE3?fnPBr-4MGTKx@${(A~$F;{xp0XP(8afoq6{HVD2f%k9nf_2q zzw)n)iVp)~1h9XCG$4be zW!)tfO{r0Fm5%56VKJqrhm*Y};$HA-^%viD*Hno!D%$;&khNmXMRiov*(tc)1t(DZ z?=qEtRSjvH zE`%{ECx zmwwipWyr#;%p3dT(4XbMDUoz(78+uqaBw;dmwGPMj)Ikn6Q5_)^=d8nriV$?oyZMFPjLAb(@Y1ov?VE1rT%&(&7VNW}4W%~a37BTB8!kA2G*{SIf8U#kw~M1Z z@SJ;%XU-A%pv~##N5g(g2PH8KK#WYV)&&bN0GCgm%@J6`60o-N1qz2^6u%KlDts_* zAdJdj6|0lqsM+7!291p>dyN@Dm~fmn+X}1p7rzcDau~4P{IEp|OG>P}HT2#Xvx{Kw z`5c8&@5la@?VT0Rz}p4oWRCThiwv$0+2>^K(-Mg*?pYkB`=e!VI&##4-6MIva{s~t z#`NwHWby9LCrWbv9{~J71HT;-MTG^6XHJ-J{SpAiOP0p@PXR#xyafR8cKd|#->>U` z`}p>klSbdVtl|DyTQ7RFuTVtf^GUD50H)oM41}VmrW@xz(`qJz6f4NEBXQ=8x>b24 zzO`QH>;eF@v#a>dF38T-JU{FRj!ad!XI`}K1b6Laj?iQI#{)peY+>s~k5n$WrsCFR zJ0HQQ@2RD}p-$yp@O9L+a%(K`SpWbcm(TXprTVk$4GNAJ1w;`}>qauU@A@Mf93#N6 zE$v;Uc@0i1#MsTYGp(SG%_vrVb*RK-m~jLg5Cc;|xU`5V;yxIHI4EH*s99%7l<{FU zf{6!wYoo_Jahtn=4H(!HxqNo;c*A2$oLPU`4+}q?Dt9A>hz>w^F;%gmu*sth0lR7w zIHfYv?3K`F$JEU?d+HdcwBYmfcmcLkVytHi3$BkH|a%D$!KXjMoLQIq; zcae}ONacy94K-a>VA%7=6*bA&+v(~@Ph`pG!-#CEIs zNd{l}#t(^xj9;6%MIj$KaF?i7GkN@nH{+P_^f`}CKDhoLHgFzzRjJ;3?b)XChk`XBUgek!^*L5bKfRu2PK@Rr@2XVWaZW^z<*q8@9 z%*KYj)I2gbe)|KAc<)>G`5<(3`@iTSIu9OWMn?~vEqMSi1SSGaXX*WjUml^rz%g{E z9UIglgA*AWyM0d;KBuZ-M&b7Mu(Lbj$Wmh<224aoj>B~BgMbxrP$JaYp;u%LeoZ4jyOLpZ1tj(P~$f)?|up2m=Fb?C#TqES6}MEm^Ff`es_c zGXb@;k(b@MBHK9nVr}WKmyk4SI{nG+8AIq9Lc^BF?x3N0cFBCVPe)h7j?y_eS|RjI zkW@c1El_wu%e7~`f2?<_jCUUp)WYXfHk9Y~SZWniXKU>71>4-NjY43Zfj?hs-5{eQrS_o_aK!XDwe$j)sF;MrOSu)RSqfauPh&R=bC@Fj+PMe zy`z-hz0TSop)>)u>$`iL!DG!>H8?)5#hl`3qD%Q|{8Y?8p#F!5j zO)JOfpci5sg!GOfYjRsBWg;?-5p^ayRFo~`Q|oVpW1<(FwCss5<}TQJk~=woKv**6 zTM-1#nZEnR<-kBZo-IEeW4g_;e+rrPb;Hu;!NA(ZFwHs!08zmjq^5#ZKic~VN4kJf zpApE37ue(DoE?KzlcH$(TNA0w^nuxh8laphIABwy0>!s?ccv|;*f)Z9IJ1l&3_5Q*CNn!}Znqp)b6Z8t z?#BQ-(cM$F&?BfSOYLGf{buXgp$`j+HX6Wr$@`hf@f&y{Yg#Zd@T%4R^1!E1EE4_C zUuS+~n^n-bb?>9?zgpJ

      #!`?uk>I);WrES2zU9pa-~V(3nBCcY96NGu0iQ!j!1h zwu%6N%J+yPrPRJPX6aS{0PB>Gc#inJ0~N zV-|lJ4-z&`(&jEnf%icNK}hkydL!c(f@kWAV)SkAbSF~1 z`$uWS3B*eXHo)Cr2#Mj@_Z&(XoTj;smbnTaSk-y$wAd7Fyrp%p%Ht)=@}pm1zyKuH zFJVBmQmUEzNR|!icJJ2PkKbCk;F^LzE?HeY4Jrn1%0sOG9`^p~CD-O{p`dAe$88*^6t{Ep7-q*9C!@6fdqF z%T;2H_b!>(1Y0LH6{Pz2GR@yG2p99A zMJiu%hA>f?v&EzmPLxPg+M5e^I*+q}KC`OnL~pHv^o@E!f(?+m9UEZlVjM$ok^}(G z|5!ASl};H_;*`CB6G#>cEF;6nV$|O^rmpyo_`XXZ(0T1N%V}LdC|xnjvdtJIPu6-} zz3j{HyDaLW@y~g%#T;4gbcYmOH_Rj__t5R~v5((Y^hpM_bg^_A4H8|3tyVs+9O)+C z)UaPXiwA@MW?f5zLC-V2@s7mj)hCuQMM4;559GP7)38ni!DZ0scvq|(i%CH1t=5h- z*Ny(91T-4mrCo$a7KhTFIRFL%Vt^PJcCH6Z!DdLZ$vIGpNxLj25b3iy8Ax%84GjB} zYumIS&4aR?QDO-CEtMQ2&52AaqS{EgdK@Y+L4+iWq}Ujmy9~K&qNt^-cUU0c78zTu zER)HqRYWlL*%9T?LV$5>QMfDu0ziNyi8J0u1)r#M^2%dK1Vybj$ZA_@SMV+y!$C?E!M)HJPF%|S#3-zGDi z5yImIpuNKhv0f8-|A4@-Av%Itku`24n64mV$GzSUX{M*SVXk!-KDDa*%A=#x^dFS2 z_?~mC#!;OiWv6-6utsRwiIpq^M!V@U*1Ow1R2|1nph2o-3~@jY6ea++*xqDR+$(7$DA}tB2|OfG(+s5R#t%8n<^)D&bTf-g}PN@GN6| zd7BY)@w6<6lygYO703{GE0SVdclD-5;R3{qMJgk{KOv$2m7sHu>ONYL!@Tel?x>4E zTW8^UVD_U%<^3#894`ttdv8IQJ|;K)tpI+F8pYD=Y_SA$cVV_rPaeS+?0EhiJX2bKOE zn^uSygOK5t2-O@U6WBkkiFL?bkznD--dJ%DE3RodapNNsdQQ?B=lwlfGJDnK%D>zm zgC)+Js+}Cad%`=@l@^WTvo?OaeM_LaIZk^*TYfj`gsP){d;PQ71hl>2NaOIw(8NU# ze#5m@XX*fFZ@-wo=;aC1?kQfl_g<~lv`e47&DxLw_{H$O>u@4{=2Y>9&W?|ZihtjG zO4fDtw4C#{qc%3<`CE%VHc)drOQ!)LJia?@gYtp>tH}9Y${g+J0ci zOpN_JIoh+yfd|O;R=FT?#=6_ez6|euH53X9Hs75$%H0BI4PIwI-}FcYmj&I+5W}Y5 zE&!lN6c`82xM5N~4zWSc1_1yNMi>FYNRgS>VG?uX=vqWUOi*Njy)1ql10cxDkNmj! zgD1qfHC_3Ty;LUN32|s{iZSj$012O>a3dd}s+3VSk z80WZmkZ_4x0!dwW$~7%gt~XKS!6t}tN+rBs!x1sS1}7b1vwKi)tiz7Y;oQLcjft`f zdJ;==Elg=vFq5ud3;#!_9Q7oL`X`O3noLkhm*gN`P&Ut$_sQIKnRKIG) z+6J|F&u{tajqcU3Z?i*|&Ktk>a`}@fgID>w=vruMt9lwTC63k;ZBpFk+~$+wrWnqU zo|xIb*9nO*DKB9TtCnLi>?B%AbWmaSq3ZU&KxGswmpF!jjoNHxZ#OqwY?3SF!)a-U z8x%qiD2Q^7Qayeu<30u-Y=EQ9G!?Ao?6;1z2ALeCLT1NQCn#Ac8#XkQ?71Tlkum6@ zZ)lG0nQJ*ZGiX8mZd`7KK-qh;ie-+b=~Fij!Kh zQ0krzhHZBVv|l@Q;x{*K{>K#m<4fVc1_(F;-OUX*OGoT?)SMmoO!R-=q5AV^4t{>= zY?8u6MWTs>3}6%N?G#Z+76^tNF=2;?M3K7X)(Rnoln@wp9;=Y(;Pg@hbb*4soeCgL=EK4tXE6UE6(AbxVqK-hKI$v6pZDlmA5kU`f%|ny&kyYueOc`(LKm-&(u< zR55Qt*T0{cwW4J@01%B?YwP#ihS--i|N7>ux~B?PU-Zra_lmW5e))e>mM9Ye?ij4j z*G1Q|L;`AR6?wejZ~`FBNtlSJge@jR-96bloYLJB*&>W3k@_8)N7h}$upq<9%^~b^ z4jDKZU>)E2ZPpjm%CTQ_iE4I}wpy{r%~L5FjbWP&yIop<&Q+q+#yCdY;}kGv zktkCmEIb$JsFg((1FLIOS{2;4N0BAX5ctA_RM&Df&wQH3~H;to^uNJ3#j_6(UP zk~ALA+^)^Vv&k3&ewXkXsiyFZ))Hb6`=Y_LQT(MCW9OpO~G zbtWQKAy_h8Z#2Py%u%BKSOp(j((AYt3fsr5Xa& zc{oU%PUNt&XpE)yMsvYbRs3)@;(POZ|GMbfEKqH8)swl%q>xc#$CWi-h@2aJ`4$lw z6qyXVdT1!zzrK*4%RJ8Qr`k0it$ZOPHg^SV7Lywzg%5sT;24+)uF>JU$G-M{Y~rsP z&y8jjg!pMCn`YP>7Y3&_ME$#5`y&7jVqC*il+rg831X;Avb0*EaZPnY0re zPILZiO}xUM%ELuXP6&koKq$=b_?vB3{4zKK1sSlUIjJntQybRII$%yL|1G((Rhhk@o(m{#%ydE-Uz#I=klHTisi9 z05BW^ngrl7tOyzm^t+bx!kc|wIsk|4oX>A4{yT}>nEG=1i(mCC4-3$^O7vj5F_<&z zI?yJSI*tHwsNCMgTiPrCQ1+|94|2A5A&Cp^zl z^PVy{TUjW~?|j%guc#gXmIuq&qe$q`fHNcr*x^t;_;mZmM?A;x){X7gPB`OROFnq= zn4G^IY!JoQOV_eg3br(6KMR=>BvB@bOd`}NQwz3gI`r4I2s6J+&9j+S&P6W7GG<37 z0MNZ|UPctK3D^XTpje1ynA8<_002VVC1e65o;2imTETSJTzdl2{1(HGnU!ISDT}5- z31sbB049Lh-%j0i5o7{lGBGU39OA{^NP?-L6P&fLyQTtwX@e7-wQq(duk0+A!++yQW*fi`i>lT2$%qf0X6{` zV49^D12KuzxG1E7s2mV55n}^*nh+I;&auvc1LB+`M3wB}hhW$UwK6~efC2LWiHAkI zRnav`;b_RoSUCt8E~ZV$x>%Sn5)^Kl$<|JT2@>TfYFe$WX}Q8lcg&ntGr39kFu-#h zbp|IoBQqV1$12#3>zgId-Cd`*wfKr{h?N(*#oi2VQEK(COQU5qLT*4T%`uL%+MOAK zP#blv+g@bt!oawY=I^FG3NiqoTnvvEZDvwbwue*c!NNpG9Jq)lyIVCX07g{7vt3)4 zy35dx$ZO(uLBPiml3R8JiS$I6s*-QmrBI|03ZNKL_t)l5nYoh!+Ni% zxguRQYSs0gy5*V})@@s~0L~bcapJVos-jE|@)MHdOybeyU{U~pNSp?PhMj-IvH2a_ zF$e!fUoTzTAJ#AG$87PVR40qZx_)?6;n~f>=Ssa>oBJvtQP_5tN3BweU!nF*-L!4w z`dJJHSF`C@+u4eWzRj;N>5dymj^1pW_<=CCxu!r4VzJLP2LTg7_48vdUtg?*J9HNS z$k^=G9BaD@qXy3SB|tzWK)lz2*^L7u9l#l{w3p;9BN>6W8Xnnv{1D=SMC>vTjFRrq{*?otjHyVv0%{74C02d0W_HZgMIHVq(_UY5#hQD0gf(O!M$>i!ZQm zb^h&b2g#I+;?HwGeEr$BGAU?By@x{=)?DHIf3~dV#k#3z^tZn}>xq|6et5~TRd-qI0FDe!D73k0)s>S3jj~XO^$YD^m!DJ~%g`N0ZP!KPF8k5@ z811~yd;0Oy^ZvTD?x*E9&VNrtG|i-cK5@#TB_~?z>iVDDeVB3l{+Cy{YU9@CdX`av z(ag-MWA9mhtG(8aQmfHXr&P9y~~fvF;uzS{RAj1kn_BxSs@Lc4`tS zig(MS#}P1*U+7&~F2>(UR;QT^02&iSfnu2&c3>i>Rt^kd3PK9uUCl5i0*rV?ixrtv zR)JyChGuND!l*)=RL!PsG#G?nko$dj@;JshPV3AnQAGgGnW_q!j#ZgD6ebJE1Tle; zK>-s|S(dKy+KC#aR_8WVXbrK_0;C$K-=>W*EXA>PZIi|0R3a`Zm;##(dp*o!M;#&B z)58VsBI%Ltu#JIQ5aK{ohB#*;&R#!b3POhBl*SWDju2oBi~;AI6xh6(jMr)Rc>qAn zaNxiQqB79F(^CXY<`;Tb76^&QwBs>iIM8)t?05C%qXUNS*ilPMomd@bS8?!bkjmBWbhW>wcPQWW9C(A99WqG}> zu2qY&?j>B{UXla=gA->9u_rpJox6(o}4ok5%%F#QhQ z2?X)bJT-W1uF@*XQBb`Ypx=-~KqX)z2Y^~Vu;|knT;`V^+j}c!x2x({T9q5Tt@!;m z(^IeJy;ys+u-vYMnYDY+r4Q?j5u7NImwCeB#op{I-7TzbDmJ; z7Ts4Ygef5495LunT`5g+@+8uz5GCzl=cnl^Ev9hFAj`Arb^=D&qhI1&|D^L&05DtI zU{K22kpiM|jt~CKs~lpvDLJ30${ak+@`B>2R5*v0;0PQ zHjV%zMiAoy=lxiXH~^zqK&)7ZQ$X#+EsB(hfK3pi8W#x{5YiboD3b-ggCB~@gi4so zz=RQ$B55xeCE7=ck)L@@05EKPuBF9_2|;M4Y)q3{dzhYJWO2GIOzjssYA|5af|yQ%=O|%wb9SD#8y-XH+3|bcw+QraHk`8N zZm4tV6^6|#MNJ_umwR2N$0}|Mnyqc5s@x1Xge~nf7(9SJ|4-L`?SK%Z%QZDmaMlqe z%rqBfLtuADhzo>ni3DzrU3_AG{m%m{tmSWfo>TqY!jp=gsZY-=k5ug+NBm*Krmcy~ zii^y++0!F`me_J(;W)L;9Eecj=J&oc=7H|Q&}Pb6^*xQBK0Kj1)5SH7#d_x_4TcJ? z7vHEjvEzQ1M@#{Lvbin%T~C3QG=m|+c=3leCd>b{oLSYTW+TdYI!!vdEoqe|^K*!G z=;sQD9oBA|C|8)!>lL*ZlCsD+XZIXaujW1nQ@oeyo2Pb_pVbS4v)vp-XZpU7C$K7y!)%(xgdY1g&nu6=ag;l5Ehq(=F z001>x5|`y=7Xg6Xa|p8fCg1jUIBiJbIyrI1GZYR;=r%OtaQ@ zncG?pu^jdnh;k;NeQ(Pc6Eu!fge6IuE8MT!94ZkQwV0+=FjSBd95K*bJKUoH06;{L zFGjQe0WvmoY)Q=!;sHre%&lsmOLZ8A0EknCa|~S7P}WnF5NuI+KW}4BAlt(uz@*&+ z)(*a~cFM|}(rRb-h2E9Z1(`8kG0h=m8NC4Iu4>9Z|QJh z34l06Emd47IPCzSd5|09av^5e>)-H9Fl=s;F=<1SnVtp!x`(DKJbufFVZS>#;DU^P z%Czj~-l@bGm^2o*Zb}zKszkp!nXGA$TID2FvbwhaA|NK|-$KU~Nf7{ub~tkZxS?}H zCrM3AS&^)tWTB=N06>hAcOyqhsRLZ=_Al1^?z``vK7G2w;mFC!IrrRi>*{u<)#RN2 z<~P47C@8R4EGL|B!p4oelf;f>m^OZbwPDV@^^N~WVsl1eyA27wiwfUw*7E^yxa5XS z&Na=sw!7>t!&WD0F~!gY0FY%vv1{oHJvxp70x8Zh1)}lXkGo6W4nMl&gge%s{r0x; zAGMDDsC9Hp%JaQ~FRm~C==$Q1j?3AK5Z}<9fBnYGe!uCo7i*8Uc5+0>S9D%?=;h{r zY2B7H{dc{30RT{mV~+k1it}guKx8vTp`-}zWk6rs&TgA4B zM-ZrFHNdZ#GGeNlP5rGGxXp28rc)WLsRO`aT;hDMtgF1SRlHPdI@fpImzRo&T<=}^ zWYr6q3u9X^auolStiEF66OoyN{ro6L%l0$8Ef*BGTu`h{Ok;#{i8Nb@{(S6v72mDz zn%?VLK@eVY=6!#A_^(fmdUF^%e;DQV`Ed_F@Yq8SJoZrERAQ-=+0ixnPui;AOq+P| zroGQo>-yHu@1FI-?@xQ-_or1pZ}c(Y^GyxjSH6rid-`6Z@~(|dXStnktUa)P?w_vx z^wUqTzyA7V%a$!(yx26&`Sa(ecCcyOd+)vX-FM$Z4?VPU<;uLgypvBpIWdBR1$Tpe zJG!pnTOrLlt+*vxN%YAT{OB=sN;UNvUQ3!EbhePgB{#!Cgz_@#cTgDv0MOp(G=up>b-lTZma23fFaW$CdCFN1|>;dZqx%?w7e}^UQl-cfJHL$9dVnibA}Ml z@@;)3cI}~;8%w9nj!q$i6vR=kmYO*#dCJ7p1v5zHC;;Gwfizv|;Yyd_C8M)Tp-1Kf3FT#Gj#GDvx<}G{ zvhEgjhscECp@=$UL+&#bE^Ye8qtQYD$SV$~E}WS-ePaBCO0y!LTNOeW064JZz$g*3 zDBXxE#B|9o)*k(f+Vg~%3JBRH-6N#>Ub{@{QO9Kx71OL)vH&}nKOrTe*gXV|KbvRYLDs z@(1I|86pms+~OrdqNso)00gFuBOUR6%oU1N=N6Q%0F)uNZ3LO9dzyn<09jQ`Sf8aD zNn8HeFeCe!18|PUdb@7R`(QzI#vA$sj;&nRcN@OLg~KH`CV(GHH%$I`p>OJi#cR&7 z*PQdfPxAlLM8gq?#C$Jx2mHPzr&Z3fG^GPX?y*Kcwe{G!Fb<`1J$XG5h{guab4)Oo z1mM6`lA$61+_mU}%6n?v$u+|+zF`+#vVhuDLbGj zX8?d@8M&Mdmw7+@_8(oC01VHjPpH0MU?+@kNaZwXl2Nj6COT{;OVbaYQ<7>DTr$PEru zbp3M@kPMO;Q6*6qm>^P&vytu`%akF|yx6oMPB@bQiwxs_9-$o39c!Ca)(h-$mzY_r z6>W;=C3Z)$S$vaC*-%m7 z-V8JnIY`Ou6T>rAIY@Dy^?R0Hh;Xl2_$6L3$ zF$zuQj8vy5Wn8Xw`-wiwL?-~GbI=*Kr9PY?J5C!!M7)Fm00!J-s;?)DpKF(YGbx@>tmzq)5KvV=UA4kt^e zIi+12a<4Zpb2plnmPFh7+-JJoTqR;is7mf}QN1HG5)uS#wVLBc1*h6<`jdxqTIKb91+C+nqM}?z`{)?Qeg3 zpk4jSk^j&t^q4T3wgKBAS&R@u1KTJEgaeZs42S3}K`vxCM}meqw;Qrz002T@vFY3j z+@%5l0>A+M742>)bA@j!eDBlLm`9rCwr%q{>O|8D?ehYAPn~=4IK*=EKED#ZB8_Gp zoO6T_U~Dauj4?&hmUh;a${BiVA&sMr^+ zO#7$*zvP*>&3gZP&aF!?__KaKR}dnA)XBYSfdDwLfPs)*T_rGJ5s{BlqwiUEnrDSr z_Vj9Qm;lglv2EqWf3{)~;H!-n_^Rb*d2=;hEL(5Nf9K9WPJipiqjzM##_ z=`9uQ1-PY)Mk1BJT!RQ<>Q=^C#T^nth;t4A=HTl&b~t!(Zqqr|rI-EDfh7R(4GMGEWb1EZ%U#4eQsh|NQgM`xl~qfA!u)YFGU1XFt2;mRqu)mv?KZZI68V**eaQ41$F)9p;VEg74j3z#MixxfFH&PXU_Wo)PNv`9v=Gh%X* zF-3(KD>LQGBcs~dy+TyTTK{~2v?9ZdLnb#od0gkQ?(FBlmnpPlT`zM@jy*O?_9gwq zFjzdvO#@jhAPC$riCqbwJ&p;;|7INx?_s2R-JwZVF~#j|x|9^e1a`El*5Kuv1_O$q=2gexvh5Oyc60$run@D-jVKEkiudQnVM{#LzUthD>PH5lfzk=ZS2Pi-hC((ZEC2%JFIRYzyP zEtuHhA=U#I$B;2xaw9o`@L6NUGMhv=w+r~;-}FZ9L6dpk;%aJACmCaEo2UV`oPAKy{*OX*eDH^5&ocYDCO2V-@Wul_lbxA!1xz_RIwwsN3>E79ZkiI z!$m2klqDH2&Si>-H>;52JNqXe=Zdj~YfgYYbgfq8&YYZ3*EroTt`jM>A-sFuMgRan zf*AQh^6jZlTo}L2HGH~u7^kYUDaAK$#});RE8~0Qsx#dRI1AGGaczg; z1aC*F5~@}@D95+2yTq}L005Ohn?U!}wWf(_RFZt^d9%I@>h{f%ycX4`yAIN2V*fCV za$B4lXa5n2R+Mae7){#aC7vt$xB0UVFkpb*9qX#;|J0@#v;TTa!Jn4rVuU2A>4Kxy zR>9bd+9%5`>3a)Z&C&N?o-o$CX}6|6NsoU0&DrjHp1W{uj%jkn+ist^?8e@~ECAVG zPuK&%Fv`swmHV5YKmBgxsHRUntfO3NEC~qX>@c|>*DH#lRvvA|KdiV z6tam{hY9LRf4AZ+FygQH=3{&O%GHL=Fdpgor5RC`|1#HjAARm5Kl$VCI(6GNvEJ z#_j;d+6on-E2<&?3(On|GJ$s*}YW*kWCpP6WtD{A|&*6flc~J9V&FHWlzr}*6aP_VbMF=& zTdh6cI?Ax2!dJGM9s5lyHSD5O{fes~4-ndox7k#P;UHOyQ@8JKdXk9H0>18;-6EHb z4|IB^l)WULbXt`Lxj(J3NNA2dsSwj6r#sTlx=fy_lQ)_tXqu=eB@#Y#G%3R_x3O~T zKQ2GR@K7%vz;%ltOm$txIfE_%((8=+P4z*SU(qA-NPrDP8GzJ}r6EI%RAyxa$QEAx^tFx^UZ>grvax zC246bncR7;W2uD?-@W0^H`=e-*I$4A3opFz`s=Sd9FFWkyvyaXSS$#kn{U4PuDkB4 zs;a80s=Dj0yR260rI%hh?A<*=F>>T)ZAZ`{0Z1If(kh4I%Y1+Al5t|lhI9%jt;&q3 zv%S4`m5XF%C{3%?(m!vUmkC-OTLcRS3miI%k3%mv<;@ipZ|zVQ{Q{ZD$7_6_lHk=d zqT_iw*D5A0;hBbH*P}6)qbW1`j*Tpt+-)gEiVS%H5{%{DU(@R+H|D?};Sn(Db zI6jKef=w2?$H8SHe|+K!=J z0wkFjzNm0o{ORwFSsD-$|F7qKIkZ#9$f7yh*Hk2hk5;y=R!jdJo|oyd@^u!O9cr@t zVVB!UR&(>^e$UIZd6D_;FwzM@!c^*2qklQd{A?^V^?yG*&Whow^e=iu;S|8(sm zk30eZC!BCXU&+%?KYhg&R{+3Ie)5w{CUf0&*F_?cnKNg8@WBTThhsQQX=&J4SaLg;#seWt9DXC-aoerY*ajW(ijwh3I>f$+SyG=^qY%0A&iLXv>LU~!! zr3IEC5By`z?t9q5W*TR{8dXdx-Lp;EpRufSSc0N!OA=*_;KdVwL(ZZ)+Asex%JsL+ z^V!>}eS4d4qdNZ08+@zDKBjTMZ+Rm5?xI<*J7-pRv>(7R)<_$2h=CX(s&4x`KSmNw z#E{|SxxSbpn2lR=Q?f`ODg}|2yuTYuv-;mi(2Bx1s4g?TqOi zvxTCMb>ZKu0e~AOf8RH%{f7X6OjNYSRC?5wE2^0YWzTIhTX()PDlOV_Wx%wXbKkiI z8A$wjfoC&!J->Xg2PH0^6`FuXy^-WAHw>x&yQ0@M>(C<}kGov16W|;H9U(lrJ799- z6L>uqi#eUn!_tAQ=*C`m7m5CH)aCw)sJHl$=*Z;OJp{5 zP)*(Z@Xrss+_FPXKV{lq9{t4;LlN~oX`qOlDqp#vud#LmM#Ni!sS-DNP>i52Fcu%`l^-1y4LG9WB!7-?Q zZo23h)7BXrfA-E4Ci2rxU1>7%-j=Z}BHNnCuv}75O|5bmPREdRZRLV% zDsEj?|Kzl$)1Mr$!dgwcq>vUWWWkSVZpdJJ5F}i{OP-wq9yD4%6BdTXQQ68s^7o!&nK?=e(nVgyPr;Hfl$*6 zlhz*p#IbkXob&L&58C@Y{U0Cle>21sm*QM^Aj3Y?wJ^=3O^JM+5ddh6_>>J6F%Fh6 z%UZOi1!?XfG{r%VazX89r4dMtr2Ko9#_+{2+-&JW`I$9)ubKGPtge|*_NF0xv>E`o zrUe%kpHgyrWqo+h?T1iS(r{Iw6i3C6)*P_1z>3m-?bKu`0{|g`DxYjMn}^dg`Cvdr ztop_N{=KGhBytarL>zzY#?S7bbxfT7xCaV9VU_fn;-y3CxsaFJ zcufV?q4crZou!O>YZ5bFxYb=ZxHA;zo_DO1T5l>}+slWQou`=`UitSS#SZ*W*Zwy{ zOmSPA3PsA$b*;+8Es;P*7XcvEWh+~22r0AgFh}!CnoAf8v%4ikrRdH8DkhP1*$B!{ zK({oO{h|>7_Nfs&PNEH`KQ_7JhJud(0Jv!e9$6Xy7;r}FMc#)mdHkK|QMJ$K9dO@} z%{uX$oBmn$2>^VM7XS3_r7&W2Et7CM2MZCvg3Y<2b@9vz^Q~X*f5#6qEQ?lD z3^`vB%k}>Hk_9b>_v4o*^)KhEYRdPu$#Flo)ZOpD*?Ico{10yb_&V`_y7p@VqH#-z zn=(?pNXT#{(yKwl)R2rTY=CDYP?>yDFe={}*Udo#W`#6!v{BuT_i5dx14MT!0Du@+ zf(AC3wfm6xE)O?~-$vuxZz%abpI(~P<1T0c{eB2_M_3@mx zn9K5|73;tW2pO(~2i=@$uKhTwIlP$o?&Tky_eg~}oToY>HfLFy?)l|>K`^Vt(7OlM znwJpcs!;9uIsfN=dwBXc9N2!xjH*Ys)1J`qHjCPO?t1(ZY(PQJMyT-Z`v-#~J5Rss z8&|faZ7A%Z|I@Yq4Zu2Bx^=@LXdXdO!P>EZw}Xg+drJx!ub<|iY;Q{`Nt>3m3AwW7 z-YbCx0^Nml=uOxsM={o@(lh*S^oIbJMJr18zH4SYOWO+wnQiTb_qGE717L}S>-jcz z`K(V*d*H;}@1sZ2&cIqUfU9%gS4`9Vk1zG_C>SA`SmpYT_ym_}9Ucvb0I-gfI*D4~ z_|t3MV&=ov(eX}4=|+PS6fGBs2G%Ye4dPA0MA@|U_GEo7~Y#iMso&mLn$7_of=L!G-QPFy>on&*Zq&aT!T5 zvzbPAgJ~BteqvhoV|il)lKFz55vlday9yc#SU5tSn$Vp~qCYkPd92$+TRZo?ypE;Q zz&X+RO3jr>TKb~*6Bp0wIWL`EE&{Jw?JqCuYYK_d_Mc8uE7j2t>U>qrVR@aw5SvxP zq~TF(*nr&SjHt|T5Y2%WFQ3Hirq!t;9a)JM_|D=09FF|GA4EnlAtU_Rc*zs_Ne3zrD{s zXJ#_5JZJJC2_ZZLsT4veD6N#<2GrGJ?X9r13f1bBUR-XIIPJvp#xu?)t1bb?YBVt`N@-B-jnsWovXxtO zjbI%?eKVYIvNfoRPmdJG02cMSfZS==nlxLJW^LAS@3gAP#ru;t=a3i^$UD!C%YWfh zb|96;$|I(88f04EO-w>86wX+?Z|v*sReB}>1eqSG85IrXEXcITOYeV$s>+SbT}si~ zihUi$QH^?#C0^6?R}auwMF`r9m3?1*(LW;;yJq%B?tABZ$r8@xt z$qFZ^_rkKs&w{KBeEG+`P7xtU9%zn1jB7_Kt{Q{LJ!UVk%1y4q#)#);BAv?B&8}8k zC_U4#%ZxyJ2e;O>0R!r`>P|W6A=J`4>+A>xPnlT$7-2Q`aZes)7Yc25({V>BUDV1q zWn`?`7xU{eI9I=I)mPstzVVKQJGL?micE?M>u$~i4uAfydBrtqcYNdM&A!>^mq*?g z9`bR7>K^$DxuMnlN2g`$KiG5Ld%O>MKdDWUspELS2((Slk~=dTU$n~2l0Pqy zH0HM-o$-218ywg&W$BHbcQhP-_s5sj6Ez`;&Jsj)Vi6@GI?+Y1A)@z)vPy!ei(P$* z&gxwVqDEb!m*_o8zM`%Ej6A>JdH(pF=bYdEGjq<&+%xxn?q~MQeBSrIeyl`(efh3V zE?zF6?4y&>bw%yd+y7LvT!n;%r<)8OY(jE|-Uwv28h=Gxc~vx})YdRwsVUjHZUN1* zGZiC+Ep~c2(%EykNt9yM$I=SCfBxp60)sA_Rev8;hG8C;95<>f)tzAZNJd6zmwYb` zdHr@3yMS`qkqr#@Stzd?Z}->p$a#P}%AZbCqFGdigNwqX>Ok<_iF;9Z3ER^Z=?#kT zJ(CcvBpO1Ft$hA#)9KE%5xD;TjsjOMeT@d0(o{lTxJISSN{{cx#CT@!GGIiHC2Z98 z{TB2W9kyji+-D`qvM?lEjz>$3B0MpEOOh5#sTfb--9+}+7$#Q5wAtd2ggj?rkg!DQ zAnFMtGg%<>W*ggwbOjxL&L<=6)FnIv%Q-*MfowRks`6+$gINkkr==)JRPJ3P>s((~ zrxYAq#v(Ct2v72wx-YpAsvaEsYIIyDX34uj8N#k2c!8Ce}Q_*EBIIOYe-Mnp2NV=n84en z&=ZcygUC0V``Rg$@lWK50=R12f2ICjm8L~GMSbju5j|=8PP1zS#c-bo2E|#JiCA?Q z8=){P=C44!h=YC(7^?9hJ`0GmG@wv_!p6FiS+)V~*0Je{a#QF-nN7pWtGpeq6K|PG zXl>oMLLvg(4PN;TOniQ8r_3*OtV*BNJo^ozy^%_ z2%@yI_vpF%^5>1W|I|+mz0G)cA*DiCi?w>}cE7puC^14IBKGtQL&Y4qcBpNJNuSzz z-xnk$K4Q-;rhD)U<`?-PxptS6EbM!$VW2=PymdmzdQ2`h)5K>CI;c#JlX;^>Op9Z2XYH+ES4eD5Vm{lIU77pq6@cpQTN2gajVfa zZd>B>TxQ>&b^~Q*BU*Gr=?4hQ*VUL4uK@RUbTFxZy}G7f4$NQc^=k2iyG8$(OBm-b zjZx4dcTw0^t)xhwU#Zd8%}Z%f(>Ufnn5G|Q1?eXBmkKEoJZA3~t84LnExk;~lSvjL z`ZHMh=hwq&uY!@~DbmUZT`w(Xx{GptoXp>CtJXW)vppMF6s$xB+ z@})KBH&$|uyfTKuDDX5@w6dBEP9xLcBPlqTAYpCuQC1Q@llce9o#9aVjZC_%%-n>X z&3i=(R?f2V2(il3B4RpNN`UhuicB_s79Uj8p*yi)-+(Vte)*M!b zOEjWxA3u|Kr`q$9)gr`T<^lg_b^D$iJbBN&d@XTGLFjiP{?Bmb*%?LOMpmnI%Im(E zj-H&Ywb=ZVaG<>ao<|^kZz9(;A6AhN^i|Bpcg)m;+{xBR;(N5u=qJs5>)0BP3JvbO zt@u?Ln(YVn6BB<{ZZ&HRpEtx|{Oum|@WS+f?%NEmurY|Cs@oTt_%~s(o?h~P*4D)< zrIB|C=4?5O(Q3|)8y2mlw8BEMfmO#qFH&^`0AI}g5Aqk2+q80iVcXKJc^&b?i-7~9OpNcGS94xWVBniP2votS0=C;LzJ&ka# z8Q`ro{)lZ~#TpoObd6h1=!MWrbJr8#1g_`i^sbPe@FS~~m^Y%oO-^27&0trXGci(o z0yHP-DA;5lGS5igLqUIV2DUIqUYhQG$V=HrE!4)|E)l5RTjbP1D;!_Ia3FWNSkD7-+D7V+aHA}L~Z&H3j&jxrtX1Z^G z))SAX5YI+;xs5&-`%Op^xVo0TLS3gu7*#Ejbmg`T7k086rIvmU^t7R}bSuch9`&eb zS*1sYgC~MMa1v{B$w4@%vk`QmPS52@aLE8=8OuWp&?1olvBJFf(P!E*ZkkXPPZhN011_Y`Wvai1`=ytsAteC=$*a1$~AKxiH+E42GG8y#Ka{ZmF% zJg_*v0JbhsUT|FhQkWx6GDa=TB(pzEaq-lGC+7CLKIwphz z)O_zEtEvdXp>19gz5QKa9YJ{RkB@2#Oh=VV_jTT`sh1zN<}4(X9mQ$-#P{QaSjb_V z8<#EwxS)W|DWq|Meuu_$7awLKYn8TvGP4?|lTV~B6SP{%3bdCwJsPF^4UJizN67y2 zqE1D$xJdG)LaScWpA{xgYQIZfRL$u{*@kU?xyrF^{hpidX*SM?_H1NxC~0kM91`R` zcAVyf3t&w&XvhjY=YlnE;ogp(w6%n2yF=vK3{)uBf}RF*HlRfwTEV2^bX+D1InlSF z=~8L4Kc7`=b%=3+K-v$nw-`{2w?W|{IWc_!V1RtCz`$;?*Uuqr*WE~mJFg$`rBH~j zwfUlc<+bmCe~T+N>;Yfy*p-I#QLVn!9vm_qfK6z9@~e!!D2%`?&3ViW4Lh3#Q+sFk zo!Up*DfD4U)Mz6!$n}JMA_DMgUIv{I9Z4r^0r;=hW-tFeXDh}7@neiS%HxmjiY>!j+;Ok zd2zy}fKZ`L5;oWRtsVRbMAA+m$9Uk5H;04wim=4J6I#nE=flP=2noy%7>BlLq3P~# zNVVqnL?B)8?d|mDLRtH3#Xz;pB}+XW=2XjUastTv3Oyjj;2o}KHcCa44>aElLAT^* zeB{&yIT-FB5$413`g7{r)pZ0s35djCscqNSY`}X9xR5S4$8)y*-Nk(;4HdN}ECbsg!;2;Q9Fiyk+>vx4TS78ws0i-RXhlfgn)AvuqHEO?8f% z-gT34Ec6cw#cpCDUPNu-wuvwm&+<>VbX+O2_1L5pPf(BTe2<}I1sjVHoN&xf2TW@2 zy?2e&CW(&o1&H)pvs**ek6P>{J*nvT5O_jG;7mX9w%$E<2z5-8rOe~}Gcb5^-IbTvAdqi14QPf4|I57{0i z9S-|)fkj#clHJ>RNn|pzWkJ*+E`Z6~PPbT95sQggb)> zxv-uzRT^Rw)uN;_E1_9R;$YHuV^uGxxmk=R1BXL}Y2Fmbzv_|^w%IQRfrz%YXh>Q3 zL7My?;M>X~@?y&Y47e!xn>m-BGf4#o7Y%Sct;mVy>^B&` z+*ZNtPt3$>5lU6lDGtYn3jbx}vv$n(_=)mgQ!uJd`YON@5#Ig_tl^DKqUFf{wVot* zHj`xfzNoOU=WT5w0^x^U3hVGY)GgLSCMJrb)MLN9Zs)Q)S{B-N*!NmV@Mhnl$e;fB8#Kh?g>XQ%Qz)oWEND+uV~@;5Bj&lo@|2IJqNdOh$Bh&s#PXbSg2 zP{V`5&pAyj*Wn^+5`I`00|NtZ6$69m`R3=^jXih_3=AN6M#lVHmHi}d?02Dn3oIbn z=4161Wd8Sf0B*4%Z=AcG}7iT&SmfC7c}}|XPxQ)xhrlH)@nEAySmWSgU#5E-m2IAF^rOp zwnG_vi63v>lb=@wA`XBa0e+`Zox_*ix>+hqQ?vg>#u}~;#3u{ME70;pNJu+Ace4rE z-QB(En_{ujM#$v1f$|3aS|#6(6(&opuCCstp#g;G?~_R*KLKg>H#b!i*hYxwRE1VY z*loxRG!Xz($8omKv)*C0ZWmbFWm2buZUDOE*$P0b!5|S45pgzKnwOWCpZ}19!xrke zP5yWAZ$|3j(v6`zd|LzEwkBM0-}Y+lCmDgk?~0)IYHCKK-$F?N*k{q~?tHDizBkC5 z|Nd(F`Q;UoTYqn^slKYp4G;(Ox8U3U;iDhNB{r; literal 0 HcmV?d00001 diff --git a/tutorials/training/source_en/advanced_use/images/fuzz_seed.png b/tutorials/training/source_en/advanced_use/images/fuzz_seed.png new file mode 100644 index 0000000000000000000000000000000000000000..cb138aebfabea1a1f778fbb65b6a0ee4533974e2 GIT binary patch literal 6175 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 xxf4#LN(5!936l1NZ21i#X + +- [Test Model Security Using Fuzz Testing](#test-model-security-using-fuzz-testing) + - [Overview](#overview) + - [Implementation](#implementation) + - [Importing Library Files](#importing-library-files) + - [Parameter Configuration](#parameter-configuration) + - [Fuzz Testing Application](#fuzz-testing-application) + + +   + +## Overview + +The decision logic of traditional software is determined by the code logic. Traditional software determines whether the test is adequate based on the code line coverage rate. Ideally, the higher the coverage rate is, the more adequate the code test is. However, for deep neural network, the decision logic of the program is determined by the training data, network structure, and parameters through a black box mechanism. The code line coverage fails to evaluate the test adequacy. A more suitable test evaluation criterion needs to be selected according to the deep network features to guide the neural network to perform a more adequate test and find more corner error cases, thereby ensuring universality and robustness of a model. + +The fuzz testing module of MindArmour uses the neuron coverage rate as the test evaluation criterion. Neuron coverage is the range of the number of neurons observed and activated and the range of the neuron output value through a set of inputs. The neuron coverage is used to guide input mutation so that input can activate more neurons and neuron values can be distributed in a wider range. In this way, we can explore different types of model output results and incorrect behaviors. + +The LeNet model and MNIST dataset are used as an example to describe how to use Fuzz testing. + +> This example is for CPUs, GPUs, and Ascend 910 AI processors. You can download the complete sample code at . + +## Implementation + +### Importing Library Files + +The following lists the required common modules, MindSpore-related modules, Fuzz testing feature modules, and configuration log labels and log levels. + +```python +import numpy as np +from mindspore import Model +from mindspore import context +from mindspore.train.serialization import load_checkpoint, load_param_into_net + +from mindarmour.fuzz_testing import Fuzzer +from mindarmour.fuzz_testing import ModelCoverageMetrics +from mindarmour.utils.logger import LogUtil + +from examples.common.dataset.data_processing import generate_mnist_dataset +from examples.common.networks.lenet5.lenet5_net import LeNet5 + +LOGGER = LogUtil.get_instance() +TAG = 'Fuzz_testing' +LOGGER.set_level('INFO') +``` + +### Parameter Configuration + +Configure necessary information, including the environment information and execution mode. + +```python +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") +``` + +For details about the API configuration, see the `context.set_context`. + +### Fuzz testing Application + +1. Create a LeNet model and load the MNIST dataset. The operation is the same as that for [Model Security](). + + ```python + ... + # Lenet model + model = Model(net) + # get training data + data_list = "../common/dataset/MNIST/train" + batch_size = 32 + ds = generate_mnist_dataset(data_list, batch_size, sparse=False) + train_images = [] + for data in ds.create_tuple_iterator(): + images = data[0].asnumpy().astype(np.float32) + train_images.append(images) + train_images = np.concatenate(train_images, axis=0) + + # get test data + data_list = "../common/dataset/MNIST/test" + batch_size = 32 + ds = generate_mnist_dataset(data_list, batch_size, sparse=False) + test_images = [] + test_labels = [] + for data in ds.create_tuple_iterator(): + images = data[0].asnumpy().astype(np.float32) + labels = data[1].asnumpy() + test_images.append(images) + test_labels.append(labels) + test_images = np.concatenate(test_images, axis=0) + test_labels = np.concatenate(test_labels, axis=0) + ``` + +2. Configure Fuzzer parameters. + + Set the data mutation method and parameters. Multiple methods can be configured at the same time. Currently, the following data mutation methods are supported: + + - Image affine transformation methods: Translate, Scale, Shear, and Rotate. + - Methods based on image pixel value changes: Contrast, Brightness, Blur, and Noise. + - Methods for generating adversarial examples based on white-box and black-box attacks: FGSM, PGD, and MDIIM. + + The data mutation method must include the method based on the image pixel value changes. + + The first two image transform methods support user-defined configuration parameters and randomly generated parameters by algorithms. For user-defined configuration parameters see the class methods corresponding to https://gitee.com/mindspore/mindarmour/blob/master/mindarmour/fuzz_testing/image_transform.py. For randomly generated parameters by algorithms you can set method's params to `'auto_param': [True]`. The mutation parameters are randomly generated within the recommended range. + + For details about how to set parameters based on the attack defense method, see the corresponding attack method class. + + Following is an example for configure Fuzzer parameters. + + ```python + mutate_config = [{'method': 'Blur', + 'params': {'radius': [0.1, 0.2, 0.3], + 'auto_param': [True, False]}}, + {'method': 'Contrast', + 'params': {'auto_param': [True]}}, + {'method': 'Translate', + 'params': {'auto_param': [True]}}, + {'method': 'Brightness', + 'params': {'auto_param': [True]}}, + {'method': 'Noise', + 'params': {'auto_param': [True]}}, + {'method': 'Scale', + 'params': {'auto_param': [True]}}, + {'method': 'Shear', + 'params': {'auto_param': [True]}}, + {'method': 'FGSM', + 'params': {'eps': [0.3, 0.2, 0.4], 'alpha': [0.1]}} + ] + ``` + + Set evaluation metrics. Currently, the following evaluation metrics are supported: + - General evaluation metric: accuracy + - Neuron coverage rate metrics: kmnc, nbc, and snac + - Adversarial attack evaluation metric: attack_success_rate. + You can set this parameter to `auto`. By default, all evaluation metrics are used. + + ```python + eval_metrics =['accuracy', 'kmnc', 'attack_success_rate'] + ``` + +3. Initialize the seed queue. Each seed in the seed queue has two values: original image and image label. Here we select 100 samples as initial seed queue. + + ```python + # make initial seeds + initial_seeds = [] + for img, label in zip(test_images, test_labels): + initial_seeds.append([img, label]) + initial_seeds = initial_seeds[:100] + ``` + +4. Test the neuron coverage rate before the fuzz testing. + + ```python + segmented_num=1000 + neuron_num=10 + model_coverage_test = ModelCoverageMetrics(model, segmented_num, neuron_num, train_images) + model_coverage_test.calculate_coverage(np.array(test_images[:100]).astype(np.float32)) + LOGGER.info(TAG, 'KMNC of this test is : %s', model_coverage_test.get_kmnc()) + ``` + + Result: + + ```python + KMNC of this test is : 0.0851 + ``` + +5. Perform the fuzz testing. + + ```python + eval_metrics = 'auto' + model_fuzz_test = Fuzzer(model, train_images, neuron_num, segmented_num) + _, _, _, _, metrics = model_fuzz_test.fuzzing(mutate_config, initial_seeds, eval_metrics=eval_metrics) + ``` + +6. Experiment results. + + The results of fuzz testing contains five aspect data: + + - fuzz_samples: mutated samples in fuzz testing. + - true_labels: the ground truth labels of fuzz_samples. + - fuzz_pred: predictions of tested model about fuzz_samples. + - fuzz_strategies: the methods used to mutate fuzz_samples. + - metrics_report: metrics report of fuzz testing. + + The first 4 returns can be used to further calculated complex metrics and analyze the robustness of the model. + + Run the following command to view the result: + + ```python + if metrics: + for key in metrics: + LOGGER.info(TAG, key + ': %s', metrics[key]) + ``` + + The fuzz testing result is as follows: + + ```python + Accuracy: 0.7929 + Attack_success_rate: 0.3939 + Neural_coverage_KMNC: 0.4797 + ``` + + Before the fuzzing test, the KMNC neuron coverage rate of the seed is 8.5%. After the fuzzing test, the KMNC neuron coverage rate is 47.97%, and the neuron coverage rate and sample diversity increase. After the fuzzing test, the accuracy rate of the model to generate samples is 79.29%, and the attack success rate is 39.39% for samples using the adversarial attack method. Since the initial seed, the mutation method and the corresponding parameters are all randomly selected, it is normal that the result floats to some extent. + + Original image: + + ![fuzz_seed](./images/fuzz_seed.png) + + Mutation images generated by fuzzing: + + ![fuzz_res](./images/fuzz_res.png) \ No newline at end of file diff --git a/tutorials/training/source_en/index.rst b/tutorials/training/source_en/index.rst index 7f32e97139..5e0530dc3c 100644 --- a/tutorials/training/source_en/index.rst +++ b/tutorials/training/source_en/index.rst @@ -36,7 +36,7 @@ Train with MindSpore .. toctree:: :glob: :maxdepth: 1 - :caption: + :caption: advanced_use/custom_operator advanced_use/migrate_script @@ -77,6 +77,7 @@ Train with MindSpore advanced_use/improve_model_security_nad advanced_use/protect_user_privacy_with_differential_privacy + advanced_use/test_model_security_fuzzing .. toctree:: :glob: diff --git a/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md b/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md index 78a717a180..70a54faf10 100644 --- a/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md +++ b/tutorials/training/source_zh_cn/advanced_use/test_model_security_fuzzing.md @@ -1,16 +1,16 @@ -# 使用fuzzer模块测试模型安全性 +# 使用fuzz testing模块测试模型安全性 `Linux` `Ascend` `GPU` `CPU` `数据准备` `模型开发` `模型训练` `模型调优` `企业` `高级` -- [使用fuzzer模块测试模型安全性](#使用fuzzer模块测试模型安全性) +- [使用fuzz testing模块测试模型安全性](#使用fuzz-testing模块测试模型安全性) - [概述](#概述) - [实现阶段](#实现阶段) - [导入需要的库文件](#导入需要的库文件) - [参数配置](#参数配置) - - [运用Fuzzer](#运用fuzzer) - + - [运用Fuzz Testing](#运用fuzz-testing) +    @@ -18,33 +18,33 @@ 传统软件的决策逻辑由代码逻辑决定,传统软件通过代码行覆盖率来判断当前测试是否充分,理想情况下覆盖率越高,代码测试越充分。然而,对于深度神经网络而言,程序的决策逻辑由训练数据、网络模型结构和参数通过某种黑盒机制决定,代码行覆盖率已不足以评估测试的充分性。需要根据深度网络的特点选择更为适合的测试评价准则,指导神经网络进行更为充分的测试,发现更多的边缘错误用例,从而确保模型的通用性、鲁棒性。 -MindArmour的Fuzzer模块以神经元覆盖率作为测试评价准则。神经元覆盖率,是指通过一组输入观察到的、激活的神经元数量和神经元输出值的范围。我们通过神经元覆盖率来指导输入变异,让输入能够激活更多的神经元,神经元值的分布范围更广,从而探索不同类型的模型输出结果、错误行为。 +MindArmour的fuzz_testing模块以神经元覆盖率作为测试评价准则。神经元覆盖率,是指通过一组输入观察到的、激活的神经元数量和神经元输出值的范围。我们通过神经元覆盖率来指导输入变异,让输入能够激活更多的神经元,神经元值的分布范围更广,从而探索不同类型的模型输出结果、错误行为。 这里以LeNet模型,MNIST数据集为例,说明如何使用Fuzzer。 -> 本例面向CPU、GPU、Ascend 910 AI处理器,你可以在这里下载完整的样例代码: +> 本例面向CPU、GPU、Ascend 910 AI处理器,你可以在这里下载完整的样例代码: ## 实现阶段 ### 导入需要的库文件 -下列是我们需要的公共模块、MindSpore相关模块和Fuzzer特性模块,以及配置日志标签和日志等级。 +下列是我们需要的公共模块、MindSpore相关模块和fuzz_testing特性模块,以及配置日志标签和日志等级。 ```python -import sys - import numpy as np from mindspore import Model from mindspore import context from mindspore.train.serialization import load_checkpoint, load_param_into_net -from lenet5_net import LeNet5 -from mindarmour.fuzzing.fuzzing import Fuzzer -from mindarmour.fuzzing.model_coverage_metrics import ModelCoverageMetrics +from mindarmour.fuzz_testing import Fuzzer +from mindarmour.fuzz_testing import ModelCoverageMetrics from mindarmour.utils.logger import LogUtil +from examples.common.dataset.data_processing import generate_mnist_dataset +from examples.common.networks.lenet5.lenet5_net import LeNet5 + LOGGER = LogUtil.get_instance() -TAG = 'Fuzz_test' +TAG = 'Fuzz_testing' LOGGER.set_level('INFO') ``` @@ -53,12 +53,12 @@ LOGGER.set_level('INFO') 配置必要的信息,包括环境信息、执行的模式。 ```python -context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) +context.set_context(mode=context.GRAPH_MODE, device_target="Ascend") ``` 详细的接口配置信息,请参见`context.set_context`接口说明。 -### 运用Fuzzer +### 运用Fuzz Testing 1. 建立LeNet模型,加载MNIST数据集,操作同[模型安全]() @@ -67,17 +67,17 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) # Lenet model model = Model(net) # get training data - data_list = "./MNIST_unzip/train" + data_list = "../common/dataset/MNIST/train" batch_size = 32 ds = generate_mnist_dataset(data_list, batch_size, sparse=False) train_images = [] for data in ds.create_tuple_iterator(): images = data[0].asnumpy().astype(np.float32) train_images.append(images) - train_images = np.concatenate(train_images, axis=0) + train_images = np.concatenate(train_images, axis=0) # get test data - data_list = "./MNIST_unzip/test" + data_list = "../common/dataset/MNIST/test" batch_size = 32 ds = generate_mnist_dataset(data_list, batch_size, sparse=False) test_images = [] @@ -93,36 +93,40 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) 2. Fuzzer参数配置。 - 设置数据变异方法及参数。目前支持的数据变异方法包含三类: + 设置数据变异方法及参数。支持同时配置多种方法,目前支持的数据变异方法包含三类: - 图像仿射变换方法:Translate、Scale、Shear、Rotate。 - 基于图像像素值变化的方法: Contrast、Brightness、Blur、Noise。 - 基于对抗攻击的白盒、黑盒对抗样本生成方法:FGSM、PGD、MDIIM。 - 数据变异方法一定要包含基于图像像素值变化的方法。 + 数据变异方法中一定要包含基于图像像素值变化的方法。 - 前两种图像变化方法的可配置参数,以及推荐参数范围请参考:对应的类方法,也可以均设置为`'auto_param': True`,变异参数将在推荐范围内随机生成。 + 前两种类型的图像变化方法,支持用户自定义配置参数,也支持算法随机选择参数。用于自定义参数配置范围请参考: + 中对应的类方法。算法随机选择参数,则`params`设置为`'auto_param': [True]`,参数将在推荐范围内随机生成。 基于对抗攻击方法的参数配置请参考对应的攻击方法类。 + + 下面时变异方法及其参数配置的一个例子: ```python mutate_config = [{'method': 'Blur', - 'params': {'auto_param': True}}, + 'params': {'radius': [0.1, 0.2, 0.3], + 'auto_param': [True, False]}}, {'method': 'Contrast', - 'params': {'auto_param': True}}, + 'params': {'auto_param': [True]}}, {'method': 'Translate', - 'params': {'auto_param': True}}, + 'params': {'auto_param': [True]}}, {'method': 'Brightness', - 'params': {'auto_param': True}}, + 'params': {'auto_param': [True]}}, {'method': 'Noise', - 'params': {'auto_param': True}}, + 'params': {'auto_param': [True]}}, {'method': 'Scale', - 'params': {'auto_param': True}}, + 'params': {'auto_param': [True]}}, {'method': 'Shear', - 'params': {'auto_param': True}}, + 'params': {'auto_param': [True]}}, {'method': 'FGSM', - 'params': {'eps': 0.3, 'alpha': 0.1}} - ] + 'params': {'eps': [0.3, 0.2, 0.4], 'alpha': [0.1]}} + ] ``` 设置评价指标,目前支持5种评价指标,包括: @@ -135,13 +139,13 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) eval_metrics =['accuracy', 'kmnc', 'attack_success_rate'] ``` -3. 初始化种子队列,种子队列中的每个种子,包含3个值:原始图片、图片标签。 +3. 初始化种子队列,种子队列中的每个种子,包含2个值:原始图片、图片标签。这里取100个样本作为初始种子队列。 ```python # make initial seeds initial_seeds = [] for img, label in zip(test_images, test_labels): - initial_seeds.append([img, label]) + initial_seeds.append([img, label]) initial_seeds = initial_seeds[:100] ``` @@ -164,11 +168,14 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) 5. Fuzz测试。 ```python + eval_metrics = 'auto' model_fuzz_test = Fuzzer(model, train_images, neuron_num, segmented_num) _, _, _, _, metrics = model_fuzz_test.fuzzing(mutate_config, initial_seeds, eval_metrics=eval_metrics) ``` 6. 实验结果。 + + fuzzing的返回结果中包含了5个数据:fuzz生成的样本fuzz_samples、生成样本的真实标签true_labels、被测模型对于生成样本的预测值fuzz_preds、 生成样本使用的变异方法fuzz_strategies、fuzz testing的评估报告metrics_report。用户可使用这些返回结果进一步的分析模型的鲁棒性。这里只展开metrics_report,查看fuzz testing后的各个评估指标。 ```python if metrics: @@ -184,7 +191,7 @@ context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target) Neural_coverage_KMNC: 0.4797 ``` - Fuzz测试前种子的KMNC神经元覆盖率为8.5%,Fuzz后,KMNC神经元覆盖率为47.97%,神经元覆盖率提升,样本的多样性提升。Fuzz后,模型对于Fuzz生成样本的准确率为79.29%,使用了对抗攻击方法的样本,攻击成功率为47.97%。由于初始化种子、变异方法和相应的参数均为随机选择的,结果有一定的浮动是正常的。 + Fuzz测试前种子的KMNC神经元覆盖率为8.5%,Fuzz后,KMNC神经元覆盖率为47.97%,神经元覆盖率提升,样本的多样性提升。Fuzz后,模型对于Fuzz生成样本的准确率为79.29%,使用了对抗攻击方法的样本,攻击成功率为39.39%。由于初始化种子、变异方法和相应的参数均为随机选择的,结果有一定的浮动是正常的。 原始图片: -- Gitee From c914387500f2d2b5767281361cf87aeabddbccbf Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Fri, 18 Sep 2020 11:55:01 +0800 Subject: [PATCH 080/100] Fix the link for markdown --- tutorials/notebook/README.md | 32 +++++++++---------- .../computer_vision_application.ipynb | 2 +- ...ert_dataset_to_mindspore_data_format.ipynb | 4 +-- .../customized_debugging_information.ipynb | 6 ++-- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/tutorials/notebook/README.md b/tutorials/notebook/README.md index 23361b0ea8..3221cd630f 100644 --- a/tutorials/notebook/README.md +++ b/tutorials/notebook/README.md @@ -50,19 +50,19 @@ | 教  程  名  称 | 文  件  名  称 | 教  程  类  别 | 内  容  描  述 | :----------- | :----------- | :------- |:------ -| 手写数字分类识别入门体验教程 | [quick_start.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/quick_start.ipynb) | 快速入门 | - CPU平台下从数据集到模型验证的全过程解读
      - 体验教程中各功能模块的使用说明
      - 数据集图形化展示
      - 了解LeNet5具体结构和参数作用
      - 学习使用自定义回调函数
      - loss值与训练步数的变化图
      - 模型精度与训练步数的变化图
      - 使用模型应用到手写图片的预测与分类上 -| 线性拟合 | [linear_regression.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/linear_regression.ipynb) | 快速入门 | - 了解线性拟合的算法原理
      - 了解在MindSpore中如何实现线性拟合的算法原理
      - 学习使用MindSpore实现AI训练中的正向传播和方向传播
      - 可视化线性函数拟合数据的全过程。 -| 加载数据集 | [loading_dataset.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/loading_dataset.ipynb) | 使用指南 | - 学习MindSpore中加载数据集的方法
      - 展示加载常用数据集的方法
      - 展示加载MindRecord格式数据集的方法
      - 展示加载自定义格式数据集的方法 -| 将数据集转换为MindSpore数据格式 | [convert_dataset_to_mindspore_data_format.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb) | 使用指南 | - 展示将MNIST数据集转换为MindSpore数据格式
      - 展示将CSV数据集转换为MindSpore数据格式
      - 展示将CIFAR-10数据集转换为MindSpore数据格式
      - 展示将CIFAR-100数据集转换为MindSpore数据格式
      - 展示将ImageNet数据集转换为MindSpore数据格式
      - 展示用户自定义生成MindSpore数据格式 -| 数据处理与数据增强 | [data_loading_enhancement.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb) | 使用指南 | - 学习MindSpore中数据处理和增强的方法
      - 展示数据处理、增强方法的实际操作
      - 对比展示数据处理前和处理后的效果
      - 表述在数据处理、增强后的意义 -| 自然语言处理应用 | [nlp_application.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/nlp_application.ipynb) | 应用实践 | - 展示MindSpore在自然语言处理的应用
      - 展示自然语言处理中数据集特定的预处理方法
      - 展示如何定义基于LSTM的SentimentNet网络 -| 计算机视觉应用 | [computer_vision_application.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/computer_vision_application.ipynb) | 应用实践 | - 学习MindSpore卷积神经网络在计算机视觉应用的过程
      - 学习下载CIFAR-10数据集,搭建运行环境
      - 学习使用ResNet-50构建卷积神经网络
      - 学习使用Momentum和SoftmaxCrossEntropyWithLogits构建优化器和损失函数
      - 学习调试参数训练模型,判断模型精度 -| 模型的训练及验证同步方法 | [synchronization_training_and_evaluation.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/synchronization_training_and_evaluation.ipynb) | 应用实践 | - 了解模型训练和验证同步进行的方法
      - 学习同步训练和验证中参数设置方法
      - 利用绘图函数从保存的模型中挑选出最优模型 -| 优化数据准备的性能 | [optimize_the_performance_of_data_preparation.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb) | 应用实践 | - 数据加载性能优化
      - shuffle性能优化
      - 数据增强性能优化
      - 性能优化方案总结 -| 使用PyNative进行神经网络的训练调试体验 | [debugging_in_pynative_mode.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/debugging_in_pynative_mode.ipynb) | 模型调优 | - GPU平台下从数据集获取单个数据进行单个step训练的数据变化全过程解读
      - 了解PyNative模式下的调试方法
      - 图片数据在训练过程中的变化情况的图形展示
      - 了解构建权重梯度计算函数的方法
      - 展示1个step过程中权重的变化及数据展示 -| 自定义调试信息体验文档 | [customized_debugging_information.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/customized_debugging_information.ipynb) | 模型调优 | - 了解MindSpore的自定义调试算子
      - 学习使用自定义调试算子Callback设置定时训练
      - 学习设置metrics算子输出相对应的模型精度信息
      - 学习设置日志环境变量来控制glog输出日志 -| MindInsight的模型溯源和数据溯源体验 | [mindinsight_model_lineage_and_data_lineage.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb) | 模型调优 | - 了解MindSpore中训练数据的采集及展示
      - 学习使用SummaryRecord记录数据
      - 学习使用回调函数SummaryCollector进行数据采集
      - 使用MindInsight进行数据可视化
      - 了解数据溯源和模型溯源的使用方法 -| 计算图和数据图可视化 | [calculate_and_datagraphic.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb) | 模型调优 | - 了解MindSpore中新增可视化功能
      - 学习使用MindInsight可视化看板
      - 学习使用查看计算图可视化图的信息的方法
      - 学习使用查看数据图中展示的信息的方法 -| 标量、直方图、图像和张量可视化 | [mindinsight_image_histogram_scalar_tensor.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb) | 模型调优 | - 了解完整的MindSpore深度学习及MindInsight可视化展示的过程
      - 学习使用MindInsight对训练过程中标量、直方图、图像和张量信息进行可视化展示
      - 学习使用Summary算子记录标量、直方图、图像和张量信息
      - 学习单独对标量、直方图、图像和张量信息进行记录并可视化展示的方法 -| 混合精度 | [mixed_precision.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/mixed_precision.ipynb) | 性能优化 | - 了解混合精度训练的原理
      - 学习在MindSpore中使用混合精度训练
      - 对比单精度训练和混合精度训练的对模型训练的影响 -| 模型安全 | [model_security.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/model_security.ipynb) | AI安全和隐私 | - 了解AI算法的安全威胁的概念和影响
      - 介绍MindArmour提供的模型安全防护手段
      - 学习如何模拟攻击训练模型
      - 学习针对被攻击模型进行对抗性防御 +| 手写数字分类识别入门体验教程 | [quick_start.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/quick_start.ipynb) | 快速入门 | - CPU平台下从数据集到模型验证的全过程解读
      - 体验教程中各功能模块的使用说明
      - 数据集图形化展示
      - 了解LeNet5具体结构和参数作用
      - 学习使用自定义回调函数
      - loss值与训练步数的变化图
      - 模型精度与训练步数的变化图
      - 使用模型应用到手写图片的预测与分类上 +| 线性拟合 | [linear_regression.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/linear_regression.ipynb) | 快速入门 | - 了解线性拟合的算法原理
      - 了解在MindSpore中如何实现线性拟合的算法原理
      - 学习使用MindSpore实现AI训练中的正向传播和方向传播
      - 可视化线性函数拟合数据的全过程。 +| 加载数据集 | [loading_dataset.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/loading_dataset.ipynb) | 使用指南 | - 学习MindSpore中加载数据集的方法
      - 展示加载常用数据集的方法
      - 展示加载MindRecord格式数据集的方法
      - 展示加载自定义格式数据集的方法 +| 将数据集转换为MindSpore数据格式 | [convert_dataset_to_mindspore_data_format.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb) | 使用指南 | - 展示将MNIST数据集转换为MindSpore数据格式
      - 展示将CSV数据集转换为MindSpore数据格式
      - 展示将CIFAR-10数据集转换为MindSpore数据格式
      - 展示将CIFAR-100数据集转换为MindSpore数据格式
      - 展示将ImageNet数据集转换为MindSpore数据格式
      - 展示用户自定义生成MindSpore数据格式 +| 数据处理与数据增强 | [data_loading_enhancement.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb) | 使用指南 | - 学习MindSpore中数据处理和增强的方法
      - 展示数据处理、增强方法的实际操作
      - 对比展示数据处理前和处理后的效果
      - 表述在数据处理、增强后的意义 +| 自然语言处理应用 | [nlp_application.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/nlp_application.ipynb) | 应用实践 | - 展示MindSpore在自然语言处理的应用
      - 展示自然语言处理中数据集特定的预处理方法
      - 展示如何定义基于LSTM的SentimentNet网络 +| 计算机视觉应用 | [computer_vision_application.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/computer_vision_application.ipynb) | 应用实践 | - 学习MindSpore卷积神经网络在计算机视觉应用的过程
      - 学习下载CIFAR-10数据集,搭建运行环境
      - 学习使用ResNet-50构建卷积神经网络
      - 学习使用Momentum和SoftmaxCrossEntropyWithLogits构建优化器和损失函数
      - 学习调试参数训练模型,判断模型精度 +| 模型的训练及验证同步方法 | [synchronization_training_and_evaluation.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/synchronization_training_and_evaluation.ipynb) | 应用实践 | - 了解模型训练和验证同步进行的方法
      - 学习同步训练和验证中参数设置方法
      - 利用绘图函数从保存的模型中挑选出最优模型 +| 优化数据准备的性能 | [optimize_the_performance_of_data_preparation.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb) | 应用实践 | - 数据加载性能优化
      - shuffle性能优化
      - 数据增强性能优化
      - 性能优化方案总结 +| 使用PyNative进行神经网络的训练调试体验 | [debugging_in_pynative_mode.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/debugging_in_pynative_mode.ipynb) | 模型调优 | - GPU平台下从数据集获取单个数据进行单个step训练的数据变化全过程解读
      - 了解PyNative模式下的调试方法
      - 图片数据在训练过程中的变化情况的图形展示
      - 了解构建权重梯度计算函数的方法
      - 展示1个step过程中权重的变化及数据展示 +| 自定义调试信息体验文档 | [customized_debugging_information.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/customized_debugging_information.ipynb) | 模型调优 | - 了解MindSpore的自定义调试算子
      - 学习使用自定义调试算子Callback设置定时训练
      - 学习设置metrics算子输出相对应的模型精度信息
      - 学习设置日志环境变量来控制glog输出日志 +| MindInsight的模型溯源和数据溯源体验 | [mindinsight_model_lineage_and_data_lineage.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb) | 模型调优 | - 了解MindSpore中训练数据的采集及展示
      - 学习使用SummaryRecord记录数据
      - 学习使用回调函数SummaryCollector进行数据采集
      - 使用MindInsight进行数据可视化
      - 了解数据溯源和模型溯源的使用方法 +| 计算图和数据图可视化 | [calculate_and_datagraphic.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb) | 模型调优 | - 了解MindSpore中新增可视化功能
      - 学习使用MindInsight可视化看板
      - 学习使用查看计算图可视化图的信息的方法
      - 学习使用查看数据图中展示的信息的方法 +| 标量、直方图、图像和张量可视化 | [mindinsight_image_histogram_scalar_tensor.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb) | 模型调优 | - 了解完整的MindSpore深度学习及MindInsight可视化展示的过程
      - 学习使用MindInsight对训练过程中标量、直方图、图像和张量信息进行可视化展示
      - 学习使用Summary算子记录标量、直方图、图像和张量信息
      - 学习单独对标量、直方图、图像和张量信息进行记录并可视化展示的方法 +| 混合精度 | [mixed_precision.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/mixed_precision.ipynb) | 性能优化 | - 了解混合精度训练的原理
      - 学习在MindSpore中使用混合精度训练
      - 对比单精度训练和混合精度训练的对模型训练的影响 +| 模型安全 | [model_security.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/model_security.ipynb) | AI安全和隐私 | - 了解AI算法的安全威胁的概念和影响
      - 介绍MindArmour提供的模型安全防护手段
      - 学习如何模拟攻击训练模型
      - 学习针对被攻击模型进行对抗性防御 diff --git a/tutorials/notebook/computer_vision_application.ipynb b/tutorials/notebook/computer_vision_application.ipynb index 2b2f978b16..ddf652cb21 100644 --- a/tutorials/notebook/computer_vision_application.ipynb +++ b/tutorials/notebook/computer_vision_application.ipynb @@ -71,7 +71,7 @@ "metadata": {}, "source": [ "本次面向Ascend 910 AI处理器硬件平台,将卷积神经网络ResNet加入到案例中,你可以在这里下载完整的样例代码案例作为基础用例:\n", - "https://gitee.com/mindspore/docs/tree/master/tutorials/tutorial_code/resnet" + "https://gitee.com/mindspore/docs/tree/r1.0/tutorials/tutorial_code/resnet" ] }, { diff --git a/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb b/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb index 0fea6b2a76..e95583048e 100644 --- a/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb +++ b/tutorials/notebook/convert_dataset_to_mindspore_data_format/convert_dataset_to_mindspore_data_format.ipynb @@ -280,7 +280,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "- 本例中需要的数据位置在https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/convert_dataset_to_mindspore_data_format/csv_data/data.csv\n", + "- 本例中需要的数据位置在https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/convert_dataset_to_mindspore_data_format/csv_data/data.csv\n", "中,使用过程中可以在此路径下找到文件并下载,并且保存在`jupyter工作目录/dataset/`下,如图所示:" ] }, @@ -837,7 +837,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "3. 准备需要写入的数据,按照用户定义的Schema形式,准备需要写入的样本列表,本例中需要的数据位置在https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/convert_dataset_to_mindspore_data_format/images/transform.jpg\n", + "3. 准备需要写入的数据,按照用户定义的Schema形式,准备需要写入的样本列表,本例中需要的数据位置在https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/convert_dataset_to_mindspore_data_format/images/transform.jpg\n", "中,使用过程中可以在此路径下找到图片并下载,并且保存在`jupyter工作目录/dataset/`下。" ] }, diff --git a/tutorials/notebook/customized_debugging_information.ipynb b/tutorials/notebook/customized_debugging_information.ipynb index b05388f1b4..ff1da4a809 100644 --- a/tutorials/notebook/customized_debugging_information.ipynb +++ b/tutorials/notebook/customized_debugging_information.ipynb @@ -18,7 +18,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "本文将使用[快速入门](https://gitee.com/mindspore/docs/blob/master/tutorials/tutorial_code/lenet.py)作为样例,并通过构建自定义调试函数:`Callback`、`metrics`、`Print算子`、日志打印等,同时将构建的自定义调试函数添加进代码中,通过运行效果来展示具体如何使用MindSpore提供给我们的自定义调试能力,帮助快速调试训练网络。\n", + "本文将使用[快速入门](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/tutorial_code/lenet.py)作为样例,并通过构建自定义调试函数:`Callback`、`metrics`、`Print算子`、日志打印等,同时将构建的自定义调试函数添加进代码中,通过运行效果来展示具体如何使用MindSpore提供给我们的自定义调试能力,帮助快速调试训练网络。\n", "体验过程如下:\n", "1. 数据集准备。\n", "2. 定义深度学习网络LeNet5。\n", @@ -46,7 +46,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "这里我们需要将MNIST数据集中随机取出一张图片,并增强成适合LeNet网络的数据格式(如何处理请参考[quick_start.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/quick_start.ipynb)),训练数据集下载地址:{\"\", \"\"}。\n", + "这里我们需要将MNIST数据集中随机取出一张图片,并增强成适合LeNet网络的数据格式(如何处理请参考[quick_start.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/quick_start.ipynb)),训练数据集下载地址:{\"\", \"\"}。\n", "
      数据集放在----`Jupyter工作目录+\\MNIST_Data\\train\\`,如下图结构:" ] }, @@ -303,7 +303,7 @@ "\n", "`GLOG_logtostderr`:控制日志输出方式,设置为`1`时,日志输出到屏幕;值设置为`0`时,日志输出到文件。设置输出屏幕时,日志部分的信息会显示成红色,设置成输出到文件时,会在`GLOG_log_dir`路径下生成`mindspore.log`文件。\n", "\n", - "> 更多设置请参考官网:" + "> 更多设置请参考官网:" ] }, { -- Gitee From a9f1be79cee53bc7fed4c523dc88f444d56533a1 Mon Sep 17 00:00:00 2001 From: bingyaweng Date: Fri, 18 Sep 2020 10:33:52 +0800 Subject: [PATCH 081/100] add tutorial and programming_guide of mdp --- .../source_zh_cn/probability.md | 2373 +++++++---------- .../apply_deep_probability_programming.md | 1048 +++++--- 2 files changed, 1567 insertions(+), 1854 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/probability.md b/docs/programming_guide/source_zh_cn/probability.md index d47554f8ca..5cfb3c79d4 100644 --- a/docs/programming_guide/source_zh_cn/probability.md +++ b/docs/programming_guide/source_zh_cn/probability.md @@ -1,1419 +1,954 @@ -# 深度概率编程库编程指南 - - - -- [深度概率编程库编程指南](#深度概率编程库编程指南) - - [概率分布: mindspore.nn.probability.distribution](#概率分布-mindsporennprobabilitydistribution) - - [概率分布类](#概率分布类) - - [Distribution基类](#distribution基类) - - [伯努利分布Bernoulli](#伯努利分布bernoulli) - - [指数分布Exponential](#指数分布exponential) - - [几何分布Geometric](#几何分布geometric) - - [正态分布Normal](#正态分布normal) - - [均匀分布Uniform](#均匀分布uniform) - - [概率分布类在PyNative模式下的应用](#概率分布类在pynative模式下的应用) - - [概率分布类在图模式下的应用](#概率分布类在图模式下的应用) - - [概率分布映射: mindspore.nn.probability.bijector](#概率分布映射-mindsporennprobabilitybijector) - - [Bijector类接口设计](#bijector类接口设计) - - [Bijector基类](#bijector基类) - - [幂函数变换映射PowerTransform](#幂函数变换映射powertransform) - - [指数变换映射Exp](#指数变换映射exp) - - [标量仿射变换映射ScalarAffine](#标量仿射变换映射scalaraffine) - - [Softplus变换映射Softplus](#softplus变换映射softplus) - - [PyNative模式下调用Bijector实例](#pynative模式下调用bijector实例) - - [图模式下调用Bijector实例](#图模式下调用bijector实例) - - [TransformedDistribution类接口设计](#transformeddistribution类接口设计) - - [PyNative模式下调用TransformedDistribution实例](#pynative模式下调用transformeddistribution实例) - - [图模式下调用TransformedDistribution实例](#图模式下调用transformeddistribution实例) - - [深度概率网络:mindspore.nn.probability.dpn](#深度概率网络mindsporennprobabilitydpn) - - [VAE](#vae) - - [ConditionalVAE](#conditionalvae) - - [概率推断算法:mindspore.nn.probability.infer](#概率推断算法mindsporennprobabilityinfer) - - [贝叶斯层:mindspore.nn.probability.bnn_layers](#贝叶斯层mindsporennprobabilitybnn_layers) - - [定义模型](#定义模型) - - [训练模型](#训练模型) - - [贝叶斯转换:mindspore.nn.probability.transform](#贝叶斯转换mindsporennprobabilitytransform) - - [定义DNN模型](#定义dnn模型) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [实例化TransformToBNN](#实例化transformtobnn) - - [功能一:转换整个模型](#功能一转换整个模型) - - [功能二:转换指定类型的层](#功能二转换指定类型的层) - - [贝叶斯工具箱:mindspore.nn.probability.toolbox](#贝叶斯工具箱mindsporennprobabilitytoolbox) - - - - - -## 概率分布: mindspore.nn.probability.distribution - -概率分布是概率编程的基础。**Distribution** 类提供多样的概率统计接口, 例如概率密度函数 *pdf* 、累积密度函数*cdf* ,散度计算 *kl_loss* ,抽样 *sample* 等。现有的概率分布实例包括高斯分布,伯努利分布,指数型分布,几何分布和均匀分布。 - -### 概率分布类 - -- `Distribution`: 所有概率分布的基类。 - -- `Bernoulli`: 伯努利分布。参数为试验成功的概率。 - -- `Exponential`: 指数型分布。参数为率参数。 - -- `Geometric`: 几何分布。参数为一次伯努利试验成功的概率。 - -- `Normal`: 正态(高斯)分布。参数为均值和标准差。 - -- `Uniform`: 均匀分布。参数为数轴上的最小值和最大值。 - -#### Distribution基类 - -`Distribution` 继承`Cell`,是所有概率分布的基类。构造函数参数包括: - -- `seed`: 随机抽样种子。 -- `dtype`: 分布的数据类型。 -- `name`: 分布的名称。 -- `param`: 分布初始化时所用参数。 - -接口介绍:`Distribution`类支持的函数包括 `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`, `mean`, `sd`, `var`, `entropy`, `kl_loss`, `cross_entropy`,和 `sample`。分布不同,所需传入的参数也不同。只有在派生类中才能使用,由派生类的函数实现决定参数。 - -- `prob` : 概率密度函数(pdf)/ 概率质量函数(pmf) -- `log_prob` :对数似然函数。 -- `cdf` : 累积分布函数(cdf)。 -- `log_cdf` : 对数累积分布函数(cdf)。 -- `survival_function` : 生存函数。 -- `log_survival` : 对数生存函数。 -- `mean` : 均值。 -- `sd` : 标准差。 -- `var` : 方差。 -- `entropy` : 熵。 -- `kl_loss` : Kullback-Leibler散度。 -- `cross_entropy` : 两个概率分布的交叉熵。 -- `sample` : 概率分布的随机抽样。 - -#### 伯努利分布Bernoulli -伯努利分布,继承自 `Distribution` 类。构造函数参数如下: -- `probs`: 伯努利试验成功的概率。 -- `seed`: 随机种子。 -- `dtype`: 分布类型。 -- `name`: 分布名称。 - -Property: -- `Bernoulli.probs`: 伯努利试验成功的概率。 - -`Distribution` 基类调用 `Bernoulli` 中私有接口以实现基类中的公有接口。`Bernoulli` 支持的公有接口为 - -- `mean`, `mode`, `var`: 可选择传入 *probs1* 指定试验成功的概率。 -- `entropy`:可选择传入 *probs1* 指定试验成功的概率. -- `cross_entropy`, `kl_loss`:必须传入 *dist* 和 *probs1_b* 。*dist*: 另一分布类型的名称,目前只支持此处为 *‘Bernoulli’* , *probs1_b* 指定分布 *b* 的试验成功概率。可选择传入 *probs1_a* 分布 *a* 的参数。 -- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value* 。 可选择传入 *probs* 指定试验成功的概率。 -- `sample`: 可选择传入 *shape* 样本形状和 *probs1* 指定试验成功的概率。 - -#### 指数分布Exponential -指数分布,继承自`Distribution`类。其构造函数参数如下: -- `rate`: 分布的率参数。 -- `seed`: 随机种子。 -- `dtype`: 分布类型。 -- `name`: 分布名称。 - -Property: -- `Exponential.rate`: 率参数。 - -`Distribution` 基类调用 `Exponential` 私有接口以实现基类中的公有接口。`Exponential` 支持的公有接口为 - -- `mean`, `mode`, `var`: 可选择传入 *rate* 指定率参数 -- `entropy`:可选择传入 *rate* 指定率参数 -- `cross_entropy`, `kl_loss`:。必须传入 *dist* 和 *rate_b*. *dist*: 另一分布类型的名称, 目前只支持此处为 *‘Exponential’* ,*rate_b* 指定分布 *b* 的率参数。可选择传入 *rate_a* 分布 *a* 的参数. -- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value*,可选择传入 *rate* 指定率参数。 -- `sample`: 可选择传入 *shape* 样本形状,以及 *rate* 指定率参数。 - -#### 几何分布Geometric -几何分布,继承自`Distribution`类。其构造函数参数如下: -- `probs`: 伯努利试验成功的概率。 -- `seed`: 随机种子。 -- `dtype`: 分布类型。 -- `name`: 分布名称。 - -Property: -- `Geometric.probs`: 伯努利试验成功的概率。 - -`Distribution` 基类调用 `Geometric` 中私有接口以实现基类中的公有接口。`Geometric` 支持的公有接口为 - -- `mean`, `mode`, `var`: 可选择传入 *probs1* 指定试验成功的概率。 -- `entropy`:可选择传入 *probs1* 指定试验成功的概率. -- `cross_entropy`, `kl_loss`:必须传入 *dist* 和 *probs1_b* 。*dist*: 另一分布类型的名称,目前只支持此处为 *‘Geometric’* , *probs1_b* 指定分布 *b* 的试验成功概率。可选择传入 *probs1_a* 分布 *a* 的参数。 -- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value*。 可选择传入 *probs1* 指定试验成功的概率。 -- `sample`: 可选择传入 *shape* 样本形状和 *probs1* 指定试验成功的概率。 - -#### 正态分布Normal -正态(高斯)分布,继承自 **Distribution** 类。其构造函数参数如下: -- `mean`: 分布均值。 -- `sd`: 分布方差。 -- `seed`: 随机种子。 -- `dtype`: 分布类型。 -- `name`: 分布名称。 - -**Distribution** 基类调用 **Normal** 中私有接口以实现基类中的公有接口。**Normal** 支持的公有接口为 -- `mean`, `mode`, `var`: 可选择传入 *mean* 和 *sd* 指定分布的参数。 -- `entropy`:可选择传入 *mean* 和 *sd* 指定分布的参数。 -- `cross_entropy`, `kl_loss`:必须传入 *dist* ,*mean_b* 和 *sd_b*。*dist*: 另一分布类型的名称,目前只支持此处为 *‘Normal’* ,*mean_b* 和 *sd_b* 指定分布b的参数。可选择传入 *mean_a* 和 *sd_a* 指定分布的参数。 -- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value*。可选择传入 *mean* 和 *sd* 指定分布的参数。 -- `sample`: 可选择传入 *shape* 样本形状。可选择传入 *mean_a* 和 *sd_a* 指定分布的参数。 - -#### 均匀分布Uniform -均匀分布,继承自`Distribution`类。其构造函数参数如下: -- `low`: 最小值。 -- `high`: 最大值。 -- `seed`: 随机种子。 -- `dtype`: 分布类型。 -- `name`: 分布名称。 - -Property: -- `Uniform.low`: 最小值。 -- `Uniform.high`: 最大值。 - -`Distribution` 基类调用 `Uniform` 以实现基类中的公有接口。`Uniform` 支持的公有接口为 - -- `mean`, `mode`, `var`: 可选择传入 *high* 和 *low* 指定分布的参数。 -- `entropy`:可选择传入 *high* 和 *low* 指定分布的参数。 -- `cross_entropy`, `kl_loss`:必须传入 *dist* ,*high_b* 和 *low_b* 。*dist* : 另一分布类型的名称,目前只支持此处为 *‘Uniform’* ,*high_b* 和 *low_b* 指定分布 *b* 的参数。可选择传入 *high_a* 和 *low_a* 指定分布的参数。 -- `prob`, `log_prob`, `cdf`, `log_cdf`, `survival_function`, `log_survival`: 必须传入 *value* 。可选择传入 *high* 和 *low* 指定分布的参数。 -- `sample`: 可选择传入 *shape* 。 可选择传入 *high* 和 *low* 指定分布的参数。 - -### 概率分布类在PyNative模式下的应用 - -`Distribution`子类可在 **PyNative** 模式下使用。 -导入相关模块: - -```python -from mindspore import Tensor -from mindspore import dtype as mstype -import mindspore.context as context -import mindspore.nn.probability.distribution as msd -context.set_context(mode=context.PYNATIVE_MODE) -``` -以 **Normal** 为例, 创建一个均值为0.0 标准差为1.0 的正态分布: -```python -my_normal = msd.Normal(0.0, 1.0, dtype=mstype.float32) -``` -计算均值: -```python -mean = my_normal.mean() -print(mean) -``` -输出为: -``` -0.0 -``` -计算方差: -```python -var = my_normal.var() -print(var) -``` -输出为: -``` -1.0 -``` -计算熵: -```python -entropy = my_normal.entropy() -print(entropy) -``` -``` -1.4189385 -``` -计算 **pdf**: -```python -value = Tensor([-0.5, 0.0, 0.5], dtype=mstype.float32) -prob = my_normal.prob(value) -print(prob) -``` -输出为: -``` -[0.35206532, 0.3989423, 0.35206532] -``` -计算 **cdf**: -```python -cdf = my_normal.cdf(value) -print(cdf) -``` -输出为: -``` -[0.30852754, 0.5, 0.69146246] -``` -计算 **kl_loss**: -```python -mean_b = Tensor(1.0, dtype=mstype.float32) -sd_b = Tensor(2.0, dtype=mstype.float32) -kl = my_normal.kl_loss('Normal', mean_b, sd_b) -print(kl) -``` -输出为: -``` -0.44314718 -``` - -### 概率分布类在图模式下的应用 - -在图模式下,**Distribution**子类可用在网络中。 -导入相关模块: -```python -import mindspore.nn as nn -from mindspore import Tensor -from mindspore import dtype as mstype -import mindspore.context as context -import mindspore.nn.probability.distribution as msd -context.set_context(mode=context.GRAPH_MODE) -``` -创建网络: -```python -# 网络继承nn.Cell -class Net(nn.Cell): - def __init__(self): - super(Net, self).__init__() - # 创建 Normal 实例 - self.normal = msd.Normal(0.0, 1.0, dtype=mstype.float32) - - #定义计算 - def construct(self, value, mean, sd): - pdf = self.normal.prob(value) - kl = self.normal.kl_loss("Normal", mean, sd) - return pdf, kl -``` -调用网络 -```python -net = Net() -value = Tensor([-0.5, 0.0, 0.5], dtype=mstype.float32) -mean = Tensor(1.0, dtype=mstype.float32) -sd = Tensor(1.0, dtype=mstype.float32) -pdf, kl = net(value, mean, sd) -print("pdf: ", pdf) -print("kl: ", kl) -``` -输出为: -``` -pdf: [0.3520653, 0.39894226, 0.3520653] -kl: 0.5 -``` - -## 概率分布映射: mindspore.nn.probability.bijector - -Bijector是概率编程的基本组成部分。Bijector描述了一种随机变量的变换方法,可以通过一个已有的随机变量X和一个映射函数f生成一个新的随机变量Y = f(x)。 -`Bijector`提供了映射相关的四种变换方法。它可以当做算子直接使用,也可以作用在某个随机变量`Distribution`类实例上生成新的随机变量的`Distribution`类实例。 - -### Bijector类接口设计 - -#### Bijector基类 - -`Bijector`类是所有Bejictor的基类,继承自`Cell`基类。 - -* 基类构造函数__init__ - - 输入参数: - `is_constant_jacobian`:映射函数的导数是否常数,只在创建衍生类的时候使用,默认false。 - `is_injective`:射函数是否是单设,只在创建衍生类的时候使用,默认true。 - `name`:Bijector的名字,创建派生类后由派生类的具体函数名决定,只在创建衍生类的时候使用,可以接受输入为str。默认None。 - `dtype`:Bijector对应的函数的类型(自变量和因变量的数据类型),创建派生类后由由派生类的具体函数决定,只在创建衍生类的时候使用,默认为None。 - `param`:Bijector内部的参数,创建派生类后由由派生类的具体函数参数决定,只在创建衍生类的时候使用,默认为None。 - -* 类特征函数property -`name`:无参函数,返回`name`的值。 -`is_dtype`:无参函数,返回`dtype`的值。 -`parameter`:无参函数,返回`parameter`的值。 -`is_constant_jacobian`:无参函数,返回`is_constant_jacobian`的值。 -`is_injective`:无参函数,返回`is_injective`的值。 - -* 映射函数 -`forward (args)`:正向映射,创建派生类后由派生类的`_forward`决定参数。 -`inverse (args)`:反向映射,创建派生类后由派生类的`_inverse`决定参数。 -`forward_log_jacobian (args)`:正向映射的(log)导数,创建派生类后由派生类的`_forward_log_jacobian`决定参数。 -`inverse_log_jacobian (args)`:反向映射的(log)导数,创建派生类后由派生类的`_inverse_log_jacobian`决定参数。 - -* `Bijector` 作为函数调用: -输入是一个`Distribution`类:生成一个`TransformedDistribution`**(不可在图内调用)** -其他输入:内部使用,不对外开放。 - -#### 幂函数变换映射PowerTransform -`PowerTransform`做如下变量替换:Y = g(X) = (1 + X * c)^(1 / c)。 - -* `PowerTransform`构造函数`__init__` -输入参数: -`power`:`PowerTransform`双射类对象的指数,可以接受输入为scalar(int or float), 默认0。 -`name`:`PowerTransform`双射类对象的名字,可以接受输入为str。默认为“PowerTransform”。 -`param`:`PowerTransform`内部的参数,创建派生类后由由派生类(exp)的具体函数参数决定,只在创建衍生类的时候使用。默认为None。 - -* 类特征函数property -`power`:无参函数,返回power的值。 - -* 映射函数 -`forward (args)`:正向映射,输入为tensor。 -`inverse (args)`:反向映射,输入为tensor。 -`forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。 -`inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。 - -#### 指数变换映射Exp -`Exp`做如下变量替换:Y = g(X)= exp(X)。 - -* `Exp`构造函数`__init__` -输入参数: -`name`:Exp双射类对象的名字,可以接受输入为str。默认为“Exp”。 - -* 映射函数 -`forward (args)`:正向映射,输入为tensor。继承自父类`PowerTransform`双射。 -`inverse (args)`:反向映射,输入为tensor。继承自父类`PowerTransform`双射。 -`forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。继承自父类`PowerTransform`双射。 -`inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。继承自父类`PowerTransform`双射。 - -#### 标量仿射变换映射ScalarAffine -`ScalarAffine`做如下变量替换:Y = g(X) = a * X + b。 - -* `ScalarAffine`构造函数`__init__` -输入参数: -`scale`:ScalarAffine的斜率,可以接受输入为float, 默认1.0。 -`shift`:ScalarAffine的截距,可以接受输入为float, 默认0.0。 -`name`:ScalarAffine的名字,可以接受输入为str。默认“ScalarAffine”。 - -* 类特征函数property -`scale`:无参函数,返回scale的值。 -`shift`:无参函数,返回shift的值。 - -* 映射函数 -`forward (args)`:正向映射,输入为tensor。 -`inverse (args)`:反向映射,输入为tensor。 -`forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。 -`inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。 - -#### Softplus变换映射Softplus -`Softplus`做如下变量替换:Y = g(X) = \frac{\log(1 + e ^ {kX})}{k}。 - -* `Softplus`构造函数`__init__` -输入参数: -`sharpness`:Softplus的斜率,可以接受输入为float, 默认1.0。 -`name`:Softplus的名字,可以接受输入为str。默认“Softplus”。 -* 类特征函数property -`sharpness`:无参函数,返回sharpness的值。 -* 映射函数 - `forward (args)`:正向映射,输入为tensor。 - `inverse (args)`:反向映射,输入为tensor。 - `forward_log_jacobian (args)`:正向映射的(log)导数,输入为tensor。 - `inverse_log_jacobian (args)`:反向映射的(log)导数,输入为tensor。 - -### PyNative模式下调用Bijector实例 - -PyNative模式类似于命令行调用,可以即时输入函数及其参数,完成函数调用。PyNative模式为异步执行,仅在访问函数结果时函数会被调用。 - -在执行之前,我们需要导入需要的库文件包。双射类最主要的库是`mindspore.nn.probability.bijector`,导入后我们使用`msb`作为库的缩写并进行调用。 - -导入相关模块: -```python -import numpy as np -import mindspore.nn as nn -import mindspore.nn.probability.bijector as msb -import mindspore.context as context -from mindspore import Tensor -from mindspore import dtype -context.set_context(mode=context.PYNATIVE_MODE) -``` - -通常我们并不直接构造基类`Bijector`,而是直接构造派生的子类,并调用子类对应的函数接口。下面我们以`PowerTransform`为例。 - -创建一个`powertransform`对象,初始化参数中power=2。 - -构造`PowerTransform`: -```python -powertransform = msb.PowerTransform(power=2) -powertransform -``` - -输出: -```python -PowerTransform -``` - -接下来可以使用映射函数进行运算。 - -调用`forward`方法,计算正向映射: -```python -x = np.array([2.0, 3.0, 4.0, 5.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -forward = powertransform.forward(tx) -foward -``` - -输出: -```python -Tensor(shape=[4], dtype=Float32, [ 2.23606801e+00 2.64575124e+00 3.00000000e+00 3.31662488e+00]) -``` - -输入`inverse`方法,计算反向映射: -```python -inverse = powertransform.inverse(tx) -inverse -``` - -输出: -```python -Tensor(shape=[4], dtype=Float32, [ 1.50000000e+00 4.00000048e+00 7.50000000e+00 1.20000010e+01]) -``` - -输入`forward_log_jacobian`方法,计算正向映射导数: -```python -forward_log_jaco = powertransform.forward_log_jacobian(tx) -forward_log_jaco -``` - -输出: -```python -Tensor(shape=[4], dtype=Float32, [-8.04718971e-01 -9.72955048e-01 -1.09861231e+00 -1.19894767e+00]) -``` - -输入`inverse_log_jacobian`方法,计算正向映射导数: -```python -inverse_log_jaco = powertransform.inverse_log_jacobian(tx) -inverse_log_jaco -``` - -输出: -```python -Tensor(shape=[4], dtype=Float32, [ 6.93147182e-01 1.09861231e+00 1.38629436e+00 1.60943794e+00]) -``` - -### 图模式下调用Bijector实例 - -在图模式下,`Bijector`子类可用在网络中。 - -导入相关模块: -```python -import mindspore.nn as nn -from mindspore import Tensor -from mindspore import dtype as mstype -import mindspore.context as context -import mindspore.nn.probability.Bijector as msb -context.set_context(mode=context.GRAPH_MODE) -``` - -创建网络: -```python -# 网络继承nn.Cell -class Net(nn.Cell): - def __init__(self): - super(Net, self).__init__() - # 创建PowerTransform实例 - self.powertransform = msb.PowerTransform(power=2) - - #定义计算 - def construct(self, value): - forward = self.s1.forward(value) - inverse = self.s1.inverse(value) - forward_log_jaco = self.s1.forward_log_jacobian(value) - inverse_log_jaco = self.s1.inverse_log_jacobian(value) - return forward, inverse, forward_log_jaco, inverse_log_jaco -``` -调用网络 -```python -net = Net() -x = np.array([2.0, 3.0, 4.0, 5.0]).astype(np.float32) -tx = Tensor(x, dtype=dtype.float32) -forward, inverse, forward_log_jaco, inverse_log_jaco = net(tx) -print("forward: ", forward) -print("inverse: ", inverse) -print("forward_log_jaco: ", forward_log_jaco) -print("inverse_log_jaco: ", inverse_log_jaco) -``` -输出为: -```python -forward: [2.236068 2.6457512 3. 3.3166249] -inverse: [ 1.5 4.0000005 7.5 12.000001 ] -forward_log_jaco: [-0.804719 -0.97295505 -1.0986123 -1.1989477 ] -inverse_log_jaco: [0.6931472 1.0986123 1.3862944 1.609438 ] -``` - -### TransformedDistribution类接口设计 - -`TransformedDistribution`继承自`Distribution`,是可通过映射f(x)变化得到的数学分布的基类。 - -* 构造函数`__init__` - - 输入参数: - `bijector`:分布的变换方法。可以接受输入为bijector的派生类,作为映射变换函数f。 - `distribution`:原始分布。可以接受输入为distribution的派生类,作为映射需要变换的分布类*X*。 - `seed`: 随机种子。 - `dtype`: 分布类型。 - `name`:分布名称。可以接受输入为str。默认为“transformed_distribution”。 - -* 类特征函数property -`bijector`:无参函数,返回分布的变换方法。 -`distribution`:无参函数,返回原始分布。 -`is_linear_transformation`:无参函数,返回线性变换标志。 - -* 接口函数 -`cdf`:累积分布函数(cdf)。 -`log_cdf`:对数累积分布函数(cdf)。 -`survival_function`:生存函数。与 cdf 互补。 -`log_survival`:对数生存函数。 -`prob`:概率密度函数(pdf)/ 概率质量函数(pmf)。 -`log_prob`:对数似然函数。 -`sample`:随机取样。必须传入shape,类型tuple。 -`mean`:无参数。只有当`Bijector.is_constant_jacobian=true`时可调用。 - -### PyNative模式下调用TransformedDistribution实例 - -`TransformedDistribution` 子类可在 **PyNative** 模式下使用。 -在执行之前,我们需要导入需要的库文件包。 - -导入相关模块: -```python -import numpy as np -import mindspore.nn as nn -import mindspore.nn.probability.bijector as msb -import mindspore.nn.probability.distribution as msd -import mindspore.context as context -from mindspore import Tensor -from mindspore import dtype -context.set_context(mode=context.PYNATIVE_MODE) -``` - -构造一个`TransformedDistribution`实例,使用Normal分布作为需要变换的分布类,使用Exp作为映射变换,可以生成`LogNormal`分布。 -```python -normal = msd.Normal(0.0, 1.0, dtype=dtype.float32) -exp = msb.Exp() -LogNormal = msd.TransformedDistribution(exp, normal, dtype=dtype.float32, seed=0, name="LogNormal") -LogNormal -``` - -输出: -```python -TransformedDistribution< - (_bijector): Exp - (_distribution): Normal - > -``` - -可以对`LogNormal`进行概率分布计算。例如: - -计算 **cdf** : -```python -x = np.array([2.0, 5.0, 10.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -cdf = LogNormal.cdf(tx) -cdf -``` - -输出: -```python -Tensor(shape=[3], dtype=Float32, [ 7.55891383e-01 9.46239710e-01 9.89348888e-01]) -``` - -计算 **log_cdf** : -```python -x = np.array([2.0, 5.0, 10.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -log_cdf = LogNormal.log_cdf(tx) -log_cdf -``` - -输出: -```python -Tensor(shape=[3], dtype=Float32, [-2.79857576e-01 -5.52593507e-02 -1.07082408e-02]) -``` - -计算 **survival_function** : -```python -x = np.array([2.0, 5.0, 10.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -survival_function = LogNormal.survival_function(tx) -survival_function -``` - -输出: -```python -Tensor(shape=[3], dtype=Float32, [ 2.44108617e-01 5.37602901e-02 1.06511116e-02]) -``` - -计算 **log_survival** : -```python -x = np.array([2.0, 5.0, 10.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -log_survival = LogNormal.log_survival(tx) -log_survival -``` - -输出: -```python -Tensor(shape=[3], dtype=Float32, [-1.41014194e+00 -2.92322016e+00 -4.54209089e+00]) -``` - -计算 **prob** : -```python -x = np.array([2.0, 5.0, 10.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -prob = LogNormal.prob(tx) -prob -``` - -输出: -```python -Tensor(shape=[3], dtype=Float32, [ 1.56874031e-01 2.18507163e-02 2.81590177e-03]) -``` - -计算 **log_prob** : -```python -x = np.array([2.0, 5.0, 10.0], dtype=np.float32) -tx = Tensor(x, dtype=dtype.float32) -log_prob = LogNormal.log_prob(tx) -log_prob -``` - -输出: -```python -Tensor(shape=[3], dtype=Float32, [-1.85231221e+00 -3.82352161e+00 -5.87247276e+00]) -``` - -调用取样函数 **sample** : -```python -shape = ((3, 2)) -sample = LogNormal.sample(shape) -sample -``` - -输出: -```python -Tensor(shape=[3, 2], dtype=Float32, -[[ 7.64315844e-01 3.01435232e-01] - [ 1.17166102e+00 2.60277224e+00] - [ 7.02699006e-01 3.91564220e-01]]) -``` - -### 图模式下调用TransformedDistribution实例 - -在图模式下,**TransformedDistribution**子类可用在网络中。 - -导入相关模块: -```python -import mindspore.nn as nn -from mindspore import Tensor -from mindspore import dtype -import mindspore.context as context -import mindspore.nn.probability.Bijector as msb -import mindspore.nn.probability.Distribution as msd -context.set_context(mode=self.GRAPH_MODE) -``` - -创建网络: -```python -# 网络继承nn.Cell -class Net(nn.Cell): - def __init__(self, shape, dtype=dtype.float32, seed=0, name='transformed_distribution'): - super(Net, self).__init__() - # 创建TransformedDistribution实例 - self.exp = msb.Exp() - self.normal = msd.Normal(0.0, 1.0, dtype=dtype) - self.lognormal = msd.TransformedDistribution(self.exp, self.normal, dtype=dtype, seed=seed, name=name) - self.shape = shape - - #定义计算cdf,以及随机取样 - def construct(self, value): - cdf = self.lognormal.cdf(value) - sample = self.lognormal.sample(self.shape) - return cdf, sample -``` - -调用网络 -```python -shape = (2, 3) -net = Net(shape=shape, name="LogNormal") -x = np.array([2.0, 3.0, 4.0, 5.0]).astype(np.float32) -tx = Tensor(x, dtype=dtype.float32) -cdf, sample = net(tx) -print("cdf: ", cdf) -print("sample: ", sample) -``` -输出为: -```python -cdf: [0.7558914 0.8640314 0.9171715 0.9462397] -sample: [[0.21036398 0.44932044 0.5669641 ] - [1.4103683 6.724116 0.97894996]] -``` - -## 深度概率网络:mindspore.nn.probability.dpn - -使用MindSpore深度概率编程库来构造变分自编码器(VAE)进行推理尤为简单。我们只需要自定义编码器和解码器(DNN模型),调用VAE或CVAE接口形成其派生网络,然后调用ELBO接口进行优化,最后使用SVI接口进行变分推理。这样做的好处是,不熟悉变分推理的用户可以像构建DNN模型一样来构建概率模型,而熟悉的用户可以调用这些接口来构建更为复杂的概率模型。VAE的接口在`mindspore.nn.probability.dpn`下面,dpn代表的是Deep probabilistic network,这里提供了一些基本的深度概率网络的接口,例如VAE。 - -### VAE - -首先,我们需要先自定义encoder和decoder,调用`mindspore.nn.probability.dpn.VAE`接口来构建VAE网络,我们除了传入encoder和decoder之外,还需要传入encoder输出变量的维度hidden size,以及VAE网络存储潜在变量的维度latent size,一般latent size会小于hidden size。 - -```python -import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore.nn.probability.dpn import VAE - -IMAGE_SHAPE = (-1, 1, 32, 32) - - -class Encoder(nn.Cell): - def __init__(self): - super(Encoder, self).__init__() - self.fc1 = nn.Dense(1024, 800) - self.fc2 = nn.Dense(800, 400) - self.relu = nn.ReLU() - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - return x - - -class Decoder(nn.Cell): - def __init__(self): - super(Decoder, self).__init__() - self.fc1 = nn.Dense(400, 1024) - self.sigmoid = nn.Sigmoid() - self.reshape = P.Reshape() - - def construct(self, z): - z = self.fc1(z) - z = self.reshape(z, IMAGE_SHAPE) - z = self.sigmoid(z) - return z - - -encoder = Encoder() -decoder = Decoder() -vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) -``` -### ConditionalVAE - -类似地,ConditionalVAE与VAE的使用方法比较相近,不同的是,ConditionalVAE利用了数据集的标签信息,属于有监督学习算法,其生成效果一般会比VAE好。 - -首先,先自定义encoder和decoder,并调用`mindspore.nn.probability.dpn.ConditionalVAE`接口来构建ConditionalVAE网络,这里的encoder和VAE的不同,因为需要传入数据集的标签信息;decoder和上述的一样。ConditionalVAE接口的传入则还需要传入数据集的标签类别个数,其余和VAE接口一样。 - -``` -import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore.nn.probability.dpn import ConditionalVAE - -IMAGE_SHAPE = (-1, 1, 32, 32) - - -class Encoder(nn.Cell): - def __init__(self, num_classes): - super(Encoder, self).__init__() - self.fc1 = nn.Dense(1024 + num_classes, 400) - self.relu = nn.ReLU() - self.flatten = nn.Flatten() - self.concat = P.Concat(axis=1) - self.one_hot = nn.OneHot(depth=num_classes) - - def construct(self, x, y): - x = self.flatten(x) - y = self.one_hot(y) - input_x = self.concat((x, y)) - input_x = self.fc1(input_x) - input_x = self.relu(input_x) - return input_x - - -class Decoder(nn.Cell): - def __init__(self): - super(Decoder, self).__init__() - self.fc1 = nn.Dense(400, 1024) - self.sigmoid = nn.Sigmoid() - self.reshape = P.Reshape() - - def construct(self, z): - z = self.fc1(z) - z = self.reshape(z, IMAGE_SHAPE) - z = self.sigmoid(z) - return z - - -encoder = Encoder(num_classes=10) -decoder = Decoder() -cvae = ConditionalVAE(encoder, decoder, hidden_size=400, latent_size=20, num_classes=10) -``` - -加载数据集,我们可以使用Mnist数据集,具体的数据加载和预处理过程可以参考这里[Implementing an Image Classification Application](https://www.mindspore.cn/tutorial/en/master/quick_start/quick_start.html),这里会用到create_dataset函数创建数据迭代器。 - -```python -ds_train = create_dataset(image_path, 128, 1) -``` -接下来,需要用到infer接口进行VAE网络的变分推断。 - -## 概率推断算法:mindspore.nn.probability.infer - -调用ELBO接口(`mindspore.nn.probability.infer.ELBO`)来定义VAE网络的损失函数,调用`WithLossCell`封装VAE网络和损失函数,并定义优化器,之后传入SVI接口(`mindspore.nn.probability.infer.SVI`)。SVI的`run`函数可理解为VAE网络的训练,可以指定训练的`epochs`,返回结果为训练好的网络;`get_train_loss`函数可以返回训练好后模型的loss。 - -```python -from mindspore.nn.probability.infer import ELBO, SVI - -net_loss = ELBO(latent_prior='Normal', output_prior='Normal') -net_with_loss = nn.WithLossCell(vae, net_loss) -optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) - -vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) -vae = vi.run(train_dataset=ds_train, epochs=10) -trained_loss = vi.get_train_loss() -``` -最后,得到训练好的VAE网络后,我们可以使用`vae.generate_sample`生成新样本,需要传入待生成样本的个数,及生成样本的shape,shape需要保持和原数据集中的样本shape一样;当然,我们也可以使用`vae.reconstruct_sample`重构原来数据集中的样本,来测试VAE网络的重建能力。 -```python -generated_sample = vae.generate_sample(64, IMAGE_SHAPE) -for sample in ds_train.create_dict_iterator(): - sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) - reconstructed_sample = vae.reconstruct_sample(sample_x) -print('The shape of the generated sample is ', generated_sample.shape) -``` -我们可以看一下新生成样本的shape: -``` -The shape of the generated sample is (64, 1, 32, 32) -``` -ConditionalVAE训练过程和vae的过程类似,但需要注意的是使用训练好的ConditionalVAE网络生成新样本和重建新样本时,需要输入标签信息,例如下面生成的新样本就是64个0-7的数字。 - -``` -sample_label = Tensor([i for i in range(0, 8)] * 8, dtype=mstype.int32) -generated_sample = cvae.generate_sample(sample_label, 64, IMAGE_SHAPE) -for sample in ds_train.create_dict_iterator(): - sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) - sample_y = Tensor(sample['label'].asnumpy(), dtype=mstype.int32) - reconstructed_sample = cvae.reconstruct_sample(sample_x, sample_y) -print('The shape of the generated sample is ', generated_sample.shape) -``` -查看一下新生成的样本的shape: -``` -The shape of the generated sample is (64, 1, 32, 32) -``` - -如果希望新生成的样本更好,更清晰,用户可以自己定义更复杂的encoder和decoder,这里的示例只用了两层全连接层,仅供示例的指导。 - -## 贝叶斯层:mindspore.nn.probability.bnn_layers - -下面的范例使用MindSpore的`nn.probability.bnn_layers`中的API实现BNN图片分类模型。MindSpore的`nn.probability.bnn_layers`中的API包括`NormalPrior`,`NormalPosterior`,`ConvReparam`,`DenseReparam`和`WithBNNLossCell`。 - -- ### 处理数据 - -``` -import mindspore.dataset as ds -import mindspore.dataset.transforms.vision.c_transforms as CV -import mindspore.dataset.transforms.c_transforms as C -from mindspore.dataset.transforms.vision import Inter -from mindspore.common import dtype as mstype - - -def create_dataset(data_path, batch_size=32, repeat_size=1, - num_parallel_workers=1): - """ - create dataset for train or test - """ - # 定义数据集 - mnist_ds = ds.MnistDataset(data_path) - - resize_height, resize_width = 32, 32 - rescale = 1.0 / 255.0 - shift = 0.0 - rescale_nml = 1 / 0.3081 - shift_nml = -1 * 0.1307 / 0.3081 - - # 定义映射操作 - resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR) - rescale_nml_op = CV.Rescale(rescale_nml, shift_nml) - rescale_op = CV.Rescale(rescale, shift) - hwc2chw_op = CV.HWC2CHW() - type_cast_op = C.TypeCast(mstype.int32) - - # 对图像应用映射操作 - mnist_ds = mnist_ds.map(input_columns="label", operations=type_cast_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=resize_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers) - mnist_ds = mnist_ds.map(input_columns="image", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers) - - # 应用DatasetOps - buffer_size = 10000 - mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size) # 10000 as in LeNet train script - mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True) - mnist_ds = mnist_ds.repeat(repeat_size) - - return mnist_ds - -``` -### 定义模型 - -利用bnn_layers构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,bnn_layers和普通的神经网络层可以互相组合。当网络中包含bnn_layers时,需要将`WithLossCel`l替换为适用于BNN的`WithBNNLossCell`。除了`backbone`和`loss_fn`两个参数之外,`WithBNNLossCell`增加了`dnn_factor`和`bnn_factor`两个参数。`dnn_factor`是由损失函数计算得到的网络整体损失的系数,`bnn_factor`是每个贝叶斯层的KL散度的系数,这两个参数是用来平衡网络整体损失和贝叶斯层的KL散度的,防止KL散度的值过大掩盖了网络整体损失。 - -``` -import mindspore.nn as nn -from mindspore.nn.probability import bnn_layers -from mindspore.ops import operations as P - -class BNNLeNet5(nn.Cell): - def __init__(self, num_class=10): - super(BNNLeNet5, self).__init__() - self.num_class = num_class - self.conv1 = bnn_layers.ConvReparam(1, 6, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") - self.conv2 = bnn_layers.ConvReparam(6, 16, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") - self.fc1 = bnn_layers.DenseReparam(16 * 5 * 5, 120, activation=nn.ReLU()) - self.fc2 = bnn_layers.DenseReparam(120, 84) - self.fc3 = bnn_layers.DenseReparam(84, self.num_class) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x - -network = BNNLeNet5() -# 定义损失函数 -criterion = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") -# 定义优化器 -optimizer = nn.AdamWeightDecay(params=network.trainable_params(), learning_rate=0.001) -net_with_loss = bnn_layers.WithBNNLossCell(network, criterion, dnn_factor=60000, bnn_factor=0.00001) -train_bnn_network = TrainOneStepCell(net_with_loss, optimizer) -train_bnn_network.set_train() -``` -### 训练模型 - -``` -def train_model(train_net, net, dataset): - accs = [] - loss_sum = 0 - for i, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].asnumpy().astype(np.float32)) - label = Tensor(data['label'].asnumpy().astype(np.int32)) - loss = train_net(train_x, label) - output = net(train_x) - log_output = P.LogSoftmax(axis=1)(output) - acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) - accs.append(acc) - loss_sum += loss.asnumpy() - - loss_sum = loss_sum / len(accs) - acc_mean = np.mean(accs) - return loss_sum, acc_mean - - -def validate_model(net, dataset): - accs = [] - for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].asnumpy().astype(np.float32)) - label = Tensor(data['label'].asnumpy().astype(np.int32)) - output = net(train_x) - log_output = P.LogSoftmax(axis=1)(output) - acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) - accs.append(acc) - - acc_mean = np.mean(accs) - return acc_mean - -train_set = create_dataset('./mnist_data/train', 64, 1) -test_set = create_dataset('./mnist_data/test', 64, 1) - -epoch = 10 - -for i in range(epoch): - train_loss, train_acc = train_model(train_bnn_network, network, train_set) - - valid_acc = validate_model(network, test_set) - - print('Epoch: {} \tTraining Loss: {:.4f} \tTraining Accuracy: {:.4f} \tvalidation Accuracy: {:.4f}'.format( - i, train_loss, train_acc, valid_acc)) -``` - - -``` -Epoch 0 Training Loss 12925.5249 Training Accuracy 0.9413 validation Accuracy 0.9279 -Epoch 1 Training Loss 5287.0440 Training Accuracy 0.9771 validation Accuracy 0.9592 -Epoch 2 Training Loss 4186.9598 Training Accuracy 0.9821 validation Accuracy 0.9786 -Epoch 3 Training Loss 3538.2411 Training Accuracy 0.9857 validation Accuracy 0.9696 -Epoch 4 Training Loss 3255.8431 Training Accuracy 0.9869 validation Accuracy 0.9756 -Epoch 5 Training Loss 2880.1353 Training Accuracy 0.9880 validation Accuracy 0.9792 -Epoch 6 Training Loss 2569.0690 Training Accuracy 0.9897 validation Accuracy 0.9802 -Epoch 7 Training Loss 2391.5061 Training Accuracy 0.9906 validation Accuracy 0.9825 -Epoch 8 Training Loss 2165.1392 Training Accuracy 0.9912 validation Accuracy 0.9794 -Epoch 9 Training Loss 1910.2262 Training Accuracy 0.9931 validation Accuracy 0.9833 -``` - -## 贝叶斯转换:mindspore.nn.probability.transform - -对于不熟悉贝叶斯模型的DNN研究人员,MDP提供了高级API`TransformToBNN`,支持DNN模型一键转换成BNN模型。 - -### 定义DNN模型 - -本例使用的DNN模型是LeNet。 - -``` -from mindspore.common.initializer import TruncatedNormal -import mindspore.nn as nn -import mindspore.ops.operations as P - -def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): - """weight initial for conv layer""" - weight = weight_variable() - return nn.Conv2d(in_channels, out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, - weight_init=weight, has_bias=False, pad_mode="valid") - - -def fc_with_initialize(input_channels, out_channels): - """weight initial for fc layer""" - weight = weight_variable() - bias = weight_variable() - return nn.Dense(input_channels, out_channels, weight, bias) - - -def weight_variable(): - """weight initial""" - return TruncatedNormal(0.02) - - -class LeNet5(nn.Cell): - """ - Lenet network - - Args: - num_class (int): Num classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> LeNet5(num_class=10) - - """ - def __init__(self, num_class=10): - super(LeNet5, self).__init__() - self.num_class = num_class - self.conv1 = conv(1, 6, 5) - self.conv2 = conv(6, 16, 5) - self.fc1 = fc_with_initialize(16 * 5 * 5, 120) - self.fc2 = fc_with_initialize(120, 84) - self.fc3 = fc_with_initialize(84, self.num_class) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - self.reshape = P.Reshape() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` -LeNet网络结构如下: - -``` -LeNet5 - (conv1) Conv2dinput_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False - (conv2) Conv2dinput_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False - (fc1) Densein_channels=400, out_channels=120, weight=Parameter (name=fc1.weight), has_bias=True, bias=Parameter (name=fc1.bias) - (fc2) Densein_channels=120, out_channels=84, weight=Parameter (name=fc2.weight), has_bias=True, bias=Parameter (name=fc2.bias) - (fc3) Densein_channels=84, out_channels=10, weight=Parameter (name=fc3.weight), has_bias=True, bias=Parameter (name=fc3.bias) - (relu) ReLU - (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID - (flatten) Flatten - -``` - -### 定义损失函数和优化器 - -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,Adam作为优化器。 - -``` -network = LeNet5() - -# loss function definition -criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - -# optimization definition -optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) - -net_with_loss = WithLossCell(network, criterion) -train_network = TrainOneStepCell(net_with_loss, optimizer) -``` -### 实例化TransformToBNN - -`TransformToBNN`的`__init__`函数定义如下: - -``` -class TransformToBNN: - def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): - net_with_loss = trainable_dnn.network - self.optimizer = trainable_dnn.optimizer - self.backbone = net_with_loss.backbone_network - self.loss_fn = getattr(net_with_loss, "_loss_fn") - self.dnn_factor = dnn_factor - self.bnn_factor = bnn_factor - self.bnn_loss_file = None -``` -参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 -MindSpore中实例化`TransformToBNN`的代码如下: - -``` -from mindspore.nn.probability import transforms - -bnn_transformer = transforms.TransformToBNN(train_network, 60000, 0.000001) -``` -#### 功能一:转换整个模型 -`transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下 - -``` - def transform_to_bnn_model(self, - get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, - "out_channels": dp.out_channels, "activation": dp.activation}, - get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, - "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, - "stride": dp.stride, "has_bias": dp.has_bias, - "padding": dp.padding, "dilation": dp.dilation, - "group": dp.group}, - add_dense_args=None, - add_conv_args=None): - r""" - Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. - - Args: - get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: - {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. - get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: - {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, - "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. - add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. - add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. - - Returns: - Cell, a trainable BNN model wrapped by TrainOneStepCell. - """ - -``` -参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 -在MindSpore中将整个DNN模型转换成BNN模型的代码如下: - -``` -train_bnn_network = bnn_transformer.transform_to_bnn_model() -``` -整个模型转换后的结构如下: - -``` -LeNet5 - (conv1) ConvReparam - in_channels=1, out_channels=6, kernel_size=(5, 5), stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, weight_mean=Parameter (name=conv1.weight_posterior.mean), weight_std=Parameter (name=conv1.weight_posterior.untransformed_std), has_bias=False - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (conv2) ConvReparam - in_channels=6, out_channels=16, kernel_size=(5, 5), stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, weight_mean=Parameter (name=conv2.weight_posterior.mean), weight_std=Parameter (name=conv2.weight_posterior.untransformed_std), has_bias=False - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (fc1) DenseReparam - in_channels=400, out_channels=120, weight_mean=Parameter (name=fc1.weight_posterior.mean), weight_std=Parameter (name=fc1.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc1.bias_posterior.mean), bias_std=Parameter (name=fc1.bias_posterior.untransformed_std) - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - (bias_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (bias_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (fc2) DenseReparam - in_channels=120, out_channels=84, weight_mean=Parameter (name=fc2.weight_posterior.mean), weight_std=Parameter (name=fc2.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc2.bias_posterior.mean), bias_std=Parameter (name=fc2.bias_posterior.untransformed_std) - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - (bias_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (bias_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (fc3) DenseReparam - in_channels=84, out_channels=10, weight_mean=Parameter (name=fc3.weight_posterior.mean), weight_std=Parameter (name=fc3.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc3.bias_posterior.mean), bias_std=Parameter (name=fc3.bias_posterior.untransformed_std) - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - (bias_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (bias_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (relu) ReLU - (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID - (flatten) Flatten - -``` - -#### 功能二:转换指定类型的层 -`transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(`nn.Dense`或者`nn.Conv2d`)转换为对应的贝叶斯层。其定义如下 - -``` - def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): - r""" - Transform a specific type of layers in DNN model to corresponding BNN layer. - - Args: - dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are - nn.Dense, nn.Conv2d. - bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are - DenseReparameterization, ConvReparameterization. - get_args (dict): The arguments gotten from the DNN layer. Default: None. - add_args (dict): The new arguments added to BNN layer. Default: None. - - Returns: - Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. - """ -``` -参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 -在MindSpore中将DNN模型中的Dense层转换成相应贝叶斯层`DenseReparam`的代码如下: - -``` -train_bnn_network = bnn_transformer.transform_to_bnn_layer(nn.Dense, bnn_layers.DenseReparam) -``` -转换后的结构如下: - -``` -LeNet5 - (conv1) Conv2dinput_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False - (conv2) Conv2dinput_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False - (fc1) DenseReparam - in_channels=400, out_channels=120, weight_mean=Parameter (name=fc1.weight_posterior.mean), weight_std=Parameter (name=fc1.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc1.bias_posterior.mean), bias_std=Parameter (name=fc1.bias_posterior.untransformed_std) - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - (bias_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (bias_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (fc2) DenseReparam - in_channels=120, out_channels=84, weight_mean=Parameter (name=fc2.weight_posterior.mean), weight_std=Parameter (name=fc2.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc2.bias_posterior.mean), bias_std=Parameter (name=fc2.bias_posterior.untransformed_std) - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - (bias_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (bias_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (fc3) DenseReparam - in_channels=84, out_channels=10, weight_mean=Parameter (name=fc3.weight_posterior.mean), weight_std=Parameter (name=fc3.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc3.bias_posterior.mean), bias_std=Parameter (name=fc3.bias_posterior.untransformed_std) - (weight_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (weight_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - (bias_prior) NormalPrior - (normal) Normalmean = 0.0, standard deviation = 0.1 - - (bias_posterior) NormalPosterior - (normal) Normalbatch_shape = None - - - (relu) ReLU - (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID - (flatten) Flatten - -``` - -## 贝叶斯工具箱:mindspore.nn.probability.toolbox - -贝叶斯神经网络的优势之一就是可以获取不确定性,MDP在上层提供了不确定性估计的工具箱,用户可以很方便地使用该工具箱计算不确定性。不确定性意味着深度学习模型不知道什么。目前,大多数深度学习算法只能给出高置信度的预测结果,而不能判断预测结果的确定性,不确定性主要有两种类型:偶然不确定性和认知不确定性。 - -- 偶然不确定性(Aleatoric Uncertainty):描述数据中的内在噪声,即无法避免的误差,这个现象不能通过增加采样数据来削弱。 -- 认知不确定性(Epistemic Uncertainty):模型自身对输入数据的估计可能因为训练不佳、训练数据不够等原因而不准确,可以通过增加训练数据等方式来缓解。 - -不确定性评估工具箱的接口如下: -- `model`: 待评估不确定性的已训练好的模型。 -- `train_dataset`: 用于训练的数据集,迭代器类型。 -- `task_type`: 模型的类型,字符串,输入“regression”或者“classification”。 -- `num_classes`: 如果是分类模型,需要指定类别的标签数量。 -- `epochs`: 用于训练不确定模型的迭代数。 -- `epi_uncer_model_path`: 用于存储或加载计算认知不确定性的模型的路径。 -- `ale_uncer_model_path`: 用于存储或加载计算偶然不确定性的模型的路径。 -- `save_model`: 布尔类型,是否需要存储模型。 - -在使用前,需要先训练好模型,以LeNet5为例,使用方式如下: -``` -from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation -from mindspore.train.serialization import load_checkpoint, load_param_into_net - -if __name__ == '__main__': - # get trained model - network = LeNet5() - param_dict = load_checkpoint('checkpoint_lenet.ckpt') - load_param_into_net(network, param_dict) - # get train and eval dataset - ds_train = create_dataset('workspace/mnist/train') - ds_eval = create_dataset('workspace/mnist/test') - evaluation = UncertaintyEvaluation(model=network, - train_dataset=ds_train, - task_type='classification', - num_classes=10, - epochs=1, - epi_uncer_model_path=None, - ale_uncer_model_path=None, - save_model=False) - for eval_data in ds_eval.create_dict_iterator(): - eval_data = Tensor(eval_data['image'].asnumpy(), mstype.float32) - epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) - aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) - print('The shape of epistemic uncertainty is ', epistemic_uncertainty.shape) - print('The shape of epistemic uncertainty is ', aleatoric_uncertainty.shape) -``` -`eval_epistemic_uncertainty`计算的是认知不确定性,也叫模型不确定性,对于每一个样本的每个预测标签都会有一个不确定值;`eval_aleatoric_uncertainty`计算的是偶然不确定性,也叫数据不确定性,对于每一个样本都会有一个不确定值。 -所以输出为: - -``` -The shape of epistemic uncertainty is (32, 10) -The shape of epistemic uncertainty is (32,) -``` \ No newline at end of file +# 深度概率编程库 + + + +- [深度概率编程库](#深度概率编程库) + - [概率分布](#概率分布) + - [概率分布类](#概率分布类) + - [Distribution基类](#distribution基类) + - [伯努利分布Bernoulli](#伯努利分布bernoulli) + - [指数分布Exponential](#指数分布exponential) + - [几何分布Geometric](#几何分布geometric) + - [正态分布Normal](#正态分布normal) + - [均匀分布Uniform](#均匀分布uniform) + - [概率分布类在PyNative模式下的应用](#概率分布类在pynative模式下的应用) + - [概率分布类在图模式下的应用](#概率分布类在图模式下的应用) + - [概率分布映射](#概率分布映射) + - [Bijector类接口设计](#bijector类接口设计) + - [Bijector基类](#bijector基类) + - [幂函数变换映射PowerTransform](#幂函数变换映射powertransform) + - [指数变换映射Exp](#指数变换映射exp) + - [标量仿射变换映射ScalarAffine](#标量仿射变换映射scalaraffine) + - [Softplus变换映射Softplus](#softplus变换映射softplus) + - [PyNative模式下调用Bijector实例](#pynative模式下调用bijector实例) + - [图模式下调用Bijector实例](#图模式下调用bijector实例) + - [TransformedDistribution类接口设计](#transformeddistribution类接口设计) + - [PyNative模式下调用TransformedDistribution实例](#pynative模式下调用transformeddistribution实例) + - [图模式下调用TransformedDistribution实例](#图模式下调用transformeddistribution实例) + - [深度概率网络](#深度概率网络) + - [VAE](#vae) + - [ConditionalVAE](#conditionalvae) + - [概率推断算法](#概率推断算法) + - [贝叶斯层](#贝叶斯层) + - [贝叶斯转换](#贝叶斯转换) + - [贝叶斯工具箱](#贝叶斯工具箱) + + + + + +MindSpore深度概率编程的目标是将深度学习和贝叶斯学习结合,包括概率分布、概率分布映射、深度概率网络、概率推断算法、贝叶斯层、贝叶斯转换和贝叶斯工具箱,面向不同的开发者。对于专业的贝叶斯学习用户,提供概率采样、推理算法和模型构建库;另一方面,为不熟悉贝叶斯深度学习的用户提供了高级的API,从而不用更改深度学习编程逻辑,即可利用贝叶斯模型。 + +## 概率分布 + +概率分布(`mindspore.nn.probability.distribution`)是概率编程的基础。**Distribution** 类提供多样的概率统计接口,例如概率密度函数 *pdf* 、累积密度函数 *cdf* 、散度计算 *kl_loss* 、抽样 *sample* 等。现有的概率分布实例包括高斯分布,伯努利分布,指数型分布,几何分布和均匀分布。 + +### 概率分布类 + +- `Distribution`:所有概率分布的基类。 + +- `Bernoulli`:伯努利分布。参数为试验成功的概率。 + +- `Exponential`: 指数型分布。参数为率参数。 + +- `Geometric`:几何分布。参数为一次伯努利试验成功的概率。 + +- `Normal`:正态(高斯)分布。参数为均值和标准差。 + +- `Uniform`:均匀分布。参数为数轴上的最小值和最大值。 + +#### Distribution基类 + +`Distribution` 是所有概率分布的基类。 + +接口介绍:`Distribution`类支持的函数包括 `prob`、`log_prob`、`cdf`、`log_cdf`、`survival_function`、`log_survival`、`mean`、`sd`、`var`、`entropy`、`kl_loss`、`cross_entropy` 和 `sample` 。分布不同,所需传入的参数也不同。只有在派生类中才能使用,由派生类的函数实现决定参数。 + +- `prob` :概率密度函数(pdf)/ 概率质量函数(pmf)。 +- `log_prob` :对数似然函数。 +- `cdf` :累积分布函数(cdf)。 +- `log_cdf` :对数累积分布函数(cdf)。 +- `survival_function` :生存函数。 +- `log_survival` :对数生存函数。 +- `mean` :均值。 +- `sd` :标准差。 +- `var` :方差。 +- `entropy` :熵。 +- `kl_loss` :Kullback-Leibler散度。 +- `cross_entropy` :两个概率分布的交叉熵。 +- `sample` :概率分布的随机抽样。 + +#### 伯努利分布Bernoulli + +伯努利分布,继承自 `Distribution` 类。 + +属性: +- `Bernoulli.probs`:伯努利试验成功的概率。 + +`Distribution` 基类调用 `Bernoulli` 中私有接口以实现基类中的公有接口。`Bernoulli` 支持的公有接口为: + +- `mean`,`mode`,`var`:可选择传入 试验成功的概率 *probs1* 。 +- `entropy`:可选择传入 试验成功的概率 *probs1* 。 +- `cross_entropy`,`kl_loss`:必须传入 *dist* 和 *probs1_b* 。*dist* 为另一分布的类型,目前只支持此处为 *‘Bernoulli’* 。 *probs1_b* 为分布 *b* 的试验成功概率。可选择传入分布 *a* 的参数 *probs1_a* 。 +- `prob`,`log_prob`,`cdf`,`log_cdf`,`survival_function`,`log_survival`:必须传入 *value* 。可选择传入试验成功的概率 *probs* 。 +- `sample`:可选择传入样本形状 *shape* 和试验成功的概率 *probs1* 。 + +#### 指数分布Exponential + +指数分布,继承自`Distribution`类。 + +属性: +- `Exponential.rate`:率参数。 + +`Distribution` 基类调用 `Exponential` 私有接口以实现基类中的公有接口。`Exponential` 支持的公有接口为: + +- `mean`,`mode`,`var`:可选择传入率参数 *rate* 。 +- `entropy`:可选择传入率参数 *rate* 。 +- `cross_entropy`,`kl_loss`:必须传入 *dist* 和 *rate_b* 。 *dist* 为另一分布的类型的名称, 目前只支持此处为 *‘Exponential’* 。*rate_b* 为分布 *b* 的率参数。可选择传入分布 *a* 的参数 *rate_a* 。 +- `prob`,`log_prob`,`cdf`,`log_cdf`,`survival_function`,`log_survival`:必须传入 *value* 。可选择传入率参数 *rate* 。 +- `sample`:可选择传入样本形状 *shape* 和率参数 *rate* 。 + +#### 几何分布Geometric + +几何分布,继承自`Distribution`类。 + +属性: +- `Geometric.probs`:伯努利试验成功的概率。 + +`Distribution` 基类调用 `Geometric` 中私有接口以实现基类中的公有接口。`Geometric` 支持的公有接口为: + +- `mean`,`mode`,`var`:可选择传入 试验成功的概率 *probs1* 。 +- `entropy`:可选择传入 试验成功的概率 *probs1* 。 +- `cross_entropy`,`kl_loss`:必须传入 *dist* 和 *probs1_b* 。*dist* 为另一分布的类型的名称,目前只支持此处为 *‘Geometric’* 。 *probs1_b* 为分布 *b* 的试验成功概率。可选择传入分布 *a* 的参数 *probs1_a* 。 +- `prob`,`log_prob`,`cdf`,`log_cdf`,`survival_function`,`log_survival`:必须传入 *value* 。可选择传入试验成功的概率 *probs1* 。 +- `sample`:可选择传入样本形状 *shape* 和试验成功的概率 *probs1* 。 + +#### 正态分布Normal + +正态(高斯)分布,继承自 **Distribution** 类。 + +**Distribution** 基类调用 **Normal** 中私有接口以实现基类中的公有接口。**Normal** 支持的公有接口为: +- `mean`,`mode`,`var`:可选择传入分布的参数均值 *mean* 和标准差 *sd* 。 +- `entropy`:可选择传入分布的参数均值 *mean* 和标准差 *sd* 。 +- `cross_entropy`,`kl_loss`:必须传入 *dist* ,*mean_b* 和 *sd_b* 。*dist* 为另一分布的类型的名称,目前只支持此处为 *‘Normal’* 。*mean_b* 和 *sd_b* 为分布 *b* 的均值和标准差。可选择传入分布的参数 *a* 均值 *mean_a* 和标准差 *sd_a* 。 +- `prob`,`log_prob`,`cdf`,`log_cdf`,`survival_function`,`log_survival`:必须传入 *value* 。可选择分布的参数包括均值 *mean_a* 和标准差 *sd_a* 。 +- `sample`:可选择传入样本形状 *shape* 和分布的参数包括均值 *mean_a* 和标准差 *sd_a* 。 + +#### 均匀分布Uniform + +均匀分布,继承自`Distribution`类。 + +属性: +- `Uniform.low`:最小值。 +- `Uniform.high`:最大值。 + +`Distribution` 基类调用 `Uniform` 以实现基类中的公有接口。`Uniform` 支持的公有接口为: + +- `mean`,`mode`,`var`:可选择传入分布的参数最大值 *high* 和最小值 *low* 。 +- `entropy`:可选择传入分布的参数最大值 *high* 和最小值 *low* 。 +- `cross_entropy`,`kl_loss`:必须传入 *dist* ,*high_b* 和 *low_b* 。*dist* 为另一分布的类型的名称,目前只支持此处为 *‘Uniform’* 。 *high_b* 和 *low_b* 为分布 *b* 的参数。可选择传入分布 *a* 的参数即最大值 *high_a* 和最小值 *low_a* 。 +- `prob`,`log_prob`,`cdf`,`log_cdf`,`survival_function`,`log_survival`:必须传入 *value* 。可选择传入分布的参数最大值 *high* 和最小值 *low* 。 +- `sample`:可选择传入 *shape* 和分布的参数即最大值 *high* 和最小值 *low* 。 + +### 概率分布类在PyNative模式下的应用 + +`Distribution` 子类可在 **PyNative** 模式下使用。 + +导入相关模块: + +```python +from mindspore import Tensor +from mindspore import dtype as mstype +import mindspore.context as context +import mindspore.nn.probability.distribution as msd +context.set_context(mode=context.PYNATIVE_MODE) +``` +以 **Normal** 为例, 创建一个均值为0.0、标准差为1.0的正态分布: +```python +my_normal = msd.Normal(0.0, 1.0, dtype=mstype.float32) +``` +计算均值: +```python +mean = my_normal.mean() +print(mean) +``` +输出为: +``` +0.0 +``` +计算方差: +```python +var = my_normal.var() +print(var) +``` +输出为: +``` +1.0 +``` +计算熵: +```python +entropy = my_normal.entropy() +print(entropy) +``` +输出为: +``` +1.4189385 +``` +计算 **pdf**: +```python +value = Tensor([-0.5, 0.0, 0.5], dtype=mstype.float32) +prob = my_normal.prob(value) +print(prob) +``` +输出为: +``` +[0.35206532, 0.3989423, 0.35206532] +``` +计算 **cdf**: +```python +cdf = my_normal.cdf(value) +print(cdf) +``` +输出为: +``` +[0.30852754, 0.5, 0.69146246] +``` +计算 **kl_loss**: +```python +mean_b = Tensor(1.0, dtype=mstype.float32) +sd_b = Tensor(2.0, dtype=mstype.float32) +kl = my_normal.kl_loss('Normal', mean_b, sd_b) +print(kl) +``` +输出为: +``` +0.44314718 +``` + +### 概率分布类在图模式下的应用 + +在图模式下,**Distribution** 子类可用在网络中。 + +导入相关模块: +```python +import mindspore.nn as nn +from mindspore import Tensor +from mindspore import dtype as mstype +import mindspore.context as context +import mindspore.nn.probability.distribution as msd +context.set_context(mode=context.GRAPH_MODE) +``` +创建网络: +```python +# 网络继承nn.Cell +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + self.normal = msd.Normal(0.0, 1.0, dtype=mstype.float32) + + def construct(self, value, mean, sd): + pdf = self.normal.prob(value) + kl = self.normal.kl_loss("Normal", mean, sd) + return pdf, kl +``` +调用网络: +```python +net = Net() +value = Tensor([-0.5, 0.0, 0.5], dtype=mstype.float32) +mean = Tensor(1.0, dtype=mstype.float32) +sd = Tensor(1.0, dtype=mstype.float32) +pdf, kl = net(value, mean, sd) +print("pdf: ", pdf) +print("kl: ", kl) +``` +输出为: +``` +pdf: [0.3520653, 0.39894226, 0.3520653] +kl: 0.5 +``` + +## 概率分布映射 + +Bijector(`mindspore.nn.probability.bijector`)是概率编程的基本组成部分。Bijector描述了一种随机变量的变换方法,可以通过一个已有的随机变量X和一个映射函数f生成一个新的随机变量$Y = f(x)$。 +`Bijector`提供了映射相关的四种变换方法。它可以当做算子直接使用,也可以作用在某个随机变量`Distribution`类实例上生成新的随机变量的`Distribution`类实例。 + +### Bijector类接口设计 + +#### Bijector基类 + +`Bijector`类是所有Bejictor的基类。其接口包括: + +1. 类特征函数 + - `name`:无参函数,返回 `name` 的值。 + - `is_dtype`:无参函数,返回 `dtype` 的值。 + - `parameter`:无参函数,返回 `parameter` 的值。 + - `is_constant_jacobian`:无参函数,返回 `is_constant_jacobian` 的值。 + - `is_injective`:无参函数,返回 `is_injective` 的值。 + +2. 映射函数 + - `forward`:正向映射,创建派生类后由派生类的 `_forward` 决定参数。 + - `inverse`:反向映射,创建派生类后由派生类的 `_inverse` 决定参数。 + - `forward_log_jacobian`:正向映射的导数的对数,创建派生类后由派生类的 `_forward_log_jacobian` 决定参数。 + - `inverse_log_jacobian`:反向映射的导数的对数,创建派生类后由派生类的 `_inverse_log_jacobian` 决定参数。 + +* `Bijector` 作为函数调用: +输入是一个 `Distribution` 类:生成一个 `TransformedDistribution` **(不可在图内调用)**。 + +#### 幂函数变换映射PowerTransform +`PowerTransform`做如下变量替换:$Y = g(X) = {(1 + X * c)}^{1 / c}$。其接口包括: + +1. 类特征函数 + - `power`:无参函数,返回 `power` 的值。 + +2. 映射函数 + - `forward`:正向映射,输入为 `Tensor` 。 + - `inverse`:反向映射,输入为 `Tensor` 。 + - `forward_log_jacobian`:正向映射的导数的对数,输入为 `Tensor` 。 + - `inverse_log_jacobian`:反向映射的导数的对数,输入为 `Tensor` 。 + +#### 指数变换映射Exp +`Exp`做如下变量替换:$Y = g(X)= exp(X)$。其接口包括: + +1. 映射函数 + - `forward`:正向映射,输入为 `Tensor` 。 + - `inverse`:反向映射,输入为 `Tensor` 。 + - `forward_log_jacobian`:正向映射的导数的对数,输入为 `Tensor` 。 + - `inverse_log_jacobian`:反向映射的导数的对数,输入为 `Tensor` 。 + +#### 标量仿射变换映射ScalarAffine +`ScalarAffine`做如下变量替换:Y = g(X) = a * X + b。其接口包括: + +1. 类特征函数 + - `scale`:无参函数,返回scale的值。 + - `shift`:无参函数,返回shift的值。 + +2. 映射函数 + - `forward`:正向映射,输入为 `Tensor` 。 + - `inverse`:反向映射,输入为 `Tensor` 。 + - `forward_log_jacobian`:正向映射的导数的对数,输入为 `Tensor` 。 + - `inverse_log_jacobian`:反向映射的导数的对数,输入为 `Tensor` 。 + +#### Softplus变换映射Softplus +`Softplus`做如下变量替换:$Y = g(X) = log(1 + e ^ {kX}) / k $。其接口包括: + +1. 类特征函数 + - `sharpness`:无参函数,返回 `sharpness` 的值。 + +2. 映射函数 + - `forward`:正向映射,输入为 `Tensor` 。 + - `inverse`:反向映射,输入为 `Tensor` 。 + - `forward_log_jacobian`:正向映射的导数的对数,输入为 `Tensor` 。 + - `inverse_log_jacobian`:反向映射的导数的对数,输入为 `Tensor` 。 + +### PyNative模式下调用Bijector实例 + +在执行之前,我们需要导入需要的库文件包。双射类最主要的库是 `mindspore.nn.probability.bijector`,导入后我们使用 `msb` 作为库的缩写并进行调用。 + +导入相关模块: +```python +import numpy as np +import mindspore.nn as nn +import mindspore.nn.probability.bijector as msb +import mindspore.context as context +from mindspore import Tensor +from mindspore import dtype +context.set_context(mode=context.PYNATIVE_MODE) +``` + +下面我们以 `PowerTransform` 为例。创建一个指数为2的 `PowerTransform` 对象。 + +构造`PowerTransform`: +```python +powertransform = msb.PowerTransform(power=2) +powertransform +``` + +输出: +```python +PowerTransform +``` + +接下来可以使用映射函数进行运算。 + +调用 `forward` 方法,计算正向映射: +```python +x = np.array([2.0, 3.0, 4.0, 5.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +forward = powertransform.forward(tx) +foward +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [ 2.23606801e+00 2.64575124e+00 3.00000000e+00 3.31662488e+00]) +``` + +输入 `inverse` 方法,计算反向映射: +```python +inverse = powertransform.inverse(tx) +inverse +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [ 1.50000000e+00 4.00000048e+00 7.50000000e+00 1.20000010e+01]) +``` + +输入 `forward_log_jacobian` 方法,计算正向映射导数的对数: +```python +forward_log_jaco = powertransform.forward_log_jacobian(tx) +forward_log_jaco +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [-8.04718971e-01 -9.72955048e-01 -1.09861231e+00 -1.19894767e+00]) +``` + +输入`inverse_log_jacobian`方法,计算反向映射导数的对数: +```python +inverse_log_jaco = powertransform.inverse_log_jacobian(tx) +inverse_log_jaco +``` + +输出: +```python +Tensor(shape=[4], dtype=Float32, [ 6.93147182e-01 1.09861231e+00 1.38629436e+00 1.60943794e+00]) +``` + +### 图模式下调用Bijector实例 + +在图模式下,`Bijector`子类可用在网络中。 + +导入相关模块: +```python +import mindspore.nn as nn +from mindspore import Tensor +from mindspore import dtype as mstype +import mindspore.context as context +import mindspore.nn.probability.Bijector as msb +context.set_context(mode=context.GRAPH_MODE) +``` + +创建网络: +```python +class Net(nn.Cell): + def __init__(self): + super(Net, self).__init__() + # 创建PowerTransform实例 + self.powertransform = msb.PowerTransform(power=2) + + def construct(self, value): + forward = self.s1.forward(value) + inverse = self.s1.inverse(value) + forward_log_jaco = self.s1.forward_log_jacobian(value) + inverse_log_jaco = self.s1.inverse_log_jacobian(value) + return forward, inverse, forward_log_jaco, inverse_log_jaco +``` +调用网络: +```python +net = Net() +x = np.array([2.0, 3.0, 4.0, 5.0]).astype(np.float32) +tx = Tensor(x, dtype=dtype.float32) +forward, inverse, forward_log_jaco, inverse_log_jaco = net(tx) +print("forward: ", forward) +print("inverse: ", inverse) +print("forward_log_jaco: ", forward_log_jaco) +print("inverse_log_jaco: ", inverse_log_jaco) +``` +输出为: +```python +forward: [2.236068 2.6457512 3. 3.3166249] +inverse: [ 1.5 4.0000005 7.5 12.000001 ] +forward_log_jaco: [-0.804719 -0.97295505 -1.0986123 -1.1989477 ] +inverse_log_jaco: [0.6931472 1.0986123 1.3862944 1.609438 ] +``` + +### TransformedDistribution类接口设计 + +`TransformedDistribution` 继承自 `Distribution` ,是可通过映射f(x)变化得到的数学分布的基类。其接口包括: + +1. 类特征函数 + + - `bijector`:无参函数,返回分布的变换方法。 + - `distribution`:无参函数,返回原始分布。 + - `is_linear_transformation`:无参函数,返回线性变换标志。 + +2. 接口函数(以下接口函数的参数与构造函数中 `distribution` 的对应接口的参数相同)。 + + - `cdf`:累积分布函数(cdf)。 + - `log_cdf`:对数累积分布函数(cdf)。 + - `survival_function`:生存函数。 + - `log_survival`:对数生存函数。 + - `prob`:概率密度函数(pdf)/ 概率质量函数(pmf)。 + - `log_prob`:对数似然函数。 + - `sample`:随机取样。 + - `mean`:无参数。只有当 `Bijector.is_constant_jacobian=true` 时可调用。 + +### PyNative模式下调用TransformedDistribution实例 + +`TransformedDistribution` 子类可在 **PyNative** 模式下使用。 +在执行之前,我们需要导入需要的库文件包。 + +导入相关模块: +```python +import numpy as np +import mindspore.nn as nn +import mindspore.nn.probability.bijector as msb +import mindspore.nn.probability.distribution as msd +import mindspore.context as context +from mindspore import Tensor +from mindspore import dtype +context.set_context(mode=context.PYNATIVE_MODE) +``` + +构造一个 `TransformedDistribution` 实例,使用 `Normal` 分布作为需要变换的分布类,使用 `Exp` 作为映射变换,可以生成 `LogNormal` 分布。 +```python +normal = msd.Normal(0.0, 1.0, dtype=dtype.float32) +exp = msb.Exp() +LogNormal = msd.TransformedDistribution(exp, normal, dtype=dtype.float32, seed=0, name="LogNormal") +LogNormal +``` + +输出: +```python +TransformedDistribution< + (_bijector): Exp + (_distribution): Normal + > +``` + +可以对 `LogNormal` 进行概率分布计算。例如: + +计算 **cdf** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +cdf = LogNormal.cdf(tx) +cdf +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [ 7.55891383e-01 9.46239710e-01 9.89348888e-01]) +``` + +计算 **log_cdf** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +log_cdf = LogNormal.log_cdf(tx) +log_cdf +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [-2.79857576e-01 -5.52593507e-02 -1.07082408e-02]) +``` + +计算 **survival_function** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +survival_function = LogNormal.survival_function(tx) +survival_function +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [ 2.44108617e-01 5.37602901e-02 1.06511116e-02]) +``` + +计算 **log_survival** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +log_survival = LogNormal.log_survival(tx) +log_survival +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [-1.41014194e+00 -2.92322016e+00 -4.54209089e+00]) +``` + +计算 **prob** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +prob = LogNormal.prob(tx) +prob +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [ 1.56874031e-01 2.18507163e-02 2.81590177e-03]) +``` + +计算 **log_prob** : +```python +x = np.array([2.0, 5.0, 10.0], dtype=np.float32) +tx = Tensor(x, dtype=dtype.float32) +log_prob = LogNormal.log_prob(tx) +log_prob +``` + +输出: +```python +Tensor(shape=[3], dtype=Float32, [-1.85231221e+00 -3.82352161e+00 -5.87247276e+00]) +``` + +调用取样函数 **sample** : +```python +shape = ((3, 2)) +sample = LogNormal.sample(shape) +sample +``` + +输出: +```python +Tensor(shape=[3, 2], dtype=Float32, +[[ 7.64315844e-01 3.01435232e-01] + [ 1.17166102e+00 2.60277224e+00] + [ 7.02699006e-01 3.91564220e-01]]) +``` + +### 图模式下调用TransformedDistribution实例 + +在图模式下,**TransformedDistribution**子类可用在网络中。 + +导入相关模块: +```python +import mindspore.nn as nn +from mindspore import Tensor +from mindspore import dtype +import mindspore.context as context +import mindspore.nn.probability.Bijector as msb +import mindspore.nn.probability.Distribution as msd +context.set_context(mode=self.GRAPH_MODE) +``` + +创建网络: +```python +class Net(nn.Cell): + def __init__(self, shape, dtype=dtype.float32, seed=0, name='transformed_distribution'): + super(Net, self).__init__() + # 创建TransformedDistribution实例 + self.exp = msb.Exp() + self.normal = msd.Normal(0.0, 1.0, dtype=dtype) + self.lognormal = msd.TransformedDistribution(self.exp, self.normal, dtype=dtype, seed=seed, name=name) + self.shape = shape + + def construct(self, value): + cdf = self.lognormal.cdf(value) + sample = self.lognormal.sample(self.shape) + return cdf, sample +``` + +调用网络: +```python +shape = (2, 3) +net = Net(shape=shape, name="LogNormal") +x = np.array([2.0, 3.0, 4.0, 5.0]).astype(np.float32) +tx = Tensor(x, dtype=dtype.float32) +cdf, sample = net(tx) +print("cdf: ", cdf) +print("sample: ", sample) +``` +输出为: +```python +cdf: [0.7558914 0.8640314 0.9171715 0.9462397] +sample: [[0.21036398 0.44932044 0.5669641 ] + [1.4103683 6.724116 0.97894996]] +``` + +## 深度概率网络 + +使用MindSpore深度概率编程库(`mindspore.nn.probability.dpn`)来构造变分自编码器(VAE)进行推理尤为简单。我们只需要自定义编码器和解码器(DNN模型),调用VAE或CVAE接口形成其派生网络,然后调用ELBO接口进行优化,最后使用SVI接口进行变分推理。这样做的好处是,不熟悉变分推理的用户可以像构建DNN模型一样来构建概率模型,而熟悉的用户可以调用这些接口来构建更为复杂的概率模型。VAE的接口在`mindspore.nn.probability.dpn`下面,dpn代表的是Deep probabilistic network,这里提供了一些基本的深度概率网络的接口,例如VAE。 + +### VAE + +首先,我们需要先自定义encoder和decoder,调用`mindspore.nn.probability.dpn.VAE`接口来构建VAE网络,我们除了传入encoder和decoder之外,还需要传入encoder输出变量的维度hidden size,以及VAE网络存储潜在变量的维度latent size,一般latent size会小于hidden size。 + +```python +import mindspore.nn as nn +from mindspore.ops import operations as P +from mindspore.nn.probability.dpn import VAE + +IMAGE_SHAPE = (-1, 1, 32, 32) + + +class Encoder(nn.Cell): + def __init__(self): + super(Encoder, self).__init__() + self.fc1 = nn.Dense(1024, 800) + self.fc2 = nn.Dense(800, 400) + self.relu = nn.ReLU() + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + return x + + +class Decoder(nn.Cell): + def __init__(self): + super(Decoder, self).__init__() + self.fc1 = nn.Dense(400, 1024) + self.sigmoid = nn.Sigmoid() + self.reshape = P.Reshape() + + def construct(self, z): + z = self.fc1(z) + z = self.reshape(z, IMAGE_SHAPE) + z = self.sigmoid(z) + return z + + +encoder = Encoder() +decoder = Decoder() +vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) +``` +### ConditionalVAE + +类似地,ConditionalVAE与VAE的使用方法比较相近,不同的是,ConditionalVAE利用了数据集的标签信息,属于有监督学习算法,其生成效果一般会比VAE好。 + +首先,先自定义encoder和decoder,并调用`mindspore.nn.probability.dpn.ConditionalVAE`接口来构建ConditionalVAE网络,这里的encoder和VAE的不同,因为需要传入数据集的标签信息;decoder和上述的一样。ConditionalVAE接口的传入则还需要传入数据集的标签类别个数,其余和VAE接口一样。 + +``` +import mindspore.nn as nn +from mindspore.ops import operations as P +from mindspore.nn.probability.dpn import ConditionalVAE + +IMAGE_SHAPE = (-1, 1, 32, 32) + + +class Encoder(nn.Cell): + def __init__(self, num_classes): + super(Encoder, self).__init__() + self.fc1 = nn.Dense(1024 + num_classes, 400) + self.relu = nn.ReLU() + self.flatten = nn.Flatten() + self.concat = P.Concat(axis=1) + self.one_hot = nn.OneHot(depth=num_classes) + + def construct(self, x, y): + x = self.flatten(x) + y = self.one_hot(y) + input_x = self.concat((x, y)) + input_x = self.fc1(input_x) + input_x = self.relu(input_x) + return input_x + + +class Decoder(nn.Cell): + def __init__(self): + super(Decoder, self).__init__() + self.fc1 = nn.Dense(400, 1024) + self.sigmoid = nn.Sigmoid() + self.reshape = P.Reshape() + + def construct(self, z): + z = self.fc1(z) + z = self.reshape(z, IMAGE_SHAPE) + z = self.sigmoid(z) + return z + + +encoder = Encoder(num_classes=10) +decoder = Decoder() +cvae = ConditionalVAE(encoder, decoder, hidden_size=400, latent_size=20, num_classes=10) +``` + +加载数据集,我们可以使用Mnist数据集,具体的数据加载和预处理过程可以参考这里[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html),这里会用到create_dataset函数创建数据迭代器。 + +```python +ds_train = create_dataset(image_path, 128, 1) +``` +接下来,需要用到infer接口进行VAE网络的变分推断。 + +## 概率推断算法 + +调用ELBO接口(`mindspore.nn.probability.infer.ELBO`)来定义VAE网络的损失函数,调用`WithLossCell`封装VAE网络和损失函数,并定义优化器,之后传入SVI接口(`mindspore.nn.probability.infer.SVI`)。SVI的`run`函数可理解为VAE网络的训练,可以指定训练的`epochs`,返回结果为训练好的网络;`get_train_loss`函数可以返回训练好后模型的loss。 + +```python +from mindspore.nn.probability.infer import ELBO, SVI + +net_loss = ELBO(latent_prior='Normal', output_prior='Normal') +net_with_loss = nn.WithLossCell(vae, net_loss) +optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) + +vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) +vae = vi.run(train_dataset=ds_train, epochs=10) +trained_loss = vi.get_train_loss() +``` +最后,得到训练好的VAE网络后,我们可以使用`vae.generate_sample`生成新样本,需要传入待生成样本的个数,及生成样本的shape,shape需要保持和原数据集中的样本shape一样;当然,我们也可以使用`vae.reconstruct_sample`重构原来数据集中的样本,来测试VAE网络的重建能力。 +```python +generated_sample = vae.generate_sample(64, IMAGE_SHAPE) +for sample in ds_train.create_dict_iterator(): + sample_x = Tensor(sample['image'], dtype=mstype.float32) + reconstructed_sample = vae.reconstruct_sample(sample_x) +print('The shape of the generated sample is ', generated_sample.shape) +``` +我们可以看一下新生成样本的shape: +``` +The shape of the generated sample is (64, 1, 32, 32) +``` +ConditionalVAE训练过程和VAE的过程类似,但需要注意的是使用训练好的ConditionalVAE网络生成新样本和重建新样本时,需要输入标签信息,例如下面生成的新样本就是64个0-7的数字。 + +``` +sample_label = Tensor([i for i in range(0, 8)] * 8, dtype=mstype.int32) +generated_sample = cvae.generate_sample(sample_label, 64, IMAGE_SHAPE) +for sample in ds_train.create_dict_iterator(): + sample_x = Tensor(sample['image'], dtype=mstype.float32) + sample_y = Tensor(sample['label'], dtype=mstype.int32) + reconstructed_sample = cvae.reconstruct_sample(sample_x, sample_y) +print('The shape of the generated sample is ', generated_sample.shape) +``` +查看一下新生成的样本的shape: +``` +The shape of the generated sample is (64, 1, 32, 32) +``` + +如果希望新生成的样本更好,更清晰,用户可以自己定义更复杂的encoder和decoder,这里的示例只用了两层全连接层,仅供示例的指导。 + +## 贝叶斯层 + +下面的范例使用MindSpore的`nn.probability.bnn_layers`中的API实现BNN图片分类模型。MindSpore的`nn.probability.bnn_layers`中的API包括`NormalPrior`,`NormalPosterior`,`ConvReparam`,`DenseReparam`和`WithBNNLossCell`。BNN与DNN的最大区别在于,BNN层的weight和bias不再是确定的值,而是服从一个分布。其中,`NormalPrior`,`NormalPosterior`分别用来生成服从正态分布的先验分布和后验分布;`ConvReparam`和`DenseReparam`分别是使用reparameteration方法实现的贝叶斯卷积层和全连接层;`WithBNNLossCell`是用来封装BNN和损失函数的。 + +如何使用`nn.probability.bnn_layers`中的API构建贝叶斯神经网络并实现图片分类,可以参考教程[使用贝叶斯网络](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/deep_probability_program.html#id3)。 + +## 贝叶斯转换 + +对于不熟悉贝叶斯模型的研究人员,MDP提供了贝叶斯转换接口(`mindspore.nn.probability.transform`),支持DNN (Deep Neural Network)模型一键转换成BNN (Bayesian Neural Network)模型。 + +其中的模型转换API`TransformToBNN`的`__init__`函数定义如下: + +``` +class TransformToBNN: + def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): + net_with_loss = trainable_dnn.network + self.optimizer = trainable_dnn.optimizer + self.backbone = net_with_loss.backbone_network + self.loss_fn = getattr(net_with_loss, "_loss_fn") + self.dnn_factor = dnn_factor + self.bnn_factor = bnn_factor + self.bnn_loss_file = None +``` +参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 +API`TransformToBNN`主要实现了两个功能: +- 功能一:转换整个模型 + + `transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下: + + ``` + def transform_to_bnn_model(self, + get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, + "out_channels": dp.out_channels, "activation": dp.activation}, + get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, + "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, + "stride": dp.stride, "has_bias": dp.has_bias, + "padding": dp.padding, "dilation": dp.dilation, + "group": dp.group}, + add_dense_args=None, + add_conv_args=None): + r""" + Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. + + Args: + get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. + get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, + "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. + add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. + add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. + + Returns: + Cell, a trainable BNN model wrapped by TrainOneStepCell. + """ + + ``` + 参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,默认值是DNN模型的全连接层和BNN的全连接层所共有的参数,参数具体的含义可以参考[API说明文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Dense);`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,默认值是DNN模型的卷积层和BNN的卷积层所共有的参数,参数具体的含义可以参考[API说明文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Conv2d);参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 + +- 功能二:转换指定类型的层 + + `transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(`nn.Dense`或者`nn.Conv2d`)转换为对应的贝叶斯层。其定义如下: + + ``` + def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): + r""" + Transform a specific type of layers in DNN model to corresponding BNN layer. + + Args: + dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are + nn.Dense, nn.Conv2d. + bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are + DenseReparameterization, ConvReparameterization. + get_args (dict): The arguments gotten from the DNN layer. Default: None. + add_args (dict): The new arguments added to BNN layer. Default: None. + + Returns: + Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. + """ + ``` + 参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 + +如何在MindSpore中使用API`TransformToBNN`可以参考教程[DNN一键转换成BNN](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/deep_probability_program.html#dnnbnn) + +## 贝叶斯工具箱 + +贝叶斯神经网络的优势之一就是可以获取不确定性,MDP在上层提供了不确定性估计的工具箱(`mindspore.nn.probability.toolbox`),用户可以很方便地使用该工具箱计算不确定性。不确定性意味着深度学习模型对预测结果的不确定程度。目前,大多数深度学习算法只能给出高置信度的预测结果,而不能判断预测结果的确定性,不确定性主要有两种类型:偶然不确定性和认知不确定性。 + +- 偶然不确定性(Aleatoric Uncertainty):描述数据中的内在噪声,即无法避免的误差,这个现象不能通过增加采样数据来削弱。 +- 认知不确定性(Epistemic Uncertainty):模型自身对输入数据的估计可能因为训练不佳、训练数据不够等原因而不准确,可以通过增加训练数据等方式来缓解。 + +不确定性评估工具箱的接口如下: +- `model`:待评估不确定性的已训练好的模型。 +- `train_dataset`:用于训练的数据集,迭代器类型。 +- `task_type`:模型的类型,字符串,输入“regression”或者“classification”。 +- `num_classes`:如果是分类模型,需要指定类别的标签数量。 +- `epochs`:用于训练不确定模型的迭代数。 +- `epi_uncer_model_path`:用于存储或加载计算认知不确定性的模型的路径。 +- `ale_uncer_model_path`:用于存储或加载计算偶然不确定性的模型的路径。 +- `save_model`:布尔类型,是否需要存储模型。 + +在使用前,需要先训练好模型,以LeNet5为例,使用方式如下: +``` +from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation +from mindspore.train.serialization import load_checkpoint, load_param_into_net + +if __name__ == '__main__': + # get trained model + network = LeNet5() + param_dict = load_checkpoint('checkpoint_lenet.ckpt') + load_param_into_net(network, param_dict) + # get train and eval dataset + ds_train = create_dataset('workspace/mnist/train') + ds_eval = create_dataset('workspace/mnist/test') + evaluation = UncertaintyEvaluation(model=network, + train_dataset=ds_train, + task_type='classification', + num_classes=10, + epochs=1, + epi_uncer_model_path=None, + ale_uncer_model_path=None, + save_model=False) + for eval_data in ds_eval.create_dict_iterator(): + eval_data = Tensor(eval_data['image'], mstype.float32) + epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) + aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) + print('The shape of epistemic uncertainty is ', epistemic_uncertainty.shape) + print('The shape of epistemic uncertainty is ', aleatoric_uncertainty.shape) +``` +`eval_epistemic_uncertainty`计算的是认知不确定性,也叫模型不确定性,对于每一个样本的每个预测标签都会有一个不确定值;`eval_aleatoric_uncertainty`计算的是偶然不确定性,也叫数据不确定性,对于每一个样本都会有一个不确定值。 +所以输出为: + +``` +The shape of epistemic uncertainty is (32, 10) +The shape of epistemic uncertainty is (32,) +``` +uncertainty的值位于[0,1]之间,越大表示不确定性越高。 diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md index 465769b4b9..e819dd8d7d 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md @@ -1,435 +1,613 @@ -# 进行深度概率编程 -`Linux` `Ascend` `GPU` `全流程` `初级` `中级` `高级` - - - -- [进行深度概率编程](#进行深度概率编程) - - [概述](#概述) - - [贝叶斯神经网络](#贝叶斯神经网络) - - [处理数据集](#处理数据集) - - [定义贝叶斯神经网络](#定义贝叶斯神经网络) - - [定义损失函数和优化器](#定义损失函数和优化器) - - [训练网络](#训练网络) - - [变分推断](#变分推断) - - [定义变分自编码器](#定义变分自编码器) - - [定义损失函数和优化器](#定义损失函数和优化器-1) - - [处理数据](#处理数据) - - [训练网络](#训练网络-1) - - [生成新样本或重构输入样本](#生成新样本或重构输入样本) - - [DNN一键转换成BNN](#dnn一键转换成bnn) - - [定义DNN模型](#定义dnn模型) - - [定义损失函数和优化器](#定义损失函数和优化器-2) - - [实例化TransformToBNN](#实例化transformtobnn) - - [功能一:转换整个模型](#功能一转换整个模型) - - [功能二:转换指定类型的层](#功能二转换指定类型的层) - - [不确定性估计](#不确定性估计) - - - -## 概述 -MindSpore深度概率编程(MindSpore Deep Probabilistic Programming, MDP)的目标是将深度学习和贝叶斯学习结合,并能面向不同的开发者。具体来说,对于专业的贝叶斯学习用户,提供概率采样、推理算法和模型构建库;另一方面,为不熟悉贝叶斯深度学习的用户提供了高级的API,从而不用更改深度学习编程逻辑,即可利用贝叶斯模型。 - -本章将详细介绍深度概率编程在MindSpore上的应用。 - -### 贝叶斯神经网络 -本例子利用贝叶斯神经网络实现一个简单的图片分类功能,整体流程如下: -1. 处理MNIST数据集。 -2. 定义贝叶斯LeNet网络。 -3. 定义损失函数和优化器。 -4. 加载数据集并进行训练。 - -#### 处理数据集 -本例子使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 - -#### 定义贝叶斯神经网络 -本例子使用的是贝叶斯LeNet。利用`bnn_layers`构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,`bnn_layers`和普通的神经网络层可以互相组合。 - -``` -import mindspore.nn as nn -from mindspore.nn.probability import bnn_layers -import mindspore.ops.operations as P - -class BNNLeNet5(nn.Cell): - """ - bayesian Lenet network - - Args: - num_class (int): Num classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> BNNLeNet5(num_class=10) - - """ - def __init__(self, num_class=10): - super(BNNLeNet5, self).__init__() - self.num_class = num_class - self.conv1 = bnn_layers.ConvReparam(1, 6, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") - self.conv2 = bnn_layers.ConvReparam(6, 16, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") - self.fc1 = bnn_layers.DenseReparam(16 * 5 * 5, 120) - self.fc2 = bnn_layers.DenseReparam(120, 84) - self.fc3 = bnn_layers.DenseReparam(84, self.num_class) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - self.reshape = P.Reshape() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` -#### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。损失函数是深度学习的训练目标,也叫目标函数,可以理解为神经网络的输出(Logits)和标签(Labels)之间的距离,是一个标量数据。 -常见的损失函数包括均方误差、L2损失、Hinge损失、交叉熵等等。图像分类应用通常采用交叉熵损失(`CrossEntropy`)。 -优化器用于神经网络求解(训练)。由于神经网络参数规模庞大,无法直接求解,因而深度学习中采用随机梯度下降算法(SGD)及其改进算法进行求解。MindSpore封装了常见的优化器,如`SGD`、`Adam`、`Momemtum`等等。本例采用`Adam`优化器,通常需要设定两个参数,学习率(`learnin _rate`)和权重衰减项(`weight decay`)。 -MindSpore中定义损失函数和优化器的代码样例如下: - -``` -# loss function definition -criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - -# optimization definition -optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) -``` - -#### 训练网络 -贝叶斯神经网络的训练过程与DNN基本相同,唯一不同的是将`WithLossCell`替换为适用于BNN的`WithBNNLossCell`。除了`backbone`和`loss_fn`两个参数之外,`WithBNNLossCell`增加了`dnn_factor`和`bnn_factor`两个参数。`dnn_factor`是由损失函数计算得到的网络整体损失的系数,`bnn_factor`是每个贝叶斯层的KL散度的系数,这两个参数是用来平衡网络整体损失和贝叶斯层的KL散度的,防止KL散度的值过大掩盖了网络整体损失。 - -``` -net_with_loss = bnn_layers.WithBNNLossCell(network, criterion, dnn_factor=60000, bnn_factor=0.000001) -train_bnn_network = TrainOneStepCell(net_with_loss, optimizer) -train_bnn_network.set_train() - -train_set = create_dataset('./mnist_data/train', 64, 1) -test_set = create_dataset('./mnist_data/test', 64, 1) - -epoch = 10 - -for i in range(epoch): - train_loss, train_acc = train_model(train_bnn_network, network, train_set) - - valid_acc = validate_model(network, test_set) - - print('Epoch: {} \tTraining Loss: {:.4f} \tTraining Accuracy: {:.4f} \tvalidation Accuracy: {:.4f}'. - format(i, train_loss, train_acc, valid_acc)) -``` -其中,`train_model`和`validate_model`在MindSpore中的代码样例如下: - -``` -def train_model(train_net, net, dataset): - accs = [] - loss_sum = 0 - for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].asnumpy().astype(np.float32)) - label = Tensor(data['label'].asnumpy().astype(np.int32)) - loss = train_net(train_x, label) - output = net(train_x) - log_output = P.LogSoftmax(axis=1)(output) - acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) - accs.append(acc) - loss_sum += loss.asnumpy() - - loss_sum = loss_sum / len(accs) - acc_mean = np.mean(accs) - return loss_sum, acc_mean - - -def validate_model(net, dataset): - accs = [] - for _, data in enumerate(dataset.create_dict_iterator()): - train_x = Tensor(data['image'].asnumpy().astype(np.float32)) - label = Tensor(data['label'].asnumpy().astype(np.int32)) - output = net(train_x) - log_output = P.LogSoftmax(axis=1)(output) - acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) - accs.append(acc) - - acc_mean = np.mean(accs) - return acc_mean -``` - -### 变分推断 -#### 定义变分自编码器 -我们只需要自定义编码器和解码器,编码器和解码器都是神经网络。 - -``` -class Encoder(nn.Cell): - def __init__(self): - super(Encoder, self).__init__() - self.fc1 = nn.Dense(1024, 800) - self.fc2 = nn.Dense(800, 400) - self.relu = nn.ReLU() - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - return x - - -class Decoder(nn.Cell): - def __init__(self): - super(Decoder, self).__init__() - self.fc1 = nn.Dense(400, 1024) - self.sigmoid = nn.Sigmoid() - self.reshape = P.Reshape() - - def construct(self, z): - z = self.fc1(z) - z = self.reshape(z, IMAGE_SHAPE) - z = self.sigmoid(z) - return z - - -encoder = Encoder() -decoder = Decoder() -vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) -``` -### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用的损失函数是`ELBO`,`ELBO`是变分推断专用的损失函数;本例使用的优化器是`Adam`。 -MindSpore中定义损失函数和优化器的代码样例如下: - -``` -# loss function definition -net_loss = ELBO(latent_prior='Normal', output_prior='Normal') - -# optimization definition -optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) - -net_with_loss = nn.WithLossCell(vae, net_loss) -``` -#### 处理数据 -本例使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 - -#### 训练网络 -使用`SVI`接口对VAE网络进行训练。 - -``` -from mindspore.nn.probability.infer import SVI - -vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) -vae = vi.run(train_dataset=ds_train, epochs=10) -trained_loss = vi.get_train_loss() -``` -通过`vi.run`可以得到训练好的网络,使用`vi.get_train_loss`可以得到训练之后的损失。 -#### 生成新样本或重构输入样本 -利用训练好的VAE网络,我们可以生成新的样本或重构输入样本。 - -``` -IMAGE_SHAPE = (-1, 1, 32, 32) -generated_sample = vae.generate_sample(64, IMAGE_SHAPE) -for sample in ds_train.create_dict_iterator(): - sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) - reconstructed_sample = vae.reconstruct_sample(sample_x) -``` - -### DNN一键转换成BNN -对于不熟悉贝叶斯模型的DNN研究人员,MDP提供了高级API`TransformToBNN`,支持DNN模型一键转换成BNN模型。 -#### 定义DNN模型 -本例使用的DNN模型是LeNet。 - -``` -from mindspore.common.initializer import TruncatedNormal -import mindspore.nn as nn -import mindspore.ops.operations as P - -def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): - """weight initial for conv layer""" - weight = weight_variable() - return nn.Conv2d(in_channels, out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, - weight_init=weight, has_bias=False, pad_mode="valid") - - -def fc_with_initialize(input_channels, out_channels): - """weight initial for fc layer""" - weight = weight_variable() - bias = weight_variable() - return nn.Dense(input_channels, out_channels, weight, bias) - - -def weight_variable(): - """weight initial""" - return TruncatedNormal(0.02) - - -class LeNet5(nn.Cell): - """ - Lenet network - - Args: - num_class (int): Num classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> LeNet5(num_class=10) - - """ - def __init__(self, num_class=10): - super(LeNet5, self).__init__() - self.num_class = num_class - self.conv1 = conv(1, 6, 5) - self.conv2 = conv(6, 16, 5) - self.fc1 = fc_with_initialize(16 * 5 * 5, 120) - self.fc2 = fc_with_initialize(120, 84) - self.fc3 = fc_with_initialize(84, self.num_class) - self.relu = nn.ReLU() - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - self.reshape = P.Reshape() - - def construct(self, x): - x = self.conv1(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.relu(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.relu(x) - x = self.fc2(x) - x = self.relu(x) - x = self.fc3(x) - return x -``` -#### 定义损失函数和优化器 -接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,`Adam`作为优化器。 - -``` -network = LeNet5() - -# loss function definition -criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - -# optimization definition -optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) - -net_with_loss = WithLossCell(network, criterion) -train_network = TrainOneStepCell(net_with_loss, optimizer) -``` -#### 实例化TransformToBNN -`TransformToBNN`的`__init__`函数定义如下: - -``` -class TransformToBNN: - def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): - net_with_loss = trainable_dnn.network - self.optimizer = trainable_dnn.optimizer - self.backbone = net_with_loss.backbone_network - self.loss_fn = getattr(net_with_loss, "_loss_fn") - self.dnn_factor = dnn_factor - self.bnn_factor = bnn_factor - self.bnn_loss_file = None -``` -参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 -MindSpore中实例化`TransformToBNN`的代码如下: - -``` -from mindspore.nn.probability import transforms - -bnn_transformer = transforms.TransformToBNN(train_network, 60000, 0.000001) -``` -#### 功能一:转换整个模型 -`transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下: - -``` - def transform_to_bnn_model(self, - get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, - "out_channels": dp.out_channels, "activation": dp.activation}, - get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, - "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, - "stride": dp.stride, "has_bias": dp.has_bias, - "padding": dp.padding, "dilation": dp.dilation, - "group": dp.group}, - add_dense_args=None, - add_conv_args=None): - r""" - Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. - - Args: - get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: - {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. - get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: - {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, - "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. - add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. - add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. - - Returns: - Cell, a trainable BNN model wrapped by TrainOneStepCell. - """ -``` -参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 -在MindSpore中将整个DNN模型转换成BNN模型的代码如下: - -``` -train_bnn_network = bnn_transformer.transform_to_bnn_model() -``` -#### 功能二:转换指定类型的层 -`transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(nn.Dense或者nn.Conv2d)转换为对应的贝叶斯层。其定义如下: - -``` - def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): - r""" - Transform a specific type of layers in DNN model to corresponding BNN layer. - - Args: - dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are - nn.Dense, nn.Conv2d. - bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are - DenseReparameterization, ConvReparameterization. - get_args (dict): The arguments gotten from the DNN layer. Default: None. - add_args (dict): The new arguments added to BNN layer. Default: None. - - Returns: - Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. - """ -``` -参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 - -### 不确定性估计 -不确定性估计工具箱基于MindSpore Deep probability Programming (MDP),适用于主流的深度学习模型,如回归、分类、目标检测等。在推理阶段,利用不确定性估计工具箱,开发人员只需通过训练模型和训练数据集,指定需要估计的任务和样本,即可得到任意不确定性(aleatoric uncertainty)和认知不确定性(epistemic uncertainty)。基于不确定性信息,开发人员可以更好地理解模型和数据集。 -以分类任务为例,本例中使用的模型是LeNet,数据集为MNIST,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。为了评估测试示例的不确定性,使用工具箱的方法如下: - -``` -from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation -from mindspore.train.serialization import load_checkpoint, load_param_into_net - -network = LeNet5() -param_dict = load_checkpoint('checkpoint_lenet.ckpt') -load_param_into_net(network, param_dict) -# get train and eval dataset -ds_train = create_dataset('workspace/mnist/train') -ds_eval = create_dataset('workspace/mnist/test') -evaluation = UncertaintyEvaluation(model=network, - train_dataset=ds_train, - task_type='classification', - num_classes=10, - epochs=1, - epi_uncer_model_path=None, - ale_uncer_model_path=None, - save_model=False) -for eval_data in ds_eval.create_dict_iterator(): - eval_data = Tensor(eval_data['image'].asnumpy(), mstype.float32) - epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) - aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) -``` - - +# 深度概率编程 +`Ascend` `GPU` `全流程` `初级` `中级` `高级` + + + +- [深度概率编程](#深度概率编程) + - [概述](#概述) + - [使用贝叶斯神经网络](#使用贝叶斯神经网络) + - [处理数据集](#处理数据集) + - [定义贝叶斯神经网络](#定义贝叶斯神经网络) + - [定义损失函数和优化器](#定义损失函数和优化器) + - [训练网络](#训练网络) + - [使用变分自编码器](#使用变分自编码器) + - [定义变分自编码器](#定义变分自编码器) + - [定义损失函数和优化器](#定义损失函数和优化器-1) + - [处理数据](#处理数据) + - [训练网络](#训练网络-1) + - [生成新样本或重构输入样本](#生成新样本或重构输入样本) + - [DNN一键转换成BNN](#dnn一键转换成bnn) + - [定义DNN模型](#定义dnn模型) + - [定义损失函数和优化器](#定义损失函数和优化器-2) + - [实例化TransformToBNN](#实例化transformtobnn) + - [实现功能一:转换整个模型](#实现功能一转换整个模型) + - [实现功能二:转换指定类型的层](#实现功能二转换指定类型的层) + - [使用不确定性估计工具箱](#使用不确定性估计工具箱) + + + + + +## 概述 +深度学习模型具有强大的拟合能力,而贝叶斯理论具有很好的可解释能力。MindSpore深度概率编程(MindSpore Deep Probabilistic Programming, MDP)将深度学习和贝叶斯学习结合,通过设置网络权重为分布、引入隐空间分布等,可以对分布进行采样前向传播,由此引入了不确定性,从而增强了模型的鲁棒性和可解释性。MDP不仅包含通用、专业的概率学习编程语言,适用于“专业”用户,而且支持使用开发深度学习模型的逻辑进行概率编程,让初学者轻松上手;此外,还提供深度概率学习的工具箱,拓展贝叶斯应用功能。 + +本章将详细介绍深度概率编程在MindSpore上的应用。在动手进行实践之前,确保,你已经正确安装了MindSpore 0.7.0-beta及其以上版本。本章的具体内容如下: +1. 介绍如何使用[bnn_layers模块](https://gitee.com/mindspore/mindspore/tree/master/mindspore/nn/probability/bnn_layers)实现贝叶斯神经网(Bayesian Neural Network, BNN); +2. 介绍如何使用[variational模块](https://gitee.com/mindspore/mindspore/tree/master/mindspore/nn/probability/infer/variational)和[dpn模块](https://gitee.com/mindspore/mindspore/tree/master/mindspore/nn/probability/dpn)实现变分自编码器(Variational AutoEncoder, VAE); +3. 介绍如何使用[transforms模块](https://gitee.com/mindspore/mindspore/tree/master/mindspore/nn/probability/transforms)实现DNN(Deep Neural Network, DNN)一键转BNN; +4. 介绍如何使用[toolbox模块](https://gitee.com/mindspore/mindspore/tree/master/mindspore/nn/probability/toolbox/uncertainty_evaluation.py)实现不确定性估计。 + +## 使用贝叶斯神经网络 +贝叶斯神经网络是由概率模型和神经网络组成的基本模型,它的权重不再是一个确定的值,而是一个分布。本例介绍了如何使用MDP中的bnn_layers模块实现贝叶斯神经网络,并利用贝叶斯神经网络实现一个简单的图片分类功能,整体流程如下: +1. 处理MNIST数据集; +2. 定义贝叶斯LeNet网络; +3. 定义损失函数和优化器; +4. 加载数据集并进行训练。 + +> 本例面向GPU或Ascend 910 AI处理器平台,你可以在这里下载完整的样例代码: + +### 处理数据集 +本例子使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 + +### 定义贝叶斯神经网络 +本例使用的是Bayesian LeNet。利用bnn_layers模块构建贝叶斯神经网络的方法与构建普通的神经网络相同。值得注意的是,`bnn_layers`和普通的神经网络层可以互相组合。 + +``` +import mindspore.nn as nn +from mindspore.nn.probability import bnn_layers +import mindspore.ops.operations as P + +class BNNLeNet5(nn.Cell): + """ + bayesian Lenet network + + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + Examples: + >>> BNNLeNet5(num_class=10) + + """ + def __init__(self, num_class=10): + super(BNNLeNet5, self).__init__() + self.num_class = num_class + self.conv1 = bnn_layers.ConvReparam(1, 6, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") + self.conv2 = bnn_layers.ConvReparam(6, 16, 5, stride=1, padding=0, has_bias=False, pad_mode="valid") + self.fc1 = bnn_layers.DenseReparam(16 * 5 * 5, 120) + self.fc2 = bnn_layers.DenseReparam(120, 84) + self.fc3 = bnn_layers.DenseReparam(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` +### 定义损失函数和优化器 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。损失函数是深度学习的训练目标,也叫目标函数,可以理解为神经网络的输出(Logits)和标签(Labels)之间的距离,是一个标量数据。 + +常见的损失函数包括均方误差、L2损失、Hinge损失、交叉熵等等。图像分类应用通常采用交叉熵损失(CrossEntropy)。 + +优化器用于神经网络求解(训练)。由于神经网络参数规模庞大,无法直接求解,因而深度学习中采用随机梯度下降算法(SGD)及其改进算法进行求解。MindSpore封装了常见的优化器,如`SGD`、`Adam`、`Momemtum`等等。本例采用`Adam`优化器,通常需要设定两个参数,学习率(`learning_rate`)和权重衰减项(`weight_decay`)。 + +MindSpore中定义损失函数和优化器的代码样例如下: + +``` +# loss function definition +criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + +# optimization definition +optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) +``` + +### 训练网络 +贝叶斯神经网络的训练过程与DNN基本相同,唯一不同的是将`WithLossCell`替换为适用于BNN的`WithBNNLossCell`。除了`backbone`和`loss_fn`两个参数之外,`WithBNNLossCell`增加了`dnn_factor`和`bnn_factor`两个参数。`dnn_factor`是由损失函数计算得到的网络整体损失的系数,`bnn_factor`是每个贝叶斯层的KL散度的系数,这两个参数是用来平衡网络整体损失和贝叶斯层的KL散度的,防止KL散度的值过大掩盖了网络整体损失。 + +``` +net_with_loss = bnn_layers.WithBNNLossCell(network, criterion, dnn_factor=60000, bnn_factor=0.000001) +train_bnn_network = TrainOneStepCell(net_with_loss, optimizer) +train_bnn_network.set_train() + +train_set = create_dataset('./mnist_data/train', 64, 1) +test_set = create_dataset('./mnist_data/test', 64, 1) + +epoch = 10 + +for i in range(epoch): + train_loss, train_acc = train_model(train_bnn_network, network, train_set) + + valid_acc = validate_model(network, test_set) + + print('Epoch: {} \tTraining Loss: {:.4f} \tTraining Accuracy: {:.4f} \tvalidation Accuracy: {:.4f}'. + format(i, train_loss, train_acc, valid_acc)) +``` +其中,`train_model`和`validate_model`在MindSpore中的代码样例如下: + +``` +def train_model(train_net, net, dataset): + accs = [] + loss_sum = 0 + for _, data in enumerate(dataset.create_dict_iterator()): + train_x = Tensor(data['image'].asnumpy().astype(np.float32)) + label = Tensor(data['label'].asnumpy().astype(np.int32)) + loss = train_net(train_x, label) + output = net(train_x) + log_output = P.LogSoftmax(axis=1)(output) + acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) + accs.append(acc) + loss_sum += loss.asnumpy() + + loss_sum = loss_sum / len(accs) + acc_mean = np.mean(accs) + return loss_sum, acc_mean + + +def validate_model(net, dataset): + accs = [] + for _, data in enumerate(dataset.create_dict_iterator()): + train_x = Tensor(data['image'].asnumpy().astype(np.float32)) + label = Tensor(data['label'].asnumpy().astype(np.int32)) + output = net(train_x) + log_output = P.LogSoftmax(axis=1)(output) + acc = np.mean(log_output.asnumpy().argmax(axis=1) == label.asnumpy()) + accs.append(acc) + + acc_mean = np.mean(accs) + return acc_mean +``` + +## 使用变分自编码器 +接下来介绍如何使用MDP中的variational模块和dpn模块实现变分自编码器。变分自编码器是经典的应用了变分推断的深度概率模型,用来学习潜在变量的表示,通过该模型,不仅可以压缩输入数据,还可以生成该类型的新图像。本例的整体流程如下: +1. 定义变分自编码器; +2. 定义损失函数和优化器; +3. 处理数据; +4. 训练网络; +5. 生成新样本或重构输入样本。 +> 本例面向GPU或Ascend 910 AI处理器平台,你可以在这里下载完整的样例代码: +### 定义变分自编码器 +使用dpn模块来构造变分自编码器尤为简单,你只需要自定义编码器和解码器(DNN模型),调用`VAE`接口即可。 + +``` +class Encoder(nn.Cell): + def __init__(self): + super(Encoder, self).__init__() + self.fc1 = nn.Dense(1024, 800) + self.fc2 = nn.Dense(800, 400) + self.relu = nn.ReLU() + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + return x + + +class Decoder(nn.Cell): + def __init__(self): + super(Decoder, self).__init__() + self.fc1 = nn.Dense(400, 1024) + self.sigmoid = nn.Sigmoid() + self.reshape = P.Reshape() + + def construct(self, z): + z = self.fc1(z) + z = self.reshape(z, IMAGE_SHAPE) + z = self.sigmoid(z) + return z + + +encoder = Encoder() +decoder = Decoder() +vae = VAE(encoder, decoder, hidden_size=400, latent_size=20) +``` +### 定义损失函数和优化器 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用的损失函数是`ELBO`,`ELBO`是变分推断专用的损失函数;本例使用的优化器是`Adam`。 +MindSpore中定义损失函数和优化器的代码样例如下: + +``` +# loss function definition +net_loss = ELBO(latent_prior='Normal', output_prior='Normal') + +# optimization definition +optimizer = nn.Adam(params=vae.trainable_params(), learning_rate=0.001) + +net_with_loss = nn.WithLossCell(vae, net_loss) +``` +### 处理数据 +本例使用的是MNIST数据集,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。 + +### 训练网络 +使用variational模块中的`SVI`接口对VAE网络进行训练。 + +``` +from mindspore.nn.probability.infer import SVI + +vi = SVI(net_with_loss=net_with_loss, optimizer=optimizer) +vae = vi.run(train_dataset=ds_train, epochs=10) +trained_loss = vi.get_train_loss() +``` +通过`vi.run`可以得到训练好的网络,使用`vi.get_train_loss`可以得到训练之后的损失。 +### 生成新样本或重构输入样本 +利用训练好的VAE网络,我们可以生成新的样本或重构输入样本。 + +``` +IMAGE_SHAPE = (-1, 1, 32, 32) +generated_sample = vae.generate_sample(64, IMAGE_SHAPE) +for sample in ds_train.create_dict_iterator(): + sample_x = Tensor(sample['image'].asnumpy(), dtype=mstype.float32) + reconstructed_sample = vae.reconstruct_sample(sample_x) +``` + +## DNN一键转换成BNN +对于不熟悉贝叶斯模型的DNN研究人员,MDP提供了高级API`TransformToBNN`,支持DNN模型一键转换成BNN模型。目前在LeNet,ResNet,MobileNet,VGG等模型上验证了API的通用性。本例将会介绍如何使用transforms模块中的`TransformToBNN`API实现DNN一键转换成BNN,整体流程如下: +1. 定义DNN模型; +2. 定义损失函数和优化器; +3. 实现功能一:转换整个模型; +4. 实现功能二:转换指定类型的层。 +> 本例面向GPU或Ascend 910 AI处理器平台,你可以在这里下载完整的样例代码: +### 定义DNN模型 +本例使用的DNN模型是LeNet。 + +``` +from mindspore.common.initializer import TruncatedNormal +import mindspore.nn as nn +import mindspore.ops.operations as P + +def conv(in_channels, out_channels, kernel_size, stride=1, padding=0): + """weight initial for conv layer""" + weight = weight_variable() + return nn.Conv2d(in_channels, out_channels, + kernel_size=kernel_size, stride=stride, padding=padding, + weight_init=weight, has_bias=False, pad_mode="valid") + + +def fc_with_initialize(input_channels, out_channels): + """weight initial for fc layer""" + weight = weight_variable() + bias = weight_variable() + return nn.Dense(input_channels, out_channels, weight, bias) + + +def weight_variable(): + """weight initial""" + return TruncatedNormal(0.02) + + +class LeNet5(nn.Cell): + """ + Lenet network + + Args: + num_class (int): Num classes. Default: 10. + + Returns: + Tensor, output tensor + Examples: + >>> LeNet5(num_class=10) + + """ + def __init__(self, num_class=10): + super(LeNet5, self).__init__() + self.num_class = num_class + self.conv1 = conv(1, 6, 5) + self.conv2 = conv(6, 16, 5) + self.fc1 = fc_with_initialize(16 * 5 * 5, 120) + self.fc2 = fc_with_initialize(120, 84) + self.fc3 = fc_with_initialize(84, self.num_class) + self.relu = nn.ReLU() + self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) + self.flatten = nn.Flatten() + self.reshape = P.Reshape() + + def construct(self, x): + x = self.conv1(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.conv2(x) + x = self.relu(x) + x = self.max_pool2d(x) + x = self.flatten(x) + x = self.fc1(x) + x = self.relu(x) + x = self.fc2(x) + x = self.relu(x) + x = self.fc3(x) + return x +``` +LeNet的网络结构如下: + +``` +LeNet5 + (conv1) Conv2dinput_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (conv2) Conv2dinput_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (fc1) Densein_channels=400, out_channels=120, weight=Parameter (name=fc1.weight), has_bias=True, bias=Parameter (name=fc1.bias) + (fc2) Densein_channels=120, out_channels=84, weight=Parameter (name=fc2.weight), has_bias=True, bias=Parameter (name=fc2.bias) + (fc3) Densein_channels=84, out_channels=10, weight=Parameter (name=fc3.weight), has_bias=True, bias=Parameter (name=fc3.bias) + (relu) ReLU + (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID + (flatten) Flatten +``` + +### 定义损失函数和优化器 +接下来需要定义损失函数(Loss)和优化器(Optimizer)。本例使用交叉熵损失作为损失函数,`Adam`作为优化器。 + +``` +network = LeNet5() + +# loss function definition +criterion = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") + +# optimization definition +optimizer = AdamWeightDecay(params=network.trainable_params(), learning_rate=0.0001) + +net_with_loss = WithLossCell(network, criterion) +train_network = TrainOneStepCell(net_with_loss, optimizer) +``` +### 实例化TransformToBNN +`TransformToBNN`的`__init__`函数定义如下: + +``` +class TransformToBNN: + def __init__(self, trainable_dnn, dnn_factor=1, bnn_factor=1): + net_with_loss = trainable_dnn.network + self.optimizer = trainable_dnn.optimizer + self.backbone = net_with_loss.backbone_network + self.loss_fn = getattr(net_with_loss, "_loss_fn") + self.dnn_factor = dnn_factor + self.bnn_factor = bnn_factor + self.bnn_loss_file = None +``` +参数`trainable_bnn`是经过`TrainOneStepCell`包装的可训练DNN模型,`dnn_factor`和`bnn_factor`分别为由损失函数计算得到的网络整体损失的系数和每个贝叶斯层的KL散度的系数。 +MindSpore中实例化`TransformToBNN`的代码如下: + +``` +from mindspore.nn.probability import transforms + +bnn_transformer = transforms.TransformToBNN(train_network, 60000, 0.000001) +``` +### 实现功能一:转换整个模型 +`transform_to_bnn_model`方法可以将整个DNN模型转换为BNN模型。其定义如下: + +``` + def transform_to_bnn_model(self, + get_dense_args=lambda dp: {"in_channels": dp.in_channels, "has_bias": dp.has_bias, + "out_channels": dp.out_channels, "activation": dp.activation}, + get_conv_args=lambda dp: {"in_channels": dp.in_channels, "out_channels": dp.out_channels, + "pad_mode": dp.pad_mode, "kernel_size": dp.kernel_size, + "stride": dp.stride, "has_bias": dp.has_bias, + "padding": dp.padding, "dilation": dp.dilation, + "group": dp.group}, + add_dense_args=None, + add_conv_args=None): + r""" + Transform the whole DNN model to BNN model, and wrap BNN model by TrainOneStepCell. + + Args: + get_dense_args (function): The arguments gotten from the DNN full connection layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "has_bias": dp.has_bias}. + get_conv_args (function): The arguments gotten from the DNN convolutional layer. Default: lambda dp: + {"in_channels": dp.in_channels, "out_channels": dp.out_channels, "pad_mode": dp.pad_mode, + "kernel_size": dp.kernel_size, "stride": dp.stride, "has_bias": dp.has_bias}. + add_dense_args (dict): The new arguments added to BNN full connection layer. Default: {}. + add_conv_args (dict): The new arguments added to BNN convolutional layer. Default: {}. + + Returns: + Cell, a trainable BNN model wrapped by TrainOneStepCell. + """ +``` +参数`get_dense_args`指定从DNN模型的全连接层中获取哪些参数,`get_conv_args`指定从DNN模型的卷积层中获取哪些参数,参数`add_dense_args`和`add_conv_args`分别指定了要为BNN层指定哪些新的参数值。需要注意的是,`add_dense_args`中的参数不能与`get_dense_args`重复,`add_conv_args`和`get_conv_args`也是如此。 + +在MindSpore中将整个DNN模型转换成BNN模型的代码如下: + +``` +train_bnn_network = bnn_transformer.transform_to_bnn_model() +``` +整个模型转换后的结构如下: + +``` +LeNet5 + (conv1) ConvReparam + in_channels=1, out_channels=6, kernel_size=(5, 5), stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, weight_mean=Parameter (name=conv1.weight_posterior.mean), weight_std=Parameter (name=conv1.weight_posterior.untransformed_std), has_bias=False + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (conv2) ConvReparam + in_channels=6, out_channels=16, kernel_size=(5, 5), stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, weight_mean=Parameter (name=conv2.weight_posterior.mean), weight_std=Parameter (name=conv2.weight_posterior.untransformed_std), has_bias=False + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc1) DenseReparam + in_channels=400, out_channels=120, weight_mean=Parameter (name=fc1.weight_posterior.mean), weight_std=Parameter (name=fc1.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc1.bias_posterior.mean), bias_std=Parameter (name=fc1.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc2) DenseReparam + in_channels=120, out_channels=84, weight_mean=Parameter (name=fc2.weight_posterior.mean), weight_std=Parameter (name=fc2.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc2.bias_posterior.mean), bias_std=Parameter (name=fc2.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc3) DenseReparam + in_channels=84, out_channels=10, weight_mean=Parameter (name=fc3.weight_posterior.mean), weight_std=Parameter (name=fc3.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc3.bias_posterior.mean), bias_std=Parameter (name=fc3.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (relu) ReLU + (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID + (flatten) Flatten +``` +可以看到,整个LeNet网络中的卷积层和全连接层都转变成了相应的贝叶斯层。 + +### 实现功能二:转换指定类型的层 +`transform_to_bnn_layer`方法可以将DNN模型中指定类型的层(nn.Dense或者nn.Conv2d)转换为对应的贝叶斯层。其定义如下: + +``` + def transform_to_bnn_layer(self, dnn_layer, bnn_layer, get_args=None, add_args=None): + r""" + Transform a specific type of layers in DNN model to corresponding BNN layer. + + Args: + dnn_layer_type (Cell): The type of DNN layer to be transformed to BNN layer. The optional values are + nn.Dense, nn.Conv2d. + bnn_layer_type (Cell): The type of BNN layer to be transformed to. The optional values are + DenseReparameterization, ConvReparameterization. + get_args (dict): The arguments gotten from the DNN layer. Default: None. + add_args (dict): The new arguments added to BNN layer. Default: None. + + Returns: + Cell, a trainable model wrapped by TrainOneStepCell, whose sprcific type of layer is transformed to the corresponding bayesian layer. + """ +``` +参数`dnn_layer`指定将哪个类型的DNN层转换成BNN层,`bnn_layer`指定DNN层将转换成哪个类型的BNN层,`get_args`和`add_args`分别指定从DNN层中获取哪些参数和要为BNN层的哪些参数重新赋值。 + +在MindSpore中将DNN模型中的Dense层转换成相应贝叶斯层`DenseReparam`的代码如下: + +``` +train_bnn_network = bnn_transformer.transform_to_bnn_layer(nn.Dense, bnn_layers.DenseReparam) +``` +转换后网络的结构如下: + +``` +LeNet5 + (conv1) Conv2dinput_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (conv2) Conv2dinput_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1), pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False + (fc1) DenseReparam + in_channels=400, out_channels=120, weight_mean=Parameter (name=fc1.weight_posterior.mean), weight_std=Parameter (name=fc1.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc1.bias_posterior.mean), bias_std=Parameter (name=fc1.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc2) DenseReparam + in_channels=120, out_channels=84, weight_mean=Parameter (name=fc2.weight_posterior.mean), weight_std=Parameter (name=fc2.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc2.bias_posterior.mean), bias_std=Parameter (name=fc2.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (fc3) DenseReparam + in_channels=84, out_channels=10, weight_mean=Parameter (name=fc3.weight_posterior.mean), weight_std=Parameter (name=fc3.weight_posterior.untransformed_std), has_bias=True, bias_mean=Parameter (name=fc3.bias_posterior.mean), bias_std=Parameter (name=fc3.bias_posterior.untransformed_std) + (weight_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (weight_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + (bias_prior) NormalPrior + (normal) Normalmean = 0.0, standard deviation = 0.1 + + (bias_posterior) NormalPosterior + (normal) Normalbatch_shape = None + + + (relu) ReLU + (max_pool2d) MaxPool2dkernel_size=2, stride=2, pad_mode=VALID + (flatten) Flatten +``` +可以看到,LeNet网络中的卷积层保持不变,全连接层变成了对应的贝叶斯层`DenseReparam`。 + +## 使用不确定性估计工具箱 +贝叶斯神经网络的优势之一就是可以获取不确定性,MDP在上层提供了不确定性估计的工具箱,用户可以很方便地使用该工具箱计算不确定性。不确定性意味着深度学习模型对预测结果的不确定程度。目前,大多数深度学习算法只能给出预测结果,而不能判断预测结果的可靠性。不确定性主要有两种类型:偶然不确定性和认知不确定性。 +- 偶然不确定性(Aleatoric Uncertainty):描述数据中的内在噪声,即无法避免的误差,这个现象不能通过增加采样数据来削弱。 +- 认知不确定性(Epistemic Uncertainty):模型自身对输入数据的估计可能因为训练不佳、训练数据不够等原因而不准确,可以通过增加训练数据等方式来缓解。 + +不确定性估计工具箱,适用于主流的深度学习模型,如回归、分类等。在推理阶段,利用不确定性估计工具箱,开发人员只需通过训练模型和训练数据集,指定需要估计的任务和样本,即可得到任意不确定性和认知不确定性。基于不确定性信息,开发人员可以更好地理解模型和数据集。 +> 本例面向GPU或Ascend 910 AI处理器平台,你可以在这里下载完整的样例代码: + +以分类任务为例,本例中使用的模型是LeNet,数据集为MNIST,数据处理过程与教程中的[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)一致。为了评估测试示例的不确定性,使用工具箱的方法如下: + +``` +from mindspore.nn.probability.toolbox.uncertainty_evaluation import UncertaintyEvaluation +from mindspore.train.serialization import load_checkpoint, load_param_into_net + +network = LeNet5() +param_dict = load_checkpoint('checkpoint_lenet.ckpt') +load_param_into_net(network, param_dict) +# get train and eval dataset +ds_train = create_dataset('workspace/mnist/train') +ds_eval = create_dataset('workspace/mnist/test') +evaluation = UncertaintyEvaluation(model=network, + train_dataset=ds_train, + task_type='classification', + num_classes=10, + epochs=1, + epi_uncer_model_path=None, + ale_uncer_model_path=None, + save_model=False) +for eval_data in ds_eval.create_dict_iterator(): + eval_data = Tensor(eval_data['image'].asnumpy(), mstype.float32) + epistemic_uncertainty = evaluation.eval_epistemic_uncertainty(eval_data) + aleatoric_uncertainty = evaluation.eval_aleatoric_uncertainty(eval_data) +``` + -- Gitee From 7345d2aea85d4ce6a4138edbfdc9182f50476c95 Mon Sep 17 00:00:00 2001 From: hangq Date: Fri, 18 Sep 2020 14:41:38 +0800 Subject: [PATCH 082/100] add python requirements in build.md --- tutorials/lite/source_en/use/build.md | 1 + tutorials/lite/source_zh_cn/use/build.md | 1 + 2 files changed, 2 insertions(+) diff --git a/tutorials/lite/source_en/use/build.md b/tutorials/lite/source_en/use/build.md index 12a746acd3..c17ddc704b 100644 --- a/tutorials/lite/source_en/use/build.md +++ b/tutorials/lite/source_en/use/build.md @@ -50,6 +50,7 @@ This chapter introduces how to quickly compile MindSpore Lite, which includes th - [Libevent](https://libevent.org) >= 2.0 - [M4](https://www.gnu.org/software/m4/m4.html) >= 1.4.18 - [OpenSSL](https://www.openssl.org/) >= 1.1.1 + - [Python](https://www.python.org/) >= 3.7.5 > - To install and use `Android_NDK`, you need to configure environment variables. The command example is `export ANDROID_NDK={$NDK_PATH}/android-ndk-r20b`. > - In the `build.sh` script, run the `git clone` command to obtain the code in the third-party dependency library. Ensure that the network settings of Git are correct. diff --git a/tutorials/lite/source_zh_cn/use/build.md b/tutorials/lite/source_zh_cn/use/build.md index 19d5457427..023387f756 100644 --- a/tutorials/lite/source_zh_cn/use/build.md +++ b/tutorials/lite/source_zh_cn/use/build.md @@ -50,6 +50,7 @@ - [Libevent](https://libevent.org) >= 2.0 - [M4](https://www.gnu.org/software/m4/m4.html) >= 1.4.18 - [OpenSSL](https://www.openssl.org/) >= 1.1.1 + - [Python](https://www.python.org/) >= 3.7.5 > - 当安装完依赖项Android_NDK后,需配置环境变量:`export ANDROID_NDK={$NDK_PATH}/android-ndk-r20b`。 > - 编译脚本中会执行`git clone`获取第三方依赖库的代码,请提前确保git的网络设置正确可用。 -- Gitee From 801de21a942e4acadecb422252a091b968a206e9 Mon Sep 17 00:00:00 2001 From: huzhifeng Date: Fri, 18 Sep 2020 11:49:28 +0800 Subject: [PATCH 083/100] modify hub tutorial for mindspore 1.0 interface --- .../source_en/advanced_use/hub_tutorial.md | 134 +++++++++++------- .../source_zh_cn/advanced_use/hub_tutorial.md | 99 ++++++++----- 2 files changed, 151 insertions(+), 82 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/hub_tutorial.md b/tutorials/training/source_en/advanced_use/hub_tutorial.md index cbee7aced7..d39f6fa8ea 100644 --- a/tutorials/training/source_en/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_en/advanced_use/hub_tutorial.md @@ -91,30 +91,29 @@ Once your PR is merged into master branch here, your model will show up in [Mind - 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)) -``` + ```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 + import mindspore.dataset.vision.py_transforms as py_transforms + + context.set_context(mode=context.GRAPH_MODE, + device_target="Ascend", + device_id=0) + + model = "mindspore/ascend/0.7/googlenet_v1_cifar10" + + # Initialize the number of classes based on the pre-trained model. + network = mshub.load(model, num_classes=10) + network.set_train(False) + + # ... + + ``` +- After loading the model, you can use MindSpore to do inference. You can refer to [here](https://www.mindspore.cn/tutorial/en/master/use/multi_platform_inference.html). ### Model Fine-tuning @@ -128,56 +127,83 @@ We use GoogleNet as example to illustrate how to load a model trained on ImageNe ```python import mindspore - from mindspore import context + from mindspore import nn, context, Tensor + from mindpsore.train.serialization import save_checkpoint + from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits + from mindspore.ops import operations as P + from mindspore.nn import Momentum + + import math + import numpy as np + import mindspore_hub as mshub + from src.dataset import create_dataset 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) + model_url = "mindspore/ascend/0.7/googlenet_v1_cifar10" + network = mshub.load(model_url, include_top=False, num_classes=1000) network.set_train(False) ``` 3. Add a new classification layer into current model architecture. ```python - from mindspore import nn - + class ReduceMeanFlatten(nn.Cell): + def __init__(self): + super(ReduceMeanFlatten, self).__init__() + self.mean = P.ReduceMean(keep_dims=True) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.mean(x, (2, 3)) + x = self.flatten(x) + return x + # 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 + + reducemean_flatten = ReduceMeanFlatten() + classification_layer = nn.Dense(last_channel, num_classes) classification_layer.set_train(True) - train_network = nn.SequentialCell([network, classification_layer]) + train_network = nn.SequentialCell([network, reducemean_flatten, classification_layer]) ``` 4. Define `loss` and `optimizer` for training. ```python - from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits + epoch_size = 60 # Wrap the backbone network with loss. - loss_fn = SoftmaxCrossEntropyWithLogits() + loss_fn = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") 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) + lr = get_lr(global_step=0, + lr_init=0, + lr_max=0.05, + lr_end=0.001, + warmup_epochs=5, + total_epochs=epoch_size) + # Create an optimizer. + optim = Momentum(filter(lambda x: x.requires_grad, loss_net.get_parameters()), Tensor(lr), 0.9, 4e-5) train_net = nn.TrainOneStepCell(loss_net, optim) ``` 5. Create dataset and start fine-tuning. As is shown below, the new dataset used for fine-tuning is the garbage classification data located at `/ssd/data/garbage/train` folder. ```python - from src.dataset import create_dataset - from mindspore.train.serialization import save_checkpoint - - dataset = create_dataset("/ssd/data/garbage/train", do_train=True, batch_size=32) - - epoch_size = 15 + dataset = create_dataset("/ssd/data/garbage/train", + do_train=True, + batch_size=32, + platform="Ascend", + repeat_num=1) + for epoch in range(epoch_size): for i, items in enumerate(dataset): data, label = items @@ -185,7 +211,7 @@ We use GoogleNet as example to illustrate how to load a model trained on ImageNe label = mindspore.Tensor(label) loss = train_net(data, label) - print(f"epoch: {epoch}, loss: {loss}") + print(f"epoch: {epoch}/{epoch_size}, loss: {loss}") # Save the ckpt file for each epoch. ckpt_path = f"./ckpt/garbage_finetune_epoch{epoch}.ckpt" save_checkpoint(train_network, ckpt_path) @@ -196,20 +222,30 @@ We use GoogleNet as example to illustrate how to load a model trained on ImageNe ```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)]) + network = mshub.load('mindspore/ascend/0.7/googlenet_v1_cifar10', pretrained=False, + include_top=False, num_classes=1000) + + reducemean_flatten = ReduceMeanFlatten() + + classification_layer = nn.Dense(last_channel, num_classes) + classification_layer.set_train(False) + softmax = nn.Softmax() + network = nn.SequentialCell([network, reducemean_flatten, + classification_layer, softmax]) # Load a pre-trained ckpt file. - ckpt_path = "./ckpt/garbage_finetune_epoch15.ckpt" + ckpt_path = "./ckpt/garbage_finetune_epoch59.ckpt" trained_ckpt = load_checkpoint(ckpt_path) - load_param_into_net(train_network, trained_ckpt) + load_param_into_net(network, trained_ckpt) # Define loss and create model. - loss = SoftmaxCrossEntropyWithLogits() - model = Model(network, loss_fn=loss, metrics={'acc'}) + model = Model(network, metrics={'acc'}, eval_network=network) - eval_dataset = create_dataset("/ssd/data/garbage/train", do_train=False, - batch_size=32) + eval_dataset = create_dataset("/ssd/data/garbage/test", + do_train=True, + batch_size=32, + platform="Ascend", + repeat_num=1) res = model.eval(eval_dataset) print("result:", res, "ckpt=", ckpt_path) diff --git a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md index 65744ed3fc..e30eabc78d 100644 --- a/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md +++ b/tutorials/training/source_zh_cn/advanced_use/hub_tutorial.md @@ -97,9 +97,6 @@ MindSpore Hub是MindSpore生态的预训练模型应用工具,作为模型开 from mindspore import context, Tensor, nn from mindspore.train.model import Model from mindspore.common import dtype as mstype - from mindspore.dataset.transforms.py_transforms import Compose - from PIL import Image - import cv2 import mindspore.dataset.vision.py_transforms as py_transforms context.set_context(mode=context.GRAPH_MODE, @@ -108,16 +105,14 @@ MindSpore Hub是MindSpore生态的预训练模型应用工具,作为模型开 model = "mindspore/ascend/0.7/googlenet_v1_cifar10" - # Test an image from CIFAR-10 dataset - image = Image.open('cifar10/a.jpg') - transforms = Compose([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进行推理,参考[这里](https://www.mindspore.cn/tutorial/zh-CN/master/use/multi_platform_inference.html)。 ### 模型微调 在使用 `mindspore_hub.load` 进行模型加载时,可以增加一个额外的参数项只加载神经网络的特征提取部分。这样我们就能很容易地在之后增加一些新的层进行迁移学习。*当模型开发者将额外的参数(例如 include_top)添加到模型构造中时,可以在模型的详情页中找到这个功能。`include_top` 取值为True或者False,表示是否保留顶层的全连接网络。* @@ -130,55 +125,83 @@ MindSpore Hub是MindSpore生态的预训练模型应用工具,作为模型开 ```python import mindspore - from mindspore import context + from mindspore import nn, context, Tensor + from mindpsore.train.serialization import save_checkpoint + from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits + from mindspore.ops import operations as P + from mindspore.nn import Momentum + + import math + import numpy as np + import mindspore_hub as mshub + from src.dataset import create_dataset 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) + model_url = "mindspore/ascend/0.7/googlenet_v1_cifar10" + network = mshub.load(model_url, include_top=False, num_classes=1000) network.set_train(False) ``` 3. 在现有模型结构基础上增加一个与新任务相关的分类层。 ```python - from mindspore import nn - + class ReduceMeanFlatten(nn.Cell): + def __init__(self): + super(ReduceMeanFlatten, self).__init__() + self.mean = P.ReduceMean(keep_dims=True) + self.flatten = nn.Flatten() + + def construct(self, x): + x = self.mean(x, (2, 3)) + x = self.flatten(x) + return x + # 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 + + reducemean_flatten = ReduceMeanFlatten() + classification_layer = nn.Dense(last_channel, num_classes) classification_layer.set_train(True) - train_network = nn.SequentialCell([network, classification_layer]) + train_network = nn.SequentialCell([network, reducemean_flatten, classification_layer]) ``` 4. 为模型训练选择损失函数和优化器。 ```python - from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits + epoch_size = 60 # Wrap the backbone network with loss. - loss_fn = SoftmaxCrossEntropyWithLogits() + loss_fn = SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") loss_net = nn.WithLossCell(train_network, loss_fn) + lr = get_lr(global_step=0, + lr_init=0, + lr_max=0.05, + lr_end=0.001, + warmup_epochs=5, + total_epochs=epoch_size) + # Create an optimizer. - optim = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), Tensor(lr), config.momentum, config.weight_decay) + optim = Momentum(filter(lambda x: x.requires_grad, loss_net.get_parameters()), Tensor(lr), 0.9, 4e-5) train_net = nn.TrainOneStepCell(loss_net, optim) ``` 5. 构建数据集,开始重训练。如下所示,进行微调任务的数据集为垃圾分类数据集,存储位置为 `/ssd/data/garbage/train`。 ```python - from src.dataset import create_dataset - from mindspore.train.serialization import save_checkpoint - - dataset = create_dataset("/ssd/data/garbage/train", do_train=True, batch_size=32) - - epoch_size = 15 + dataset = create_dataset("/ssd/data/garbage/train", + do_train=True, + batch_size=32, + platform="Ascend", + repeat_num=1) + for epoch in range(epoch_size): for i, items in enumerate(dataset): data, label = items @@ -186,7 +209,7 @@ MindSpore Hub是MindSpore生态的预训练模型应用工具,作为模型开 label = mindspore.Tensor(label) loss = train_net(data, label) - print(f"epoch: {epoch}, loss: {loss}") + print(f"epoch: {epoch}/{epoch_size}, loss: {loss}") # Save the ckpt file for each epoch. ckpt_path = f"./ckpt/garbage_finetune_epoch{epoch}.ckpt" save_checkpoint(train_network, ckpt_path) @@ -197,20 +220,30 @@ MindSpore Hub是MindSpore生态的预训练模型应用工具,作为模型开 ```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)]) + network = mshub.load('mindspore/ascend/0.7/googlenet_v1_cifar10', pretrained=False, + include_top=False, num_classes=1000) + + reducemean_flatten = ReduceMeanFlatten() + + classification_layer = nn.Dense(last_channel, num_classes) + classification_layer.set_train(False) + softmax = nn.Softmax() + network = nn.SequentialCell([network, reducemean_flatten, + classification_layer, softmax]) # Load a pre-trained ckpt file. - ckpt_path = "./ckpt/garbage_finetune_epoch15.ckpt" + ckpt_path = "./ckpt/garbage_finetune_epoch59.ckpt" trained_ckpt = load_checkpoint(ckpt_path) - load_param_into_net(train_network, trained_ckpt) + load_param_into_net(network, trained_ckpt) # Define loss and create model. - loss_fn = SoftmaxCrossEntropyWithLogits() - model = Model(network, loss_fn=loss, metrics={'acc'}) + model = Model(network, metrics={'acc'}, eval_network=network) - eval_dataset = create_dataset("/ssd/data/garbage/train", do_train=False, - batch_size=32) + eval_dataset = create_dataset("/ssd/data/garbage/test", + do_train=True, + batch_size=32, + platform="Ascend", + repeat_num=1) res = model.eval(eval_dataset) print("result:", res, "ckpt=", ckpt_path) -- Gitee From 6da45876e470863fda085b8461a3b025edd3aa94 Mon Sep 17 00:00:00 2001 From: hukang hwx963878 Date: Fri, 18 Sep 2020 14:52:39 +0800 Subject: [PATCH 084/100] fix SDK to NDK on quick_start on branch r1.0 --- tutorials/lite/source_en/quick_start/quick_start.md | 2 +- tutorials/lite/source_zh_cn/quick_start/quick_start.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/lite/source_en/quick_start/quick_start.md b/tutorials/lite/source_en/quick_start/quick_start.md index 7e2f918c11..ddc735dc55 100644 --- a/tutorials/lite/source_en/quick_start/quick_start.md +++ b/tutorials/lite/source_en/quick_start/quick_start.md @@ -68,7 +68,7 @@ The following section describes how to build and execute an on-device image clas ![start_sdk](../images/lite_quick_start_sdk.png) - (Optional) If an NDK version issue occurs during the installation, manually download the corresponding [NDK version](https://developer.android.com/ndk/downloads) (the version used in the sample code is 21.3). Specify the SDK location in `Android NDK location` of `Project Structure`. + (Optional) If an NDK version issue occurs during the installation, manually download the corresponding [NDK version](https://developer.android.com/ndk/downloads) (the version used in the sample code is 21.3). Specify the NDK location in `Android NDK location` of `Project Structure`. ![project_structure](../images/lite_quick_start_project_structure.png) diff --git a/tutorials/lite/source_zh_cn/quick_start/quick_start.md b/tutorials/lite/source_zh_cn/quick_start/quick_start.md index 933bb46528..6efa228c07 100644 --- a/tutorials/lite/source_zh_cn/quick_start/quick_start.md +++ b/tutorials/lite/source_zh_cn/quick_start/quick_start.md @@ -67,7 +67,7 @@ MindSpore Model Zoo中图像分类模型可[在此下载](https://download.minds ![start_sdk](../images/lite_quick_start_sdk.png) - (可选)若安装时出现NDK版本问题,可手动下载相应的[NDK版本](https://developer.android.com/ndk/downloads?hl=zh-cn)(本示例代码使用的NDK版本为21.3),并在`Project Structure`的`Android NDK location`设置中指定SDK的位置。 + (可选)若安装时出现NDK版本问题,可手动下载相应的[NDK版本](https://developer.android.com/ndk/downloads?hl=zh-cn)(本示例代码使用的NDK版本为21.3),并在`Project Structure`的`Android NDK location`设置中指定NDK的位置。 ![project_structure](../images/lite_quick_start_project_structure.png) -- Gitee From beb2176a0b5c3f4fd3f67e53ae6b3bdecc089add Mon Sep 17 00:00:00 2001 From: bingyaweng Date: Fri, 18 Sep 2020 15:00:59 +0800 Subject: [PATCH 085/100] modify tutorial of mdp --- .../advanced_use/apply_deep_probability_programming.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md index e819dd8d7d..c477860fb8 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_deep_probability_programming.md @@ -26,7 +26,7 @@ - + ## 概述 深度学习模型具有强大的拟合能力,而贝叶斯理论具有很好的可解释能力。MindSpore深度概率编程(MindSpore Deep Probabilistic Programming, MDP)将深度学习和贝叶斯学习结合,通过设置网络权重为分布、引入隐空间分布等,可以对分布进行采样前向传播,由此引入了不确定性,从而增强了模型的鲁棒性和可解释性。MDP不仅包含通用、专业的概率学习编程语言,适用于“专业”用户,而且支持使用开发深度学习模型的逻辑进行概率编程,让初学者轻松上手;此外,还提供深度概率学习的工具箱,拓展贝叶斯应用功能。 -- Gitee From 1de4ba440d26b52905924d1a416d13cde04a0e39 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Fri, 18 Sep 2020 14:48:23 +0800 Subject: [PATCH 086/100] Fix the link for markdown --- .../data_loading_enhance/data_loading_enhancement.ipynb | 2 +- tutorials/notebook/debugging_in_pynative_mode.ipynb | 4 ++-- tutorials/notebook/linear_regression.ipynb | 2 +- tutorials/notebook/loading_dataset.ipynb | 4 ++-- .../notebook/mindinsight/calculate_and_datagraphic.ipynb | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb index 6733e3aa75..74b75c2337 100644 --- a/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb +++ b/tutorials/notebook/data_loading_enhance/data_loading_enhancement.ipynb @@ -439,7 +439,7 @@ "source": [ "2. 使用一类图片当作数据,体验操作。在一个数据量比较大的图片数据集中,例如数据集名称叫`images`,它的存储方式是在`images`文件夹下,有不同子类别的文件夹,一个子类别文件夹中的图片属于同一类。所以我们本次体验所使用的图片放置方法,就需要创建`enhance_images`文件夹,接着在`enhance_images`下建一个名为`sample`的子类别文件夹,将图片放在`sample`文件夹中即可。如果有更多类别图片,可以在`enhance_images`下创建对应的子类别文件夹,将图片放入即可。\n", "\n", - " 增强体验使用的数据位置在中,使用过程中可以在此路径下找到图片数据,并参照本次体验中图片放置的位置来新建文件夹。" + " 增强体验使用的数据位置在中,使用过程中可以在此路径下找到图片数据,并参照本次体验中图片放置的位置来新建文件夹。" ] }, { diff --git a/tutorials/notebook/debugging_in_pynative_mode.ipynb b/tutorials/notebook/debugging_in_pynative_mode.ipynb index 1e93c5bcc4..1ab9f2cec4 100644 --- a/tutorials/notebook/debugging_in_pynative_mode.ipynb +++ b/tutorials/notebook/debugging_in_pynative_mode.ipynb @@ -34,7 +34,7 @@ "\n", "4. 执行神经网络训练,查看网络各参数梯度。\n", "\n", - "> 你可以在这里找到完整可运行的样例代码:。" + "> 你可以在这里找到完整可运行的样例代码:。" ] }, { @@ -55,7 +55,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "这里我们需要将MNIST数据集中随机取出一张图片,并增强成适合LeNet网络的数据格式(如何处理请参考[quick_start.ipynb](https://gitee.com/mindspore/docs/blob/master/tutorials/notebook/quick_start.ipynb)),训练数据集下载地址:{\"\", \"\"} 。\n", + "这里我们需要将MNIST数据集中随机取出一张图片,并增强成适合LeNet网络的数据格式(如何处理请参考[quick_start.ipynb](https://gitee.com/mindspore/docs/blob/r1.0/tutorials/notebook/quick_start.ipynb)),训练数据集下载地址:{\"\", \"\"} 。\n", "
      数据集放在----Jupyter工作目录+\\MNIST_Data\\train\\,如下图结构:" ] }, diff --git a/tutorials/notebook/linear_regression.ipynb b/tutorials/notebook/linear_regression.ipynb index 25008ff1e3..e50ef977e5 100644 --- a/tutorials/notebook/linear_regression.ipynb +++ b/tutorials/notebook/linear_regression.ipynb @@ -504,7 +504,7 @@ "source": [ "### 定义回调函数\n", "\n", - "MindSpore提供的工具,可对模型训练过程进行自定义控制,这里在`step_end`中调用可视化函数,展示拟合过程。更多的使用可参考[官网说明](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/customized_debugging_information.html#callback)\n", + "MindSpore提供的工具,可对模型训练过程进行自定义控制,这里在`step_end`中调用可视化函数,展示拟合过程。更多的使用可参考[官网说明](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/custom_debugging_info.html#callback)\n", "\n", "- `display.clear_output`:清除打印内容,实现动态拟合效果。" ] diff --git a/tutorials/notebook/loading_dataset.ipynb b/tutorials/notebook/loading_dataset.ipynb index 59161e12d1..de6ad120fd 100644 --- a/tutorials/notebook/loading_dataset.ipynb +++ b/tutorials/notebook/loading_dataset.ipynb @@ -308,7 +308,7 @@ "\n", "MindSpore天然支持读取MindSpore数据格式——`MindRecord`存储的数据集,在性能和特性上有更好的支持。 \n", "\n", - "> 阅读[将数据集转换为MindSpore数据格式](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/converting_datasets.html),了解如何将数据集转换为MindSpore数据格式。\n", + "> 阅读[将数据集转换为MindSpore数据格式](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/converse_dataset.html),了解如何将数据集转换为MindSpore数据格式。\n", "\n", "可以通过`MindDataset`对象对数据集进行读取。详细方法如下所示:" ] @@ -407,7 +407,7 @@ "## 加载自定义数据集\n", "\n", "现实场景中,数据集的种类多种多样,对于自定义数据集或者目前不支持直接加载的数据集,有两种方法可以处理。\n", - "一种方法是将数据集转成MindRecord格式(请参考[将数据集转换为MindSpore数据格式](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/converting_datasets.html)章节),另一种方法是通过`GeneratorDataset`对象加载,以下将展示如何使用`GeneratorDataset`。\n", + "一种方法是将数据集转成MindRecord格式(请参考[将数据集转换为MindSpore数据格式](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/converse_dataset.html)章节),另一种方法是通过`GeneratorDataset`对象加载,以下将展示如何使用`GeneratorDataset`。\n", "\n", "1. 定义一个可迭代的对象,用于生成数据集。以下展示了两种示例,一种是含有`yield`返回值的自定义函数,另一种是含有`__getitem__`的自定义类。两种示例都将产生一个含有从0到9数字的数据集。\n", " \n", diff --git a/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb b/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb index 2e9bf71b08..ef4385712e 100644 --- a/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb +++ b/tutorials/notebook/mindinsight/calculate_and_datagraphic.ipynb @@ -287,7 +287,7 @@ "1. 导入所需的代码包,并示例化训练网络。\n", "2. 通过MindSpore提供的 `SummaryCollector` 接口,实现收集计算图和数据图。在实例化 `SummaryCollector` 时,在 `collect_specified_data` 参数中,通过设置 `collect_graph` 指定收集计算图,设置 `collect_dataset_graph` 指定收集数据图。\n", "\n", - "更多 `SummaryCollector` 的用法,请点击[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.train.html?highlight=summarycollector#mindspore.train.callback.SummaryCollector)查看。\n", + "更多 `SummaryCollector` 的用法,请点击[API文档](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.train.html#mindspore.train.callback.SummaryCollector)查看。\n", "\n" ] }, @@ -338,7 +338,7 @@ "\n", "> 其中 /path/ 为 `SummaryCollector` 中参数 `summary_dir` 所指定的目录。\n", "\n", - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/mindinsight_map.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/mindinsight_map.png)" ] }, { @@ -352,7 +352,7 @@ "- 节点信息:显示当前所查看节点的信息,包括名称、类型、属性、输入和输出。便于在训练结束后,核对计算正确性时查看。\n", "- 图例:图例中包括命名空间、聚合节点、虚拟节点、算子节点、常量节点,通过不同图形来区分。\n", "\n", - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/cast_map.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/cast_map.png)" ] }, { @@ -384,7 +384,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/data_map.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/data_map.png)" ] }, { -- Gitee From fb24b0a63bf04d88bc05bfb273ada25a4658546c Mon Sep 17 00:00:00 2001 From: hangq Date: Fri, 18 Sep 2020 15:45:26 +0800 Subject: [PATCH 087/100] update example code --- tutorials/lite/source_en/use/runtime.md | 59 +++------------------- tutorials/lite/source_zh_cn/use/runtime.md | 59 +++------------------- 2 files changed, 12 insertions(+), 106 deletions(-) diff --git a/tutorials/lite/source_en/use/runtime.md b/tutorials/lite/source_en/use/runtime.md index 73e77c42ee..dba49c12ad 100644 --- a/tutorials/lite/source_en/use/runtime.md +++ b/tutorials/lite/source_en/use/runtime.md @@ -81,66 +81,16 @@ Contexts save some basic configuration parameters required by sessions to guide MindSpore Lite supports heterogeneous inference. The preferred backend for inference is specified by `device_ctx_` in `Context` and is CPU by default. During graph compilation, operator selection and scheduling are performed based on the preferred backend. -```cpp -/// \brief DeviceType defined for holding user's preferred backend. -typedef enum { - DT_CPU, /**< CPU device type */ - DT_GPU, /**< GPU device type */ - DT_NPU /**< NPU device type, not supported yet */ -} DeviceType; - -/// \brief DeviceContext defined for holding DeviceType. -typedef struct { - DeviceType type; /**< device type */ -} DeviceContext; - -DeviceContext device_ctx_{DT_CPU}; -``` - MindSpore Lite has a built-in thread pool shared by processes. During inference, `thread_num_` is used to specify the maximum number of threads in the thread pool. The default maximum number is 2. It is recommended that the maximum number be no more than 4. Otherwise, the performance may be affected. -```c++ -int thread_num_ = 2; /**< thread number config for thread pool */ -``` - MindSpore Lite supports dynamic memory allocation and release. If `allocator` is not specified, a default `allocator` is generated during inference. You can also use the `Context` method to allow multiple `Context` to share the memory allocator. If users create the `Context` by using `new`, it should be released by using `delete` once it's not required. Usually the `Context` is released after finishing the session creation. -```cpp -/// \brief Allocator defined a memory pool for malloc memory and free memory dynamically. -/// -/// \note List public class and interface for reference. -class Allocator; - -/// \brief Context defined for holding environment variables during runtime. -class MS_API Context { - public: - /// \brief Constructor of MindSpore Lite Context using input value for parameters. - /// - /// \param[in] thread_num Define the work thread number during the runtime. - /// \param[in] allocator Define the allocator for malloc. - /// \param[in] device_ctx Define device information during the runtime. - Context(int thread_num, std::shared_ptr allocator, DeviceContext device_ctx); - - public: - std::shared_ptr allocator = nullptr; -} -``` - ### Creating Sessions Use the `Context` created in the previous step to call the static `CreateSession` method of LiteSession to create `LiteSession`. The `LiteSession` instance returned by the function is a pointer, which is created by using `new`. If the pointer is not required, you need to release it by using `delete`. -```cpp -/// \brief Static method to create a LiteSession pointer. -/// -/// \param[in] context Define the context of session to be created. -/// -/// \return Pointer of MindSpore Lite LiteSession. -static LiteSession *CreateSession(lite::Context *context); -``` - ### Example The following sample code demonstrates how to create a `Context` and how to allow two `LiteSession` to share a memory pool. @@ -152,13 +102,16 @@ if (context == nullptr) { return RET_ERROR; } // The preferred backend is GPU, which means, if there is a GPU operator, it will run on the GPU first, otherwise it will run on the CPU. -context->device_ctx_.type = lite::DT_GPU; +context->device_type_ = lite::DT_GPU; // The medium core takes priority in thread and core binding methods. This parameter will work in the BindThread interface. For specific binding effect, see the "Run Graph" section. context->cpu_bind_mode_ = MID_CPU; // Configure the number of worker threads in the thread pool to 2, including the main thread. context->thread_num_ = 2; // Allocators can be shared across multiple Contexts. -auto *context2 = new Context(context->thread_num_, context->allocator, context->device_ctx_); +auto *context2 = new Context(); +context2->thread_num_ = context->thread_num_; +context2->allocator = context->allocator; +context2->device_type_ = context->device_type_; context2->cpu_bind_mode_ = context->cpu_bind_mode_; // Use Context to create Session. auto session1 = session::LiteSession::CreateSession(context); @@ -171,7 +124,7 @@ if (session1 == nullptr) { // session1 and session2 can share one memory pool. auto session2 = session::LiteSession::CreateSession(context2); delete (context2); -if (session == nullptr) { +if (session2 == nullptr) { MS_LOG(ERROR) << "CreateSession failed while running %s", modelName.c_str(); return RET_ERROR; } diff --git a/tutorials/lite/source_zh_cn/use/runtime.md b/tutorials/lite/source_zh_cn/use/runtime.md index 47e4ba6a03..b3460b5042 100644 --- a/tutorials/lite/source_zh_cn/use/runtime.md +++ b/tutorials/lite/source_zh_cn/use/runtime.md @@ -80,66 +80,16 @@ static Model *Import(const char *model_buf, size_t size); MindSpore Lite支持异构推理,推理时的主选后端由`Context`中的`device_ctx_`指定,默认为CPU。在进行图编译时,会根据主选后端进行算子选型调度。 -```cpp -/// \brief DeviceType defined for holding user's preferred backend. -typedef enum { - DT_CPU, /**< CPU device type */ - DT_GPU, /**< GPU device type */ - DT_NPU /**< NPU device type, not supported yet */ -} DeviceType; - -/// \brief DeviceContext defined for holding DeviceType. -typedef struct { - DeviceType type; /**< device type */ -} DeviceContext; - -DeviceContext device_ctx_{DT_CPU}; -``` - MindSpore Lite内置一个进程共享的线程池,推理时通过`thread_num_`指定线程池的最大线程数,默认为2线程,推荐最多不超过4个线程,否则可能会影响性能。 -```cpp -int thread_num_ = 2; /**< thread number config for thread pool */ -``` - MindSpore Lite支持动态内存分配和释放,如果没有指定`allocator`,推理时会生成一个默认的`allocator`,也可以通过`Context`方法在多个`Context`中共享内存分配器。 如果用户通过`new`创建`Context`,不再需要时,需要用户通过`delete`释放。一般在创建完Session后,Context即可释放。 -```cpp -/// \brief Allocator defined a memory pool for malloc memory and free memory dynamically. -/// -/// \note List public class and interface for reference. -class Allocator; - -/// \brief Context defined for holding environment variables during runtime. -class MS_API Context { - public: - /// \brief Constructor of MindSpore Lite Context using input value for parameters. - /// - /// \param[in] thread_num Define the work thread number during the runtime. - /// \param[in] allocator Define the allocator for malloc. - /// \param[in] device_ctx Define device information during the runtime. - Context(int thread_num, std::shared_ptr allocator, DeviceContext device_ctx); - - public: - std::shared_ptr allocator = nullptr; -} -``` - ### 创建会话 用上一步创建得到的`Context`,调用LiteSession的静态`CreateSession`方法来创建`LiteSession`。函数返回的`LiteSession`实例是一个指针,通过`new`创建,不再需要时,需要用户通过`delete`释放。 -```cpp -/// \brief Static method to create a LiteSession pointer. -/// -/// \param[in] context Define the context of session to be created. -/// -/// \return Pointer of MindSpore Lite LiteSession. -static LiteSession *CreateSession(lite::Context *context); -``` - ### 使用示例 下面示例代码演示了`Context`的创建,以及在两个`LiteSession`间共享内存池的功能: @@ -151,13 +101,16 @@ if (context == nullptr) { return RET_ERROR; } // The preferred backend is GPU, which means, if there is a GPU operator, it will run on the GPU first, otherwise it will run on the CPU. -context->device_ctx_.type = lite::DT_GPU; +context->device_type_ = lite::DT_GPU; // The medium core takes priority in thread and core binding methods. This parameter will work in the BindThread interface. For specific binding effect, see the "Run Graph" section. context->cpu_bind_mode_ = MID_CPU; // Configure the number of worker threads in the thread pool to 2, including the main thread. context->thread_num_ = 2; // Allocators can be shared across multiple Contexts. -auto *context2 = new Context(context->thread_num_, context->allocator, context->device_ctx_); +auto *context2 = new Context(); +context2->thread_num_ = context->thread_num_; +context2->allocator = context->allocator; +context2->device_type_ = context->device_type_; context2->cpu_bind_mode_ = context->cpu_bind_mode_; // Use Context to create Session. auto session1 = session::LiteSession::CreateSession(context); @@ -170,7 +123,7 @@ if (session1 == nullptr) { // session1 and session2 can share one memory pool. auto session2 = session::LiteSession::CreateSession(context2); delete (context2); -if (session == nullptr) { +if (session2 == nullptr) { MS_LOG(ERROR) << "CreateSession failed while running %s", modelName.c_str(); return RET_ERROR; } -- Gitee From 70554dbfa43020a93132e056ab266f21496631bc Mon Sep 17 00:00:00 2001 From: changzherui Date: Fri, 18 Sep 2020 14:36:25 +0800 Subject: [PATCH 088/100] modify export input info --- .../source_en/use/save_and_load_model.md | 17 ++++++++++------- .../source_zh_cn/use/save_and_load_model.md | 17 ++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/tutorials/training/source_en/use/save_and_load_model.md b/tutorials/training/source_en/use/save_and_load_model.md index c361519ff9..e0bf53f682 100644 --- a/tutorials/training/source_en/use/save_and_load_model.md +++ b/tutorials/training/source_en/use/save_and_load_model.md @@ -149,6 +149,9 @@ The `load_checkpoint` method returns a parameter dictionary and then the `load_p When you have a CheckPoint file, if you want to do inference, you need to generate corresponding models based on the network and CheckPoint. The `export` interface supports exporting multiple types of model file formats for inference on different hardware platforms. +> `input` is the input parameter of the `export` method, representing the input of the network. If the network has multiple inputs, they need to be passed into the `export` method together. +> eg:`export(network, Tensor(input1), Tensor(input2), file_name='network.mindir', file_format='MINDIR')`. + ### Export AIR Model AIR format file only supports Ascend AI processor. The code example of exporting this format file is as follows: @@ -161,8 +164,8 @@ resnet = ResNet50() param_dict = load_checkpoint("resnet50-2_32.ckpt") # load the parameter into net load_param_into_net(resnet, param_dict) -input = np.random.uniform(0.0, 1.0, size = [32, 3, 224, 224]).astype(np.float32) -export(resnet, Tensor(input), file_name = 'resnet50-2_32.air', file_format = 'AIR') +input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32) +export(resnet, Tensor(input), file_name='resnet50-2_32.air', file_format='AIR') ``` Before using the `export` interface, you need to import` mindspore.train.serialization`. @@ -183,8 +186,8 @@ resnet = ResNet50() param_dict = load_checkpoint("resnet50-2_32.ckpt") # load the parameter into net load_param_into_net(resnet, param_dict) -input = np.random.uniform(0.0, 1.0, size = [32, 3, 224, 224]).astype(np.float32) -export(resnet, Tensor(input), file_name = 'resnet50-2_32.onnx', file_format = 'ONNX') +input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32) +export(resnet, Tensor(input), file_name='resnet50-2_32.onnx', file_format='ONNX') ``` It is recommended to use '.onnx' as the suffix of ONNX format files. @@ -204,8 +207,8 @@ resnet = ResNet50() param_dict = load_checkpoint("resnet50-2_32.ckpt") # load the parameter into net load_param_into_net(resnet, param_dict) -input = np.random.uniform(0.0, 1.0, size = [32, 3, 224, 224]).astype(np.float32) -export(resnet, Tensor(input), file_name = 'resnet50-2_32.mindir', file_format = 'MINDIR') +input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32) +export(resnet, Tensor(input), file_name='resnet50-2_32.mindir', file_format='MINDIR') ``` -It is recommended to use '.mindir' as the suffix of MINDIR format files. +It is recommended to use '.mindir' as the suffix of MINDIR format files. \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/use/save_and_load_model.md b/tutorials/training/source_zh_cn/use/save_and_load_model.md index 47e516cd3b..ed8c449ecf 100644 --- a/tutorials/training/source_zh_cn/use/save_and_load_model.md +++ b/tutorials/training/source_zh_cn/use/save_and_load_model.md @@ -150,6 +150,9 @@ model.train(epoch, dataset) 当有了CheckPoint文件后,如果想继续做推理,需要通过网络和CheckPoint生成对应的模型。`export`接口支持导出多种类型的模型文件格式,用于不同硬件平台的推理。 +> `input`为`export`方法的入参,代表网络的输入,如果网络有多个输入,需要一同传进`export`方法。 +> 例如:`export(network, Tensor(input1), Tensor(input2), file_name='network.mindir', file_format='MINDIR')` + ### 导出AIR格式文件 AIR格式文件仅支持昇腾AI处理器,导出该格式文件的代码样例如下: @@ -162,8 +165,8 @@ resnet = ResNet50() param_dict = load_checkpoint("resnet50-2_32.ckpt") # load the parameter into net load_param_into_net(resnet, param_dict) -input = np.random.uniform(0.0, 1.0, size = [32, 3, 224, 224]).astype(np.float32) -export(resnet, Tensor(input), file_name = 'resnet50-2_32.air', file_format = 'AIR') +input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32) +export(resnet, Tensor(input), file_name='resnet50-2_32.air', file_format='AIR') ``` 使用`export`接口之前,需要先导入`mindspore.train.serialization`。 @@ -184,8 +187,8 @@ resnet = ResNet50() param_dict = load_checkpoint("resnet50-2_32.ckpt") # load the parameter into net load_param_into_net(resnet, param_dict) -input = np.random.uniform(0.0, 1.0, size = [32, 3, 224, 224]).astype(np.float32) -export(resnet, Tensor(input), file_name = 'resnet50-2_32.onnx', file_format = 'ONNX') +input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32) +export(resnet, Tensor(input), file_name='resnet50-2_32.onnx', file_format='ONNX') ``` 建议使用`.onnx`作为ONNX格式文件的后缀名。 @@ -202,8 +205,8 @@ resnet = ResNet50() param_dict = load_checkpoint("resnet50-2_32.ckpt") # load the parameter into net load_param_into_net(resnet, param_dict) -input = np.random.uniform(0.0, 1.0, size = [32, 3, 224, 224]).astype(np.float32) -export(resnet, Tensor(input), file_name = 'resnet50-2_32.mindir', file_format = 'MINDIR') +input = np.random.uniform(0.0, 1.0, size=[32, 3, 224, 224]).astype(np.float32) +export(resnet, Tensor(input), file_name='resnet50-2_32.mindir', file_format='MINDIR') ``` -建议使用`.mindir`作为MINDIR格式文件的后缀名。 +建议使用`.mindir`作为MINDIR格式文件的后缀名。 \ No newline at end of file -- Gitee From 4b70b91e548b242c544bfc98c38b8cd4889b52cb Mon Sep 17 00:00:00 2001 From: yingchen Date: Fri, 18 Sep 2020 15:52:52 +0800 Subject: [PATCH 089/100] update links for r1.0_b --- docs/faq/source_en/FAQ.md | 24 ++++++++++++------------ docs/faq/source_zh_cn/FAQ.md | 22 +++++++++++----------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/faq/source_en/FAQ.md b/docs/faq/source_en/FAQ.md index 153aaf1e00..d96cb9365b 100644 --- a/docs/faq/source_en/FAQ.md +++ b/docs/faq/source_en/FAQ.md @@ -1,4 +1,4 @@ -# FAQ +# FAQ `Linux` `Windows` `Ascend` `GPU` `CPU` `Environmental Setup` `Model Export` `Model Training` `Beginner` `Intermediate` `Expert` @@ -18,7 +18,7 @@ - [Supported Features](#supported-features) - + ## Installation @@ -116,7 +116,7 @@ A: After MindSpore is installed on a CPU hardware platform, run the `python -c'i Q: What can I do if the LSTM example on the official website cannot run on Ascend? -A: Currently, the LSTM runs only on a GPU or CPU and does not support the hardware environment. You can click [here](https://www.mindspore.cn/docs/en/master/operator_list.html) to view the supported operators. +A: Currently, the LSTM runs only on a GPU or CPU and does not support the hardware environment. You can click [here](https://www.mindspore.cn/doc/programming_guide/en/r1.0/operator_list_ms.html) to view the supported operators.
      @@ -134,7 +134,7 @@ A: MindSpore uses protocol buffers (protobuf) to store training parameters and c Q: How do I use models trained by MindSpore on Ascend 310? Can they be converted to models used by HiLens Kit? -A: Yes. HiLens Kit uses Ascend 310 as the inference core. Therefore, the two questions are essentially the same. Ascend 310 requires a dedicated OM model. Use MindSpore to export the ONNX or AIR model and convert it into an OM model supported by Ascend 310. For details, see [Multi-platform Inference](https://www.mindspore.cn/tutorial/en/master/use/multi_platform_inference.html). +A: Yes. HiLens Kit uses Ascend 310 as the inference core. Therefore, the two questions are essentially the same. Ascend 310 requires a dedicated OM model. Use MindSpore to export the ONNX or AIR model and convert it into an OM model supported by Ascend 310. For details, see [Multi-platform Inference](https://www.mindspore.cn/tutorial/inference/en/r1.0/multi_platform_inference.html).
      @@ -146,19 +146,19 @@ A: When building a network, use `if self.training: x = dropput(x)`. During verif Q: Where can I view the sample code or tutorial of MindSpore training and inference? -A: Please visit the [MindSpore official website](https://www.mindspore.cn/tutorial/en/master/index.html). +A: Please visit the [MindSpore official website](https://www.mindspore.cn/tutorial/en/r1.0/index.html).
      Q: What types of model is currently supported by MindSpore for training? -A: MindSpore has basic support for common training scenarios, please refer to [Release note](https://gitee.com/mindspore/mindspore/blob/master/RELEASE.md) for detailed information. +A: MindSpore has basic support for common training scenarios, please refer to [Release note](https://gitee.com/mindspore/mindspore/blob/r1.0/RELEASE.md) for detailed information.
      Q: What are the available recommendation or text generation networks or models provided by MindSpore? -A: Currently, recommendation models such as Wide & Deep, DeepFM, and NCF are under development. In the natural language processing (NLP) field, Bert\_NEZHA is available and models such as MASS are under development. You can rebuild the network into a text generation network based on the scenario requirements. Please stay tuned for updates on the [MindSpore Model Zoo](https://gitee.com/mindspore/mindspore/tree/master/model_zoo). +A: Currently, recommendation models such as Wide & Deep, DeepFM, and NCF are under development. In the natural language processing (NLP) field, Bert\_NEZHA is available and models such as MASS are under development. You can rebuild the network into a text generation network based on the scenario requirements. Please stay tuned for updates on the [MindSpore Model Zoo](https://gitee.com/mindspore/mindspore/tree/r1.0/model_zoo).
      @@ -176,7 +176,7 @@ A: Ascend 310 can only be used for inference. MindSpore supports training on Asc Q: Does MindSpore require computing units such as GPUs and NPUs? What hardware support is required? -A: MindSpore currently supports CPU, GPU, Ascend, and NPU. Currently, you can try out MindSpore through Docker images on laptops or in environments with GPUs. Some models in MindSpore Model Zoo support GPU-based training and inference, and other models are being improved. For distributed parallel training, MindSpore supports multi-GPU training. You can obtain the latest information from [Road Map](https://www.mindspore.cn/docs/en/master/roadmap.html) and [project release notes](https://gitee.com/mindspore/mindspore/blob/master/RELEASE.md). +A: MindSpore currently supports CPU, GPU, Ascend, and NPU. Currently, you can try out MindSpore through Docker images on laptops or in environments with GPUs. Some models in MindSpore Model Zoo support GPU-based training and inference, and other models are being improved. For distributed parallel training, MindSpore supports multi-GPU training. You can obtain the latest information from [Road Map](https://www.mindspore.cn/doc/note/en/r1.0/roadmap.html) and [project release notes](https://gitee.com/mindspore/mindspore/blob/r1.0/RELEASE.md).
      @@ -188,7 +188,7 @@ A: MindSpore provides pluggable device management interface so that developer co Q: What is the relationship between MindSpore and ModelArts? Can MindSpore be used on ModelArts? -A: ModelArts is an online training and inference platform on HUAWEI CLOUD. MindSpore is a Huawei deep learning framework. You can view the tutorials on the [MindSpore official website](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/use_on_the_cloud.html) to learn how to train MindSpore models on ModelArts. +A: ModelArts is an online training and inference platform on HUAWEI CLOUD. MindSpore is a Huawei deep learning framework. You can view the tutorials on the [MindSpore official website](https://www.mindspore.cn/tutorial/training/en/r1.0/advanced_use/use_on_the_cloud.html) to learn how to train MindSpore models on ModelArts.
      @@ -232,7 +232,7 @@ A: The problem is that the Graph mode is selected but the PyNative mode is used. - PyNative mode: dynamic graph mode. In this mode, operators in the neural network are delivered and executed one by one, facilitating the compilation and debugging of the neural network model. - Graph mode: static graph mode. In this mode, the neural network model is compiled into an entire graph and then delivered for execution. This mode uses technologies such as graph optimization to improve the running performance and facilitates large-scale deployment and cross-platform running. -You can select a proper mode and writing method to complete the training by referring to the official website [tutorial](https://www.mindspore.cn/tutorial/en/master/advanced_use/debugging_in_pynative_mode.html). +You can select a proper mode and writing method to complete the training by referring to the official website [tutorial](https://www.mindspore.cn/tutorial/training/en/r1.0/advanced_use/debug_in_pynative_mode.html). ## Programming Language Extensions @@ -255,7 +255,7 @@ A: In addition to data parallelism, MindSpore distributed training also supports
      Q: Has MindSpore implemented the anti-pooling operation similar to `nn.MaxUnpool2d`? -A: Currently, MindSpore does not provide anti-pooling APIs but you can customize the operator to implement the operation. For details, click [here](https://www.mindspore.cn/tutorial/en/master/use/custom_operator.html). +A: Currently, MindSpore does not provide anti-pooling APIs but you can customize the operator to implement the operation. For details, click [here](https://www.mindspore.cn/tutorial/training/en/r1.0/advanced_use/custom_operator_ascend.html).
      @@ -291,7 +291,7 @@ A: The TensorFlow's object detection pipeline API belongs to the TensorFlow's Mo Q: How do I migrate scripts or models of other frameworks to MindSpore? -A: For details about script or model migration, please visit the [MindSpore official website](https://www.mindspore.cn/tutorial/en/master/advanced_use/network_migration.html). +A: For details about script or model migration, please visit the [MindSpore official website](https://www.mindspore.cn/tutorial/training/en/r1.0/advanced_use/migrate_3rd_scripts.html).
      diff --git a/docs/faq/source_zh_cn/FAQ.md b/docs/faq/source_zh_cn/FAQ.md index f768d6bcc2..a0c816d094 100644 --- a/docs/faq/source_zh_cn/FAQ.md +++ b/docs/faq/source_zh_cn/FAQ.md @@ -18,7 +18,7 @@ - [特性支持](#特性支持) - + ## 安装类 @@ -123,7 +123,7 @@ A:CPU硬件平台安装MindSpore后测试是否安装成功,只需要执行命 Q:官网的LSTM示例在Ascend上跑不通 -A:目前LSTM只支持在GPU和CPU上运行,暂不支持硬件环境,您可以[点击这里](https://www.mindspore.cn/docs/zh-CN/master/operator_list.html)查看算子支持情况。 +A:目前LSTM只支持在GPU和CPU上运行,暂不支持硬件环境,您可以[点击这里](https://www.mindspore.cn/doc/programming_guide/zh-CN/r1.0/operator_list_ms.html)查看算子支持情况。
      @@ -143,7 +143,7 @@ A: MindSpore采用protbuf存储训练参数,无法直接读取其他框架 Q:用MindSpore训练出的模型如何在Ascend 310上使用?可以转换成适用于HiLens Kit用的吗? -A:Ascend 310需要运行专用的OM模型,先使用MindSpore导出ONNX或AIR模型,再转化为Ascend 310支持的OM模型。具体可参考[多平台推理](https://www.mindspore.cn/tutorial/zh-CN/master/use/multi_platform_inference.html)。可以,HiLens Kit是以Ascend 310为推理核心,所以前后两个问题本质上是一样的,需要转换为OM模型. +A:Ascend 310需要运行专用的OM模型,先使用MindSpore导出ONNX或AIR模型,再转化为Ascend 310支持的OM模型。具体可参考[多平台推理](https://www.mindspore.cn/tutorial/inference/zh-CN/r1.0/multi_platform_inference.html)。可以,HiLens Kit是以Ascend 310为推理核心,所以前后两个问题本质上是一样的,需要转换为OM模型.
      @@ -155,19 +155,19 @@ A:在构造网络的时候可以通过 `if self.training: x = dropput(x)`, Q:从哪里可以查看MindSpore训练及推理的样例代码或者教程? -A:可以访问[MindSpore官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/index.html)。 +A:可以访问[MindSpore官网教程](https://www.mindspore.cn/tutorial/zh-CN/r1.0/index.html)。
      Q:MindSpore支持哪些模型的训练? -A:MindSpore针对典型场景均有模型训练支持,支持情况详见[Release note](https://gitee.com/mindspore/mindspore/blob/master/RELEASE.md)。 +A:MindSpore针对典型场景均有模型训练支持,支持情况详见[Release note](https://gitee.com/mindspore/mindspore/blob/r1.0/RELEASE.md)。
      Q:MindSpore有哪些现成的推荐类或生成类网络或模型可用? -A:目前正在开发Wide & Deep、DeepFM、NCF等推荐类模型,NLP领域已经支持Bert_NEZHA,正在开发MASS等模型,用户可根据场景需要改造为生成类网络,可以关注[MindSpore Model Zoo](https://gitee.com/mindspore/mindspore/tree/master/model_zoo)。 +A:目前正在开发Wide & Deep、DeepFM、NCF等推荐类模型,NLP领域已经支持Bert_NEZHA,正在开发MASS等模型,用户可根据场景需要改造为生成类网络,可以关注[MindSpore Model Zoo](https://gitee.com/mindspore/mindspore/tree/r1.0/model_zoo)。
      @@ -187,7 +187,7 @@ A:Ascend 310只能用作推理,MindSpore支持在Ascend 910训练,训练 Q:安装运行MindSpore时,是否要求平台有GPU、NPU等计算单元?需要什么硬件支持? -A:MindSpore当前支持CPU/GPU/Ascend /NPU。目前笔记本电脑或者有GPU的环境,都可以通过Docker镜像来试用。当前MindSpore Model Zoo中有部分模型已经支持GPU的训练和推理,其他模型也在不断地进行完善。在分布式并行训练方面,MindSpore当前支持GPU多卡训练。你可以通过[RoadMap](https://www.mindspore.cn/docs/zh-CN/master/roadmap.html)和项目[Release note](https://gitee.com/mindspore/mindspore/blob/master/RELEASE.md)获取最新信息。 +A:MindSpore当前支持CPU/GPU/Ascend /NPU。目前笔记本电脑或者有GPU的环境,都可以通过Docker镜像来试用。当前MindSpore Model Zoo中有部分模型已经支持GPU的训练和推理,其他模型也在不断地进行完善。在分布式并行训练方面,MindSpore当前支持GPU多卡训练。你可以通过[RoadMap](https://www.mindspore.cn/doc/note/zh-CN/r1.0/roadmap.html)和项目[Release note](https://gitee.com/mindspore/mindspore/blob/r1.0/RELEASE.md)获取最新信息。
      @@ -199,7 +199,7 @@ A:MindSpore提供了可插拔式的设备管理接口,其他计算单元( Q:MindSpore与ModelArts是什么关系,在ModelArts中能使用MindSpore吗? -A:ModelArts是华为公有云线上训练及推理平台,MindSpore是华为深度学习框架,可以查阅[MindSpore官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/use_on_the_cloud.html),教程中详细展示了用户如何使用ModelArts来做MindSpore的模型训练。 +A:ModelArts是华为公有云线上训练及推理平台,MindSpore是华为深度学习框架,可以查阅[MindSpore官网教程](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/use_on_the_cloud.html),教程中详细展示了用户如何使用ModelArts来做MindSpore的模型训练。
      @@ -245,7 +245,7 @@ A:这边的问题是选择了Graph模式却使用了PyNative的写法,所以 - PyNative模式:也称动态图模式,将神经网络中的各个算子逐一下发执行,方便用户编写和调试神经网络模型。 - Graph模式:也称静态图模式或者图模式,将神经网络模型编译成一整张图,然后下发执行。该模式利用图优化等技术提高运行性能,同时有助于规模部署和跨平台运行。 -用户可以参考[官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/debugging_in_pynative_mode.html)选择合适、统一的模式和写法来完成训练。 +用户可以参考[官网教程](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/debug_in_pynative_mode.html)选择合适、统一的模式和写法来完成训练。
      @@ -273,7 +273,7 @@ A:MindSpore分布式训练除了支持数据并行,还支持算子级模型 Q:请问MindSpore实现了反池化操作了吗?类似于`nn.MaxUnpool2d` 这个反池化操作? -A:目前 MindSpore 还没有反池化相关的接口。如果用户想自己实现的话,可以通过自定义算子的方式自行开发算子,自定义算子[详见这里](https://www.mindspore.cn/tutorial/zh-CN/master/use/custom_operator.html)。 +A:目前 MindSpore 还没有反池化相关的接口。如果用户想自己实现的话,可以通过自定义算子的方式自行开发算子,自定义算子[详见这里](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/custom_operator_ascend.html)。
      @@ -309,7 +309,7 @@ A:TensorFlow的对象检测Pipeline接口属于TensorFlow Model模块。待Min Q:其他框架的脚本或者模型怎么迁移到MindSpore? -A:关于脚本或者模型迁移,可以查询MindSpore官网中关于[网络迁移](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/network_migration.html)的介绍。 +A:关于脚本或者模型迁移,可以查询MindSpore官网中关于[网络迁移](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/migrate_3rd_scripts.html)的介绍。
      -- Gitee From 1d6817cee35fcd28521244b1e778de656c741eb3 Mon Sep 17 00:00:00 2001 From: zhangyi Date: Fri, 18 Sep 2020 11:35:18 +0800 Subject: [PATCH 090/100] fix links for r1.0 branch. --- .../training/source_en/advanced_use/dashboard.md | 2 +- .../advanced_use/debug_in_pynative_mode.md | 2 +- .../advanced_use/enable_graph_kernel_fusion.md | 4 ++-- .../advanced_use/enable_mixed_precision.md | 2 +- .../source_zh_cn/advanced_use/dashboard.md | 4 ++-- .../advanced_use/debug_in_pynative_mode.md | 4 ++-- .../advanced_use/distributed_training_gpu.md | 10 +++++----- .../advanced_use/enable_auto_augmentation.md | 4 ++-- .../advanced_use/enable_graph_kernel_fusion.md | 16 ++++++++-------- .../advanced_use/enable_mixed_precision.md | 4 ++-- 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/dashboard.md b/tutorials/training/source_en/advanced_use/dashboard.md index 55520c7a2a..1fa5ae50eb 100644 --- a/tutorials/training/source_en/advanced_use/dashboard.md +++ b/tutorials/training/source_en/advanced_use/dashboard.md @@ -16,7 +16,7 @@ - + ## Overview diff --git a/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md b/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md index b64fa616fc..a5d3de74e7 100644 --- a/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md +++ b/tutorials/training/source_en/advanced_use/debug_in_pynative_mode.md @@ -13,7 +13,7 @@ - + ## Overview diff --git a/tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md b/tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md index abe3f20292..bca48ad250 100644 --- a/tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md +++ b/tutorials/training/source_en/advanced_use/enable_graph_kernel_fusion.md @@ -13,7 +13,7 @@ - + ## Overview @@ -99,7 +99,7 @@ context.set_context(enable_graph_kernel=True) 2. `BERT-large` training network - Take the training model of the `BERT-large` network as an example. For details about the dataset and training script, see . You only need to modify the `context` parameter. + Take the training model of the `BERT-large` network as an example. For details about the dataset and training script, see . You only need to modify the `context` parameter. ## Effect Evaluation diff --git a/tutorials/training/source_en/advanced_use/enable_mixed_precision.md b/tutorials/training/source_en/advanced_use/enable_mixed_precision.md index bc10129a5e..40fad1e698 100644 --- a/tutorials/training/source_en/advanced_use/enable_mixed_precision.md +++ b/tutorials/training/source_en/advanced_use/enable_mixed_precision.md @@ -12,7 +12,7 @@ - + ## Overview diff --git a/tutorials/training/source_zh_cn/advanced_use/dashboard.md b/tutorials/training/source_zh_cn/advanced_use/dashboard.md index 4cd8689353..308ba18906 100644 --- a/tutorials/training/source_zh_cn/advanced_use/dashboard.md +++ b/tutorials/training/source_zh_cn/advanced_use/dashboard.md @@ -16,8 +16,8 @@ -   - +   + ## 概述 diff --git a/tutorials/training/source_zh_cn/advanced_use/debug_in_pynative_mode.md b/tutorials/training/source_zh_cn/advanced_use/debug_in_pynative_mode.md index ef1deef9f8..79890d821b 100644 --- a/tutorials/training/source_zh_cn/advanced_use/debug_in_pynative_mode.md +++ b/tutorials/training/source_zh_cn/advanced_use/debug_in_pynative_mode.md @@ -13,9 +13,9 @@ - +    - + ## 概述 diff --git a/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md b/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md index d0888857a3..05beae1113 100644 --- a/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md +++ b/tutorials/training/source_zh_cn/advanced_use/distributed_training_gpu.md @@ -16,7 +16,7 @@ - + ## 概述 @@ -30,7 +30,7 @@ > 数据集的下载和加载方式参考: > -> 。 +> 。 ### 配置分布式环境 @@ -82,7 +82,7 @@ if __name__ == "__main__": 在GPU硬件平台上,网络的定义和Ascend 910 AI处理器一致。 -> 网络、优化器、损失函数的定义参考:。 +> 网络、优化器、损失函数的定义参考:。 ## 运行脚本 @@ -90,7 +90,7 @@ if __name__ == "__main__": > 你可以在这里找到样例的运行脚本: > -> 。 +> 。 > > 如果通过root用户执行脚本,`mpirun`需要加上`--allow-run-as-root`参数。 @@ -145,4 +145,4 @@ echo "start training" mpirun -n 16 --hostfile $HOSTFILE -x DATA_PATH=$DATA_PATH -x PATH -mca pml ob1 pytest -s -v ./resnet50_distributed_training.py > train.log 2>&1 & ``` -在GPU上进行分布式训练时,模型参数的保存和加载可参考[分布式训练模型参数保存和加载](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_ascend.html#id12) \ No newline at end of file +在GPU上进行分布式训练时,模型参数的保存和加载可参考[分布式训练模型参数保存和加载](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/distributed_training_ascend.html#id12) \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md index ad6191be8e..93836cccdc 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md @@ -12,12 +12,12 @@ - + ## 概述 自动数据增强(AutoAugment)[1]是在一系列图像增强子策略的搜索空间中,通过搜索算法找到适合特定数据集的图像增强方案。MindSpore的`c_transforms`模块提供了丰富的C++算子来实现AutoAugment,用户也可以自定义函数或者算子来实现。 -更多MindSpore算子的详细说明参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html)。 +更多MindSpore算子的详细说明参见[API文档](https://www.mindspore.cn/docs/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.vision.html)。 MindSpore算子和AutoAugment中的算子的对应关系如下: diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md b/tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md index f37771211e..5d38995b9a 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_graph_kernel_fusion.md @@ -4,16 +4,16 @@ -- [图算融合](#图算融合) - - [概述](#概述) - - [启用方法](#启用方法) - - [样例脚本](#样例脚本) - - [效果评估](#效果评估) - - [计算图](#计算图) +- [使能图算融合](#使能图算融合) + - [概述](#概述) + - [启用方法](#启用方法) + - [样例脚本](#样例脚本) + - [效果评估](#效果评估) + - [计算图](#计算图) - + ## 概述 @@ -100,7 +100,7 @@ context.set_context(enable_graph_kernel=True) 2. `BERT-large`训练网络 以`BERT-large`网络的训练模型为例,数据集和训练脚本可参照 - ,同样我们只需修改`context`参数即可。 + ,同样我们只需修改`context`参数即可。 ## 效果评估 diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md b/tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md index c374919e93..2557689597 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_mixed_precision.md @@ -12,8 +12,8 @@ -   - +   + ## 概述 -- Gitee From a03c456848e3493a8dca6506155e6f10a2762f7f Mon Sep 17 00:00:00 2001 From: caozhou Date: Fri, 18 Sep 2020 16:02:27 +0800 Subject: [PATCH 091/100] optimize overview in r1.0 --- .../source_zh_cn/api_structure.md | 44 ++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/api_structure.md b/docs/programming_guide/source_zh_cn/api_structure.md index 31fc7aeb0a..4c13a8f12b 100644 --- a/docs/programming_guide/source_zh_cn/api_structure.md +++ b/docs/programming_guide/source_zh_cn/api_structure.md @@ -3,22 +3,56 @@ - [MindSpore API概述](#mindsporeapi概述) + - [总体架构](#总体架构) - [设计理念](#设计理念) - [层次结构](#层次结构) - + + +## 总体架构 +MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景覆盖三大目标,其中易开发表现为API友好、调试难度低以及额外的自动化属性,高效执行包括计算效率、数据预处理效率和分布式训练效率,全场景则指框架同时支持云、边缘以及端侧场景。 + +MindSpore总体架构分为前端表示层(Mind Expression,ME)、计算图引擎(Graph Engine,GE)和后端运行时三个部分。ME提供了用户级应用软件编程接口(Application Programming Interface,API),用于构建和训练神经网络,并将用户的Python代码转换为数据流图。GE是算子和硬件资源的管理器,负责控制从ME接收的数据流图的执行。后端运行时包含云、边、端上不同环境中的高效运行环境,例如CPU、GPU、Ascend AI处理器、 Android/iOS等。更多总体架构的相关内容请参见[总体架构](https://www.mindspore.cn/docs/zh-CN/master/architecture.html)。 ## 设计理念 MindSpore源于全产业的最佳实践,向数据科学家和算法工程师提供了统一的模型训练、推理和导出等接口,支持端、边、云等不同场景下的灵活部署,推动深度学习和科学计算等领域繁荣发展。 -神经网络模型通常基于梯度下降算法进行训练,但手动求导过程复杂且梯度难以计算。MindSpore采用函数式可微分编程架构,用户可聚焦于模型算法的数学原生表达,无需进行手动求导。MindSpore的基于源码转换(Source Code Transformation, SCT)的自动微分(Automatic Differentiation)机制能够将Python代码转换为函数中间表达(Intermediate Representation, IR),函数中间表达构造出能够在不同设备解析和执行的计算图,并且在执行该计算图前,应用了多种软硬件协同优化技术,端、边、云等不同场景下的性能和效率得到针对性的提升。此外,MindSpore提供了Python编程范式,用户使用Python原生控制逻辑即可构建复杂的神经网络模型,AI编程变得简单。 +MindSpore提供了Python编程范式,用户使用Python原生控制逻辑即可构建复杂的神经网络模型,AI编程变得简单,具体示例请参见[实现一个图片分类应用](https://www.mindspore.cn/tutorial/zh-CN/master/quick_start/quick_start.html)。 + +目前主流的深度学习框架的执行模式有两种,分别为静态图模式和动态图模式。静态图模式拥有较高的训练性能,但难以调试。动态图模式相较于静态图模式虽然易于调试,但难以高效执行。MindSpore提供了动态图和静态图统一的编码方式,大大增加了静态图和动态图的可兼容性,用户无需开发多套代码,仅变更一行代码便可切换动态图/静态图模式,例如设置`context.set_context(mode=context.PYNATIVE_MODE)`切换成动态图模式,设置`context.set_context(mode=context.GRAPH_MODE)`即可切换成静态图模式,用户可拥有更轻松的开发调试及性能体验。 + +神经网络模型通常基于梯度下降算法进行训练,但手动求导过程复杂且梯度难以计算。MindSpore的基于源码转换(Source Code Transformation,SCT)的自动微分(Automatic Differentiation)机制采用函数式可微分编程架构,在接口层提供Python编程接口,包括控制流的表达。用户可聚焦于模型算法的数学原生表达,无需手动进行求导,在动态图模式下自动微分的样例代码如下所示。 + +```python +import mindspore as ms +from mindspore.ops import composite as C +from mindspore import context +from mindspore.common import Tensor + + +context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU") + + +def cost(x, y): return x * (x + y) + + +def test_grad(x, y): + return C.grad_all(cost)(Tensor(x, dtype=ms.float32), Tensor(y, dtype=ms.float32)) + + +def main(): + return test_grad(2, 1) + +``` + +其中,第一步定义了一个函数(计算图),第二步利用MindSpore提供的反向接口进行自动微分,定义了一个反向函数(计算图),最后给定一些输入就能获取第一步定义的函数在指定处的导数,求导结果为`(5, 2)`。 -目前主流的深度学习框架的执行模式有两种,分别为静态图模式和动态图模式。静态图模式拥有较高的训练性能,但难以调试。动态图模式相较于静态图模式虽然易于调试,但难以高效执行。MindSpore提供了动态图和静态图统一的编码方式。大大增加了静态图和动态图的可兼容性,用户无需开发多套代码,仅变更一行代码便可切换动态图/静态图模式,例如设置`context.set_context(mode=context.PYNATIVE_MODE)`即可从静态图模式切换成动态图模式,从而拥有更轻松的开发调试及性能体验。 +此外,SCT能够将Python代码转换为函数中间表达(Intermediate Representation,IR),函数中间表达构造出能够在不同设备解析和执行的计算图,并且在执行该计算图前,应用了多种软硬件协同优化技术,端、边、云等不同场景下的性能和效率得到针对性的提升。 -随着神经网络模型和数据集的规模不断增加,分布式并行训练成为了神经网络训练的常见做法,但分布式并行训练的策略选择和编写十分复杂,这制约着深度学习的发展。MindSpore统一了单机和分布式训练的编码方式,开发者无需编写复杂的分布式策略,在单机代码中添加少量代码即可实现分布式训练,例如设置`context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL)`便可自动建立代价模型,为用户选择一种较优的并行模式,大大降低了AI开发门槛,提高了神经网络训练效率。 +随着神经网络模型和数据集的规模不断增加,分布式并行训练成为了神经网络训练的常见做法,但分布式并行训练的策略选择和编写十分复杂,这严重制约着深度学习模型的训练效率,阻碍深度学习的发展。MindSpore统一了单机和分布式训练的编码方式,开发者无需编写复杂的分布式策略,在单机代码中添加少量代码即可实现分布式训练,例如设置`context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL)`便可自动建立代价模型,为用户选择一种较优的并行模式,提高神经网络训练效率,大大降低了AI开发门槛,使用户能够快速实现模型思路。 ## 层次结构 @@ -28,7 +62,7 @@ MindSpore向用户提供了3个不同层次的API,支撑用户进行网络构 - Low-Level Python API - 第一层为低阶API,主要包括张量定义、基础算子、自动微分等模块,用户可使用低阶API轻松实现张量定义和求导计算,例如用户可通过`Tensor`接口自定义张量,使用`grad_all`算子计算函数在指定处的导数。 + 第一层为低阶API,主要包括张量定义、基础算子、自动微分等模块,用户可使用低阶API轻松实现张量定义和求导计算,例如用户可通过`Tensor`接口自定义张量,使用`ops.composite`模块下的`grad_all`算子计算函数在指定处的导数。 - Medium-Level Python API -- Gitee From 19b7c5383157efe23226833705d7843fd2d882b7 Mon Sep 17 00:00:00 2001 From: liuxiao78 Date: Fri, 18 Sep 2020 16:47:17 +0800 Subject: [PATCH 092/100] fix build.md --- tutorials/lite/source_en/use/build.md | 2 +- tutorials/lite/source_zh_cn/use/build.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/lite/source_en/use/build.md b/tutorials/lite/source_en/use/build.md index 12a746acd3..1fbf98555d 100644 --- a/tutorials/lite/source_en/use/build.md +++ b/tutorials/lite/source_en/use/build.md @@ -174,7 +174,7 @@ The inference framework can be obtained under `-I x86_64`, `-I arm64` and `-I ar - When the compilation option is `-I arm32`: ``` | - ├── mindspore-lite-{version}-runtime-arm64-cpu + ├── mindspore-lite-{version}-runtime-arm32-cpu │ └── benchmark # Benchmarking Tool │ └── lib # Inference framework dynamic library │ ├── libmindspore-lite.so # Dynamic library of infernece framework in MindSpore Lite diff --git a/tutorials/lite/source_zh_cn/use/build.md b/tutorials/lite/source_zh_cn/use/build.md index 19d5457427..4c147c214c 100644 --- a/tutorials/lite/source_zh_cn/use/build.md +++ b/tutorials/lite/source_zh_cn/use/build.md @@ -175,7 +175,7 @@ tar -xvf mindspore-lite-{version}-minddata-{os}-{device}.tar.gz - 当编译选项为`-I arm32`时: ``` | - ├── mindspore-lite-{version}-runtime-arm64-cpu + ├── mindspore-lite-{version}-runtime-arm32-cpu │ └── benchmark # 基准测试工具 │ └── lib # 推理框架动态库 │ ├── libmindspore-lite.so # MindSpore Lite推理框架的动态库 -- Gitee From 5f6a4a9d3cd2385aac71d5d127b6b8d5379d7b12 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Fri, 18 Sep 2020 17:00:30 +0800 Subject: [PATCH 093/100] Fix the link for markdown --- ...sight_model_lineage_and_data_lineage.ipynb | 12 ++++---- tutorials/notebook/mixed_precision.ipynb | 6 ++-- tutorials/notebook/model_security.ipynb | 2 +- ..._the_performance_of_data_preparation.ipynb | 30 +++++++++---------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb b/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb index d8a27986e8..a2c292e699 100644 --- a/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb +++ b/tutorials/notebook/mindinsight/mindinsight_model_lineage_and_data_lineage.ipynb @@ -29,7 +29,7 @@ "6. 数据溯源的使用。调整数据参数多次训练并存储数据,并使用MindInsight的数据溯源功能对不同数据集下训练产生的模型进行对比分析,了解如何调优。\n", "\n", "\n", - "本次体验将使用快速入门案例作为基础用例,将MindInsight的模型溯源和数据溯源的数据记录功能加入到案例中,快速入门案例的源码请参考:。" + "本次体验将使用快速入门案例作为基础用例,将MindInsight的模型溯源和数据溯源的数据记录功能加入到案例中,快速入门案例的源码请参考:。" ] }, { @@ -292,7 +292,7 @@ "source": [ "MindSpore 提供 `SummaryCollector` 进行记录训练过程中的信息。通过 `SummaryCollector` 的 `collect_specified_data` 参数,可以自定义记录指定数据。\n", "\n", - "在本次体验中,我们将记录训练数据与数据集预处理的操作,我们将 `collect_specified_data` 中的 `collect_train_lineage`, `collect_eval_lineage`, `collect_dataset_graph` 设置成 `True`。SummaryCollector的更多用法,请参考[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.train.html?highlight=collector#mindspore.train.callback.SummaryCollector)。\n" + "在本次体验中,我们将记录训练数据与数据集预处理的操作,我们将 `collect_specified_data` 中的 `collect_train_lineage`, `collect_eval_lineage`, `collect_dataset_graph` 设置成 `True`。SummaryCollector的更多用法,请参考[API文档](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.train.html#mindspore.train.callback.SummaryCollector)。\n" ] }, { @@ -353,7 +353,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "这里主要展示如何启用及关闭MindInsight,更多的命令集信息,请参考MindSpore官方网站:。\n", + "这里主要展示如何启用及关闭MindInsight,更多的命令集信息,请参考MindSpore官方网站:。\n", "\n", "启动MindInsight服务命令:\n", "\n", @@ -389,7 +389,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![image](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/model_lineage_all.png)" + "![image](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/model_lineage_all.png)" ] }, { @@ -412,7 +412,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![image](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/model_lineage_cp.png)" + "![image](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/model_lineage_cp.png)" ] }, { @@ -442,7 +442,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![image](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/data_lineage.png)" + "![image](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/data_lineage.png)" ] }, { diff --git a/tutorials/notebook/mixed_precision.ipynb b/tutorials/notebook/mixed_precision.ipynb index e9f8b54d07..0da994b2d6 100644 --- a/tutorials/notebook/mixed_precision.ipynb +++ b/tutorials/notebook/mixed_precision.ipynb @@ -42,7 +42,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "> 你可以在这里找到完整可运行的样例代码:。" + "> 你可以在这里找到完整可运行的样例代码:。" ] }, { @@ -56,7 +56,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![image](https://www.mindspore.cn/tutorial/zh-CN/master/_images/mix_precision.jpg)" + "![image](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/images/mix_precision.jpg)" ] }, { @@ -952,7 +952,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "当然,如果你想参考单步训练或者手动设置混合精度训练,可以参考官网教程。" + "当然,如果你想参考单步训练或者手动设置混合精度训练,可以参考官网教程。" ] }, { diff --git a/tutorials/notebook/model_security.ipynb b/tutorials/notebook/model_security.ipynb index e63f9c1f37..53323232b4 100644 --- a/tutorials/notebook/model_security.ipynb +++ b/tutorials/notebook/model_security.ipynb @@ -579,7 +579,7 @@ "source": [ "### 攻击模型\n", "\n", - "调用MindArmour提供的FGSM接口(`FastGradientSignMethod`),使用被攻击前抽取的96张数据图像`test_images`作为被攻击数据集,保存被攻击后数据集图像到当前notebook目录下的`ada_data`文件中。其中,参数`eps`为攻击对数据范围产生的单步对抗性摄动的比例,该值越大,则攻击程度越大。关于`FastGradientSignMethod`的详细使用说明,可参考[官方API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindarmour/mindarmour.attacks.html?highlight=fastgradientsignmethod#mindarmour.attacks.FastGradientSignMethod)。" + "调用MindArmour提供的FGSM接口(`FastGradientSignMethod`),使用被攻击前抽取的96张数据图像`test_images`作为被攻击数据集,保存被攻击后数据集图像到当前notebook目录下的`ada_data`文件中。其中,参数`eps`为攻击对数据范围产生的单步对抗性摄动的比例,该值越大,则攻击程度越大。关于`FastGradientSignMethod`的详细使用说明,可参考[官方API文档](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindarmour/mindarmour.adv_robustness.attacks.html#mindarmour.adv_robustness.attacks.FastGradientSignMethod)。" ] }, { diff --git a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb index 989d18b7f6..808f28aa98 100644 --- a/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb +++ b/tutorials/notebook/optimize_the_performance_of_data_preparation/optimize_the_performance_of_data_preparation.ipynb @@ -20,7 +20,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/optimize_the_performance_of_data_preparation/images/pipeline.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/images/pipeline.png)" ] }, { @@ -148,7 +148,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "MindSpore为用户提供了多种数据加载方式,其中包括常用数据集加载、用户自定义数据集加载、MindSpore数据格式加载,详情内容请参考[加载数据集](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/loading_the_datasets.html)。对于数据集加载,底层实现方式的不同,会导致数据集加载的性能存在差异,如下所示:" + "MindSpore为用户提供了多种数据加载方式,其中包括常用数据集加载、用户自定义数据集加载、MindSpore数据格式加载,详情内容请参考[加载数据集](https://www.mindspore.cn/doc/programming_guide/zh-CN/r1.0/dataset_loading.html)。对于数据集加载,底层实现方式的不同,会导致数据集加载的性能存在差异,如下所示:" ] }, { @@ -172,7 +172,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/optimize_the_performance_of_data_preparation/images/data_loading_performance_scheme.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/images/data_loading_performance_scheme.png)" ] }, { @@ -180,8 +180,8 @@ "metadata": {}, "source": [ "数据加载性能优化建议如下:\n", - "- 已经支持的数据集格式优选内置加载算子,具体内容请参考[内置加载算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html),如果性能仍无法满足需求,则可采取多线程并发方案,请参考本文[多线程优化方案](#多线程优化方案)。\n", - "- 不支持的数据集格式,优选转换为MindSpore数据格式后再使用`MindDataset`类进行加载,具体内容请参考[将数据集转换为MindSpore数据格式](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/converting_datasets.html),如果性能仍无法满足需求,则可采取多线程并发方案,请参考本文[多线程优化方案](#多线程优化方案)。\n", + "- 已经支持的数据集格式优选内置加载算子,具体内容请参考[内置加载算子](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.html),如果性能仍无法满足需求,则可采取多线程并发方案,请参考本文[多线程优化方案](#多线程优化方案)。\n", + "- 不支持的数据集格式,优选转换为MindSpore数据格式后再使用`MindDataset`类进行加载,具体内容请参考[将数据集转换为MindSpore数据格式](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/converse_dataset.html),如果性能仍无法满足需求,则可采取多线程并发方案,请参考本文[多线程优化方案](#多线程优化方案)。\n", "- 不支持的数据集格式,算法快速验证场景,优选用户自定义`GeneratorDataset`类实现,如果性能仍无法满足需求,则可采取多进程并发方案,请参考本文[多进程优化方案](#多进程优化方案)。" ] }, @@ -350,7 +350,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "shuffle操作主要是对有序的数据集或者进行过repeat的数据集进行混洗,MindSpore专门为用户提供了`shuffle`函数,其中设定的`buffer_size`参数越大,混洗程度越大,但时间、计算资源消耗也会大。该接口支持用户在整个pipeline的任何时候都可以对数据进行混洗,具体内容请参考[shuffle处理](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/data_processing_and_augmentation.html#shuffle)。但是因为底层的实现方式不同,该方式的性能不如直接在[内置加载算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)中设置`shuffle`参数直接对数据进行混洗。" + "shuffle操作主要是对有序的数据集或者进行过repeat的数据集进行混洗,MindSpore专门为用户提供了`shuffle`函数,其中设定的`buffer_size`参数越大,混洗程度越大,但时间、计算资源消耗也会大。该接口支持用户在整个pipeline的任何时候都可以对数据进行混洗,具体内容请参考[shuffle处理](https://www.mindspore.cn/doc/programming_guide/zh-CN/r1.0/pipeline.html#shuffle)。但是因为底层的实现方式不同,该方式的性能不如直接在[内置加载算子](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.html)中设置`shuffle`参数直接对数据进行混洗。" ] }, { @@ -364,7 +364,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/optimize_the_performance_of_data_preparation/images/shuffle_performance_scheme.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/images/shuffle_performance_scheme.png)" ] }, { @@ -528,7 +528,7 @@ "- 使用内置Python算子(`py_transforms`模块)进行数据增强。\n", "- 用户可根据自己的需求,自定义Python函数进行数据增强。\n", "\n", - "具体的内容请参考[数据增强](https://www.mindspore.cn/tutorial/zh-CN/master/use/data_preparation/data_processing_and_augmentation.html#id3)。因为底层的实现方式不同,所以性能还是有一定的差异,如下所示:" + "具体的内容请参考[数据增强](https://www.mindspore.cn/doc/programming_guide/zh-CN/r1.0/augmentation.html)。因为底层的实现方式不同,所以性能还是有一定的差异,如下所示:" ] }, { @@ -552,7 +552,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/optimize_the_performance_of_data_preparation/images/data_enhancement_performance_scheme.png)\n" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/images/data_enhancement_performance_scheme.png)\n" ] }, { @@ -688,7 +688,7 @@ "- 在数据增强的过程中,`map`函数有`num_parallel_workers`参数用来设置线程数。\n", "- 在Batch的过程中,`batch`函数有`num_parallel_workers`参数用来设置线程数。\n", "\n", - "具体内容请参考[内置加载算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)。" + "具体内容请参考[内置加载算子](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.html)。" ] }, { @@ -703,8 +703,8 @@ "metadata": {}, "source": [ "数据处理中Python实现的算子均支持多进程的模式,例如:\n", - "- `GeneratorDataset`这个类默认是多进程模式,它的`num_parallel_workers`参数表示的是开启的进程数,默认为1,具体内容请参考[GeneratorDataset](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html#mindspore.dataset.GeneratorDataset)。\n", - "- 如果使用Python自定义函数或者`py_transforms`模块进行数据增强的时候,当`map`函数的参数`python_multiprocessing`设置为True时,此时参数`num_parallel_workers`表示的是进程数,参数`python_multiprocessing`默认为False,此时参数`num_parallel_workers`表示的是线程数,具体的内容请参考[内置加载算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)。" + "- `GeneratorDataset`这个类默认是多进程模式,它的`num_parallel_workers`参数表示的是开启的进程数,默认为1,具体内容请参考[GeneratorDataset](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.html#mindspore.dataset.GeneratorDataset)。\n", + "- 如果使用Python自定义函数或者`py_transforms`模块进行数据增强的时候,当`map`函数的参数`python_multiprocessing`设置为True时,此时参数`num_parallel_workers`表示的是进程数,参数`python_multiprocessing`默认为False,此时参数`num_parallel_workers`表示的是线程数,具体的内容请参考[内置加载算子](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.html)。" ] }, { @@ -725,7 +725,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/optimize_the_performance_of_data_preparation/images/compose.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/images/compose.png)" ] }, { @@ -739,14 +739,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "提供某些融合算子,这些算子将两个或多个算子的功能聚合到一个算子中。具体内容请参考[数据增强算子](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html),与它们各自组件的流水线相比,这种融合算子提供了更好的性能。如图所示:" + "提供某些融合算子,这些算子将两个或多个算子的功能聚合到一个算子中。具体内容请参考[数据增强算子](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.dataset.vision.html),与它们各自组件的流水线相比,这种融合算子提供了更好的性能。如图所示:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "![title](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/optimize_the_performance_of_data_preparation/images/operator_fusion.png)" + "![title](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/optimize_the_performance_of_data_preparation/images/operator_fusion.png)" ] } ], -- Gitee From 5e582de809ddb5b783dbba31b91267e72829f80a Mon Sep 17 00:00:00 2001 From: yuximiao Date: Fri, 18 Sep 2020 17:20:25 +0800 Subject: [PATCH 094/100] fix Profiler tutorial. --- .../training/source_en/advanced_use/performance_profiling.md | 2 +- .../training/source_zh_cn/advanced_use/performance_profiling.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/performance_profiling.md b/tutorials/training/source_en/advanced_use/performance_profiling.md index a055ff95d6..4ad58c5589 100644 --- a/tutorials/training/source_en/advanced_use/performance_profiling.md +++ b/tutorials/training/source_en/advanced_use/performance_profiling.md @@ -32,7 +32,7 @@ Performance data like operators' execution time is recorded in files and can be ## Preparing the Environment -Before using Profiler, make sure the process of ada in background running right. The ada process must using the root user to run. The start command is `/usr/local/Ascend/driver/tools/ada`. +Before using Profiler, make sure the process of ada in background running right. The ada process must using users in HwHiAiUser user group or the root user to run, and run the scripts using the same user. The start command is `/usr/local/Ascend/driver/tools/ada`. ## Preparing the Training Script diff --git a/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md b/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md index d3ed71c1ec..c217f0a283 100644 --- a/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md +++ b/tutorials/training/source_zh_cn/advanced_use/performance_profiling.md @@ -30,7 +30,7 @@ - 在训练列表找到对应训练,点击性能分析,即可在页面中查看训练性能数据。 ## 环境准备 -在使用性能分析工具之前,要确保后台工具进程(ada)正确启动,要求用户使用root启动ada进程,启动命令为:`/usr/local/Ascend/driver/tools/ada`。 +在使用性能分析工具之前,要确保后台工具进程(ada)正确启动,要求用户使用HwHiAiUser用户组的用户或root启动ada进程,并使用同用户跑训练脚本,启动命令为:`/usr/local/Ascend/driver/tools/ada`。 ## 准备训练脚本 -- Gitee From 12378d4f8545c9023bb4b0d39ca1d27cfbd2841f Mon Sep 17 00:00:00 2001 From: Xiao Tianci Date: Fri, 18 Sep 2020 20:10:12 +0800 Subject: [PATCH 095/100] update r1.0 to review modify --- .../source_zh_cn/augmentation.md | 2 +- .../source_zh_cn/auto_augmentation.md | 2 +- .../source_zh_cn/dataset_conversion.md | 2 +- .../source_zh_cn/dataset_loading.md | 12 +-- .../programming_guide/source_zh_cn/sampler.md | 18 ++--- .../source_zh_cn/tokenizer.md | 75 +++++++++---------- .../accelerate_data_processing.md | 4 +- .../advanced_use/enable_auto_augmentation.md | 24 +++--- .../source_zh_cn/use/load_dataset_image.md | 22 +++--- .../source_zh_cn/use/load_dataset_text.md | 21 ++---- 10 files changed, 87 insertions(+), 95 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/augmentation.md b/docs/programming_guide/source_zh_cn/augmentation.md index 7771869303..9f7586e269 100644 --- a/docs/programming_guide/source_zh_cn/augmentation.md +++ b/docs/programming_guide/source_zh_cn/augmentation.md @@ -375,7 +375,7 @@ Transformed image Shape: (3, 200, 200) , Transformed label: 3 ## 使用说明 -请勿混用`c_transforms`与`py_transforms`,因为`c_transforms`是在C++内维护buffer管理,`py_transforms`是在Python内维护buffer管理,两者混用会降低性能。 +请勿混用`c_transforms`与`py_transforms`,因为两者作用于图片的格式不同,混用会降低处理性能。 ![tranform_pipeline](./images/tranform_pipeline.png) diff --git a/docs/programming_guide/source_zh_cn/auto_augmentation.md b/docs/programming_guide/source_zh_cn/auto_augmentation.md index 32a727946a..cebc614030 100644 --- a/docs/programming_guide/source_zh_cn/auto_augmentation.md +++ b/docs/programming_guide/source_zh_cn/auto_augmentation.md @@ -12,7 +12,7 @@ - + ## 概述 diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index 2e21a74b41..19103afae3 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -19,7 +19,7 @@ ## 概述 -用户可以将非标准的数据集和常用的数据集转换为MindSpore数据格式,即MindRecord,从而方便地加载到MindSpore中进行训练。同时,MindSpore在部分场景做了性能优化,使用MindRecord可以获得更好的性能体验。 +用户可以将非标准的数据集和常用的数据集转换为MindSpore数据格式,即MindRecord,从而方便地加载到MindSpore中进行训练。同时,MindSpore在部分场景做了性能优化,使用MindRecord可以获得更好的性能。 ## 非标准数据集转换MindRecord diff --git a/docs/programming_guide/source_zh_cn/dataset_loading.md b/docs/programming_guide/source_zh_cn/dataset_loading.md index 1e39519c6a..433d6b31ca 100644 --- a/docs/programming_guide/source_zh_cn/dataset_loading.md +++ b/docs/programming_guide/source_zh_cn/dataset_loading.md @@ -220,24 +220,24 @@ TFRecord是TensorFlow定义的一种二进制数据文件格式。 ``` { - "datasetType": "TF", - "numRows": 3, "columns": { "image": { "type": "uint8", "rank": 1 }, "label" : { - "type": "int64", + "type": "string", "rank": 1 } + "id" : { + "type": "int64", + "rank": 0 + } } } ``` - - `datasetType`: 数据格式的类型,这里`TF`是指TFRecord数据格式。 - - `columns`:列信息字段,需要根据数据集的实际列名定义,上面Schema文件示例中,数据集列为`image`和`label`两列。 - - `numRows`:行数信息字段,控制加载数据的最大行数。如果定义的行数大于实际行数,加载时则以实际行数为准。 + - `columns`:列信息字段,需要根据数据集的实际列名定义。上面的示例中,数据集列为`image`、`label`和`id`。 然后在创建`TFRecordDataset`时将Schema文件路径传入。 diff --git a/docs/programming_guide/source_zh_cn/sampler.md b/docs/programming_guide/source_zh_cn/sampler.md index 4c6ccbca2f..ef44e3089d 100644 --- a/docs/programming_guide/source_zh_cn/sampler.md +++ b/docs/programming_guide/source_zh_cn/sampler.md @@ -18,7 +18,7 @@ ## 概述 -MindSpore提供了多种用途的采样器,帮助用户对数据集进行不同形式的采样,以满足训练需求,能够解决诸如数据集过大或样本类别分布不均等问题。只需在加载数据集时传入采样器对象,即可实现数据的采样。 +MindSpore提供了多种用途的采样器(Sampler),帮助用户对数据集进行不同形式的采样,以满足训练需求,能够解决诸如数据集过大或样本类别分布不均等问题。只需在加载数据集时传入采样器对象,即可实现数据的采样。 MindSpore目前提供的采样器类别如下表所示。此外,用户也可以根据需要实现自定义的采样器类。 @@ -94,9 +94,9 @@ DATA_DIR = "Cifar10Data/" weights = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0] sampler = ds.WeightedRandomSampler(weights, num_samples=6) -dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) +dataset = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -for data in dataset1.create_dict_iterator(): +for data in dataset.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` @@ -126,9 +126,9 @@ DATA_DIR = "Cifar10Data/" indices = [0, 1, 2, 3, 4, 5] sampler = ds.SubsetRandomSampler(indices, num_samples=3) -dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) +dataset = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -for data in dataset1.create_dict_iterator(): +for data in dataset.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` @@ -154,9 +154,9 @@ ds.config.set_seed(3) DATA_DIR = "Cifar10Data/" sampler = ds.PKSampler(num_val=2, class_column='label', num_samples=20) -dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) +dataset = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -for data in dataset1.create_dict_iterator(): +for data in dataset.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` @@ -228,9 +228,9 @@ class MySampler(ds.Sampler): DATA_DIR = "Cifar10Data/" -dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=MySampler()) +dataset = ds.Cifar10Dataset(DATA_DIR, sampler=MySampler()) -for data in dataset1.create_dict_iterator(): +for data in dataset.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` diff --git a/docs/programming_guide/source_zh_cn/tokenizer.md b/docs/programming_guide/source_zh_cn/tokenizer.md index ef7eb64c9d..1b4ae83b49 100644 --- a/docs/programming_guide/source_zh_cn/tokenizer.md +++ b/docs/programming_guide/source_zh_cn/tokenizer.md @@ -20,7 +20,7 @@ 分词就是将连续的字序列按照一定的规范重新组合成词序列的过程,合理的进行分词有助于语义的理解。 -MindSpore提供了多种用途的分词器,能够帮助用户高性能地处理文本,用户可以构建自己的字典,使用适当的标记器将句子拆分为不同的标记,并通过查找操作获取字典中标记的索引。 +MindSpore提供了多种用途的分词器(Tokenizer),能够帮助用户高性能地处理文本,用户可以构建自己的字典,使用适当的标记器将句子拆分为不同的标记,并通过查找操作获取字典中标记的索引。 MindSpore目前提供的分词器如下表所示。此外,用户也可以根据需要实现自定义的分词器。 @@ -56,7 +56,7 @@ input_list = ["床前明月光", "疑是地上霜", "举头望明月", "低头 "😀嘿嘿😃哈哈😄大笑😁嘻嘻", "繁體字"] dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) -print("------------------------before tokenize----------------------------") +print("------------------------before tokenization----------------------------") for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) @@ -71,17 +71,16 @@ vocab = text.Vocab.from_list(vocab_list) tokenizer_op = text.BertTokenizer(vocab=vocab) dataset = dataset.map(operations=tokenizer_op) -print("------------------------after tokenize-----------------------------") +print("------------------------after tokenization-----------------------------") for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']) - print(token) + print(text.to_str(i['text'])) ``` 输出结果如下: ``` -------------------------before tokenize---------------------------- +------------------------before tokenization---------------------------- 床前明月光 疑是地上霜 举头望明月 @@ -89,7 +88,7 @@ for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): I am making small mistakes during working hours 😀嘿嘿😃哈哈😄大笑😁嘻嘻 繁體字 -------------------------after tokenize----------------------------- +------------------------after tokenization----------------------------- ['床' '前' '明' '月' '光'] ['疑' '是' '地' '上' '霜'] ['举' '头' '望' '明' '月'] @@ -113,7 +112,7 @@ input_list = ["床前明月光", "疑是地上霜", "举头望明月", "低头 "😀嘿嘿😃哈哈😄大笑😁嘻嘻", "繁體字"] dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) -print("------------------------before tokenize----------------------------") +print("------------------------before tokenization----------------------------") for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) @@ -123,19 +122,18 @@ MP_FILE = "jieba.dict.utf8" jieba_op = text.JiebaTokenizer(HMM_FILE, MP_FILE) dataset = dataset.map(operations=jieba_op, input_columns=["text"], num_parallel_workers=1) -print("------------------------after tokenize-----------------------------") +print("------------------------after tokenization-----------------------------") for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']) - print(token) + print(text.to_str(i['text'])) ``` 输出结果如下: ``` -------------------------before tokenize---------------------------- +------------------------before tokenization---------------------------- 今天天气太好了我们一起去外面玩吧 -------------------------after tokenize----------------------------- +------------------------after tokenization----------------------------- ['今天天气' '太好了' '我们' '一起' '去' '外面' '玩吧'] ``` @@ -152,28 +150,27 @@ import mindspore.dataset.text as text input_list = ["I saw a girl with a telescope."] dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) -print("------------------------before tokenize----------------------------") +print("------------------------before tokenization----------------------------") for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) -vocab = text.SentencePieceVocab.from_file([VOCAB_FILE], 5000, 0.9995, SentencePieceModel.UNIGRAM, {}) +vocab = text.SentencePieceVocab.from_dataset(dataset, 5000, 0.9995, SentencePieceModel.UNIGRAM, {}) tokenizer_op = text.SentencePieceTokenizer(vocab, out_type=SPieceTokenizerOutType.STRING) dataset = dataset.map(operations=tokenizer_op) -print("------------------------after tokenize-----------------------------") +print("------------------------after tokenization-----------------------------") for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']) - print(token) + print(text.to_str(i['text'])) ``` 输出结果如下: ``` -------------------------before tokenize---------------------------- +------------------------before tokenization---------------------------- I saw a girl with a telescope. -------------------------after tokenize----------------------------- +------------------------after tokenization----------------------------- ['▁I' '▁sa' 'w' '▁a' '▁girl' '▁with' '▁a' '▁te' 'les' 'co' 'pe' '.'] ``` @@ -190,7 +187,7 @@ import mindspore.dataset.text as text input_list = ["Welcome to Beijing!", "北京欢迎您!", "我喜欢English!"] dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) -print("------------------------before tokenize----------------------------") +print("------------------------before tokenization----------------------------") for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) @@ -198,21 +195,20 @@ for data in dataset.create_dict_iterator(output_numpy=True): tokenizer_op = text.UnicodeCharTokenizer() dataset = dataset.map(operations=tokenizer_op) -print("------------------------after tokenize-----------------------------") +print("------------------------after tokenization-----------------------------") for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']).tolist() - print(token) + print(text.to_str(i['text']).tolist()) ``` 输出结果如下: ``` -------------------------before tokenize---------------------------- +------------------------before tokenization---------------------------- Welcome to Beijing! 北京欢迎您! 我喜欢English! -------------------------after tokenize----------------------------- +------------------------after tokenization----------------------------- ['W', 'e', 'l', 'c', 'o', 'm', 'e', ' ', 't', 'o', ' ', 'B', 'e', 'i', 'j', 'i', 'n', 'g', '!'] ['北', '京', '欢', '迎', '您', '!'] ['我', '喜', '欢', 'E', 'n', 'g', 'l', 'i', 's', 'h', '!'] @@ -231,7 +227,7 @@ import mindspore.dataset.text as text input_list = ["Welcome to Beijing!", "北京欢迎您!", "我喜欢English!"] dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) -print("------------------------before tokenize----------------------------") +print("------------------------before tokenization----------------------------") for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) @@ -239,22 +235,20 @@ for data in dataset.create_dict_iterator(output_numpy=True): tokenizer_op = text.WhitespaceTokenizer() dataset = dataset.map(operations=tokenizer_op) -print("------------------------after tokenize-----------------------------") +print("------------------------after tokenization-----------------------------") for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']).tolist() - print(token) + print(text.to_str(i['text']).tolist()) ``` 输出结果如下: ``` ->> Tokenize Result -------------------------before tokenize---------------------------- +------------------------before tokenization---------------------------- Welcome to Beijing! 北京欢迎您! 我喜欢English! -------------------------after tokenize----------------------------- +------------------------after tokenization----------------------------- ['Welcome', 'to', 'Beijing!'] ['北京欢迎您!'] ['我喜欢English!'] @@ -270,29 +264,28 @@ Welcome to Beijing! import mindspore.dataset as ds import mindspore.dataset.text as text -input_list = ["my", "favorite", "book", "is", "love", "during", "the", "cholera", "era", "what", "我", "最", "喜", "欢", "的", "书", "是", "霍", "乱", "时", "期", "的", "爱", "情", "您"] +input_list = ["my", "favorite", "book", "is", "love", "during", "the", "cholera", "era", "what", "我", "最", "喜", "欢", "书", "是", "霍", "乱", "时", "期", "的", "爱", "情", "您"] dataset = ds.NumpySlicesDataset(input_list, column_names=["text"], shuffle=False) -print("------------------------before tokenize----------------------------") +print("------------------------before tokenization----------------------------") for data in dataset.create_dict_iterator(output_numpy=True): print(text.to_str(data['text'])) -vocab = text.Vocab.from_list(vocab_list) +vocab = text.Vocab.from_list(input_list) tokenizer_op = text.WordpieceTokenizer(vocab=vocab) dataset = dataset.map(operations=tokenizer_op) -print("------------------------after tokenize-----------------------------") +print("------------------------after tokenization-----------------------------") for i in dataset.create_dict_iterator(num_epochs=1, output_numpy=True): - token = text.to_str(i['text']) - print(token) + print(text.to_str(i['text'])) ``` 输出结果如下: ``` -------------------------before tokenize---------------------------- +------------------------before tokenization---------------------------- my favorite book @@ -318,7 +311,7 @@ what 爱 情 您 -------------------------after tokenize----------------------------- +------------------------after tokenization----------------------------- ['my'] ['favor' '##ite'] ['book'] diff --git a/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md index 66f46b093b..3261cbdbc2 100644 --- a/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md +++ b/tutorials/training/source_zh_cn/advanced_use/accelerate_data_processing.md @@ -15,11 +15,11 @@ ## 概述 -数据处理的性能涉及到多方面的因素,包括脚本撰写、操作系统等。 +数据是整个深度学习中重要的一环,合理地对数据进行处理,会在整个深度神经网络中起到积极作用。数据处理的性能涉及到多方面的因素,下面将从脚本撰写和操作系统方面阐述如何优化性能。 ## 脚本撰写 -数据处理的脚本大致分为以下几个模块: +数据处理的脚本大致分为数据加载、数据混洗、数据增强、`batch`和`repeat`等模块。 ![dataset_pipeline](./images/dataset_pipeline.png) diff --git a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md index ea35460c88..998b63206f 100644 --- a/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md +++ b/tutorials/training/source_zh_cn/advanced_use/enable_auto_augmentation.md @@ -46,15 +46,15 @@ MindSpore算子和AutoAugment中的算子的对应关系如下: 用户可以使用MindSpore中`c_transforms`模块的`RandomSelectSubpolicy`接口来实现AutoAugment, 在ImageNet分类训练中标准的数据增强方式分以下几个步骤: -一. `RandomCropDecodeResize`:随机裁剪后进行解码。 +- `RandomCropDecodeResize`:随机裁剪后进行解码。 -二. `RandomHorizontalFlip`:水平方向上随机翻转。 +- `RandomHorizontalFlip`:水平方向上随机翻转。 -三. `Normalize`:归一化。 +- `Normalize`:归一化。 -四. `HWC2CHW`:shape变换。 +- `HWC2CHW`:图片通道变化。 -在步骤一后插入AutoAugment变换,如下所示: +在`RandomCropDecodeResize`后插入AutoAugment变换,如下所示: 1. 引入MindSpore数据增强模块。 @@ -196,16 +196,16 @@ MindSpore算子和AutoAugment中的算子的对应关系如下: c_vision.Normalize(mean=mean, std=std), c_vision.HWC2CHW() ] - ds = ds.map(operations=trans, input_columns="image", num_parallel_workers=8) + ds = ds.map(operations=trans, input_columns="image") if do_train: ds = ds.map(operations=c_vision.RandomSelectSubpolicy(imagenet_policy), input_columns=["image"]) - ds = ds.map(operations=post_trans, input_columns=["image"], num_parallel_workers=8) + ds = ds.map(operations=post_trans, input_columns="image") type_cast_op = c_transforms.TypeCast(mstype.int32) - ds = ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) - # apply batch operations + ds = ds.map(operations=type_cast_op, input_columns="label") + # apply batch operation ds = ds.batch(batch_size, drop_remainder=True) - # apply dataset repeat operation + # apply repeat operation ds = ds.repeat(repeat_num) return ds @@ -238,8 +238,8 @@ MindSpore算子和AutoAugment中的算子的对应关系如下: ![augment](./images/auto_augmentation.png) - 运行结果可以看到,batch中每张图像的增强效果,X方向表示1个batch的5张图像,Y方向表示5个bacth。 - + 运行结果可以看到,batch中每张图像的增强效果,水平方向表示1个batch的5张图像,垂直方向表示5个bacth。 + ## 参考文献 [1] [AutoAugment: Learning Augmentation Policies from Data](https://arxiv.org/abs/1805.09501) diff --git a/tutorials/training/source_zh_cn/use/load_dataset_image.md b/tutorials/training/source_zh_cn/use/load_dataset_image.md index 540da9ab61..58ca834501 100644 --- a/tutorials/training/source_zh_cn/use/load_dataset_image.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_image.md @@ -47,7 +47,6 @@ MindSpore目前支持加载图像领域常用的经典数据集和多种数据 ```python DATA_DIR = "./MNIST" - # 为方便展示,指定num_samples只获取6个样本 mnist_dataset = ds.MnistDataset(DATA_DIR, num_samples=6, shuffle=False) ``` @@ -56,7 +55,6 @@ MindSpore目前支持加载图像领域常用的经典数据集和多种数据 ```python import matplotlib.pyplot as plt - # 创建迭代器并展示样本及标签 mnist_it = mnist_dataset.create_dict_iterator() data = mnist_it.get_next() plt.imshow(data['image'].asnumpy().squeeze(), cmap=plt.cm.gray) @@ -64,6 +62,8 @@ MindSpore目前支持加载图像领域常用的经典数据集和多种数据 plt.show() ``` + 图片展示如下: + ![mnist_5](./images/mnist_5.png) 此外,用户还可以在数据集加载时传入sampler指定数据采样方式。MindSpore目前支持的数据采样器及其详细使用方法,可参考编程指南中[采样器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/sampler.html)章节。 @@ -75,11 +75,12 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 下面演示构建pipeline,对MNIST数据集进行`shuffle`、`batch`、`repeat`等操作。 ```python -# 查看原始数据label for data in mnist_dataset.create_dict_iterator(): print(data['label']) ``` +输出结果如下: + ```python 5 0 @@ -92,15 +93,15 @@ for data in mnist_dataset.create_dict_iterator(): 1. 对数据集进行混洗。 ```python - # 固定随机种子便于展示混洗结果 ds.config.set_seed(58) - ds1 = mnist_dataset.shuffle(buffer_size=6) - # 查看混洗后数据label + for data in ds1.create_dict_iterator(): print(data['label']) ``` + 输出结果如下: + ```python 4 2 @@ -114,11 +115,13 @@ for data in mnist_dataset.create_dict_iterator(): ```python ds2 = ds1.batch(batch_size=2) - # 查看分批后数据label + for data in ds2.create_dict_iterator(): print(data['label']) ``` + 输出结果如下: + ```python [4 2] [1 0] @@ -129,11 +132,13 @@ for data in mnist_dataset.create_dict_iterator(): ```python ds3 = ds2.repeat(count=2) - # 查看复制后数据label + for data in ds3.create_dict_iterator(): print(data['label']) ``` + 输出结果如下: + ```python [4 2] [1 0] @@ -159,7 +164,6 @@ MindSpore目前支持的数据增强算子及其详细使用方法,可参考 from mindspore.dataset.vision import Inter import mindspore.dataset.vision.c_transforms as transforms - # 重新加载数据集 mnist_dataset = ds.MnistDataset(DATA_DIR, num_samples=6, shuffle=False) ``` diff --git a/tutorials/training/source_zh_cn/use/load_dataset_text.md b/tutorials/training/source_zh_cn/use/load_dataset_text.md index 824b236734..4d2f4f7bf8 100644 --- a/tutorials/training/source_zh_cn/use/load_dataset_text.md +++ b/tutorials/training/source_zh_cn/use/load_dataset_text.md @@ -81,7 +81,7 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 - **SlidingWindow** - `TensorOp`从数据(现在仅是1-D)构造张量,其中尺寸轴上的每个元素都是从指定位置开始并具有指定宽度的数据切片。 + 下面演示使用`SlidingWindow`对文本数据进行切片操作。 1. 加载数据集。 @@ -97,6 +97,8 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 print(text.to_str(data['text']).tolist()) ``` + 输出结果如下: + ``` ['大', '家', '早', '上', '好'] ``` @@ -114,6 +116,8 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 print(text.to_str(data['text']).tolist()) ``` + 输出结果如下: + ``` [['大', '家'], ['家', '早'], @@ -123,13 +127,13 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 - **shuffle** - 当`shuffle=True`时,对数据集进行随机输出。 + 下面演示在加载数据集时使用`shuffle`对文本数据进行混洗操作。 1. 加载数据集。 ```python inputs = ["a", "b", "c", "d"] - dataset = ds.NumpySlicesDataset(inputs, column_names=["text"], shuffle=False) + dataset = ds.NumpySlicesDataset(inputs, column_names=["text"], shuffle=True) ``` 2. 数据输出效果。 @@ -139,7 +143,7 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 print(text.to_str(data['text']).tolist()) ``` - 第一次输出: + 输出结果如下: ``` c @@ -148,15 +152,6 @@ MindSpore目前支持的数据处理算子及其详细使用方法,可参考 b ``` - 第二次输出: - - ``` - b - a - c - d - ``` - ## 数据分词 MindSpore目前支持的数据分词算子及其详细使用方法,可参考编程指南中[分词器](https://www.mindspore.cn/api/zh-CN/master/programming_guide/tokenizer.html)章节。 -- Gitee From 7789dfcc90144d8defb9ee87008dcda5b766f4f3 Mon Sep 17 00:00:00 2001 From: lihongkang <[lihongkang1@huawei.com]> Date: Fri, 18 Sep 2020 21:24:20 +0800 Subject: [PATCH 096/100] update op list --- docs/programming_guide/source_en/operator_list.md | 2 ++ docs/programming_guide/source_zh_cn/operator_list_ms.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/programming_guide/source_en/operator_list.md b/docs/programming_guide/source_en/operator_list.md index b50fdcb41f..1fc434c418 100644 --- a/docs/programming_guide/source_en/operator_list.md +++ b/docs/programming_guide/source_en/operator_list.md @@ -354,6 +354,8 @@ | [mindspore.ops.operations.Xdivy](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xdivy) | Supported | Doing | Doing | math_ops | [mindspore.ops.operations.Xlogy](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xlogy) | Supported | Doing | Doing | math_ops | [mindspore.ops.operations.HistogramFixedWidth](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.HistogramFixedWidth) | Supported | Doing | Doing | math_ops +| [mindspore.ops.operations.Eps](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Eps) | Supported | Supported | Doing | math_ops +| [mindspore.ops.operations.ReLUV2](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReLUV2) | Supported | Doing | Doing | nn_ops ## mindspore.ops.functional diff --git a/docs/programming_guide/source_zh_cn/operator_list_ms.md b/docs/programming_guide/source_zh_cn/operator_list_ms.md index 8ae072ecd4..80cfad80e9 100644 --- a/docs/programming_guide/source_zh_cn/operator_list_ms.md +++ b/docs/programming_guide/source_zh_cn/operator_list_ms.md @@ -354,6 +354,8 @@ | [mindspore.ops.operations.Xdivy](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xdivy) | Supported | Doing | Doing | math_ops | [mindspore.ops.operations.Xlogy](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xlogy) | Supported | Doing | Doing | math_ops | [mindspore.ops.operations.HistogramFixedWidth](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.HistogramFixedWidth) | Supported | Doing | Doing | math_ops +| [mindspore.ops.operations.Eps](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Eps) | Supported | Supported | Doing | math_ops +| [mindspore.ops.operations.ReLUV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReLUV2) | Supported | Doing | Doing | nn_ops ## mindspore.ops.functional -- Gitee From 3af057d69d0e8a4ead1e1119638437bd20663349 Mon Sep 17 00:00:00 2001 From: ZPaC Date: Sat, 19 Sep 2020 09:34:42 +0800 Subject: [PATCH 097/100] Fix 'forward computation gradient' mistake --- .../source_en/advanced_use/apply_parameter_server_training.md | 2 +- .../advanced_use/apply_parameter_server_training.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md b/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md index 04899d9c37..d73b2390c6 100644 --- a/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md +++ b/tutorials/training/source_en/advanced_use/apply_parameter_server_training.md @@ -25,7 +25,7 @@ The ps-lite architecture consists of three independent components: server, worke - Server: saves model weights and backward computation gradients, and updates the model using gradients pushed by workers. -- Worker: performs forward and backward computation on the network. The gradient value for forward computation is uploaded to a server through the `Push` API, and the model updated by the server is downloaded to the worker through the `Pull` API. +- Worker: performs forward and backward computation on the network. The gradient value for backward computation is uploaded to a server through the `Push` API, and the model updated by the server is downloaded to the worker through the `Pull` API. - Scheduler: establishes the communication relationship between the server and worker. diff --git a/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md index 7fe27367e2..9e932e4e30 100644 --- a/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md +++ b/tutorials/training/source_zh_cn/advanced_use/apply_parameter_server_training.md @@ -25,7 +25,7 @@ Parameter Server(参数服务器)是分布式训练中一种广泛使用的架 - Server:保存模型的权重和反向计算的梯度值,并使用优化器通过Worker上传的梯度值对模型进行更新。 -- Worker:执行网络的正反向计算,正向计算的梯度值通过Push接口上传至Server中,通过Pull接口把Server更新好的模型下载到Worker本地。 +- Worker:执行网络的正反向计算,反向计算的梯度值通过Push接口上传至Server中,通过Pull接口把Server更新好的模型下载到Worker本地。 - Scheduler:用于建立Server和Worker的通信关系。 -- Gitee From a9214809c729bab185a7a82945163513015deed2 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Sat, 19 Sep 2020 09:37:29 +0800 Subject: [PATCH 098/100] Fix the link for markdown --- .../use/post_training_quantization.md | 6 +-- tutorials/lite/source_zh_cn/use/runtime.md | 2 +- .../source_zh_cn/use/timeprofiler_tool.md | 6 +-- ...nsight_image_histogram_scalar_tensor.ipynb | 46 +++++++++---------- tutorials/notebook/quick_start.ipynb | 4 +- ...chronization_training_and_evaluation.ipynb | 2 +- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tutorials/lite/source_zh_cn/use/post_training_quantization.md b/tutorials/lite/source_zh_cn/use/post_training_quantization.md index b5c7410c40..49d3fbbdce 100644 --- a/tutorials/lite/source_zh_cn/use/post_training_quantization.md +++ b/tutorials/lite/source_zh_cn/use/post_training_quantization.md @@ -15,7 +15,7 @@ - + ## 概述 @@ -26,7 +26,7 @@ MindSpore Lite训练后量化分为两类: 1. 权重量化:单独对模型的权值进行量化; 2. 全量化:对模型的权值、激活值、bias值统一进行量化。 -训练后量化在两种情况下所需的数据类型和参数设定不同,但均可通过转换工具设定。有关转换工具`converter_lite`的使用方法可参考[转换为MindSpore Lite模型](https://www.mindspore.cn/lite/tutorial/zh-CN/master/use/converter_tool.html)。在此基础之上进行配置,启用训练后量化。 +训练后量化在两种情况下所需的数据类型和参数设定不同,但均可通过转换工具设定。有关转换工具`converter_lite`的使用方法可参考[转换为MindSpore Lite模型](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.0/use/converter_tool.html)。在此基础之上进行配置,启用训练后量化。 ## 权重量化 @@ -52,7 +52,7 @@ MindSpore Lite训练后量化分为两类: ### 使用步骤 -1. 正确编译出`converter_lite`可执行文件。该部分可参考构建文档[编译MindSpore Lite](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html),获得`converter_lite`工具,并配置环境变量。 +1. 正确编译出`converter_lite`可执行文件。该部分可参考构建文档[编译MindSpore Lite](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.0/use/build.html),获得`converter_lite`工具,并配置环境变量。 2. 以TensorFlow Lite模型为例,执行权重量化模型转换命令: ``` ./converter_lite --fmk=TFLITE --modelFile=Inception_v3.tflite --outputFile=Inception_v3.tflite --quantType=WeightQuant --bitNum=8 --quantSize=0 --convWeightQuantChannelThreshold=0 diff --git a/tutorials/lite/source_zh_cn/use/runtime.md b/tutorials/lite/source_zh_cn/use/runtime.md index b3460b5042..b63d69771d 100644 --- a/tutorials/lite/source_zh_cn/use/runtime.md +++ b/tutorials/lite/source_zh_cn/use/runtime.md @@ -35,7 +35,7 @@ - + ## 概述 diff --git a/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md b/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md index 7c7a60576b..bec1da2fad 100644 --- a/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md +++ b/tutorials/lite/source_zh_cn/use/timeprofiler_tool.md @@ -10,7 +10,7 @@ - + ## 概述 @@ -20,9 +20,9 @@ 使用TimeProfiler工具,需要进行如下环境准备工作。 -- 编译:TimeProfiler工具代码在MindSpore源码的`mindspore/lite/tools/time_profiler`目录中,参考构建文档中的[环境要求](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id1)和[编译示例](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id3)执行编译。 +- 编译:TimeProfiler工具代码在MindSpore源码的`mindspore/lite/tools/time_profiler`目录中,参考构建文档中的[环境要求](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.0/use/build.html#id1)和[编译示例](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.0/use/build.html#id3)执行编译。 -- 运行:参考部署文档中的[编译输出](https://www.mindspore.cn/lite/tutorial/zh-CN/master/build.html#id4),获得`timeprofiler`工具,并配置环境变量。 +- 运行:参考部署文档中的[编译输出](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.0/use/build.html#id4),获得`timeprofiler`工具,并配置环境变量。 ## 使用示例 diff --git a/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb b/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb index f1fb22e942..83864c1f49 100644 --- a/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb +++ b/tutorials/notebook/mindinsight/mindinsight_image_histogram_scalar_tensor.ipynb @@ -305,10 +305,10 @@ "\n", "当前支持的Summary算子:\n", "\n", - "- [ScalarSummary](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html?highlight=scalarsummary#mindspore.ops.operations.ScalarSummary): 记录标量数据\n", - "- [TensorSummary](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html?highlight=tensorsummary#mindspore.ops.operations.TensorSummary): 记录张量数据\n", - "- [ImageSummary](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html?highlight=imagesummary#mindspore.ops.operations.ImageSummary): 记录图片数据\n", - "- [HistogramSummary](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html?highlight=histogramsummar#mindspore.ops.operations.HistogramSummary): 将张量数据转为直方图数据记录" + "- [ScalarSummary](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.ops.html#mindspore.ops.ScalarSummary): 记录标量数据\n", + "- [TensorSummary](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.ops.html#mindspore.ops.TensorSummary): 记录张量数据\n", + "- [ImageSummary](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/api/mindspore/mindspore.ops.html#mindspore.ops.ImageSummary): 记录图片数据\n", + "- [HistogramSummary](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.ops.html#mindspore.ops.HistogramSummary): 将张量数据转为直方图数据记录" ] }, { @@ -393,7 +393,7 @@ "\n", "下面展示使用`SummaryCollector`来记录标量、直方图信息。\n", "\n", - "在MindSpore中通过`Callback`机制,提供支持快速简易地收集损失值、参数权重、梯度等信息的`Callback`, 叫做`SummaryCollector`(详细的用法可以参考API文档中[mindspore.train.callback.SummaryCollector](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.train.html?highlight=summarycollector#mindspore.train.callback.SummaryCollector))。`SummaryCollector`使用方法如下: \n", + "在MindSpore中通过`Callback`机制,提供支持快速简易地收集损失值、参数权重、梯度等信息的`Callback`, 叫做`SummaryCollector`(详细的用法可以参考API文档中[mindspore.train.callback.SummaryCollector](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.train.html#mindspore.train.callback.SummaryCollector))。`SummaryCollector`使用方法如下: \n", "\n", "`SummaryCollector` 提供 `collect_specified_data` 参数,允许自定义想要收集的数据。\n", "\n", @@ -577,17 +577,17 @@ "\n", "在本地浏览器中打开地址:`127.0.0.1:8080`,进入到可视化面板。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/mindinsight_panel.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/mindinsight_panel.png)\n", "\n", "在上图所示面板中可以看到`summary_01`日志文件目录,点击**训练看板**进入到下图所示的训练数据展示面板,该面板展示了标量数据、直方图、图像和张量信息,并随着训练、测试的进行实时刷新数据,实时显示训练过程参数的变化情况。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/mindinsight_panel2.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/mindinsight_panel2.png)\n", "\n", "### 标量可视化\n", "\n", "标量可视化用于展示训练过程中标量的变化趋势,点击打开标量信息展示面板,该面板记录了迭代计算过程中的损失值标量信息,如下图展示了损失值标量趋势图。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/scalar_panel.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/scalar_panel.png)\n", "\n", "上图展示了神经网络在训练过程中损失值的变化过程。横坐标是训练步骤,纵坐标是损失值。\n", "\n", @@ -599,7 +599,7 @@ "- 分步回退是指对同一个区域连续框选并放大查看时,可以逐步撤销操作。\n", "- 还原图形是指进行了多次框选后,点击此按钮可以将图还原回原始状态。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/scalar_select.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/scalar_select.png)\n", "\n", "上图展示的标量可视化的功能区,提供了根据选择不同标签,水平轴的不同维度和平滑度来查看标量信息的功能。\n", "\n", @@ -614,15 +614,15 @@ "\n", "直方图用于将用户所指定的张量以直方图的形式展示。点击打开直方图展示面板,以直方图的形式记录了在迭代过程中所有层参数分布信息。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/histogram_panel.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/histogram_panel.png)\n", "\n", "如下图为`conv1`层参数分布信息,点击图中右上角,可以将图放大。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/histogram.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/histogram.png)\n", "\n", "下图为直方图功能区。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/histogram_func.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/histogram_func.png)\n", "\n", "上图展示直方图的功能区,包含以下内容:\n", "\n", @@ -636,11 +636,11 @@ "\n", "下图为展示`summary_01`记录的图像信息。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/image_panel.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/image_panel.png)\n", "\n", "通过滑动上图中的\"步骤\"滑条,查看不同步骤的图片。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/image_function.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/image_function.png)\n", "\n", "上图展示图像可视化的功能区,提供了选择查看不同标签,不同亮度和不同对比度来查看图片信息。\n", "\n", @@ -652,7 +652,7 @@ "\n", "张量可视化用于将张量以表格以及直方图的形式进行展示。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/tensor_func.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/tensor_func.png)\n", "\n", "上图展示了张量可视化的功能区,包含以下内容:\n", "\n", @@ -661,7 +661,7 @@ "- 纵轴:可以选择步骤、相对时间、绝对时间中的任意一项,来作为直方图纵轴显示的数据。\n", "- 视角:可以选择正视和俯视中的一种。正视是指从正面的角度查看直方图,此时不同步骤之间的数据会覆盖在一起。俯视是指 偏移以45度角俯视直方图区域,这时可以呈现不同步骤之间数据的差异。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/tensor.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/tensor.png)\n", "\n", "上图中将用户所记录的张量以表格的形式展示,包含以下功能:\n", "\n", @@ -804,7 +804,7 @@ "source": [ "此时点击打开MindInsight**训练列表**看板中的`./summary_loss_only`目录,如下图所示,可以看到只记录有损失值标量信息。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/loss_scalar_only.png)" + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/loss_scalar_only.png)" ] }, { @@ -900,11 +900,11 @@ "source": [ "此时点击打开MindInsight**训练列表**看板中的`./summary_histogram_only`目录。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/histogram_only.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/histogram_only.png)\n", "\n", "在MindInsight面板中,如上图所示,只展示了直方图信息。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/histogram_only_all.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/histogram_only_all.png)\n", "\n", "点击进入直方图面板,如上图所示,只展示了`conv1`层的直方图信息。" ] @@ -1043,7 +1043,7 @@ "source": [ "此时点击打开MindInsight**训练列表**看板中的`./summary_tensor_only`目录,如下图所示,可以看到只记录有张量信息。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/tensor_only.png)" + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/tensor_only.png)" ] }, { @@ -1177,7 +1177,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/image_only.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/image_only.png)\n", "\n", "在MindInsight面板中,如上图所示,只展示了输入图像信息。" ] @@ -1192,11 +1192,11 @@ "\n", "点击MindInsight看板中的**对比看板**,打开对比看板,可以得到多次(不同)训练搜集到的标量数据对比信息。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/multi_scalars.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/multi_scalars.png)\n", "\n", "上图展示了`summary_01`(上图中红色曲线)和`summary_loss_only`(上图中蓝色曲线)的标量曲线对比效果,横坐标是训练步骤,纵坐标是标量值。\n", "\n", - "![](https://gitee.com/mindspore/docs/raw/master/tutorials/notebook/mindinsight/images/multi_scalars_select.png)\n", + "![](https://gitee.com/mindspore/docs/raw/r1.0/tutorials/notebook/mindinsight/images/multi_scalars_select.png)\n", "\n", "上图展示的对比看板可视的功能区,提供了根据选择不同训练或标签,水平轴的不同维度和平滑度来进行标量对比的功能。\n", "\n", diff --git a/tutorials/notebook/quick_start.ipynb b/tutorials/notebook/quick_start.ipynb index 99757efd66..caecc17131 100644 --- a/tutorials/notebook/quick_start.ipynb +++ b/tutorials/notebook/quick_start.ipynb @@ -34,7 +34,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "说明:
      你可以在这里找到完整可运行的样例代码:" + "说明:
      你可以在这里找到完整可运行的样例代码:" ] }, { @@ -508,7 +508,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"LeNet5\"" + "\"LeNet5\"" ] }, { diff --git a/tutorials/notebook/synchronization_training_and_evaluation.ipynb b/tutorials/notebook/synchronization_training_and_evaluation.ipynb index 8c22d397b8..3a1d5ecaa3 100644 --- a/tutorials/notebook/synchronization_training_and_evaluation.ipynb +++ b/tutorials/notebook/synchronization_training_and_evaluation.ipynb @@ -208,7 +208,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "实现思想:每隔n个epoch验证一次模型精度,由于在自定义函数中实现,如需了解自定义回调函数的详细用法,请参考[API说明](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.train.html?highlight=callback#mindspore.train.callback.Callback)。\n", + "实现思想:每隔n个epoch验证一次模型精度,由于在自定义函数中实现,如需了解自定义回调函数的详细用法,请参考[API说明](https://www.mindspore.cn/doc/api_python/zh-CN/r1.0/mindspore/mindspore.train.html#mindspore.train.callback.Callback)。\n", "\n", "核心实现:回调函数的`epoch_end`内设置验证点,如下:\n", "\n", -- Gitee From 7e67279d37ee88dbe274985eca18bb8010a59f38 Mon Sep 17 00:00:00 2001 From: caozhou Date: Sat, 19 Sep 2020 10:19:02 +0800 Subject: [PATCH 099/100] fix interface due to the interface has been changed --- docs/programming_guide/source_zh_cn/api_structure.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/programming_guide/source_zh_cn/api_structure.md b/docs/programming_guide/source_zh_cn/api_structure.md index 4c13a8f12b..bf7c1f392e 100644 --- a/docs/programming_guide/source_zh_cn/api_structure.md +++ b/docs/programming_guide/source_zh_cn/api_structure.md @@ -40,7 +40,7 @@ def cost(x, y): return x * (x + y) def test_grad(x, y): - return C.grad_all(cost)(Tensor(x, dtype=ms.float32), Tensor(y, dtype=ms.float32)) + return C.GradOperation(get_all=True)(cost)(Tensor(x, dtype=ms.float32), Tensor(y, dtype=ms.float32)) def main(): @@ -62,7 +62,7 @@ MindSpore向用户提供了3个不同层次的API,支撑用户进行网络构 - Low-Level Python API - 第一层为低阶API,主要包括张量定义、基础算子、自动微分等模块,用户可使用低阶API轻松实现张量定义和求导计算,例如用户可通过`Tensor`接口自定义张量,使用`ops.composite`模块下的`grad_all`算子计算函数在指定处的导数。 + 第一层为低阶API,主要包括张量定义、基础算子、自动微分等模块,用户可使用低阶API轻松实现张量定义和求导计算,例如用户可通过`Tensor`接口自定义张量,使用`ops.composite`模块下的`GradOperation`算子计算函数在指定处的导数。 - Medium-Level Python API -- Gitee From 6ecfdc1a27f067c5140ddba4f59763dc8db40b0e Mon Sep 17 00:00:00 2001 From: Ting Wang Date: Sat, 19 Sep 2020 11:59:08 +0800 Subject: [PATCH 100/100] update contents for 1.0 Signed-off-by: Ting Wang --- docs/note/source_en/index.rst | 4 +- docs/note/source_en/network_list.rst | 7 + .../source_en/network_list_ms.md} | 6 +- docs/note/source_en/operator_list.rst | 10 ++ docs/note/source_en/operator_list_implicit.md | 104 +++++++++++ docs/note/source_en/operator_list_lite.md | 111 ++++++++++++ .../source_en/operator_list_ms.md} | 162 +----------------- docs/note/source_en/operator_list_parallel.md | 76 ++++++++ docs/note/source_en/specification_note.rst | 2 + docs/note/source_zh_cn/index.rst | 4 +- docs/note/source_zh_cn/network_list.rst | 7 + .../source_zh_cn/network_list_ms.md} | 6 +- docs/note/source_zh_cn/operator_list.rst | 10 ++ .../source_zh_cn/operator_list_implicit.md | 103 +++++++++++ docs/note/source_zh_cn/operator_list_lite.md | 111 ++++++++++++ .../source_zh_cn/operator_list_ms.md | 162 +----------------- .../source_zh_cn/operator_list_parallel.md | 75 ++++++++ docs/note/source_zh_cn/specification_note.rst | 2 + docs/programming_guide/source_en/index.rst | 14 ++ .../source_en/network_list.rst | 7 + .../source_en/operator_list.rst | 10 ++ .../source_en/operator_list_lite.md | 113 ------------ .../source_zh_cn/advanced_use.rst | 5 +- .../source_zh_cn/extension.rst | 7 + docs/programming_guide/source_zh_cn/index.rst | 5 +- docs/programming_guide/source_zh_cn/infer.md | 19 ++ .../source_zh_cn/network_list.rst | 7 + .../source_zh_cn/operator_list.rst | 6 +- .../source_zh_cn/operator_list_lite.md | 113 ------------ .../source_zh_cn/performance_optimization.md | 19 ++ .../source_zh_cn/user_defined.rst | 4 +- 31 files changed, 729 insertions(+), 562 deletions(-) create mode 100644 docs/note/source_en/network_list.rst rename docs/{programming_guide/source_en/network_list.md => note/source_en/network_list_ms.md} (97%) create mode 100644 docs/note/source_en/operator_list.rst create mode 100644 docs/note/source_en/operator_list_implicit.md create mode 100644 docs/note/source_en/operator_list_lite.md rename docs/{programming_guide/source_en/operator_list.md => note/source_en/operator_list_ms.md} (77%) create mode 100644 docs/note/source_en/operator_list_parallel.md create mode 100644 docs/note/source_zh_cn/network_list.rst rename docs/{programming_guide/source_zh_cn/network_list.md => note/source_zh_cn/network_list_ms.md} (97%) create mode 100644 docs/note/source_zh_cn/operator_list.rst create mode 100644 docs/note/source_zh_cn/operator_list_implicit.md create mode 100644 docs/note/source_zh_cn/operator_list_lite.md rename docs/{programming_guide => note}/source_zh_cn/operator_list_ms.md (77%) create mode 100644 docs/note/source_zh_cn/operator_list_parallel.md create mode 100644 docs/programming_guide/source_en/index.rst create mode 100644 docs/programming_guide/source_en/network_list.rst create mode 100644 docs/programming_guide/source_en/operator_list.rst delete mode 100644 docs/programming_guide/source_en/operator_list_lite.md create mode 100644 docs/programming_guide/source_zh_cn/extension.rst create mode 100644 docs/programming_guide/source_zh_cn/infer.md create mode 100644 docs/programming_guide/source_zh_cn/network_list.rst delete mode 100644 docs/programming_guide/source_zh_cn/operator_list_lite.md create mode 100644 docs/programming_guide/source_zh_cn/performance_optimization.md diff --git a/docs/note/source_en/index.rst b/docs/note/source_en/index.rst index d6befad46c..3e3751cfc8 100644 --- a/docs/note/source_en/index.rst +++ b/docs/note/source_en/index.rst @@ -11,5 +11,5 @@ MindSpore Note :maxdepth: 1 design - Specification_list - note + specification_note + others diff --git a/docs/note/source_en/network_list.rst b/docs/note/source_en/network_list.rst new file mode 100644 index 0000000000..e4b29f1e46 --- /dev/null +++ b/docs/note/source_en/network_list.rst @@ -0,0 +1,7 @@ +Network List +============ + +.. toctree:: + :maxdepth: 1 + + network_list_ms \ No newline at end of file diff --git a/docs/programming_guide/source_en/network_list.md b/docs/note/source_en/network_list_ms.md similarity index 97% rename from docs/programming_guide/source_en/network_list.md rename to docs/note/source_en/network_list_ms.md index 0cc5bb974e..6775c4fbbe 100644 --- a/docs/programming_guide/source_en/network_list.md +++ b/docs/note/source_en/network_list_ms.md @@ -1,16 +1,16 @@ -# Network List +# MindSpore Network List `Linux` `Ascend` `GPU` `CPU` `Model Development` `Intermediate` `Expert` -- [Network List](#network-list) +- [MindSpore Network List](#mindspore-network-list) - [Model Zoo](#model-zoo) - [Pre-trained Models](#pre-trained-models) - + ## Model Zoo diff --git a/docs/note/source_en/operator_list.rst b/docs/note/source_en/operator_list.rst new file mode 100644 index 0000000000..8a013bafdf --- /dev/null +++ b/docs/note/source_en/operator_list.rst @@ -0,0 +1,10 @@ +Operator List +============= + +.. toctree:: + :maxdepth: 1 + + operator_list_ms + operator_list_implicit + operator_list_parallel + operator_list_lite \ No newline at end of file diff --git a/docs/note/source_en/operator_list_implicit.md b/docs/note/source_en/operator_list_implicit.md new file mode 100644 index 0000000000..c36420936f --- /dev/null +++ b/docs/note/source_en/operator_list_implicit.md @@ -0,0 +1,104 @@ +# MindSpore Implicit Type Conversion Operator List + +`Linux` `Ascend` `GPU` `CPU` `Model Development` `Beginner` `Intermediate` `Expert` + + + +- [MindSpore Implicit Type Conversion Operator List](#mindspore-implicit-type-conversion-operator-list) + - [Implicit Type Conversion](#implicit-type-conversion) + - [conversion rules](#conversion-rules) + - [data types involved in conversion](#data-types-involved-in-conversion) + - [support ops](#support-ops) + + + + + +## Implicit Type Conversion + +### conversion rules +* Scalar and Tensor operations: during operation, the scalar is automatically converted to Tensor, and the data type is consistent with the Tensor data type involved in the operation; +when Tensor is a bool data type and the scalar is int or float, both the scalar and Tensor are converted to the Tensor with the data type of int32 or float32. +* Tensor operation of different data types: the priority of data type is bool < uint8 < int8 < int16 < int32 < int64 < float16 < float32 + +| Operation | CPU
      FP16 | CPU
      FP32 | CPU
      Int8 | CPU
      UInt8 | GPU
      FP16 | GPU
      FP32 | Tensorflow
      Lite op supported | Caffe
      Lite op supported | Onnx
      Lite op supported | +|-----------------------|----------|----------|-----------|----------|----------|------------------|----------|----------|----------| +| Abs | | Supported | Supported | Supported | Supported | Supported | Abs | | Abs | +| Add | Supported | Supported | Supported | Supported | Supported | Supported | Add | | Add | +| AddN | | Supported | | | | | AddN | | | +| Argmax | | Supported | Supported | Supported | | | Argmax | ArgMax | ArgMax | +| Argmin | | Supported | Supported | Supported | | | Argmin | | | +| AvgPool | Supported | Supported | Supported | Supported | Supported | Supported | MeanPooling| Pooling | AveragePool | +| BatchNorm | Supported | Supported | Supported | Supported | Supported | Supported | | BatchNorm | BatchNormalization | +| BatchToSpace | | Supported | Supported | Supported | | | BatchToSpace, BatchToSpaceND | | | +| BiasAdd | | Supported | Supported | Supported | Supported | Supported | | | BiasAdd | +| Broadcast | | Supported | | | | | BroadcastTo | | Expand | +| Cast | Supported | Supported | | Supported | Supported | Supported | Cast, DEQUANTIZE* | | Cast | +| Ceil | | Supported | Supported | Supported | Supported | Supported | Ceil | | Ceil | +| Concat | Supported | Supported | Supported | Supported | Supported | Supported | Concat | Concat | Concat | +| Conv2d | Supported | Supported | Supported | Supported | Supported | Supported | Conv2D | Convolution | Conv | +| Conv2dTranspose | Supported | Supported | Supported | Supported | Supported | Supported | DeConv2D | Deconvolution | ConvTranspose | +| Cos | | Supported | Supported | Supported | Supported | Supported | Cos | | Cos | +| Crop | | Supported | Supported | Supported | | | | Crop | | +| DeDepthwiseConv2D | | Supported | Supported | Supported | | | | Deconvolution| ConvTranspose | +| DepthToSpace | | Supported | Supported | Supported | | | DepthToSpace| | DepthToSpace | +| DepthwiseConv2dNative | Supported | Supported | Supported | Supported | Supported | Supported | DepthwiseConv2D | Convolution | Convolution | +| Div | Supported | Supported | Supported | Supported | Supported | Supported | Div, RealDiv | | Div | +| Eltwise | Supported | Supported | | | | | | Eltwise | | +| Elu | | Supported | | | | | Elu | | Elu | +| Equal | Supported | Supported | Supported | Supported | | | Equal | | Equal | +| Exp | | Supported | | | Supported | Supported | Exp | | Exp | +| ExpandDims | | Supported | | | | | | | | +| Fill | | Supported | | | | | Fill | | | +| Flatten | | Supported | | | | | | Flatten | | +| Floor | | Supported | Supported | Supported | Supported | Supported | flOOR | | Floor | +| FloorDiv | Supported | Supported | | | | | FloorDiv | | | +| FloorMod | Supported | Supported | | | | | FloorMod | | | +| FullConnection | | Supported | Supported | Supported | Supported | Supported | FullyConnected | InnerProduct | | +| GatherNd | | Supported | Supported | Supported | | | GatherND | | | +| GatherV2 | | Supported | Supported | Supported | | | Gather | | Gather | +| Greater | Supported | Supported | Supported | Supported | | | Greater | | Greater | +| GreaterEqual | Supported | Supported | Supported | Supported | | | GreaterEqual| | | +| Hswish | Supported | Supported | Supported | Supported | | | HardSwish | | | +| LeakyReLU | Supported | Supported | | | Supported | Supported | LeakyRelu | | LeakyRelu | +| Less | Supported | Supported | Supported | Supported | | | Less | | Less | +| LessEqual | Supported | Supported | Supported | Supported | | | LessEqual | | | +| LRN | | Supported | | | | | LocalResponseNorm | | Lrn | +| Log | | Supported | Supported | Supported | Supported | Supported | Log | | Log | +| LogicalAnd | Supported | Supported | | | | | LogicalAnd | | | +| LogicalNot | | Supported | Supported | Supported | Supported | Supported | LogicalNot | | | +| LogicalOr | Supported | Supported | | | | | LogicalOr | | | +| LSTM | | Supported | | | | | | | | +| MatMul | | Supported | Supported | Supported | Supported | Supported | | | MatMul | +| Maximum | Supported | Supported | | | | | Maximum | | Max | +| MaxPool | Supported | Supported | Supported | Supported | Supported | Supported | MaxPooling | Pooling | MaxPool | +| Minimum | Supported | Supported | | | | | Minimum | | Min | +| Mul | Supported | Supported | Supported | Supported | Supported | Supported | Mul | | Mul | +| NotEqual | Supported | Supported | Supported | Supported | | | NotEqual | | | +| OneHot | | Supported | | | | | OneHot | | | +| Pad | | Supported | Supported | Supported | | | Pad | | Pad | +| Pow | | Supported | Supported | Supported | | | Pow | Power | Power | +| PReLU | | Supported | | | Supported | Supported | | PReLU | | +| Range | | Supported | | | | | Range | | | +| Rank | | Supported | | | | | Rank | | | +| ReduceMax | Supported | Supported | Supported | Supported | | | ReduceMax | | ReduceMax | +| ReduceMean | Supported | Supported | Supported | Supported | | | Mean | | ReduceMean | +| ReduceMin | Supported | Supported | Supported | Supported | | | ReduceMin | | ReduceMin | +| ReduceProd | Supported | Supported | Supported | Supported | | | ReduceProd | | | +| ReduceSum | Supported | Supported | Supported | Supported | | | Sum | | ReduceSum | +| ReduceSumSquare | Supported | Supported | Supported | Supported | | | | | | +| ReLU | Supported | Supported | Supported | Supported | Supported | Supported | Relu | ReLU | Relu | +| ReLU6 | Supported | Supported | Supported | Supported | Supported | Supported | Relu6 | ReLU6 | Clip* | +| Reshape | Supported | Supported | Supported | Supported | Supported | Supported | Reshape | Reshape | Reshape,Flatten | +| Resize | | Supported | Supported | Supported | | | ResizeBilinear, NearestNeighbor | Interp | | +| Reverse | | Supported | | | | | reverse | | | +| ReverseSequence | | Supported | | | | | ReverseSequence | | | +| Round | | Supported | Supported | Supported | Supported | Supported | Round | | | +| Rsqrt | | Supported | Supported | Supported | Supported | Supported | Rsqrt | | | +| Scale | | Supported | | | Supported | Supported | | Scale | | +| ScatterNd | | Supported | | | | | ScatterNd | | | +| Shape | | Supported | | | | | Shape | | Shape | +| Sigmoid | Supported | Supported | Supported | Supported | Supported | Supported | Logistic | Sigmoid | Sigmoid | +| Sin | | Supported | Supported | Supported | Supported | Supported | Sin | | Sin | +| Slice | | Supported | Supported | Supported | Supported | Supported | Slice | | Slice | +| Softmax | Supported | Supported | Supported | Supported | Supported | Supported | Softmax | Softmax | Softmax | +| SpaceToBatch | | Supported | | | | | | | | +| SpaceToBatchND | | Supported | | | | | SpaceToBatchND | | | +| SpaceToDepth | | Supported | | | | | SpaceToDepth | | SpaceToDepth | +| SparseToDense | | Supported | | | | | SpareToDense | | | +| Split | Supported | Supported | Supported | Supported | | | Split, SplitV | | | +| Sqrt | | Supported | Supported | Supported | Supported | Supported | Sqrt | | Sqrt | +| Square | | Supported | Supported | Supported | Supported | Supported | Square | | | +| SquaredDifference | | Supported | | | | | SquaredDifference | | | +| Squeeze | | Supported | Supported | Supported | | | Squeeze | | Squeeze | +| StridedSlice | | Supported | Supported | Supported | | | StridedSlice| | | +| Stack | | Supported | | | | | Stack | | | +| Sub | Supported | Supported | Supported | Supported | Supported | Supported | Sub | | Sub | +| Tanh | Supported | Supported | | | Supported | Supported | Tanh | TanH | | +| Tile | | Supported | | | | | Tile | | Tile | +| TopK | | Supported | Supported | Supported | | | TopKV2 | | | +| Transpose | Supported | Supported | | | Supported | Supported | Transpose | Permute | Transpose | +| Unique | | Supported | | | | | Unique | | | +| Unsqueeze | | Supported | Supported | Supported | | | | | Unsqueeze | +| Unstack | | Supported | | | | | Unstack | | | +| Where | | Supported | | | | | Where | | | +| ZerosLike | | Supported | | | | | ZerosLike | | | + +* Clip: only support convert clip(0, 6) to Relu6. +* DEQUANTIZE: only support to convert fp16 to fp32. diff --git a/docs/programming_guide/source_en/operator_list.md b/docs/note/source_en/operator_list_ms.md similarity index 77% rename from docs/programming_guide/source_en/operator_list.md rename to docs/note/source_en/operator_list_ms.md index 1fc434c418..f8e83eb7e1 100644 --- a/docs/programming_guide/source_en/operator_list.md +++ b/docs/note/source_en/operator_list_ms.md @@ -1,4 +1,4 @@ -# Operator List +# MindSpore Operator List `Linux` `Ascend` `GPU` `CPU` `Model Development` `Beginner` `Intermediate` `Expert` @@ -8,15 +8,10 @@ - [mindspore.nn](#mindsporenn) - [mindspore.ops.operations](#mindsporeopsoperations) - [mindspore.ops.functional](#mindsporeopsfunctional) - - [Distributed Operator](#distributed-operator) - - [Implicit Type Conversion](#implicit-type-conversion) - - [conversion rules](#conversion-rules) - - [data types involved in conversion](#data-types-involved-in-conversion) - - [support ops](#support-ops) - + ## mindspore.nn @@ -392,156 +387,3 @@ | [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) | tensor_pow > At present, functional supports some operators without attributes, which will be further completed in the future. - -## Distributed Operator - -| op name | constraints -| :----------- | :----------- -| [mindspore.ops.operations.ACos](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ACos) | None -| [mindspore.ops.operations.Cos](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cos) | None -| [mindspore.ops.operations.LogicalNot](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalNot) | None -| [mindspore.ops.operations.Log](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Log) | None -| [mindspore.ops.operations.Exp](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Exp) | None -| [mindspore.ops.operations.LogSoftmax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogSoftmax) | The logits can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. -| [mindspore.ops.operations.Softmax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Softmax) | The logits can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. -| [mindspore.ops.operations.Tanh](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tanh) | None -| [mindspore.ops.operations.Gelu](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Gelu) | None -| [mindspore.ops.operations.ReLU](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReLU) | None -| [mindspore.ops.operations.Sqrt](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sqrt) | None -| [mindspore.ops.operations.Cast](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cast) | None -| [mindspore.ops.operations.Neg](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Neg) | None -| [mindspore.ops.operations.ExpandDims](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ExpandDims) | None -| [mindspore.ops.operations.Squeeze](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Squeeze) | None -| [mindspore.ops.operations.Square](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Square) | None -| [mindspore.ops.operations.Sigmoid](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sigmoid) | None -| [mindspore.ops.operations.Dropout](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Dropout) | Repeated calculation is not supported. -| [mindspore.ops.operations.Div](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Div) | None -| [mindspore.ops.operations.TensorAdd](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TensorAdd) | None -| [mindspore.ops.operations.RealDiv](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.RealDiv) | None -| [mindspore.ops.operations.Mul](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mul) | None -| [mindspore.ops.operations.Sub](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sub) | None -| [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) | None -| [mindspore.ops.operations.FloorDiv](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorDiv) | None -| [mindspore.ops.operations.Greater](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Greater) | None -| [mindspore.ops.operations.AssignSub](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.AssignSub) | None -| [mindspore.ops.operations.SigmoidCrossEntropyWithLogits](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SigmoidCrossEntropyWithLogits) | None -| [mindspore.ops.operations.Equal](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Equal) | None -| [mindspore.ops.operations.NotEqual](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.NotEqual) | None -| [mindspore.ops.operations.Maximum](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Maximum) | None -| [mindspore.ops.operations.Minimum](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Minimum) | None -| [mindspore.ops.operations.BiasAdd](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BiasAdd) | None -| [mindspore.ops.operations.Concat](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Concat) | The input_x can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. -| [mindspore.ops.operations.DropoutGenMask](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutGenMask) | Need to be used in conjunction with `DropoutDoMask`. -| [mindspore.ops.operations.DropoutDoMask](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutDoMask) | Need to be used in conjunction with `DropoutGenMask`,configuring shard strategy is not supported. -| [mindspore.ops.operations.GatherV2](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.GatherV2) | Only support 1-dim and 2-dim parameters and the last dimension of the input_params should be 32-byte aligned; Scalar input_indices is not supported; Repeated calculation is not supported when the parameters are split in the dimension of the axis; Split input_indices and input_params at the same time is not supported. -| [mindspore.ops.operations.SparseGatherV2](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseGatherV2) | The same as GatherV2. -| [mindspore.ops.operations.EmbeddingLookup](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.EmbeddingLookup) | The same as GatherV2. -| [mindspore.ops.operations.L2Normalize](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.L2Normalize) | The input_x can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. -| [mindspore.ops.operations.SoftmaxCrossEntropyWithLogits](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SoftmaxCrossEntropyWithLogits) | The last dimension of logits and labels can't be splited; Only supports using output[0]. -| [mindspore.ops.operations.MatMul](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.MatMul) | `transpose_a=True` is not supported. -| [mindspore.ops.operations.BatchMatMul](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BatchMatMul) | `transpore_a=True` is not supported. -| [mindspore.ops.operations.PReLU](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.PReLU) | The shard strategy in channel dimension of input_x should be consistent with weight. -| [mindspore.ops.operations.OneHot](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.OneHot) | Only support 1-dim indices. -| [mindspore.ops.operations.ReduceSum](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceSum) | None -| [mindspore.ops.operations.ReduceMax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMax) | None -| [mindspore.ops.operations.ReduceMin](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMin) | None -| [mindspore.ops.operations.ArgMinWithValue](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMinWithValue) | The output index can't be used as the input of other operators. -| [mindspore.ops.operations.ArgMaxWithValue](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMaxWithValue) | The output index can't be used as the input of other operators. -| [mindspore.ops.operations.ReduceMean](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMean) | None -| [mindspore.ops.operations.Reshape](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Reshape) | Configuring shard strategy is not supported. -| [mindspore.ops.operations.StridedSlice](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.StridedSlice) | Only support mask with all 0 values; The dimension needs to be split should be all extracted; Split is not supported when the strides of dimension is 1. -| [mindspore.ops.operations.Tile](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tile) | Only support configuring shard strategy for multiples. -| [mindspore.ops.operations.Transpose](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Transpose) | None -| [mindspore.ops.operations.Diag](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Diag) | Configuring shard strategy is not supported. - -> Repeated calculation means that the device is not fully used. For example, the cluster has 8 devices to run distributed training, the splitting strategy only cuts the input into 4 copies. In this case, double counting will occur. -> - -## Implicit Type Conversion - -### conversion rules -* Scalar and Tensor operations: during operation, the scalar is automatically converted to Tensor, and the data type is consistent with the Tensor data type involved in the operation; -when Tensor is a bool data type and the scalar is int or float, both the scalar and Tensor are converted to the Tensor with the data type of int32 or float32. -* Tensor operation of different data types: the priority of data type is bool < uint8 < int8 < int16 < int32 < int64 < float16 < float32 + +- [MindSpore Distributed Operator List](#mindspore-distributed-operator-list) + - [Distributed Operator](#distributed-operator) + + + + + +## Distributed Operator + +| op name | constraints +| :----------- | :----------- +| [mindspore.ops.operations.ACos](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ACos) | None +| [mindspore.ops.operations.Cos](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cos) | None +| [mindspore.ops.operations.LogicalNot](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalNot) | None +| [mindspore.ops.operations.Log](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Log) | None +| [mindspore.ops.operations.Exp](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Exp) | None +| [mindspore.ops.operations.LogSoftmax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogSoftmax) | The logits can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. +| [mindspore.ops.operations.Softmax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Softmax) | The logits can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. +| [mindspore.ops.operations.Tanh](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tanh) | None +| [mindspore.ops.operations.Gelu](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Gelu) | None +| [mindspore.ops.operations.ReLU](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReLU) | None +| [mindspore.ops.operations.Sqrt](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sqrt) | None +| [mindspore.ops.operations.Cast](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cast) | None +| [mindspore.ops.operations.Neg](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Neg) | None +| [mindspore.ops.operations.ExpandDims](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ExpandDims) | None +| [mindspore.ops.operations.Squeeze](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Squeeze) | None +| [mindspore.ops.operations.Square](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Square) | None +| [mindspore.ops.operations.Sigmoid](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sigmoid) | None +| [mindspore.ops.operations.Dropout](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Dropout) | Repeated calculation is not supported. +| [mindspore.ops.operations.Div](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Div) | None +| [mindspore.ops.operations.TensorAdd](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TensorAdd) | None +| [mindspore.ops.operations.RealDiv](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.RealDiv) | None +| [mindspore.ops.operations.Mul](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mul) | None +| [mindspore.ops.operations.Sub](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sub) | None +| [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) | None +| [mindspore.ops.operations.FloorDiv](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorDiv) | None +| [mindspore.ops.operations.Greater](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Greater) | None +| [mindspore.ops.operations.AssignSub](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.AssignSub) | None +| [mindspore.ops.operations.SigmoidCrossEntropyWithLogits](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SigmoidCrossEntropyWithLogits) | None +| [mindspore.ops.operations.Equal](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Equal) | None +| [mindspore.ops.operations.NotEqual](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.NotEqual) | None +| [mindspore.ops.operations.Maximum](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Maximum) | None +| [mindspore.ops.operations.Minimum](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Minimum) | None +| [mindspore.ops.operations.BiasAdd](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BiasAdd) | None +| [mindspore.ops.operations.Concat](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Concat) | The input_x can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. +| [mindspore.ops.operations.DropoutGenMask](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutGenMask) | Need to be used in conjunction with `DropoutDoMask`. +| [mindspore.ops.operations.DropoutDoMask](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutDoMask) | Need to be used in conjunction with `DropoutGenMask`,configuring shard strategy is not supported. +| [mindspore.ops.operations.GatherV2](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.GatherV2) | Only support 1-dim and 2-dim parameters and the last dimension of the input_params should be 32-byte aligned; Scalar input_indices is not supported; Repeated calculation is not supported when the parameters are split in the dimension of the axis; Split input_indices and input_params at the same time is not supported. +| [mindspore.ops.operations.SparseGatherV2](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseGatherV2) | The same as GatherV2. +| [mindspore.ops.operations.EmbeddingLookup](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.EmbeddingLookup) | The same as GatherV2. +| [mindspore.ops.operations.L2Normalize](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.L2Normalize) | The input_x can't be split into the dimension of axis, otherwise it's inconsistent with the single machine in the mathematical logic. +| [mindspore.ops.operations.SoftmaxCrossEntropyWithLogits](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SoftmaxCrossEntropyWithLogits) | The last dimension of logits and labels can't be splited; Only supports using output[0]. +| [mindspore.ops.operations.MatMul](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.MatMul) | `transpose_a=True` is not supported. +| [mindspore.ops.operations.BatchMatMul](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BatchMatMul) | `transpore_a=True` is not supported. +| [mindspore.ops.operations.PReLU](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.PReLU) | The shard strategy in channel dimension of input_x should be consistent with weight. +| [mindspore.ops.operations.OneHot](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.OneHot) | Only support 1-dim indices. +| [mindspore.ops.operations.ReduceSum](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceSum) | None +| [mindspore.ops.operations.ReduceMax](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMax) | None +| [mindspore.ops.operations.ReduceMin](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMin) | None +| [mindspore.ops.operations.ArgMinWithValue](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMinWithValue) | The output index can't be used as the input of other operators. +| [mindspore.ops.operations.ArgMaxWithValue](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMaxWithValue) | The output index can't be used as the input of other operators. +| [mindspore.ops.operations.ReduceMean](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMean) | None +| [mindspore.ops.operations.Reshape](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Reshape) | Configuring shard strategy is not supported. +| [mindspore.ops.operations.StridedSlice](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.StridedSlice) | Only support mask with all 0 values; The dimension needs to be split should be all extracted; Split is not supported when the strides of dimension is 1. +| [mindspore.ops.operations.Tile](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tile) | Only support configuring shard strategy for multiples. +| [mindspore.ops.operations.Transpose](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Transpose) | None +| [mindspore.ops.operations.Diag](https://www.mindspore.cn/api/en/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Diag) | Configuring shard strategy is not supported. + +> Repeated calculation means that the device is not fully used. For example, the cluster has 8 devices to run distributed training, the splitting strategy only cuts the input into 4 copies. In this case, double counting will occur. +> diff --git a/docs/note/source_en/specification_note.rst b/docs/note/source_en/specification_note.rst index 00875e6023..66b021a446 100644 --- a/docs/note/source_en/specification_note.rst +++ b/docs/note/source_en/specification_note.rst @@ -5,5 +5,7 @@ :maxdepth: 1 benchmark + network_list + operator_list constraints_on_network_construction diff --git a/docs/note/source_zh_cn/index.rst b/docs/note/source_zh_cn/index.rst index 40d2a2ee36..8853982859 100644 --- a/docs/note/source_zh_cn/index.rst +++ b/docs/note/source_zh_cn/index.rst @@ -11,5 +11,5 @@ MindSpore Note :maxdepth: 1 design - Specification_list - note + specification_note + others diff --git a/docs/note/source_zh_cn/network_list.rst b/docs/note/source_zh_cn/network_list.rst new file mode 100644 index 0000000000..e70ac86c49 --- /dev/null +++ b/docs/note/source_zh_cn/network_list.rst @@ -0,0 +1,7 @@ +网络支持 +=========== + +.. toctree:: + :maxdepth: 1 + + network_list_ms \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/network_list.md b/docs/note/source_zh_cn/network_list_ms.md similarity index 97% rename from docs/programming_guide/source_zh_cn/network_list.md rename to docs/note/source_zh_cn/network_list_ms.md index c521843f87..8202dac05e 100644 --- a/docs/programming_guide/source_zh_cn/network_list.md +++ b/docs/note/source_zh_cn/network_list_ms.md @@ -1,16 +1,16 @@ -# 网络支持 +# MindSpore网络支持 `Linux` `Ascend` `GPU` `CPU` `模型开发` `中级` `高级` -- [网络支持](#网络支持) +- [MindSpore网络支持](#mindspore网络支持) - [Model Zoo](#model-zoo) - [预训练模型](#预训练模型) - + ## Model Zoo diff --git a/docs/note/source_zh_cn/operator_list.rst b/docs/note/source_zh_cn/operator_list.rst new file mode 100644 index 0000000000..4a5895cf24 --- /dev/null +++ b/docs/note/source_zh_cn/operator_list.rst @@ -0,0 +1,10 @@ +算子支持 +=========== + +.. toctree:: + :maxdepth: 1 + + operator_list_ms + operator_list_implicit + operator_list_parallel + operator_list_lite \ No newline at end of file diff --git a/docs/note/source_zh_cn/operator_list_implicit.md b/docs/note/source_zh_cn/operator_list_implicit.md new file mode 100644 index 0000000000..b21cc8aab6 --- /dev/null +++ b/docs/note/source_zh_cn/operator_list_implicit.md @@ -0,0 +1,103 @@ +# MindSpore隐式类型转换的算子支持 + +`Linux` `Ascend` `GPU` `CPU` `模型开发` `初级` `中级` `高级` + + + +- [MindSpore隐式类型转换的算子支持](#mindspore隐式类型转换的算子支持) + - [隐式类型转换](#隐式类型转换) + - [转换规则](#转换规则) + - [参与转换的数据类型](#参与转换的数据类型) + - [支持算子](#支持算子) + + + + + +## 隐式类型转换 +### 转换规则 +* 标量与Tensor运算:运算时,将标量自动转为Tensor,数据类型和参与运算的Tensor数据类型保持一致; +而当Tensor是bool数据类型,标量是int或float时,将标量和Tensor都转为数据类型为int32或float32的Tensor。 +* 不同数据类型Tensor运算:数据类型优先级排序为bool < uint8 < int8 < int16 < int32 < int64 < float16 < float32 < float64, +运算时,先确定参与运算的Tensor中优先级相对最高的数据类型,然后将低优先级数据类型Tensor转换为相对最高优先级数据类型; +而当int8和uint8数据类型的Tensor进行运算时,将其都转为int16的Tensor。 +* 不支持对Parameter进行数据类型转换:如果按照转换规则推导,需要对网络中定义的Parameter进行数据类型转换时,会抛出RuntimeError异常。 + +### 参与转换的数据类型 +* bool +* int8 +* uint8 +* int16 +* int32 +* int64 +* float16 +* float32 +* float64 + +### 支持算子 + +| 算子名 +| :----------- +| [mindspore.ops.operations.Assign](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Assign) +| [mindspore.ops.operations.AssignSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.AssignSub) +| [mindspore.ops.operations.ApplyMomentum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyMomentum) +| [mindspore.ops.operations.FusedSparseAdam](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseAdam) +| [mindspore.ops.operations.FusedSparseLazyAdam](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseLazyAdam) +| [mindspore.ops.operations.FusedSparseFtrl](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseFtrl) +| [mindspore.ops.operations.FusedSparseProximalAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseProximalAdagrad) +| [mindspore.ops.operations.ApplyAdaMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdaMax) +| [mindspore.ops.operations.ApplyAdadelta](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdadelta) +| [mindspore.ops.operations.ApplyAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdagrad) +| [mindspore.ops.operations.ApplyAdagradV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdagradV2) +| [mindspore.ops.operations.SparseApplyAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyAdagrad) +| [mindspore.ops.operations.SparseApplyAdagradV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyAdagradV2) +| [mindspore.ops.operations.ApplyProximalAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyProximalAdagrad) +| [mindspore.ops.operations.SparseApplyProximalAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyProximalAdagrad) +| [mindspore.ops.operations.ApplyAddSign](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAddSign) +| [mindspore.ops.operations.ApplyPowerSign](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyPowerSign) +| [mindspore.ops.operations.ApplyGradientDescent](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyGradientDescent) +| [mindspore.ops.operations.ApplyProximalGradientDescent](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyProximalGradientDescent) +| [mindspore.ops.operations.SparseApplyFtrl](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyFtrl) +| [mindspore.ops.operations.SparseApplyFtrlV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyFtrlV2) +| [mindspore.ops.operations.BitwiseAnd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BitwiseAnd) +| [mindspore.ops.operations.BitwiseOr](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BitwiseOr) +| [mindspore.ops.operations.BitwiseXor](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BitwiseXor) +| [mindspore.ops.operations.TensorAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TensorAdd) +| [mindspore.ops.operations.Sub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sub) +| [mindspore.ops.operations.Mul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mul) +| [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) +| [mindspore.ops.operations.Minimum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Minimum) +| [mindspore.ops.operations.Maximum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Maximum) +| [mindspore.ops.operations.RealDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.RealDiv) +| [mindspore.ops.operations.Div](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Div) +| [mindspore.ops.operations.DivNoNan](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DivNoNan) +| [mindspore.ops.operations.FloorDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorDiv) +| [mindspore.ops.operations.TruncateDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TruncateDiv) +| [mindspore.ops.operations.TruncateMod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TruncateMod) +| [mindspore.ops.operations.Mod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mod) +| [mindspore.ops.operations.FloorMod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorMod) +| [mindspore.ops.operations.Atan2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Atan2) +| [mindspore.ops.operations.SquaredDifference](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SquaredDifference) +| [mindspore.ops.operations.Xdivy](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xdivy) +| [mindspore.ops.operations.Xlogy](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xlogy) +| [mindspore.ops.operations.Equal](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Equal) +| [mindspore.ops.operations.ApproximateEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApproximateEqual) +| [mindspore.ops.operations.NotEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.NotEqual) +| [mindspore.ops.operations.Greater](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Greater) +| [mindspore.ops.operations.GreaterEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.GreaterEqual) +| [mindspore.ops.operations.Less](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Less) +| [mindspore.ops.operations.LessEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LessEqual) +| [mindspore.ops.operations.LogicalAnd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalAnd) +| [mindspore.ops.operations.LogicalOr](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalOr) +| [mindspore.ops.operations.ScatterNdUpdate](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNdUpdate) +| [mindspore.ops.operations.ScatterNdAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNdAdd) +| [mindspore.ops.operations.ScatterNdSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNdSub) +| [mindspore.ops.operations.ScatterNonAliasingAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNonAliasingAdd) +| [mindspore.ops.operations.ScatterUpdate](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterUpdate) +| [mindspore.ops.operations.ScatterMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterMax) +| [mindspore.ops.operations.ScatterMin](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterMin) +| [mindspore.ops.operations.ScatterAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterAdd) +| [mindspore.ops.operations.ScatterSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterSub) +| [mindspore.ops.operations.ScatterMul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterMul) +| [mindspore.ops.operations.ScatterDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterDiv) + diff --git a/docs/note/source_zh_cn/operator_list_lite.md b/docs/note/source_zh_cn/operator_list_lite.md new file mode 100644 index 0000000000..d5d5424ef4 --- /dev/null +++ b/docs/note/source_zh_cn/operator_list_lite.md @@ -0,0 +1,111 @@ +# MindSpore Lite算子支持 + +`Linux` `Ascend` `端侧` `推理应用` `初级` `中级` `高级` + + + +| 操作名 | CPU
      FP16 | CPU
      FP32 | CPU
      Int8 | CPU
      UInt8 | GPU
      FP16 | GPU
      FP32 | 支持的Tensorflow
      Lite算子 | 支持的Caffe
      Lite算子 | 支持的Onnx
      Lite算子 | +|-----------------------|----------|----------|----------|-----------|----------|-------------------|----------|----------|---------| +| Abs | | Supported | Supported | Supported | Supported | Supported | Abs | | Abs | +| Add | Supported | Supported | Supported | Supported | Supported | Supported | Add | | Add | +| AddN | | Supported | | | | | AddN | | | +| Argmax | | Supported | Supported | Supported | | | Argmax | ArgMax | ArgMax | +| Argmin | | Supported | Supported | Supported | | | Argmin | | | +| AvgPool | Supported | Supported | Supported | Supported | Supported | Supported | MeanPooling| Pooling | AveragePool | +| BatchNorm | Supported | Supported | Supported | Supported | Supported | Supported | | BatchNorm | BatchNormalization | +| BatchToSpace | | Supported | Supported | Supported | | | BatchToSpace, BatchToSpaceND | | | +| BiasAdd | | Supported | Supported | Supported | Supported | Supported | | | BiasAdd | +| Broadcast | | Supported | | | | | BroadcastTo | | Expand | +| Cast | Supported | Supported | | Supported | Supported | Supported | Cast, DEQUANTIZE* | | Cast | +| Ceil | | Supported | Supported | Supported | Supported | Supported | Ceil | | Ceil | +| Concat | Supported | Supported | Supported | Supported | Supported | Supported | Concat | Concat | Concat | +| Conv2d | Supported | Supported | Supported | Supported | Supported | Supported | Conv2D | Convolution | Conv | +| Conv2dTranspose | Supported | Supported | Supported | Supported | Supported | Supported | DeConv2D | Deconvolution | ConvTranspose | +| Cos | | Supported | Supported | Supported | Supported | Supported | Cos | | Cos | +| Crop | | Supported | Supported | Supported | | | | Crop | | +| DeDepthwiseConv2D | | Supported | Supported | Supported | | | | Deconvolution| ConvTranspose | +| DepthToSpace | | Supported | Supported | Supported | | | DepthToSpace| | DepthToSpace | +| DepthwiseConv2dNative | Supported | Supported | Supported | Supported | Supported | Supported | DepthwiseConv2D | Convolution | Convolution | +| Div | Supported | Supported | Supported | Supported | Supported | Supported | Div, RealDiv | | Div | +| Eltwise | Supported | Supported | | | | | | Eltwise | | +| Elu | | Supported | | | | | Elu | | Elu | +| Equal | Supported | Supported | Supported | Supported | | | Equal | | Equal | +| Exp | | Supported | | | Supported | Supported | Exp | | Exp | +| ExpandDims | | Supported | | | | | | | | +| Fill | | Supported | | | | | Fill | | | +| Flatten | | Supported | | | | | | Flatten | | +| Floor | | Supported | Supported | Supported | Supported | Supported | flOOR | | Floor | +| FloorDiv | Supported | Supported | | | | | FloorDiv | | | +| FloorMod | Supported | Supported | | | | | FloorMod | | | +| FullConnection | | Supported | Supported | Supported | Supported | Supported | FullyConnected | InnerProduct | | +| GatherNd | | Supported | Supported | Supported | | | GatherND | | | +| GatherV2 | | Supported | Supported | Supported | | | Gather | | Gather | +| Greater | Supported | Supported | Supported | Supported | | | Greater | | Greater | +| GreaterEqual | Supported | Supported | Supported | Supported | | | GreaterEqual| | | +| Hswish | Supported | Supported | Supported | Supported | | | HardSwish | | | +| LeakyReLU | Supported | Supported | | | Supported | Supported | LeakyRelu | | LeakyRelu | +| Less | Supported | Supported | Supported | Supported | | | Less | | Less | +| LessEqual | Supported | Supported | Supported | Supported | | | LessEqual | | | +| LRN | | Supported | | | | | LocalResponseNorm | | Lrn | +| Log | | Supported | Supported | Supported | Supported | Supported | Log | | Log | +| LogicalAnd | Supported | Supported | | | | | LogicalAnd | | | +| LogicalNot | | Supported | Supported | Supported | Supported | Supported | LogicalNot | | | +| LogicalOr | Supported | Supported | | | | | LogicalOr | | | +| LSTM | | Supported | | | | | | | | +| MatMul | | Supported | Supported | Supported | Supported | Supported | | | MatMul | +| Maximum | Supported | Supported | | | | | Maximum | | Max | +| MaxPool | Supported | Supported | Supported | Supported | Supported | Supported | MaxPooling | Pooling | MaxPool | +| Minimum | Supported | Supported | | | | | Minimum | | Min | +| Mul | Supported | Supported | Supported | Supported | Supported | Supported | Mul | | Mul | +| NotEqual | Supported | Supported | Supported | Supported | | | NotEqual | | | +| OneHot | | Supported | | | | | OneHot | | | +| Pad | | Supported | Supported | Supported | | | Pad | | Pad | +| Pow | | Supported | Supported | Supported | | | Pow | Power | Power | +| PReLU | | Supported | | | Supported | Supported | | PReLU | | +| Range | | Supported | | | | | Range | | | +| Rank | | Supported | | | | | Rank | | | +| ReduceMax | Supported | Supported | Supported | Supported | | | ReduceMax | | ReduceMax | +| ReduceMean | Supported | Supported | Supported | Supported | | | Mean | | ReduceMean | +| ReduceMin | Supported | Supported | Supported | Supported | | | ReduceMin | | ReduceMin | +| ReduceProd | Supported | Supported | Supported | Supported | | | ReduceProd | | | +| ReduceSum | Supported | Supported | Supported | Supported | | | Sum | | ReduceSum | +| ReduceSumSquare | Supported | Supported | Supported | Supported | | | | | | +| ReLU | Supported | Supported | Supported | Supported | Supported | Supported | Relu | ReLU | Relu | +| ReLU6 | Supported | Supported | Supported | Supported | Supported | Supported | Relu6 | ReLU6 | Clip* | +| Reshape | Supported | Supported | Supported | Supported | Supported | Supported | Reshape | Reshape | Reshape,Flatten | +| Resize | | Supported | Supported | Supported | | | ResizeBilinear, NearestNeighbor | Interp | | +| Reverse | | Supported | | | | | reverse | | | +| ReverseSequence | | Supported | | | | | ReverseSequence | | | +| Round | | Supported | Supported | Supported | Supported | Supported | Round | | | +| Rsqrt | | Supported | Supported | Supported | Supported | Supported | Rsqrt | | | +| Scale | | Supported | | | Supported | Supported | | Scale | | +| ScatterNd | | Supported | | | | | ScatterNd | | | +| Shape | | Supported | | | | | Shape | | Shape | +| Sigmoid | Supported | Supported | Supported | Supported | Supported | Supported | Logistic | Sigmoid | Sigmoid | +| Sin | | Supported | Supported | Supported | Supported | Supported | Sin | | Sin | +| Slice | | Supported | Supported | Supported | Supported | Supported | Slice | | Slice | +| Softmax | Supported | Supported | Supported | Supported | Supported | Supported | Softmax | Softmax | Softmax | +| SpaceToBatch | | Supported | | | | | | | | +| SpaceToBatchND | | Supported | | | | | SpaceToBatchND | | | +| SpaceToDepth | | Supported | | | | | SpaceToDepth | | SpaceToDepth | +| SparseToDense | | Supported | | | | | SpareToDense | | | +| Split | Supported | Supported | Supported | Supported | | | Split, SplitV | | | +| Sqrt | | Supported | Supported | Supported | Supported | Supported | Sqrt | | Sqrt | +| Square | | Supported | Supported | Supported | Supported | Supported | Square | | | +| SquaredDifference | | Supported | | | | | SquaredDifference | | | +| Squeeze | | Supported | Supported | Supported | | | Squeeze | | Squeeze | +| StridedSlice | | Supported | Supported | Supported | | | StridedSlice| | | +| Stack | | Supported | | | | | Stack | | | +| Sub | Supported | Supported | Supported | Supported | Supported | Supported | Sub | | Sub | +| Tanh | Supported | Supported | | | Supported | Supported | Tanh | TanH | | +| Tile | | Supported | | | | | Tile | | Tile | +| TopK | | Supported | Supported | Supported | | | TopKV2 | | | +| Transpose | Supported | Supported | | | Supported | Supported | Transpose | Permute | Transpose | +| Unique | | Supported | | | | | Unique | | | +| Unsqueeze | | Supported | Supported | Supported | | | | | Unsqueeze | +| Unstack | | Supported | | | | | Unstack | | | +| Where | | Supported | | | | | Where | | | +| ZerosLike | | Supported | | | | | ZerosLike | | | + +* Clip: 仅支持将clip(0, 6)转换为Relu6. +* DEQUANTIZE: 仅支持将fp16转换为fp32. diff --git a/docs/programming_guide/source_zh_cn/operator_list_ms.md b/docs/note/source_zh_cn/operator_list_ms.md similarity index 77% rename from docs/programming_guide/source_zh_cn/operator_list_ms.md rename to docs/note/source_zh_cn/operator_list_ms.md index 80cfad80e9..215cc412ff 100644 --- a/docs/programming_guide/source_zh_cn/operator_list_ms.md +++ b/docs/note/source_zh_cn/operator_list_ms.md @@ -1,22 +1,17 @@ -# MindSpore 算子支持 +# MindSpore算子支持 `Linux` `Ascend` `GPU` `CPU` `模型开发` `初级` `中级` `高级` -- [MindSpore 算子支持](#mindspore-算子支持) +- [MindSpore算子支持](#mindspore算子支持) - [mindspore.nn](#mindsporenn) - [mindspore.ops.operations](#mindsporeopsoperations) - [mindspore.ops.functional](#mindsporeopsfunctional) - - [分布式算子](#分布式算子) - - [隐式类型转换](#隐式类型转换) - - [转换规则](#转换规则) - - [参与转换的数据类型](#参与转换的数据类型) - - [支持算子](#支持算子) - + ## mindspore.nn @@ -392,154 +387,3 @@ | [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) | tensor_pow > 当前functional支持了一部分没有属性的算子,后续会进一步补齐完整。 - -## 分布式算子 - -| 操作名 | 约束 -| :----------- | :----------- -| [mindspore.ops.operations.ACos](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ACos) | None -| [mindspore.ops.operations.Cos](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cos) | None -| [mindspore.ops.operations.LogicalNot](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalNot) | None -| [mindspore.ops.operations.Log](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Log) | None -| [mindspore.ops.operations.Exp](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Exp) | None -| [mindspore.ops.operations.LogSoftmax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogSoftmax) | 输入(logits)在轴(axis)对应的维度不可切分,切分后,在数学逻辑上和单机不等价 -| [mindspore.ops.operations.Softmax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Softmax) | 输入(logits)在轴(axis)对应的维度不可切分,切分后,在数学逻辑上和单机不等价 -| [mindspore.ops.operations.Tanh](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tanh) | None -| [mindspore.ops.operations.Gelu](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Gelu) | None -| [mindspore.ops.operations.ReLU](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReLU) | None -| [mindspore.ops.operations.Sqrt](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sqrt) | None -| [mindspore.ops.operations.Cast](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cast) | None -| [mindspore.ops.operations.Neg](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Neg) | None -| [mindspore.ops.operations.ExpandDims](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ExpandDims) | None -| [mindspore.ops.operations.Squeeze](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Squeeze) | None -| [mindspore.ops.operations.Square](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Square) | None -| [mindspore.ops.operations.Sigmoid](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sigmoid) | None -| [mindspore.ops.operations.Dropout](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Dropout) | 不支持重复计算 -| [mindspore.ops.operations.Div](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Div) | None -| [mindspore.ops.operations.TensorAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TensorAdd) | None -| [mindspore.ops.operations.RealDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.RealDiv) | None -| [mindspore.ops.operations.Mul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mul) | None -| [mindspore.ops.operations.Sub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sub) | None -| [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) | None -| [mindspore.ops.operations.FloorDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorDiv) | None -| [mindspore.ops.operations.Greater](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Greater) | None -| [mindspore.ops.operations.AssignSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.AssignSub) | None -| [mindspore.ops.operations.SigmoidCrossEntropyWithLogits](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SigmoidCrossEntropyWithLogits) | None -| [mindspore.ops.operations.Equal](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Equal) | None -| [mindspore.ops.operations.NotEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.NotEqual) | None -| [mindspore.ops.operations.Maximum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Maximum) | None -| [mindspore.ops.operations.Minimum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Minimum) | None -| [mindspore.ops.operations.BiasAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BiasAdd) | None -| [mindspore.ops.operations.Concat](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Concat) | 输入(input_x)在轴(axis)所对应的维度不能切分,切分后,在数学逻辑上和单机不等价 -| [mindspore.ops.operations.DropoutGenMask](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutGenMask) | 需和`DropoutDoMask`联合使用 -| [mindspore.ops.operations.DropoutDoMask](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutDoMask) | 需和`DropoutGenMask`联合使用,不支持配置切分策略 -| [mindspore.ops.operations.GatherV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.GatherV2) | 仅支持1维和2维的input_params,并且input_params的最后一维要32字节对齐(出于性能考虑);不支持标量input_indices;参数在轴(axis)所在维度切分时,不支持重复计算;不支持input_indices和input_params同时进行切分 -| [mindspore.ops.operations.SparseGatherV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseGatherV2) | 同GatherV2 -| [mindspore.ops.operations.EmbeddingLookup](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.EmbeddingLookup) | 同GatherV2 -| [mindspore.ops.operations.L2Normalize](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.L2Normalize) | 输入(input_x)在轴(axis)对应的维度不能切,切分后,在数学逻辑上和单机不等价 -| [mindspore.ops.operations.SoftmaxCrossEntropyWithLogits](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SoftmaxCrossEntropyWithLogits) | 输入(logits、labels)的最后一维不能切分;有两个输出,正向的loss只支持取[0] -| [mindspore.ops.operations.MatMul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.MatMul) | 不支持`transpose_a=True` -| [mindspore.ops.operations.BatchMatMul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BatchMatMul) | 不支持`transpore_a=True` -| [mindspore.ops.operations.PReLU](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.PReLU) | 输入(input_x)的Channel维要和weight的切分方式一致 -| [mindspore.ops.operations.OneHot](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.OneHot) | 仅支持输入(indices)是1维的Tensor -| [mindspore.ops.operations.ReduceSum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceSum) | None -| [mindspore.ops.operations.ReduceMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMax) | None -| [mindspore.ops.operations.ReduceMin](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMin) | None -| [mindspore.ops.operations.ArgMinWithValue](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMinWithValue) | 第一个输出(index)不能作为其他算子的输入 -| [mindspore.ops.operations.ArgMaxWithValue](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMaxWithValue) | 第一个输出(index)不能作为其他算子的输入 -| [mindspore.ops.operations.ReduceMean](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMean) | None -| [mindspore.ops.operations.Reshape](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Reshape) | 不支持配置切分策略 -| [mindspore.ops.operations.StridedSlice](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.StridedSlice) | 仅支持值为全0的mask;需要切分的维度必须全部提取;输入在strides不为1对应的维度不支持切分 -| [mindspore.ops.operations.Tile](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tile) | 仅支持对multiples配置切分策略 -| [mindspore.ops.operations.Transpose](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Transpose) | None -| [mindspore.ops.operations.Diag](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Diag) | 不支持配置切分策略 - -> 重复计算是指,机器没有用满,比如:集群有8张卡跑分布式训练,切分策略只对输入切成了4份。这种情况下会发生重复计算。 - -## 隐式类型转换 -### 转换规则 -* 标量与Tensor运算:运算时,将标量自动转为Tensor,数据类型和参与运算的Tensor数据类型保持一致; -而当Tensor是bool数据类型,标量是int或float时,将标量和Tensor都转为数据类型为int32或float32的Tensor。 -* 不同数据类型Tensor运算:数据类型优先级排序为bool < uint8 < int8 < int16 < int32 < int64 < float16 < float32 < float64, -运算时,先确定参与运算的Tensor中优先级相对最高的数据类型,然后将低优先级数据类型Tensor转换为相对最高优先级数据类型; -而当int8和uint8数据类型的Tensor进行运算时,将其都转为int16的Tensor。 -* 不支持对Parameter进行数据类型转换:如果按照转换规则推导,需要对网络中定义的Parameter进行数据类型转换时,会抛出RuntimeError异常。 - -### 参与转换的数据类型 -* bool -* int8 -* uint8 -* int16 -* int32 -* int64 -* float16 -* float32 -* float64 - -### 支持算子 - -| 算子名 -| :----------- -| [mindspore.ops.operations.Assign](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Assign) -| [mindspore.ops.operations.AssignSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.AssignSub) -| [mindspore.ops.operations.ApplyMomentum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyMomentum) -| [mindspore.ops.operations.FusedSparseAdam](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseAdam) -| [mindspore.ops.operations.FusedSparseLazyAdam](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseLazyAdam) -| [mindspore.ops.operations.FusedSparseFtrl](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseFtrl) -| [mindspore.ops.operations.FusedSparseProximalAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FusedSparseProximalAdagrad) -| [mindspore.ops.operations.ApplyAdaMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdaMax) -| [mindspore.ops.operations.ApplyAdadelta](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdadelta) -| [mindspore.ops.operations.ApplyAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdagrad) -| [mindspore.ops.operations.ApplyAdagradV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAdagradV2) -| [mindspore.ops.operations.SparseApplyAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyAdagrad) -| [mindspore.ops.operations.SparseApplyAdagradV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyAdagradV2) -| [mindspore.ops.operations.ApplyProximalAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyProximalAdagrad) -| [mindspore.ops.operations.SparseApplyProximalAdagrad](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyProximalAdagrad) -| [mindspore.ops.operations.ApplyAddSign](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyAddSign) -| [mindspore.ops.operations.ApplyPowerSign](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyPowerSign) -| [mindspore.ops.operations.ApplyGradientDescent](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyGradientDescent) -| [mindspore.ops.operations.ApplyProximalGradientDescent](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApplyProximalGradientDescent) -| [mindspore.ops.operations.SparseApplyFtrl](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyFtrl) -| [mindspore.ops.operations.SparseApplyFtrlV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseApplyFtrlV2) -| [mindspore.ops.operations.BitwiseAnd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BitwiseAnd) -| [mindspore.ops.operations.BitwiseOr](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BitwiseOr) -| [mindspore.ops.operations.BitwiseXor](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BitwiseXor) -| [mindspore.ops.operations.TensorAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TensorAdd) -| [mindspore.ops.operations.Sub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sub) -| [mindspore.ops.operations.Mul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mul) -| [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) -| [mindspore.ops.operations.Minimum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Minimum) -| [mindspore.ops.operations.Maximum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Maximum) -| [mindspore.ops.operations.RealDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.RealDiv) -| [mindspore.ops.operations.Div](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Div) -| [mindspore.ops.operations.DivNoNan](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DivNoNan) -| [mindspore.ops.operations.FloorDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorDiv) -| [mindspore.ops.operations.TruncateDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TruncateDiv) -| [mindspore.ops.operations.TruncateMod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TruncateMod) -| [mindspore.ops.operations.Mod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mod) -| [mindspore.ops.operations.FloorMod](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorMod) -| [mindspore.ops.operations.Atan2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Atan2) -| [mindspore.ops.operations.SquaredDifference](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SquaredDifference) -| [mindspore.ops.operations.Xdivy](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xdivy) -| [mindspore.ops.operations.Xlogy](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Xlogy) -| [mindspore.ops.operations.Equal](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Equal) -| [mindspore.ops.operations.ApproximateEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ApproximateEqual) -| [mindspore.ops.operations.NotEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.NotEqual) -| [mindspore.ops.operations.Greater](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Greater) -| [mindspore.ops.operations.GreaterEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.GreaterEqual) -| [mindspore.ops.operations.Less](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Less) -| [mindspore.ops.operations.LessEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LessEqual) -| [mindspore.ops.operations.LogicalAnd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalAnd) -| [mindspore.ops.operations.LogicalOr](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalOr) -| [mindspore.ops.operations.ScatterNdUpdate](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNdUpdate) -| [mindspore.ops.operations.ScatterNdAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNdAdd) -| [mindspore.ops.operations.ScatterNdSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNdSub) -| [mindspore.ops.operations.ScatterNonAliasingAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterNonAliasingAdd) -| [mindspore.ops.operations.ScatterUpdate](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterUpdate) -| [mindspore.ops.operations.ScatterMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterMax) -| [mindspore.ops.operations.ScatterMin](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterMin) -| [mindspore.ops.operations.ScatterAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterAdd) -| [mindspore.ops.operations.ScatterSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterSub) -| [mindspore.ops.operations.ScatterMul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterMul) -| [mindspore.ops.operations.ScatterDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ScatterDiv) - diff --git a/docs/note/source_zh_cn/operator_list_parallel.md b/docs/note/source_zh_cn/operator_list_parallel.md new file mode 100644 index 0000000000..50773ec339 --- /dev/null +++ b/docs/note/source_zh_cn/operator_list_parallel.md @@ -0,0 +1,75 @@ +# MindSpore分布式算子支持 + +`Linux` `Ascend` `GPU` `CPU` `模型开发` `初级` `中级` `高级` + + + +- [MindSpore分布式算子支持](#mindspore分布式算子支持) + - [分布式算子](#分布式算子) + + + + + +## 分布式算子 + +| 操作名 | 约束 +| :----------- | :----------- +| [mindspore.ops.operations.ACos](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ACos) | None +| [mindspore.ops.operations.Cos](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cos) | None +| [mindspore.ops.operations.LogicalNot](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogicalNot) | None +| [mindspore.ops.operations.Log](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Log) | None +| [mindspore.ops.operations.Exp](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Exp) | None +| [mindspore.ops.operations.LogSoftmax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.LogSoftmax) | 输入(logits)在轴(axis)对应的维度不可切分,切分后,在数学逻辑上和单机不等价 +| [mindspore.ops.operations.Softmax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Softmax) | 输入(logits)在轴(axis)对应的维度不可切分,切分后,在数学逻辑上和单机不等价 +| [mindspore.ops.operations.Tanh](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tanh) | None +| [mindspore.ops.operations.Gelu](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Gelu) | None +| [mindspore.ops.operations.ReLU](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReLU) | None +| [mindspore.ops.operations.Sqrt](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sqrt) | None +| [mindspore.ops.operations.Cast](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Cast) | None +| [mindspore.ops.operations.Neg](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Neg) | None +| [mindspore.ops.operations.ExpandDims](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ExpandDims) | None +| [mindspore.ops.operations.Squeeze](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Squeeze) | None +| [mindspore.ops.operations.Square](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Square) | None +| [mindspore.ops.operations.Sigmoid](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sigmoid) | None +| [mindspore.ops.operations.Dropout](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Dropout) | 不支持重复计算 +| [mindspore.ops.operations.Div](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Div) | None +| [mindspore.ops.operations.TensorAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.TensorAdd) | None +| [mindspore.ops.operations.RealDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.RealDiv) | None +| [mindspore.ops.operations.Mul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Mul) | None +| [mindspore.ops.operations.Sub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Sub) | None +| [mindspore.ops.operations.Pow](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Pow) | None +| [mindspore.ops.operations.FloorDiv](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.FloorDiv) | None +| [mindspore.ops.operations.Greater](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Greater) | None +| [mindspore.ops.operations.AssignSub](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.AssignSub) | None +| [mindspore.ops.operations.SigmoidCrossEntropyWithLogits](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SigmoidCrossEntropyWithLogits) | None +| [mindspore.ops.operations.Equal](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Equal) | None +| [mindspore.ops.operations.NotEqual](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.NotEqual) | None +| [mindspore.ops.operations.Maximum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Maximum) | None +| [mindspore.ops.operations.Minimum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Minimum) | None +| [mindspore.ops.operations.BiasAdd](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BiasAdd) | None +| [mindspore.ops.operations.Concat](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Concat) | 输入(input_x)在轴(axis)所对应的维度不能切分,切分后,在数学逻辑上和单机不等价 +| [mindspore.ops.operations.DropoutGenMask](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutGenMask) | 需和`DropoutDoMask`联合使用 +| [mindspore.ops.operations.DropoutDoMask](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.DropoutDoMask) | 需和`DropoutGenMask`联合使用,不支持配置切分策略 +| [mindspore.ops.operations.GatherV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.GatherV2) | 仅支持1维和2维的input_params,并且input_params的最后一维要32字节对齐(出于性能考虑);不支持标量input_indices;参数在轴(axis)所在维度切分时,不支持重复计算;不支持input_indices和input_params同时进行切分 +| [mindspore.ops.operations.SparseGatherV2](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SparseGatherV2) | 同GatherV2 +| [mindspore.ops.operations.EmbeddingLookup](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.EmbeddingLookup) | 同GatherV2 +| [mindspore.ops.operations.L2Normalize](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.L2Normalize) | 输入(input_x)在轴(axis)对应的维度不能切,切分后,在数学逻辑上和单机不等价 +| [mindspore.ops.operations.SoftmaxCrossEntropyWithLogits](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.SoftmaxCrossEntropyWithLogits) | 输入(logits、labels)的最后一维不能切分;有两个输出,正向的loss只支持取[0] +| [mindspore.ops.operations.MatMul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.MatMul) | 不支持`transpose_a=True` +| [mindspore.ops.operations.BatchMatMul](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.BatchMatMul) | 不支持`transpore_a=True` +| [mindspore.ops.operations.PReLU](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.PReLU) | 输入(input_x)的Channel维要和weight的切分方式一致 +| [mindspore.ops.operations.OneHot](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.OneHot) | 仅支持输入(indices)是1维的Tensor +| [mindspore.ops.operations.ReduceSum](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceSum) | None +| [mindspore.ops.operations.ReduceMax](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMax) | None +| [mindspore.ops.operations.ReduceMin](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMin) | None +| [mindspore.ops.operations.ArgMinWithValue](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMinWithValue) | 第一个输出(index)不能作为其他算子的输入 +| [mindspore.ops.operations.ArgMaxWithValue](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ArgMaxWithValue) | 第一个输出(index)不能作为其他算子的输入 +| [mindspore.ops.operations.ReduceMean](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.ReduceMean) | None +| [mindspore.ops.operations.Reshape](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Reshape) | 不支持配置切分策略 +| [mindspore.ops.operations.StridedSlice](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.StridedSlice) | 仅支持值为全0的mask;需要切分的维度必须全部提取;输入在strides不为1对应的维度不支持切分 +| [mindspore.ops.operations.Tile](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Tile) | 仅支持对multiples配置切分策略 +| [mindspore.ops.operations.Transpose](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Transpose) | None +| [mindspore.ops.operations.Diag](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.ops.operations.html#mindspore.ops.operations.Diag) | 不支持配置切分策略 + +> 重复计算是指,机器没有用满,比如:集群有8张卡跑分布式训练,切分策略只对输入切成了4份。这种情况下会发生重复计算。 diff --git a/docs/note/source_zh_cn/specification_note.rst b/docs/note/source_zh_cn/specification_note.rst index 00875e6023..66b021a446 100644 --- a/docs/note/source_zh_cn/specification_note.rst +++ b/docs/note/source_zh_cn/specification_note.rst @@ -5,5 +5,7 @@ :maxdepth: 1 benchmark + network_list + operator_list constraints_on_network_construction diff --git a/docs/programming_guide/source_en/index.rst b/docs/programming_guide/source_en/index.rst new file mode 100644 index 0000000000..2933364dd8 --- /dev/null +++ b/docs/programming_guide/source_en/index.rst @@ -0,0 +1,14 @@ +.. MindSpore documentation master file, created by + sphinx-quickstart on Thu Mar 24 11:00:00 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +MindSpore Programming Guide +=========================== + +.. toctree:: + :maxdepth: 1 + + api_structure + network_list + operator_list diff --git a/docs/programming_guide/source_en/network_list.rst b/docs/programming_guide/source_en/network_list.rst new file mode 100644 index 0000000000..3e7a1bb42a --- /dev/null +++ b/docs/programming_guide/source_en/network_list.rst @@ -0,0 +1,7 @@ +Network List +============ + +.. toctree:: + :maxdepth: 1 + + MindSpore Network List \ No newline at end of file diff --git a/docs/programming_guide/source_en/operator_list.rst b/docs/programming_guide/source_en/operator_list.rst new file mode 100644 index 0000000000..a43ce5681e --- /dev/null +++ b/docs/programming_guide/source_en/operator_list.rst @@ -0,0 +1,10 @@ +Operator List +============= + +.. toctree:: + :maxdepth: 1 + + MindSpore Operator List + MindSpore Implicit Type Conversion + MindSpore Distributed Operator List + MindSpore Lite Operator List \ No newline at end of file diff --git a/docs/programming_guide/source_en/operator_list_lite.md b/docs/programming_guide/source_en/operator_list_lite.md deleted file mode 100644 index 63bfd34990..0000000000 --- a/docs/programming_guide/source_en/operator_list_lite.md +++ /dev/null @@ -1,113 +0,0 @@ -# Operator List - -`Linux` `On Device` `Inference Application` `Beginner` `Intermediate` `Expert` - - - -> √ The checked items are the operators supported by MindSpore Lite。 - -| Operation | CPU
      FP16 | CPU
      FP32 | CPU
      Int8 | CPU
      UInt8 | GPU
      FP16 | GPU
      FP32 | Tensorflow
      Lite op supported | Caffe
      Lite op supported | Onnx
      Lite op supported | -|-----------------------|----------|----------|-----------|----------|----------|------------------|----------|----------|----------| -| Abs | | √ | √ | √ | √ | √ | Abs | | Abs | -| Add | √ | √ | √ | √ | √ | √ | Add | | Add | -| AddN | | √ | | | | | AddN | | | -| Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | -| Argmin | | √ | √ | √ | | | Argmin | | | -| AvgPool | √ | √ | √ | √ | √ | √ | MeanPooling| Pooling | AveragePool | -| BatchNorm | √ | √ | √ | √ | √ | √ | | BatchNorm | BatchNormalization | -| BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | -| BiasAdd | | √ | √ | √ | √ | √ | | | BiasAdd | -| Broadcast | | √ | | | | | BroadcastTo | | Expand | -| Cast | √ | √ | | √ | √ | √ | Cast, DEQUANTIZE* | | Cast | -| Ceil | | √ | √ | √ | √ | √ | Ceil | | Ceil | -| Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | -| Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | -| Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | -| Cos | | √ | √ | √ | √ | √ | Cos | | Cos | -| Crop | | √ | √ | √ | | | | Crop | | -| DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | -| DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | -| DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | -| Div | √ | √ | √ | √ | √ | √ | Div, RealDiv | | Div | -| Eltwise | √ | √ | | | | | | Eltwise | | -| Elu | | √ | | | | | Elu | | Elu | -| Equal | √ | √ | √ | √ | | | Equal | | Equal | -| Exp | | √ | | | √ | √ | Exp | | Exp | -| ExpandDims | | √ | | | | | | | | -| Fill | | √ | | | | | Fill | | | -| Flatten | | √ | | | | | | Flatten | | -| Floor | | √ | √ | √ | √ | √ | flOOR | | Floor | -| FloorDiv | √ | √ | | | | | FloorDiv | | | -| FloorMod | √ | √ | | | | | FloorMod | | | -| FullConnection | | √ | √ | √ | √ | √ | FullyConnected | InnerProduct | | -| GatherNd | | √ | √ | √ | | | GatherND | | | -| GatherV2 | | √ | √ | √ | | | Gather | | Gather | -| Greater | √ | √ | √ | √ | | | Greater | | Greater | -| GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | -| Hswish | √ | √ | √ | √ | | | HardSwish | | | -| LeakyReLU | √ | √ | | | √ | √ | LeakyRelu | | LeakyRelu | -| Less | √ | √ | √ | √ | | | Less | | Less | -| LessEqual | √ | √ | √ | √ | | | LessEqual | | | -| LRN | | √ | | | | | LocalResponseNorm | | Lrn | -| Log | | √ | √ | √ | √ | √ | Log | | Log | -| LogicalAnd | √ | √ | | | | | LogicalAnd | | | -| LogicalNot | | √ | √ | √ | √ | √ | LogicalNot | | | -| LogicalOr | √ | √ | | | | | LogicalOr | | | -| LSTM | | √ | | | | | | | | -| MatMul | | √ | √ | √ | √ | √ | | | MatMul | -| Maximum | √ | √ | | | | | Maximum | | Max | -| MaxPool | √ | √ | √ | √ | √ | √ | MaxPooling | Pooling | MaxPool | -| Minimum | √ | √ | | | | | Minimum | | Min | -| Mul | √ | √ | √ | √ | √ | √ | Mul | | Mul | -| NotEqual | √ | √ | √ | √ | | | NotEqual | | | -| OneHot | | √ | | | | | OneHot | | | -| Pad | | √ | √ | √ | | | Pad | | Pad | -| Pow | | √ | √ | √ | | | Pow | Power | Power | -| PReLU | | √ | | | √ | √ | | PReLU | | -| Range | | √ | | | | | Range | | | -| Rank | | √ | | | | | Rank | | | -| ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | -| ReduceMean | √ | √ | √ | √ | | | Mean | | ReduceMean | -| ReduceMin | √ | √ | √ | √ | | | ReduceMin | | ReduceMin | -| ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | -| ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | -| ReduceSumSquare | √ | √ | √ | √ | | | | | | -| ReLU | √ | √ | √ | √ | √ | √ | Relu | ReLU | Relu | -| ReLU6 | √ | √ | √ | √ | √ | √ | Relu6 | ReLU6 | Clip* | -| Reshape | √ | √ | √ | √ | √ | √ | Reshape | Reshape | Reshape,Flatten | -| Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | -| Reverse | | √ | | | | | reverse | | | -| ReverseSequence | | √ | | | | | ReverseSequence | | | -| Round | | √ | √ | √ | √ | √ | Round | | | -| Rsqrt | | √ | √ | √ | √ | √ | Rsqrt | | | -| Scale | | √ | | | √ | √ | | Scale | | -| ScatterNd | | √ | | | | | ScatterNd | | | -| Shape | | √ | | | | | Shape | | Shape | -| Sigmoid | √ | √ | √ | √ | √ | √ | Logistic | Sigmoid | Sigmoid | -| Sin | | √ | √ | √ | √ | √ | Sin | | Sin | -| Slice | | √ | √ | √ | √ | √ | Slice | | Slice | -| Softmax | √ | √ | √ | √ | √ | √ | Softmax | Softmax | Softmax | -| SpaceToBatch | | √ | | | | | | | | -| SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | -| SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | -| SparseToDense | | √ | | | | | SpareToDense | | | -| Split | √ | √ | √ | √ | | | Split, SplitV | | | -| Sqrt | | √ | √ | √ | √ | √ | Sqrt | | Sqrt | -| Square | | √ | √ | √ | √ | √ | Square | | | -| SquaredDifference | | √ | | | | | SquaredDifference | | | -| Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | -| StridedSlice | | √ | √ | √ | | | StridedSlice| | | -| Stack | | √ | | | | | Stack | | | -| Sub | √ | √ | √ | √ | √ | √ | Sub | | Sub | -| Tanh | √ | √ | | | √ | √ | Tanh | TanH | | -| Tile | | √ | | | | | Tile | | Tile | -| TopK | | √ | √ | √ | | | TopKV2 | | | -| Transpose | √ | √ | | | √ | √ | Transpose | Permute | Transpose | -| Unique | | √ | | | | | Unique | | | -| Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | -| Unstack | | √ | | | | | Unstack | | | -| Where | | √ | | | | | Where | | | -| ZerosLike | | √ | | | | | ZerosLike | | | - -* Clip: only support convert clip(0, 6) to Relu6. -* DEQUANTIZE: only support to convert fp16 to fp32. diff --git a/docs/programming_guide/source_zh_cn/advanced_use.rst b/docs/programming_guide/source_zh_cn/advanced_use.rst index 33edc062bc..44d483602d 100644 --- a/docs/programming_guide/source_zh_cn/advanced_use.rst +++ b/docs/programming_guide/source_zh_cn/advanced_use.rst @@ -5,5 +5,8 @@ :maxdepth: 1 train + infer + performance_optimization user_defined - security_and_privacy \ No newline at end of file + security_and_privacy + extension \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/extension.rst b/docs/programming_guide/source_zh_cn/extension.rst new file mode 100644 index 0000000000..ffba7b0682 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/extension.rst @@ -0,0 +1,7 @@ +功能扩展 +=========== + +.. toctree:: + :maxdepth: 1 + + probability \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/index.rst b/docs/programming_guide/source_zh_cn/index.rst index 82c4400a4a..faca5855e5 100644 --- a/docs/programming_guide/source_zh_cn/index.rst +++ b/docs/programming_guide/source_zh_cn/index.rst @@ -3,12 +3,11 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -MindSpore API -============= +MindSpore编程指南 +=================== .. toctree:: :maxdepth: 1 - :caption: 编程指南 api_structure data_type diff --git a/docs/programming_guide/source_zh_cn/infer.md b/docs/programming_guide/source_zh_cn/infer.md new file mode 100644 index 0000000000..cd9b07a781 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/infer.md @@ -0,0 +1,19 @@ +# 推理 + + + +- [推理](#推理) + + + + + +基于MindSpore训练后的模型,支持在Ascend 910 AI处理器、Ascend 310 AI处理器、GPU、CPU、端侧等多种不同的平台上执行推理。使用方法可参考如下教程: + +- [在Ascend 910 AI处理器上执行推理](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/use/multi_platform_inference.html#ascend-910-ai) +- [在Ascend 310 AI处理器上执行推理](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/use/multi_platform_inference.html#ascend-310-ai) +- [在GPU上执行推理](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/use/multi_platform_inference.html#gpu) +- [在CPU上执行推理](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/use/multi_platform_inference.html#cpu) +- [在端侧执行推理](https://www.mindspore.cn/lite/tutorial/lite/zh-CN/r1.0/quick_start/quick_start.html) + +同时,MindSpore提供了一个轻量级、高性能的服务模块,称为MindSpore Serving,可帮助MindSpore开发者在生产环境中高效部署在线推理服务,使用方法可参考[部署推理服务](https://www.mindspore.cn/tutorial/inference/zh-CN/r1.0/serving.html)。 \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/network_list.rst b/docs/programming_guide/source_zh_cn/network_list.rst new file mode 100644 index 0000000000..9f3f23bd00 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/network_list.rst @@ -0,0 +1,7 @@ +网络支持 +=========== + +.. toctree:: + :maxdepth: 1 + + MindSpore网络支持 \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/operator_list.rst b/docs/programming_guide/source_zh_cn/operator_list.rst index 23ec64f1a8..c99fcc79f8 100644 --- a/docs/programming_guide/source_zh_cn/operator_list.rst +++ b/docs/programming_guide/source_zh_cn/operator_list.rst @@ -4,5 +4,7 @@ .. toctree:: :maxdepth: 1 - operator_list_ms - operator_list_lite \ No newline at end of file + MindSpore算子支持 + MindSpore隐式类型转换的算子支持 + MindSpore分布式算子支持 + MindSpore Lite算子支持 \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/operator_list_lite.md b/docs/programming_guide/source_zh_cn/operator_list_lite.md deleted file mode 100644 index a68dbe8b72..0000000000 --- a/docs/programming_guide/source_zh_cn/operator_list_lite.md +++ /dev/null @@ -1,113 +0,0 @@ -# MindSpore Lite 算子支持 - -`Linux` `Ascend` `端侧` `推理应用` `初级` `中级` `高级` - - - -> √勾选的项为MindSpore Lite所支持的算子。 - -| 操作名 | CPU
      FP16 | CPU
      FP32 | CPU
      Int8 | CPU
      UInt8 | GPU
      FP16 | GPU
      FP32 | 支持的Tensorflow
      Lite op | 支持的Caffe
      Lite op | 支持的Onnx
      Lite op | -|-----------------------|----------|----------|----------|-----------|----------|-------------------|----------|----------|---------| -| Abs | | √ | √ | √ | √ | √ | Abs | | Abs | -| Add | √ | √ | √ | √ | √ | √ | Add | | Add | -| AddN | | √ | | | | | AddN | | | -| Argmax | | √ | √ | √ | | | Argmax | ArgMax | ArgMax | -| Argmin | | √ | √ | √ | | | Argmin | | | -| AvgPool | √ | √ | √ | √ | √ | √ | MeanPooling| Pooling | AveragePool | -| BatchNorm | √ | √ | √ | √ | √ | √ | | BatchNorm | BatchNormalization | -| BatchToSpace | | √ | √ | √ | | | BatchToSpace, BatchToSpaceND | | | -| BiasAdd | | √ | √ | √ | √ | √ | | | BiasAdd | -| Broadcast | | √ | | | | | BroadcastTo | | Expand | -| Cast | √ | √ | | √ | √ | √ | Cast, DEQUANTIZE* | | Cast | -| Ceil | | √ | √ | √ | √ | √ | Ceil | | Ceil | -| Concat | √ | √ | √ | √ | √ | √ | Concat | Concat | Concat | -| Conv2d | √ | √ | √ | √ | √ | √ | Conv2D | Convolution | Conv | -| Conv2dTranspose | √ | √ | √ | √ | √ | √ | DeConv2D | Deconvolution | ConvTranspose | -| Cos | | √ | √ | √ | √ | √ | Cos | | Cos | -| Crop | | √ | √ | √ | | | | Crop | | -| DeDepthwiseConv2D | | √ | √ | √ | | | | Deconvolution| ConvTranspose | -| DepthToSpace | | √ | √ | √ | | | DepthToSpace| | DepthToSpace | -| DepthwiseConv2dNative | √ | √ | √ | √ | √ | √ | DepthwiseConv2D | Convolution | Convolution | -| Div | √ | √ | √ | √ | √ | √ | Div, RealDiv | | Div | -| Eltwise | √ | √ | | | | | | Eltwise | | -| Elu | | √ | | | | | Elu | | Elu | -| Equal | √ | √ | √ | √ | | | Equal | | Equal | -| Exp | | √ | | | √ | √ | Exp | | Exp | -| ExpandDims | | √ | | | | | | | | -| Fill | | √ | | | | | Fill | | | -| Flatten | | √ | | | | | | Flatten | | -| Floor | | √ | √ | √ | √ | √ | flOOR | | Floor | -| FloorDiv | √ | √ | | | | | FloorDiv | | | -| FloorMod | √ | √ | | | | | FloorMod | | | -| FullConnection | | √ | √ | √ | √ | √ | FullyConnected | InnerProduct | | -| GatherNd | | √ | √ | √ | | | GatherND | | | -| GatherV2 | | √ | √ | √ | | | Gather | | Gather | -| Greater | √ | √ | √ | √ | | | Greater | | Greater | -| GreaterEqual | √ | √ | √ | √ | | | GreaterEqual| | | -| Hswish | √ | √ | √ | √ | | | HardSwish | | | -| LeakyReLU | √ | √ | | | √ | √ | LeakyRelu | | LeakyRelu | -| Less | √ | √ | √ | √ | | | Less | | Less | -| LessEqual | √ | √ | √ | √ | | | LessEqual | | | -| LRN | | √ | | | | | LocalResponseNorm | | Lrn | -| Log | | √ | √ | √ | √ | √ | Log | | Log | -| LogicalAnd | √ | √ | | | | | LogicalAnd | | | -| LogicalNot | | √ | √ | √ | √ | √ | LogicalNot | | | -| LogicalOr | √ | √ | | | | | LogicalOr | | | -| LSTM | | √ | | | | | | | | -| MatMul | | √ | √ | √ | √ | √ | | | MatMul | -| Maximum | √ | √ | | | | | Maximum | | Max | -| MaxPool | √ | √ | √ | √ | √ | √ | MaxPooling | Pooling | MaxPool | -| Minimum | √ | √ | | | | | Minimum | | Min | -| Mul | √ | √ | √ | √ | √ | √ | Mul | | Mul | -| NotEqual | √ | √ | √ | √ | | | NotEqual | | | -| OneHot | | √ | | | | | OneHot | | | -| Pad | | √ | √ | √ | | | Pad | | Pad | -| Pow | | √ | √ | √ | | | Pow | Power | Power | -| PReLU | | √ | | | √ | √ | | PReLU | | -| Range | | √ | | | | | Range | | | -| Rank | | √ | | | | | Rank | | | -| ReduceMax | √ | √ | √ | √ | | | ReduceMax | | ReduceMax | -| ReduceMean | √ | √ | √ | √ | | | Mean | | ReduceMean | -| ReduceMin | √ | √ | √ | √ | | | ReduceMin | | ReduceMin | -| ReduceProd | √ | √ | √ | √ | | | ReduceProd | | | -| ReduceSum | √ | √ | √ | √ | | | Sum | | ReduceSum | -| ReduceSumSquare | √ | √ | √ | √ | | | | | | -| ReLU | √ | √ | √ | √ | √ | √ | Relu | ReLU | Relu | -| ReLU6 | √ | √ | √ | √ | √ | √ | Relu6 | ReLU6 | Clip* | -| Reshape | √ | √ | √ | √ | √ | √ | Reshape | Reshape | Reshape,Flatten | -| Resize | | √ | √ | √ | | | ResizeBilinear, NearestNeighbor | Interp | | -| Reverse | | √ | | | | | reverse | | | -| ReverseSequence | | √ | | | | | ReverseSequence | | | -| Round | | √ | √ | √ | √ | √ | Round | | | -| Rsqrt | | √ | √ | √ | √ | √ | Rsqrt | | | -| Scale | | √ | | | √ | √ | | Scale | | -| ScatterNd | | √ | | | | | ScatterNd | | | -| Shape | | √ | | | | | Shape | | Shape | -| Sigmoid | √ | √ | √ | √ | √ | √ | Logistic | Sigmoid | Sigmoid | -| Sin | | √ | √ | √ | √ | √ | Sin | | Sin | -| Slice | | √ | √ | √ | √ | √ | Slice | | Slice | -| Softmax | √ | √ | √ | √ | √ | √ | Softmax | Softmax | Softmax | -| SpaceToBatch | | √ | | | | | | | | -| SpaceToBatchND | | √ | | | | | SpaceToBatchND | | | -| SpaceToDepth | | √ | | | | | SpaceToDepth | | SpaceToDepth | -| SparseToDense | | √ | | | | | SpareToDense | | | -| Split | √ | √ | √ | √ | | | Split, SplitV | | | -| Sqrt | | √ | √ | √ | √ | √ | Sqrt | | Sqrt | -| Square | | √ | √ | √ | √ | √ | Square | | | -| SquaredDifference | | √ | | | | | SquaredDifference | | | -| Squeeze | | √ | √ | √ | | | Squeeze | | Squeeze | -| StridedSlice | | √ | √ | √ | | | StridedSlice| | | -| Stack | | √ | | | | | Stack | | | -| Sub | √ | √ | √ | √ | √ | √ | Sub | | Sub | -| Tanh | √ | √ | | | √ | √ | Tanh | TanH | | -| Tile | | √ | | | | | Tile | | Tile | -| TopK | | √ | √ | √ | | | TopKV2 | | | -| Transpose | √ | √ | | | √ | √ | Transpose | Permute | Transpose | -| Unique | | √ | | | | | Unique | | | -| Unsqueeze | | √ | √ | √ | | | | | Unsqueeze | -| Unstack | | √ | | | | | Unstack | | | -| Where | | √ | | | | | Where | | | -| ZerosLike | | √ | | | | | ZerosLike | | | - -* Clip: 仅支持将clip(0, 6)转换为Relu6. -* DEQUANTIZE: 仅支持将fp16转换为fp32. diff --git a/docs/programming_guide/source_zh_cn/performance_optimization.md b/docs/programming_guide/source_zh_cn/performance_optimization.md new file mode 100644 index 0000000000..96a9415173 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/performance_optimization.md @@ -0,0 +1,19 @@ +# 性能优化 + + + +- [性能优化](#性能优化) + + + + + +MindSpore提供了多种性能优化方法,用户可根据实际情况,利用它们来提升训练和推理的性能。 + +| 优化阶段 | 优化方法 | 支持情况 | +| --- | --- | --- | +| 训练 | [分布式并行训练](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/distributed_training_tutorials.html) | Ascend、GPU | +| | [混合精度](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/enable_mixed_precision.html) | Ascend、GPU | +| | [图算融合](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/enable_graph_kernel_fusion.html) | Ascend | +| | [梯度累积](https://www.mindspore.cn/tutorial/training/zh-CN/r1.0/advanced_use/apply_gradient_accumulation.html) | Ascend、GPU | +| 推理 | [训练后量化](https://www.mindspore.cn/tutorial/lite/zh-CN/r1.0/use/post_training_quantization.html) | Lite | \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/user_defined.rst b/docs/programming_guide/source_zh_cn/user_defined.rst index b710df2302..5fc891eb18 100644 --- a/docs/programming_guide/source_zh_cn/user_defined.rst +++ b/docs/programming_guide/source_zh_cn/user_defined.rst @@ -4,4 +4,6 @@ .. toctree:: :maxdepth: 1 - 自定义算子 \ No newline at end of file + 自定义TBE算子 + 自定义GPU算子 + 自定义CPU算子 \ No newline at end of file -- Gitee

    ear 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 literal 73509 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¬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 IL;?Z;JIIQkFaQ7m diff --git a/tutorials/training/source_zh_cn/quick_start/images/linear_regression_eval_datasets.png b/tutorials/training/source_zh_cn/quick_start/images/linear_regression_eval_datasets.png index 13fe0b3774b4c0e6b2b9375bc3582089f1452da7..7dc474508bf5241a038fee6d9b5c093199d93691 100644 GIT binary patch literal 10314 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 A+W-In literal 6278 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 MTH7HiEU(=BFZzBu*#H0l diff --git a/tutorials/training/source_zh_cn/quick_start/images/model_net_and_eval_datasets.png b/tutorials/training/source_zh_cn/quick_start/images/model_net_and_eval_datasets.png index f465ac789f03ca726f18c8694c90923741e24130..c99e0bd2155c4c42befeab1ead6820f9edf7c059 100644 GIT binary patch literal 10854 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 literal 6903 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 -- [实现简单线性函数拟合](#实现简单线性函数拟合) - - [概述](#概述) - - [环境准备](#环境准备) - - [生成数据集](#生成数据集) - - [定义数据集生成函数](#定义数据集生成函数) - - [生成测试数据](#生成测试数据) +- [概述](#概述) +- [环境准备](#环境准备) +- [生成数据集](#生成数据集) + - [定义数据集生成函数](#定义数据集生成函数) + - [定义数据增强函数](#定义数据增强函数) +- [定义训练网络](#定义训练网络) +- [定义前向传播网络与反向传播网络并关联](#定义前向传播网络与反向传播网络并关联) - [定义前向传播网络](#定义前向传播网络) - - [初始化网络模型](#初始化网络模型) - - [查看初始化的网络模型](#查看初始化的网络模型) - - [定义损失函数](#定义损失函数) - - [损失函数与网络结合](#损失函数与网络结合) - [定义反向传播网络](#定义反向传播网络) - - [实现梯度函数](#实现梯度函数) - - [反向传播更新权重](#反向传播更新权重) - - [定义模型拟合过程可视化函数](#定义模型拟合过程可视化函数) - - [执行训练](#执行训练) - - [总结](#总结) + - [关联前向和反向传播网络](#关联前向和反向传播网络) +- [拟合过程可视化准备](#拟合过程可视化准备) + - [定义绘图函数](#定义绘图函数) + - [定义回调函数](#定义回调函数) +- [执行训练](#执行训练) +- [总结](#总结) @@ -30,374 +26,331 @@    + ## 概述 回归问题算法通常是利用一系列属性来预测一个值,预测的值是连续的。例如给出一套房子的一些特征数据,如面积、卧室数等等来预测房价,利用最近一周的气温变化和卫星云图来预测未来的气温情况等。如果一套房子实际价格为500万元,通过回归分析的预测值为499万元,则认为这是一个比较好的回归分析。在机器学习问题中,常见的回归分析有线性回归、多项式回归、逻辑回归等。本例子介绍线性回归算法,并通过MindSpore进行线性回归AI训练体验。 -主要流程如下: +整体流程如下: 1. 生成数据集 -2. 定义前向传播网络 -3. 定义反向传播网络 -4. 定义线性拟合过程的可视化函数 +2. 定义训练网络 +3. 定义前向传播网络与反向传播网络并关联 +4. 拟合过程可视化准备 5. 执行训练 -本次样例源代码请参考:。 +本例的源代码地址:。 ## 环境准备 -系统:Ubuntu18.04 - -MindSpore版本:GPU - 设置MindSpore运行配置 -第三方支持包:`matplotlib`,未安装此包的,可使用命令`pip install matplotlib`预先安装。 ```python from mindspore import context -context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU") +context.set_context(mode=context.GRAPH_MODE, device_target="CPU") ``` -`PYNATIVE_MODE`:自定义调试模式。 +`GRAPH_MODE`:自定义调试模式。 + +`device_target`:设置MindSpore的训练硬件为CPU。 -`device_target`:设置MindSpore的训练硬件为GPU。 +> 本教程代码依赖`matplotlib`第三方支持包,可使用命令`pip install matplotlib`安装。 ## 生成数据集 ### 定义数据集生成函数 -`get_data`用于生成训练数据集和测试数据集。由于拟合的是线性数据,假定要拟合的目标函数为:$y=2x+3$,那么我们需要的训练数据集应随机分布于函数周边,这里采用了$y=2x+3+noise$的方式生成,其中`noise`为遵循标准正态分布规律的随机数值。 +`get_data`用于生成训练数据集和测试数据集。由于拟合的是线性数据,假定要拟合的目标函数为:$f(x)=2x+3$,那么我们需要的训练数据集应随机分布于函数周边,这里采用了$f(x)=2x+3+noise$的方式生成,其中`noise`为遵循标准正态分布规律的随机数值。 ```python import numpy as np -import mindspore as ms -from mindspore import Tensor - -def get_data(num,w=2.0, b=3.0): - np_x = np.ones([num, 1]) - np_y = np.ones([num, 1]) + +def get_data(num, w=2.0, b=3.0): for i in range(num): x = np.random.uniform(-10.0, 10.0) - np_x[i] = x noise = np.random.normal(0, 1) y = x * w + b + noise - np_y[i] = y - return Tensor(np_x,ms.float32), Tensor(np_y,ms.float32) + yield np.array([x]).astype(np.float32), np.array([y]).astype(np.float32) ``` -数据生成函数将有以下两个作用。 - -1. 生成训练数据,对模型函数进行训练。 -2. 生成验证数据,在训练结束后,对模型函数进行精度验证。 - -### 生成测试数据 - -使用数据生成函数`get_data`随机生成50组验证数据,并可视化展示。 +使用`get_data`生成50组测试数据,可视化展示。 ```python import matplotlib.pyplot as plt -eval_x, eval_label = get_data(50) -x1, y1 = eval_x.asnumpy(), eval_label.asnumpy() -plt.scatter(x1, y1, color="red", s=5) -plt.title("Eval_data") +eval_data = list(get_data(50)) +x_target_label = np.array([-10, 10, 0.1]) +y_target_label = x_target_label * 2 + 3 +x_eval_label,y_eval_label = zip(*eval_data) + +plt.scatter(x_eval_label, y_eval_label, color="red", s=5) +plt.plot(x_target_label, y_target_label, color="green") +plt.title("Eval data") plt.show() ``` 输出结果: -![png](./images/linear_regression_eval_datasets.png) +![png](./images/linear_regression_eval_datasets.png) -## 定义前向传播网络 -### 初始化网络模型 +上图中绿色线条部分为目标函数,红点部分为验证数据`eval_data`。 -使用`nn.Dense`定义了网络模型,即为线性模型, +### 定义数据增强函数 -$$y=wx+b\tag{1}$$ +先使用MindSpore的数据转换函数`GeneratorDataset`转换成适应MindSpore训练的数据类型,然后再使用`batch`、`repeat`对数据进行增强操作,操作解释如下: -其中,权重值$w$对应`weight`,$b$对应`bias`,并将其打印出来。 +- `ds.GeneratorDataset`:将生成的数据转换为MindSpore的数据集,并且将生成的数据的x,y值存入到`data`和`label`的数组中。 +- `batch`:将`batch_size`个数据组合成一个batch。 +- `repeat`:将数据集数量倍增。 ```python -from mindspore.common.initializer import TruncatedNormal -from mindspore import nn +from mindspore import dataset as ds -net = nn.Dense(1,1,TruncatedNormal(0.02),TruncatedNormal(0.02)) -print("weight:", net.weight.set_data([0][0]), "bias:", net.bias.set_data([0])) +def create_dataset(num_data, batch_size=16, repeat_size=1): + input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data', 'label']) + input_data = input_data.batch(batch_size) + input_data = input_data.repeat(repeat_size) + return input_data ``` -输出结果: - - weight: -0.00034249047 bias: -0.019308656 - +使用数据集增强函数生成训练数据,并查看训练数据的格式。 -### 查看初始化的网络模型 -我们将验证数据集和初始化的模型函数可视化。 +```python +num_data = 1600 +batch_size = 16 +repeat_size = 1 +ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size) +print("The dataset size of ds_train:", ds_train.get_dataset_size()) +dict_datasets = ds_train.create_dict_iterator().get_next() -```python -x = np.arange(-10, 10, 0.1) -y = x * (net.weight.set_data([0][0]).asnumpy()) + (net.bias.set_data([0]).asnumpy()) -plt.scatter(x1, y1, color="red", s=5) -plt.plot(x, y, "blue") -plt.title("Eval data and net") -plt.show() +print(dict_datasets.keys()) +print("The x label value shape:", dict_datasets["data"].shape) +print("The y label value shape:", dict_datasets["label"].shape) ``` 输出结果: -![png](./images/model_net_and_eval_datasets.png) - - -红色的点:为之前生成的50组验证数据集。 - -蓝色的线:初始化的模型网络。 - -### 定义损失函数 - -我们的网络模型表达式为: - -$$h(x)=wx+b\tag{2}$$ - -一般地,数学上对线性回归模型采用均方差的方式来判断模型是否拟合得很好,即均方差的值$J(w)$值越小,函数模型便拟合得越好,验证数据代入后,预测得到的y值就越准确。公式2对应m个数据的均方差公式为: - -$$J(w)=\frac{1}{m}\sum_{i=1}^m(h(x_i)-y^{(i)})^2\tag{3}$$ - -为了方便后续的计算,我们采用0.5倍的均方差的表达式来进行计算,均方差值整体缩小至0.5倍的计算方式对判断模型拟合的好坏没有影响。 - -$$J(w)=\frac{1}{2m}\sum_{i=1}^m(h(x_i)-y^{(i)})^2\tag{4}$$ - -公式4即为网络训练中的损失函数,其中参数: + The dataset size of ds_train: 100 + dict_keys(['data', 'label']) + The x label value shape: (16, 1) + The y label value shape: (16, 1) + -- $J(w)$为均方差。 +通过定义的`create_dataset`将生成的1600个数据增强为了100组shape为16x1的数据集。 -- $m$为样本数据的数量。 +## 定义训练网络 -- $h(x_i)$为第$i$个数据的$x_i$值代入模型网络(公式2)后的预测值。 +在MindSpore中使用`nn.Dense`生成单个数据输入,单个数据输出的线性函数模型: -- $y^{(i)}$为第$i$个数据中的$y$值(label值)。 +$$f(x)=wx+b\tag{1}$$ -在MindSpore中定义损失函数的方法如下。 +并使用Normal算子随机初始化权重$w$和$b$。 ```python -from mindspore.ops import operations as P - -class MyLoss(nn.loss.loss._Loss): - def __init__(self,reduction='mean'): - super().__init__(reduction) - self.square = P.Square() - def construct(self, data, label): - x = self.square(data-label) * 0.5 - return self.get_loss(x) -``` - -其中: - -- `nn.loss.loss._Loss`:是MindSpore自定义loss算子的一个基类。 +from mindspore.common.initializer import Normal +from mindspore import nn -- `P.Square`:MindSpore训练的框架中的平方算子,算子需要注册过才能在框架的计算图中使用。 +class LinearNet(nn.Cell): + def __init__(self): + super(LinearNet, self).__init__() + self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02)) -### 损失函数与网络结合 + def construct(self, x): + x = self.fc(x) + return x +``` -接下来我们需要将loss函数的表达式和网络net关联在一起,在MindSpore中需要`nn.WithLossCell`,实现方法如下: +调用网络查看初始化的模型参数。 ```python -criterion = MyLoss() -loss_opeartion = nn.WithLossCell(net, criterion) +net = LinearNet() +model_params = net.trainable_params() +print(model_params) ``` -其中: - -- `net`:网络模型。 - -- `criterion`:即为实例化的loss函数。 - -上述从数据代入到计算出loss值的过程为AI训练中的前向传播过程。 - -## 定义反向传播网络 +输出结果: -有了损失函数后,我们如何使得损失函数最小呢?我们可以将公式1代入到损失函数公式4中展开: + [Parameter (name=fc.weight, value=Tensor(shape=[1, 1], dtype=Float32, + [[-7.35660456e-003]])), Parameter (name=fc.bias, value=Tensor(shape=[1], dtype=Float32, [-7.35660456e-003]))] + -$$J(w,b)=\frac{1}{2m}\sum_{i=1}^m(wx_i+b-y^{(i)})^2\tag{5}$$ +初始化网络模型后,接下来将初始化的网络函数和训练数据集进行可视化,了解拟合前的模型函数情况。 -公式5可以将$J(w)$看作为凹函数,对权重值$w$微分可求得: -$$\frac{\partial{J(w)}}{\partial{w}}=\frac{1}{m}\sum_{i=1}^mx_i(wx_i+b-y^{(i)})\tag{6}$$ +```python +from mindspore import Tensor +x_model_label = np.array([-10, 10, 0.1]) +y_model_label = (x_model_label * Tensor(model_params[0]).asnumpy()[0][0] + + Tensor(model_params[1]).asnumpy()[0]) -由凹函数的特性可以知道,当公式6等于0时,损失函数有最小值: +plt.scatter(x_eval_label, y_eval_label, color="red", s=5) +plt.plot(x_model_label, y_model_label, color="blue") +plt.plot(x_target_label, y_target_label, color="green") +plt.show() +``` -$$\sum_{i=1}^mx_i(wx_i+b-y^{(i)})=0\tag{7}$$ +输出结果: -假设有一个$w_{min}$使得公式7成立。我们如何将初始的权重$w_{s}$逐步的变成$w_{min}$,在这里采取迭代法,也就是梯度下降方法 -当权重$w_{s}w_{min}$,权重值需要左移即权重值变小接近$w_{min}$,才能使得损失函数逐步的变小,由凹函数的性质可知,在$w_{s}$处的导数为正(损失函数在$w_{min}$右边单调上升),公式8的值为正。其权重的更新公式为: +- $h(x_i)$为第$i$个数据的$x_i$值代入模型网络(公式1)后的预测值。 -$$w_{ud}=w_{s}-\alpha\frac{\partial{J(w_{s})}}{\partial{w}}\tag{10}$$ +- $y^{(i)}$为第$i$个数据中的$y^{(i)}$值(label值)。 +### 定义前向传播网络 -当$w_{s}=w_{min}$时,到$\frac{\partial{J(w_{s})}}{\partial{w}}$=0,即梯度消失,其表达式也可写为公式9的样式。 +前向传播网络包含两个部分,其中: -在考虑了全区间的情况后,可以得出权重$w$的更新公式即为: +1. 将参数带入到模型网络中得出预测值。 +2. 使用预测值和训练数据计算出loss值。 -$$w_{ud}=w_{s}-\alpha\frac{\partial{J(w_{s})}}{\partial{w}}\tag{11}$$ +在MindSpore中使用如下方式实现。 -当权重$w$在更新的过程中假如临近$w_{min}$在增加或者减少一个$\Delta{w}$,从左边或者右边越过了$w_{min}$,公式11都会使权重往反的方向移动,那么最终$w_{s}$的值会在$w_{min}$附近来回迭代,在实际训练中我们也是这样采用迭代的方式取得最优权重$w$,使得损失函数无限逼近局部最小值。 -同理:对于公式5中的另一个权重$b$容易得出其更新公式为: +```python +net = LinearNet() +net_loss = nn.loss.MSELoss() +``` -$$b_{ud}=b_{s}-\alpha\frac{\partial{J(b_{s})}}{\partial{b}}\tag{12}$$ +### 定义反向传播网络 +反向传播网络的目标是不断变换权重值,使得loss值取得最小值,一般的在线性网络中采用权重更新公式: -当所有的权重更新完成后,将新的权重赋值给初始权重:即$w_{s}$=$w_{ud}$,$b_{s}$=$b_{ud}$。将新的初始权重传递回到模型函数中,这样就完成了反向传播的过程。 +$$w_{t}=w_{t-1}-\alpha\frac{\partial{J(w_{t-1})}}{\partial{w}}\tag{3}$$ -> 当遇到多项式的回归模型时,上述梯度方法也适用,由于权重数量的增加,需要将权重的名称更新为$w_0,w_1,w_2,...,w_n$,引入矩阵的表达方式,公式将会更加简洁,这里就不多介绍了。 +公式3参数解释: -### 实现梯度函数 +- $w_{t}$为迭代后的权重值。 +- $w_{t-1}$为迭代前的权重值。 +- $\alpha$为学习率。 +- $\frac{\partial{J(w_{t-1}\ )}}{\partial{w}}$为损失函数对权重$w_{t-1}$的微分。 -在MindSpore中的所有要编入计算图的类都需要继承`nn.Cell`算子。MindSpore的梯度计算函数采用如下方式。 +函数中所有的权重值更新完成后,将值传入到模型函数中,这个过程就是反向传播过程,实现此过程需要使用MindSpore中的优化器函数,如下: ```python -from mindspore.ops import composite as C - -class GradWrap(nn.Cell): - """ GradWrap definition """ - def __init__(self, network): - super().__init__(auto_prefix=False) - self.network = network - self.weights = ms.ParameterTuple(filter(lambda x: x.requires_grad, - network.get_parameters())) - - def construct(self, data, label): - weights = self.weights - return C.GradOperation(get_by_list=True) \ - (self.network, weights)(data, label) - +opt = nn.Momentum(net.trainable_params(), learning_rate=0.005, momentum=0.9) ``` -上述代码中`GradWrap`实现的是对各个权重的微分$\frac{\partial{J(w)}}{\partial{w}}$,其展开式子参考公式6。 - -### 反向传播更新权重 +### 关联前向和反向传播网络 -`nn.RMSProp`为完成权重更新的函数,更新方式大致为公式11,但是考虑的因素更多,具体信息请参考[官网说明](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html?highlight=rmsprop#mindspore.nn.RMSProp)。 +定义完成前向传播和反向传播后,在MindSpore中需要调用`Model`函数,将前面定义的网络,损失函数,优化器函数关联起来,使之变成完整的计算网络。 ```python -train_network = GradWrap(loss_opeartion) -train_network.set_train() -optim = nn.RMSProp(params=net.trainable_params(),learning_rate=0.02) +from mindspore.train import Model + +model = Model(net, net_loss, opt) ``` -通过以上操作,我们就完成了前向传播网络和反向传播网络的定义,接下来可以加载训练数据进行线性拟合了。 +## 拟合过程可视化准备 -## 定义模型拟合过程可视化函数 +### 定义绘图函数 -定义一个可视化函数`plot_model_and_datasets`,将模型函数和验证数据集打印出来,观察其变化。 +为了使得整个训练过程更容易理解,需要将训练过程的测试数据、目标函数和模型网络进行可视化,这里定义了可视化函数,将在每个step训练结束后调用,展示模型网络的拟合过程。 ```python -import time +import matplotlib.pyplot as plt +import time -def plot_model_and_datasets(weight, bias, data_x, data_y): +def plot_model_and_datasets(net, eval_data): + weight = net.trainable_params()[0] + bias = net.trainable_params()[1] x = np.arange(-10, 10, 0.1) - y = x * ((weight[0][0]).asnumpy()) + ((bias[0]).asnumpy()) - plt.scatter(x1,y1,color="red",s=5) - plt.scatter(data_x.asnumpy(), data_y.asnumpy(), color="black", s=5) - plt.plot(x, y, "blue") + y = x * Tensor(weight).asnumpy()[0][0] + Tensor(bias).asnumpy()[0] + x1, y1 = zip(*eval_data) + x_target = x + y_target = x_target * 2 + 3 + plt.axis([-11, 11, -20, 25]) + plt.scatter(x1, y1, color="red", s=5) + plt.plot(x, y, color="blue") + plt.plot(x_target, y_target, color="green") plt.show() time.sleep(0.02) ``` -上述函数的参数: - -- `weight`:模型函数的权重,即$w$。 +### 定义回调函数 -- `bias`:模型函数的权重,即$b$。 +MindSpore提供的工具,可对模型训练过程进行自定义控制,这里在`step_end`中调用可视化函数,展示拟合过程。更多的使用可参考[官网说明]()。 -- `data_x`:训练数据的$x$值。 -- `data_y`:训练数据的$y$值。 - -> 可视化过程中,红色的点是验证数据集,黑色的点是单个batch的训练数据,蓝色的线条是正在训练的回归模型。 +```python +from IPython import display +from mindspore.train.callback import Callback + +class ImageShowCallback(Callback): + def __init__(self, net, eval_data): + self.net = net + self.eval_data = eval_data + + def step_end(self, run_context): + plot_model_and_datasets(self.net, self.eval_data) + display.clear_output(wait=True) +``` ## 执行训练 -其训练过程如下: - -1. 设置训练的迭代次数`step_size`。 -2. 设置单次迭代的训练数据量`batch_size`。 -3. 正向传播训练`grads`。 -4. 反向传播训练`optim`。 -5. 图形展示模型函数和数据集。 -6. 清除本轮迭代的输出`display.clear_output`,起到动态可视化效果。 +完成以上过程后,可以使用训练数`ds_train`对模型训练,这里调用`model.train`进行,其中参数解释: -迭代完成后,输出网络模型的权重值$w$和$b$。 +- `epoch`:训练迭代的整个数据集的次数。 +- `ds_train`:训练数据集。 +- `callbacks`:训练过程中需要调用的回调函数。 +- `dataset_sink_model`:数据集下沉模式,支持Ascend、GPU计算平台,本例为CPU计算平台设置为False。 ```python -from IPython import display -step_size = 200 -batch_size = 16 +from mindspore.train.callback import LossMonitor -for i in range(step_size): - data_x,data_y = get_data(batch_size) - grads = train_network(data_x,data_y) - optim(grads) - plot_model_and_datasets(net.weight.data, - net.bias.data, data_x, data_y) - display.clear_output(wait=True) - -output = net(eval_x) -loss_output = criterion(output, eval_label) -print("loss_value:", loss_output.asnumpy()) -plot_model_and_datasets(net.weight.data, net.bias.data, data_x,data_y) -print("weight:", net.weight.set_data([0][0]), "bias:", net.bias.set_data([0])) +epoch = 1 +imageshow_cb = ImageShowCallback(net, eval_data) +model.train(epoch, ds_train, callbacks=[imageshow_cb], dataset_sink_mode=False) + +plot_model_and_datasets(net,eval_data) +print(net.trainable_params()[0], "\n%s" % net.trainable_params()[1]) ``` 输出结果: - loss_value: 0.42879593 - - - ![gif](./images/linear_regression.gif) - weight: 1.9990227 bias: 2.9115517 + Parameter (name=fc.weight, value=[[2.0065749]]) + Parameter (name=fc.bias, value=[3.0089042]) -可以看到最终得到的线性拟合的权重值非常接近目标函数权重weight=2、bias=3。 +训练完成后打印出最终模型的权重参数,其中weight接近于2.0,bias接近于3.0,模型训练完成,符合预期。 ## 总结 diff --git a/tutorials/tutorial_code/linear_regression.py b/tutorials/tutorial_code/linear_regression.py index 6e53c6ae09..35003f67b2 100644 --- a/tutorials/tutorial_code/linear_regression.py +++ b/tutorials/tutorial_code/linear_regression.py @@ -1,74 +1,53 @@ import numpy as np -import mindspore as ms -from mindspore.ops import composite as C -from mindspore.ops import operations as P -from mindspore import Tensor -from mindspore import context -from mindspore.common.initializer import TruncatedNormal +from mindspore import dataset as ds +from mindspore.common.initializer import Normal from mindspore import nn - -context.set_context(mode=context.PYNATIVE_MODE, device_target="GPU") +from mindspore.train import Model +from mindspore.train.callback import LossMonitor +from mindspore import context + +context.set_context(mode=context.GRAPH_MODE, device_target="CPU") + -# Generating training data sets def get_data(num, w=2.0, b=3.0): - np_x = np.ones([num, 1]) - np_y = np.ones([num, 1]) for i in range(num): - x = np.random.uniform(-10.0, 10.0) - np_x[i] = x + x = np.random.uniform(-10.0, 10.0) noise = np.random.normal(0, 1) - y = x * w + b + noise - np_y[i]=y - return Tensor(np_x,ms.float32), Tensor(np_y,ms.float32) - -# Define the form of loss function: 1/2 * (y - y')^2 -class MyLoss(nn.loss.loss._Loss): - def __init__(self, reduction='mean'): - super().__init__(reduction) - self.square = P.Square() - def construct(self, data, label): - x = self.square(data - label) * 0.5 - return self.get_loss(x) - -# Gradient function -class GradWrap(nn.Cell): - """ GradWrap definition """ - def __init__(self, network): - super().__init__(auto_prefix=False) - self.network = network - self.weights = ms.ParameterTuple(filter(lambda x: x.requires_grad, - network.get_parameters())) - - def construct(self, data, label): - weights = self.weights - return C.GradOperation(get_by_list=True) \ - (self.network, weights)(data, label) - -# Initializing model functions -net = nn.Dense(1, 1, TruncatedNormal(0.02), TruncatedNormal(0.02)) - -# Loss function -criterion = MyLoss() -loss_opeartion = nn.WithLossCell(net, criterion) -train_network = GradWrap(loss_opeartion) -train_network.set_train() - -# Defining optimization -optim = nn.RMSProp(params=net.trainable_params(), learning_rate=0.02) - -# Executive Training -step_size = 200 -batch_size = 16 -for i in range(step_size): - data_x, data_y = get_data(batch_size) - grads = train_network(data_x, data_y) - optim(grads) - - # Print loss value per 10 step - if i%10 == 0: - output = net(data_x) - loss_output = criterion(output, data_y) - print(loss_output.asnumpy()) - -# Print final weight parameters -print("weight:", net.weight.set_data([0][0]), "bias:", net.bias.set_data([0])) \ No newline at end of file + y = x * w + b + noise + yield np.array([x]).astype(np.float32), np.array([y]).astype(np.float32) + + +def create_dataset(num_data, batch_size=16, repeat_size=1): + input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data','label']) + input_data = input_data.batch(batch_size) + input_data = input_data.repeat(repeat_size) + return input_data + + +class LinearNet(nn.Cell): + def __init__(self): + super(LinearNet, self).__init__() + self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02)) + + def construct(self, x): + x = self.fc(x) + return x + + +if __name__ == "__main__": + + num_data = 1600 + batch_size = 16 + repeat_size = 1 + lr = 0.005 + momentum = 0.9 + + net = LinearNet() + net_loss = nn.loss.MSELoss() + opt = nn.Momentum(net.trainable_params(), lr, momentum) + model = Model(net, net_loss, opt) + + ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size) + model.train(1, ds_train, callbacks=LossMonitor(), dataset_sink_mode=False) + + print(net.trainable_params()[0], "\n%s" % net.trainable_params()[1]) \ No newline at end of file -- Gitee From 113a28a113b6810d8629f17da7f5e4b39c98b027 Mon Sep 17 00:00:00 2001 From: jzg Date: Thu, 17 Sep 2020 10:34:31 +0800 Subject: [PATCH 050/100] amend deeplabv3 link --- docs/programming_guide/source_en/network_list.md | 2 +- docs/programming_guide/source_zh_cn/network_list.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/programming_guide/source_en/network_list.md b/docs/programming_guide/source_en/network_list.md index d8cc516092..0cc5bb974e 100644 --- a/docs/programming_guide/source_en/network_list.md +++ b/docs/programming_guide/source_en/network_list.md @@ -31,7 +31,7 @@ | Computer Vision (CV) | Targets Detection | [YoloV3-ResNet18](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_resnet18/src/yolov3.py) | Supported | Doing | Doing | Computer Vision (CV) | Targets Detection | [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | Supported | Doing | Doing | Computer Vision (CV) | Targets Detection | [FasterRCNN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/faster_rcnn/src/FasterRcnn/faster_rcnn_r50.py) | Supported | Doing | Doing -| Computer Vision (CV) | Semantic Segmentation | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/deeplabv3.py) | Supported | Doing | Doing +| Computer Vision (CV) | Semantic Segmentation | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/nets/deeplab_v3/deeplab_v3.py) | Supported | Doing | Doing | Computer Vision(CV) | Targets Detection | [WarpCTC](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/warpctc/src/warpctc.py) | Doing | Supported | Doing | Natural Language Processing (NLP) | Natural Language Understanding | [BERT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | Supported | Doing | Doing | Natural Language Processing (NLP) | Natural Language Understanding | [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py) | Supported | Doing | Doing diff --git a/docs/programming_guide/source_zh_cn/network_list.md b/docs/programming_guide/source_zh_cn/network_list.md index 638b9518ac..c521843f87 100644 --- a/docs/programming_guide/source_zh_cn/network_list.md +++ b/docs/programming_guide/source_zh_cn/network_list.md @@ -31,7 +31,7 @@ | 计算机视觉(CV) | 目标检测(Targets Detection) | [YoloV3-ResNet18](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_resnet18/src/yolov3.py) | Supported | Doing | Doing | 计算机视觉(CV) | 目标检测(Targets Detection) | [YoloV3-DarkNet53](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/yolov3_darknet53/src/yolo.py) | Supported | Doing | Doing | 计算机视觉(CV) | 目标检测(Targets Detection) | [FasterRCNN](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/faster_rcnn/src/FasterRcnn/faster_rcnn_r50.py) | Supported | Doing | Doing -| 计算机视觉(CV) | 语义分割(Semantic Segmentation) | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/deeplabv3.py) | Supported | Doing | Doing +| 计算机视觉(CV) | 语义分割(Semantic Segmentation) | [DeeplabV3](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/deeplabv3/src/nets/deeplab_v3/deeplab_v3.py) | Supported | Doing | Doing | 计算机视觉(CV) | 目标检测(Targets Detection) | [WarpCTC](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/cv/warpctc/src/warpctc.py) | Doing | Supported | Doing | 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [BERT](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/bert/src/bert_model.py) | Supported | Doing | Doing | 自然语言处理(NLP) | 自然语言理解(Natural Language Understanding) | [Transformer](https://gitee.com/mindspore/mindspore/blob/master/model_zoo/official/nlp/transformer/src/transformer_model.py) | Supported | Doing | Doing -- Gitee From 4f64c92dc698955efebb47636d654bcaa43ac8d0 Mon Sep 17 00:00:00 2001 From: leiyuning Date: Thu, 17 Sep 2020 10:30:46 +0800 Subject: [PATCH 051/100] fix .rst bug --- docs/note/source_en/design.rst | 2 ++ docs/note/source_zh_cn/design.rst | 1 + tutorials/lite/source_en/use/converter_tool.md | 6 +++--- tutorials/lite/source_zh_cn/convert_model.rst | 8 ++++++++ tutorials/lite/source_zh_cn/index.rst | 2 +- .../lite/source_zh_cn/use/post_training_quantization.md | 5 ++--- .../training/source_zh_cn/advanced_use/migrate_script.rst | 6 +++--- tutorials/training/source_zh_cn/index.rst | 1 + 8 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 tutorials/lite/source_zh_cn/convert_model.rst diff --git a/docs/note/source_en/design.rst b/docs/note/source_en/design.rst index 4671808d08..9373ac6ee0 100644 --- a/docs/note/source_en/design.rst +++ b/docs/note/source_en/design.rst @@ -5,7 +5,9 @@ Design :maxdepth: 1 design/mindspore/architecture + design/mindspore/architecture_lite design/mindspore/mindir + design/mindspore/distributed_training_design design/mindinsight/training_visual_design design/mindinsight/graph_visual_design design/mindinsight/tensor_visual_design diff --git a/docs/note/source_zh_cn/design.rst b/docs/note/source_zh_cn/design.rst index 4e1eb6ed8f..2eddcf074f 100644 --- a/docs/note/source_zh_cn/design.rst +++ b/docs/note/source_zh_cn/design.rst @@ -6,6 +6,7 @@ design/technical_white_paper design/mindspore/architecture + design/mindspore/architecture_lite design/mindspore/mindir design/mindspore/distributed_training_design design/mindinsight/profiler_design diff --git a/tutorials/lite/source_en/use/converter_tool.md b/tutorials/lite/source_en/use/converter_tool.md index 99f3d5464f..9075adc364 100644 --- a/tutorials/lite/source_en/use/converter_tool.md +++ b/tutorials/lite/source_en/use/converter_tool.md @@ -1,14 +1,14 @@ -# Convert to MindSpore Lite +# Convert to MindSpore Lite Model -- [Convert to MindSpore Lite](#convert-to-mindspore-lite) +- [Convert to MindSpore Lite Model](#convert-to-mindspore-lite-model) - [Overview](#overview) - [Linux Environment Instructions](#linux-environment-instructions) - [Environment Preparation](#environment-preparation) - [Example](#example) - [Parameter Description](#parameter-description) - - [Windows Environment Instructions](#windows-environment-instructions) + - [Windows Environment Instructions](#windows-environment-instructions) - [Environment Preparation](#environment-preparation-1) - [Parameter Description](#parameter-description-1) - [Example](#example-1) diff --git a/tutorials/lite/source_zh_cn/convert_model.rst b/tutorials/lite/source_zh_cn/convert_model.rst new file mode 100644 index 0000000000..7a6e093242 --- /dev/null +++ b/tutorials/lite/source_zh_cn/convert_model.rst @@ -0,0 +1,8 @@ +转换为MindSpore Lite模型 +=========== + +.. toctree:: + :maxdepth: 1 + + converter_tool + post_training_quantization \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/index.rst b/tutorials/lite/source_zh_cn/index.rst index 6c70679a8a..98cb3a95ac 100644 --- a/tutorials/lite/source_zh_cn/index.rst +++ b/tutorials/lite/source_zh_cn/index.rst @@ -19,6 +19,6 @@ :caption: 基础使用 use/build - use/converter_tool + use/converter_model use/evaluating_the_model use/runtime \ No newline at end of file diff --git a/tutorials/lite/source_zh_cn/use/post_training_quantization.md b/tutorials/lite/source_zh_cn/use/post_training_quantization.md index 921b60211e..11ae39928d 100644 --- a/tutorials/lite/source_zh_cn/use/post_training_quantization.md +++ b/tutorials/lite/source_zh_cn/use/post_training_quantization.md @@ -1,8 +1,8 @@ -# 训练后量化 +# 转换为MindSpore Lite量化模型(训练后量化) -- [训练后量化](#训练后量化) +- [转换为MindSpore Lite量化模型(训练后量化)](#转换为mindspore-lite量化模型训练后量化) - [概述](#概述) - [权重量化](#权重量化) - [参数说明](#参数说明) @@ -13,7 +13,6 @@ - [使用步骤](#使用步骤-1) - [部分模型精度结果](#部分模型精度结果-1) - diff --git a/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst b/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst index b4aeabcb92..e23cb61a2d 100644 --- a/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst +++ b/tutorials/training/source_zh_cn/advanced_use/migrate_script.rst @@ -1,9 +1,9 @@ 迁移第三方框架训练脚本 -=========== +==================== .. toctree:: :maxdepth: 1 - advanced_use/migrate_3rd_scripts_mindconverter - advanced_use/migrate_3rd_scripts + migrate_3rd_scripts_mindconverter + migrate_3rd_scripts \ No newline at end of file diff --git a/tutorials/training/source_zh_cn/index.rst b/tutorials/training/source_zh_cn/index.rst index 5878b4a0f9..3dc97552cb 100644 --- a/tutorials/training/source_zh_cn/index.rst +++ b/tutorials/training/source_zh_cn/index.rst @@ -41,6 +41,7 @@ advanced_use/custom_operator advanced_use/migrate_script + advanced_use/apply_deep_probability_programming .. toctree:: :glob: -- Gitee From 9aa9a04b775a0351a2d9c0a97cc1dd38a1e9850c Mon Sep 17 00:00:00 2001 From: liuluobin Date: Thu, 17 Sep 2020 10:42:16 +0800 Subject: [PATCH 052/100] Interface change --- ...est_model_security_membership_inference.md | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md b/tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md index c1bad5d744..50ca3b0c83 100644 --- a/tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md +++ b/tutorials/training/source_zh_cn/advanced_use/test_model_security_membership_inference.md @@ -1,33 +1,31 @@ # 使用成员推理测试模型安全性 -`Linux` `Ascend` `全流程` `初级` `中级` `高级` - - [使用成员推理测试模型安全性](#使用成员推理测试模型安全性) - [概述](#概述) - [实现阶段](#实现阶段) - [导入需要的库文件](#导入需要的库文件) - - [引入相关包](#引入相关包) - [加载数据集](#加载数据集) - [建立模型](#建立模型) - - [运用MembershipInference](#运用membershipinference) + - [运用MembershipInference进行隐私安全评估](#运用membershipinference进行隐私安全评估) - [参考文献](#参考文献) +    ## 概述 -成员推理攻击是一种窃取用户数据隐私的方法。隐私指的是单个用户的某些属性,一旦泄露可能会造成人身损害、名誉损害等后果。通常情况下,用户的隐私数据会作保密处理,但我们可以利用非敏感信息来进行推测。例如:”抽烟的人更容易得肺癌“,这个信息不属于隐私信息,但如果知道“张三抽烟”,就可以推断“张三”更容易得肺癌,这就是成员推理。 +成员推理是一种推测用户隐私数据的方法。隐私指的是单个用户的某些属性,一旦泄露可能会造成人身损害、名誉损害等后果。通常情况下,用户的隐私数据会作保密处理,但我们可以利用非敏感信息来进行推测。如果我们知道了某个私人俱乐部的成员都喜欢戴紫色墨镜、穿红色皮鞋,那么我们遇到一个戴紫色墨镜且穿红色皮鞋(非敏感信息)的人,就可以推断他/她很可能是这个私人俱乐部的成员(敏感信息)。这就是成员推理。 -机器学习/深度学习的成员推理攻击(Membership Inference),指的是攻击者拥有模型的部分访问权限(黑盒、灰盒或白盒),能够获取到模型的输出、结构或参数等部分或全部信息,并基于这些信息推断某个样本是否属于模型的训练集。 +机器学习/深度学习的成员推理(MembershipInference),指的是攻击者拥有模型的部分访问权限(黑盒、灰盒或白盒),能够获取到模型的输出、结构或参数等部分或全部信息,并基于这些信息推断某个样本是否属于模型的训练集。利用成员推理,我们可以评估机器学习/深度学习模型的隐私数据安全。如果在成员推理下能正确识别出60%+的样本,那么我们认为该模型存在隐私数据泄露风险。 -这里以VGG16模型,CIFAR-100数据集为例,说明如何使用MembershipInference。本教程使用预训练的模型参数进行演示,这里仅给出模型结构、参数设置和数据集预处理方式。 +这里以VGG16模型,CIFAR-100数据集为例,说明如何使用MembershipInference进行模型隐私安全评估。本教程使用预训练的模型参数进行演示,这里仅给出模型结构、参数设置和数据集预处理方式。 >本例面向Ascend 910处理器,您可以在这里下载完整的样例代码: > -> +> ## 实现阶段 @@ -52,7 +50,7 @@ from mindspore.common.initializer import initializer import mindspore.dataset as de import mindspore.dataset.transforms.c_transforms as C import mindspore.dataset.vision.c_transforms as vision -from mindarmour.diff_privacy.evaluation.membership_inference import MembershipInference +from mindarmour import MembershipInference from mindarmour.utils import LogUtil LOGGER = LogUtil.get_instance() @@ -179,7 +177,7 @@ def vgg16(num_classes=1000, args=None, phase="train"): return net ``` -### 运用MembershipInference +### 运用MembershipInference进行隐私安全评估 1. 构建VGG16模型并加载参数文件。 这里直接加载预训练完成的VGG16参数配置,您也可以使用如上的网络自行训练。 @@ -197,37 +195,34 @@ def vgg16(num_classes=1000, args=None, phase="train"): args.padding = 0 args.pad_mode = "same" args.weight_decay = 5e-4 - args.loss_scale = 1.0 - - data_path = "./cifar-100-binary" # Replace your data path here. - pre_trained = "./VGG16-100_781.ckpt" # Replace your pre trained checkpoint file here. + args.loss_scale = 1.0 # Load the pretrained model. net = vgg16(num_classes=100, args=args) - loss = nn.SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True) + loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True) opt = nn.Momentum(params=net.trainable_params(), learning_rate=0.1, momentum=0.9, weight_decay=args.weight_decay, loss_scale=args.loss_scale) load_param_into_net(net, load_checkpoint(args.pre_trained)) model = Model(network=net, loss_fn=loss, optimizer=opt) ``` -2. 加载CIFAR-100数据集,按8:2分割为成员推理攻击模型的训练集和测试集。 +2. 加载CIFAR-100数据集,按8:2分割为成员推理模型的训练集和测试集。 ```python # Load and split dataset. train_dataset = vgg_create_dataset100(data_home=args.data_path, image_size=(224, 224), - batch_size=64, num_samples=10000, shuffle=False) + batch_size=64, num_samples=5000, shuffle=False) test_dataset = vgg_create_dataset100(data_home=args.data_path, image_size=(224, 224), - batch_size=64, num_samples=10000, shuffle=False, training=False) + batch_size=64, num_samples=5000, shuffle=False, training=False) train_train, eval_train = train_dataset.split([0.8, 0.2]) train_test, eval_test = test_dataset.split([0.8, 0.2]) msg = "Data loading completed." LOGGER.info(TAG, msg) ``` -3. 配置攻击参数和评估参数 +3. 配置推理参数和评估参数 - 设置用于成员推理评估的方法和参数。目前支持的推理方法有:KNN、LR、MLPClassifier和RandomForest Classifier。 + 设置用于成员推理的方法和参数。目前支持的推理方法有:KNN、LR、MLPClassifier和RandomForestClassifier。推理参数数据类型使用list,各个方法使用key为"method"和"params"的字典表示。 ```python config = [ @@ -264,35 +259,41 @@ def vgg16(num_classes=1000, args=None, phase="train"): ] ``` - 设置评价指标,目前支持3种评价指标。包括: - * 准确率:accuracy。 - * 精确率:precision。 - * 召回率:recall。 - + 我们约定标签为数据集的是正类,标签为测试集的是负类。设置评价指标,目前支持3种评价指标。包括: + * 准确率:accuracy,正确推理的数量占全体样本中的比例。 + * 精确率:precision,正确推理的正类样本占所有推理为正类中的比例。 + * 召回率:recall,正确推理的正类样本占全体正类样本的比例。 + 在样本数量足够大时,如果上述指标均大于0.6,我们认为目标模型就存在隐私泄露的风险。 + ```python - metrics = ["precision", "accuracy", "recall"] + metrics = ["precision", "accuracy", "recall"] ``` - -4. 训练成员推理攻击模型,并给出评估结果。 + +4. 训练成员推理模型,并给出评估结果。 ```python - attacker = MembershipInference(model) # Get attack model. + inference = MembershipInference(model) # Get inference model. - attacker.train(train_train, train_test, config) # Train attack model. + inference.train(train_train, train_test, config) # Train inference model. msg = "Membership inference model training completed." LOGGER.info(TAG, msg) - result = attacker.eval(eval_train, eval_test, metrics) # Eval metrics. + result = inference.eval(eval_train, eval_test, metrics) # Eval metrics. count = len(config) for i in range(count): print("Method: {}, {}".format(config[i]["method"], result[i])) ``` 5. 实验结果。 + 执行如下指令,开始成员推理训练和评估: + + ``` + python membership_inference_example.py --data_path ./cifar-100-binary/ --pre_trained ./VGG16-100_781.ckpt + ``` 成员推理的指标如下所示,各数值均保留至小数点后四位。 - 以第一行结果为例:在使用lr(逻辑回归分类)进行成员推理时,推理的准确率(accuracy)为0.7132,推理精确率(precision)为0.6596,正类样本召回率为0.8810。在二分类任务下,指标表明我们的成员推理是有效的。 + 以第一行结果为例:在使用lr(逻辑回归分类)进行成员推理时,推理的准确率(accuracy)为0.7132,推理精确率(precision)为0.6596,正类样本召回率为0.8810,说明lr有71.32%的概率能正确分辨一个数据样本是否属于目标模型的训练数据集。在二分类任务下,指标表明成员推理是有效的,即该模型存在隐私泄露的风险。 ``` Method: lr, {'recall': 0.8810,'precision': 0.6596,'accuracy': 0.7132} -- Gitee From 81a33c267af9b81c6ef43568ff76bbe3ba3e4b38 Mon Sep 17 00:00:00 2001 From: pkuliuliu Date: Thu, 17 Sep 2020 11:41:44 +0800 Subject: [PATCH 053/100] update diff_privacy tutorial --- ...user_privacy_with_differential_privacy.md} | 22 +++++++++---------- tutorials/training/source_en/index.rst | 2 +- ...user_privacy_with_differential_privacy.md} | 22 +++++++++---------- tutorials/training/source_zh_cn/index.rst | 4 ++-- 4 files changed, 23 insertions(+), 27 deletions(-) rename tutorials/training/source_en/advanced_use/{improve_model_security_differential_privacy.md => protect_user_privacy_with_differential_privacy.md} (95%) rename tutorials/training/source_zh_cn/advanced_use/{improve_model_security_differential_privacy.md => protect_user_privacy_with_differential_privacy.md} (95%) diff --git a/tutorials/training/source_en/advanced_use/improve_model_security_differential_privacy.md b/tutorials/training/source_en/advanced_use/protect_user_privacy_with_differential_privacy.md similarity index 95% rename from tutorials/training/source_en/advanced_use/improve_model_security_differential_privacy.md rename to tutorials/training/source_en/advanced_use/protect_user_privacy_with_differential_privacy.md index ffe88955c8..c94dea741f 100644 --- a/tutorials/training/source_en/advanced_use/improve_model_security_differential_privacy.md +++ b/tutorials/training/source_en/advanced_use/protect_user_privacy_with_differential_privacy.md @@ -1,10 +1,10 @@ -# Improve Model Security with Differential Privacy Mechanism +# Protect User Privacy with Differential Privacy Mechanism `Linux` `Ascend` `Model Development` `Model Optimization` `Enterprise` `Expert` -- [Improve Model Security with Differential Privacy Mechanism](#improve-model-security-with-differential-privacy-mechanism) +- [Protect User Privacy with Differential Privacy Mechanism](#protect-user-privacy-with-differential-privacy-mechanism) - [Overview](#overview) - [Implementation](#implementation) - [Importing Library Files](#importing-library-files) @@ -16,7 +16,7 @@ - + ## Overview @@ -45,7 +45,7 @@ MindArmour differential privacy module Differential-Privacy implements the diffe The LeNet model and MNIST dataset are used as an example to describe how to use the differential privacy optimizer to train a neural network model on MindSpore. -> This example is for the Ascend 910 AI processor. You can download the complete sample code from . +> This example is for the Ascend 910 AI processor. You can download the complete sample code from . ## Implementation @@ -70,13 +70,11 @@ import mindspore.dataset.transforms.c_transforms as C from mindspore.dataset.vision import Inter import mindspore.common.dtype as mstype -from mindarmour.diff_privacy import DPModel -from mindarmour.diff_privacy import PrivacyMonitorFactory -from mindarmour.diff_privacy import NoiseMechanismsFactory -from mindarmour.diff_privacy import ClipMechanismsFactory +from mindarmour.privacy.diff_privacy import DPModel +from mindarmour.privacy.diff_privacy import PrivacyMonitorFactory +from mindarmour.privacy.diff_privacy import NoiseMechanismsFactory +from mindarmour.privacy.diff_privacy import ClipMechanismsFactory from mindarmour.utils.logger import LogUtil -from lenet5_net import LeNet5 -from lenet5_config import mnist_cfg as cfg LOGGER = LogUtil.get_instance() LOGGER.set_level('INFO') @@ -85,7 +83,7 @@ TAG = 'Lenet5_train' ### Configuring Parameters -1. Set the running environment, dataset path, model training parameters, checkpoint storage parameters, and differential privacy parameters. Replace 'data_path' with you data path. For more configurations, see . +1. Set the running environment, dataset path, model training parameters, checkpoint storage parameters, and differential privacy parameters. Replace 'data_path' with you data path. For more configurations, see . ```python cfg = edict({ @@ -99,7 +97,7 @@ TAG = 'Lenet5_train' 'save_checkpoint_steps': 234, # the interval steps for saving checkpoint file of the model 'keep_checkpoint_max': 10, # the maximum number of checkpoint files would be saved 'device_target': 'Ascend', # device used - 'data_path': './MNIST_unzip', # the path of training and testing data set + 'data_path': '../../common/dataset/MNIST', # the path of training and testing data set 'dataset_sink_mode': False, # whether deliver all training data to device one time 'micro_batches': 32, # the number of small batches split from an original batch 'norm_bound': 1.0, # the clip bound of the gradients of model's training parameters diff --git a/tutorials/training/source_en/index.rst b/tutorials/training/source_en/index.rst index fc6aa64a29..b6dde45805 100644 --- a/tutorials/training/source_en/index.rst +++ b/tutorials/training/source_en/index.rst @@ -74,7 +74,7 @@ Train with MindSpore :caption: Model Security and Privacy advanced_use/improve_model_security_nad - advanced_use/improve_model_security_differential_privacy + advanced_use/protect_user_privacy_with_differential_privacy .. toctree:: :glob: diff --git a/tutorials/training/source_zh_cn/advanced_use/improve_model_security_differential_privacy.md b/tutorials/training/source_zh_cn/advanced_use/protect_user_privacy_with_differential_privacy.md similarity index 95% rename from tutorials/training/source_zh_cn/advanced_use/improve_model_security_differential_privacy.md rename to tutorials/training/source_zh_cn/advanced_use/protect_user_privacy_with_differential_privacy.md index 209a15f740..a5f7bad2e7 100644 --- a/tutorials/training/source_zh_cn/advanced_use/improve_model_security_differential_privacy.md +++ b/tutorials/training/source_zh_cn/advanced_use/protect_user_privacy_with_differential_privacy.md @@ -1,10 +1,10 @@ -# 应用差分隐私优化器提升模型安全性 +# 应用差分隐私机制保护用户隐私 `Linux` `Ascend` `模型开发` `模型调优` `企业` `高级` -- [应用差分隐私优化器](#应用差分隐私优化器) +- [应用差分隐私机制保护用户隐私](#应用差分隐私机制保护用户隐私) - [概述](#概述) - [实现阶段](#实现阶段) - [导入需要的库文件](#导入需要的库文件) @@ -16,7 +16,7 @@ - + ## 概述 @@ -45,7 +45,7 @@ MindArmour的差分隐私模块Differential-Privacy,实现了差分隐私优 这里以LeNet模型,MNIST 数据集为例,说明如何在MindSpore上使用差分隐私优化器训练神经网络模型。 -> 本例面向Ascend 910 AI处理器,你可以在这里下载完整的样例代码: +> 本例面向Ascend 910 AI处理器,你可以在这里下载完整的样例代码: ## 实现阶段 @@ -70,13 +70,11 @@ import mindspore.dataset.transforms.c_transforms as C from mindspore.dataset.vision import Inter import mindspore.common.dtype as mstype -from mindarmour.diff_privacy import DPModel -from mindarmour.diff_privacy import NoiseMechanismsFactory -from mindarmour.diff_privacy import ClipMechanismsFactory -from mindarmour.diff_privacy import PrivacyMonitorFactory +from mindarmour.privacy.diff_privacy import DPModel +from mindarmour.privacy.diff_privacy import NoiseMechanismsFactory +from mindarmour.privacy.diff_privacy import ClipMechanismsFactory +from mindarmour.privacy.diff_privacy import PrivacyMonitorFactory from mindarmour.utils.logger import LogUtil -from lenet5_net import LeNet5 -from lenet5_config import mnist_cfg as cfg LOGGER = LogUtil.get_instance() LOGGER.set_level('INFO') @@ -85,7 +83,7 @@ TAG = 'Lenet5_train' ### 参数配置 -1. 设置运行环境、数据集路径、模型训练参数、checkpoint存储参数、差分隐私参数,`data_path`数据路径替换成你的数据集所在路径。更多配置可以参考。 +1. 设置运行环境、数据集路径、模型训练参数、checkpoint存储参数、差分隐私参数,`data_path`数据路径替换成你的数据集所在路径。更多配置可以参考。 ```python cfg = edict({ @@ -99,7 +97,7 @@ TAG = 'Lenet5_train' 'save_checkpoint_steps': 234, # the interval steps for saving checkpoint file of the model 'keep_checkpoint_max': 10, # the maximum number of checkpoint files would be saved 'device_target': 'Ascend', # device used - 'data_path': './MNIST_unzip', # the path of training and testing data set + 'data_path': '../../common/dataset/MNIST', # the path of training and testing data set 'dataset_sink_mode': False, # whether deliver all training data to device one time 'micro_batches': 32, # the number of small batches split from an original batch 'norm_bound': 1.0, # the clip bound of the gradients of model's training parameters diff --git a/tutorials/training/source_zh_cn/index.rst b/tutorials/training/source_zh_cn/index.rst index 5878b4a0f9..06b31a230a 100644 --- a/tutorials/training/source_zh_cn/index.rst +++ b/tutorials/training/source_zh_cn/index.rst @@ -76,7 +76,7 @@ :caption: 模型安全和隐私 advanced_use/improve_model_security_nad - advanced_use/improve_model_security_differential_privacy + advanced_use/protect_user_privacy_with_differential_privacy advanced_use/test_model_security_fuzzing advanced_use/test_model_security_membership_inference @@ -87,4 +87,4 @@ advanced_use/cv advanced_use/nlp - advanced_use/use_on_the_cloud \ No newline at end of file + advanced_use/use_on_the_cloud -- Gitee From 37206a1fe8f2ec4e51bd31c5aa2e630bf24cdbf4 Mon Sep 17 00:00:00 2001 From: JunYuLiu Date: Thu, 17 Sep 2020 11:16:28 +0800 Subject: [PATCH 054/100] Modify the programming guide for r1.0 --- .../source_zh_cn/advanced_use.rst | 9 + .../source_zh_cn/api_structure.md | 14 +- .../source_zh_cn/augmentation.md | 164 +- .../source_zh_cn/auto_augmentation.md | 159 +- ...o_parallel_context.md => auto_parallel.md} | 43 +- .../source_zh_cn/callback.md | 19 +- docs/programming_guide/source_zh_cn/cell.md | 268 ++-- .../source_zh_cn/compute_component.rst | 10 + .../programming_guide/source_zh_cn/context.md | 135 ++ .../source_zh_cn/data_pipeline.rst | 13 + .../source_zh_cn/data_type.rst | 8 + .../source_zh_cn/dataset_conversion.md | 665 +++----- .../source_zh_cn/dataset_loading.md | 259 ++- docs/programming_guide/source_zh_cn/dtype.md | 64 + .../source_zh_cn/execution_management.rst | 9 + .../source_zh_cn/images/batch.png | Bin 37732 -> 12224 bytes .../source_zh_cn/images/concat.png | Bin 24282 -> 13809 bytes .../source_zh_cn/images/ctrans_invert.png | Bin 146960 -> 128890 bytes .../source_zh_cn/images/ctrans_resize.png | Bin 43654 -> 19400 bytes .../source_zh_cn/images/map.png | Bin 21621 -> 14962 bytes .../source_zh_cn/images/pytrans_compose.png | Bin 64995 -> 42922 bytes .../source_zh_cn/images/randomcrop.png | Bin 51488 -> 92040 bytes .../images/randomhorizontalflip.png | Bin 73862 -> 130799 bytes .../source_zh_cn/images/repeat.png | Bin 38083 -> 11920 bytes .../source_zh_cn/images/shuffle.png | Bin 37331 -> 12301 bytes .../source_zh_cn/images/tranform_bad.png | Bin 27679 -> 10375 bytes .../source_zh_cn/images/tranform_good_1.png | Bin 24757 -> 9345 bytes .../source_zh_cn/images/tranform_good_2.png | Bin 24291 -> 9300 bytes .../source_zh_cn/images/tranform_good_3.png | Bin 23743 -> 9246 bytes .../source_zh_cn/images/tranform_pipeline.png | Bin 62195 -> 14272 bytes .../source_zh_cn/images/zip.png | Bin 25299 -> 11011 bytes docs/programming_guide/source_zh_cn/index.rst | 21 + .../{component.md => network_component.md} | 35 +- docs/programming_guide/source_zh_cn/nn.md | 2 +- .../source_zh_cn/operator.md | 341 ++-- .../source_zh_cn/operator_list.rst | 8 + .../source_zh_cn/operator_list_lite.md | 2 +- .../{operator_list.md => operator_list_ms.md} | 4 +- docs/programming_guide/source_zh_cn/ops.md | 2 +- docs/programming_guide/source_zh_cn/optim.md | 126 +- .../source_zh_cn/parameter.md | 28 +- .../source_zh_cn/pipeline.md | 201 +-- .../source_zh_cn/probability.md | 1419 +++++++++++++++++ docs/programming_guide/source_zh_cn/run.md | 372 +++++ .../programming_guide/source_zh_cn/sampler.md | 171 +- .../source_zh_cn/security_and_privacy.md | 40 +- docs/programming_guide/source_zh_cn/tensor.md | 22 +- .../source_zh_cn/tokenizer.md | 232 +-- docs/programming_guide/source_zh_cn/train.md | 442 +++++ docs/programming_guide/source_zh_cn/type.md | 54 - .../source_zh_cn/user_defined.rst | 7 + 51 files changed, 3691 insertions(+), 1677 deletions(-) create mode 100644 docs/programming_guide/source_zh_cn/advanced_use.rst rename docs/programming_guide/source_zh_cn/{auto_parallel_context.md => auto_parallel.md} (90%) create mode 100644 docs/programming_guide/source_zh_cn/compute_component.rst create mode 100644 docs/programming_guide/source_zh_cn/context.md create mode 100644 docs/programming_guide/source_zh_cn/data_pipeline.rst create mode 100644 docs/programming_guide/source_zh_cn/data_type.rst create mode 100644 docs/programming_guide/source_zh_cn/dtype.md create mode 100644 docs/programming_guide/source_zh_cn/execution_management.rst create mode 100644 docs/programming_guide/source_zh_cn/index.rst rename docs/programming_guide/source_zh_cn/{component.md => network_component.md} (76%) create mode 100644 docs/programming_guide/source_zh_cn/operator_list.rst rename docs/programming_guide/source_zh_cn/{operator_list.md => operator_list_ms.md} (99%) create mode 100644 docs/programming_guide/source_zh_cn/probability.md create mode 100644 docs/programming_guide/source_zh_cn/run.md create mode 100644 docs/programming_guide/source_zh_cn/train.md delete mode 100644 docs/programming_guide/source_zh_cn/type.md create mode 100644 docs/programming_guide/source_zh_cn/user_defined.rst diff --git a/docs/programming_guide/source_zh_cn/advanced_use.rst b/docs/programming_guide/source_zh_cn/advanced_use.rst new file mode 100644 index 0000000000..33edc062bc --- /dev/null +++ b/docs/programming_guide/source_zh_cn/advanced_use.rst @@ -0,0 +1,9 @@ +进阶用法 +=========== + +.. toctree:: + :maxdepth: 1 + + train + user_defined + security_and_privacy \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/api_structure.md b/docs/programming_guide/source_zh_cn/api_structure.md index f53f7c7759..31fc7aeb0a 100644 --- a/docs/programming_guide/source_zh_cn/api_structure.md +++ b/docs/programming_guide/source_zh_cn/api_structure.md @@ -8,15 +8,17 @@ - + ## 设计理念 MindSpore源于全产业的最佳实践,向数据科学家和算法工程师提供了统一的模型训练、推理和导出等接口,支持端、边、云等不同场景下的灵活部署,推动深度学习和科学计算等领域繁荣发展。 -MindSpore提供了动态图和静态图统一的编码方式,用户无需开发多套代码,仅变更一行代码便可切换动态图/静态图模式,从而拥有更轻松的开发调试及性能体验。 +神经网络模型通常基于梯度下降算法进行训练,但手动求导过程复杂且梯度难以计算。MindSpore采用函数式可微分编程架构,用户可聚焦于模型算法的数学原生表达,无需进行手动求导。MindSpore的基于源码转换(Source Code Transformation, SCT)的自动微分(Automatic Differentiation)机制能够将Python代码转换为函数中间表达(Intermediate Representation, IR),函数中间表达构造出能够在不同设备解析和执行的计算图,并且在执行该计算图前,应用了多种软硬件协同优化技术,端、边、云等不同场景下的性能和效率得到针对性的提升。此外,MindSpore提供了Python编程范式,用户使用Python原生控制逻辑即可构建复杂的神经网络模型,AI编程变得简单。 -此外,由于MindSpore统一了单机和分布式训练的编码方式,开发者无需编写复杂的分布式策略,在单机代码中添加少量代码即可实现分布式训练,大大降低了AI开发门槛。 +目前主流的深度学习框架的执行模式有两种,分别为静态图模式和动态图模式。静态图模式拥有较高的训练性能,但难以调试。动态图模式相较于静态图模式虽然易于调试,但难以高效执行。MindSpore提供了动态图和静态图统一的编码方式。大大增加了静态图和动态图的可兼容性,用户无需开发多套代码,仅变更一行代码便可切换动态图/静态图模式,例如设置`context.set_context(mode=context.PYNATIVE_MODE)`即可从静态图模式切换成动态图模式,从而拥有更轻松的开发调试及性能体验。 + +随着神经网络模型和数据集的规模不断增加,分布式并行训练成为了神经网络训练的常见做法,但分布式并行训练的策略选择和编写十分复杂,这制约着深度学习的发展。MindSpore统一了单机和分布式训练的编码方式,开发者无需编写复杂的分布式策略,在单机代码中添加少量代码即可实现分布式训练,例如设置`context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL)`便可自动建立代价模型,为用户选择一种较优的并行模式,大大降低了AI开发门槛,提高了神经网络训练效率。 ## 层次结构 @@ -26,12 +28,12 @@ MindSpore向用户提供了3个不同层次的API,支撑用户进行网络构 - Low-Level Python API - 第一层为低阶API,主要包括张量定义、基础算子、自动微分等模块,用户可使用低阶API轻松实现张量操作和求导计算。 + 第一层为低阶API,主要包括张量定义、基础算子、自动微分等模块,用户可使用低阶API轻松实现张量定义和求导计算,例如用户可通过`Tensor`接口自定义张量,使用`grad_all`算子计算函数在指定处的导数。 - Medium-Level Python API - 第二层为中阶API,其封装了低价API,提供网络层、优化器、损失函数等模块,用户可通过中阶API灵活构建神经网络和控制执行流程,快速实现模型算法逻辑。 + 第二层为中阶API,其封装了低价API,提供网络层、优化器、损失函数等模块,用户可通过中阶API灵活构建神经网络和控制执行流程,快速实现模型算法逻辑,例如用户可调用`Cell`接口构建神经网络模型和计算逻辑,通过使用`loss`模块和`Optimizer`接口为神经网络模型添加损失函数和优化方式。 - High-Level Python API - 第三层为高阶API,其在中阶API的基础上又提供了训练推理的管理、Callback、混合精度训练等高级接口,方便用户控制整网的执行流程和实现神经网络的训练及推理。 + 第三层为高阶API,其在中阶API的基础上又提供了训练推理的管理、Callback、混合精度训练等高级接口,方便用户控制整网的执行流程和实现神经网络的训练及推理,例如用户使用`Model`接口,指定要训练的神经网络模型和相关的训练设置,即可对神经网络模型进行训练。 diff --git a/docs/programming_guide/source_zh_cn/augmentation.md b/docs/programming_guide/source_zh_cn/augmentation.md index 6d20f22c24..7771869303 100644 --- a/docs/programming_guide/source_zh_cn/augmentation.md +++ b/docs/programming_guide/source_zh_cn/augmentation.md @@ -15,21 +15,20 @@ - + ## 概述 在计算机视觉任务中,数据量过小或是样本场景单一等问题都会影响模型的训练效果,用户可以通过数据增强操作对图像进行预处理,从而提升模型的泛化性。 -MindSpore提供了c_transforms模块和py_transforms模块供用户进行数据增强操作,用户也可以自定义函数或者算子进行数据增强。 - -MindSpore目前支持的常用数据增强算子如下表所示,更多数据增强算子参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html)。 +MindSpore提供了`c_transforms`模块和`py_transforms`模块供用户进行数据增强操作,用户也可以自定义函数或者算子进行数据增强。 | 模块 | 实现 | 说明 | | ---- | ---- | ---- | | c_transforms | 基于C++的OpenCV实现 | 具有较高的性能。 | -| py_transforms | 基于Python的PIL实现 | 该模块提供了多种图像增强功能,并提供了PIL Image和numpy数组之间的传输方法。| +| py_transforms | 基于Python的PIL实现 | 该模块提供了多种图像增强功能,并提供了PIL Image和NumPy数组之间的传输方法。| +MindSpore目前支持的常用数据增强算子如下表所示,更多数据增强算子参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html)。 | 模块 | 算子 | 说明 | | ---- | ---- | ---- | @@ -44,42 +43,34 @@ MindSpore目前支持的常用数据增强算子如下表所示,更多数据 ## c_transforms -下面将简要介绍几种常用的c_transforms模块数据增强算子的使用方法,更多的c_transforms模块数据增强算子参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html#module-mindspore.dataset.vision.c_transforms)。 +下面将简要介绍几种常用的`c_transforms`模块数据增强算子的使用方法。 ### RandomCrop 对输入图像进行在随机位置的裁剪。 **参数说明:** -- *size: 裁剪图像的尺寸。* -- *padding: 填充的像素数量。* -- *pad_if_needed: 原图小于裁剪尺寸时,是否需要填充。* -- *fill_value: 在常量填充模式时使用的填充值。* -- *padding_mode: 填充模式。* +- `size`:裁剪图像的尺寸。 +- `padding`:填充的像素数量。 +- `pad_if_needed`:原图小于裁剪尺寸时,是否需要填充。 +- `fill_value`:在常量填充模式时使用的填充值。 +- `padding_mode`:填充模式。 -```python -# 对输入图像进行在随机位置的裁剪 +下面的样例首先使用顺序采样器加载CIFAR-10数据集,然后对已加载的图片进行长宽均为10的随机裁剪,最后输出裁剪前后的图片形状及对应标签,并对图片进行了展示。 +```python import matplotlib.pyplot as plt import mindspore.dataset as ds import mindspore.dataset.vision.c_transforms as c_trans -# 下载Cifar10数据集,将其解压到Cifar10Data目录 DATA_DIR = "../data/dataset/testCifar10Data2" -# 指定一个顺序采样器SequentialSampler,按照读取顺序获取3个样本数据 sampler = ds.SequentialSampler(num_samples=3) - -# 使用Cifar10Dataset读取数据集,指定sampler为上述采样器 dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 创建一个随机裁剪算子,裁剪后的长宽分为10个像素 random_crop = c_trans.RandomCrop([10, 10]) - -# 使用map算子将其作用到数据管道的数据集中 dataset2 = dataset1.map(operations=random_crop, input_columns=["image"]) -# 启动数据管道,输出3个样本数据 image_list1, label_list1 = [], [] image_list2, label_list2 = [], [] for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_iterator()): @@ -89,9 +80,8 @@ for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_it image_list2.append(data2['image']) label_list2.append(data2['label']) print("Cropped image Shape:", data2['image'].shape, ", Cropped label:", data2['label']) - print("") + print("------") -# 将原图与裁剪后的图可视化 num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): @@ -105,17 +95,22 @@ for i in range(num_samples): plt.show() ``` +输出结果如下: + ``` Source image Shape : (32, 32, 3) , Source label : 6 Cropped image Shape: (10, 10, 3) , Cropped label: 6 - +------ Source image Shape : (32, 32, 3) , Source label : 9 Cropped image Shape: (10, 10, 3) , Cropped label: 9 - +------ Source image Shape : (32, 32, 3) , Source label : 9 Cropped image Shape: (10, 10, 3) , Cropped label: 9 +------ ``` +图片展示如下: + ![randomcrop](./images/randomcrop.png) ### RandomHorizontalFlip @@ -123,34 +118,25 @@ Cropped image Shape: (10, 10, 3) , Cropped label: 9 对输入图像进行随机水平翻转。 **参数说明:** -- *prob: 单张图片发生翻转的概率。* +- `prob`: 单张图片发生翻转的概率。 -```python -# 对输入图像进行随机水平翻转 +下面的样例首先使用随机采样器加载CIFAR-10数据集,然后对已加载的图片进行概率为0.8的随机水平翻转,最后输出翻转前后的图片形状及对应标签,并对图片进行了展示。 +```python import matplotlib.pyplot as plt import mindspore.dataset as ds import mindspore.dataset.vision.c_transforms as c_trans -# 设置全局随机种子 ds.config.set_seed(6) -# 下载Cifar10数据集,将其解压到Cifar10Data目录 DATA_DIR = "../data/dataset/testCifar10Data2" -# 指定一个随机采样器RandomSampler,按照读取顺序获取4个样本数据 sampler = ds.RandomSampler(num_samples=4) - -# 使用Cifar10Dataset读取数据集,指定sampler为上述采样器 dataset1 = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 创建一个随机翻转算子,设置翻转概率为0.8 random_horizontal_flip = c_trans.RandomHorizontalFlip(prob=0.8) - -# 使用map算子将其作用到数据管道的数据集中 dataset2 = dataset1.map(operations=random_horizontal_flip, input_columns=["image"]) -# 启动数据管道,输出4个样本数据 image_list1, label_list1 = [], [] image_list2, label_list2 = [], [] for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_iterator()): @@ -160,9 +146,8 @@ for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_it image_list2.append(data2['image']) label_list2.append(data2['label']) print("Flipped image Shape:", data2['image'].shape, ", Flipped label:", data2['label']) - print("") + print("------") -# 将原图与裁剪后的图可视化 num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): @@ -176,20 +161,25 @@ for i in range(num_samples): plt.show() ``` +输出结果如下: + ``` Source image Shape : (32, 32, 3) , Source label : 3 Flipped image Shape: (32, 32, 3) , Flipped label: 3 - +------ Source image Shape : (32, 32, 3) , Source label : 6 Flipped image Shape: (32, 32, 3) , Flipped label: 6 - +------ Source image Shape : (32, 32, 3) , Source label : 6 Flipped image Shape: (32, 32, 3) , Flipped label: 6 - +------ Source image Shape : (32, 32, 3) , Source label : 9 Flipped image Shape: (32, 32, 3) , Flipped label: 9 +------ ``` +图片展示如下: + ![randomhorizontalflip](./images/randomhorizontalflip.png) ### Resize @@ -197,29 +187,23 @@ Flipped image Shape: (32, 32, 3) , Flipped label: 9 对输入图像进行缩放。 **参数说明:** -- *self: 缩放的目标大小。* -- *interpolation: 缩放时采用的插值方式。* +- `self`:缩放的目标大小。 +- `interpolation`:缩放时采用的插值方式。 -```python -# 对输入图像进行指定大小缩放 +下面的样例首先加载MNIST数据集,然后将已加载的图片缩放至(101, 101)大小,最后输出缩放前后的图片形状及对应标签,并对图片进行了展示。 +```python import matplotlib.pyplot as plt import mindspore.dataset as ds import mindspore.dataset.vision.c_transforms as c_trans -# 下载MNIST数据集,将其解压到MnistData目录 DATA_DIR = "../data/dataset/testMnistData2" -# 使用MnistDataset读取数据集 dataset1 = ds.MnistDataset(DATA_DIR, num_samples=4, shuffle=False) -# 创建一个缩放算子,将MNIST的图片从(28, 28)缩放到(101, 101) resize = c_trans.Resize(size=[101, 101]) - -# 使用map算子将其作用到数据管道的数据集中 dataset2 = dataset1.map(operations=resize, input_columns=["image"]) -# 启动数据管道 image_list1, label_list1 = [], [] image_list2, label_list2 = [], [] for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_iterator()): @@ -229,9 +213,8 @@ for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_it image_list2.append(data2['image']) label_list2.append(data2['label']) print("Flipped image Shape:", data2['image'].shape, ", Flipped label:", data2['label']) - print("") + print("------") -# 将原图与裁剪后的图可视化 num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): @@ -245,52 +228,48 @@ for i in range(num_samples): plt.show() ``` +输出结果如下: + ``` Source image Shape : (28, 28, 1) , Source label : 5 Flipped image Shape: (101, 101, 1) , Flipped label: 5 - +------ Source image Shape : (28, 28, 1) , Source label : 0 Flipped image Shape: (101, 101, 1) , Flipped label: 0 - +------ Source image Shape : (28, 28, 1) , Source label : 4 Flipped image Shape: (101, 101, 1) , Flipped label: 4 - +------ Source image Shape : (28, 28, 1) , Source label : 1 Flipped image Shape: (101, 101, 1) , Flipped label: 1 +------ ``` +图片展示如下: + ![ctrans_resize](./images/ctrans_resize.png) ### Invert 对输入图像进行反相处理。 -```python -# 对输入图像进行反相处理 +下面的样例首先加载CIFAR-10数据集,然后同时定义缩放和反相操作并作用于已加载的图片,最后输出缩放与反相前后的图片形状及对应标签,并对图片进行了展示。 +```python import matplotlib.pyplot as plt import mindspore.dataset as ds import mindspore.dataset.vision.c_transforms as c_trans -# 设置全局随机种子 ds.config.set_seed(8) -# 下载Cifar10数据集,将其解压到Cifar10Data目录 DATA_DIR = "../data/dataset/testCifar10Data2" -# 使用Cifar10Dataset读取数据集 dataset1 = ds.Cifar10Dataset(DATA_DIR, num_samples=4, shuffle=True) -# 创建一个缩放算子,将图片缩放到(101, 101) resize = c_trans.Resize(size=[101, 101]) - -# 创建一个反相算子 invert = c_trans.Invert() - -# 使用map算子将其作用到数据管道的数据集中(两个算子按顺序起作用) dataset2 = dataset1.map(operations=[resize, invert], input_columns=["image"]) -# 启动数据管道 image_list1, label_list1 = [], [] image_list2, label_list2 = [], [] for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_iterator()): @@ -300,9 +279,8 @@ for data1, data2 in zip(dataset1.create_dict_iterator(), dataset2.create_dict_it image_list2.append(data2['image']) label_list2.append(data2['label']) print("Flipped image Shape:", data2['image'].shape, ", Flipped label:", data2['label']) - print("") + print("------") -# 将原图与裁剪后的图可视化 num_samples = len(image_list1) + len(image_list2) for i in range(num_samples): if i < len(image_list1): @@ -316,63 +294,63 @@ for i in range(num_samples): plt.show() ``` +输出结果如下: + ``` Source image Shape : (32, 32, 3) , Source label : 4 Flipped image Shape: (32, 32, 3) , Flipped label: 4 - +------ Source image Shape : (32, 32, 3) , Source label : 9 Flipped image Shape: (32, 32, 3) , Flipped label: 9 - +------ Source image Shape : (32, 32, 3) , Source label : 6 Flipped image Shape: (32, 32, 3) , Flipped label: 6 - +------ Source image Shape : (32, 32, 3) , Source label : 5 Flipped image Shape: (32, 32, 3) , Flipped label: 5 +------ ``` +图片展示如下: + ![ctrans_invert](./images/ctrans_invert.png) ## py_transforms -下面将简要介绍几种常用的py_transforms模块数据增强算子的使用方法,更多的py_transforms模块数据增强算子参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.vision.html#module-mindspore.dataset.vision.py_transforms)。 +下面将简要介绍几种常用的`py_transforms`模块数据增强算子的使用方法。 ### Compose -```python -# 对输入图像进行解码,缩放组合操作 +接收一个`transforms`列表,将列表中的数据增强操作依次作用于数据集图片。 + +下面的样例首先加载一个图片数据集,然后同时定义解码、缩放和数据类型转换操作,并作用于已加载的图片,最后输出处理后的图片形状及对应标签,并对图片进行了展示。 +```python import matplotlib.pyplot as plt import mindspore.dataset as ds import mindspore.dataset.vision.py_transforms as py_trans from mindspore.dataset.transforms.py_transforms import Compose -# 设置全局随机种子 + ds.config.set_seed(8) -# 图像数据集目录 DATA_DIR = "../data/dataset/testPK/data" -# 使用ImageFolderDataset读取数据集,获取5个样本 dataset1 = ds.ImageFolderDataset(DATA_DIR, num_samples=5, shuffle=True) -# 创建一组数据增强算子的集合 transforms_list = [ - py_trans.Decode(), # 解码图像到PIL格式 - py_trans.Resize(size=(200,200)), # 缩放图像到[200, 200]大小 - py_trans.ToTensor() # 将PIL图像转换到Numpy + py_trans.Decode(), + py_trans.Resize(size=(200,200)), + py_trans.ToTensor() ] compose_trans = Compose(transforms_list) - -# 使用map算子将其作用到数据管道的数据集中 dataset2 = dataset1.map(operations=compose_trans, input_columns=["image"]) -# 启动数据管道,输出5个样本数据 image_list, label_list = [], [] for data in dataset2.create_dict_iterator(): image_list.append(data['image']) label_list.append(data['label']) print("Transformed image Shape:", data['image'].shape, ", Transformed label:", data['label']) -# 将原图与裁剪后的图可视化 num_samples = len(image_list) for i in range(num_samples): plt.subplot(1, len(image_list), i + 1) @@ -381,6 +359,8 @@ for i in range(num_samples): plt.show() ``` +输出结果如下: + ``` Transformed image Shape: (3, 200, 200) , Transformed label: 3 Transformed image Shape: (3, 200, 200) , Transformed label: 0 @@ -389,11 +369,13 @@ Transformed image Shape: (3, 200, 200) , Transformed label: 0 Transformed image Shape: (3, 200, 200) , Transformed label: 3 ``` +图片展示如下: + ![pytrans_compose](./images/pytrans_compose.png) ## 使用说明 -请勿混用c_transforms与py_transforms,因为c_transforms是在C++内维护buffer管理,py_transforms是在Python内维护buffer管理,两者混用会降低性能。 +请勿混用`c_transforms`与`py_transforms`,因为`c_transforms`是在C++内维护buffer管理,`py_transforms`是在Python内维护buffer管理,两者混用会降低性能。 ![tranform_pipeline](./images/tranform_pipeline.png) @@ -401,15 +383,15 @@ Transformed image Shape: (3, 200, 200) , Transformed label: 3 **推荐的使用方式:** -- 单独使用py_transform或c_transform +- 单独使用`py_transform`或`c_transform` ![tranform_c_py](./images/tranform_good_1.png) -- 先使用py_transform,再使用c_transform +- 先使用`py_transform`,再使用`c_transform` ![tranform_c_py](./images/tranform_good_2.png) -- 先使用c_transform,再使用py_transform +- 先使用`c_transform`,再使用`py_transform` ![tranform_c_py](./images/tranform_good_3.png) diff --git a/docs/programming_guide/source_zh_cn/auto_augmentation.md b/docs/programming_guide/source_zh_cn/auto_augmentation.md index ef71980b51..32a727946a 100644 --- a/docs/programming_guide/source_zh_cn/auto_augmentation.md +++ b/docs/programming_guide/source_zh_cn/auto_augmentation.md @@ -3,110 +3,129 @@ - [自动数据增强](#自动数据增强) - - [基于概率动态调整数据增强策略](#基于概率动态调整数据增强策略) - - [基于训练结果信息动态调整数据增强策略](#基于训练结果信息动态调整数据增强策略) + - [概述](#概述) + - [基于概率的自动数据增强](#基于概率的自动数据增强) + - [RandomApply](#RandomApply) + - [RandomChoice](#RandomChoice) + - [RandomSelectSubpolicy](#RandomSelectSubpolicy) + - [基于回调参数的自动数据增强](#基于回调参数的自动数据增强) - + -## 基于概率动态调整数据增强策略 +## 概述 -MindSpore提供一系列基于概率的数据增强的API,用户可以对各种图像操作进行随机选择、组合,使数据增强更灵活。 +MindSpore除了可以让用户自定义数据增强的使用,还提供了一种自动数据增强方式,可以基于特定策略自动对图像进行数据增强处理。 -- [`RandomApply(transforms, prob=0.5)`](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.transforms.html?highlight=randomapply#mindspore.dataset.transforms.c_transforms.RandomApply) -以一定的概率指定`transforms`操作,即可能执行,也可以能不执行;`transform`可以是一个,也可以是一系列。 +自动数据增强主要分为基于概率的自动数据增强和基于回调参数的自动数据增强。 - ```python +## 基于概率的自动数据增强 - rand_apply_list = RandomApply([c_vision.RandomCrop(), c_vision.RandomColorAdjust()]) - ds = ds.map(operations=rand_apply_list) +MindSpore提供了一系列基于概率的自动数据增强API,用户可以对各种数据增强操作进行随机选择与组合,使数据增强更加灵活。 - ``` +关于API的详细说明,可以参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.transforms.html)。 - 按50%的概率来顺序执行`RandomCrop`和`RandomColorAdjust`操作,否则都不执行。 +### RandomApply -- [`RandomChoice(transforms)`](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.transforms.html?highlight=randomchoice#mindspore.dataset.transforms.c_transforms.RandomChoice) -从`transfrom`操作中随机选择一个执行。 +API接收一个数据增强操作列表`transforms`,以一定的概率顺序执行列表中各数据增强操作,默认概率为0.5,否则都不执行。 - ```python +在下面的代码示例中,以0.5的概率来顺序执行`RandomCrop`和`RandomColorAdjust`操作,否则都不执行。 - rand_choice = RandomChoice([c_vision.CenterCrop(), c_vision.RandomCrop()]) - ds = ds.map(operations=rand_choice) +```python +import mindspore.dataset.vision.c_transforms as c_vision +from mindspore.dataset.transforms.c_transforms import RandomApply - ``` +rand_apply_list = RandomApply([c_vision.RandomCrop(512), c_vision.RandomColorAdjust()]) +``` - 分别以50%概率来执行`CenterCrop`和`RandomCrop`操作。 +### RandomChoice -- [`RandomSelectSubpolicy(policy)`](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.transforms.vision.html?highlight=randomselectsubpolicy#mindspore.dataset.transforms.vision.c_transforms.RandomSelectSubpolicy) -用户可以预置策略(Policy),每次随机选择一个子策略(SubPolicy)组合,同一子策略中由若干个顺序执行的图像增强操作组成,每个操作与两个参数关联:1) 执行操作的概率 2)执行操作的幅度; -对于一个batch中的每张图像,随机选择子策略来变换图像。 +API接收一个数据增强操作列表`transforms`,从中随机选择一个数据增强操作执行。 - ```python +在下面的代码示例中,等概率地在`CenterCrop`和`RandomCrop`中选择一个操作执行。 - policy = [ - [(c_vision.RandomRotation((45, 45)), 0.5), (c_vision.RandomVerticalFlip(), 1.0), (c_vision.RandomColorAdjust(), 0.8)], - [(c_vision.RandomRotation((90, 90)), 1), (c_vision.RandomColorAdjust(), 0.2)] - ] - ds = ds.map(operations=c_vision.RandomSelectSubpolicy(policy), input_columns=["image"]) +```python +import mindspore.dataset.vision.c_transforms as c_vision +from mindspore.dataset.transforms.c_transforms import RandomChoice - ``` +rand_choice = RandomChoice([c_vision.CenterCrop(512), c_vision.RandomCrop(512)]) +``` - 示例中包括2条子策略,其中子策略1中包含`RandomRotation`、`RandomVerticalFlip`、`RandomColorAdjust`3个操作,概率分别为0.5、1.0、0.8;子策略2中包含`RandomRotation`和`RandomColorAdjust`,概率分别为1.0、2.0。 +### RandomSelectSubpolicy -## 基于训练结果信息动态调整数据增强策略 +API接收一个预置策略列表,包含一系列子策略组合,每一子策略由若干个顺序执行的数据增强操作及其执行概率组成。 -Mindspore的`sync_wait`接口支持按batch或epoch粒度来调整数据增强策略,实现训练过程中动态调整数据增强策略。 -`sync_wait`必须和`sync_update`配合使用实现数据pipeline上的同步回调。 +对各图像先等概率随机选择一种子策略,再依照子策略中的概率顺序执行各个操作。 -- [`sync_wait(condition_name, num_batch=1, callback=None)`](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html?highlight=sync_wait#mindspore.dataset.ImageFolderDatasetV2.sync_wait) -- [`sync_update(condition_name, num_batch=None, data=None)`](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html?highlight=sync_update#mindspore.dataset.ImageFolderDatasetV2.sync_update) +在下面的代码示例中,预置了两条子策略,子策略1中包含`RandomRotation`、`RandomVerticalFlip`和`RandomColorAdjust`三个操作,概率分别为0.5、1.0和0.8;子策略2中包含`RandomRotation`和`RandomColorAdjust`两个操作,概率分别为1.0和0.2。 -`sync_wait`将阻塞整个数据处理pipeline直到`sync_update`触发用户预先定义的`callback`函数。 +```python +import mindspore.dataset.vision.c_transforms as c_vision +from mindspore.dataset.vision.c_transforms import RandomSelectSubpolicy -1. 用户预先定义class`Augment`,其中`preprocess`为`map`操作中的自定义数据增强函数,`update`为更新数据增强策略的回调函数。 +policy_list = [ + [(c_vision.RandomRotation((45, 45)), 0.5), (c_vision.RandomVerticalFlip(), 1.0), (c_vision.RandomColorAdjust(), 0.8)], + [(c_vision.RandomRotation((90, 90)), 1.0), (c_vision.RandomColorAdjust(), 0.2)] + ] +policy = RandomSelectSubpolicy(policy_list) +``` - ```python - import mindspore.dataset.vision.py_transforms as transforms - import mindspore.dataset as de - import numpy as np +## 基于回调参数的自动数据增强 - class Augment: - def __init__(self): - self.ep_num = 0 - self.step_num = 0 +MindSpore的`sync_wait`接口支持按batch或epoch粒度在训练过程中动态调整数据增强策略,用户可以设定阻塞条件触发特定的数据增强操作。 - def preprocess(self, input_): - return (np.array((input_ + self.step_num ** self.ep_num - 1), )) +`sync_wait`将阻塞整个数据处理pipeline直到`sync_update`触发用户预先定义的`callback`函数,两者需配合使用,对应说明如下: - def update(self, data): - self.ep_num = data['ep_num'] - self.step_num = data['step_num'] +- sync_wait(condition_name, num_batch=1, callback=None) - ``` + 该API为数据集添加一个阻塞条件`condition_name`,当`sync_update`调用时执行指定的`callback`函数。 -2. 数据处理pipeline先回调自定义的增强策略更新函数`auto_aug.update`,然后在`map`操作中按更新后的策略来执行`auto_aug.preprocess`中定义的数据增强。 +- sync_update(condition_name, num_batch=None, data=None) - ```python + 该API用于释放对应`condition_name`的阻塞,并对`data`触发指定的`callback`函数。 - arr = list(range(1, 4)) - ds = de.NumpySlicesDataset(arr, shuffle=False) - aug = Augment() - ds= ds.sync_wait(condition_name="policy", callback=aug.update) - ds = ds.map(operations=[aug.preprocess]) +下面将演示基于回调参数的自动数据增强的用法。 - ``` +1. 用户预先定义`Augment`类,其中`preprocess`为自定义的数据增强函数,`update`为更新数据增强策略的回调函数。 -3. 在每个step调用`sync_update`进行数据增强策略的更新。 + ```python + import mindspore.dataset.vision.py_transforms as transforms + import mindspore.dataset as ds + import numpy as np - ```python - epochs = 5 - itr = ds.create_tuple_iterator(num_epochs=epochs) - step_num = 0 - for ep_num in range(epochs): - for data in itr: - print("epcoh: {}, step:{}, data :{}".format(ep_num, step_num, data)) - step_num += 1 - ds.sync_update(condition_name="policy", data={'ep_num': ep_num, 'step_num': step_num}) + class Augment: + def __init__(self): + self.ep_num = 0 + self.step_num = 0 - ``` + def preprocess(self, input_): + return (np.array((input_ + self.step_num ** self.ep_num - 1), )) + + def update(self, data): + self.ep_num = data['ep_num'] + self.step_num = data['step_num'] + ``` + +2. 数据处理pipeline先回调自定义的增强策略更新函数`update`,然后在`map`操作中按更新后的策略来执行`preprocess`中定义的数据增强操作。 + + ```python + arr = list(range(1, 4)) + dataset = ds.NumpySlicesDataset(arr, shuffle=False) + aug = Augment() + dataset = dataset.sync_wait(condition_name="policy", callback=aug.update) + dataset = dataset.map(operations=[aug.preprocess]) + ``` + +3. 在每个step中调用`sync_update`进行数据增强策略的更新。 + + ```python + epochs = 5 + itr = dataset.create_tuple_iterator(num_epochs=epochs) + step_num = 0 + for ep_num in range(epochs): + for data in itr: + print("epcoh: {}, step:{}, data :{}".format(ep_num, step_num, data)) + step_num += 1 + dataset.sync_update(condition_name="policy", data={'ep_num': ep_num, 'step_num': step_num}) + ``` diff --git a/docs/programming_guide/source_zh_cn/auto_parallel_context.md b/docs/programming_guide/source_zh_cn/auto_parallel.md similarity index 90% rename from docs/programming_guide/source_zh_cn/auto_parallel_context.md rename to docs/programming_guide/source_zh_cn/auto_parallel.md index 14ce9bdab9..cc8cee2f71 100644 --- a/docs/programming_guide/source_zh_cn/auto_parallel_context.md +++ b/docs/programming_guide/source_zh_cn/auto_parallel.md @@ -6,31 +6,32 @@ - [概述](#概述) - [分布式并行配置](#分布式并行配置) - [通用配置](#通用配置) - - [device_num](#device_num) - - [global_rank](#global_rank) - - [gradients_mean](#gradients_mean) - - [parallel_mode](#parallel_mode) + - [device_num](#device_num) + - [global_rank](#global_rank) + - [gradients_mean](#gradients_mean) + - [parallel_mode](#parallel_mode) + - [all_reduce_fusion_config](#all_reduce_fusion_config) - [自动并行配置](#自动并行配置) - - [gradient_fp32_sync](#gradient_fp32-sync) - - [loss_repeated_mean](#loss_repeated_mean) - - [auto_parallel_search_mode](#auto_parallel_search_mode) - - [strategy_ckpt_load_file](#strategy_ckpt_load_file) - - [strategy_ckpt_save_file](#strategy_ckpt_save_file) - - [full_batch](#full_batch) + - [gradient_fp32_sync](#gradient_fp32_sync) + - [loss_repeated_mean](#loss_repeated_mean) + - [auto_parallel_search_mode](#auto_parallel_search_mode) + - [strategy_ckpt_load_file](#strategy_ckpt_load_file) + - [strategy_ckpt_save_file](#strategy_ckpt_save_file) + - [full_batch](#full_batch) - [数据并行配置](#数据并行配置) - - [enable_parallel_optimizer](#enable_parallel_optimizer) + - [enable_parallel_optimizer](#enable_parallel_optimizer) - [混合并行配置](#混合并行配置) - - [layerwise_parallel](#layerwise_parallel) + - [layerwise_parallel](#layerwise_parallel) - [分布式通信接口](#分布式通信接口) - [init](#init) - - [get_rank](#get_rank) - [get_group_size](#get_group_size) - - [数据并行](#数据并行) - - [自动并行](#自动并行) + - [get_rank](#get_rank) + - [数据并行](#数据并行) + - [自动并行](#自动并行) - + ## 概述 @@ -105,7 +106,7 @@ context.get_auto_parallel_context("gradients_mean") ```python from mindspore import context -context.set_auto_parallel_context(parallel_mode=“auto_parallel”) +context.set_auto_parallel_context(parallel_mode="auto_parallel") context.get_auto_parallel_context("parallel_mode") ``` @@ -162,7 +163,7 @@ MindSpore提供了`dynamic_programming`和`recursive_programming`两种搜索策 ```python from mindspore import context -context.set_auto_parallel_context(auto_parallel_search_mode=“dynamic_programming”) +context.set_auto_parallel_context(auto_parallel_search_mode="dynamic_programming") context.get_auto_parallel_context("auto_parallel_search_mode") ``` @@ -175,7 +176,7 @@ context.get_auto_parallel_context("auto_parallel_search_mode") ```python from mindspore import context -context.set_auto_parallel_context(strategy_ckpt_load_file=“./”) +context.set_auto_parallel_context(strategy_ckpt_load_file="./") context.get_auto_parallel_context("strategy_ckpt_load_file") ``` @@ -188,7 +189,7 @@ context.get_auto_parallel_context("strategy_ckpt_load_file") ```python from mindspore import context -context.set_auto_parallel_context(strategy_ckpt_save_file=“./”) +context.set_auto_parallel_context(strategy_ckpt_save_file="./") context.get_auto_parallel_context("strategy_ckpt_save_file") ``` @@ -299,4 +300,4 @@ rank_id = get_rank() 具体用例请参考MindSpore分布式并行训练教程: -。 \ No newline at end of file +。 diff --git a/docs/programming_guide/source_zh_cn/callback.md b/docs/programming_guide/source_zh_cn/callback.md index 5717a72a47..e82abbc1fb 100644 --- a/docs/programming_guide/source_zh_cn/callback.md +++ b/docs/programming_guide/source_zh_cn/callback.md @@ -1,29 +1,26 @@ -# MindSpore Callback回调函数机制 +# Callback机制 -- [概述](#概述) -- [MindSpore内置回调函数](#mindspore内置回调函数) -- [MindSpore自定义回调函数](#mindspore自定义回调函数) +- [Callback机制](#callback机制) + - [概述](#概述) + - [MindSpore内置回调函数](#mindspore内置回调函数) + - [MindSpore自定义回调函数](#mindspore自定义回调函数) - + ## 概述 Callback回调函数在MindSpore中被实现为一个类,Callback机制类似于一种监控模式,可以帮助用户观察网络训练过程中各种参数的变化情况和网络内部的状态,还可以根据用户的指定,在达到特定条件后执行相应的操作,在训练过程中,Callback列表会按照定义的顺序执行Callback函数。Callback机制让用户可以及时有效地掌握网络模型的训练状态,并根据需要随时作出调整,可以极大地提升用户的开发效率。 -在MindSpore中,Callback机制一般用在网络训练过程`model.train`中,用户可以通过配置不同的内置回调函数传入不同的参数,从而实现各种功能。例如,可以通过`LossMonitor`监控每一个epoch的loss变化情况,通过checkpoint保存网络参数和模型进行再训练或推理,通过`TimeMonitor`监控每一个epoch,每一个step的训练时间,以及提前终止训练,动态调整参数等。 +在MindSpore中,Callback机制一般用在网络训练过程`model.train`中,用户可以通过配置不同的内置回调函数传入不同的参数,从而实现各种功能。例如,可以通过`LossMonitor`监控每一个epoch的loss变化情况,通过`ModelCheckpoint`保存网络参数和模型进行再训练或推理,通过`TimeMonitor`监控每一个epoch,每一个step的训练时间,以及提前终止训练,动态调整参数等。 ## MindSpore内置回调函数 - ModelCheckpoint - 与模型训练过程相结合,保存训练后的模型和网络参数,方便进行再推理或再训练。 - -- CheckpointConfig - - 一般与`ModelCheckpoint`配合使用,可自定义配置checkpoint的保存策略。 + 与模型训练过程相结合,保存训练后的模型和网络参数,方便进行再推理或再训练。`ModelCheckpoint`一般与`CheckpointConfig`配合使用,`CheckpointConfig`是一个参数配置类,可自定义配置checkpoint的保存策略。 详细内容,请参考[Checkpoint官网教程](https://www.mindspore.cn/tutorial/zh-CN/master/use/saving_and_loading_model_parameters.html)。 diff --git a/docs/programming_guide/source_zh_cn/cell.md b/docs/programming_guide/source_zh_cn/cell.md index 698e7f5995..b1cec98e2a 100644 --- a/docs/programming_guide/source_zh_cn/cell.md +++ b/docs/programming_guide/source_zh_cn/cell.md @@ -1,58 +1,71 @@ -# cell模块概述 +# Cell及其继承类 -- [cell模块概述](#cell模块概述) - - [概念用途](#概念用途) - - [关键成员函数](#关键成员函数) - - [模型层](#模型层) - - [损失函数](#损失函数) - - [网络构造](#Cell构造自定义网络) +- [Cell及其继承类](#cell及其继承类) + - [概述](#概述) + - [关键成员函数](#关键成员函数) + - [construct方法](#construct方法) + - [parameters_dict](#parameters_dict) + - [cells_and_names](#cells_and_names) + - [set_grad](#set_grad) + - [模型层](#模型层) + - [内置模型层](#内置模型层) + - [应用实例](#应用实例) + - [损失函数](#损失函数) + - [内置损失函数](#内置损失函数) + - [应用实例](#应用实例-1) + - [优化算法](#优化算法) + - [构建自定义网络](#构建自定义网络) -## 概念用途 + -MindSpose的Cell类是构建所有网络的基类,也是网络的基本单元。当用户需要自定义网络时,需要继承Cell类,并重写__init_方法和contruct方法。 +## 概述 -损失函数,优化器和模型层等本质上也属于网络结构,也需要继承Cell类才能实现功能,同样用户也可以根据业务需求自定义这部分内容。 +MindSpore的`Cell`类是构建所有网络的基类,也是网络的基本单元。当用户需要自定义网络时,需要继承`Cell`类,并重写`__init__`方法和`contruct`方法。 -本节内容首先将会介绍Cell类的关键成员函数,然后介绍基于Cell实现的MindSpore内置损失函数,优化器和模型层及使用方法,最后通过实例介绍 -如何利用Cell类构建自定义网络。 +损失函数、优化器和模型层等本质上也属于网络结构,也需要继承`Cell`类才能实现功能,同样用户也可以根据业务需求自定义这部分内容。 + +本节内容首先将会介绍`Cell`类的关键成员函数,然后介绍基于`Cell`实现的MindSpore内置损失函数、优化器和模型层及使用方法,最后通过实例介绍如何利用`Cell`类构建自定义网络。 ## 关键成员函数 ### construct方法 -Cell类重写了__call__方法,在cell类的实例被调用时,会执行contruct方法。网络结构在contruct方法里面定义。 +`Cell`类重写了`__call__`方法,在`Cell`类的实例被调用时,会执行`contruct`方法。网络结构在`contruct`方法里面定义。 + +下面的样例中,我们构建了一个简单的网络实现卷积计算功能。构成网络的算子在`__init__`中定义,在`contruct`方法里面使用,用例的网络结构为`Conv2d`->`BiasAdd`。 -下面的样例中,我们构建了一个简单的网络。用例的网络结构为Conv2d->BatchNorm2d->ReLU->Flatten->Dense。 -在construct方法中,x为输入数据, out是经过网络的每层计算后得到的计算结果。 +在`construct`方法中,`x`为输入数据,`output`是经过网络结构计算后得到的计算结果。 ``` +import mindspore.nn as nn +from mindspore.ops import operations as P +from mindspore.common.parameter import Parameter +from mindspore.common.initializer import initializer + class Net(nn.Cell): - def __init__(self): + def __init__(self, in_channels=10, out_channels=20, kernel_size=3): super(Net, self).__init__() - self.conv = nn.Conv2d(3, 64, 3, has_bias=False, weight_init='normal') - self.bn = nn.BatchNorm2d(64) - self.relu = nn.ReLU() - self.flatten = nn.Flatten() - self.fc = nn.Dense(64 * 222 * 222, 3) + self.conv2d = P.Conv2D(out_channels, kernel_size) + self.bias_add = P.BiasAdd() + self.weight = Parameter( + initializer('normal', [out_channels, in_channels, kernel_size, kernel_size]), + name='conv.weight') def construct(self, x): - x = self.conv(x) - x = self.bn(x) - x = self.relu(x) - x = self.flatten(x) - out = self.fc(x) - return out + output = self.conv2d(x, self.weight) + output = self.bias_add(output, self.bias) + return output ``` ### parameters_dict -parameters_dict方法识别出网络结构中所有的参数,返回一个以key为参数名,value为参数值的OrderedDict()。 +`parameters_dict`方法识别出网络结构中所有的参数,返回一个以key为参数名,value为参数值的`OrderedDict`。 -Cell类中返回参数的方法还有许多,例如get_parameters(),trainable_params()等, 具体使用方法可以参见MindSpore API手册。 +`Cell`类中返回参数的方法还有许多,例如`get_parameters`、`trainable_params`等,具体使用方法可以参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.nn.html#mindspore.nn.Cell)。 代码样例如下: @@ -63,120 +76,163 @@ print(result.keys()) print(result['conv.weight']) ``` -样例中的Net()采用上文构造网络的用例,打印了网络中是所有参数的名字和conv.weight参数的结果。 +样例中的`Net`采用上文构造网络的用例,打印了网络中所有参数的名字和`conv.weight`参数的结果。 -运行结果如下: +输出如下: ``` -odict_keys(['conv.weight', 'bn.moving_mean', 'bn.moving_variance', 'bn.gamma', 'bn.beta', 'fc.weight', 'fc.bias']) -Parameter (name=conv.weight, value=[[[[ 1.07402597e-02 7.70052336e-03 5.55867562e-03] - [-3.21971579e-03 -3.75304517e-04 -8.73021083e-04] -... -[-1.81201510e-02 -1.31190736e-02 -4.27651079e-03]]]]) +odict_keys(['conv.weight']) +Parameter (name=conv.weight, value=[[[[-3.95042636e-03 1.08830128e-02 -6.51786150e-03] + [ 8.66129529e-03 7.36288540e-03 -4.32638079e-03] + [-1.47628486e-02 8.24100431e-03 -2.71035335e-03]] + ...... + [ 1.58852488e-02 -1.03505487e-02 1.72988791e-02]]]]) ``` ### cells_and_names -cells_and_names方法是一个迭代器,返回网络中每个cell的名字和它的内容本身。 +`cells_and_names`方法是一个迭代器,返回网络中每个`Cell`的名字和它的内容本身。 + +用例简单实现了获取与打印每个`Cell`名字的功能,其中根据网络结构可知,存在1个`Cell`为`nn.Conv2d`。 -用例简单实现了网络的cell获取与打印每个cell名字的功能,其中根据上文网络结构可知,存在五个cell分别是'conv','bn','relu','flatten','fc'。 +其中`nn.Conv2d`是MindSpore以`Cell`为基类封装好的一个卷积层,其具体内容将在“模型层”中进行介绍。 代码样例如下: ``` -net = Net() +import mindspore.nn as nn + +class Net1(nn.Cell): + def __init__(self): + super(Net1, self).__init__() + self.conv = nn.Conv2d(3, 64, 3, has_bias=False, weight_init='normal') + + def construct(self, x): + out = self.conv(x) + return out + +net = Net1() names = [] for m in net.cells_and_names(): + print(m) names.append(m[0]) if m[0] else None +print('-------names-------') print(names) ``` -运行结果: +输出如下: +``` +('', Net1< + (conv): Conv2d + >) +('conv', Conv2d) +-------names------- +['conv'] +``` + +### set_grad + +`set_grad`接口功能是使用户构建反向网络,在不传入参数调用时,默认设置`requires_grad`为True,需要在计算网络反向的场景中使用。 + +以`TrainOneStepCell`为例,其接口功能是使网络进行单步训练,需要计算网络反向,因此初始化方法里需要使用`set_grad`。 + +`TrainOneStepCell`部分代码如下: ``` -['conv', 'bn', 'relu', 'flatten', 'fc'] +class TrainOneStepCell(Cell): + def __init__(self, network, optimizer, sens=1.0): + super(TrainOneStepCell, self).__init__(auto_prefix=False) + self.network = network + self.network.set_grad() + ...... ``` + +如果用户使用`TrainOneStepCell`等类似接口无需使用`set_grad`, 内部已封装实现。 + +若用户需要自定义此类训练功能的接口,需要在其内部调用,或者在外部设置`network.set_grad`。 + ## 模型层 -在讲述了Cell的使用方法后可知,MindSpore能够以Cell为基类构造网络结构。 +在讲述了`Cell`的使用方法后可知,MindSpore能够以`Cell`为基类构造网络结构。 -为了方便业界需求及用户使用方便,MindSpore框架内置了大量的模型层,用户可以通过接口直接调用。 +为了方便用户的使用,MindSpore框架内置了大量的模型层,用户可以通过接口直接调用。 -同样,用户也可以自定义模型,此内容在cell自定义构建中介绍。 +同样,用户也可以自定义模型,此内容在“构建自定义网络”中介绍。 ### 内置模型层 -MindSpore框架在nn的layer层内置了丰富的接口,主要内容如下: +MindSpore框架在`mindspore.nn`的layer层内置了丰富的接口,主要内容如下: -- 激活层: +- 激活层 激活层内置了大量的激活函数,在定义网络结构中经常使用。激活函数为网络加入了非线性运算,使得网络能够拟合效果更好。 - 主要接口有Softmax,Relu,Elu,Tanh,Sigmoid等。 + 主要接口有`Softmax`、`Relu`、`Elu`、`Tanh`、`Sigmoid`等。 -- 基础层: +- 基础层 - 基础层实现了网络中一些常用的基础结构,例如全连接层,Onehot编码,Dropout,平铺层等都在此部分实现。 + 基础层实现了网络中一些常用的基础结构,例如全连接层、Onehot编码、Dropout、平铺层等都在此部分实现。 - 主要接口有Dense,Flatten,Dropout,Norm,OneHot等。 + 主要接口有`Dense`、`Flatten`、`Dropout`、`Norm`、`OneHot`等。 -- 容器层: +- 容器层 - 容器层主要功能是实现一些存储多个cell的数据结构。 + 容器层主要功能是实现一些存储多个Cell的数据结构。 - 主要接口有SequentialCell,CellList等。 + 主要接口有`SequentialCell`、`CellList`等。 -- 卷积层: +- 卷积层 - 卷积层提供了一些卷积计算的功能,如普通卷积,深度卷积和卷积转置等。 + 卷积层提供了一些卷积计算的功能,如普通卷积、深度卷积和卷积转置等。 - 主要接口有Conv2d,Conv1d,Conv2dTranspose,Conv1dTranspose等。 + 主要接口有`Conv2d`、`Conv1d`、`Conv2dTranspose`、`Conv1dTranspose`等。 -- 池化层: +- 池化层 池化层提供了平均池化和最大池化等计算的功能。 - 主要接口有AvgPool2d,MaxPool2d,AvgPool1d。 + 主要接口有`AvgPool2d`、`MaxPool2d`和`AvgPool1d`。 -- 嵌入层: +- 嵌入层 嵌入层提供word embedding的计算功能,将输入的单词映射为稠密向量。 - 主要接口有:Embedding,EmbeddingLookup,EmbeddingLookUpSplitMode等。 + 主要接口有`Embedding`、`EmbeddingLookup`、`EmbeddingLookUpSplitMode`等。 -- 长短记忆循环层: +- 长短记忆循环层 - 长短记忆循环层提供LSTM计算功能。其中LSTM内部会调用LSTMCell接口, LSTMCell是一个LSTM单元, - 对一个LSTM层做运算,当涉及多LSTM网络层运算时,使用LSTM接口。 + 长短记忆循环层提供LSTM计算功能。其中`LSTM`内部会调用`LSTMCell`接口,`LSTMCell`是一个LSTM单元,对一个LSTM层做运算,当涉及多LSTM网络层运算时,使用`LSTM`接口。 - 主要接口有:LSTM,LSTMCell。 + 主要接口有`LSTM`和`LSTMCell`。 -- 标准化层: +- 标准化层 标准化层提供了一些标准化的方法,即通过线性变换等方式将数据转换成均值和标准差。 - 主要接口有:BatchNorm1d,BatchNorm2d,LayerNorm,GroupNorm,GlobalBatchNorm等。 + 主要接口有`BatchNorm1d`、`BatchNorm2d`、`LayerNorm`、`GroupNorm`、`GlobalBatchNorm`等。 -- 数学计算层: +- 数学计算层 数据计算层提供一些算子拼接而成的计算功能,例如数据生成和一些数学计算等。 - 主要接口有ReduceLogSumExp,Range,LinSpace,LGamma等。 + 主要接口有`ReduceLogSumExp`、`Range`、`LinSpace`、`LGamma`等。 -- 图片层: +- 图片层 图片计算层提供了一些矩阵计算相关的功能,将图片数据进行一些变换与计算。 - 主要接口有ImageGradients,SSIM,MSSSIM,PSNR,CentralCrop等。 + 主要接口有`ImageGradients`、`SSIM`、`MSSSIM`、`PSNR`、`CentralCrop`等。 -- 量化层: +- 量化层 量化是指将数据从float的形式转换成一段数据范围的int类型,所以量化层提供了一些数据量化的方法和模型层结构封装。 - - 主要接口有Conv2dBnAct,DenseBnAct,Conv2dBnFoldQuant,LeakyReLUQuant等。 + + 主要接口有`Conv2dBnAct`、`DenseBnAct`、`Conv2dBnFoldQuant`、`LeakyReLUQuant`等。 ### 应用实例 -MindSpore的模型层在mindspore.nn下,使用方法如下所示: +MindSpore的模型层在`mindspore.nn`下,使用方法如下所示: ``` +import mindspore.nn as nn + class Net(nn.Cell): def __init__(self): super(Net, self).__init__() @@ -195,44 +251,37 @@ class Net(nn.Cell): return out ``` -依然是上述网络构造的用例,从这个用例中可以看出,程序调用了Conv2d,BatchNorm2d,ReLU,Flatten和Dense模型层的接口。 -在Net初始化方法里面被定义,然后在construct方法里面真正运行,这些模型层接口有序的连接,形成一个可执行的网络。 +依然是上述网络构造的用例,从这个用例中可以看出,程序调用了`Conv2d`、`BatchNorm2d`、`ReLU`、`Flatten`和`Dense`模型层的接口。 + +在`Net`初始化方法里被定义,然后在`construct`方法里真正运行,这些模型层接口有序的连接,形成一个可执行的网络。 ## 损失函数 -目前MindSpore主要支持的损失函数有L1Loss,MSELoss,SmoothL1Loss,SoftmaxCrossEntropyWithLogits,SoftmaxCrossEntropyExpand -和CosineEmbeddingLoss。 +目前MindSpore主要支持的损失函数有`L1Loss`、`MSELoss`、`SmoothL1Loss`、`SoftmaxCrossEntropyWithLogits`和`CosineEmbeddingLoss`。 -MindSpore的损失函数全部是Cell的子类实现,所以也支持用户自定义损失函数,其构造方法在cell自定义构建中进行介绍。 +MindSpore的损失函数全部是`Cell`的子类实现,所以也支持用户自定义损失函数,其构造方法在“构建自定义网络”中进行介绍。 ### 内置损失函数 -- L1Loss: - - 计算两个输入数据的绝对值误差,用于回归模型。reduction参数默认值为mean,返回loss平均值结果, -若reduction值为sum,返回loss累加结果,若reduction值为none,返回每个loss的结果。 +- L1Loss -- MSELoss: + 计算两个输入数据的绝对值误差,用于回归模型。`reduction`参数默认值为mean,返回loss平均值结果,若`reduction`值为sum,返回loss累加结果,若`reduction`值为none,返回每个loss的结果。 - 计算两个输入数据的平方误差,用于回归模型。reduction参数默认值为mean,返回loss平均值结果, -若reduction值为sum,返回loss累加结果,若reduction值为none,返回每个loss的结果。 +- MSELoss -- SmoothL1Loss: + 计算两个输入数据的平方误差,用于回归模型。`reduction`参数同`L1Loss`。 - SmoothL1Loss为平滑L1损失函数,用于回归模型,阈值sigma默认参数为1。 +- SmoothL1Loss -- SoftmaxCrossEntropyWithLogits: + `SmoothL1Loss`为平滑L1损失函数,用于回归模型,阈值`sigma`默认参数为1。 +` +- SoftmaxCrossEntropyWithLogits - 交叉熵损失函数,用于分类模型。当标签数据不是one-hot编码形式时,需要输入参数sparse为True。reduction参数 - 与L1Loss一致。 + 交叉熵损失函数,用于分类模型。当标签数据不是one-hot编码形式时,需要输入参数`sparse`为True。`reduction`参数默认值为none,其参数含义同`L1Loss`。 -- SoftmaxCrossEntropyExpand: - - 交叉熵扩展损失函数,用于分类模型。当标签数据不是one-hot编码形式时,需要输入参数sparse为True。 +- CosineEmbeddingLoss -- CosineEmbeddingLoss: - - CosineEmbeddingLoss用于衡量两个输入相似程度,用于分类模型。margin默认为0.0,reduction参数与L1Loss一致 + `CosineEmbeddingLoss`用于衡量两个输入相似程度,用于分类模型。`margin`默认为0.0,`reduction`参数同`L1Loss`。 ### 应用实例 @@ -249,28 +298,33 @@ target_data = Tensor(np.array([[0, 2, 5], [3, 1, 1]]).astype(np.float32)) print(loss(input_data, target_data)) ``` -此用例构造了两个Tensor数据,利用nn.L1Loss()接口定义了L1Loss,将input_data和target_data传入loss, -执行L1Loss的计算,结果为1.5。若loss = nn.L1Loss(reduction='sum'),则结果为9.0。 -若loss = nn.L1Loss(reduction='none'),结果为[[1. 0. 2.] [1. 2. 3.]] +输出结果: +``` +1.5 +``` + +此用例构造了两个Tensor数据,利用`nn.L1Loss()`接口定义了loss,将`input_data`和`target_data`传入loss,执行L1Loss的计算,结果为1.5。若loss = nn.L1Loss(reduction='sum'),则结果为9.0。若loss = nn.L1Loss(reduction='none'),结果为[[1. 0. 2.] [1. 2. 3.]]。 + +## 优化算法 +`mindspore.nn.optim`是MindSpore框架中实现各种优化算法的模块,详细说明参见[优化算法](https://www.mindspore.cn/api/zh-CN/master/programming_guide/optim.html)。 -## Cell构造自定义网络 +## 构建自定义网络 -无论是网络结构,还是前文提到的模型层,损失函数和优化器等,本质上都是一个Cell,因此都可以自定义实现。 +无论是网络结构,还是前文提到的模型层、损失函数和优化器等,本质上都是一个`Cell`,因此都可以自定义实现。 -首先构造一个继承cell的子类,然后在__init__方法里面定义算子和模型层等,然后在construct方法里面构造网络结构。 +首先构造一个继承`Cell`的子类,然后在`__init__`方法里面定义算子和模型层等,在`construct`方法里面构造网络结构。 -以lenet5网络为例,在__init__方法中定义了卷积层,池化层和全连接层等结构单元,然后在construct方法将定义的内容连接在一起, -形成一个完整lenet5的网络结构。 +以LeNet网络为例,在`__init__`方法中定义了卷积层,池化层和全连接层等结构单元,然后在`construct`方法将定义的内容连接在一起,形成一个完整LeNet的网络结构。 -lenet5网络实现方式如下所示: +LeNet网络实现方式如下所示: ``` import mindspore.nn as nn class LeNet5(nn.Cell): def __init__(self): super(LeNet5, self).__init__() - self.conv1 = nn.Conv2d(3, 6, 5, pad_mode="valid") + self.conv1 = nn.Conv2d(1, 6, 5, pad_mode="valid") self.conv2 = nn.Conv2d(6, 16, 5, pad_mode="valid") self.fc1 = nn.Dense(16 * 5 * 5, 120) self.fc2 = nn.Dense(120, 84) diff --git a/docs/programming_guide/source_zh_cn/compute_component.rst b/docs/programming_guide/source_zh_cn/compute_component.rst new file mode 100644 index 0000000000..58d676eacf --- /dev/null +++ b/docs/programming_guide/source_zh_cn/compute_component.rst @@ -0,0 +1,10 @@ +计算组件 +=========== + +.. toctree:: + :maxdepth: 1 + + operator + parameter + cell + network_component \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/context.md b/docs/programming_guide/source_zh_cn/context.md new file mode 100644 index 0000000000..d4aec895ec --- /dev/null +++ b/docs/programming_guide/source_zh_cn/context.md @@ -0,0 +1,135 @@ +# 运行管理 + + + +- [运行管理](#运行管理) + - [概述](#概述) + - [执行模式管理](#执行模式管理) + - [模式选择](#模式选择) + - [模式切换](#模式切换) + - [硬件管理](#硬件管理) + - [分布式管理](#分布式管理) + - [维测管理](#维测管理) + - [采集profiling数据](#采集profiling数据) + - [异步数据dump功能](#异步数据dump功能) + - [print算子落盘](#print算子落盘) + + + + + +## 概述 +初始化网络之前要配置context参数,用于控制程序执行的策略。比如选择执行模式、选择执行后端、配置分布式相关参数等。按照context参数设置实现的不同功能,可以将其分为执行模式管理、硬件管理、分布式管理和维测管理等。 + +## 执行模式管理 +MindSpore支持PyNative和Graph这两种运行模式: + +- `PYNATIVE_MODE`:动态图模式,将神经网络中的各个算子逐一下发执行,方便用户编写和调试神经网络模型。 + +- `GRAPH_MODE`:静态图模式或者图模式,将神经网络模型编译成一整张图,然后下发执行。该模式利用图优化等技术提高运行性能,同时有助于规模部署和跨平台运行。 + +### 模式选择 +通过设置可以控制程序运行的模式,默认情况下,MindSpore处于PyNative模式。 + +代码样例如下: +```python +from mindspore import context +context.set_context(mode=context.GRAPH_MODE) +``` + +### 模式切换 +实现两种模式之间的切换,可以通过`context.set_context(mode=context.GRAPH_MODE)`切换为Graph模式;同样地,MindSpore处于Graph模式时,可以通过 `context.set_context(mode=context.PYNATIVE_MODE)`切换为PyNative模式。 + +代码样例如下: +```python +import numpy as np +import mindspore.nn as nn +from mindspore import context, Tensor + +context.set_context(mode=context.GRAPH_MODE, device_target="GPU") + +conv = nn.Conv2d(3, 4, 3, bias_init='zeros') +input_data = Tensor(np.ones([1, 3, 5, 5]).astype(np.float32)) +conv(input_data) +context.set_context(mode=context.PYNATIVE_MODE) +conv(input_data) +``` + +上面的例子先将运行模式设置为`GRAPH_MODE`模式,然后将模式切换为`PYNATIVE_MODE`模式,实现了模式的切换。 + +## 硬件管理 +硬件管理部分主要包括`device_target`和`device_id`两个参数。 + +- `device_target`: 用于设置目标设备,支持Ascend、GPU和CPU,默认设置是Ascend。 + +- `device_id`: 表示卡物理序号,即卡所在机器中的实际序号。如果目标设备为Ascend,且规格为N*Ascend(其中N>1,如8*Ascend),在非分布式模式执行的情况下,为了避免设备的使用冲突,可以通过设置`device_id`决定程序执行的device编号,该编号范围为:0 ~ 服务器总设备数量-1,服务器总设备数量不能超过4096,默认为设备0。 + +> 在GPU和CPU上,设置`device_id`参数无效。 + +代码样例如下: +```python +from mindspore import context +context.set_context(device_target="Ascend", device_id=6) +``` + +## 分布式管理 +context中有专门用于配置并行训练参数的接口:context.set_auto_parallel_context,该接口必须在初始化网络之前调用。 + +- `parallel_mode`:分布式并行模式,默认为单机模式`ParallelMode.STAND_ALONE`。可选数据并行`ParallelMode.DATA_PARALLEL`及自动并行`ParallelMode.AUTO_PARALLEL`。 + +- `gradients_mean`:反向计算时,框架内部会将数据并行参数分散在多台机器的梯度值进行收集,得到全局梯度值后再传入优化器中更新。默认值为`False`,设置为True对应`allreduce_mean`操作,False对应`allreduce_sum`操作。 + +- `enable_parallel_optimizer`:开发中特性。打开优化器模型并行开关,通过拆分权重到各卡分别进行更新再同步的方式以提升性能。该参数目前只在数据并行模式和参数量大于机器数时有效,支持`Lamb`和`Adam`优化器。 + +> `device_num`和`global_rank`建议采用默认值,框架内会调用HCCL接口获取。 + +代码样例如下: +```python +from mindspore import context +from mindspore.context import ParallelMode +context.set_auto_parallel_context(parallel_mode=ParallelMode.AUTO_PARALLEL, gradients_mean=True) +``` + +> 分布式并行训练详细介绍可以查看[分布式并行训练](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/distributed_training_tutorials.html)。 + +## 维测管理 +为了方便维护和定位问题,context提供了大量维测相关的参数配置,如采集profiling数据、异步数据dump功能和print算子落盘等。 + +### 采集profiling数据 +系统支持在训练过程中采集profiling数据,然后通过profiling工具进行性能分析。当前支持采集的profiling数据包括: + +- `enable_profiling`:是否开启profiling功能。设置为True,表示开启profiling功能,从enable_options读取profiling的采集选项;设置为False,表示关闭profiling功能,仅采集training_trace。 + +- `enable_options`:profiling采集选项,取值如下,支持采集多项数据。training_trace:采集迭代轨迹数据,即训练任务及AI软件栈的软件信息,实现对训练任务的性能分析,重点关注数据增强、前后向计算、梯度聚合更新等相关数据;task_trace:采集任务轨迹数据,即昇腾910处理器HWTS/AICore的硬件信息,分析任务开始、结束等信息;op_trace:采集单算子性能数据。格式:['op_trace','task_trace','training_trace'] + +代码样例如下: +```python +from mindspore import context +context.set_context(enable_profiling=True, profiling_options="training_trace") +``` + +### 异步数据dump功能 +在Ascend环境上执行训练,当训练结果和预期有偏差时,可以通过异步数据dump功能保存算子的输入输出进行调试。 + +代码样例如下: +```python +from mindspore import context +context.set_context(save_graphs=True) +``` + +> 详细的调试方法可以查看[异步数据Dump功能介绍](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/customized_debugging_information.html#dump)。 + +### print算子落盘 +默认情况下,MindSpore的自研print算子可以将用户输入的Tensor或字符串信息打印出来,支持多字符串输入,多Tensor输入和字符串与Tensor的混合输入,输入参数以逗号隔开。 + +> Print打印功能可以查看[Print算子功能介绍](https://www.mindspore.cn/tutorial/zh-CN/master/advanced_use/customized_debugging_information.html#print)。 + +- `print_file_path`:可以将print算子数据保存到文件,同时关闭屏幕打印功能。如果保存的文件已经存在,则会给文件添加时间戳后缀。数据保存到文件可以解决数据量较大时屏幕打印数据丢失的问题。 + +代码样例如下: +```python +from mindspore import context +context.set_context(print_file_path="print.pb") +``` + +> context接口详细介绍可以查看[mindspore.context](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.context.html)。 \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/data_pipeline.rst b/docs/programming_guide/source_zh_cn/data_pipeline.rst new file mode 100644 index 0000000000..62f55a9e10 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/data_pipeline.rst @@ -0,0 +1,13 @@ +数据管道 +=========== + +.. toctree:: + :maxdepth: 1 + + dataset_loading + sampler + pipeline + augmentation + tokenizer + dataset_conversion + auto_augmentation diff --git a/docs/programming_guide/source_zh_cn/data_type.rst b/docs/programming_guide/source_zh_cn/data_type.rst new file mode 100644 index 0000000000..ee35ad4275 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/data_type.rst @@ -0,0 +1,8 @@ +数据类型 +=========== + +.. toctree:: + :maxdepth: 1 + + dtype + tensor \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/dataset_conversion.md b/docs/programming_guide/source_zh_cn/dataset_conversion.md index 29f7557b12..702ecf4686 100644 --- a/docs/programming_guide/source_zh_cn/dataset_conversion.md +++ b/docs/programming_guide/source_zh_cn/dataset_conversion.md @@ -4,179 +4,153 @@ - [MindSpore数据格式转换](#mindspore数据格式转换) - [概述](#概述) - - [非标准数据集转换MindRecord](#非标准数据集转换mindrecord) - - [CV类数据集](#cv类数据集) - - [NLP类数据集](#nlp类数据集) - - [常用数据集转换MindRecord](#常用数据集转换mindrecord) - - [转换CIFAR-10数据集](#转换cifar-10数据集) - - [转换CIFAR-100数据集](#转换cifar-100数据集) - - [转换ImageNet数据集](#转换imagenet数据集) - - [转换MNIST数据集](#转换mnist数据集) - - [转换CSV数据集](#转换csv数据集) - - [转换TFRecord数据集](#转换tfrecord数据集) + - [非标准数据集转换MindRecord](#非标准数据集转换mindrecord) + - [转换CV类数据集](#转换cv类数据集) + - [转换NLP类数据集](#转换nlp类数据集) + - [常用数据集转换MindRecord](#常用数据集转换mindrecord) + - [转换CIFAR-10数据集](#转换cifar-10数据集) + - [转换ImageNet数据集](#转换imagenet数据集) + - [转换CSV数据集](#转换csv数据集) + - [转换TFRecord数据集](#转换tfrecord数据集) - + ## 概述 -用户可以将非标准的数据集和常见的经典数据集转换为MindSpore数据格式即MindRecord,从而方便地加载到MindSpore中进行训练。同时,MindSpore在部分场景做了性能优化,使用MindSpore数据格式可以获得更好的性能体验。 +用户可以将非标准的数据集和常用的数据集转换为MindSpore数据格式,即MindRecord,从而方便地加载到MindSpore中进行训练。同时,MindSpore在部分场景做了性能优化,使用MindRecord可以获得更好的性能体验。 ## 非标准数据集转换MindRecord -主要介绍如何将CV类数据和NLP类数据转换为MindRecord格式,并通过MindDataset实现MindRecoed格式文件的读取。 +下面主要介绍如何将CV类数据和NLP类数据转换为MindRecord,并通过`MindDataset`实现MindRecoed文件的读取。 -### CV类数据集 +### 转换CV类数据集 - ```python - """ - 示例说明:本示例主要介绍用户如何将自己的CV类数据集转换成MindRecoed格式,并使用MindDataset读取。 - 详细步骤: - 1. 创建一个包含100条记录的MindRecord文件,其样本包含file_name(字符串), label(整形), data(二进制)三个字段; - 2. 使用MindDataset读取MindRecord文件。 - """ +本示例主要介绍用户如何将自己的CV类数据集转换成MindRecord,并使用`MindDataset`读取。 - from io import BytesIO - import os - import mindspore.dataset as ds - from mindspore.mindrecord import FileWriter - import mindspore.dataset.vision.c_transforms as vision - from PIL import Image +本示例首先创建一个包含100条记录的MindRecord文件,其样本包含`file_name`(字符串)、 +`label`(整形)、 `data`(二进制)三个字段,然后使用`MindDataset`读取该MindRecord文件。 - ################################ 生成MindRecord文件 ################################ +```python +from io import BytesIO +import os +import mindspore.dataset as ds +from mindspore.mindrecord import FileWriter +import mindspore.dataset.vision.c_transforms as vision +from PIL import Image - mindrecord_filename = "test.mindrecord" +mindrecord_filename = "test.mindrecord" - # 如果存在MindRecord文件,则需要先删除 - if os.path.exists(mindrecord_filename): - os.remove(mindrecord_filename) - os.remove(mindrecord_filename + ".db") +if os.path.exists(mindrecord_filename): + os.remove(mindrecord_filename) + os.remove(mindrecord_filename + ".db") - # 创建写对象,将会生成 mindrecord_filename 和 mindrecord_filename.db 两个文件 - writer = FileWriter(file_name=mindrecord_filename, shard_num=1) +writer = FileWriter(file_name=mindrecord_filename, shard_num=1) - # 定义数据集Schema - cv_schema = {"file_name": {"type": "string"}, "label": {"type": "int32"}, "data": {"type": "bytes"}} - writer.add_schema(cv_schema, "it is a cv dataset") +cv_schema = {"file_name": {"type": "string"}, "label": {"type": "int32"}, "data": {"type": "bytes"}} +writer.add_schema(cv_schema, "it is a cv dataset") - # [可选]定义索引字段,只能是标量字段 - writer.add_index(["file_name", "label"]) +writer.add_index(["file_name", "label"]) - # 按Schema方式组织训练数据,并将其写入MindRecord文件 - # 此处使用Image.new(...)模拟图片数据,真实场景可以使用io接口读取磁盘上的图像数据 - data = [] - for i in range(100): # 模拟数据集有100个样本 - i += 1 +data = [] +for i in range(100): + i += 1 - sample = {} - white_io = BytesIO() - Image.new('RGB', (i*10, i*10), (255, 255, 255)).save(white_io, 'JPEG') # 图片大小可以不同 - image_bytes = white_io.getvalue() - sample['file_name'] = str(i) + ".jpg" # 对应file_name字段 - sample['label'] = i # 对应label字段 - sample['data'] = white_io.getvalue() # 对应data字段 + sample = {} + white_io = BytesIO() + Image.new('RGB', (i*10, i*10), (255, 255, 255)).save(white_io, 'JPEG') + image_bytes = white_io.getvalue() + sample['file_name'] = str(i) + ".jpg" + sample['label'] = i + sample['data'] = white_io.getvalue() - data.append(sample) - if i % 10 == 0: # 每10条样本做一次写操作 - writer.write_raw_data(data) - data = [] + data.append(sample) + if i % 10 == 0: + writer.write_raw_data(data) + data = [] - if data: # 写入可能剩余的数据 - writer.write_raw_data(data) +if data: + writer.write_raw_data(data) + +writer.commit() + +data_set = ds.MindDataset(dataset_file=mindrecord_filename) +decode_op = vision.Decode() +data_set = data_set.map(operations=decode_op, input_columns=["data"], num_parallel_workers=2) +count = 0 +for item in data_set.create_dict_iterator(): + print("sample: {}".format(item)) + count += 1 +print("Got {} samples".format(count)) +``` + +### 转换NLP类数据集 + +> NLP类数据一般会先经过预处理转换为字典序,本示例只演示转换后的字典序数据如何写入MindRecord文件,而不包括预处理过程。 + +本示例主要介绍用户如何将自己的NLP类数据集转换成MindRecord,并使用`MindDataset`读取。 + +本示例首先创建一个包含100条记录的MindRecord文件,其样本包含八个字段,均为整形数组,然后使用`MindDataset`读取该MindRecord文件。 + +```python +import os +import numpy as np +import mindspore.dataset as ds +from mindspore.mindrecord import FileWriter + +mindrecord_filename = "test.mindrecord" + +if os.path.exists(mindrecord_filename): + os.remove(mindrecord_filename) + os.remove(mindrecord_filename + ".db") - writer.commit() # 关闭写入操作 - - ################################ 读取MindRecord文件 ################################ - - data_set = ds.MindDataset(dataset_file=mindrecord_filename) # 创建读取对象,默认开启shuffle - decode_op = vision.Decode() - data_set = data_set.map(operations=decode_op, input_columns=["data"], num_parallel_workers=2) # 解码data字段 - count = 0 - for item in data_set.create_dict_iterator(output_numpy=True): # 循环读取MindRecord中所有数据 - print("sample: {}".format(item)) - count += 1 - print("Got {} samples".format(count)) - ``` - -### NLP类数据集 - -> 因为NLP类数据一般会经过预处理转换为字典序,此预处理过程不在本示例范围,该示例只演示转换后的字典序数据如何写入MindRecord。 - - ```python - """ - 示例说明:本示例主要介绍用户如何将自己的NLP类数据集转换成MindRecoed格式,并使用MindDataset读取。 - 详细步骤: - 1. 创建一个包含100条记录的MindRecord文件,其样本包含八个字段,均为整形数组; - 2. 使用MindDataset读取MindRecord文件。 - """ - - import os - import numpy as np - import mindspore.dataset as ds - from mindspore.mindrecord import FileWriter - - ################################ 生成MindRecord文件 ################################ - - mindrecord_filename = "test.mindrecord" - - # 如果存在MindRecord文件,则需要先删除 - if os.path.exists(mindrecord_filename): - os.remove(mindrecord_filename) - os.remove(mindrecord_filename + ".db") - - # 创建写对象,将会生成 mindrecord_filename 和 mindrecord_filename.db 两个文件 - writer = FileWriter(file_name=mindrecord_filename, shard_num=1) - - # 定义数据集Schema,此处认为文本已经转为字典序 - nlp_schema = {"source_sos_ids": {"type": "int64", "shape": [-1]}, - "source_sos_mask": {"type": "int64", "shape": [-1]}, - "source_eos_ids": {"type": "int64", "shape": [-1]}, - "source_eos_mask": {"type": "int64", "shape": [-1]}, - "target_sos_ids": {"type": "int64", "shape": [-1]}, - "target_sos_mask": {"type": "int64", "shape": [-1]}, - "target_eos_ids": {"type": "int64", "shape": [-1]}, - "target_eos_mask": {"type": "int64", "shape": [-1]}} - writer.add_schema(nlp_schema, "it is a preprocessed nlp dataset") - - # 按Schema方式组织训练数据,并将其写入MindRecord文件 - data = [] - for i in range(100): # 模拟数据集有100个样本 - i += 1 - - # 组织训练数据 - sample = {"source_sos_ids": np.array([i, i+1, i+2, i+3, i+4], dtype=np.int64), - "source_sos_mask": np.array([i*1, i*2, i*3, i*4, i*5, i*6, i*7], dtype=np.int64), - "source_eos_ids": np.array([i+5, i+6, i+7, i+8, i+9, i+10], dtype=np.int64), - "source_eos_mask": np.array([19, 20, 21, 22, 23, 24, 25, 26, 27], dtype=np.int64), - "target_sos_ids": np.array([28, 29, 30, 31, 32], dtype=np.int64), - "target_sos_mask": np.array([33, 34, 35, 36, 37, 38], dtype=np.int64), - "target_eos_ids": np.array([39, 40, 41, 42, 43, 44, 45, 46, 47], dtype=np.int64), - "target_eos_mask": np.array([48, 49, 50, 51], dtype=np.int64)} - - data.append(sample) - if i % 10 == 0: # 每10条样本做一次写操作 - writer.write_raw_data(data) - data = [] - - if data: # 写入可能剩余的数据 +writer = FileWriter(file_name=mindrecord_filename, shard_num=1) + +nlp_schema = {"source_sos_ids": {"type": "int64", "shape": [-1]}, + "source_sos_mask": {"type": "int64", "shape": [-1]}, + "source_eos_ids": {"type": "int64", "shape": [-1]}, + "source_eos_mask": {"type": "int64", "shape": [-1]}, + "target_sos_ids": {"type": "int64", "shape": [-1]}, + "target_sos_mask": {"type": "int64", "shape": [-1]}, + "target_eos_ids": {"type": "int64", "shape": [-1]}, + "target_eos_mask": {"type": "int64", "shape": [-1]}} +writer.add_schema(nlp_schema, "it is a preprocessed nlp dataset") + +data = [] +for i in range(100): + i += 1 + + sample = {"source_sos_ids": np.array([i, i+1, i+2, i+3, i+4], dtype=np.int64), + "source_sos_mask": np.array([i*1, i*2, i*3, i*4, i*5, i*6, i*7], dtype=np.int64), + "source_eos_ids": np.array([i+5, i+6, i+7, i+8, i+9, i+10], dtype=np.int64), + "source_eos_mask": np.array([19, 20, 21, 22, 23, 24, 25, 26, 27], dtype=np.int64), + "target_sos_ids": np.array([28, 29, 30, 31, 32], dtype=np.int64), + "target_sos_mask": np.array([33, 34, 35, 36, 37, 38], dtype=np.int64), + "target_eos_ids": np.array([39, 40, 41, 42, 43, 44, 45, 46, 47], dtype=np.int64), + "target_eos_mask": np.array([48, 49, 50, 51], dtype=np.int64)} + + data.append(sample) + if i % 10 == 0: writer.write_raw_data(data) + data = [] - writer.commit() # 关闭写入操作 +if data: + writer.write_raw_data(data) - ################################ 读取MindRecord文件 ################################ +writer.commit() - data_set = ds.MindDataset(dataset_file=mindrecord_filename) # 创建读取对象,默认开启shuffle - count = 0 - for item in data_set.create_dict_iterator(): # 循环读取MindRecord中所有数据 - print("sample: {}".format(item)) - count += 1 - print("Got {} samples".format(count)) - ``` +data_set = ds.MindDataset(dataset_file=mindrecord_filename) +count = 0 +for item in data_set.create_dict_iterator(): + print("sample: {}".format(item)) + count += 1 +print("Got {} samples".format(count)) +``` ## 常用数据集转换MindRecord -MindSpore提供转换常见数据集的工具类,能够将常见的经典数据集转换为MindRecord格式。常见数据集及其对应的工具类列表如下。 +MindSpore提供转换常用数据集的工具类,能够将常用的数据集转换为MindRecord。常用数据集及其对应的工具类列表如下。 | 数据集 | 格式转换工具类 | | -------- | ------------ | @@ -191,9 +165,9 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 ### 转换CIFAR-10数据集 -用户可以通过`Cifar10ToMR`类,将CIFAR-10原始数据转换为MindRecord格式。 +用户可以通过`Cifar10ToMR`类,将CIFAR-10原始数据转换为MindRecord。 -1. 下载[CIFAR-10数据集](https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz)并解压,目录结构如下所示。 +1. 下载[CIFAR-10数据集](https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz)并解压,其目录结构如下所示。 ``` └─cifar-10-batches-py @@ -213,10 +187,10 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 from mindspore.mindrecord import Cifar10ToMR ``` -3. 创建`Cifar10ToMR`对象,调用`transform`接口,将CIFAR-10数据集转换为MindRecord格式。 +3. 创建`Cifar10ToMR`对象,调用`transform`接口,将CIFAR-10数据集转换为MindRecord。 ```python - CIFAR10_DIR = "./cifar10/cifar-10-batches-py" + CIFAR10_DIR = "./cifar-10-batches-py" MINDRECORD_FILE = "./cifar10.mindrecord" cifar10_transformer = Cifar10ToMR(CIFAR10_DIR, MINDRECORD_FILE) cifar10_transformer.transform(['label']) @@ -224,52 +198,14 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 **参数说明:** - `CIFAR10_DIR`:CIFAR-10数据集的文件夹路径。 - - `MINDRECORD_FILE`:输出的MindSpore数据格式文件路径。 - -### 转换CIFAR-100数据集 - -用户可以通过`Cifar100ToMR`类,将CIFAR-100原始数据转换为MindRecord格式。 - -1. 准备好CIFAR-100数据集,将文件解压至指定的目录(示例中将数据集保存到`cifar100`目录),如下所示。 - - ``` - % ll cifar100/cifar-100-python/ - meta - test - train - ``` - > CIFAR-100数据集下载地址: - -2. 导入转换数据集的工具类`Cifar100ToMR`。 - - ```python - from mindspore.mindrecord import Cifar100ToMR - ``` - -3. 实例化`Cifar100ToMR`对象,调用`transform`接口,将CIFAR-100数据集转换为MindSpore数据格式。 - - ```python - CIFAR100_DIR = "./cifar100/cifar-100-python" - MINDRECORD_FILE = "./cifar100.mindrecord" - cifar100_transformer = Cifar100ToMR(CIFAR100_DIR, MINDRECORD_FILE) - cifar100_transformer.transform(['fine_label', 'coarse_label']) - ``` - - **参数说明:** - - `CIFAR100_DIR`:CIFAR-100数据集的文件夹路径。 - - `MINDRECORD_FILE`:输出的MindSpore数据格式文件路径。 + - `MINDRECORD_FILE`:输出的MindRecord文件路径。 ### 转换ImageNet数据集 -用户可以通过`ImageNetToMR`类,将ImageNet原始数据(图片、标注)转换为MindSpore数据格式。 - -1. 下载并按照要求准备好ImageNet数据集。 +用户可以通过`ImageNetToMR`类,将ImageNet原始数据(图片、标注)转换为MindRecord。 - > ImageNet数据集下载地址: +1. 下载[ImageNet数据集](http://image-net.org/download),将所有图片存放在同一文件夹,用一个映射文件记录图片和标签的对应关系。映射文件包含2列,分别为各类别图片目录和标签ID,用空格隔开,映射文件示例如下: - 对下载后的ImageNet数据集,整理数据集组织形式为一个包含所有图片的文件夹,以及一个记录图片对应标签的映射文件。 - - 标签映射文件包含2列,分别为各类别图片目录、标签ID,用空格隔开,映射文件示例如下: ``` n01440760 0 n01443537 1 @@ -279,13 +215,14 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 n01496331 5 ``` -2. 导入转换数据集的工具类`ImageNetToMR`。 +2. 导入数据集转换工具类`ImageNetToMR`。 ```python from mindspore.mindrecord import ImageNetToMR ``` -3. 实例化`ImageNetToMR`对象,调用`transform`接口,将数据集转换为MindSpore数据格式。 +3. 创建`ImageNetToMR`对象,调用`transform`接口,将数据集转换为MindRecord。 + ```python IMAGENET_MAP_FILE = "./testImageNetDataWhole/labels_map.txt" IMAGENET_IMAGE_DIR = "./testImageNetDataWhole/images" @@ -294,228 +231,156 @@ MindSpore提供转换常见数据集的工具类,能够将常见的经典数 imagenet_transformer = ImageNetToMR(IMAGENET_MAP_FILE, IMAGENET_IMAGE_DIR, MINDRECORD_FILE, PARTITION_NUMBER) imagenet_transformer.transform() ``` - 其中, - `IMAGENET_MAP_FILE`:ImageNetToMR数据集的标签映射文件路径。 - `IMAGENET_IMAGE_DIR`:包含ImageNet所有图片的文件夹路径。 - `MINDRECORD_FILE`:输出的MindSpore数据格式文件路径。 -### 转换MNIST数据集 + **参数说明:** + - `IMAGENET_MAP_FILE`:ImageNet数据集标签映射文件的路径。 + - `IMAGENET_IMAGE_DIR`:包含ImageNet所有图片的文件夹路径。 + - `MINDRECORD_FILE`:输出的MindRecord文件路径。 -用户可以通过`MnistToMR`类,将MNIST原始数据转换为MindSpore数据格式。 +### 转换CSV数据集 -1. 准备MNIST数据集,将下载好的文件放至指定的目录,如下所示: +本示例首先创建一个包含5条记录的CSV文件,然后通过`CsvToMR`工具类将CSV文件转换为MindRecord,并最终通过`MindDataset`将其读取出来。 - ``` - % ll mnist_data/ - train-images-idx3-ubyte.gz - train-labels-idx1-ubyte.gz - t10k-images-idx3-ubyte.gz - t10k-labels-idx1-ubyte.gz - ``` +```python +import csv +import os +import mindspore.dataset as ds +from mindspore.mindrecord import CsvToMR - > MNIST数据集下载地址: +CSV_FILE_NAME = "test.csv" +MINDRECORD_FILE_NAME = "test.mindrecord" +PARTITION_NUM = 1 -2. 导入转换数据集的工具类`MnistToMR`。 +def generate_csv(): + headers = ["id", "name", "math", "english"] + rows = [(1, "Lily", 78.5, 90), + (2, "Lucy", 99, 85.2), + (3, "Mike", 65, 71), + (4, "Tom", 95, 99), + (5, "Jeff", 85, 78.5)] + with open(CSV_FILE_NAME, 'w', encoding='utf-8') as f: + writer = csv.writer(f) + writer.writerow(headers) + writer.writerows(rows) - ```python - from mindspore.mindrecord import MnistToMR - ``` +generate_csv() -3. 实例化`MnistToMR`对象,调用`transform`接口,将MNIST数据集转换为MindSpore数据格式。 +if os.path.exists(MINDRECORD_FILE_NAME): + os.remove(MINDRECORD_FILE_NAME) + os.remove(MINDRECORD_FILE_NAME + ".db") - ```python - MNIST_DIR = "./mnist_data" - MINDRECORD_FILE = "./mnist.mindrecord" - mnist_transformer = MnistToMR(MNIST_DIR, MINDRECORD_FILE) - mnist_transformer.transform() - ``` +csv_transformer = CsvToMR(CSV_FILE_NAME, MINDRECORD_FILE_NAME, partition_number=PARTITION_NUM) - ***参数说明:*** - - `MNIST_DIR`:MNIST数据集的文件夹路径。 - - `MINDRECORD_FILE`:输出的MindSpore数据格式文件路径。 +csv_transformer.transform() +assert os.path.exists(MINDRECORD_FILE_NAME) +assert os.path.exists(MINDRECORD_FILE_NAME + ".db") -### 转换CSV数据集 - - ```python - """ - 示例说明:本示例首先创建一个CSV文件,然后通过MindSpore中CsvToMR工具, - 将Csv文件转换为MindRecord文件,并最终通过MindDataset将其读取出来。 - 详细步骤: - 1. 创建一个包含5条记录的CSV文件; - 2. 使用CsvToMR工具将CSV转换为MindRecord; - 3. 使用MindDataset读取MindRecord文件。 - """ - - import csv - import os - import mindspore.dataset as ds - from mindspore.mindrecord import CsvToMR - - CSV_FILE_NAME = "test.csv" # 创建的CSV文件 - MINDRECORD_FILE_NAME = "test.mindrecord" # 转换后的MindRecord文件 - PARTITION_NUM = 1 - - ################################ 创建CSV文件 ################################ - - # 生成CSV文件 - def generate_csv(): - headers = ["id", "name", "math", "english"] - rows = [(1, "Lily", 78.5, 90), - (2, "Lucy", 99, 85.2), - (3, "Mike", 65, 71), - (4, "Tom", 95, 99), - (5, "Jeff", 85, 78.5)] - with open(CSV_FILE_NAME, 'w', encoding='utf-8') as f: - writer = csv.writer(f) - writer.writerow(headers) - writer.writerows(rows) - - generate_csv() - - if os.path.exists(MINDRECORD_FILE_NAME): - os.remove(MINDRECORD_FILE_NAME) - os.remove(MINDRECORD_FILE_NAME + ".db") - - ################################ CSV 转 MindRecord文件 ################################ - - # 调用CsvToMR工具,初始化 - csv_transformer = CsvToMR(CSV_FILE_NAME, MINDRECORD_FILE_NAME, partition_number=PARTITION_NUM) - # 执行转换操作 - csv_transformer.transform() - - assert os.path.exists(MINDRECORD_FILE_NAME) - assert os.path.exists(MINDRECORD_FILE_NAME + ".db") - - ############################### 读取MindRecord文件 ################################ - - data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) # 创建读取对象,默认开启shuffle - count = 0 - for item in data_set.create_dict_iterator(output_numpy=True): # 循环读取MindRecord中所有数据 - print("sample: {}".format(item)) - count += 1 - print("Got {} samples".format(count)) - ``` +data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) +count = 0 +for item in data_set.create_dict_iterator(): + print("sample: {}".format(item)) + count += 1 +print("Got {} samples".format(count)) +``` ### 转换TFRecord数据集 - ```python - """ - 示例说明:本示例通过TF创建一个TFRecord文件,然后通过MindSpore中TFRecordToMR工具, - 将TFRecord文件转换为MindRecord文件,并最终通过MindDataset将其读取出来。 - 详细步骤: - 1. 创建一个包含10条记录,且样本格式为: - feature_dict = {"file_name": tf.io.FixedLenFeature([], tf.string), - "image_bytes": tf.io.FixedLenFeature([], tf.string), - "int64_scalar": tf.io.FixedLenFeature([], tf.int64), - "float_scalar": tf.io.FixedLenFeature([], tf.float32), - "int64_list": tf.io.FixedLenFeature([6], tf.int64), - "float_list": tf.io.FixedLenFeature([7], tf.float32)} - 的TFRecord文件; - 2. 使用TFRecordToMR工具将TFRecord转换为MindRecord; - 3. 使用MindDataset读取MindRecord文件,并通过Decode算子对其image_bytes字段进行解码。 - """ - - import collections - from io import BytesIO - import os - import mindspore.dataset as ds - from mindspore.mindrecord import TFRecordToMR - import mindspore.dataset.vision.c_transforms as vision - from PIL import Image - import tensorflow as tf # 需要tensorflow >= 2.1.0 - - TFRECORD_FILE_NAME = "test.tfrecord" # 创建的TFRecord文件 - MINDRECORD_FILE_NAME = "test.mindrecord" # 转换后的MindRecord文件 - PARTITION_NUM = 1 - - ################################ 创建TFRecord文件 ################################ - - # 生成TFRecord文件 - def generate_tfrecord(): - def create_int_feature(values): - if isinstance(values, list): - feature = tf.train.Feature(int64_list=tf.train.Int64List(value=list(values))) # values: [int, int, int] - else: - feature = tf.train.Feature(int64_list=tf.train.Int64List(value=[values])) # values: int - return feature - - def create_float_feature(values): - if isinstance(values, list): - feature = tf.train.Feature(float_list=tf.train.FloatList(value=list(values))) # values: [float, float] - else: - feature = tf.train.Feature(float_list=tf.train.FloatList(value=[values])) # values: float - return feature - - def create_bytes_feature(values): - if isinstance(values, bytes): - white_io = BytesIO() - Image.new('RGB', (10, 10), (255, 255, 255)).save(white_io, 'JPEG') # 图片大小可以不同 - image_bytes = white_io.getvalue() - feature = tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes])) # values: bytes - else: - # values: string - feature = tf.train.Feature(bytes_list=tf.train.BytesList(value=[bytes(values, encoding='utf-8')])) - return feature - - writer = tf.io.TFRecordWriter(TFRECORD_FILE_NAME) - - example_count = 0 - for i in range(10): - file_name = "000" + str(i) + ".jpg" - image_bytes = bytes(str("aaaabbbbcccc" + str(i)), encoding="utf-8") - int64_scalar = i - float_scalar = float(i) - int64_list = [i, i+1, i+2, i+3, i+4, i+1234567890] - float_list = [float(i), float(i+1), float(i+2.8), float(i+3.2), - float(i+4.4), float(i+123456.9), float(i+98765432.1)] - - features = collections.OrderedDict() - features["file_name"] = create_bytes_feature(file_name) - features["image_bytes"] = create_bytes_feature(image_bytes) - features["int64_scalar"] = create_int_feature(int64_scalar) - features["float_scalar"] = create_float_feature(float_scalar) - features["int64_list"] = create_int_feature(int64_list) - features["float_list"] = create_float_feature(float_list) - - tf_example = tf.train.Example(features=tf.train.Features(feature=features)) - writer.write(tf_example.SerializeToString()) - example_count += 1 - writer.close() - print("Write {} rows in tfrecord.".format(example_count)) - - generate_tfrecord() - - ################################ TFRecord 转 MindRecord文件 ################################ - - feature_dict = {"file_name": tf.io.FixedLenFeature([], tf.string), - "image_bytes": tf.io.FixedLenFeature([], tf.string), - "int64_scalar": tf.io.FixedLenFeature([], tf.int64), - "float_scalar": tf.io.FixedLenFeature([], tf.float32), - "int64_list": tf.io.FixedLenFeature([6], tf.int64), - "float_list": tf.io.FixedLenFeature([7], tf.float32), - } - - if os.path.exists(MINDRECORD_FILE_NAME): - os.remove(MINDRECORD_FILE_NAME) - os.remove(MINDRECORD_FILE_NAME + ".db") - - # 调用TFRecordToMR工具,初始化 - tfrecord_transformer = TFRecordToMR(TFRECORD_FILE_NAME, MINDRECORD_FILE_NAME, feature_dict, ["image_bytes"]) - # 执行转换操作 - tfrecord_transformer.transform() - - assert os.path.exists(MINDRECORD_FILE_NAME) - assert os.path.exists(MINDRECORD_FILE_NAME + ".db") - - ############################### 读取MindRecord文件 ################################ - - data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) # 创建读取对象,默认开启shuffle - decode_op = vision.Decode() - data_set = data_set.map(operations=decode_op, input_columns=["image_bytes"], num_parallel_workers=2) # 解码图像字段 - count = 0 - for item in data_set.create_dict_iterator(output_numpy=True): # 循环读取MindRecord中所有数据 - print("sample: {}".format(item)) - count += 1 - print("Got {} samples".format(count)) - ``` +> 目前只支持TensorFlow 2.1.0及以上版本。 + +本示例首先通过TensorFlow创建一个TFRecord文件,然后通过`TFRecordToMR`工具类将TFRecord文件转换为MindRecord,最后通过`MindDataset`将其读取出来,并使用`Decode`算子对`image_bytes`字段进行解码。 + +```python +import collections +from io import BytesIO +import os +import mindspore.dataset as ds +from mindspore.mindrecord import TFRecordToMR +import mindspore.dataset.vision.c_transforms as vision +from PIL import Image +import tensorflow as tf + +TFRECORD_FILE_NAME = "test.tfrecord" +MINDRECORD_FILE_NAME = "test.mindrecord" +PARTITION_NUM = 1 + +def generate_tfrecord(): + def create_int_feature(values): + if isinstance(values, list): + feature = tf.train.Feature(int64_list=tf.train.Int64List(value=list(values))) + else: + feature = tf.train.Feature(int64_list=tf.train.Int64List(value=[values])) + return feature + + def create_float_feature(values): + if isinstance(values, list): + feature = tf.train.Feature(float_list=tf.train.FloatList(value=list(values))) + else: + feature = tf.train.Feature(float_list=tf.train.FloatList(value=[values])) + return feature + + def create_bytes_feature(values): + if isinstance(values, bytes): + white_io = BytesIO() + Image.new('RGB', (10, 10), (255, 255, 255)).save(white_io, 'JPEG') + image_bytes = white_io.getvalue() + feature = tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_bytes])) + else: + feature = tf.train.Feature(bytes_list=tf.train.BytesList(value=[bytes(values, encoding='utf-8')])) + return feature + + writer = tf.io.TFRecordWriter(TFRECORD_FILE_NAME) + + example_count = 0 + for i in range(10): + file_name = "000" + str(i) + ".jpg" + image_bytes = bytes(str("aaaabbbbcccc" + str(i)), encoding="utf-8") + int64_scalar = i + float_scalar = float(i) + int64_list = [i, i+1, i+2, i+3, i+4, i+1234567890] + float_list = [float(i), float(i+1), float(i+2.8), float(i+3.2), + float(i+4.4), float(i+123456.9), float(i+98765432.1)] + + features = collections.OrderedDict() + features["file_name"] = create_bytes_feature(file_name) + features["image_bytes"] = create_bytes_feature(image_bytes) + features["int64_scalar"] = create_int_feature(int64_scalar) + features["float_scalar"] = create_float_feature(float_scalar) + features["int64_list"] = create_int_feature(int64_list) + features["float_list"] = create_float_feature(float_list) + + tf_example = tf.train.Example(features=tf.train.Features(feature=features)) + writer.write(tf_example.SerializeToString()) + example_count += 1 + writer.close() + print("Write {} rows in tfrecord.".format(example_count)) + +generate_tfrecord() + +feature_dict = {"file_name": tf.io.FixedLenFeature([], tf.string), + "image_bytes": tf.io.FixedLenFeature([], tf.string), + "int64_scalar": tf.io.FixedLenFeature([], tf.int64), + "float_scalar": tf.io.FixedLenFeature([], tf.float32), + "int64_list": tf.io.FixedLenFeature([6], tf.int64), + "float_list": tf.io.FixedLenFeature([7], tf.float32), + } + +if os.path.exists(MINDRECORD_FILE_NAME): + os.remove(MINDRECORD_FILE_NAME) + os.remove(MINDRECORD_FILE_NAME + ".db") + +tfrecord_transformer = TFRecordToMR(TFRECORD_FILE_NAME, MINDRECORD_FILE_NAME, feature_dict, ["image_bytes"]) +tfrecord_transformer.transform() + +assert os.path.exists(MINDRECORD_FILE_NAME) +assert os.path.exists(MINDRECORD_FILE_NAME + ".db") + +data_set = ds.MindDataset(dataset_file=MINDRECORD_FILE_NAME) +decode_op = vision.Decode() +data_set = data_set.map(operations=decode_op, input_columns=["image_bytes"], num_parallel_workers=2) +count = 0 +for item in data_set.create_dict_iterator(): + print("sample: {}".format(item)) + count += 1 +print("Got {} samples".format(count)) +``` diff --git a/docs/programming_guide/source_zh_cn/dataset_loading.md b/docs/programming_guide/source_zh_cn/dataset_loading.md index 320b8300c5..1e39519c6a 100644 --- a/docs/programming_guide/source_zh_cn/dataset_loading.md +++ b/docs/programming_guide/source_zh_cn/dataset_loading.md @@ -4,8 +4,7 @@ - [数据集加载](#数据集加载) - [概述](#概述) - - [经典数据集加载](#经典数据集加载) - - [MNIST数据集](#mnist数据集) + - [常用数据集加载](#常用数据集加载) - [CIFAR10/100数据集](#cifar10100数据集) - [VOC数据集](#voc数据集) - [COCO数据集](#coco数据集) @@ -13,8 +12,7 @@ - [MindRecord数据格式](#mindrecord数据格式) - [Manifest数据格式](#manifest数据格式) - [TFRecord数据格式](#tfrecord数据格式) - - [Numpy数据格式](#numpy数据格式) - - [text数据格式](#text数据格式) + - [NumPy数据格式](#numpy数据格式) - [CSV数据格式](#csv数据格式) - [自定义数据集加载](#自定义数据集加载) - [构造数据集生成函数](#构造数据集生成函数) @@ -23,19 +21,19 @@ - + ## 概述 -MindSpore支持加载图像领域常用的经典数据集,用户可以直接使用`mindspore.dataset`中对应的类实现数据集的加载。目前支持的经典数据集及对应的数据集类如下表所示。 +MindSpore支持加载图像领域常用的数据集,用户可以直接使用`mindspore.dataset`中对应的类实现数据集的加载。目前支持的常用数据集及对应的数据集类如下表所示。 | 图像数据集 | 数据集类 | 数据集简介 | | ---- | ---- | ---- | | MNIST | MnistDataset | MNIST是一个大型手写数字图像数据集,拥有60,000张训练图像和10,000张测试图像,常用于训练各种图像处理系统。 | | CIFAR-10 | Cifar10Dataset | CIFAR-10是一个微小图像数据集,包含10种类别下的60,000张32x32大小彩色图像,平均每种类别6,000张,其中5,000张为训练集,1,000张为测试集。 | | CIFAR-100 | Cifar100Dataset | CIFAR-100与CIFAR-10类似,但拥有100种类别,平均每种类别600张,其中500张为训练集,100张为测试集。 | -|CelebA | CelebADataset | CelebA是一个大型人脸图像数据集,包含超过200,000张名人人脸图像,每张图像拥有40个特征标记。 | -| PASCAL-VOC | VOCDataset | PASCAL-VOC是一个经典图像数据集,被广泛用于目标检测、图像分割等计算机视觉领域。 | +| CelebA | CelebADataset | CelebA是一个大型人脸图像数据集,包含超过200,000张名人人脸图像,每张图像拥有40个特征标记。 | +| PASCAL-VOC | VOCDataset | PASCAL-VOC是一个常用图像数据集,被广泛用于目标检测、图像分割等计算机视觉领域。 | | COCO | CocoDataset | COCO是一个大型目标检测、图像分割、姿态估计数据集。 | | CLUE | CLUEDataset | CLUE是一个大型中文语义理解数据集。 | @@ -45,65 +43,39 @@ MindSpore还支持加载多种数据存储格式下的数据集,用户可以 | ---- | ---- | ---- | | MindRecord | MindDataset | MindRecord是MindSpore的自研数据格式,具有读写高效、易于分布式处理等优势。 | | Manifest | ManifestDataset | Manifest是华为ModelArts支持的一种数据格式,描述了原始文件和标注信息,可用于标注、训练、推理场景。 | -| TFRecord | TFRecordDataset | TFRecord是Tensorflow定义的一种二进制数据文件格式。 | -| Numpy | NumpySlicesDataset | Numpy数据源指的是已经读入内存中的Numpy arrays格式数据集。 | +| TFRecord | TFRecordDataset | TFRecord是TensorFlow定义的一种二进制数据文件格式。 | +| NumPy | NumpySlicesDataset | NumPy数据源指的是已经读入内存中的NumPy arrays格式数据集。 | | Text File | TextFileDataset | Text File指的是常见的文本格式数据。 | | CSV File | CSVDataset | CSV指逗号分隔值,其文件以纯文本形式存储表格数据。 | -MindSpore也同样支持使用GeneratorDataset自定义数据集的加载方式,用户可以根据需要实现自己的数据集类。 +MindSpore也同样支持使用`GeneratorDataset`自定义数据集的加载方式,用户可以根据需要实现自己的数据集类。 -更多详细的数据集加载接口说明,参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)。 +> 更多详细的数据集加载接口说明,参见[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)。 -## 经典数据集加载 +## 常用数据集加载 -### MNIST数据集 +下面将介绍几种常用数据集的加载方式。 -```python -# 通过MNIST API读取、解析MNIST数据集,并构建数据管道 - -import mindspore.dataset as ds - -# 下载MNIST数据集,将其解压到MnistData目录 -DATA_DIR = "MnistData/" - -# 使用MnistDataset读取数据集,指定num_samples以获取5个样本数据 -# shuffle参数为True时,是随机获取5个样本,每次运行的label结果可能不一致 -dataset = ds.MnistDataset(DATA_DIR, num_samples=5, shuffle=True) - -# 启动数据管道,输出5个样本数据 -for data in dataset.create_dict_iterator(): - print("Image shape:", data['image'].shape, ", Label:", data['label']) -``` +### CIFAR10/100数据集 -``` -Image shape: (28, 28, 1) , Label: 4 -Image shape: (28, 28, 1) , Label: 9 -Image shape: (28, 28, 1) , Label: 4 -Image shape: (28, 28, 1) , Label: 0 -Image shape: (28, 28, 1) , Label: 9 -``` +下面的样例通过`Cifar10Dataset`接口加载CIFAR-10数据集,使用顺序采样器获取其中5个样本,然后展示了对应图片的形状和标签。 -### CIFAR10/100数据集 +CIFAR-100数据集和MNIST数据集的加载方式也与之类似。 ```python -# 通过Cifar API读取、解析CIFAR数据集,并构建数据管道(以CIFAR10数据集为例) - import mindspore.dataset as ds -# 下载CIFAR10数据集,将其解压到CIFAR10Data目录 DATA_DIR = "Cifar10Data/" -# 指定一个顺序采样器SequentialSampler,按照读取顺序获取5个样本数据 sampler = ds.SequentialSampler(num_samples=5) - -# 使用CIFAR10Dataset读取数据集,指定sampler为上述采样器 dataset = ds.Cifar10Dataset(DATA_DIR, sampler=sampler) -# 启动数据管道,输出5个样本数据 for data in dataset.create_dict_iterator(): print("Image shape:", data['image'].shape, ", Label:", data['label']) ``` +输出结果如下: + ``` Image shape: (32, 32, 3) , Label: 0 Image shape: (32, 32, 3) , Label: 1 @@ -114,34 +86,30 @@ Image shape: (32, 32, 3) , Label: 4 ### VOC数据集 -```python -# 通过VOC API读取、解析VOC数据集,并构建数据管道 +下面的样例通过`VOCDataset`接口加载VOC2012数据集,分别演示了将任务指定为分割(Segmentation)和检测(Detection)时的原始图像形状和目标形状。 +```python import mindspore.dataset as ds -# 下载VOC数据集,将其解压到VOC2012目录 DATA_DIR = "VOC2012/" -# 使用VOCDataset读取数据集,指定为Segmentation任务,同时指定num_samples以获取2个样本数据 -# decode参数会将读取的图像解码 -dataset = ds.VOCDataset(DATA_DIR, task="Segmentation", mode="train", num_samples=2, decode=True, shuffle=False) +dataset = ds.VOCDataset(DATA_DIR, task="Segmentation", usage="train", num_samples=2, decode=True, shuffle=False) + print("[Segmentation]:") for data in dataset.create_dict_iterator(): - # 原图像 print("image shape:", data["image"].shape) - # 分割后图像 print("target shape:", data["target"].shape) -# 接下来是Detection任务 -dataset = ds.VOCDataset(DATA_DIR, task="Detection", mode="train", num_samples=1, decode=True, shuffle=False) +dataset = ds.VOCDataset(DATA_DIR, task="Detection", usage="train", num_samples=1, decode=True, shuffle=False) + print("[Detection]:") for data in dataset.create_dict_iterator(): - # 原图像 print("image shape:", data["image"].shape) - # 目标框 print("bbox shape:", data["bbox"].shape) ``` +输出结果如下: + ``` [Segmentation]: image shape: (281, 500, 3) @@ -155,39 +123,35 @@ bbox shape: (2, 4) ### COCO数据集 -```python -# 通过Coco API读取、解析Coco数据集,并构建数据管道 +下面的样例通过`CocoDataset`接口加载COCO数据集,分别演示了将任务指定为目标检测(Detection)、背景分割(Stuff)、关键点检测(Keypoint)和全景分割(Panoptic)时获取到的不同数据。 +```python import mindspore.dataset as ds -# 下载Coco数据集,将其解压到CocoData目录 DATA_DIR = "COCO/train/" ANNOTATION_FILE = "COCO/annotations/train.json" KEYPOINT_FILE = "COCO/annotations/key_point.json" PANOPTIC_FILE = "COCO/annotations/panoptic.json" -# 使用CocoDataset读取数据集,指定为Detection任务,同时指定num_samples以获取1个样本数据 dataset = ds.CocoDataset(DATA_DIR, annotation_file=ANNOTATION_FILE, task="Detection", num_samples=1) for data in dataset.create_dict_iterator(): print("Detection:", data.keys()) -# 让我们来观察一下,在指定Coco不同任务时,我们获取到的不同数据 -# Stuff 任务 dataset = ds.CocoDataset(DATA_DIR, annotation_file=ANNOTATION_FILE, task="Stuff", num_samples=1) for data in dataset.create_dict_iterator(): print("Stuff:", data.keys()) -# Keypoint 任务 dataset = ds.CocoDataset(DATA_DIR, annotation_file=KEYPOINT_FILE, task="Keypoint", num_samples=1) for data in dataset.create_dict_iterator(): print("Keypoint:", data.keys()) -# Panoptic 任务 dataset = ds.CocoDataset(DATA_DIR, annotation_file=PANOPTIC_FILE, task="Panoptic", num_samples=1) for data in dataset.create_dict_iterator(): print("Panoptic:", data.keys()) ``` +输出结果如下: + ``` Detection: dict_keys(['bbox', 'image', 'iscrowd', 'category_id']) Stuff: dict_keys(['segmentation', 'iscrowd', 'image']) @@ -195,49 +159,51 @@ Keypoint: dict_keys(['keypoints', 'num_keypoints', 'image']) Panoptic: dict_keys(['bbox', 'image', 'area', 'category_id', 'iscrowd']) ``` -> 更多经典数据集加载接口说明,参见对应[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)。 - ## 特定格式数据集加载 +下面将介绍几种特定格式数据集文件的加载方式。 + ### MindRecord数据格式 -MindRecord是MindSpore的自研数据格式,具有更好的性能和特性。 +MindRecord是MindSpore定义的一种数据格式,使用MindRecord能够获得更好的性能提升。 ->阅读[数据格式转换](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dataset_conversion.html)章节,了解如何将数据集转化为MindSpore数据格式。 +> 阅读[数据格式转换](https://www.mindspore.cn/api/zh-CN/master/programming_guide/dataset_conversion.html)章节,了解如何将数据集转化为MindSpore数据格式。 + +下面的样例通过`MindDataset`接口加载MindRecord文件,并展示已加载数据的标签。 ```python import mindspore.dataset as ds -# 指定MindRecord数据格式地址 DATA_DIR = "mindrecord_dataset_path" mindrecord_dataset = ds.MindDataset(DATA_DIR) -# 启动数据管道读取 for data in mindrecord_dataset.create_dict_iterator(output_numpy=True): print(data["label"]) ``` ### Manifest数据格式 -Manifest是华为ModelArts支持的数据格式文件,详细说明请参见相关[文档](https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0009.html)。 +Manifest是华为ModelArts支持的数据格式文件,详细说明请参见[Manifest文档](https://support.huaweicloud.com/engineers-modelarts/modelarts_23_0009.html)。 + +下面的样例通过`ManifestDataset`接口加载Manifest文件,并展示已加载数据的标签。 ```python import mindspore.dataset as ds -# 指定Manifest数据集地址 DATA_DIR = "manifest_dataset_path" manifest_dataset = ds.ManifestDataset(DATA_DIR) -# 启动数据管道读取 for data in manifest_dataset.create_dict_iterator(): print(data["label"]) ``` ### TFRecord数据格式 -TFRecord是Tensorflow定义的一种二进制数据文件格式。 +TFRecord是TensorFlow定义的一种二进制数据文件格式。 -1. 传入数据集路径或`.tfrecord`文件列表,创建TFRecordDataset对象。 +下面的样例通过`TFRecordDataset`接口加载TFRecord文件,并介绍了两种不同的数据集格式设定方案。 + +1. 传入数据集路径或TFRecord文件列表,创建`TFRecordDataset`对象。 ```python import mindspore.dataset as ds @@ -246,77 +212,76 @@ TFRecord是Tensorflow定义的一种二进制数据文件格式。 dataset = ds.TFRecordDataset(DATA_DIR) ``` -2. 用户可以选择通过创建Schema文件或Schema类,设定数据集格式及特征。 - - - 创建Schema文件 - - Schema文件示例: - - ``` - { - "datasetType": "TF", - "numRows": 3, - "columns": { - "image": { - "type": "uint8", - "rank": 1 - }, - "label" : { - "type": "int64", - "rank": 1 +2. 用户可以通过编写Schema文件或创建Schema对象,设定数据集格式及特征。 + + - 编写Schema文件 + + 将数据集格式和特征按JSON格式写入Schema文件,示例如下: + + ``` + { + "datasetType": "TF", + "numRows": 3, + "columns": { + "image": { + "type": "uint8", + "rank": 1 + }, + "label" : { + "type": "int64", + "rank": 1 + } } } - } - ``` - - - `datasetType`: 数据格式的类型,这里`TF`是指TFrecord数据格式。 + ``` + - `datasetType`: 数据格式的类型,这里`TF`是指TFRecord数据格式。 - `columns`:列信息字段,需要根据数据集的实际列名定义,上面Schema文件示例中,数据集列为`image`和`label`两列。 - - `numRows`:行数信息字段,控制加载数据的最大行数。如果定义的行数大于实际行数,加载时则以实际行数为准。 - 在创建TFRecordDataset时将Schema文件路径传入。 + 然后在创建`TFRecordDataset`时将Schema文件路径传入。 - ```python - DATA_DIR = "tfrecord_dataset_path" - SCHEMA_DIR = "dataset_schema_path/schema.json" - dataset = ds.TFRecordDataset(DATA_DIR, schema=SCHEMA_DIR) - ``` + ```python + DATA_DIR = "tfrecord_dataset_path" + SCHEMA_DIR = "dataset_schema_path/schema.json" + dataset = ds.TFRecordDataset(DATA_DIR, schema=SCHEMA_DIR) + ``` - - 创建Schema类 + - 创建Schema对象 - ```python - import mindspore.common.dtype as mstype - schema = ds.Schema() - schema.add_column('image', de_type=mstype.uint8) - schema.add_column('label', de_type=mstype.int32) - dataset = ds.TFRecordDataset(DATA_DIR, schema=schema) - ``` + 创建Schema对象,为其添加自定义字段,然后在创建数据集对象时传入。 -### Numpy数据格式 + ```python + import mindspore.common.dtype as mstype + schema = ds.Schema() + schema.add_column('image', de_type=mstype.uint8) + schema.add_column('label', de_type=mstype.int32) + dataset = ds.TFRecordDataset(DATA_DIR, schema=schema) + ``` -如果所有数据已经读入内存,可以直接使用NumpySlicesDataset类将其加载。 +### NumPy数据格式 -- 加载Numpy arrays数据 +如果所有数据已经读入内存,可以直接使用`NumpySlicesDataset`类将其加载。 - ```python - # 从Numpy arrays构建数据管道 +下面的样例分别介绍了通过`NumpySlicesDataset`加载arrays数据、 list数据和dict数据的方式。 +- 加载NumPy arrays数据 + + ```python import numpy as np import mindspore.dataset as ds - # 使用numpy构建一个数组 features, labels = np.random.sample((5, 2)), np.random.sample((5, 1)) - # 从numpy中构建数据管道 - # 注意:传入参数需要是一个tuple,即是(features, labels);column_names用于指定生成的数据集名称为col1, col2 + data = (features, labels) dataset = ds.NumpySlicesDataset(data, column_names=["col1", "col2"], shuffle=False) - # 启动数据管道 for data in dataset: print(data[0], " ", data[1]) ``` + 输出结果如下: + ``` [0.49893939 0.36348882] [0.15234002] [0.83845534 0.19721032] [0.94602561] @@ -328,22 +293,19 @@ TFRecord是Tensorflow定义的一种二进制数据文件格式。 - 加载Python list数据 ```python - # 从Python list构建数据管道 import mindspore.dataset as ds - # 构建一个list data1 = [[1, 2], [3, 4]] - # 从list中构建数据管道 - # column_names用于指定生成的数据集名称为col1 dataset = ds.NumpySlicesDataset(data1, column_names=["col1"], shuffle=False) - # 启动数据管道 for data in dataset: print(data[0]) ``` + 输出结果如下: + ``` [1 2] [3 4] @@ -352,60 +314,42 @@ TFRecord是Tensorflow定义的一种二进制数据文件格式。 - 加载Python dict数据 ```python - # 从Python dict构建数据管道 - import mindspore.dataset as ds - # 构建一个dict data1 = {"a": [1, 2], "b": [3, 4]} - # 从dict中构建数据管道 - # column_names用于指定生成的数据集名称为col1, col2 dataset = ds.NumpySlicesDataset(data1, column_names=["col1", "col2"], shuffle=False) - # 启动数据管道 for data in dataset.create_dict_iterator(): print(data) ``` + 输出结果如下: + ``` {'col1': Tensor(shape=[], dtype=Int64, value= 1), 'col2': Tensor(shape=[], dtype=Int64, value= 3)} {'col1': Tensor(shape=[], dtype=Int64, value= 2), 'col2': Tensor(shape=[], dtype=Int64, value= 4)} ``` -### text数据格式 - -```python -import mindspore.dataset as ds +### CSV数据格式 -# 指定text数据格式地址 -DATA_DIR = "text_file_path" -text_dataset = ds.TextFileDataset(DATA_DIR) +下面的样例通过`CSVDataset`加载CSV格式数据集文件,并展示了已加载数据的标签。 -# 启动数据管道读取 -for data in text_dataset.create_dict_iterator(output_numpy=True): - print(data["label"]) -``` - -### CSV数据格式 +Text格式数据集文件的加载方式与CSV文件类似。 ```python import mindspore.dataset as ds -# 指定CSV数据格式地址 DATA_DIR = "csv_file_path" csv_dataset = ds.CSVDataset(DATA_DIR) -# 启动数据管道读取 for data in csv_dataset.create_dict_iterator(output_numpy=True): - print(data["label"]) + print(data["1"]) ``` ->更多数据格式文件加载说明,参见对应[API文档](https://www.mindspore.cn/api/zh-CN/master/api/python/mindspore/mindspore.dataset.html)。 - ## 自定义数据集加载 -对于目前MindSpore不支持直接加载的数据集,可以通过构造GeneratorDataset对象实现自定义方式的加载,或者将其转换成MindRecord数据格式。目前自定义数据集加载有以下几种方式。 +对于目前MindSpore不支持直接加载的数据集,可以通过构造`GeneratorDataset`对象实现自定义方式的加载,或者将其转换成MindRecord数据格式。目前自定义数据集加载有以下几种方式。 ### 构造数据集生成函数 @@ -415,23 +359,22 @@ for data in csv_dataset.create_dict_iterator(output_numpy=True): import numpy as np import mindspore.dataset as ds -# 随机生成一个数据集 np.random.seed(58) data = np.random.sample((5, 2)) label = np.random.sample((5, 1)) -# 自定义数据返回方式 def GeneratorFunc(): for i in range(5): yield (data[i], label[i]) -# 构建自定义数据集对象 dataset = ds.GeneratorDataset(GeneratorFunc, ["data", "label"]) for data in dataset.create_dict_iterator(): print(data["data"], data["label"]) ``` +输出结果如下: + ``` [0.36510558 0.45120592] [0.78888122] [0.49606035 0.07562207] [0.38068183] @@ -476,6 +419,8 @@ for data in dataset.create_dict_iterator(): print(data["data"], data["label"]) ``` +输出结果如下: + ``` [0.36510558 0.45120592] [0.78888122] [0.49606035 0.07562207] [0.38068183] @@ -511,6 +456,8 @@ for data in dataset.create_dict_iterator(): print(data["data"], data["label"]) ``` +输出结果如下: + ``` [0.36510558 0.45120592] [0.78888122] [0.49606035 0.07562207] [0.38068183] @@ -549,6 +496,8 @@ for data in dataset.create_dict_iterator(): print(data["data"], data["label"]) ``` +输出结果如下: + ``` [0.36510558 0.45120592] [0.78888122] [0.57176158 0.28963401] [0.16271622] diff --git a/docs/programming_guide/source_zh_cn/dtype.md b/docs/programming_guide/source_zh_cn/dtype.md new file mode 100644 index 0000000000..0b5e9245c9 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/dtype.md @@ -0,0 +1,64 @@ +# dtype + + + +- [dtype](#dtype) + - [概述](#概述) + - [数据类型转换接口](#数据类型转换接口) + + + + + +## 概述 + +MindSpore张量支持不同的数据类型,包含`int8`、`int16`、`int32`、`int64`、`uint8`、`uint16`、`uint32`、`uint64`、`float16`、`float32`、`float64`、`bool_`,与NumPy的数据类型一一对应。 + +在MindSpore的运算处理流程中,Python中的`int`数会被转换为定义的int64类型,`float`数会被转换为定义的`float32`类型。 + +详细的类型支持情况请参考。 + +以下代码,打印MindSpore的数据类型int32。 +``` +from mindspore import dtype as mstype + +data_type = mstype.int32 +print(data_type) +``` + +输出如下: + +``` +Int32 +``` + + +## 数据类型转换接口 + +MindSpore提供了以下几个接口,实现与NumPy数据类型和Python内置的数据类型间的转换。 + +- `dtype_to_nptype`:将MindSpore的数据类型转换为NumPy对应的数据类型。 +- `dtype_to_pytype`:将MindSpore的数据类型转换为Python对应的内置数据类型。 +- `pytype_to_dtype`:将Python内置的数据类型转换为MindSpore对应的数据类型。 + +以下代码实现了不同数据类型间的转换,并打印转换后的类型。 + +``` +from mindspore import dtype as mstype + +np_type = mstype.dtype_to_nptype(mstype.int32) +ms_type = mstype.pytype_to_dtype(int) +py_type = mstype.dtype_to_pytype(mstype.float64) + +print(np_type) +print(ms_type) +print(py_type) +``` + +输出如下: + +``` + +Int64 + +``` diff --git a/docs/programming_guide/source_zh_cn/execution_management.rst b/docs/programming_guide/source_zh_cn/execution_management.rst new file mode 100644 index 0000000000..b57742c1c7 --- /dev/null +++ b/docs/programming_guide/source_zh_cn/execution_management.rst @@ -0,0 +1,9 @@ +执行管理 +=========== + +.. toctree:: + :maxdepth: 1 + + context + run + callback \ No newline at end of file diff --git a/docs/programming_guide/source_zh_cn/images/batch.png b/docs/programming_guide/source_zh_cn/images/batch.png index cce0f467eac154d0633543e5c69613ce7bdbbdcc..ee974652d361b4085033a08789a036d331c2bec8 100644 GIT binary patch literal 12224 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 X&cxu6_y4MIvgtoD(MD;#c>8|=S}M)O diff --git a/docs/programming_guide/source_zh_cn/images/concat.png b/docs/programming_guide/source_zh_cn/images/concat.png index 742aa2a0203f078ee7d06549c3372ce271cea455..7a28ff7826cc2a1c6334e2ff15eeaaffd6b67c06 100644 GIT binary patch literal 13809 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 RZ@>wNy0V5+fr3TA{{xe(!yo_v literal 24282 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 Jm2V9K{tK|z7~B8= literal 146960 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 ESXi0T`BsE0P`??&XhYZ9&L1+l7Ef-?_P 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

    Cb6 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 z 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 QJs0P>Zi+IgHS&!AA20U->Hq)$ literal 0 HcmV?d00001 diff --git a/docs/note/source_en/object_detection.md b/docs/note/source_en/object_detection.md new file mode 100644 index 0000000000..fbd7b794f0 --- /dev/null +++ b/docs/note/source_en/object_detection.md @@ -0,0 +1,29 @@ +# Object detection + + + +## Object dectectin introduction + +Object detection can identify the object in the image and its position in the image. For the following figure, the output of the object detection model is shown in the following table. The rectangular box is used to identify the position of the object in the graph and the probability of the object category is marked. The four numbers in the coordinates are Xmin, Ymin, Xmax, Ymax; the probability represents the probility of the detected object. + +![object_detectiontion](images/object_detection.png) + +| Category | Probability | Coordinate | +| -------- | ----------- | ---------------- | +| mouse | 0.78 | [10, 25, 35, 43] | + +Using MindSpore Lite to implement object detection [example](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/lite/object_detection). + +## Object detection model list + +The following table shows the data of some object detection models using MindSpore Lite inference. + +> The performance of the table below is tested on the mate30. + +| model name | link | size | precision | CPU 4 thread delay | +|-----------------------|----------|----------|----------|-----------| +| SSD | | | | | +| Faster_RCNN | | | | | +| Yolov3_Darknet | | | | | +| Mask_RCNN | | | | | + diff --git a/docs/note/source_zh_cn/image_classification.md b/docs/note/source_zh_cn/image_classification.md new file mode 100644 index 0000000000..147ce0f851 --- /dev/null +++ b/docs/note/source_zh_cn/image_classification.md @@ -0,0 +1,33 @@ +# 图像分类 + + + +## 图像分类介绍 + +图像分类模型可以预测图片中出现哪些物体,识别出图片中出现物体列表及其概率。 比如下图经过模型推理的分类结果为下表: + +![image_classification](images/image_classification_result.png) + +| 类别 | 概率 | +| ---------- | ------ | +| plant | 0.9359 | +| flower | 0.8641 | +| tree | 0.8584 | +| houseplant | 0.7867 | + +使用MindSpore Lite实现图像分类的[示例代码](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/lite/image_classification)。 + +## 图像分类模型列表 + +下表是使用MindSpore Lite推理的部分图像分类模型的数据。 + +> 下表的性能是在mate30手机上测试的。 + +| 模型名称 | 模型链接 | 大小 | 精度 | CPU 4线程时延 | +|-----------------------|----------|----------|----------|-----------| +| MobileNetV2 | | | | | +| LeNet | | | | | +| AlexNet | | | | | +| GoogleNet | | | | | +| ResNext50 | | | | | + diff --git a/docs/note/source_zh_cn/images/image_classification_result.png b/docs/note/source_zh_cn/images/image_classification_result.png new file mode 100644 index 0000000000000000000000000000000000000000..a7cc49f582440e31b6b5b14dbba5131bfed2a4b4 GIT binary patch literal 338804 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%0DSdJHt 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 z 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┓`DxKnX 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