diff --git a/README.md b/README.md index 8c2f13d21ee608a147c640a8b9eced3e0a3e5e2c..79b1656fdafaefffd32caeeefcac80fb86be35f0 100644 --- a/README.md +++ b/README.md @@ -33,16 +33,13 @@ In order to facilitate developers to enjoy the benefits of MindSpore framework, | Computer Vision (CV) | Image Classification | [InceptionV3](https://gitee.com/mindspore/models/tree/master/official/cv/inceptionv3) | 鉁� | | | | Computer Vision (CV) | Image Classification | [InceptionV4](https://gitee.com/mindspore/models/tree/master/official/cv/inceptionv4) | 鉁� | | | | Computer Vision (CV) | Image Classification | [LeNet](https://gitee.com/mindspore/models/tree/master/official/cv/lenet) | 鉁� | 鉁� | 鉁� | -| Computer Vision (CV) | Image Classification | [LeNet (Quantization)](https://gitee.com/mindspore/models/tree/master/official/cv/lenet_quant) | 鉁� | 鉁� | | | Computer Vision (CV) | Image Classification | [MobileNetV1](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv1) | 鉁� | | | | Computer Vision (CV) | Image Classification | [MobileNetV2](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv2) | 鉁� | 鉁� | 鉁� | -| Computer Vision (CV) | Image Classification | [MobileNetV2 (Quantization)](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv2_quant) | 鉁� | 鉁� | | | Computer Vision (CV) | Image Classification | [MobileNetV3](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv3) | | 鉁� | | | Computer Vision (CV) | Image Classification | [NASNet](https://gitee.com/mindspore/models/tree/master/official/cv/nasnet) | 鉁� | 鉁� | | | Computer Vision (CV) | Image Classification | [ResNet-18](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | | | | Computer Vision (CV) | Image Classification | [ResNet-34](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | | | | Computer Vision (CV) | Image Classification | [ResNet-50](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | 鉁� | 鉁� | -| Computer Vision (CV) | Image Classification | [ResNet-50 (Quantization)](https://gitee.com/mindspore/models/tree/master/official/cv/resnet50_quant) | 鉁� | | | |Computer Vision (CV) | Image Classification | [ResNet-101](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | 鉁� | | |Computer Vision (CV) | Image Classification | [ResNet-152](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | | | |Computer Vision (CV) | Image Classification | [ResNeXt50](https://gitee.com/mindspore/models/tree/master/official/cv/resnext) | 鉁� | 鉁� | | @@ -71,7 +68,6 @@ In order to facilitate developers to enjoy the benefits of MindSpore framework, | Computer Vision (CV) | Object Detection | [WarpCTC](https://gitee.com/mindspore/models/tree/master/official/cv/warpctc) | 鉁� | 鉁� | | | Computer Vision (CV) | Object Detection | [YOLOv3-ResNet18](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_resnet18) | 鉁� | | | | Computer Vision (CV) | Object Detection | [YOLOv3-DarkNet53](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_darknet53) | 鉁� | 鉁� | | -| Computer Vision (CV) | Object Detection | [YOLOv3-DarkNet53 (Quantization)](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_darknet53_quant) | 鉁� | | | | Computer Vision (CV) | Object Detection | [YOLOv4](https://gitee.com/mindspore/models/tree/master/official/cv/yolov4) | 鉁� | | | | Computer Vision (CV) | Object Detection |[YOLOv5](https://gitee.com/mindspore/models/tree/master/official/cv/yolov5) | 鉁� | | | | Computer Vision (CV) | Object Detection |[RetinaNet](https://gitee.com/mindspore/models/tree/master/official/cv/retinanet) | 鉁� | | | diff --git a/README_CN.md b/README_CN.md index c3dbe829c9cfb593f10dc02c5a79b7da11a17faa..b8004854221af9cf8d36e09dd62e6e6fb9a63fe9 100644 --- a/README_CN.md +++ b/README_CN.md @@ -33,16 +33,13 @@ | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [InceptionV3](https://gitee.com/mindspore/models/tree/master/official/cv/inceptionv3) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [InceptionV4](https://gitee.com/mindspore/models/tree/master/official/cv/inceptionv4) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [LeNet](https://gitee.com/mindspore/models/tree/master/official/cv/lenet) | 鉁� | 鉁� | 鉁� | -| 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [LeNet锛堥噺鍖栵級](https://gitee.com/mindspore/models/tree/master/official/cv/lenet_quant) | 鉁� | 鉁� | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [MobileNetV1](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv1) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [MobileNetV2](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv2) | 鉁� | 鉁� | 鉁� | -| 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [MobileNetV2锛堥噺鍖栵級](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv2_quant) | 鉁� | 鉁� | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [MobileNetV3](https://gitee.com/mindspore/models/tree/master/official/cv/mobilenetv3) | | 鉁� | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [NASNet](https://gitee.com/mindspore/models/tree/master/official/cv/nasnet) | 鉁� | 鉁� | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNet-18](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNet-34](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNet-50](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | 鉁� | 鉁� | -| 璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNet-50锛堥噺鍖栵級](https://gitee.com/mindspore/models/tree/master/official/cv/resnet50_quant) | 鉁� | | | |璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNet-101](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | 鉁� | | |璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNet-152](https://gitee.com/mindspore/models/tree/master/official/cv/resnet) | 鉁� | | | |璁$畻鏈鸿瑙夛紙CV锛� | 鍥惧儚鍒嗙被锛圛mage Classification锛� | [ResNeXt50](https://gitee.com/mindspore/models/tree/master/official/cv/resnext) | 鉁� | 鉁� | | @@ -71,7 +68,6 @@ | 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� | [WarpCTC](https://gitee.com/mindspore/models/tree/master/official/cv/warpctc) | 鉁� | 鉁� | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� | [YOLOv3-ResNet18](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_resnet18) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� | [YOLOv3-DarkNet53](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_darknet53) | 鉁� | 鉁� | | -| 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� | [YOLOv3-DarkNet53锛堥噺鍖栵級](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_darknet53_quant) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� |[YOLOv4](https://gitee.com/mindspore/models/tree/master/official/cv/yolov4) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� |[YOLOv5](https://gitee.com/mindspore/models/tree/master/official/cv/yolov5) | 鉁� | | | | 璁$畻鏈鸿瑙夛紙CV锛� | 鐩爣妫€娴嬶紙Object Detection锛� |[RetinaNet](https://gitee.com/mindspore/models/tree/master/official/cv/retinanet) | 鉁� | | | diff --git a/official/cv/lenet_quant/Readme.md b/official/cv/lenet_quant/Readme.md deleted file mode 100644 index 787cc7ea58540932eddafa8577698e3c38f44aa8..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/Readme.md +++ /dev/null @@ -1,229 +0,0 @@ -# Contents - -- [Contents](#contents) - - [LeNet Description](#lenet-description) - - [Model Architecture](#model-architecture) - - [Dataset](#dataset) - - [Environment Requirements](#environment-requirements) - - [Quick Start](#quick-start) - - [Script Description](#script-description) - - [Script and Sample Code](#script-and-sample-code) - - [Script Parameters](#script-parameters) - - [Training Process](#training-process) - - [Training](#training) - - [Evaluation Process](#evaluation-process) - - [Evaluation](#evaluation) - - [Model Export](#model-export) - - [Ascend 310 inference](#ascend-310-inference) - - [Model Description](#model-description) - - [Performance](#performance) - - [Evaluation Performance](#evaluation-performance) - - [Description of Random Situation](#description-of-random-situation) - - [ModelZoo Homepage](#modelzoo-homepage) - -## [LeNet_Quant Description](#contents) - -LeNet was proposed in 1998, a typical convolutional neural network. It was used for digit recognition and got big success. - -[Paper](https://ieeexplore.ieee.org/document/726791): Y.Lecun, L.Bottou, Y.Bengio, P.Haffner. Gradient-Based Learning Applied to Document Recognition. *Proceedings of the IEEE*. 1998. - -This is the quantitative network of LeNet. - -## [Model Architecture](#contents) - -LeNet is very simple, which contains 5 layers. The layer composition consists of 2 convolutional layers and 3 fully connected layers. - -## [Dataset](#contents) - -Dataset used: [MNIST](<http://yann.lecun.com/exdb/mnist/>) - -- Dataset size 52.4M 60,000 28*28 in 10 classes - - Train 60,000 images - - Test 10,000 images -- Data format binary files - - Note Data will be processed in dataset.py - -- The directory structure is as follows: - -```bash -鈹斺攢Data - 鈹溾攢test - 鈹� t10k-images.idx3-ubyte - 鈹� t10k-labels.idx1-ubyte - 鈹� - 鈹斺攢train - train-images.idx3-ubyte - train-labels.idx1-ubyte -``` - -## [Environment Requirements](#contents) - -- Hardware:Ascend - - Prepare hardware environment with Ascend -- Framework - - [MindSpore](https://www.mindspore.cn/install/en) -- For more information, please check the resources below锛� - - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/en/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/en/master/index.html) - -## [Quick Start](#contents) - -After installing MindSpore via the official website, you can start training and evaluation as follows: - -```python -# enter ../lenet/scripts/ directory and train lenet network,then a '.ckpt' file will be generated. -bash run_standalone_train_ascend.sh [DATA_PATH] [CKPT_PATH] -# example: bash run_standalone_train_ascend.sh /home/DataSet/MNIST/ ./ckpt/ - -# enter lenet_quant dir, train lenet_quant -python train_quant_.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_PATH] -# example: python train_quant.py --device_target=Ascend --data_path=/home/DataSet/MNIST/ --ckpt_path=/home/model/lenet/checkpoint_lenet-10_1875.ckpt - -#evaluate LeNet-Quant -python eval_quant.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_PATH] -# example: python eval_quant.py --device_target=Ascend --data_path=/home/DataSet/MNIST/ --ckpt_path=/home/model/lenet_quant/checkpoint_lenet-10_937.ckpt -``` - -## [Script Description](#contents) - -## [Script and Sample Code](#contents) - -```lenet_quant -鈹溾攢鈹€ model_zoo - 鈹溾攢鈹€ README.md // descriptions about the model - 鈹溾攢鈹€ README_CN.md // descriptions about the model - 鈹溾攢鈹€ lenet_quant - 鈹溾攢鈹€ README.md // descriptions about LeNet-Quant - 鈹溾攢鈹€ README_CN.md // descriptions about LeNet-Quant - 鈹溾攢鈹€ ascend310_infer // application for 310 inference - 鈹溾攢鈹€ scripts - 鈹溾攢鈹€ run_infer_310.sh // shell script for 310 inference - 鈹溾攢鈹€ src - 鈹� 鈹溾攢鈹€ config.py // parameter configuration - 鈹� 鈹溾攢鈹€ dataset.py // creating dataset - 鈹� 鈹溾攢鈹€ lenet_fusion.py // auto constructed quantitative network model of LeNet-Quant - 鈹� 鈹溾攢鈹€ lenet_quant.py // manual constructed quantitative network model of LeNet-Quant - 鈹� 鈹溾攢鈹€ loss_monitor.py //monitor of network's loss and other data - 鈹溾攢鈹€ requirements.txt // package needed - 鈹溾攢鈹€ train_quant.py // training LeNet-Quant network with device Ascend - 鈹溾攢鈹€ eval_quant.py // evaluating LeNet-Quant network with device Ascend - 鈹溾攢鈹€ export.py // export model of AIR OR MINDIR - 鈹溾攢鈹€ export_bin_file.py // export bin file of MNIST for 310 inference - 鈹溾攢鈹€ mindspore_hub_conf.py.py // mindspore Hub interface - 鈹溾攢鈹€ postprocess.py // post process for 310 inference -``` - -## [Script Parameters](#contents) - -```python -Major parameters in train_quant.py and config.py as follows: - ---data_path: The absolute full path to the train and evaluation datasets. ---epoch_size: Total training epochs. ---batch_size: Training batch size. ---image_height: Image height used as input to the model. ---image_width: Image width used as input the model. ---device_target: Device where the code will be implemented. Optional values - are "Ascend", "GPU", "CPU".Only "Ascend" is supported now. ---ckpt_path: The absolute full path to the checkpoint file saved - after training. ---data_path: Path where the dataset is saved -``` - -## [Training Process](#contents) - -### Training - -```bash -python train_quant.py --device_target=Ascend --data_path=/home/datasets/MNIST --ckpt_path=../lenet/scripts/ckpt/checkpoint_lenet-10_1875.ckpt > log.txt 2>&1 & -``` - -After training, the loss value will be achieved as follows: - -```bash -# grep "Epoch " log.txt -Epoch: [ 1/ 10], step: [ 937/ 937], loss: [0.0081], avg loss: [0.0081], time: [11268.6832ms] -Epoch time: 11269.352, per step time: 12.027, avg loss: 0.008 -Epoch: [ 2/ 10], step: [ 937/ 937], loss: [0.0496], avg loss: [0.0496], time: [3085.2389ms] -Epoch time: 3085.641, per step time: 3.293, avg loss: 0.050 -Epoch: [ 3/ 10], step: [ 937/ 937], loss: [0.0017], avg loss: [0.0017], time: [3085.3510ms] -... -... -``` - -The model checkpoint will be saved in the current directory. - -## [Evaluation Process](#contents) - -### Evaluation - -Before running the command below, please check the checkpoint path used for evaluation. - -```bash -python eval_quant.py --data_path /home/datasets/MNIST --ckpt_path ./checkpoint_lenet-10_937.ckpt > log.txt 2>&1 & -``` - -You can view the results through the file "log.txt". The accuracy of the test dataset will be as follows: - -```bash -# grep "Accuracy: " log.txt -'Accuracy': 0.9842 -``` - -## [Model Export](#contents) - -```shell -python export.py --ckpt_path [CKPT_PATH] --data_path [DATA_PATH] --device_target [PLATFORM] -``` - -## [Ascend 310 inference](#contents) - -You should export AIR model at Ascend 910 before running the command below. -You can use export_bin_file.py to export MNIST bin and label for 310 inference. - -```shell -python export_bin_file.py --dataset_dir [DATASET_PATH] --save_dir [SAVE_PATH] -``` - -Run run_infer_310.sh and get the accuracy锛� - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] -``` - -You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows: - -```bash -'Accuracy':0.9883 -``` - -## [Model Description](#contents) - -### [Performance](#contents) - -#### Evaluation Performance - -| Parameters | LeNet | -| -------------------------- | ----------------------------------------------------------- | -| Resource | Ascend 910; CPU 2.60GHz, 192cores; Memory 755G; OS Euler2.8 | -| uploaded Date | 07/05/2021 (month/day/year) | -| MindSpore Version | 1.3.0 | -| Dataset | MNIST | -| Training Parameters | epoch=10, steps=937, batch_size = 64, lr=0.01 | -| Optimizer | Momentum | -| Loss Function | Softmax Cross Entropy | -| outputs | probability | -| Loss | 0.002 | -| Speed |3.29 ms/step | -| Total time | 40s | -| Checkpoint for Fine tuning | 482k (.ckpt file) | -| Scripts | [scripts](https://gitee.com/mindspore/models/tree/master/official/cv/lenet) | - -## [Description of Random Situation](#contents) - -In dataset.py, we set the seed inside 鈥渃reate_dataset" function. - -## [ModelZoo Homepage](#contents) - -Please check the official [homepage](https://gitee.com/mindspore/models). diff --git a/official/cv/lenet_quant/Readme_CN.md b/official/cv/lenet_quant/Readme_CN.md deleted file mode 100644 index 16d6b17d2ac133fbef8aa0a7b7a71139ac4f59e6..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/Readme_CN.md +++ /dev/null @@ -1,231 +0,0 @@ -# 鐩綍 - -<!-- TOC --> - -- [鐩綍](#鐩綍) - - [LeNet鎻忚堪](#lenet鎻忚堪) - - [妯″瀷鏋舵瀯](#妯″瀷鏋舵瀯) - - [鏁版嵁闆哴(#鏁版嵁闆�) - - [鐜瑕佹眰](#鐜瑕佹眰) - - [蹇€熷叆闂╙(#蹇€熷叆闂�) - - [鑴氭湰璇存槑](#鑴氭湰璇存槑) - - [鑴氭湰鍙婃牱渚嬩唬鐮乚(#鑴氭湰鍙婃牱渚嬩唬鐮�) - - [鑴氭湰鍙傛暟](#鑴氭湰鍙傛暟) - - [璁粌杩囩▼](#璁粌杩囩▼) - - [璁粌](#璁粌) - - [璇勪及杩囩▼](#璇勪及杩囩▼) - - [璇勪及](#璇勪及) - - [妯″瀷瀵煎嚭](#妯″瀷瀵煎嚭) - - [Ascend 310鎺ㄧ悊](#ascend-310鎺ㄧ悊) - - [妯″瀷鎻忚堪](#妯″瀷鎻忚堪) - - [鎬ц兘](#鎬ц兘) - - [璇勪及鎬ц兘](#璇勪及鎬ц兘) - - [闅忔満鎯呭喌璇存槑](#闅忔満鎯呭喌璇存槑) - - [ModelZoo涓婚〉](#modelzoo涓婚〉) - -<!-- /TOC --> - -## LeNet_Quant鎻忚堪 - -LeNet鏄�1998骞存彁鍑虹殑涓€绉嶅吀鍨嬬殑鍗风Н绁炵粡缃戠粶銆傚畠琚敤浜庢暟瀛楄瘑鍒苟鍙栧緱浜嗗法澶х殑鎴愬姛銆� - -[璁烘枃](https://ieeexplore.ieee.org/document/726791)锛� Y.Lecun, L.Bottou, Y.Bengio, P.Haffner.Gradient-Based Learning Applied to Document Recognition.*Proceedings of the IEEE*.1998. - -杩欐槸LeNet鐨勯噺鍖栫綉缁溿€� - -## 妯″瀷鏋舵瀯 - -LeNet闈炲父绠€鍗曪紝鍖呭惈5灞傦紝鐢�2涓嵎绉眰鍜�3涓叏杩炴帴灞傜粍鎴愩€� - -## 鏁版嵁闆� - -浣跨敤鐨勬暟鎹泦锛歔MNIST](<http://yann.lecun.com/exdb/mnist/>) - -- 鏁版嵁闆嗗ぇ灏忥細52.4M锛屽叡10涓被锛�6涓囧紶 28*28鍥惧儚 - - 璁粌闆嗭細6涓囧紶鍥惧儚 - - 娴嬭瘯闆嗭細1涓囧紶鍥惧儚 -- 鏁版嵁鏍煎紡锛氫簩杩涘埗鏂囦欢 - - 娉細鏁版嵁鍦╠ataset.py涓鐞嗐€� - -- 鐩綍缁撴瀯濡備笅锛� - -```bash -鈹斺攢Data - 鈹溾攢test - 鈹� t10k-images.idx3-ubyte - 鈹� t10k-labels.idx1-ubyte - 鈹� - 鈹斺攢train - train-images.idx3-ubyte - train-labels.idx1-ubyte -``` - -## 鐜瑕佹眰 - -- 纭欢锛欰scend - - 浣跨敤Ascend鎼缓纭欢鐜 -- 妗嗘灦 - - [MindSpore](https://www.mindspore.cn/install) -- 濡傞渶鏌ョ湅璇︽儏锛岃鍙傝濡備笅璧勬簮锛� - - [MindSpore鏁欑▼](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/zh-CN/master/index.html) - -## 蹇€熷叆闂� - -閫氳繃瀹樻柟缃戠珯瀹夎MindSpore鍚庯紝鎮ㄥ彲浠ユ寜鐓у涓嬫楠よ繘琛岃缁冨拰璇勪及锛� - -```python -# 杩涘叆../lenet/scripts鐩綍锛岃缁僱enet缃戠粶锛岀敓鎴�'.ckpt'鏂囦欢浣滀负lenet-quant棰勮缁冩枃浠� -bash run_standalone_train_ascend.sh [DATA_PATH] [CKPT_PATH] -# example: bash run_standalone_train_ascend.sh /home/DataSet/MNIST/ ./ckpt/ - -# 杩涘叆lenet-quant鐩綍锛岃缁僱enet-quant -python train_quant.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_PATH] -# example: python train_quant.py --device_target=Ascend --data_path=/home/DataSet/MNIST/ --ckpt_path=/home/model/lenet/checkpoint_lenet-10_1875.ckpt - -# 璇勪及lenet-quant -python eval_quant.py --device_target=Ascend --data_path=[DATA_PATH] --ckpt_path=[CKPT_PATH] -# example: python eval_quant.py --device_target=Ascend --data_path=/home/DataSet/MNIST/ --ckpt_path=/home/model/lenet_quant/checkpoint_lenet-10_937.ckpt -``` - -## 鑴氭湰璇存槑 - -### 鑴氭湰鍙婃牱渚嬩唬鐮� - -```lenet_quant -鈹溾攢鈹€ model_zoo - 鈹溾攢鈹€ README.md // 妯″瀷鎻忚堪 - 鈹溾攢鈹€ README_CN.md // 妯″瀷鎻忚堪 - 鈹溾攢鈹€ lenet_quant - 鈹溾攢鈹€ README.md // LeNet-Quant鎻忚堪 - 鈹溾攢鈹€ README_CN.md // LeNet-Quant鎻忚堪 - 鈹溾攢鈹€ ascend310_infer //瀹炵幇310鎺ㄧ悊婧愪唬鐮� - 鈹溾攢鈹€ scripts - 鈹溾攢鈹€ run_infer_310.sh // Ascend鎺ㄧ悊shell鑴氭湰 - 鈹溾攢鈹€src - 鈹� 鈹溾攢鈹€ config.py // 鍙傛暟閰嶇疆 - 鈹� 鈹溾攢鈹€ dataset.py // 鍒涘缓鏁版嵁闆� - 鈹� 鈹溾攢鈹€ lenet_fusion.py // 鑷姩鏋勫缓LeNet-Quant鐨勫畾閲忕綉缁滄ā鍨� - 鈹� 鈹溾攢鈹€ lenet_quant.py // 鎵嬪姩鏋勫缓鐨凩eNet-Quant瀹氶噺缃戠粶妯″瀷 - 鈹� 鈹溾攢鈹€ loss_monitor.py // 鐩戞帶缃戠粶鎹熷け鍜屽叾浠栨暟鎹� - 鈹溾攢鈹€ requirements.txt // 闇€瑕佺殑鍖� - 鈹溾攢鈹€ train_quant.py // 浣跨敤Ascend璁粌LeNet-Quant缃戠粶 - 鈹溾攢鈹€ eval_quant.py // 浣跨敤Ascend璇勪及LeNet-Quant缃戠粶 - 鈹溾攢鈹€ mindspore_hub_conf.py // mindspore Hub 鎺ュ彛 - 鈹溾攢鈹€ export_bin_file.py // 瀵煎嚭MNIST鏁版嵁闆嗙殑bin鏂囦欢鐢ㄤ簬310鎺ㄧ悊 - 鈹溾攢鈹€ export.py // 瀵煎嚭 AIR,MINDIR妯″瀷鐨勮剼鏈� - 鈹溾攢鈹€ postprocess.py // 310鎺ㄧ悊鍚庡鐞嗚剼鏈� -``` - -### 鑴氭湰鍙傛暟 - -```python -train_quant.py鍜宑onfig.py涓富瑕佸弬鏁板涓嬶細 - ---data_path锛氬埌璁粌鍜岃瘎浼版暟鎹泦鐨勭粷瀵瑰叏璺緞 ---epoch_size锛氳缁冭疆娆℃暟 ---batch_size锛氳缁冩壒娆″ぇ灏� ---image_height锛氳緭鍏ュ埌妯″瀷鐨勫浘鍍忛珮搴� ---image_width锛氳緭鍏ュ埌妯″瀷鐨勫浘鍍忓搴� ---device_target锛氫唬鐮佸疄鏂界殑璁惧鍙€夊€间负"Ascend","GPU", "CPU"锛岀洰鍓嶅彧鏀寔"Ascend" ---ckpt_path锛氳缁冨悗淇濆瓨鐨勬鏌ョ偣鏂囦欢鐨勭粷瀵瑰叏璺緞 ---data_path锛氭暟鎹泦鎵€鍦ㄨ矾寰� -``` - -### 璁粌杩囩▼ - -#### 璁粌 - -```bash -python train_quant.py --device_target=Ascend --data_path=/home/datasets/MNIST --ckpt_path=../lenet/scripts/ckpt/checkpoint_lenet-10_1875.ckpt > log.txt 2>&1 & -``` - -璁粌缁撴潫锛屾崯澶卞€煎涓嬶細 - -```bash -# grep "Epoch " log.txt -Epoch:[ 1/ 10], step:[ 937/ 937], loss:[0.0081], avg loss:[0.0081], time:[11268.6832ms] -Epoch time:11269.352, per step time:12.027, avg loss:0.008 -Epoch:[ 2/ 10], step:[ 937/ 937], loss:[0.0496], avg loss:[0.0496], time:[3085.2389ms] -Epoch time:3085.641, per step time:3.293, avg loss:0.050 -Epoch:[ 3/ 10], step:[ 937/ 937], loss:[0.0017], avg loss:[0.0017], time:[3085.3510ms] -... -... -``` - -妯″瀷妫€鏌ョ偣淇濆瓨鍦ㄥ綋鍓嶇洰褰曚笅銆� - -### 璇勪及杩囩▼ - -#### 璇勪及 - -鍦ㄨ繍琛屼互涓嬪懡浠や箣鍓嶏紝璇锋鏌ョ敤浜庤瘎浼扮殑妫€鏌ョ偣璺緞銆� - -```bash -python eval_quant.py --data_path /home/datasets/MNIST --ckpt_path ./checkpoint_lenet-10_937.ckpt > log.txt 2>&1 & -``` - -鎮ㄥ彲浠ラ€氳繃log.txt鏂囦欢鏌ョ湅缁撴灉銆傛祴璇曟暟鎹泦鐨勫噯纭€у涓嬶細 - -```bash -# grep "Accuracy:" log.txt -'Accuracy':0.9842 -``` - -### 妯″瀷瀵煎嚭 - -```shell -python export.py --ckpt_path [CKPT_PATH] --data_path [DATA_PATH] --device_target [PLATFORM] -``` - -### Ascend 310鎺ㄧ悊 - -鍦ㄦ帹鐞嗕箣鍓嶉渶瑕佸湪鏄囪吘910鐜涓婂畬鎴怉IR妯″瀷鐨勫鍑恒€� -骞朵娇鐢╡xport_bin_file.py瀵煎嚭MNIST鏁版嵁闆嗙殑bin鏂囦欢鍜屽搴旂殑label鏂囦欢锛� - -```shell -python export_bin_file.py --dataset_dir [DATASET_PATH] --save_dir [SAVE_PATH] -``` - -鎵ц鎺ㄧ悊骞跺緱鍒版帹鐞嗙簿搴︼細 - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] -``` - -鎮ㄥ彲浠ラ€氳繃acc.log鏂囦欢鏌ョ湅缁撴灉銆傛帹鐞嗗噯纭€у涓嬶細 - -```bash -'Accuracy':0.9883 -``` - -## 妯″瀷鎻忚堪 - -### 鎬ц兘 - -#### 璇勪及鎬ц兘 - -| 鍙傛暟 | LeNet | -| -------------------------- | ----------------------------------------------------------- | -| 璧勬簮 | Ascend 910锛汣PU 2.60GHz锛�192鏍革紱鍐呭瓨 755G锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2021-07-05 | -| MindSpore鐗堟湰 | 1.3.0 | -| 鏁版嵁闆� | MNIST | -| 璁粌鍙傛暟 | epoch=10, steps=937, batch_size = 64, lr=0.01 | -| 浼樺寲鍣� | Momentum | -| 鎹熷け鍑芥暟 | Softmax浜ゅ弶鐔� | -| 杈撳嚭 | 姒傜巼 | -| 鎹熷け | 0.002 | -| 閫熷害 |3.29姣/姝� | -| 鎬绘椂闀� | 40绉� | -| 寰皟妫€鏌ョ偣 | 482k (.ckpt鏂囦欢) | -| 鑴氭湰 | [鑴氭湰](https://gitee.com/mindspore/models/tree/master/official/cv/lenet) | - -## 闅忔満鎯呭喌璇存槑 - -鍦╠ataset.py涓紝鎴戜滑璁剧疆浜嗏€渃reate_dataset鈥濆嚱鏁板唴鐨勭瀛愩€� - -## ModelZoo涓婚〉 - -璇锋祻瑙堝畼缃慬涓婚〉](https://gitee.com/mindspore/models)銆� diff --git a/official/cv/lenet_quant/ascend310_infer/inc/ModelProcess.h b/official/cv/lenet_quant/ascend310_infer/inc/ModelProcess.h deleted file mode 100644 index 9acb683bee2a037a98878d98c0605985701f913a..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/inc/ModelProcess.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MODELPROCESS_H -#define MODELPROCESS_H - -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* ModelProcess -*/ -class ModelProcess { - public: - /** - * @brief Constructor - */ - ModelProcess(); - - /** - * @brief Destructor - */ - ~ModelProcess(); - - /** - * @brief load model from file with mem - * @param [in] modelPath: model path - * @return result - */ - Result LoadModelFromFileWithMem(const char *modelPath); - - /** - * @brief unload model - */ - void Unload(); - - /** - * @brief create model desc - * @return result - */ - Result CreateDesc(); - - /** - * @brief destroy desc - */ - void DestroyDesc(); - - /** - * @brief create model input - * @param [in] inputDataBuffer: input buffer - * @param [in] bufferSize: input buffer size - * @return result - */ - Result CreateInput(void *inputDataBuffer, size_t bufferSize); - - /** - * @brief destroy input resource - */ - void DestroyInput(); - - /** - * @brief create output buffer - * @return result - */ - Result CreateOutput(); - - /** - * @brief destroy output resource - */ - void DestroyOutput(); - - /** - * @brief model execute - * @return result - */ - Result Execute(); - - /** - * @brief dump model output result to file - */ - void DumpModelOutputResult(char *output_name); - - /** - * @brief get model output result - */ - void OutputModelResult(); - - private: - uint32_t modelId_; - size_t modelMemSize_; - size_t modelWeightSize_; - void *modelMemPtr_; - void *modelWeightPtr_; - bool loadFlag_; // model load flag - aclmdlDesc *modelDesc_; - aclmdlDataset *input_; - aclmdlDataset *output_; -}; -#endif diff --git a/official/cv/lenet_quant/ascend310_infer/inc/SampleProcess.h b/official/cv/lenet_quant/ascend310_infer/inc/SampleProcess.h deleted file mode 100644 index 30a77f4248c948b83d019ee05aaf56dce9a08e26..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/inc/SampleProcess.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef SAMPLEPROCESS_H -#define SAMPLEPROCESS_H - -#include <string> -#include <vector> -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* SampleProcess -*/ -class SampleProcess { - public: - /** - * @brief Constructor - */ - explicit SampleProcess(int32_t deviceId); - - /** - * @brief Destructor - */ - ~SampleProcess(); - - /** - * @brief init reousce - * @return result - */ - Result InitResource(const char *acl_config_path); - - /** - * @brief sample process - * @return result - */ - Result Process(const char *om_path, const char *input_folder); - - void GetAllFiles(std::string path, std::vector<std::string> *files); - - private: - void DestroyResource(); - - int32_t deviceId_; - aclrtContext context_; - aclrtStream stream_; -}; - -#endif diff --git a/official/cv/lenet_quant/ascend310_infer/inc/utils.h b/official/cv/lenet_quant/ascend310_infer/inc/utils.h deleted file mode 100644 index b21e418a1f4ad2b8fc0331cf0b37adf73f2703f6..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/inc/utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MINDSPORE_INFERENCE_UTILS_H_ -#define MINDSPORE_INFERENCE_UTILS_H_ - -#include <iostream> -#include <string> - -#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args) -#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args) -#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args) - -typedef enum Result { - SUCCESS = 0, - FAILED = 1 -} Result; - -/** -* Utils -*/ -class Utils { - public: - /** - * @brief create device buffer of file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return device buffer of file - */ - static void *GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize); - - /** - * @brief Read bin file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return buffer of pic - */ - static void* ReadBinFile(std::string fileName, uint32_t *fileSize); -}; -#endif diff --git a/official/cv/lenet_quant/ascend310_infer/src/CMakeLists.txt b/official/cv/lenet_quant/ascend310_infer/src/CMakeLists.txt deleted file mode 100644 index 65961330a3219658f5c46fa430e6c5844f2536a4..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - -# CMake lowest version requirement -cmake_minimum_required(VERSION 3.5.1) -# project information -project(InferClassification) -# Check environment variable -if(NOT DEFINED ENV{ASCEND_HOME}) - message(FATAL_ERROR "please define environment variable:ASCEND_HOME") -endif() - -# Compile options -add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined") - -# Skip build rpath -set(CMAKE_SKIP_BUILD_RPATH True) - -# Set output directory -set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out) - -# Set include directory and library directory -set(FWKACL_LIB_DIR $ENV{ASCEND_HOME}/fwkacllib) -set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib) -set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib) - -# Header path -include_directories(${ACL_LIB_DIR}/include/) -include_directories(${FWKACL_LIB_DIR}/include/) -include_directories(${ATLAS_ACL_LIB_DIR}/include/) -include_directories(${PROJECT_SRC_ROOT}/../inc) - -# add host lib path -link_directories(${ACL_LIB_DIR} ${FWKACL_LIB_DIR}) -find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${FWKACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64) - -add_executable(main utils.cpp - SampleProcess.cpp - ModelProcess.cpp - main.cpp) - -target_link_libraries(main ${acl} gflags pthread) diff --git a/official/cv/lenet_quant/ascend310_infer/src/ModelProcess.cpp b/official/cv/lenet_quant/ascend310_infer/src/ModelProcess.cpp deleted file mode 100644 index 72744284906a6d1b6ee9bc1051ada5872526c101..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/ModelProcess.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/ModelProcess.h" -#include <iostream> -#include <map> -#include <sstream> -#include <algorithm> -#include "../inc/utils.h" - -extern bool g_isDevice; - -ModelProcess::ModelProcess() :modelId_(0), modelMemSize_(0), modelWeightSize_(0), modelMemPtr_(nullptr), -modelWeightPtr_(nullptr), loadFlag_(false), modelDesc_(nullptr), input_(nullptr), output_(nullptr) { -} - -ModelProcess::~ModelProcess() { - Unload(); - DestroyDesc(); - DestroyInput(); - DestroyOutput(); -} - -Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath) { - if (loadFlag_) { - ERROR_LOG("has already loaded a model"); - return FAILED; - } - - aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("query model failed, model file is %s", modelPath); - return FAILED; - } - - ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_); - return FAILED; - } - - ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_); - return FAILED; - } - - ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, - modelMemSize_, modelWeightPtr_, modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("load model from file failed, model file is %s", modelPath); - return FAILED; - } - - loadFlag_ = true; - INFO_LOG("load model %s success", modelPath); - return SUCCESS; -} - -Result ModelProcess::CreateDesc() { - modelDesc_ = aclmdlCreateDesc(); - if (modelDesc_ == nullptr) { - ERROR_LOG("create model description failed"); - return FAILED; - } - - aclError ret = aclmdlGetDesc(modelDesc_, modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("get model description failed"); - return FAILED; - } - - INFO_LOG("create model description success"); - - return SUCCESS; -} - -void ModelProcess::DestroyDesc() { - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } -} - -Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) { - input_ = aclmdlCreateDataset(); - if (input_ == nullptr) { - ERROR_LOG("can't create dataset, create input failed"); - return FAILED; - } - - aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize); - if (inputData == nullptr) { - ERROR_LOG("can't create data buffer, create input failed"); - return FAILED; - } - - aclError ret = aclmdlAddDatasetBuffer(input_, inputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("add input dataset buffer failed"); - aclDestroyDataBuffer(inputData); - inputData = nullptr; - return FAILED; - } - - return SUCCESS; -} - -void ModelProcess::DestroyInput() { - if (input_ == nullptr) { - return; - } - - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); - aclDestroyDataBuffer(dataBuffer); - } - aclmdlDestroyDataset(input_); - input_ = nullptr; -} - -Result ModelProcess::CreateOutput() { - if (modelDesc_ == nullptr) { - ERROR_LOG("no model description, create output failed"); - return FAILED; - } - - output_ = aclmdlCreateDataset(); - if (output_ == nullptr) { - ERROR_LOG("can't create dataset, create output failed"); - return FAILED; - } - - size_t outputSize = aclmdlGetNumOutputs(modelDesc_); - for (size_t i = 0; i < outputSize; ++i) { - size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i); - void *outputBuffer = nullptr; - aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size); - return FAILED; - } - - aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't create data buffer, create output failed"); - aclrtFree(outputBuffer); - return FAILED; - } - - ret = aclmdlAddDatasetBuffer(output_, outputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't add data buffer, create output failed"); - aclrtFree(outputBuffer); - aclDestroyDataBuffer(outputData); - return FAILED; - } - } - - INFO_LOG("create model output success"); - return SUCCESS; -} - -void ModelProcess::DumpModelOutputResult(char *output_name) { - size_t outputNum = aclmdlGetDatasetNumBuffers(output_); - std::string homePath = "./result_Files"; - for (size_t i = 0; i < outputNum; ++i) { - std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin"; - std::string outputFileName = homePath + "/" + fileName; - FILE *outputFile = fopen(outputFileName.c_str(), "wb"); - if (outputFile != nullptr) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void* outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - (void)aclrtFreeHost(outHostData); - return; - } - fwrite(outHostData, len, sizeof(char), outputFile); - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } else { - fwrite(data, len, sizeof(char), outputFile); - } - fclose(outputFile); - outputFile = nullptr; - } else { - ERROR_LOG("create output file [%s] failed", outputFileName.c_str()); - return; - } - } - INFO_LOG("dump data success"); - return; -} - -void ModelProcess::OutputModelResult() { - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void *outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - float *outData = NULL; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - return; - } - outData = reinterpret_cast<float*>(outHostData); - } else { - outData = reinterpret_cast<float*>(data); - } - std::map<float, unsigned int, std::greater<float> > resultMap; - for (unsigned int j = 0; j < len / sizeof(float); ++j) { - resultMap[*outData] = j; - outData++; - } - int cnt = 0; - for (auto it = resultMap.begin(); it != resultMap.end(); ++it) { - // print top 5 - if (++cnt > 5) { - break; - } - INFO_LOG("top %d: index[%d] value[%lf]", cnt, it->second, it->first); - } - if (!g_isDevice) { - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } - } - INFO_LOG("output data success"); - return; -} - -void ModelProcess::DestroyOutput() { - if (output_ == nullptr) { - return; - } - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - (void)aclrtFree(data); - (void)aclDestroyDataBuffer(dataBuffer); - } - - (void)aclmdlDestroyDataset(output_); - output_ = nullptr; -} - -Result ModelProcess::Execute() { - aclError ret = aclmdlExecute(modelId_, input_, output_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("execute model failed, modelId is %u", modelId_); - return FAILED; - } - - INFO_LOG("model execute success"); - return SUCCESS; -} - -void ModelProcess::Unload() { - if (!loadFlag_) { - WARN_LOG("no model had been loaded, unload failed"); - return; - } - - aclError ret = aclmdlUnload(modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("unload model failed, modelId is %u", modelId_); - } - - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } - - if (modelMemPtr_ != nullptr) { - aclrtFree(modelMemPtr_); - modelMemPtr_ = nullptr; - modelMemSize_ = 0; - } - - if (modelWeightPtr_ != nullptr) { - aclrtFree(modelWeightPtr_); - modelWeightPtr_ = nullptr; - modelWeightSize_ = 0; - } - - loadFlag_ = false; - INFO_LOG("unload model success, modelId is %u", modelId_); -} diff --git a/official/cv/lenet_quant/ascend310_infer/src/SampleProcess.cpp b/official/cv/lenet_quant/ascend310_infer/src/SampleProcess.cpp deleted file mode 100644 index 889e696bb2ac528c67e0aeaaef69c5abe8c75758..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/SampleProcess.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/SampleProcess.h" -#include <sys/types.h> -#include <dirent.h> -#include <string.h> -#include <iostream> -#include <fstream> -#include "../inc/utils.h" -#include "../inc/ModelProcess.h" -#include "acl/acl.h" - -extern bool g_isDevice; -using std::string; -using std::vector; - -SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) { - deviceId_ = deviceId; -} - -SampleProcess::~SampleProcess() { - DestroyResource(); -} - -Result SampleProcess::InitResource(const char *aclConfigPath) { - // ACL init - aclError ret = aclInit(aclConfigPath); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl init failed"); - return FAILED; - } - INFO_LOG("acl init success"); - - // open device - ret = aclrtSetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl open device %d failed", deviceId_); - return FAILED; - } - INFO_LOG("open device %d success", deviceId_); - - // create context (set current) - ret = aclrtCreateContext(&context_, deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create context failed"); - return FAILED; - } - INFO_LOG("create context success"); - - // create stream - ret = aclrtCreateStream(&stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create stream failed"); - return FAILED; - } - INFO_LOG("create stream success"); - - // get run mode - aclrtRunMode runMode; - ret = aclrtGetRunMode(&runMode); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl get run mode failed"); - return FAILED; - } - g_isDevice = (runMode == ACL_DEVICE); - INFO_LOG("get run mode success"); - return SUCCESS; -} - -void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) { - DIR *pDir = nullptr; - struct dirent* ptr = nullptr; - if (!(pDir = opendir(path.c_str()))) - return; - while ((ptr = readdir(pDir)) != 0) { - if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) - files->push_back(path + "/" + ptr->d_name); - } - closedir(pDir); -} - -Result SampleProcess::Process(const char *om_path, const char *input_folder) { - // model init - ModelProcess processModel; - - Result ret = processModel.LoadModelFromFileWithMem(om_path); - if (ret != SUCCESS) { - ERROR_LOG("execute LoadModelFromFileWithMem failed"); - return FAILED; - } - - ret = processModel.CreateDesc(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateDesc failed"); - return FAILED; - } - - ret = processModel.CreateOutput(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateOutput failed"); - return FAILED; - } - - std::vector<string> testFile; - GetAllFiles(input_folder, &testFile); - - if (testFile.size() == 0) { - WARN_LOG("no input data under folder"); - } - - // loop begin - for (size_t index = 0; index < testFile.size(); ++index) { - INFO_LOG("start to process file:%s", testFile[index].c_str()); - // model process - uint32_t devBufferSize; - void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize); - if (picDevBuffer == nullptr) { - ERROR_LOG("get pic device buffer failed,index is %zu", index); - return FAILED; - } - ret = processModel.CreateInput(picDevBuffer, devBufferSize); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateInput failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - ret = processModel.Execute(); - if (ret != SUCCESS) { - ERROR_LOG("execute inference failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - int pos = testFile[index].find_last_of('/'); - std::string name = testFile[index].substr(pos+1); - std::string outputname = name.substr(0, name.rfind(".")); - - // print the top 5 confidence values - processModel.OutputModelResult(); - // dump output result to file in the current directory - processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str())); - - // release model input buffer - aclrtFree(picDevBuffer); - processModel.DestroyInput(); - } - // loop end - - return SUCCESS; -} - -void SampleProcess::DestroyResource() { - aclError ret; - if (stream_ != nullptr) { - ret = aclrtDestroyStream(stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy stream failed"); - } - stream_ = nullptr; - } - INFO_LOG("end to destroy stream"); - - if (context_ != nullptr) { - ret = aclrtDestroyContext(context_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy context failed"); - } - context_ = nullptr; - } - INFO_LOG("end to destroy context"); - - ret = aclrtResetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("reset device failed"); - } - INFO_LOG("end to reset device is %d", deviceId_); - - ret = aclFinalize(); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("finalize acl failed"); - } - INFO_LOG("end to finalize acl"); -} - diff --git a/official/cv/lenet_quant/ascend310_infer/src/acl.json b/official/cv/lenet_quant/ascend310_infer/src/acl.json deleted file mode 100644 index 9e26dfeeb6e641a33dae4961196235bdb965b21b..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/acl.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/official/cv/lenet_quant/ascend310_infer/src/build.sh b/official/cv/lenet_quant/ascend310_infer/src/build.sh deleted file mode 100644 index b5979b68e60b673f763a3cac98c5e147e7085291..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/build.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -path_cur=$(cd "`dirname $0`" || exit; pwd) - -function preparePath() { - rm -rf $1 - mkdir -p $1 - cd $1 || exit -} - -function buildA300() { - if [ ! "${ARCH_PATTERN}" ]; then - # set ARCH_PATTERN to acllib when it was not specified by user - export ARCH_PATTERN=acllib - echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}" - else - echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib" - export ARCH_PATTERN=${ARCH_PATTERN}/acllib - fi - - path_build=$path_cur/build - preparePath $path_build - cmake .. - make -j - ret=$? - cd .. - return ${ret} -} - -# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user -if [ ! "${ASCEND_VERSION}" ]; then - export ASCEND_VERSION=ascend-toolkit/latest - echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}" -else - echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user" -fi - -buildA300 - -if [ $? -ne 0 ]; then - exit 1 -fi diff --git a/official/cv/lenet_quant/ascend310_infer/src/main.cpp b/official/cv/lenet_quant/ascend310_infer/src/main.cpp deleted file mode 100644 index ca47f0635efd1618ba9fd85fe63186f55c54e421..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include <gflags/gflags.h> -#include <iostream> -#include <fstream> -#include <memory> -#include "../inc/SampleProcess.h" -#include "../inc/utils.h" - -bool g_isDevice = false; - -DEFINE_string(om_path, "", "om path"); -DEFINE_string(dataset_path, "", "dataset path"); -DEFINE_string(acljson_path, "", "acl json path"); -DEFINE_int32(device_id, 0, "device id"); - -int main(int argc, char **argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - std::string om_path = FLAGS_om_path; - std::string dataset_path = FLAGS_dataset_path; - std::string acljson_path = FLAGS_acljson_path; - int32_t device_id = FLAGS_device_id; - std::ifstream fin(om_path); - if (!fin) { - std::cout << "Invalid om path." << std::endl; - return FAILED; - } - SampleProcess processSample(device_id); - // acl.json is deployed for dump data. - Result ret = processSample.InitResource(acljson_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample init resource failed"); - return FAILED; - } - - ret = processSample.Process(om_path.c_str(), dataset_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample process failed"); - return FAILED; - } - - INFO_LOG("execute sample success"); - return SUCCESS; -} diff --git a/official/cv/lenet_quant/ascend310_infer/src/utils.cpp b/official/cv/lenet_quant/ascend310_infer/src/utils.cpp deleted file mode 100644 index 6e669f3f329be5ecfba41595c72f525d4fb428d0..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/ascend310_infer/src/utils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/utils.h" -#include <sys/stat.h> -#include <iostream> -#include <fstream> -#include <cstring> -#include "acl/acl.h" - -extern bool g_isDevice; - -void* Utils::ReadBinFile(std::string fileName, uint32_t *fileSize) { - struct stat sBuf; - int fileStatus = stat(fileName.data(), &sBuf); - if (fileStatus == -1) { - ERROR_LOG("failed to get file"); - return nullptr; - } - if (S_ISREG(sBuf.st_mode) == 0) { - ERROR_LOG("%s is not a file, please enter a file", fileName.c_str()); - return nullptr; - } - - std::ifstream binFile(fileName, std::ifstream::binary); - if (binFile.is_open() == false) { - ERROR_LOG("open file %s failed", fileName.c_str()); - return nullptr; - } - - binFile.seekg(0, binFile.end); - uint32_t binFileBufferLen = binFile.tellg(); - if (binFileBufferLen == 0) { - ERROR_LOG("binfile is empty, filename is %s", fileName.c_str()); - binFile.close(); - return nullptr; - } - - binFile.seekg(0, binFile.beg); - - void* binFileBufferData = nullptr; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&binFileBufferData, binFileBufferLen); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc for binFileBufferData failed"); - binFile.close(); - return nullptr; - } - if (binFileBufferData == nullptr) { - ERROR_LOG("malloc binFileBufferData failed"); - binFile.close(); - return nullptr; - } - } else { - ret = aclrtMalloc(&binFileBufferData, binFileBufferLen, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", binFileBufferLen); - binFile.close(); - return nullptr; - } - } - binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen); - binFile.close(); - *fileSize = binFileBufferLen; - return binFileBufferData; -} - -void* Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize) { - uint32_t inputHostBuffSize = 0; - void* inputHostBuff = Utils::ReadBinFile(fileName, &inputHostBuffSize); - if (inputHostBuff == nullptr) { - return nullptr; - } - if (!g_isDevice) { - void *inBufferDev = nullptr; - uint32_t inBufferSize = inputHostBuffSize; - aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - - ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u", - inBufferSize, inputHostBuffSize); - aclrtFree(inBufferDev); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - aclrtFreeHost(inputHostBuff); - *fileSize = inBufferSize; - return inBufferDev; - } else { - *fileSize = inputHostBuffSize; - return inputHostBuff; - } -} diff --git a/official/cv/lenet_quant/eval_quant.py b/official/cv/lenet_quant/eval_quant.py deleted file mode 100644 index 86f7db609611835bbab460ed782b4ab56e21bead..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/eval_quant.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -######################## eval lenet example ######################## -eval lenet according to model file: -python eval.py --data_path /YourDataPath --ckpt_path Your.ckpt -""" - -import os -import argparse -import mindspore.nn as nn -from mindspore import context -from mindspore.train.serialization import load_checkpoint, load_param_into_net -from mindspore.train import Model -from mindspore.nn.metrics import Accuracy -from mindspore.compression.quant import QuantizationAwareTraining -from src.dataset import create_dataset -from src.config import mnist_cfg as cfg -from src.lenet_fusion import LeNet5 as LeNet5Fusion - -parser = argparse.ArgumentParser(description='MindSpore MNIST 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="./MNIST_Data", - help='path where the dataset is saved') -parser.add_argument('--ckpt_path', type=str, default="", - help='if mode is test, must provide path where the trained ckpt file') -args = parser.parse_args() - -if __name__ == "__main__": - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target) - ds_eval = create_dataset(os.path.join(args.data_path, "test"), cfg.batch_size, 1) - - # define fusion network - network = LeNet5Fusion(cfg.num_classes) - # convert fusion network to quantization aware network - quantizer = QuantizationAwareTraining(quant_delay=0, - bn_fold=False, - freeze_bn=10000, - per_channel=[True, False], - symmetric=[True, False]) - network = quantizer.quantize(network) - - # define loss - net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - # define network optimization - net_opt = nn.Momentum(network.trainable_params(), cfg.lr, cfg.momentum) - - # call back and monitor - model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy()}) - - # load quantization aware network checkpoint - param_dict = load_checkpoint(args.ckpt_path) - not_load_param = load_param_into_net(network, param_dict) - if not_load_param: - raise ValueError("Load param into net fail!") - - print("============== Starting Testing ==============") - acc = model.eval(ds_eval, dataset_sink_mode=True) - print("============== {} ==============".format(acc)) diff --git a/official/cv/lenet_quant/export.py b/official/cv/lenet_quant/export.py deleted file mode 100644 index 3c046bada652962c2df4fe9c9a2be92697e1d063..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/export.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -export quantization aware training network to infer `AIR` backend. -""" - -import argparse -import numpy as np - -import mindspore -from mindspore import Tensor, context, load_checkpoint, load_param_into_net, export -from mindspore.compression.quant import QuantizationAwareTraining - -from src.config import mnist_cfg as cfg -from src.lenet_fusion import LeNet5 as LeNet5Fusion - -parser = argparse.ArgumentParser(description='MindSpore MNIST 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('--ckpt_path', type=str, default="", - help='if mode is test, must provide path where the trained ckpt file') -parser.add_argument("--file_format", type=str, choices=["AIR", "MINDIR"], default="MINDIR", help="file format") -args = parser.parse_args() - -if __name__ == "__main__": - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target) - - # define fusion network - network = LeNet5Fusion(cfg.num_classes) - # convert fusion network to quantization aware network - quantizer = QuantizationAwareTraining(quant_delay=0, - bn_fold=False, - freeze_bn=10000, - per_channel=[True, False], - symmetric=[True, False]) - network = quantizer.quantize(network) - # load quantization aware network checkpoint - param_dict = load_checkpoint(args.ckpt_path) - load_param_into_net(network, param_dict) - - # export network - inputs = Tensor(np.ones([1, 1, cfg.image_height, cfg.image_width]), mindspore.float32) - export(network, inputs, file_name="lenet_quant", file_format=args.file_format, quant_mode='QUANT') diff --git a/official/cv/lenet_quant/export_bin_file.py b/official/cv/lenet_quant/export_bin_file.py deleted file mode 100644 index 428d45451783ca43ac3bfe544ab705e36f87eae5..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/export_bin_file.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -export mnist dataset to bin. -""" -import os -import argparse -from mindspore import context -from src.dataset import create_dataset - -def parse_args(): - parser = argparse.ArgumentParser(description='MNIST to bin') - 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('--dataset_dir', type=str, default='', help='dataset path') - parser.add_argument('--save_dir', type=str, default='', help='path to save bin file') - parser.add_argument('--batch_size', type=int, default=1, help='batch size for bin') - args_, _ = parser.parse_known_args() - return args_ - -if __name__ == "__main__": - args = parse_args() - os.environ["RANK_SIZE"] = '1' - os.environ["RANK_ID"] = '0' - device_id = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0 - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=device_id) - mnist_path = os.path.join(args.dataset_dir, 'test') - batch_size = args.batch_size - save_dir = os.path.join(args.save_dir, 'lenet_quant_mnist_310_infer_data') - folder = os.path.join(save_dir, 'mnist_bs_' + str(batch_size) + '_bin') - if not os.path.exists(folder): - os.makedirs(folder) - ds = create_dataset(mnist_path, batch_size) - iter_num = 0 - label_file = os.path.join(save_dir, './mnist_bs_' + str(batch_size) + '_label.txt') - with open(label_file, 'w') as f: - for data in ds.create_dict_iterator(): - image = data['image'] - label = data['label'] - file_name = "mnist_" + str(iter_num) + ".bin" - file_path = folder + "/" + file_name - image.asnumpy().tofile(file_path) - f.write(file_name) - for i in label: - f.write(',' + str(i)) - f.write('\n') - iter_num += 1 - print("=====iter_num:{}=====".format(iter_num)) - print("=====image_data:{}=====".format(image)) - print("=====label_data:{}=====".format(label)) diff --git a/official/cv/lenet_quant/mindspore_hub_conf.py b/official/cv/lenet_quant/mindspore_hub_conf.py deleted file mode 100644 index 0cacce0dd24bb1e0034ae0c73e514aad073e0e06..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/mindspore_hub_conf.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""hub config""" -from src.lenet_fusion import LeNet5 as LeNet5Fusion -from src.config import mnist_cfg as cfg - -def lenet_net(*args, **kwargs): - return LeNet5Fusion(*args, **kwargs) - -def create_network(name, *args, **kwargs): - """create_network about lenet_quant""" - if name == "lenet_quant": - return lenet_net(cfg.num_classes, *args, **kwargs) - raise NotImplementedError(f"{name} is not implemented in the repo") diff --git a/official/cv/lenet_quant/postprocess.py b/official/cv/lenet_quant/postprocess.py deleted file mode 100644 index 91f497a27fa8fb6a4e89f839c40356b5421a0b51..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/postprocess.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -post process for 310 inference. -""" -import os -import argparse -import numpy as np - -def parse_args(): - parser = argparse.ArgumentParser(description='lenet_quant inference') - parser.add_argument('--result_path', type=str, default='', help='result files path') - parser.add_argument('--label_path', type=str, default='', help='label file path') - args_, _ = parser.parse_known_args() - return args_ - -if __name__ == "__main__": - args = parse_args() - path = args.result_path - label_path = args.label_path - files = os.listdir(path) - step = 0 - sum_right = 0 - label_dict = {} - with open(label_path, 'r') as f: - for line in f.readlines(): - batch_label = line.strip().split(',') - label_dict[batch_label[0]] = batch_label[1:] - for file in files: - full_file_path = os.path.join(path, file) - if os.path.isfile(full_file_path): - label_file = file.split('_0.bin')[0] + '.bin' - label_array = np.array(label_dict[label_file]) - line = np.fromfile(full_file_path, dtype=np.float32) - batch_size = label_array.shape[0] - line_comp = line.reshape(batch_size, int(line.shape[0] / batch_size)) - for i in range(0, batch_size): - pred = np.argmax(line_comp[i], axis=0) - step += 1 - if pred == label_array[i].astype(np.int64): - sum_right += 1 - print("=====step:{}=====".format(step)) - print("=====sum_right:{}=====".format(sum_right)) - accuracy = sum_right * 100.0 / step - print("=====accuracy:{}=====".format(accuracy)) diff --git a/official/cv/lenet_quant/requirements.txt b/official/cv/lenet_quant/requirements.txt deleted file mode 100644 index 5a619e015a5ba164371d32865c44aa47a3aa416c..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -numpy -easydict diff --git a/official/cv/lenet_quant/scripts/run_infer_310.sh b/official/cv/lenet_quant/scripts/run_infer_310.sh deleted file mode 100644 index 8f8a03fd001c0f5d9de4e8f8239c5dd530d3bacf..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/scripts/run_infer_310.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [[ $# -lt 3 || $# -gt 4 ]]; then - echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] - DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} -model=$(get_real_path $1) -data_path=$(get_real_path $2) -label_path=$(get_real_path $3) - -device_id=0 -if [ $# == 4 ]; then - device_id=$4 -fi - -echo "air name: "$model -echo "dataset path: "$data_path -echo "label path: "$label_path -echo "device id: "$device_id - -export ASCEND_HOME=/usr/local/Ascend/ -if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then - export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH - export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp -else - export PATH=$ASCEND_HOME/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/fwkacllib/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=$PYTHONPATH:$TBE_IMPL_PATH - export ASCEND_OPP_PATH=$ASCEND_HOME/opp -fi - -function air_to_om() -{ - atc --input_format=NCHW --framework=1 --model=$model --output=lenet_quant --soc_version=Ascend310 &> atc.log -} - -function compile_app() -{ - cd ../ascend310_infer/src || exit - bash build.sh &> build.log -} - -function infer() -{ - cd - || exit - if [ -d result_Files ]; then - rm -rf ./result_Files - fi - if [ -d time_Result ]; then - rm -rf ./time_Result - fi - mkdir result_Files - mkdir time_Result - ../ascend310_infer/src/out/main --om_path=./lenet_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log -} - -function cal_acc() -{ - python ../postprocess.py --result_path=./result_Files --label_path=$label_path &> acc.log -} - -air_to_om -if [ $? -ne 0 ]; then - echo " air to om failed" - exit 1 -fi -compile_app -if [ $? -ne 0 ]; then - echo "compile app code failed" - exit 1 -fi -infer -if [ $? -ne 0 ]; then - echo " execute inference failed" - exit 1 -fi -cal_acc -if [ $? -ne 0 ]; then - echo "calculate accuracy failed" - exit 1 -fi diff --git a/official/cv/lenet_quant/src/config.py b/official/cv/lenet_quant/src/config.py deleted file mode 100644 index ab4b2e4084d7228e292fa373c9e2faf52cca601c..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/src/config.py +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -network config setting, will be used in train.py -""" - -from easydict import EasyDict as edict - -mnist_cfg = edict({ - 'num_classes': 10, - 'lr': 0.01, - 'momentum': 0.9, - 'epoch_size': 10, - 'batch_size': 64, - 'buffer_size': 1000, - 'image_height': 32, - 'image_width': 32, - 'keep_checkpoint_max': 10, -}) diff --git a/official/cv/lenet_quant/src/dataset.py b/official/cv/lenet_quant/src/dataset.py deleted file mode 100644 index df9eecda1fe327a405057be7993e401c5ae08187..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/src/dataset.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -Produce the dataset -""" - -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.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 - """ - # 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 = C.TypeCast(mstype.int32) - - # apply map operations on images - 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 - 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 diff --git a/official/cv/lenet_quant/src/lenet_fusion.py b/official/cv/lenet_quant/src/lenet_fusion.py deleted file mode 100644 index 4b30ac5a4ef8ec4d13449068b831d14c6abb4460..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/src/lenet_fusion.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""LeNet.""" -import mindspore.nn as nn - - -class LeNet5(nn.Cell): - """ - Lenet network - - Args: - num_class (int): Number of classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> LeNet(num_class=10) - - """ - - def __init__(self, num_class=10, channel=1): - super(LeNet5, self).__init__() - self.type = "fusion" - self.num_class = num_class - - # change `nn.Conv2d` to `nn.Conv2dBnAct` - self.conv1 = nn.Conv2dBnAct(channel, 6, 5, pad_mode='valid', activation='relu') - self.conv2 = nn.Conv2dBnAct(6, 16, 5, pad_mode='valid', activation='relu') - # change `nn.Dense` to `nn.DenseBnAct` - self.fc1 = nn.DenseBnAct(16 * 5 * 5, 120, activation='relu') - self.fc2 = nn.DenseBnAct(120, 84, activation='relu') - self.fc3 = nn.DenseBnAct(84, self.num_class) - - self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2) - self.flatten = nn.Flatten() - - def construct(self, x): - x = self.conv1(x) - x = self.max_pool2d(x) - x = self.conv2(x) - x = self.max_pool2d(x) - x = self.flatten(x) - x = self.fc1(x) - x = self.fc2(x) - x = self.fc3(x) - return x diff --git a/official/cv/lenet_quant/src/lenet_quant.py b/official/cv/lenet_quant/src/lenet_quant.py deleted file mode 100644 index 1fd6e7f365692342d184ed1fa93c02f90fab7531..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/src/lenet_quant.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Manual construct network for LeNet""" - -import mindspore.nn as nn -from mindspore.compression.quant import create_quant_config -from mindspore.compression.common import QuantDtype - -class LeNet5(nn.Cell): - """ - Lenet network - - Args: - num_class (int): Number of classes. Default: 10. - - Returns: - Tensor, output tensor - Examples: - >>> LeNet(num_class=10) - - """ - - def __init__(self, num_class=10, channel=1): - super(LeNet5, self).__init__() - self.num_class = num_class - self.qconfig = create_quant_config(per_channel=(True, False), symmetric=(True, False)) - - self.conv1 = nn.Conv2dQuant(channel, 6, 5, pad_mode='valid', quant_config=self.qconfig, - quant_dtype=QuantDtype.INT8) - self.conv2 = nn.Conv2dQuant(6, 16, 5, pad_mode='valid', quant_config=self.qconfig, quant_dtype=QuantDtype.INT8) - self.fc1 = nn.DenseQuant(16 * 5 * 5, 120, quant_config=self.qconfig, quant_dtype=QuantDtype.INT8) - self.fc2 = nn.DenseQuant(120, 84, quant_config=self.qconfig, quant_dtype=QuantDtype.INT8) - self.fc3 = nn.DenseQuant(84, self.num_class, quant_config=self.qconfig, quant_dtype=QuantDtype.INT8) - - self.relu = nn.ActQuant(nn.ReLU(), quant_config=self.qconfig, quant_dtype=QuantDtype.INT8) - 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 diff --git a/official/cv/lenet_quant/src/loss_monitor.py b/official/cv/lenet_quant/src/loss_monitor.py deleted file mode 100644 index 4bb8400ae26efa5d4c32e72ad5f8441687db96a0..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/src/loss_monitor.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""LossMonitor Callback class.""" - -import time -import numpy as np -from mindspore.common.tensor import Tensor -from mindspore.train.callback import Callback - - -class LossMonitor(Callback): - """ - Monitor the loss in training. - - If the loss is NAN or INF, it will terminate training. - - Note: - If per_print_times is 0 do not print loss. - - Args: - per_print_times (int): Print loss every times. Default: 1. - lr_init (numpy array): train learning rate. Default: None. - - Raises: - ValueError: If print_step is not int or less than zero. - - Examples: - >>> LossMonitor(100, lr_init=Tensor([0.05]*100).asnumpy()) - """ - - def __init__(self, per_print_times=1, lr_init=None): - super(LossMonitor, self).__init__() - if not isinstance(per_print_times, int) or per_print_times < 0: - raise ValueError("print_step must be int and >= 0.") - self._per_print_times = per_print_times - self.lr_init = lr_init - - def epoch_begin(self, run_context): - """ - epoch begin - """ - self.losses = [] - self.epoch_time = time.time() - - def epoch_end(self, run_context): - """ - epoch end - """ - cb_params = run_context.original_args() - epoch_mseconds = (time.time() - self.epoch_time) * 1000 - per_step_mseconds = epoch_mseconds / cb_params.batch_num - print("Epoch time: {:5.3f}, per step time: {:5.3f}, " - "avg loss: {:5.3f}".format(epoch_mseconds, - per_step_mseconds, - np.mean(self.losses))) - print("*" * 60) - - def step_begin(self, run_context): - """ - step begin - """ - self.step_time = time.time() - - def step_end(self, run_context): - """ - step end - """ - cb_params = run_context.original_args() - step_mseconds = (time.time() - self.step_time) * 1000 - step_loss = cb_params.net_outputs - - if isinstance(step_loss, (tuple, list)) and isinstance(step_loss[0], Tensor): - step_loss = step_loss[0] - if isinstance(step_loss, Tensor): - step_loss = np.mean(step_loss.asnumpy()) - - self.losses.append(step_loss) - cur_step_in_epoch = int((cb_params.cur_step_num - 1) % cb_params.batch_num) + 1 - - if isinstance(step_loss, float) and (np.isnan(step_loss) or np.isinf(step_loss)): - raise ValueError("Epoch: [{:3d}/{:3d}], step: [{:5d}/{:5d}]. " - "Invalid loss, terminating training.".format( - cb_params.cur_epoch_num - 1, cb_params.epoch_num, - cur_step_in_epoch, cb_params.batch_num)) - - if self._per_print_times != 0 and cb_params.cur_step_num % self._per_print_times == 0: - print("Epoch: [{:3d}/{:3d}], step: [{:5d}/{:5d}], " - "loss: [{:5.4f}], avg loss: [{:5.4f}], time: [{:5.4f}ms]".format( - cb_params.cur_epoch_num, cb_params.epoch_num, - cur_step_in_epoch, int(cb_params.batch_num), - step_loss, np.mean(self.losses), - step_mseconds), flush=True) diff --git a/official/cv/lenet_quant/train_quant.py b/official/cv/lenet_quant/train_quant.py deleted file mode 100644 index fc6229c672ff3a2b9b6261bb153c7e30fe7a9678..0000000000000000000000000000000000000000 --- a/official/cv/lenet_quant/train_quant.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -######################## train lenet example ######################## -train lenet and get network model files(.ckpt) : -python train.py --data_path /YourDataPath -""" - -import os -import argparse -import mindspore.nn as nn -from mindspore import context -from mindspore.train.serialization import load_checkpoint -from mindspore.train.callback import ModelCheckpoint, CheckpointConfig -from mindspore.train import Model -from mindspore.nn.metrics import Accuracy -from mindspore.compression.quant import QuantizationAwareTraining -from mindspore.compression.quant.quant_utils import load_nonquant_param_into_quant_net -from mindspore.common import set_seed -from src.dataset import create_dataset -from src.config import mnist_cfg as cfg -from src.lenet_fusion import LeNet5 as LeNet5Fusion -from src.loss_monitor import LossMonitor - -set_seed(1) - -parser = argparse.ArgumentParser(description='MindSpore MNIST 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="./MNIST_Data", - help='path where the dataset is saved') -parser.add_argument('--ckpt_path', type=str, default="", - help='if mode is test, must provide path where the trained ckpt file') -args = parser.parse_args() - -if __name__ == "__main__": - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target) - ds_train = create_dataset(os.path.join(args.data_path, "train"), cfg.batch_size, 1) - step_size = ds_train.get_dataset_size() - - if args.device_target == "GPU": - context.set_context(enable_graph_kernel=True) - # define fusion network - network = LeNet5Fusion(cfg.num_classes) - - # load quantization aware network checkpoint - param_dict = load_checkpoint(args.ckpt_path) - load_nonquant_param_into_quant_net(network, param_dict) - - # convert fusion network to quantization aware network - quantizer = QuantizationAwareTraining(quant_delay=900, - bn_fold=False, - per_channel=[True, False], - symmetric=[True, False]) - network = quantizer.quantize(network) - - # define network loss - net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction="mean") - # define network optimization - net_opt = nn.Momentum(network.trainable_params(), cfg.lr, cfg.momentum) - - # call back and monitor - config_ckpt = CheckpointConfig(save_checkpoint_steps=cfg.epoch_size * step_size, - keep_checkpoint_max=cfg.keep_checkpoint_max) - ckpt_callback = ModelCheckpoint(prefix="checkpoint_lenet", config=config_ckpt) - - # define model - model = Model(network, net_loss, net_opt, metrics={"Accuracy": Accuracy()}) - - print("============== Starting Training ==============") - model.train(cfg['epoch_size'], ds_train, callbacks=[ckpt_callback, LossMonitor()], - dataset_sink_mode=True) - print("============== End Training ==============") diff --git a/official/cv/mobilenetv2_quant/README_CN.md b/official/cv/mobilenetv2_quant/README_CN.md deleted file mode 100644 index 10730046fc684e88976457050761fc7e4fe54295..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/README_CN.md +++ /dev/null @@ -1,323 +0,0 @@ -# 鐩綍 - -<!-- TOC --> - -- [鐩綍](#鐩綍) -- [MobileNetV2鎻忚堪](#mobilenetv2鎻忚堪) -- [妯″瀷鏋舵瀯](#妯″瀷鏋舵瀯) -- [鏁版嵁闆哴(#鏁版嵁闆�) -- [鐗规€(#鐗规€�) - - [娣峰悎绮惧害](#娣峰悎绮惧害) - - [閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌](#閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌) -- [鐜瑕佹眰](#鐜瑕佹眰) -- [鑴氭湰璇存槑](#鑴氭湰璇存槑) - - [鑴氭湰鍜屾牱渚嬩唬鐮乚(#鑴氭湰鍜屾牱渚嬩唬鐮�) - - [鑴氭湰鍙傛暟](#鑴氭湰鍙傛暟) - - [璁粌杩囩▼](#璁粌杩囩▼) - - [鐢ㄦ硶](#鐢ㄦ硶) - - [鍚姩](#鍚姩) - - [缁撴灉](#缁撴灉) - - [璇勪及杩囩▼](#璇勪及杩囩▼) - - [鐢ㄦ硶](#鐢ㄦ硶-1) - - [鍚姩](#鍚姩-1) - - [缁撴灉](#缁撴灉-1) - - [妯″瀷瀵煎嚭](#妯″瀷瀵煎嚭) - - [Ascend 310 鎺ㄧ悊](#ascend-310-鎺ㄧ悊) -- [妯″瀷鎻忚堪](#妯″瀷鎻忚堪) - - [鎬ц兘](#鎬ц兘) - - [璁粌鎬ц兘](#璁粌鎬ц兘) - - [璇勪及鎬ц兘](#璇勪及鎬ц兘) -- [闅忔満鎯呭喌璇存槑](#闅忔満鎯呭喌璇存槑) -- [ModelZoo涓婚〉](#modelzoo涓婚〉) - -<!-- /TOC --> - -# MobileNetV2鎻忚堪 - -MobileNetV2缁撳悎纭欢鎰熺煡绁炵粡缃戠粶鏋舵瀯鎼滅储锛圢AS锛夊拰NetAdapt绠楁硶锛屽凡缁忓彲浠ョЩ妞嶅埌鎵嬫満CPU涓婅繍琛岋紝鍚庣画闅忔柊鏋舵瀯杩涗竴姝ヤ紭鍖栨敼杩涖€傦紙2019骞�11鏈�20鏃ワ級 - -[璁烘枃](https://arxiv.org/pdf/1905.02244)锛欻oward, Andrew, Mark Sandler, Grace Chu, Liang-Chieh Chen, Bo Chen, Mingxing Tan, Weijun Wang et al."Searching for MobileNetV2."In Proceedings of the IEEE International Conference on Computer Vision, pp. 1314-1324.2019. - -姝や负MobileNetV2鐨勯噺鍖栫綉缁溿€� - -# 妯″瀷鏋舵瀯 - -MobileNetV2鎬讳綋缃戠粶鏋舵瀯濡備笅锛� - -[閾炬帴](https://arxiv.org/pdf/1905.02244) - -# 鏁版嵁闆� - -浣跨敤鐨勬暟鎹泦锛歔imagenet](http://www.image-net.org/) - -- 鏁版嵁闆嗗ぇ灏忥細125G锛屽叡1000涓被銆�1.2涓囧紶褰╄壊鍥惧儚 - - - 璁粌闆�: 120G锛屽叡1.2涓囧紶鍥惧儚 - - 娴嬭瘯闆嗭細5G锛屽叡5涓囧紶鍥惧儚 - -- 鏁版嵁鏍煎紡锛歊GB - - 娉細鏁版嵁鍦╯rc/dataset.py涓鐞嗐€� - -# 鐗规€� - -## 娣峰悎绮惧害 - -閲囩敤[娣峰悎绮惧害](https://www.mindspore.cn/docs/programming_guide/zh-CN/master/enable_mixed_precision.html) -鐨勮缁冩柟娉曚娇鐢ㄦ敮鎸佸崟绮惧害鍜屽崐绮惧害鏁版嵁鏉ユ彁楂樻繁搴﹀涔犵缁忕綉缁滅殑璁粌閫熷害锛屽悓鏃朵繚鎸佸崟绮惧害璁粌鎵€鑳借揪鍒扮殑缃戠粶绮惧害銆傛贩鍚堢簿搴﹁缁冩彁楂樿绠楅€熷害銆佸噺灏戝唴瀛樹娇鐢ㄧ殑鍚屾椂锛屾敮鎸佸湪鐗瑰畾纭欢涓婅缁冩洿澶х殑妯″瀷鎴栧疄鐜版洿澶ф壒娆$殑璁粌銆� -浠P16绠楀瓙涓轰緥锛屽鏋滆緭鍏ユ暟鎹被鍨嬩负FP32锛孧indSpore鍚庡彴浼氳嚜鍔ㄩ檷浣庣簿搴︽潵澶勭悊鏁版嵁銆傜敤鎴峰彲鎵撳紑INFO鏃ュ織锛屾悳绱⑩€渞educe precision鈥濇煡鐪嬬簿搴﹂檷浣庣殑绠楀瓙銆� - -## 閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌 - -鍙傝€冭鏂嘯Learned Step Size Quantization](https://arxiv.org/abs/1902.08153) -瀵归噺鍖栨劅鐭ヨ缁冭繘浼樺寲锛岄噺鍖栨闀跨敱璁粌瀛︿範寰楀埌锛岃鐗规€у浣庢瘮鐗归噺鍖栧満鏅湁杈冨ソ鏀剁泭锛屼笅杩颁腑绠€绉颁负LSQ銆� -鐢ㄦ埛鍙嚜鐢遍€夋嫨鏄惁浣跨敤LSQ閲忓寲鏂规杩涜閲忓寲銆� - -# 鐜瑕佹眰 - -- 纭欢 (Ascend/GPU) - - 浣跨敤Ascend鎴朑PU鏉ユ惌寤虹‖浠剁幆澧冦€� -- 妗嗘灦 - - [MindSpore](https://www.mindspore.cn/install) -- 濡傞渶鏌ョ湅璇︽儏锛岃鍙傝濡備笅璧勬簮 - - [MindSpore鏁欑▼](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/zh-CN/master/index.html) - -# 鑴氭湰璇存槑 - -## 鑴氭湰鍜屾牱渚嬩唬鐮� - -```python -鈹溾攢鈹€ mobileNetv2_quant - 鈹溾攢鈹€ Readme.md # MobileNetV2-Quant鐩稿叧鎻忚堪 - 鈹溾攢鈹€ ascend310_infer # 瀹炵幇310鎺ㄧ悊婧愪唬鐮� - 鈹溾攢鈹€ scripts - 鈹� 鈹溾攢鈹€run_train.sh # 浣跨敤Ascend鎴朑PU杩涜璁粌鐨剆hell鑴氭湰 - 鈹� 鈹溾攢鈹€run_infer.sh # 浣跨敤Ascend鎴朑PU杩涜璇勪及鐨剆hell鑴氭湰 - 鈹� 鈹溾攢鈹€run_lsq_train.sh # 浣跨敤Ascend鎴朑PU杩涜LSQ璁粌鐨剆hell鑴氭湰 - 鈹� 鈹溾攢鈹€run_lsq_infer.sh # 浣跨敤Ascend鎴朑PU杩涜LSQ璇勪及鐨剆hell鑴氭湰 - 鈹� 鈹溾攢鈹€run_infer_310.sh # Ascend 310 鎺ㄧ悊shell鑴氭湰 - 鈹溾攢鈹€ src - 鈹� 鈹溾攢鈹€config.py # 鍙傛暟閰嶇疆 - 鈹� 鈹溾攢鈹€dataset.py # 鍒涘缓鏁版嵁闆� - 鈹� 鈹溾攢鈹€launch.py # 鍚姩python鑴氭湰 - 鈹� 鈹溾攢鈹€lr_generator.py # 閰嶇疆瀛︿範鐜� - 鈹� 鈹溾攢鈹€mobilenetV2.py # MobileNetV2鏋舵瀯 - 鈹� 鈹溾攢鈹€utils.py # 鎻愪緵鐩戞帶妯″潡 - 鈹溾攢鈹€ train.py # 璁粌鑴氭湰 - 鈹溾攢鈹€ eval.py # 璇勪及鑴氭湰 - 鈹溾攢鈹€ export.py # 瀵煎嚭妫€鏌ョ偣鏂囦欢鍒癮ir/mindir涓� - 鈹溾攢鈹€ export_bin_file.py # 瀵煎嚭ImageNet鏁版嵁闆嗙殑bin鏂囦欢鐢ㄤ簬310鎺ㄧ悊 - 鈹溾攢鈹€ postprocess.py # 310鎺ㄧ悊鍚庡鐞嗚剼鏈� -``` - -## 鑴氭湰鍙傛暟 - -鍦╟onfig.py涓彲浠ュ悓鏃堕厤缃缁冨弬鏁板拰璇勪及鍙傛暟銆� - -- 閰嶇疆MobileNetV2-quant鍜孖mageNet2012鏁版嵁闆嗭紙浠scend鐜閰嶇疆涓轰緥锛岃瑙乻rc/config.py 锛夈€� - - ```python - 'num_classes':1000 # 鏁版嵁闆嗙被鏁� - 'batch_size':134 # 璁粌鎵规澶у皬 - 'epoch_size':60 # Mobilenetv2-quant鐨勮缁冭疆娆� - 'start_epoch':200 # 闈為噺鍖栫綉缁滈璁粌杞 - 'warmup_epochs':0 # 鐑韩杞 - 'lr':0.3 # 瀛︿範鐜� - 'momentum':0.9 # 鍔ㄩ噺 - 'weight_decay':4E-5 # 鏉冮噸琛板噺鍊� - 'loss_scale':1024 # loss_scale鍒濆鍊� - 'label_smooth':0.1 # 鏍囩骞虫粦鍥犲瓙 - 'loss_scale':1024 # loss_scale鍒濆鍊� - 'save_checkpoint':True # 璁粌缁撴潫鍚庢槸鍚︿繚瀛樻鏌ョ偣鏂囦欢 - 'save_checkpoint_epochs':1 # 寮€濮嬩繚瀛樻鏌ョ偣鏂囦欢鐨勬楠� - 'keep_checkpoint_max':300 # 鍙繚鐣欐渶鍚庝竴涓猭eep_checkpoint_max妫€鏌ョ偣 - 'save_checkpoint_path':'./checkpoint' # 妫€鏌ョ偣鏂囦欢淇濆瓨鐨勭粷瀵瑰叏璺緞 - ``` - -## 璁粌杩囩▼ - -### 鐢ㄦ硶 - -浣跨敤python鎴杝hell鑴氭湰寮€濮嬭缁冦€俿hell鑴氭湰鐨勪娇鐢ㄦ柟娉曞涓嬶細 - -浼犵粺閲忓寲鎰熺煡璁粌锛堥粯璁わ級锛� - -- bash run_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\锛堝彲閫夛級 - -- bash run_train.sh [GPU] [DEVICE_ID_LIST] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\锛堝彲閫夛級 - -閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌锛� - -- bash run_lsq_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH] - -- bash run_lsq_train.sh [GPU] [DEVICE_ID_LIST] [DATASET_PATH] [PRETRAINED_CKPT_PATH] - - `PRETRAINED_CKPT_PATH` 鏄彲閫夋嫨鐨勯€夐」锛屽鏋滅敤鎴烽厤缃閫夐」锛屽垯鍩轰簬鐢ㄦ埛鎸囧畾鐨勯璁粌妯″瀷杩涜閲忓寲锛屾垜浠洿鎺ㄨ崘鐢ㄦ埛鍩轰簬棰勮缁冩ā鍨嬮噺鍖栥€� - - `RANK_TABLE_FILE` 鏄湪Ascned涓婅繍琛屽垎甯冨紡浠诲姟鏃禜CCL鐨勯厤缃枃浠躲€� - -### 鍚姩 - -``` bash - # 璁粌绀轰緥-浼犵粺閲忓寲鎰熺煡璁粌锛堥粯璁わ級 - python锛� - Ascend: python train.py --device_target Ascend --dataset_path ~/imagenet/train/ - GPU: python train.py --device_target GPU --dataset_path ~/imagenet/train/ - shell锛� - Ascend: bash run_train.sh Ascend ~/hccl_8p.json ~/imagenet/train/ - GPU: bash run_train.sh GPU 1,2 ~/imagenet/train/ ~/mobilenet.ckpt - - # 璁粌绀轰緥-閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌 - python锛� - Ascend: python train.py --device_target Ascend --dataset_path ~/imagenet/train/ \ - --pre_trained ~/mobilenet.ckpt --optim_option "LEARNED_SCALE" - GPU: python train.py --device_target GPU --dataset_path ~/imagenet/train/ \ - --pre_trained ~/mobilenet.ckpt --optim_option "LEARNED_SCALE" - shell锛� - Ascend: bash run_lsq_train.sh Ascend ~/hccl_8p.json ~/imagenet/train/ ~/mobilenet.ckpt - GPU: bash run_lsq_train.sh GPU 1,2 ~/imagenet/train/ ~/mobilenet.ckpt -``` - -### 缁撴灉 - -璁粌缁撴灉淇濆瓨鍦ㄧず渚嬭矾寰勪腑銆俙Ascend`澶勭悊鍣ㄨ缁冪殑妫€鏌ョ偣榛樿淇濆瓨鍦╜./train/device$i/checkpoint`锛岃缁冩棩蹇楅噸瀹氬悜鍒癭./train/device$i/train.log`銆俙GPU`澶勭悊鍣ㄨ缁冪殑妫€鏌ョ偣榛樿淇濆瓨鍦╜./train/checkpointckpt_$i`涓紝璁粌鏃ュ織閲嶅畾鍚戝埌`./train/train.log`涓€� -`train.log`鍐呭濡備笅锛� - -```log -epoch:[ 0/200], step:[ 624/ 625], loss:[5.258/5.258], time:[140412.236], lr:[0.100] -epoch time:140522.500, per step time:224.836, avg loss:5.258 -epoch:[ 1/200], step:[ 624/ 625], loss:[3.917/3.917], time:[138221.250], lr:[0.200] -epoch time:138331.250, per step time:221.330, avg loss:3.917 -``` - -## 璇勪及杩囩▼ - -### 鐢ㄦ硶 - -浣跨敤python鎴杝hell鑴氭湰寮€濮嬭瘎浼般€俿hell鑴氭湰鐨勪娇鐢ㄦ柟娉曞涓嬶細 - -浼犵粺閲忓寲鎰熺煡璁粌锛堥粯璁わ級锛� - -- Ascend: bash run_infer.sh Ascend [DATASET_PATH] [CHECKPOINT_PATH] -- GPU: bash run_infer.sh GPU [DATASET_PATH] [CHECKPOINT_PATH] - -閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌锛� - -- Ascend: bash run_lsq_infer.sh Ascend [DATASET_PATH] [CHECKPOINT_PATH] -- GPU: bash run_lsq_infer.sh GPU [DATASET_PATH] [CHECKPOINT_PATH] - -### 鍚姩 - -```bash -# 鎺ㄧ悊绀轰緥-浼犵粺閲忓寲鎰熺煡璁粌锛堥粯璁わ級 -python锛� - Ascend: python eval.py --device_target Ascend --dataset_path [VAL_DATASET_PATH] --checkpoint_path ~/train/mobilenet-60_1601.ckpt - GPU: python eval.py --device_target GPU --dataset_path [VAL_DATASET_PATH] --checkpoint_path ~/train/mobilenet-60_1601.ckpt -shell: - Ascend: bash run_infer.sh Ascend ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt - GPU: bash run_infer.sh GPU ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt - -# 鎺ㄧ悊绀轰緥-閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌 -python锛� - Ascend: python eval.py --device_target Ascend --dataset_path ~/imagenet/val/ \ - --checkpoint_path ~/train/mobilenet-60_1601.ckpt --optim_option "LEARNED_SCALE" - GPU: python eval.py --device_target GPU --dataset_path ~/imagenet/val/ \ - --checkpoint_path ~/train/mobilenet-60_1601.ckpt --optim_option "LEARNED_SCALE" -shell: - Ascend: bash run_lsq_infer.sh Ascend ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt - GPU: bash run_lsq_infer.sh GPU ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt -``` - -> 璁粌杩囩▼涓彲浠ョ敓鎴愭鏌ョ偣銆� - -### 缁撴灉 - -鎺ㄧ悊缁撴灉淇濆瓨鍦ㄧず渚嬭矾寰勶紝鍙互鍦╜./val/infer.log`涓壘鍒板涓嬬粨鏋滐細 - -```log -result:{'acc':0.71976314102564111} -``` - -## 妯″瀷瀵煎嚭 - -```python -python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --device_target [PLATFORM] --optim_option [OptimizeOption] -``` - -`EXPORT_FORMAT` 鍙€� ["AIR", "MINDIR"]. - -`OptimizeOption` 鍙€� ["QAT", "LEARNED_SCALE"]. - -## Ascend 310 鎺ㄧ悊 - -鍦ㄦ帹鐞嗕箣鍓嶉渶瑕佸湪鏄囪吘910鐜涓婂畬鎴怉IR妯″瀷鐨勫鍑恒€� -骞朵娇鐢╡xport_bin_file.py瀵煎嚭ImageNet鏁版嵁闆嗙殑bin鏂囦欢鍜屽搴旂殑label鏂囦欢锛� - -```log -python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH] -``` - -鎵ц鎺ㄧ悊骞跺緱鍒版帹鐞嗙簿搴︼細 - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] -``` - -鎮ㄥ彲浠ラ€氳繃acc.log鏂囦欢鏌ョ湅缁撴灉銆俀AT閲忓寲鎺ㄧ悊鍑嗙‘鎬у涓嬶細 - -```log -'Accuracy':0.7221 -``` - -# 妯″瀷鎻忚堪 - -## 鎬ц兘 - -### 璁粌鎬ц兘 - -| 鍙傛暟 | MobilenetV2 | MobilenetV2 | -| ---------------| ----------------------------------------| ---------------------------- | -| 妯″瀷鐗堟湰 | V2 | V2 | -| 閲忓寲鏂规 | 浼犵粺閲忓寲鎰熺煡璁粌锛堥粯璁わ級 |閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌 | -| 閲忓寲绛栫暐 | W:8bit, A:8bit | W:4bit (棣栧熬灞備负 8bit), A:8bit| -| 璧勬簮 | Ascend 910锛汣PU 2.60GHz锛�192鏍革紱鍐呭瓨 755G锛涚郴缁� Euler2.8 |Ascend 910锛汣PU 2.60GHz锛�192鏍革紱鍐呭瓨 755G锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2021-07-05 |2021-04-30 | -| MindSpore鐗堟湰 | 1.3.0 |1.3.0 | -| 鏁版嵁闆� | ImageNet |ImageNet | -| 璁粌鍙傛暟 | src/config.py |src/config.py | -| 浼樺寲鍣� | Momentum |Momentum | -| 鎹熷け鍑芥暟 | Softmax浜ゅ弶鐔� |Softmax浜ゅ弶鐔� | -| 杈撳嚭 | ckpt鏂囦欢 |ckpt鏂囦欢 | -| 鎹熷け | 1.913 | | -| 鍑嗙‘鐜� | | | -| 鎬绘椂闀� | 16 h | | -| 鍙傛暟(M) | batch_size=192, epoch=60 |batch_size=192, epoch=40 | -| 寰皟妫€鏌ョ偣 | | | -| 鎺ㄧ悊妯″瀷 | | | - -#### 璇勪及鎬ц兘 - -| 鍙傛暟 | | | -| ------------------ | --------------------------|------------------------------ | -| 妯″瀷鐗堟湰 | V2 |V2 | -| 閲忓寲鏂规 | 浼犵粺閲忓寲鎰熺煡璁粌锛堥粯璁わ級 |閲忓寲姝ラ暱鍙涔犵殑閲忓寲鎰熺煡璁粌 | -| 閲忓寲绛栫暐 | W:8bit, A:8bit | W:4bit (棣栧熬灞備负 8bit), A:8bit| -| 璧勬簮 | Ascend 910锛涚郴缁� Euler2.8 | Ascend 910锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2021-07-05 |2021-04-30 | -| MindSpore鐗堟湰 | 1.3.0 | 1.3.0 | -| 鏁版嵁闆� | ImageNet, 1.2W | ImageNet, 1.2W | -| 鎵规澶у皬 | 130锛�8P锛� | | -| 杈撳嚭 | 姒傜巼 | 姒傜巼 | -| 鍑嗙‘鐜� | ACC1[71.78%] ACC5[90.90%] | | -| 閫熷害 | 200姣/姝� | | -| 鎬绘椂闀� | 5鍒嗛挓 | | -| 鎺ㄧ悊妯″瀷 | | | - -# 闅忔満鎯呭喌璇存槑 - -`dataset.py`涓缃簡鈥渃reate_dataset鈥濆嚱鏁板唴鐨勭瀛愶紝鍚屾椂杩樹娇鐢ㄤ簡train.py涓殑闅忔満绉嶅瓙銆� - -# ModelZoo涓婚〉 - -璇锋祻瑙堝畼缃慬涓婚〉](https://gitee.com/mindspore/models)銆� diff --git a/official/cv/mobilenetv2_quant/Readme.md b/official/cv/mobilenetv2_quant/Readme.md deleted file mode 100644 index fa8ce0c44328796ccc5e13a06b30b0779aad1423..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/Readme.md +++ /dev/null @@ -1,320 +0,0 @@ -# Contents - -- [Contents](#contents) -- [MobileNetV2 Description](#mobilenetv2-description) -- [Model architecture](#model-architecture) -- [Dataset](#dataset) -- [Features](#features) - - [Mixed Precision](#mixed-precision) - - [Learned Step Size Quantization](#learned-step-size-quantization) -- [Environment Requirements](#environment-requirements) -- [Script description](#script-description) - - [Script and sample code](#script-and-sample-code) - - [Script Parameters](#script-parameters) - - [Training process](#training-process) - - [Usage](#usage) - - [Launch](#launch) - - [Result](#result) - - [Evaluation process](#evaluation-process) - - [Usage](#usage-1) - - [Launch](#launch-1) - - [Result](#result-1) - - [Model Export](#model-export) - - [Ascend 310 inference](#ascend-310-inference) -- [Model description](#model-description) - - [Performance](#performance) - - [Training Performance](#training-performance) - - [Evaluation Performance](#evaluation-performance) -- [Description of Random Situation](#description-of-random-situation) -- [ModelZoo Homepage](#modelzoo-homepage) - -# [MobileNetV2 Description](#contents) - -MobileNetV2 is tuned to mobile phone CPUs through a combination of hardware- aware network architecture search (NAS) complemented by the NetAdapt algorithm and then subsequently improved through novel architecture advances.Nov 20, 2019. - -[Paper](https://arxiv.org/pdf/1905.02244) Howard, Andrew, Mark Sandler, Grace Chu, Liang-Chieh Chen, Bo Chen, Mingxing Tan, Weijun Wang et al. "Searching for MobileNetV2." In Proceedings of the IEEE International Conference on Computer Vision, pp. 1314-1324. 2019. - -This is the quantitative network of MobileNetV2. - -# [Model architecture](#contents) - -The overall network architecture of MobileNetV2 is show below: - -[Link](https://arxiv.org/pdf/1905.02244) - -# [Dataset](#contents) - -Dataset used: [imagenet](http://www.image-net.org/) - -- Dataset size: ~125G, 1.2W colorful images in 1000 classes - - Train: 120G, 1.2W images - - Test: 5G, 50000 images -- Data format: RGB images. - - Note: Data will be processed in src/dataset.py - -# [Features](#contents) - -## [Mixed Precision](#contents) - -The [mixed precision](https://www.mindspore.cn/docs/programming_guide/en/master/enable_mixed_precision.html) training method accelerates the deep learning neural network training process by using both the single-precision and half-precision data formats, and maintains the network precision achieved by the single-precision training at the same time. Mixed precision training can accelerate the computation process, reduce memory usage, and enable a larger model or batch size to be trained on specific hardware. -For FP16 operators, if the input data type is FP32, the backend of MindSpore will automatically handle it with reduced precision. Users could check the reduced-precision operators by enabling INFO log and then searching 鈥榬educe precision鈥�. - -## [Learned Step Size Quantization](#contents) - -Inspired by paper [Learned Step Size Quantization](https://arxiv.org/abs/1902.08153) -, we proposed an optimize option, whose quantization scale is learned during the fine-tune process. -This feature has good benefits for low bits quantization scenarios, which is referred to as LSQ. -Users are free to choose whether to use the LEARNED_SCALE optimize option for quantization. - -# [Environment Requirements](#contents) - -- Hardware (Ascend/GPU) - - Prepare hardware environment with Ascend or GPU. -- Framework - - [MindSpore](https://www.mindspore.cn/install/en) -- For more information, please check the resources below: - - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/en/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/en/master/index.html) - -# [Script description](#contents) - -## [Script and sample code](#contents) - -```python -鈹溾攢鈹€ mobileNetv2_quant - 鈹溾攢鈹€ Readme.md # descriptions about MobileNetV2-Quant - 鈹溾攢鈹€ ascend310_infer # application for 310 inference - 鈹溾攢鈹€ scripts - 鈹� 鈹溾攢鈹€run_train.sh # shell script for train on Ascend or GPU - 鈹� 鈹溾攢鈹€run_infer.sh # shell script for evaluation on Ascend or GPU - 鈹� 鈹溾攢鈹€run_lsq_train.sh # shell script for train (using the LEARNED_SCALE optimize option) on Ascend or GPU - 鈹� 鈹溾攢鈹€run_lsq_infer.sh # shell script for evaluation (using the LEARNED_SCALE optimize option) on Ascend or GPU - 鈹� 鈹溾攢鈹€run_infer_310.sh # shell script for 310 inference - 鈹溾攢鈹€ src - 鈹� 鈹溾攢鈹€config.py # parameter configuration - 鈹� 鈹溾攢鈹€dataset.py # creating dataset - 鈹� 鈹溾攢鈹€launch.py # start python script - 鈹� 鈹溾攢鈹€lr_generator.py # learning rate config - 鈹� 鈹溾攢鈹€mobilenetV2.py # MobileNetV2 architecture - 鈹� 鈹溾攢鈹€utils.py # supply the monitor module - 鈹溾攢鈹€ train.py # training script - 鈹溾攢鈹€ eval.py # evaluation script - 鈹溾攢鈹€ export.py # export checkpoint files into air/mindir - 鈹溾攢鈹€ export_bin_file.py # export bin file of ImageNet for 310 inference - 鈹溾攢鈹€ postprocess.py # post process for 310 inference -``` - -## [Script Parameters](#contents) - -Parameters for both training and evaluation can be set in config.py - -- config for MobileNetV2-quant, ImageNet2012 dataset锛圵e take the environment configuration of ascend as an example here, and you will get more detail in src/config.py锛� - - ```python - 'num_classes': 1000 # the number of classes in the dataset - 'batch_size': 134 # training batch size - 'epoch_size': 60 # training epochs of mobilenetv2-quant - 'start_epoch':200 # pretraining epochs of unquantative network - 'warmup_epochs': 0 # number of warmup epochs - 'lr': 0.3 #learning rate - 'momentum': 0.9 # momentum - 'weight_decay': 4e-5 # weight decay value - 'loss_scale': 1024 # the initial loss_scale value - 'label_smooth': 0.1 #label smooth factor - 'loss_scale': 1024 # the initial loss_scale value - 'save_checkpoint':True # whether save checkpoint file after training finish - 'save_checkpoint_epochs': 1 # the step from which start to save checkpoint file. - 'keep_checkpoint_max': 300 # only keep the last keep_checkpoint_max checkpoint - 'save_checkpoint_path': './checkpoint' # the absolute full path to save the checkpoint file - ``` - -## [Training process](#contents) - -### Usage - -You can start training using python or shell scripts. The usage of shell scripts as follows: - -For quantization aware training (default): - -- bash run_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\(optional) -- bash run_train.sh [GPU] [DEVICE_ID_LIST] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\(optional) - -For Learned Step Size Quantization: - -- bash run_lsq_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH] -- bash run_lsq_train.sh [GPU] [DEVICE_ID_LIST] [DATASET_PATH] [PRETRAINED_CKPT_PATH] - -`PRETRAINED_CKPT_PATH` is optional. If it is given, quantization is based on the specified pre training ckpt file. We recommend users to execute quantization based on the pre training ckpt file. - -`RANK_TABLE_FILE` is HCCL configuration file when running on Ascend. -> The common restrictions on using the distributed service are as follows. For details, see the HCCL documentation. -> -> - In a single-node system, a cluster of 1, 2, 4, or 8 devices is supported. In a multi-node system, a cluster of 8 x N devices is supported. -> - Each host has four devices numbered 0 to 3 and four devices numbered 4 to 7 deployed on two different networks. During training of 2 or 4 devices, the devices must be connected and clusters cannot be created across networks. - -### Launch - -``` bash - # training example for quantization aware training (default) - python锛� - Ascend: python train.py --device_target Ascend --dataset_path ~/imagenet/train/ - GPU: python train.py --device_target GPU --dataset_path ~/imagenet/train/ - shell锛� - Ascend: bash run_train.sh Ascend ~/hccl_8p.json ~/imagenet/train/ - GPU: bash run_train.sh GPU 1,2 ~/imagenet/train/ ~/mobilenet.ckpt - - # training example for Learned Step Size Quantization - python锛� - Ascend: python train.py --device_target Ascend --dataset_path ~/imagenet/train/ \ - --pre_trained ~/mobilenet.ckpt --optim_option "LEARNED_SCALE" - GPU: python train.py --device_target GPU --dataset_path ~/imagenet/train/ \ - --pre_trained ~/mobilenet.ckpt --optim_option "LEARNED_SCALE" - shell锛� - Ascend: bash run_lsq_train.sh Ascend ~/hccl_8p.json ~/imagenet/train/ ~/mobilenet.ckpt - GPU: bash run_lsq_train.sh GPU 1,2 ~/imagenet/train/ ~/mobilenet.ckpt -``` - -### Result - -Training result will be stored in the example path. Checkpoints trained by `Ascend` will be stored at `./train/device$i/checkpoint` by default, and training log will be redirected to `./train/device$i/train.log`. Checkpoints trained by `GPU` will be stored in `./train/checkpointckpt_$i` by default, and training log will be redirected to `./train/train.log`. -`train.log` is as follows: - -``` log -epoch: [ 0/200], step:[ 624/ 625], loss:[5.258/5.258], time:[140412.236], lr:[0.100] -epoch time: 140522.500, per step time: 224.836, avg loss: 5.258 -epoch: [ 1/200], step:[ 624/ 625], loss:[3.917/3.917], time:[138221.250], lr:[0.200] -epoch time: 138331.250, per step time: 221.330, avg loss: 3.917 -``` - -## [Evaluation process](#contents) - -### Usage - -You can start evaluating using python or shell scripts. The usage of shell scripts as follows: - -For quantization aware training (default): - -- Ascend: bash run_infer.sh Ascend [DATASET_PATH] [CHECKPOINT_PATH] -- GPU: bash run_infer.sh GPU [DATASET_PATH] [CHECKPOINT_PATH] - -For Learned Step Size Quantization: - -- Ascend: bash run_lsq_infer.sh Ascend [DATASET_PATH] [CHECKPOINT_PATH] -- GPU: bash run_lsq_infer.sh GPU [DATASET_PATH] [CHECKPOINT_PATH] - -### Launch - -```bash -# training example for quantization aware training (default) -python锛� - Ascend: python eval.py --device_target Ascend --dataset_path [VAL_DATASET_PATH] --checkpoint_path ~/train/mobilenet-60_1601.ckpt - GPU: python eval.py --device_target GPU --dataset_path [VAL_DATASET_PATH] --checkpoint_path ~/train/mobilenet-60_1601.ckpt - -shell: - Ascend: bash run_infer.sh Ascend ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt - GPU: bash run_infer.sh GPU ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt - -# training example for Learned Step Size Quantization -python锛� - Ascend: python eval.py --device_target Ascend --dataset_path ~/imagenet/val/ \ - --checkpoint_path ~/train/mobilenet-60_1601.ckpt --optim_option "LEARNED_SCALE" - GPU: python eval.py --device_target GPU --dataset_path ~/imagenet/val/ \ - --checkpoint_path ~/train/mobilenet-60_1601.ckpt --optim_option "LEARNED_SCALE" - -shell: - Ascend: bash run_lsq_infer.sh Ascend ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt - GPU: bash run_lsq_infer.sh GPU ~/imagenet/val/ ~/train/mobilenet-60_1601.ckpt -``` - -> checkpoint can be produced in training process. - -### Result - -Inference result will be stored in the example path, you can find result like the following in `./val/infer.log`. - -``` log -result: {'acc': 0.71976314102564111} -``` - -## [Model Export](#contents) - -```python -python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --device_target [PLATFORM] --optim_option [OptimizeOption] -``` - -`EXPORT_FORMAT` should be in ["AIR", "MINDIR"]. -`OptimizeOption` should be in ["QAT", "LEARNED_SCALE"]. - -## [Ascend 310 inference](#contents) - -You should export AIR model at Ascend 910 before running the command below. -You can use export_bin_file.py to export ImageNet bin and label for 310 inference. - -```python -python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH] -``` - -Run run_infer_310.sh and get the accuracy锛� - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] -``` - -You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows: - -```log -'Accuracy':0.7221 -``` - -# [Model description](#contents) - -## [Performance](#contents) - -### Training Performance - -| Parameters | MobilenetV2 | MobilenetV2 | -| -------------------------- | --------------------------------------------------| --------------------------------------------------| -| Model Version | V2 | V2 | -| Optimize Option | QAT | LEARNED_SCALE | -| Quantization Strategy | W:8bit, A:8bit | W:4bit (The first and last layers are 8bit), A:8bit| -| Resource | Ascend 910; cpu 2.60GHz, 192cores; memory 755G; OS Euler2.8 | Ascend 910; cpu 2.60GHz, 192cores; memory 755G; OS Euler2.8 | -| uploaded Date | 07/05/2021 | 04/30/2021 | -| MindSpore Version | 1.3.0 | 1.3.0 | -| Dataset | ImageNet | ImageNet | -| Training Parameters | src/config.py | src/config.py | -| Optimizer | Momentum | Momentum | -| Loss Function | SoftmaxCrossEntropy | SoftmaxCrossEntropy | -| outputs | ckpt file | ckpt file | -| Loss | 1.913 | | -| Accuracy | | | -| Total time | 16h | | -| Params (M) | batch_size=192, epoch=60 | batch_size=192, epoch=40 | -| Checkpoint for Fine tuning | | | -| Model for inference | | | - -#### Evaluation Performance - -| Parameters | | | -| -------------------------- | ----------------------------- | ----------------------------- | -| Model Version | V2 | V2 | -| Optimize Option | QAT | LEARNED_SCALE | -| Quantization Strategy | W:8bit, A:8bit | W:4bit (The first and last layers are 8bit), A:8bit| -| Resource | Ascend 910; OS Euler2.8 | Ascend 910; OS Euler2.8 | -| uploaded Date | 07/05/2021 | 04/30/2021 | -| MindSpore Version | 1.3.0 | 1.3.0 | -| Dataset | ImageNet, 1.2W | ImageNet, 1.2W | -| batch_size | 130(8P) | | -| outputs | probability | probability | -| Accuracy | ACC1[71.78%] ACC5[90.90%] | | -| Speed | 200ms/step | | -| Total time | 5min | | -| Model for inference | | | - -# [Description of Random Situation](#contents) - -In dataset.py, we set the seed inside 鈥渃reate_dataset" function. We also use random seed in train.py. - -# [ModelZoo Homepage](#contents) - -Please check the official [homepage](https://gitee.com/mindspore/models). diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/inc/ModelProcess.h b/official/cv/mobilenetv2_quant/ascend310_infer/inc/ModelProcess.h deleted file mode 100644 index 9acb683bee2a037a98878d98c0605985701f913a..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/inc/ModelProcess.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MODELPROCESS_H -#define MODELPROCESS_H - -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* ModelProcess -*/ -class ModelProcess { - public: - /** - * @brief Constructor - */ - ModelProcess(); - - /** - * @brief Destructor - */ - ~ModelProcess(); - - /** - * @brief load model from file with mem - * @param [in] modelPath: model path - * @return result - */ - Result LoadModelFromFileWithMem(const char *modelPath); - - /** - * @brief unload model - */ - void Unload(); - - /** - * @brief create model desc - * @return result - */ - Result CreateDesc(); - - /** - * @brief destroy desc - */ - void DestroyDesc(); - - /** - * @brief create model input - * @param [in] inputDataBuffer: input buffer - * @param [in] bufferSize: input buffer size - * @return result - */ - Result CreateInput(void *inputDataBuffer, size_t bufferSize); - - /** - * @brief destroy input resource - */ - void DestroyInput(); - - /** - * @brief create output buffer - * @return result - */ - Result CreateOutput(); - - /** - * @brief destroy output resource - */ - void DestroyOutput(); - - /** - * @brief model execute - * @return result - */ - Result Execute(); - - /** - * @brief dump model output result to file - */ - void DumpModelOutputResult(char *output_name); - - /** - * @brief get model output result - */ - void OutputModelResult(); - - private: - uint32_t modelId_; - size_t modelMemSize_; - size_t modelWeightSize_; - void *modelMemPtr_; - void *modelWeightPtr_; - bool loadFlag_; // model load flag - aclmdlDesc *modelDesc_; - aclmdlDataset *input_; - aclmdlDataset *output_; -}; -#endif diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/inc/SampleProcess.h b/official/cv/mobilenetv2_quant/ascend310_infer/inc/SampleProcess.h deleted file mode 100644 index 30a77f4248c948b83d019ee05aaf56dce9a08e26..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/inc/SampleProcess.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef SAMPLEPROCESS_H -#define SAMPLEPROCESS_H - -#include <string> -#include <vector> -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* SampleProcess -*/ -class SampleProcess { - public: - /** - * @brief Constructor - */ - explicit SampleProcess(int32_t deviceId); - - /** - * @brief Destructor - */ - ~SampleProcess(); - - /** - * @brief init reousce - * @return result - */ - Result InitResource(const char *acl_config_path); - - /** - * @brief sample process - * @return result - */ - Result Process(const char *om_path, const char *input_folder); - - void GetAllFiles(std::string path, std::vector<std::string> *files); - - private: - void DestroyResource(); - - int32_t deviceId_; - aclrtContext context_; - aclrtStream stream_; -}; - -#endif diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/inc/utils.h b/official/cv/mobilenetv2_quant/ascend310_infer/inc/utils.h deleted file mode 100644 index b21e418a1f4ad2b8fc0331cf0b37adf73f2703f6..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/inc/utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MINDSPORE_INFERENCE_UTILS_H_ -#define MINDSPORE_INFERENCE_UTILS_H_ - -#include <iostream> -#include <string> - -#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args) -#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args) -#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args) - -typedef enum Result { - SUCCESS = 0, - FAILED = 1 -} Result; - -/** -* Utils -*/ -class Utils { - public: - /** - * @brief create device buffer of file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return device buffer of file - */ - static void *GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize); - - /** - * @brief Read bin file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return buffer of pic - */ - static void* ReadBinFile(std::string fileName, uint32_t *fileSize); -}; -#endif diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/CMakeLists.txt b/official/cv/mobilenetv2_quant/ascend310_infer/src/CMakeLists.txt deleted file mode 100644 index 65961330a3219658f5c46fa430e6c5844f2536a4..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - -# CMake lowest version requirement -cmake_minimum_required(VERSION 3.5.1) -# project information -project(InferClassification) -# Check environment variable -if(NOT DEFINED ENV{ASCEND_HOME}) - message(FATAL_ERROR "please define environment variable:ASCEND_HOME") -endif() - -# Compile options -add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined") - -# Skip build rpath -set(CMAKE_SKIP_BUILD_RPATH True) - -# Set output directory -set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out) - -# Set include directory and library directory -set(FWKACL_LIB_DIR $ENV{ASCEND_HOME}/fwkacllib) -set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib) -set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib) - -# Header path -include_directories(${ACL_LIB_DIR}/include/) -include_directories(${FWKACL_LIB_DIR}/include/) -include_directories(${ATLAS_ACL_LIB_DIR}/include/) -include_directories(${PROJECT_SRC_ROOT}/../inc) - -# add host lib path -link_directories(${ACL_LIB_DIR} ${FWKACL_LIB_DIR}) -find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${FWKACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64) - -add_executable(main utils.cpp - SampleProcess.cpp - ModelProcess.cpp - main.cpp) - -target_link_libraries(main ${acl} gflags pthread) diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/ModelProcess.cpp b/official/cv/mobilenetv2_quant/ascend310_infer/src/ModelProcess.cpp deleted file mode 100644 index 72744284906a6d1b6ee9bc1051ada5872526c101..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/ModelProcess.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/ModelProcess.h" -#include <iostream> -#include <map> -#include <sstream> -#include <algorithm> -#include "../inc/utils.h" - -extern bool g_isDevice; - -ModelProcess::ModelProcess() :modelId_(0), modelMemSize_(0), modelWeightSize_(0), modelMemPtr_(nullptr), -modelWeightPtr_(nullptr), loadFlag_(false), modelDesc_(nullptr), input_(nullptr), output_(nullptr) { -} - -ModelProcess::~ModelProcess() { - Unload(); - DestroyDesc(); - DestroyInput(); - DestroyOutput(); -} - -Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath) { - if (loadFlag_) { - ERROR_LOG("has already loaded a model"); - return FAILED; - } - - aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("query model failed, model file is %s", modelPath); - return FAILED; - } - - ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_); - return FAILED; - } - - ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_); - return FAILED; - } - - ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, - modelMemSize_, modelWeightPtr_, modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("load model from file failed, model file is %s", modelPath); - return FAILED; - } - - loadFlag_ = true; - INFO_LOG("load model %s success", modelPath); - return SUCCESS; -} - -Result ModelProcess::CreateDesc() { - modelDesc_ = aclmdlCreateDesc(); - if (modelDesc_ == nullptr) { - ERROR_LOG("create model description failed"); - return FAILED; - } - - aclError ret = aclmdlGetDesc(modelDesc_, modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("get model description failed"); - return FAILED; - } - - INFO_LOG("create model description success"); - - return SUCCESS; -} - -void ModelProcess::DestroyDesc() { - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } -} - -Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) { - input_ = aclmdlCreateDataset(); - if (input_ == nullptr) { - ERROR_LOG("can't create dataset, create input failed"); - return FAILED; - } - - aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize); - if (inputData == nullptr) { - ERROR_LOG("can't create data buffer, create input failed"); - return FAILED; - } - - aclError ret = aclmdlAddDatasetBuffer(input_, inputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("add input dataset buffer failed"); - aclDestroyDataBuffer(inputData); - inputData = nullptr; - return FAILED; - } - - return SUCCESS; -} - -void ModelProcess::DestroyInput() { - if (input_ == nullptr) { - return; - } - - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); - aclDestroyDataBuffer(dataBuffer); - } - aclmdlDestroyDataset(input_); - input_ = nullptr; -} - -Result ModelProcess::CreateOutput() { - if (modelDesc_ == nullptr) { - ERROR_LOG("no model description, create output failed"); - return FAILED; - } - - output_ = aclmdlCreateDataset(); - if (output_ == nullptr) { - ERROR_LOG("can't create dataset, create output failed"); - return FAILED; - } - - size_t outputSize = aclmdlGetNumOutputs(modelDesc_); - for (size_t i = 0; i < outputSize; ++i) { - size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i); - void *outputBuffer = nullptr; - aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size); - return FAILED; - } - - aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't create data buffer, create output failed"); - aclrtFree(outputBuffer); - return FAILED; - } - - ret = aclmdlAddDatasetBuffer(output_, outputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't add data buffer, create output failed"); - aclrtFree(outputBuffer); - aclDestroyDataBuffer(outputData); - return FAILED; - } - } - - INFO_LOG("create model output success"); - return SUCCESS; -} - -void ModelProcess::DumpModelOutputResult(char *output_name) { - size_t outputNum = aclmdlGetDatasetNumBuffers(output_); - std::string homePath = "./result_Files"; - for (size_t i = 0; i < outputNum; ++i) { - std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin"; - std::string outputFileName = homePath + "/" + fileName; - FILE *outputFile = fopen(outputFileName.c_str(), "wb"); - if (outputFile != nullptr) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void* outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - (void)aclrtFreeHost(outHostData); - return; - } - fwrite(outHostData, len, sizeof(char), outputFile); - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } else { - fwrite(data, len, sizeof(char), outputFile); - } - fclose(outputFile); - outputFile = nullptr; - } else { - ERROR_LOG("create output file [%s] failed", outputFileName.c_str()); - return; - } - } - INFO_LOG("dump data success"); - return; -} - -void ModelProcess::OutputModelResult() { - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void *outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - float *outData = NULL; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - return; - } - outData = reinterpret_cast<float*>(outHostData); - } else { - outData = reinterpret_cast<float*>(data); - } - std::map<float, unsigned int, std::greater<float> > resultMap; - for (unsigned int j = 0; j < len / sizeof(float); ++j) { - resultMap[*outData] = j; - outData++; - } - int cnt = 0; - for (auto it = resultMap.begin(); it != resultMap.end(); ++it) { - // print top 5 - if (++cnt > 5) { - break; - } - INFO_LOG("top %d: index[%d] value[%lf]", cnt, it->second, it->first); - } - if (!g_isDevice) { - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } - } - INFO_LOG("output data success"); - return; -} - -void ModelProcess::DestroyOutput() { - if (output_ == nullptr) { - return; - } - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - (void)aclrtFree(data); - (void)aclDestroyDataBuffer(dataBuffer); - } - - (void)aclmdlDestroyDataset(output_); - output_ = nullptr; -} - -Result ModelProcess::Execute() { - aclError ret = aclmdlExecute(modelId_, input_, output_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("execute model failed, modelId is %u", modelId_); - return FAILED; - } - - INFO_LOG("model execute success"); - return SUCCESS; -} - -void ModelProcess::Unload() { - if (!loadFlag_) { - WARN_LOG("no model had been loaded, unload failed"); - return; - } - - aclError ret = aclmdlUnload(modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("unload model failed, modelId is %u", modelId_); - } - - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } - - if (modelMemPtr_ != nullptr) { - aclrtFree(modelMemPtr_); - modelMemPtr_ = nullptr; - modelMemSize_ = 0; - } - - if (modelWeightPtr_ != nullptr) { - aclrtFree(modelWeightPtr_); - modelWeightPtr_ = nullptr; - modelWeightSize_ = 0; - } - - loadFlag_ = false; - INFO_LOG("unload model success, modelId is %u", modelId_); -} diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/SampleProcess.cpp b/official/cv/mobilenetv2_quant/ascend310_infer/src/SampleProcess.cpp deleted file mode 100644 index 6870f9d8e438e6794f11d7f44ea61136ac8089f3..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/SampleProcess.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/SampleProcess.h" -#include <sys/types.h> -#include <dirent.h> -#include <string.h> -#include <iostream> -#include <fstream> -#include "../inc/utils.h" -#include "../inc/ModelProcess.h" -#include "acl/acl.h" - -extern bool g_isDevice; -using std::string; -using std::vector; - -SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) { - deviceId_ = deviceId; -} - -SampleProcess::~SampleProcess() { - DestroyResource(); -} - -Result SampleProcess::InitResource(const char *aclConfigPath) { - // ACL init - aclError ret = aclInit(aclConfigPath); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl init failed"); - return FAILED; - } - INFO_LOG("acl init success"); - - // open device - ret = aclrtSetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl open device %d failed", deviceId_); - return FAILED; - } - INFO_LOG("open device %d success", deviceId_); - - // create context (set current) - ret = aclrtCreateContext(&context_, deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create context failed"); - return FAILED; - } - INFO_LOG("create context success"); - - // create stream - ret = aclrtCreateStream(&stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create stream failed"); - return FAILED; - } - INFO_LOG("create stream success"); - - // get run mode - aclrtRunMode runMode; - ret = aclrtGetRunMode(&runMode); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl get run mode failed"); - return FAILED; - } - g_isDevice = (runMode == ACL_DEVICE); - INFO_LOG("get run mode success"); - return SUCCESS; -} - -void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) { - DIR *pDir = nullptr; - struct dirent* ptr = nullptr; - if (!(pDir = opendir(path.c_str()))) - return; - while ((ptr = readdir(pDir)) != 0) { - if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) - files->push_back(path + "/" + ptr->d_name); - } - closedir(pDir); -} - -Result SampleProcess::Process(const char *om_path, const char *input_folder) { - // model init - ModelProcess processModel; - - Result ret = processModel.LoadModelFromFileWithMem(om_path); - if (ret != SUCCESS) { - ERROR_LOG("execute LoadModelFromFileWithMem failed"); - return FAILED; - } - - ret = processModel.CreateDesc(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateDesc failed"); - return FAILED; - } - - ret = processModel.CreateOutput(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateOutput failed"); - return FAILED; - } - - std::vector<string> testFile; - GetAllFiles(input_folder, &testFile); - - if (testFile.size() == 0) { - WARN_LOG("no input data under folder"); - } - - // loop begin - for (size_t index = 0; index < testFile.size(); ++index) { - INFO_LOG("start to process file:%s", testFile[index].c_str()); - // model process - uint32_t devBufferSize; - void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize); - if (picDevBuffer == nullptr) { - ERROR_LOG("get pic device buffer failed,index is %zu", index); - return FAILED; - } - ret = processModel.CreateInput(picDevBuffer, devBufferSize); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateInput failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - ret = processModel.Execute(); - if (ret != SUCCESS) { - ERROR_LOG("execute inference failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - int pos = testFile[index].find_last_of('/'); - std::string name = testFile[index].substr(pos+1); - std::string outputname = name.substr(0, name.rfind(".")); - - // print the top 5 confidence values - processModel.OutputModelResult(); - // dump output result to file in the current directory - processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str())); - - // release model input buffer - aclrtFree(picDevBuffer); - processModel.DestroyInput(); - } - // loop end - - return SUCCESS; -} - -void SampleProcess::DestroyResource() { - aclError ret; - if (stream_ != nullptr) { - ret = aclrtDestroyStream(stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy stream failed"); - } - stream_ = nullptr; - } - INFO_LOG("end to destroy stream"); - - if (context_ != nullptr) { - ret = aclrtDestroyContext(context_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy context failed"); - } - context_ = nullptr; - } - INFO_LOG("end to destroy context"); - - ret = aclrtResetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("reset device failed"); - } - INFO_LOG("end to reset device is %d", deviceId_); - - ret = aclFinalize(); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("finalize acl failed"); - } - INFO_LOG("end to finalize acl"); -} - diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/acl.json b/official/cv/mobilenetv2_quant/ascend310_infer/src/acl.json deleted file mode 100644 index 9e26dfeeb6e641a33dae4961196235bdb965b21b..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/acl.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/build.sh b/official/cv/mobilenetv2_quant/ascend310_infer/src/build.sh deleted file mode 100644 index b5979b68e60b673f763a3cac98c5e147e7085291..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/build.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -path_cur=$(cd "`dirname $0`" || exit; pwd) - -function preparePath() { - rm -rf $1 - mkdir -p $1 - cd $1 || exit -} - -function buildA300() { - if [ ! "${ARCH_PATTERN}" ]; then - # set ARCH_PATTERN to acllib when it was not specified by user - export ARCH_PATTERN=acllib - echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}" - else - echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib" - export ARCH_PATTERN=${ARCH_PATTERN}/acllib - fi - - path_build=$path_cur/build - preparePath $path_build - cmake .. - make -j - ret=$? - cd .. - return ${ret} -} - -# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user -if [ ! "${ASCEND_VERSION}" ]; then - export ASCEND_VERSION=ascend-toolkit/latest - echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}" -else - echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user" -fi - -buildA300 - -if [ $? -ne 0 ]; then - exit 1 -fi diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/main.cpp b/official/cv/mobilenetv2_quant/ascend310_infer/src/main.cpp deleted file mode 100644 index ca47f0635efd1618ba9fd85fe63186f55c54e421..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include <gflags/gflags.h> -#include <iostream> -#include <fstream> -#include <memory> -#include "../inc/SampleProcess.h" -#include "../inc/utils.h" - -bool g_isDevice = false; - -DEFINE_string(om_path, "", "om path"); -DEFINE_string(dataset_path, "", "dataset path"); -DEFINE_string(acljson_path, "", "acl json path"); -DEFINE_int32(device_id, 0, "device id"); - -int main(int argc, char **argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - std::string om_path = FLAGS_om_path; - std::string dataset_path = FLAGS_dataset_path; - std::string acljson_path = FLAGS_acljson_path; - int32_t device_id = FLAGS_device_id; - std::ifstream fin(om_path); - if (!fin) { - std::cout << "Invalid om path." << std::endl; - return FAILED; - } - SampleProcess processSample(device_id); - // acl.json is deployed for dump data. - Result ret = processSample.InitResource(acljson_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample init resource failed"); - return FAILED; - } - - ret = processSample.Process(om_path.c_str(), dataset_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample process failed"); - return FAILED; - } - - INFO_LOG("execute sample success"); - return SUCCESS; -} diff --git a/official/cv/mobilenetv2_quant/ascend310_infer/src/utils.cpp b/official/cv/mobilenetv2_quant/ascend310_infer/src/utils.cpp deleted file mode 100644 index 6e669f3f329be5ecfba41595c72f525d4fb428d0..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/ascend310_infer/src/utils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/utils.h" -#include <sys/stat.h> -#include <iostream> -#include <fstream> -#include <cstring> -#include "acl/acl.h" - -extern bool g_isDevice; - -void* Utils::ReadBinFile(std::string fileName, uint32_t *fileSize) { - struct stat sBuf; - int fileStatus = stat(fileName.data(), &sBuf); - if (fileStatus == -1) { - ERROR_LOG("failed to get file"); - return nullptr; - } - if (S_ISREG(sBuf.st_mode) == 0) { - ERROR_LOG("%s is not a file, please enter a file", fileName.c_str()); - return nullptr; - } - - std::ifstream binFile(fileName, std::ifstream::binary); - if (binFile.is_open() == false) { - ERROR_LOG("open file %s failed", fileName.c_str()); - return nullptr; - } - - binFile.seekg(0, binFile.end); - uint32_t binFileBufferLen = binFile.tellg(); - if (binFileBufferLen == 0) { - ERROR_LOG("binfile is empty, filename is %s", fileName.c_str()); - binFile.close(); - return nullptr; - } - - binFile.seekg(0, binFile.beg); - - void* binFileBufferData = nullptr; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&binFileBufferData, binFileBufferLen); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc for binFileBufferData failed"); - binFile.close(); - return nullptr; - } - if (binFileBufferData == nullptr) { - ERROR_LOG("malloc binFileBufferData failed"); - binFile.close(); - return nullptr; - } - } else { - ret = aclrtMalloc(&binFileBufferData, binFileBufferLen, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", binFileBufferLen); - binFile.close(); - return nullptr; - } - } - binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen); - binFile.close(); - *fileSize = binFileBufferLen; - return binFileBufferData; -} - -void* Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize) { - uint32_t inputHostBuffSize = 0; - void* inputHostBuff = Utils::ReadBinFile(fileName, &inputHostBuffSize); - if (inputHostBuff == nullptr) { - return nullptr; - } - if (!g_isDevice) { - void *inBufferDev = nullptr; - uint32_t inBufferSize = inputHostBuffSize; - aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - - ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u", - inBufferSize, inputHostBuffSize); - aclrtFree(inBufferDev); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - aclrtFreeHost(inputHostBuff); - *fileSize = inBufferSize; - return inBufferDev; - } else { - *fileSize = inputHostBuffSize; - return inputHostBuff; - } -} diff --git a/official/cv/mobilenetv2_quant/eval.py b/official/cv/mobilenetv2_quant/eval.py deleted file mode 100644 index 5c914f1a1c9af4d83cc681920c6b70f84e7ee263..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/eval.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Evaluate MobilenetV2 on ImageNet""" - -import os -import argparse - -from mindspore import context -from mindspore import nn -from mindspore.train.model import Model -from mindspore.train.serialization import load_checkpoint, load_param_into_net -from mindspore.compression.common import QuantDtype -from mindspore.compression.quant import QuantizationAwareTraining -from mindspore.compression.quant.quantizer import OptimizeOption -from src.mobilenetV2 import mobilenetV2 -from src.mobilenetv2_mix_quant import mobilenetv2_mix_quant -from src.dataset import create_dataset -from src.config import config_ascend_quant, config_gpu_quant, config_lsq_ascend_quant, config_lsq_gpu_quant - -parser = argparse.ArgumentParser(description='Image classification') -parser.add_argument('--checkpoint_path', type=str, default=None, help='Checkpoint file path') -parser.add_argument('--dataset_path', type=str, default=None, help='Dataset path') -parser.add_argument('--device_target', type=str, default=None, help='Run device target') -parser.add_argument('--optim_option', type=str, default="QAT", help='OptimizeOption') -args_opt = parser.parse_args() - -if __name__ == '__main__': - config_device_target = None - device_id = int(os.getenv('DEVICE_ID')) - if args_opt.device_target == "Ascend": - if args_opt.optim_option == "LEARNED_SCALE": - config_device_target = config_lsq_ascend_quant - else: - config_device_target = config_ascend_quant - symmetric_list = [True, False] - context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", - device_id=device_id, save_graphs=False) - elif args_opt.device_target == "GPU": - if args_opt.optim_option == "LEARNED_SCALE": - config_device_target = config_lsq_gpu_quant - else: - config_device_target = config_gpu_quant - symmetric_list = [False, False] - context.set_context(mode=context.GRAPH_MODE, device_target="GPU", - device_id=device_id, save_graphs=False) - else: - raise ValueError("Unsupported device target: {}.".format(args_opt.device_target)) - - - if args_opt.optim_option == "LEARNED_SCALE": - # define fusion network - network = mobilenetv2_mix_quant(num_classes=config_device_target.num_classes) - # convert fusion network to quantization aware network - quant_optim_otions = OptimizeOption.LEARNED_SCALE - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, True], - narrow_range=[True, True], - quant_dtype=(QuantDtype.INT4, QuantDtype.INT8), - freeze_bn=0, - quant_delay=0, - one_conv_fold=True, - optimize_option=quant_optim_otions) - else: - # define fusion network - network = mobilenetV2(num_classes=config_device_target.num_classes) - # convert fusion network to quantization aware network - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=symmetric_list) - network = quantizer.quantize(network) - - # define network loss - loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') - - # define dataset - dataset = create_dataset(dataset_path=args_opt.dataset_path, - do_train=False, - config=config_device_target, - device_target=args_opt.device_target, - batch_size=config_device_target.batch_size) - step_size = dataset.get_dataset_size() - - # load checkpoint - if args_opt.checkpoint_path: - param_dict = load_checkpoint(args_opt.checkpoint_path) - not_load_param = load_param_into_net(network, param_dict) - if not_load_param: - raise ValueError("Load param into net fail!") - network.set_train(False) - - # define model - model = Model(network, loss_fn=loss, metrics={'acc'}) - - print("============== Starting Validation ==============") - res = model.eval(dataset) - print("result:", res, "ckpt=", args_opt.checkpoint_path) - print("============== End Validation ==============") diff --git a/official/cv/mobilenetv2_quant/export.py b/official/cv/mobilenetv2_quant/export.py deleted file mode 100644 index a0ccc9c86f74e1c212fb9075845bda4af158fdd4..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/export.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Export MobilenetV2 on ImageNet""" - -import argparse -import numpy as np - -import mindspore -from mindspore import Tensor, context, load_checkpoint, load_param_into_net, export -from mindspore.compression.common import QuantDtype -from mindspore.compression.quant import QuantizationAwareTraining -from mindspore.compression.quant.quantizer import OptimizeOption -from src.mobilenetV2 import mobilenetV2 -from src.mobilenetv2_mix_quant import mobilenetv2_mix_quant -from src.config import config_quant - -parser = argparse.ArgumentParser(description='Image classification') -parser.add_argument('--checkpoint_path', type=str, default=None, help='Checkpoint file path') -parser.add_argument("--file_format", type=str, choices=["AIR", "MINDIR"], default="MINDIR", help="file format") -parser.add_argument('--device_target', type=str, default=None, help='Run device target') -parser.add_argument('--optim_option', type=str, default="QAT", help='OptimizeOption') -args_opt = parser.parse_args() - -if __name__ == '__main__': - cfg = config_quant(args_opt.device_target) - context.set_context(mode=context.GRAPH_MODE, device_target=cfg.device_target, save_graphs=False) - - if args_opt.optim_option == "LEARNED_SCALE": - # define fusion network - network = mobilenetv2_mix_quant(num_classes=cfg.num_classes) - # convert fusion network to quantization aware network - quant_optim_otions = OptimizeOption.LEARNED_SCALE - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, True], - narrow_range=[True, True], - quant_dtype=(QuantDtype.INT4, QuantDtype.INT8), - freeze_bn=0, - quant_delay=0, - one_conv_fold=True, - optimize_option=quant_optim_otions) - else: - # define fusion network - network = mobilenetV2(num_classes=cfg.num_classes) - # convert fusion network to quantization aware network - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, False]) - network = quantizer.quantize(network) - # load checkpoint - param_dict = load_checkpoint(args_opt.checkpoint_path) - load_param_into_net(network, param_dict) - - # export network - print("============== Starting export ==============") - inputs = Tensor(np.ones([1, 3, cfg.image_height, cfg.image_width]), mindspore.float32) - export(network, inputs, file_name="mobilenetv2_quant", file_format=args_opt.file_format, - quant_mode='QUANT', mean=0., std_dev=48.106) - - print("============== End export ==============") diff --git a/official/cv/mobilenetv2_quant/export_bin_file.py b/official/cv/mobilenetv2_quant/export_bin_file.py deleted file mode 100644 index ef1e33d4a9164aac0da8318f18781138fed87f98..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/export_bin_file.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -export imagenet2012 dataset to bin. -""" -import os -import argparse -from mindspore import context -from src.dataset import create_dataset -from src.config import config_ascend_quant - -def parse_args(): - parser = argparse.ArgumentParser(description='ImageNet2012 to bin') - 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('--dataset_dir', type=str, default='', help='dataset path') - parser.add_argument('--save_dir', type=str, default='', help='path to save bin file') - parser.add_argument('--batch_size', type=int, default=1, help='batch size for bin') - args_, _ = parser.parse_known_args() - return args_ - -if __name__ == "__main__": - args = parse_args() - os.environ["RANK_SIZE"] = '1' - os.environ["RANK_ID"] = '0' - device_id = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0 - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=device_id) - imagenet2012_path = args.dataset_dir - batch_size = args.batch_size - save_dir = os.path.join(args.save_dir, 'imagenet2012_310_infer_data') - folder = os.path.join(save_dir, 'imagenet2012_bs_' + str(batch_size) + '_bin') - if not os.path.exists(folder): - os.makedirs(folder) - ds = create_dataset(imagenet2012_path, do_train=False, config=config_ascend_quant, - device_target=args.device_target, repeat_num=1, batch_size=batch_size) - iter_num = 0 - label_file = os.path.join(save_dir, './imagenet2012_bs_' + str(batch_size) + '_label.txt') - with open(label_file, 'w') as f: - for data in ds.create_dict_iterator(): - image = data['image'] - label = data['label'] - file_name = "imagenet2012_" + str(iter_num) + ".bin" - file_path = folder + "/" + file_name - image.asnumpy().tofile(file_path) - f.write(file_name) - for i in label: - f.write(',' + str(i)) - f.write('\n') - iter_num += 1 - print("=====iter_num:{}=====".format(iter_num)) - print("=====image_data:{}=====".format(image)) - print("=====label_data:{}=====".format(label)) diff --git a/official/cv/mobilenetv2_quant/mindspore_hub_conf.py b/official/cv/mobilenetv2_quant/mindspore_hub_conf.py deleted file mode 100644 index a7f61aa7fc0ec4f6b8d45d303fb44acb00bee791..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/mindspore_hub_conf.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""hub config""" -from mindspore.compression.quant import QuantizationAwareTraining -from src.config import config_ascend_quant -from src.mobilenetV2 import mobilenetV2 - -def mobilenetv2_quant_net(*args, **kwargs): - symmetric_list = [False, False] - # define fusion network - network = mobilenetV2(num_classes=config_ascend_quant.num_classes) - # convert fusion network to quantization aware network - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=symmetric_list) - network = quantizer.quantize(network) - return network - -def create_network(name, *args, **kwargs): - """create_network about mobilenetv2_quant""" - if name == "mobilenetv2_quant": - return mobilenetv2_quant_net(*args, **kwargs) - raise NotImplementedError(f"{name} is not implemented in the repo") diff --git a/official/cv/mobilenetv2_quant/postprocess.py b/official/cv/mobilenetv2_quant/postprocess.py deleted file mode 100644 index 101ef3e2d9212f593b86178ad29b59d6b9027c7c..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/postprocess.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -post process for 310 inference. -""" -import os -import argparse -import numpy as np - -def parse_args(): - parser = argparse.ArgumentParser(description='mobilenetv2_quant inference') - parser.add_argument('--result_path', type=str, default='', help='result files path') - parser.add_argument('--label_path', type=str, default='', help='label file path') - args_, _ = parser.parse_known_args() - return args_ - -if __name__ == "__main__": - args = parse_args() - path = args.result_path - label_path = args.label_path - files = os.listdir(path) - step = 0 - sum_right = 0 - label_dict = {} - with open(label_path, 'r') as f: - for line in f.readlines(): - batch_label = line.strip().split(',') - label_dict[batch_label[0]] = batch_label[1:] - for file in files: - full_file_path = os.path.join(path, file) - if os.path.isfile(full_file_path): - label_file = file.split('_0.bin')[0] + '.bin' - label_array = np.array(label_dict[label_file]) - line = np.fromfile(full_file_path, dtype=np.float32) - batch_size = label_array.shape[0] - line_comp = line.reshape(batch_size, int(line.shape[0] / batch_size)) - for i in range(0, batch_size): - pred = np.argmax(line_comp[i], axis=0) - step += 1 - if pred == label_array[i].astype(np.int64): - sum_right += 1 - print("=====step:{}=====".format(step)) - print("=====sum_right:{}=====".format(sum_right)) - accuracy = sum_right * 100.0 / step - print("=====accuracy:{}=====".format(accuracy)) diff --git a/official/cv/mobilenetv2_quant/requirements.txt b/official/cv/mobilenetv2_quant/requirements.txt deleted file mode 100644 index 5a619e015a5ba164371d32865c44aa47a3aa416c..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -numpy -easydict diff --git a/official/cv/mobilenetv2_quant/scripts/run_infer.sh b/official/cv/mobilenetv2_quant/scripts/run_infer.sh deleted file mode 100644 index 308723af2ae2001644902d8820c3b28a500cc4be..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/scripts/run_infer.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -if [ $# != 3 ] -then - echo "Ascend: sh run_infer.sh [PLATFORM] [DATASET_PATH] [CHECKPOINT_PATH]" -exit 1 -fi - -# check dataset path -if [ ! -d $2 ] && [ ! -f $2 ] -then - echo "error: DATASET_PATH=$2 is not a directory or file" -exit 1 -fi - -# check checkpoint file -if [ ! -f $3 ] -then - echo "error: CHECKPOINT_PATH=$3 is not a file" -exit 1 -fi - -# set environment -BASEPATH=$(cd "`dirname $0`" || exit; pwd) -export DEVICE_ID=0 -export RANK_ID=0 -export RANK_SIZE=1 -if [ -d "../eval" ]; -then - rm -rf ../eval -fi -mkdir ../eval -cd ../eval || exit - -# launch -python ${BASEPATH}/../eval.py \ - --device_target=$1 \ - --dataset_path=$2 \ - --checkpoint_path=$3 \ - &> infer.log & # dataset val folder path diff --git a/official/cv/mobilenetv2_quant/scripts/run_infer_310.sh b/official/cv/mobilenetv2_quant/scripts/run_infer_310.sh deleted file mode 100644 index 8aca5e6f8bbcd26766439849d69b704c6c79f7e4..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/scripts/run_infer_310.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [[ $# -lt 3 || $# -gt 4 ]]; then - echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] - DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} -model=$(get_real_path $1) -data_path=$(get_real_path $2) -label_path=$(get_real_path $3) - -device_id=0 -if [ $# == 4 ]; then - device_id=$4 -fi - -echo "air name: "$model -echo "dataset path: "$data_path -echo "label path: "$label_path -echo "device id: "$device_id - -export ASCEND_HOME=/usr/local/Ascend/ -if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then - export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH - export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp -else - export PATH=$ASCEND_HOME/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/fwkacllib/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=$PYTHONPATH:$TBE_IMPL_PATH - export ASCEND_OPP_PATH=$ASCEND_HOME/opp -fi - -function air_to_om() -{ - atc --input_format=NCHW --framework=1 --model=$model --output=mobilenetv2_quant --soc_version=Ascend310 &> atc.log -} - -function compile_app() -{ - cd ../ascend310_infer/src || exit - bash build.sh &> build.log -} - -function infer() -{ - cd - || exit - if [ -d result_Files ]; then - rm -rf ./result_Files - fi - if [ -d time_Result ]; then - rm -rf ./time_Result - fi - mkdir result_Files - mkdir time_Result - ../ascend310_infer/src/out/main --om_path=./mobilenetv2_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log -} - -function cal_acc() -{ - python ../postprocess.py --result_path=./result_Files --label_path=$label_path &> acc.log -} - -air_to_om -if [ $? -ne 0 ]; then - echo " air to om failed" - exit 1 -fi -compile_app -if [ $? -ne 0 ]; then - echo "compile app code failed" - exit 1 -fi -infer -if [ $? -ne 0 ]; then - echo " execute inference failed" - exit 1 -fi -cal_acc -if [ $? -ne 0 ]; then - echo "calculate accuracy failed" - exit 1 -fi diff --git a/official/cv/mobilenetv2_quant/scripts/run_lsq_infer.sh b/official/cv/mobilenetv2_quant/scripts/run_lsq_infer.sh deleted file mode 100644 index 92993a519337dd9bd9caa86a106e058d1d9bf1e8..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/scripts/run_lsq_infer.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -if [ $# != 3 ] -then - echo "Ascend: sh run_lsq_infer.sh [PLATFORM] [DATASET_PATH] [CHECKPOINT_PATH]" -exit 1 -fi - -# check dataset path -if [ ! -d $2 ] && [ ! -f $2 ] -then - echo "error: DATASET_PATH=$2 is not a directory or file" -exit 1 -fi - -# check checkpoint file -if [ ! -f $3 ] -then - echo "error: CHECKPOINT_PATH=$3 is not a file" -exit 1 -fi - -# set environment -BASEPATH=$(cd "`dirname $0`" || exit; pwd) -export DEVICE_ID=0 -export RANK_ID=0 -export RANK_SIZE=1 -if [ -d "../eval" ]; -then - rm -rf ../eval -fi -mkdir ../eval -cd ../eval || exit - -# launch -python ${BASEPATH}/../eval.py \ - --device_target=$1 \ - --dataset_path=$2 \ - --checkpoint_path=$3 \ - --optim_option="LEARNED_SCALE" \ - &> infer.log & # dataset val folder path diff --git a/official/cv/mobilenetv2_quant/scripts/run_lsq_train.sh b/official/cv/mobilenetv2_quant/scripts/run_lsq_train.sh deleted file mode 100644 index 6e10f28de1aefe4c9de37b867d69821d9f690b0e..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/scripts/run_lsq_train.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} - - -get_gpu_device_num(){ - - #device_list=(${1//,/ }) - IFS=',' read -ra device_list <<<"$1" - device_used=(0 0 0 0 0 0 0 0) - device_num=0 - for var in "${device_list[@]}" - do - if [ $((var)) -lt 0 ] || [ $((var)) -ge 8 ] - then - echo "error: device id=${var} is incorrect, device id must be in range [0,8), please check your device id list!" - exit 1 - fi - - if [ ${device_used[$((var))]} -eq 0 ] - then - device_used[ $((var)) ]=1 - device_num=$((device_num+1)) - fi - done - - echo ${device_num} -} - - -run_ascend(){ - - if [ $# -gt 4 ] || [ $# -lt 4 ] - then - echo "Usage: bash run_lsq_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\n " - exit 1 - fi - PATH1=$(get_real_path $2) - PATH2=$(get_real_path $3) - PATH3=$(get_real_path $4) - - if [ ! -f $PATH1 ] - then - echo "error: RANK_TABLE_FILE=$PATH1 is not a file" - exit 1 - fi - - if [ ! -d $PATH2 ] - then - echo "error: DATASET_PATH=$PATH2 is not a directory" - exit 1 - fi - - if [ $# == 4 ] && [ ! -f $PATH3 ] - then - echo "error: PRETRAINED_CKPT_PATH=$PATH3 is not a file" - exit 1 - fi - - - - #rank_file_name=${2##*/} - #IFS='_' read -ra array <<<"${rank_file_name}" - #device_id_list=${array[2]} - #first_device=${device_id_list:0:1} - #last_device=${device_list:${#device_list}-1:1} - #device_num=${#device_id_list} - cat $2 | awk -F "[device_id]" '/device_id/{print$0}' >temp.log - array=$(cat temp.log | awk -F "[:]" '/device_id/{print$2}') - - IFS=" " read -ra device_list <<<$array - first_device=${device_list[0]:1:1} - #device_num=${#device_list[*]} - device_num=$(cat temp.log | wc -l) - rm temp.log - ulimit -u unlimited - export DEVICE_NUM=${device_num} - export RANK_SIZE=${device_num} - export RANK_TABLE_FILE=$PATH1 - - export SERVER_ID=0 - rank_start=$((DEVICE_NUM * SERVER_ID)) - - rm -rf ./train - mkdir ./train - for((i=0; i<${device_num}; i++)) - do - export DEVICE_ID=$((first_device+i)) - export RANK_ID=$((rank_start + i)) - mkdir ./train/device$i - cp ../*.py ./train/device$i - cp *.sh ./train/device$i - cp -r ../src ./train/device$i - cd ./train/device$i || exit - echo "start training for rank $RANK_ID, device $DEVICE_ID" - env > env.log - python train.py --device_target=$1 --dataset_path=$PATH2 --pre_trained=$PATH3 \ - --optim_option="LEARNED_SCALE" &> train.log & - - cd ../.. || exit - done -} - -run_gpu(){ - if [ $# -gt 4 ] || [ $# -lt 4 ] - then - echo "Usage: bash run_lsq_train.sh [GPU] [DEVICE_ID_LIST] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\n " - exit 1 - fi - - PATH1=$(get_real_path $3) - PATH2=$(get_real_path $4) - - if [ ! -d $PATH1 ] - then - echo "error: DATASET_PATH=$PATH1 is not a directory" - exit 1 - fi - - if [ $# == 4 ] && [ ! -f $PATH2 ] - then - echo "error: PRETRAINED_CKPT_PATH=$PATH2 is not a file" - exit 1 - fi - - device_num=$(get_gpu_device_num $2) - - ulimit -u unlimited - export DEVICE_NUM=${device_num} - export RANK_SIZE=${device_num} - export CUDA_VISIBLE_DEVICES=$2 - - rm -rf ./train - mkdir ./train - cp ../*.py ./train - cp *.sh ./train - cp -r ../src ./train - cd ./train || exit - echo "start training" - env > env.log - - mpirun --allow-run-as-root -n ${RANK_SIZE} --output-filename log_output --merge-stderr-to-stdout \ - python train.py --device_target=$1 --dataset_path=$PATH1 --pre_trained=$PATH2 \ - --optim_option="LEARNED_SCALE" &> train.log & - - cd .. -} - - -if [ $1 = "Ascend" ] ; then - run_ascend "$@" -elif [ $1 = "GPU" ] ; then - run_gpu "$@" -else - echo "Unsupported device target: $1" -fi; - diff --git a/official/cv/mobilenetv2_quant/scripts/run_train.sh b/official/cv/mobilenetv2_quant/scripts/run_train.sh deleted file mode 100644 index d4f59781bcaafbf88599f77daffcd288701b3c9f..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/scripts/run_train.sh +++ /dev/null @@ -1,199 +0,0 @@ -#!/bin/bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} - - -get_gpu_device_num(){ - - #device_list=(${1//,/ }) - IFS=',' read -ra device_list <<<"$1" - device_used=(0 0 0 0 0 0 0 0) - device_num=0 - for var in "${device_list[@]}" - do - if [ $((var)) -lt 0 ] || [ $((var)) -ge 8 ] - then - echo "error: device id=${var} is incorrect, device id must be in range [0,8), please check your device id list!" - exit 1 - fi - - if [ ${device_used[$((var))]} -eq 0 ] - then - device_used[ $((var)) ]=1 - device_num=$((device_num+1)) - fi - done - - echo ${device_num} -} - - -run_ascend(){ - - if [ $# -gt 4 ] || [ $# -lt 3 ] - then - echo "Usage: bash run_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH](optional)\n " - exit 1 - fi - PATH1=$(get_real_path $2) - PATH2=$(get_real_path $3) - - if [ $# == 4 ] - then - PATH3=$(get_real_path $4) - fi - - if [ ! -f $PATH1 ] - then - echo "error: RANK_TABLE_FILE=$PATH1 is not a file" - exit 1 - fi - - if [ ! -d $PATH2 ] - then - echo "error: DATASET_PATH=$PATH2 is not a directory" - exit 1 - fi - - if [ $# == 4 ] && [ ! -f $PATH3 ] - then - echo "error: PRETRAINED_CKPT_PATH=$PATH3 is not a file" - exit 1 - fi - - - - #rank_file_name=${2##*/} - #IFS='_' read -ra array <<<"${rank_file_name}" - #device_id_list=${array[2]} - #first_device=${device_id_list:0:1} - #last_device=${device_list:${#device_list}-1:1} - #device_num=${#device_id_list} - cat $2 | awk -F "[device_id]" '/device_id/{print$0}' >temp.log - array=$(cat temp.log | awk -F "[:]" '/device_id/{print$2}') - - IFS=" " read -ra device_list <<<$array - first_device=${device_list[0]:1:1} - #device_num=${#device_list[*]} - device_num=$(cat temp.log | wc -l) - rm temp.log - ulimit -u unlimited - export DEVICE_NUM=${device_num} - export RANK_SIZE=${device_num} - export RANK_TABLE_FILE=$PATH1 - - export SERVER_ID=0 - rank_start=$((DEVICE_NUM * SERVER_ID)) - - rm -rf ./train - mkdir ./train - for((i=0; i<${device_num}; i++)) - do - export DEVICE_ID=$((first_device+i)) - export RANK_ID=$((rank_start + i)) - mkdir ./train/device$i - cp ../*.py ./train/device$i - cp *.sh ./train/device$i - cp -r ../src ./train/device$i - cd ./train/device$i || exit - echo "start training for rank $RANK_ID, device $DEVICE_ID" - env > env.log - if [ $# == 3 ] - then - python train.py --device_target=$1 --dataset_path=$PATH2 &> train.log & - fi - - if [ $# == 4 ] - then - python train.py --device_target=$1 --dataset_path=$PATH2 --pre_trained=$PATH3 &> train.log & - fi - - cd ../.. || exit - done -} - -run_gpu(){ - if [ $# -gt 4 ] || [ $# -lt 3 ] - then - echo "Usage: bash run_train.sh [GPU] [DEVICE_ID_LIST] [DATASET_PATH] [PRETRAINED_CKPT_PATH](optional)\n " - exit 1 - fi - - PATH1=$(get_real_path $3) - - if [ $# == 4 ] - then - PATH2=$(get_real_path $4) - fi - - if [ ! -d $PATH1 ] - then - echo "error: DATASET_PATH=$PATH1 is not a directory" - exit 1 - fi - - if [ $# == 4 ] && [ ! -f $PATH2 ] - then - echo "error: PRETRAINED_CKPT_PATH=$PATH2 is not a file" - exit 1 - fi - - device_num=$(get_gpu_device_num $2) - - ulimit -u unlimited - export DEVICE_NUM=${device_num} - export RANK_SIZE=${device_num} - export CUDA_VISIBLE_DEVICES=$2 - - rm -rf ./train - mkdir ./train - cp ../*.py ./train - cp *.sh ./train - cp -r ../src ./train - cd ./train || exit - echo "start training" - env > env.log - if [ $# == 3 ] - then - mpirun --allow-run-as-root -n ${RANK_SIZE} --output-filename log_output --merge-stderr-to-stdout \ - python train.py --device_target=$1 --dataset_path=$PATH1 &> train.log & - fi - - if [ $# == 4 ] - then - mpirun --allow-run-as-root -n ${RANK_SIZE} --output-filename log_output --merge-stderr-to-stdout \ - python train.py --device_target=$1 --dataset_path=$PATH1 --pre_trained=$PATH2 &> train.log & - fi - - cd .. -} - - -if [ $1 = "Ascend" ] ; then - run_ascend "$@" -elif [ $1 = "GPU" ] ; then - run_gpu "$@" -else - echo "Unsupported device target: $1" -fi; - diff --git a/official/cv/mobilenetv2_quant/src/config.py b/official/cv/mobilenetv2_quant/src/config.py deleted file mode 100644 index 2aaa8c954fbb3f3416d9ddfc2c9680afb5f824ab..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/config.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -network config setting, will be used in train.py and eval.py -""" -from easydict import EasyDict as ed -config_ascend_quant = ed({ - "num_classes": 1000, - "image_height": 224, - "image_width": 224, - "batch_size": 192, - "data_load_mode": "mindata", - "epoch_size": 60, - "start_epoch": 200, - "warmup_epochs": 0, - "lr": 0.3, - "momentum": 0.9, - "weight_decay": 4e-5, - "label_smooth": 0.1, - "loss_scale": 1024, - "save_checkpoint": True, - "save_checkpoint_epochs": 1, - "keep_checkpoint_max": 300, - "save_checkpoint_path": "./checkpoint", -}) - -config_gpu_quant = ed({ - "num_classes": 1000, - "image_height": 224, - "image_width": 224, - "batch_size": 300, - "epoch_size": 60, - "start_epoch": 200, - "warmup_epochs": 0, - "lr": 0.05, - "momentum": 0.997, - "weight_decay": 4e-5, - "label_smooth": 0.1, - "loss_scale": 1024, - "save_checkpoint": True, - "save_checkpoint_epochs": 1, - "keep_checkpoint_max": 300, - "save_checkpoint_path": "./checkpoint", -}) - -config_lsq_gpu_quant = ed({ - "num_classes": 1000, - "image_height": 224, - "image_width": 224, - "batch_size": 128, - "epoch_size": 60, - "start_epoch": 200, - "warmup_epochs": 0, - "lr": 0.05, - "momentum": 0.9, - "weight_decay": 4e-5, - "label_smooth": 0.1, - "loss_scale": 1024, - "save_checkpoint": True, - "save_checkpoint_epochs": 1, - "keep_checkpoint_max": 300, - "save_checkpoint_path": "./checkpoint", -}) - -config_lsq_ascend_quant = ed({ - "num_classes": 1000, - "image_height": 224, - "image_width": 224, - "batch_size": 192, - "data_load_mode": "mindata", - "epoch_size": 40, - "start_epoch": 200, - "warmup_epochs": 0, - "lr": 0.05, - "momentum": 0.9, - "weight_decay": 4e-5, - "label_smooth": 0.1, - "loss_scale": 1024, - "save_checkpoint": True, - "save_checkpoint_epochs": 1, - "keep_checkpoint_max": 300, - "save_checkpoint_path": "./checkpoint", -}) - -def config_quant(device_target): - if device_target not in ["Ascend", "GPU"]: - raise ValueError("Unsupported device target: {}.".format(device_target)) - configs = ed({ - "Ascend": config_ascend_quant, - "GPU": config_gpu_quant - }) - config = configs.Ascend if device_target == "Ascend" else configs.GPU - config["device_target"] = device_target - return config diff --git a/official/cv/mobilenetv2_quant/src/dataset.py b/official/cv/mobilenetv2_quant/src/dataset.py deleted file mode 100644 index 1b0a4c292f05071a962b4d1c45a8c2ddeedeb960..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/dataset.py +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -create train or eval dataset. -""" -import os -from functools import partial -import mindspore.common.dtype as mstype -import mindspore.dataset as ds -import mindspore.dataset.vision.c_transforms as C -import mindspore.dataset.transforms.c_transforms as C2 -import mindspore.dataset.transforms.py_transforms as P2 -import mindspore.dataset.vision.py_transforms as P - - -def create_dataset(dataset_path, do_train, config, device_target, repeat_num=1, batch_size=32): - """ - create a train or eval dataset - - Args: - dataset_path(string): the path of dataset. - do_train(bool): whether dataset is used for train or eval. - repeat_num(int): the repeat times of dataset. Default: 1. - batch_size(int): the batch size of dataset. Default: 32. - - Returns: - dataset - """ - if device_target == "Ascend": - rank_size = int(os.getenv("RANK_SIZE")) - rank_id = int(os.getenv("RANK_ID")) - columns_list = ['image', 'label'] - if config.data_load_mode == "mindrecord": - load_func = partial(ds.MindDataset, dataset_path, columns_list) - else: - load_func = partial(ds.ImageFolderDataset, dataset_path) - if do_train: - if rank_size == 1: - data_set = load_func(num_parallel_workers=8, shuffle=True) - else: - data_set = load_func(num_parallel_workers=8, shuffle=True, - num_shards=rank_size, shard_id=rank_id) - else: - data_set = load_func(num_parallel_workers=8, shuffle=False) - elif device_target == "GPU": - if do_train: - from mindspore.communication.management import get_rank, get_group_size - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True, - num_shards=get_group_size(), shard_id=get_rank()) - else: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True) - else: - raise ValueError("Unsupported device_target.") - - resize_height = 224 - - if do_train: - buffer_size = 20480 - # apply shuffle operations - data_set = data_set.shuffle(buffer_size=buffer_size) - - # define map operations - decode_op = C.Decode() - resize_crop_decode_op = C.RandomCropDecodeResize(resize_height, scale=(0.08, 1.0), ratio=(0.75, 1.333)) - horizontal_flip_op = C.RandomHorizontalFlip(prob=0.5) - - resize_op = C.Resize(256) - center_crop = C.CenterCrop(resize_height) - normalize_op = C.Normalize(mean=[0.485 * 255, 0.456 * 255, 0.406 * 255], - std=[0.229 * 255, 0.224 * 255, 0.225 * 255]) - change_swap_op = C.HWC2CHW() - - if do_train: - trans = [resize_crop_decode_op, horizontal_flip_op, normalize_op, change_swap_op] - else: - trans = [decode_op, resize_op, center_crop, normalize_op, change_swap_op] - - type_cast_op = C2.TypeCast(mstype.int32) - - data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=16) - data_set = data_set.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) - - # apply batch operations - data_set = data_set.batch(batch_size, drop_remainder=True) - - # apply dataset repeat operation - data_set = data_set.repeat(repeat_num) - - return data_set - - -def create_dataset_py(dataset_path, do_train, config, device_target, repeat_num=1, batch_size=32): - """ - create a train or eval dataset - - Args: - dataset_path(string): the path of dataset. - do_train(bool): whether dataset is used for train or eval. - repeat_num(int): the repeat times of dataset. Default: 1. - batch_size(int): the batch size of dataset. Default: 32. - - Returns: - dataset - """ - if device_target == "Ascend": - rank_size = int(os.getenv("RANK_SIZE")) - rank_id = int(os.getenv("RANK_ID")) - if do_train: - if rank_size == 1: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True) - else: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True, - num_shards=rank_size, shard_id=rank_id) - else: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=False) - else: - raise ValueError("Unsupported device target.") - - resize_height = 224 - - if do_train: - buffer_size = 20480 - # apply shuffle operations - data_set = data_set.shuffle(buffer_size=buffer_size) - - # define map operations - decode_op = P.Decode() - resize_crop_op = P.RandomResizedCrop(resize_height, scale=(0.08, 1.0), ratio=(0.75, 1.333)) - horizontal_flip_op = P.RandomHorizontalFlip(prob=0.5) - - resize_op = P.Resize(256) - center_crop = P.CenterCrop(resize_height) - to_tensor = P.ToTensor() - normalize_op = P.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) - - if do_train: - trans = [decode_op, resize_crop_op, horizontal_flip_op, to_tensor, normalize_op] - else: - trans = [decode_op, resize_op, center_crop, to_tensor, normalize_op] - - compose = P2.Compose(trans) - - data_set = data_set.map(operations=compose, input_columns="image", num_parallel_workers=8, - python_multiprocessing=True) - - # apply batch operations - data_set = data_set.batch(batch_size, drop_remainder=True) - - # apply dataset repeat operation - data_set = data_set.repeat(repeat_num) - - return data_set diff --git a/official/cv/mobilenetv2_quant/src/launch.py b/official/cv/mobilenetv2_quant/src/launch.py deleted file mode 100644 index 48b70d77fa72c09bcbdc83e6bf96127c95aa2a8a..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/launch.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""launch train script""" -import os -import sys -import json -import subprocess -import shutil -import platform -from argparse import ArgumentParser - - -def parse_args(): - """ - parse args . - - Args: - - Returns: - args. - - Examples: - >>> parse_args() - """ - parser = ArgumentParser(description="mindspore distributed training launch " - "helper utility that will spawn up " - "multiple distributed processes") - parser.add_argument("--nproc_per_node", type=int, default=1, - help="The number of processes to launch on each node, " - "for D training, this is recommended to be set " - "to the number of D in your system so that " - "each process can be bound to a single D.") - parser.add_argument("--visible_devices", type=str, default="0,1,2,3,4,5,6,7", - help="will use the visible devices sequentially") - parser.add_argument("--server_id", type=str, default="", - help="server ip") - parser.add_argument("--training_script", type=str, - help="The full path to the single D training " - "program/script to be launched in parallel, " - "followed by all the arguments for the " - "training script") - # rest from the training program - args, unknown = parser.parse_known_args() - args.training_script_args = unknown - return args - - -def main(): - print("start", __file__) - args = parse_args() - print(args) - visible_devices = args.visible_devices.split(',') - assert os.path.isfile(args.training_script) - assert len(visible_devices) >= args.nproc_per_node - print('visible_devices:{}'.format(visible_devices)) - if not args.server_id: - print('pleaser input server ip!!!') - exit(0) - print('server_id:{}'.format(args.server_id)) - - # construct hccn_table - hccn_configs = open('/etc/hccn.conf', 'r').readlines() - device_ips = {} - for hccn_item in hccn_configs: - hccn_item = hccn_item.strip() - if hccn_item.startswith('address_'): - device_id, device_ip = hccn_item.split('=') - device_id = device_id.split('_')[1] - device_ips[device_id] = device_ip - print('device_id:{}, device_ip:{}'.format(device_id, device_ip)) - hccn_table = {} - arch = platform.processor() - hccn_table['board_id'] = {'aarch64': '0x002f', 'x86_64': '0x0000'}[arch] - hccn_table['chip_info'] = '910' - hccn_table['deploy_mode'] = 'lab' - hccn_table['group_count'] = '1' - hccn_table['group_list'] = [] - instance_list = [] - usable_dev = '' - for instance_id in range(args.nproc_per_node): - instance = {} - instance['devices'] = [] - device_id = visible_devices[instance_id] - device_ip = device_ips[device_id] - usable_dev += str(device_id) - instance['devices'].append({ - 'device_id': device_id, - 'device_ip': device_ip, - }) - instance['rank_id'] = str(instance_id) - instance['server_id'] = args.server_id - instance_list.append(instance) - hccn_table['group_list'].append({ - 'device_num': str(args.nproc_per_node), - 'server_num': '1', - 'group_name': '', - 'instance_count': str(args.nproc_per_node), - 'instance_list': instance_list, - }) - hccn_table['para_plane_nic_location'] = 'device' - hccn_table['para_plane_nic_name'] = [] - for instance_id in range(args.nproc_per_node): - eth_id = visible_devices[instance_id] - hccn_table['para_plane_nic_name'].append('eth{}'.format(eth_id)) - hccn_table['para_plane_nic_num'] = str(args.nproc_per_node) - hccn_table['status'] = 'completed' - - # save hccn_table to file - table_path = os.getcwd() - if not os.path.exists(table_path): - os.mkdir(table_path) - table_fn = os.path.join(table_path, - 'rank_table_{}p_{}_{}.json'.format(args.nproc_per_node, usable_dev, args.server_id)) - with open(table_fn, 'w') as table_fp: - json.dump(hccn_table, table_fp, indent=4) - sys.stdout.flush() - - # spawn the processes - processes = [] - cmds = [] - log_files = [] - env = os.environ.copy() - env['RANK_SIZE'] = str(args.nproc_per_node) - cur_path = os.getcwd() - for rank_id in range(0, args.nproc_per_node): - os.chdir(cur_path) - device_id = visible_devices[rank_id] - device_dir = os.path.join(cur_path, 'device{}'.format(rank_id)) - env['RANK_ID'] = str(rank_id) - env['DEVICE_ID'] = str(device_id) - if args.nproc_per_node > 1: - env['RANK_TABLE_FILE'] = table_fn - if os.path.exists(device_dir): - shutil.rmtree(device_dir) - os.mkdir(device_dir) - os.chdir(device_dir) - cmd = [sys.executable, '-u'] - cmd.append(args.training_script) - cmd.extend(args.training_script_args) - log_file = open('{dir}/log{id}.log'.format(dir=device_dir, id=rank_id), 'w') - process = subprocess.Popen(cmd, stdout=log_file, stderr=log_file, env=env) - processes.append(process) - cmds.append(cmd) - log_files.append(log_file) - for process, cmd, log_file in zip(processes, cmds, log_files): - process.wait() - if process.returncode != 0: - raise subprocess.CalledProcessError(returncode=process, cmd=cmd) - log_file.close() - - -if __name__ == "__main__": - main() diff --git a/official/cv/mobilenetv2_quant/src/lr_generator.py b/official/cv/mobilenetv2_quant/src/lr_generator.py deleted file mode 100644 index 68bbfe315847d4d291d3d5f30df1f8f94de1dc27..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/lr_generator.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""learning rate generator""" -import math -import numpy as np - - -def get_lr(global_step, lr_init, lr_end, lr_max, warmup_epochs, total_epochs, steps_per_epoch): - """ - generate learning rate array - - Args: - global_step(int): total steps of the training - lr_init(float): init learning rate - lr_end(float): end learning rate - lr_max(float): max learning rate - warmup_epochs(int): number of warmup epochs - total_epochs(int): total epoch of training - steps_per_epoch(int): steps of one epoch - - Returns: - np.array, learning rate array - """ - lr_each_step = [] - total_steps = steps_per_epoch * total_epochs - warmup_steps = steps_per_epoch * warmup_epochs - for i in range(total_steps): - if i < warmup_steps: - lr = lr_init + (lr_max - lr_init) * i / warmup_steps - else: - lr = lr_end + \ - (lr_max - lr_end) * \ - (1. + math.cos(math.pi * (i - warmup_steps) / (total_steps - warmup_steps))) / 2. - if lr < 0.0: - lr = 0.0 - lr_each_step.append(lr) - - current_step = global_step - lr_each_step = np.array(lr_each_step).astype(np.float32) - learning_rate = lr_each_step[current_step:] - - return learning_rate diff --git a/official/cv/mobilenetv2_quant/src/mobilenetV2.py b/official/cv/mobilenetv2_quant/src/mobilenetV2.py deleted file mode 100644 index e0816b014b379f76d5608f132d169c9bb3721a99..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/mobilenetV2.py +++ /dev/null @@ -1,244 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""MobileNetV2 Quant model define""" - -import numpy as np - -import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore import Tensor - -__all__ = ['mobilenetV2'] - - -def _make_divisible(v, divisor, min_value=None): - if min_value is None: - min_value = divisor - new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) - # Make sure that round down does not go down by more than 10%. - if new_v < 0.9 * v: - new_v += divisor - return new_v - - -class GlobalAvgPooling(nn.Cell): - """ - Global avg pooling definition. - - Args: - - Returns: - Tensor, output tensor. - - Examples: - >>> GlobalAvgPooling() - """ - - def __init__(self): - super(GlobalAvgPooling, self).__init__() - self.mean = P.ReduceMean(keep_dims=False) - - def construct(self, x): - x = self.mean(x, (2, 3)) - return x - - -class ConvBNReLU(nn.Cell): - """ - Convolution/Depthwise fused with Batchnorm and ReLU block definition. - - Args: - in_planes (int): Input channel. - out_planes (int): Output channel. - kernel_size (int): Input kernel size. - stride (int): Stride size for the first convolutional layer. Default: 1. - groups (int): channel group. Convolution is 1 while Depthiwse is input channel. Default: 1. - - Returns: - Tensor, output tensor. - - Examples: - >>> ConvBNReLU(16, 256, kernel_size=1, stride=1, groups=1) - """ - - def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): - super(ConvBNReLU, self).__init__() - padding = (kernel_size - 1) // 2 - self.conv = nn.Conv2dBnAct(in_planes, out_planes, kernel_size, - stride=stride, - pad_mode='pad', - padding=padding, - group=groups, - has_bn=True, - activation='relu') - - def construct(self, x): - x = self.conv(x) - return x - - -class InvertedResidual(nn.Cell): - """ - Mobilenetv2 residual block definition. - - Args: - inp (int): Input channel. - oup (int): Output channel. - stride (int): Stride size for the first convolutional layer. Default: 1. - expand_ratio (int): expand ration of input channel - - Returns: - Tensor, output tensor. - - Examples: - >>> ResidualBlock(3, 256, 1, 1) - """ - - def __init__(self, inp, oup, stride, expand_ratio): - super(InvertedResidual, self).__init__() - assert stride in [1, 2] - - hidden_dim = int(round(inp * expand_ratio)) - self.use_res_connect = stride == 1 and inp == oup - - layers = [] - if expand_ratio != 1: - layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) - layers.extend([ - # dw - ConvBNReLU(hidden_dim, hidden_dim, stride=stride, groups=hidden_dim), - # pw-linear - nn.Conv2dBnAct(hidden_dim, oup, kernel_size=1, stride=1, pad_mode='pad', padding=0, group=1, has_bn=True) - ]) - self.conv = nn.SequentialCell(layers) - self.add = P.Add() - - def construct(self, x): - out = self.conv(x) - if self.use_res_connect: - out = self.add(out, x) - return out - - -class mobilenetV2(nn.Cell): - """ - mobilenetV2 fusion architecture. - - Args: - class_num (Cell): number of classes. - width_mult (int): Channels multiplier for round to 8/16 and others. Default is 1. - has_dropout (bool): Is dropout used. Default is false - inverted_residual_setting (list): Inverted residual settings. Default is None - round_nearest (list): Channel round to . Default is 8 - Returns: - Tensor, output tensor. - - Examples: - >>> mobilenetV2(num_classes=1000) - """ - - def __init__(self, num_classes=1000, width_mult=1., - has_dropout=False, inverted_residual_setting=None, round_nearest=8): - super(mobilenetV2, self).__init__() - block = InvertedResidual - input_channel = 32 - last_channel = 1280 - # setting of inverted residual blocks - self.cfgs = inverted_residual_setting - if inverted_residual_setting is None: - self.cfgs = [ - # t, c, n, s - [1, 16, 1, 1], - [6, 24, 2, 2], - [6, 32, 3, 2], - [6, 64, 4, 2], - [6, 96, 3, 1], - [6, 160, 3, 2], - [6, 320, 1, 1], - ] - - # building first layer - input_channel = _make_divisible(input_channel * width_mult, round_nearest) - self.out_channels = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) - - features = [ConvBNReLU(3, input_channel, stride=2)] - # building inverted residual blocks - for t, c, n, s in self.cfgs: - output_channel = _make_divisible(c * width_mult, round_nearest) - for i in range(n): - stride = s if i == 0 else 1 - features.append(block(input_channel, output_channel, stride, expand_ratio=t)) - input_channel = output_channel - # building last several layers - features.append(ConvBNReLU(input_channel, self.out_channels, kernel_size=1)) - # make it nn.CellList - self.features = nn.SequentialCell(features) - # mobilenet head - head = ([GlobalAvgPooling(), - nn.DenseBnAct(self.out_channels, num_classes, has_bias=True, has_bn=False) - ] if not has_dropout else - [GlobalAvgPooling(), - nn.Dropout(0.2), - nn.DenseBnAct(self.out_channels, num_classes, has_bias=True, has_bn=False) - ]) - self.head = nn.SequentialCell(head) - - # init weights - self.init_parameters_data() - self._initialize_weights() - - def construct(self, x): - x = self.features(x) - x = self.head(x) - return x - - def _initialize_weights(self): - """ - Initialize weights. - - Args: - - Returns: - None. - - Examples: - >>> _initialize_weights() - """ - self.init_parameters_data() - for _, m in self.cells_and_names(): - if isinstance(m, nn.Conv2d): - n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels - w = Tensor(np.random.normal(0, np.sqrt(2. / n), m.weight.data.shape).astype("float32")) - m.weight.set_data(w) - if m.bias is not None: - m.bias.set_data(Tensor(np.zeros(m.bias.data.shape, dtype="float32"))) - elif isinstance(m, nn.Conv2dBnAct): - n = m.conv.kernel_size[0] * m.conv.kernel_size[1] * m.conv.out_channels - w = Tensor(np.random.normal(0, np.sqrt(2. / n), m.conv.weight.data.shape).astype("float32")) - m.conv.weight.set_data(w) - if m.conv.bias is not None: - m.conv.bias.set_data(Tensor(np.zeros(m.conv.bias.data.shape, dtype="float32"))) - elif isinstance(m, nn.BatchNorm2d): - m.gamma.set_data(Tensor(np.ones(m.gamma.data.shape, dtype="float32"))) - m.beta.set_data(Tensor(np.zeros(m.beta.data.shape, dtype="float32"))) - elif isinstance(m, nn.Dense): - m.weight.set_data(Tensor(np.random.normal(0, 0.01, m.weight.data.shape).astype("float32"))) - if m.bias is not None: - m.bias.set_data(Tensor(np.zeros(m.bias.data.shape, dtype="float32"))) - elif isinstance(m, nn.DenseBnAct): - m.dense.weight.set_data( - Tensor(np.random.normal(0, 0.01, m.dense.weight.data.shape).astype("float32"))) - if m.dense.bias is not None: - m.dense.bias.set_data(Tensor(np.zeros(m.dense.bias.data.shape, dtype="float32"))) diff --git a/official/cv/mobilenetv2_quant/src/mobilenetv2_mix_quant.py b/official/cv/mobilenetv2_quant/src/mobilenetv2_mix_quant.py deleted file mode 100644 index c982e070c50a2835fa2b06084eadc36408e24286..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/mobilenetv2_mix_quant.py +++ /dev/null @@ -1,414 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""MobileNetV2 model define""" -import numpy as np -import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore.ops.operations import Add -from mindspore import Tensor -from mindspore.compression.common import QuantDtype -from mindspore.compression.quant import create_quant_config - -__all__ = ['mobilenetv2_mix_quant'] - - -def _make_divisible(v, divisor, min_value=None): - if min_value is None: - min_value = divisor - new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) - # Make sure that round down does not go down by more than 10%. - if new_v < 0.9 * v: - new_v += divisor - return new_v - - -class GlobalAvgPooling(nn.Cell): - """ - Global avg pooling definition. - - Args: - - Returns: - Tensor, output tensor. - - Examples: - >>> GlobalAvgPooling() - """ - - def __init__(self): - super(GlobalAvgPooling, self).__init__() - self.mean = P.ReduceMean(keep_dims=False) - - def construct(self, x): - x = self.mean(x, (2, 3)) - return x - - -class ConvBNReLU(nn.Cell): - """ - Convolution/Depthwise fused with Batchnorm and ReLU block definition. - - Args: - in_planes (int): Input channel. - out_planes (int): Output channel. - kernel_size (int): Input kernel size. - stride (int): Stride size for the first convolutional layer. Default: 1. - groups (int): channel group. Convolution is 1 while Depthiwse is input channel. Default: 1. - - Returns: - Tensor, output tensor. - - Examples: - >>> ConvBNReLU(16, 256, kernel_size=1, stride=1, groups=1) - """ - - def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): - super(ConvBNReLU, self).__init__() - padding = (kernel_size - 1) // 2 - self.conv = nn.Conv2dBnAct(in_planes, out_planes, kernel_size, - stride=stride, - pad_mode='pad', - padding=padding, - group=groups, - has_bn=True, - activation='relu6') - - def construct(self, x): - output = self.conv(x) - return output - -quant_config = create_quant_config(per_channel=(True, False), symmetric=(True, True), narrow_range=(True, True), - mode="LEARNED_SCALE") -class FirstQuantLayer(nn.Cell): - """ - The first quantization layer, which is fixed to 8bit. - """ - - def __init__(self, in_planes, out_planes, kernel_size=3, stride=1): - super(FirstQuantLayer, self).__init__() - padding = (kernel_size - 1) // 2 - in_channels = in_planes - out_channels = out_planes - conv_inner = nn.Conv2dBnFoldQuantOneConv(in_channels, - out_channels, - kernel_size=kernel_size, - stride=stride, - pad_mode='pad', - padding=padding, - quant_config=quant_config, - quant_dtype=QuantDtype.INT8) - activation = nn.ActQuant(activation=nn.ReLU6(), - quant_config=quant_config, - quant_dtype=QuantDtype.INT8) - self.features = nn.SequentialCell([conv_inner, activation]) - - def construct(self, x): - output = self.features(x) - return output - -class LastQuantLayer(nn.Cell): - """ - The last quantization layer, which is fixed to 8bit. - """ - - def __init__(self, in_channels, out_channels, has_bias, has_bn): - super(LastQuantLayer, self).__init__() - - self.dense_inner = nn.DenseQuant(in_channels, - out_channels, - has_bias=has_bias, - quant_config=quant_config, - quant_dtype=QuantDtype.INT8) - self.fake_quant_act = nn.FakeQuantWithMinMaxObserver(min_init=-16, - max_init=16, - ema=True, - quant_dtype=QuantDtype.INT8, - per_channel=False, - symmetric=True, - narrow_range=True, - mode="LEARNED_SCALE") - - def construct(self, x): - output = self.dense_inner(x) - output = self.fake_quant_act(output) - return output - -class InvertedResidual(nn.Cell): - """ - Mobilenetv2 residual block definition. - - Args: - inp (int): Input channel. - oup (int): Output channel. - stride (int): Stride size for the first convolutional layer. Default: 1. - expand_ratio (int): expand ration of input channel - - Returns: - Tensor, output tensor. - - Examples: - >>> ResidualBlock(3, 256, 1, 1) - """ - - def __init__(self, inp, oup, stride, expand_ratio): - super(InvertedResidual, self).__init__() - assert stride in [1, 2] - - hidden_dim = int(round(inp * expand_ratio)) - self.use_res_connect = stride == 1 and inp == oup - - layers = [] - if expand_ratio != 1: - layers.append(ConvBNReLU(inp, hidden_dim, kernel_size=1)) - layers.extend([ - # dw - ConvBNReLU(hidden_dim, hidden_dim, - stride=stride, groups=hidden_dim), - # pw-linear - nn.Conv2dBnAct(hidden_dim, oup, kernel_size=1, stride=1, has_bn=True) - ]) - self.conv = nn.SequentialCell(layers) - self.add = Add() - self.cast = P.Cast() - - def construct(self, x): - identity = x - x = self.conv(x) - if self.use_res_connect: - return self.add(identity, x) - return x - - -class MobileNetV2Backbone(nn.Cell): - """ - MobileNetV2 architecture. - - Args: - class_num (int): number of classes. - width_mult (int): Channels multiplier for round to 8/16 and others. Default is 1. - has_dropout (bool): Is dropout used. Default is false - inverted_residual_setting (list): Inverted residual settings. Default is None - round_nearest (list): Channel round to . Default is 8 - Returns: - Tensor, output tensor. - - Examples: - >>> MobileNetV2(num_classes=1000) - """ - - def __init__(self, width_mult=1., inverted_residual_setting=None, round_nearest=8, - input_channel=32, last_channel=1280): - super(MobileNetV2Backbone, self).__init__() - block = InvertedResidual - # setting of inverted residual blocks - self.cfgs = inverted_residual_setting - if inverted_residual_setting is None: - self.cfgs = [ - # t, c, n, s - [1, 16, 1, 1], - [6, 24, 2, 2], - [6, 32, 3, 2], - [6, 64, 4, 2], - [6, 96, 3, 1], - [6, 160, 3, 2], - [6, 320, 1, 1], - ] - - # building first layer - input_channel = _make_divisible(input_channel * width_mult, round_nearest) - self.out_channels = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) - features = [FirstQuantLayer(3, input_channel, stride=2)] - # building inverted residual blocks - for t, c, n, s in self.cfgs: - output_channel = _make_divisible(c * width_mult, round_nearest) - for i in range(n): - stride = s if i == 0 else 1 - features.append(block(input_channel, output_channel, stride, expand_ratio=t)) - input_channel = output_channel - # building last several layers - features.append(ConvBNReLU(input_channel, self.out_channels, kernel_size=1)) - # make it nn.CellList - self.features = nn.SequentialCell(features) - self._initialize_weights() - - def construct(self, x): - x = self.features(x) - return x - - def _initialize_weights(self): - """ - Initialize weights. - - Args: - - Returns: - None. - - Examples: - >>> _initialize_weights() - """ - self.init_parameters_data() - for _, m in self.cells_and_names(): - if isinstance(m, nn.Conv2d): - n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels - m.weight.set_data(Tensor(np.random.normal(0, np.sqrt(2. / n), - m.weight.data.shape).astype("float32"))) - if m.bias is not None: - m.bias.set_data( - Tensor(np.zeros(m.bias.data.shape, dtype="float32"))) - elif isinstance(m, nn.BatchNorm2d): - m.gamma.set_data( - Tensor(np.ones(m.gamma.data.shape, dtype="float32"))) - m.beta.set_data( - Tensor(np.zeros(m.beta.data.shape, dtype="float32"))) - - @property - def get_features(self): - return self.features - - -class MobileNetV2Head(nn.Cell): - """ - MobileNetV2 architecture. - - Args: - class_num (int): Number of classes. Default is 1000. - has_dropout (bool): Is dropout used. Default is false - Returns: - Tensor, output tensor. - - Examples: - >>> MobileNetV2(num_classes=1000) - """ - - def __init__(self, input_channel=1280, num_classes=1000, has_dropout=False, activation="None"): - super(MobileNetV2Head, self).__init__() - # mobilenet head - head = ([GlobalAvgPooling(), LastQuantLayer(input_channel, num_classes, has_bias=True, has_bn=False)] - if not has_dropout else - [GlobalAvgPooling(), nn.Dropout(0.2), LastQuantLayer(input_channel, num_classes, - has_bias=True, has_bn=False)]) - self.head = nn.SequentialCell(head) - self.need_activation = True - if activation == "Sigmoid": - self.activation = P.Sigmoid() - elif activation == "Softmax": - self.activation = P.Softmax() - else: - self.need_activation = False - self._initialize_weights() - - def construct(self, x): - x = self.head(x) - if self.need_activation: - x = self.activation(x) - return x - - def _initialize_weights(self): - """ - Initialize weights. - - Args: - - Returns: - None. - - Examples: - >>> _initialize_weights() - """ - self.init_parameters_data() - for _, m in self.cells_and_names(): - if isinstance(m, nn.Dense): - m.weight.set_data(Tensor(np.random.normal( - 0, 0.01, m.weight.data.shape).astype("float32"))) - if m.bias is not None: - m.bias.set_data( - Tensor(np.zeros(m.bias.data.shape, dtype="float32"))) - @property - def get_head(self): - return self.head - - -class MobileNetV2(nn.Cell): - """ - MobileNetV2 architecture. - - Args: - class_num (int): number of classes. - width_mult (int): Channels multiplier for round to 8/16 and others. Default is 1. - has_dropout (bool): Is dropout used. Default is false - inverted_residual_setting (list): Inverted residual settings. Default is None - round_nearest (list): Channel round to . Default is 8 - Returns: - Tensor, output tensor. - - Examples: - >>> MobileNetV2(backbone, head) - """ - - def __init__(self, num_classes=1000, width_mult=1., has_dropout=False, inverted_residual_setting=None, \ - round_nearest=8, input_channel=32, last_channel=1280): - super(MobileNetV2, self).__init__() - self.backbone = MobileNetV2Backbone(width_mult=width_mult, \ - inverted_residual_setting=inverted_residual_setting, \ - round_nearest=round_nearest, input_channel=input_channel, last_channel=last_channel).get_features - self.head = MobileNetV2Head(input_channel=self.backbone.out_channel, num_classes=num_classes, \ - has_dropout=has_dropout).get_head - - def construct(self, x): - x = self.backbone(x) - x = self.head(x) - return x - - -class MobileNetV2Combine(nn.Cell): - """ - MobileNetV2Combine architecture. - - Args: - backbone (Cell): the features extract layers. - head (Cell): the fully connected layers. - Returns: - Tensor, output tensor. - - Examples: - >>> MobileNetV2Combine(backbone, head) - """ - - def __init__(self, backbone, head): - super(MobileNetV2Combine, self).__init__(auto_prefix=False) - self.backbone = backbone - self.head = head - - def construct(self, x): - x = self.backbone(x) - x = self.head(x) - return x - - -def mobilenet_v2(backbone, head): - return MobileNetV2Combine(backbone, head) - - -def mobilenetv2_mix_quant(num_classes): - """ - MobileNetV2 quantization model, the first and last layers are fixed to 8bit by manual quantization cell, - and others `QuantDtype` are seted by the `QuantizationAwareTraining` API. - """ - backbone_net = MobileNetV2Backbone() - head_net = MobileNetV2Head(input_channel=backbone_net.out_channels, - num_classes=num_classes) - net = mobilenet_v2(backbone_net, head_net) - return net diff --git a/official/cv/mobilenetv2_quant/src/utils.py b/official/cv/mobilenetv2_quant/src/utils.py deleted file mode 100644 index 02398d79e98bc89e55dc730c8037b1ede515b6b1..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/src/utils.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""MobileNetV2 utils""" - -import time -import numpy as np - -from mindspore.train.callback import Callback -from mindspore import Tensor -from mindspore import nn -from mindspore.nn.loss.loss import LossBase -from mindspore.ops import operations as P -from mindspore.ops import functional as F -from mindspore.common import dtype as mstype - -class Monitor(Callback): - """ - Monitor loss and time. - - Args: - lr_init (numpy array): train lr - - Returns: - None - - Examples: - >>> Monitor(100,lr_init=Tensor([0.05]*100).asnumpy()) - """ - - def __init__(self, lr_init=None): - super(Monitor, self).__init__() - self.lr_init = lr_init - self.lr_init_len = len(lr_init) - - def epoch_begin(self, run_context): - self.losses = [] - self.epoch_time = time.time() - - def epoch_end(self, run_context): - cb_params = run_context.original_args() - - epoch_mseconds = (time.time() - self.epoch_time) * 1000 - per_step_mseconds = epoch_mseconds / cb_params.batch_num - print("epoch time: {:5.3f}, per step time: {:5.3f}, avg loss: {:5.3f}".format(epoch_mseconds, - per_step_mseconds, - np.mean(self.losses))) - - def step_begin(self, run_context): - self.step_time = time.time() - - def step_end(self, run_context): - cb_params = run_context.original_args() - step_mseconds = (time.time() - self.step_time) * 1000 - step_loss = cb_params.net_outputs - - if isinstance(step_loss, (tuple, list)) and isinstance(step_loss[0], Tensor): - step_loss = step_loss[0] - if isinstance(step_loss, Tensor): - step_loss = np.mean(step_loss.asnumpy()) - - self.losses.append(step_loss) - cur_step_in_epoch = (cb_params.cur_step_num - 1) % cb_params.batch_num - - print("epoch: [{:3d}/{:3d}], step:[{:5d}/{:5d}], loss:[{:5.3f}/{:5.3f}], time:[{:5.3f}], lr:[{:5.5f}]".format( - cb_params.cur_epoch_num, cb_params.epoch_num, cur_step_in_epoch+1, cb_params.batch_num, step_loss, - np.mean(self.losses), step_mseconds, self.lr_init[cb_params.cur_step_num - 1])) - - -class CrossEntropyWithLabelSmooth(LossBase): - """ - CrossEntropyWith LabelSmooth. - - Args: - smooth_factor (float): smooth factor for label smooth. Default is 0. - num_classes (int): number of classes. Default is 1000. - - Returns: - None. - - Examples: - >>> CrossEntropyWithLabelSmooth(smooth_factor=0., num_classes=1000) - """ - - def __init__(self, smooth_factor=0., num_classes=1000): - super(CrossEntropyWithLabelSmooth, 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) - self.cast = P.Cast() - - def construct(self, logit, label): - one_hot_label = self.onehot(self.cast(label, mstype.int32), F.shape(logit)[1], - self.on_value, self.off_value) - out_loss = self.ce(logit, one_hot_label) - out_loss = self.mean(out_loss, 0) - return out_loss diff --git a/official/cv/mobilenetv2_quant/train.py b/official/cv/mobilenetv2_quant/train.py deleted file mode 100644 index 1e1e445c3e3dc45f9e4d48db2a761ba24a0428b1..0000000000000000000000000000000000000000 --- a/official/cv/mobilenetv2_quant/train.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Train mobilenetV2 on ImageNet""" - -import os -import argparse - -from mindspore import context -from mindspore import Tensor -from mindspore import nn -from mindspore.train.model import Model -from mindspore.context import ParallelMode -from mindspore.train.loss_scale_manager import FixedLossScaleManager -from mindspore.train.callback import ModelCheckpoint, CheckpointConfig -from mindspore.train.serialization import load_checkpoint -from mindspore.communication.management import init, get_group_size, get_rank -from mindspore.compression.common import QuantDtype -from mindspore.compression.quant import QuantizationAwareTraining -from mindspore.compression.quant.quantizer import OptimizeOption -from mindspore.compression.quant.quant_utils import load_nonquant_param_into_quant_net -from mindspore.common import set_seed - -from src.dataset import create_dataset -from src.lr_generator import get_lr -from src.utils import Monitor, CrossEntropyWithLabelSmooth -from src.config import config_ascend_quant, config_gpu_quant, config_lsq_ascend_quant, config_lsq_gpu_quant -from src.mobilenetV2 import mobilenetV2 -from src.mobilenetv2_mix_quant import mobilenetv2_mix_quant - -set_seed(1) - -parser = argparse.ArgumentParser(description='Image classification') -parser.add_argument('--dataset_path', type=str, default=None, help='Dataset path') -parser.add_argument('--pre_trained', type=str, default=None, help='Pertained checkpoint path') -parser.add_argument('--device_target', type=str, default=None, help='Run device target') -parser.add_argument('--optim_option', type=str, default="QAT", help='If OptimizeOption is set to LEARNED_SCALE,' - 'the learned scale quant process is executed.') -args_opt = parser.parse_args() - -if args_opt.device_target == "Ascend": - device_id = int(os.getenv('DEVICE_ID', '0')) - rank_id = int(os.getenv('RANK_ID')) - rank_size = int(os.getenv('RANK_SIZE')) - run_distribute = rank_size > 1 - context.set_context(mode=context.GRAPH_MODE, - device_target="Ascend", - device_id=device_id, save_graphs=False) -elif args_opt.device_target == "GPU": - init() - context.set_auto_parallel_context(device_num=get_group_size(), - parallel_mode=ParallelMode.DATA_PARALLEL, - gradients_mean=True) - context.set_context(mode=context.GRAPH_MODE, - device_target="GPU", - save_graphs=False) -else: - raise ValueError("Unsupported device target.") - - -def train_on_ascend(): - if args_opt.optim_option == "LEARNED_SCALE": - config = config_lsq_ascend_quant - else: - config = config_ascend_quant - - print("training args: {}".format(args_opt)) - print("training configure: {}".format(config)) - print("parallel args: rank_id {}, device_id {}, rank_size {}".format(rank_id, device_id, rank_size)) - epoch_size = config.epoch_size - - # distribute init - if run_distribute: - context.set_auto_parallel_context(device_num=rank_size, - parallel_mode=ParallelMode.DATA_PARALLEL, - gradients_mean=True) - init() - - # define network - if args_opt.optim_option == "LEARNED_SCALE": - network = mobilenetv2_mix_quant(num_classes=config.num_classes) - else: - network = mobilenetV2(num_classes=config.num_classes) - # define loss - if config.label_smooth > 0: - loss = CrossEntropyWithLabelSmooth(smooth_factor=config.label_smooth, num_classes=config.num_classes) - else: - loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') - # define dataset - dataset = create_dataset(dataset_path=args_opt.dataset_path, - do_train=True, - config=config, - device_target=args_opt.device_target, - repeat_num=1, - batch_size=config.batch_size) - step_size = dataset.get_dataset_size() - # load pre trained ckpt - if args_opt.pre_trained: - param_dict = load_checkpoint(args_opt.pre_trained) - load_nonquant_param_into_quant_net(network, param_dict) - # convert fusion network to quantization aware network - if args_opt.optim_option == "LEARNED_SCALE": - quant_optim_otions = OptimizeOption.LEARNED_SCALE - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, True], - narrow_range=[True, True], - quant_dtype=(QuantDtype.INT4, QuantDtype.INT8), - freeze_bn=0, - quant_delay=0, - one_conv_fold=True, - optimize_option=quant_optim_otions) - else: - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, False], - one_conv_fold=True) - network = quantizer.quantize(network) - - # get learning rate - lr = Tensor(get_lr(global_step=config.start_epoch * step_size, - lr_init=0, - lr_end=0, - lr_max=config.lr, - warmup_epochs=config.warmup_epochs, - total_epochs=epoch_size + config.start_epoch, - steps_per_epoch=step_size)) - - # define optimization - opt = nn.Momentum(filter(lambda x: x.requires_grad, network.get_parameters()), lr, config.momentum, - config.weight_decay) - # define model - model = Model(network, loss_fn=loss, optimizer=opt) - - print("============== Starting Training ==============") - callback = None - if rank_id == 0: - callback = [Monitor(lr_init=lr.asnumpy())] - 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="mobilenetV2", - directory=config.save_checkpoint_path, - config=config_ck) - callback += [ckpt_cb] - model.train(epoch_size, dataset, callbacks=callback) - print("============== End Training ==============") - - -def train_on_gpu(): - if args_opt.optim_option == "LEARNED_SCALE": - config = config_lsq_gpu_quant - else: - config = config_gpu_quant - context.set_context(enable_graph_kernel=True) - - print("training args: {}".format(args_opt)) - print("training configure: {}".format(config)) - - # define network - if args_opt.optim_option == "LEARNED_SCALE": - network = mobilenetv2_mix_quant(num_classes=config.num_classes) - else: - network = mobilenetV2(num_classes=config.num_classes) - # define loss - if config.label_smooth > 0: - loss = CrossEntropyWithLabelSmooth(smooth_factor=config.label_smooth, - num_classes=config.num_classes) - else: - loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') - # define dataset - epoch_size = config.epoch_size - dataset = create_dataset(dataset_path=args_opt.dataset_path, - do_train=True, - config=config, - device_target=args_opt.device_target, - repeat_num=1, - batch_size=config.batch_size) - step_size = dataset.get_dataset_size() - # resume - if args_opt.pre_trained: - param_dict = load_checkpoint(args_opt.pre_trained) - load_nonquant_param_into_quant_net(network, param_dict) - - # convert fusion network to quantization aware network - if args_opt.optim_option == "LEARNED_SCALE": - quant_optim_otions = OptimizeOption.LEARNED_SCALE - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, True], - narrow_range=[True, True], - quant_dtype=(QuantDtype.INT4, QuantDtype.INT8), - freeze_bn=0, - quant_delay=0, - one_conv_fold=True, - optimize_option=quant_optim_otions) - else: - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[False, False], - freeze_bn=1000000, - quant_delay=step_size * 2) - network = quantizer.quantize(network) - - # get learning rate - loss_scale = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False) - lr = Tensor(get_lr(global_step=config.start_epoch * step_size, - lr_init=0, - lr_end=0, - lr_max=config.lr, - warmup_epochs=config.warmup_epochs, - total_epochs=epoch_size + config.start_epoch, - steps_per_epoch=step_size)) - - # define optimization - opt = nn.Momentum(filter(lambda x: x.requires_grad, network.get_parameters()), lr, config.momentum, - config.weight_decay, config.loss_scale) - # define model - model = Model(network, loss_fn=loss, optimizer=opt, loss_scale_manager=loss_scale) - - print("============== Starting Training ==============") - callback = [Monitor(lr_init=lr.asnumpy())] - ckpt_save_dir = config.save_checkpoint_path + "ckpt_" + str(get_rank()) + "/" - 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="mobilenetV2", directory=ckpt_save_dir, config=config_ck) - callback += [ckpt_cb] - model.train(epoch_size, dataset, callbacks=callback) - print("============== End Training ==============") - - -if __name__ == '__main__': - if args_opt.device_target == "Ascend": - train_on_ascend() - elif args_opt.device_target == "GPU": - train_on_gpu() - else: - raise ValueError("Unsupported device target.") diff --git a/official/cv/resnet50_quant/README.md b/official/cv/resnet50_quant/README.md deleted file mode 100644 index 4ed6474e15755b2182d3e8ffe64775c6e4e9ea80..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/README.md +++ /dev/null @@ -1,259 +0,0 @@ -# Contents - -- [Contents](#contents) -- [ResNet50 Description](#resnet50-description) -- [Model Architecture](#model-architecture) -- [Dataset](#dataset) -- [Features](#features) - - [Mixed Precision](#mixed-precision) -- [Environment Requirements](#environment-requirements) -- [Script description](#script-description) - - [Script and sample code](#script-and-sample-code) - - [Script Parameters](#script-parameters) - - [Training process](#training-process) - - [Usage](#usage) - - [Launch](#launch) - - [Result](#result) - - [Evaluation process](#evaluation-process) - - [Usage](#usage-1) - - [Launch](#launch-1) - - [Result](#result-1) - - [Model Export](#model-export) - - [Ascend 310 inference](#ascend-310-inference) -- [Model description](#model-description) - - [Performance](#performance) - - [Evaluation Performance](#evaluation-performance) - - [Inference Performance](#inference-performance) -- [Description of Random Situation](#description-of-random-situation) -- [ModelZoo Homepage](#modelzoo-homepage) - -# [ResNet50 Description](#contents) - -ResNet-50 is a convolutional neural network that is 50 layers deep, which can classify ImageNet image to 1000 object categories with 76% accuracy. - -[Paper](https://arxiv.org/abs/1512.03385): Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun."Deep Residual Learning for Image Recognition." He, Kaiming , et al. "Deep Residual Learning for Image Recognition." IEEE Conference on Computer Vision & Pattern Recognition IEEE Computer Society, 2016. - -This is the quantitative network of ResNet50. - -# [Model Architecture](#contents) - -The overall network architecture of Resnet50 is show below: - -[Link](https://arxiv.org/pdf/1512.03385.pdf) - -# [Dataset](#contents) - -Dataset used: [ImageNet2012](http://www.image-net.org/) - -- Dataset size 224*224 colorful images in 1000 classes - - Train锛�1,281,167 images - - Test锛� 50,000 images -- Data format锛歫peg - - Note锛欴ata will be processed in dataset.py -- Download the dataset, the directory structure is as follows: - - ```python -鈹斺攢dataset - 鈹溾攢ilsvrc # train dataset - 鈹斺攢validation_preprocess # evaluate dataset -``` - -# [Features](#contents) - -## [Mixed Precision](#contents) - -The [mixed precision](https://www.mindspore.cn/docs/programming_guide/en/master/enable_mixed_precision.html) training method accelerates the deep learning neural network training process by using both the single-precision and half-precision data formats, and maintains the network precision achieved by the single-precision training at the same time. Mixed precision training can accelerate the computation process, reduce memory usage, and enable a larger model or batch size to be trained on specific hardware. -For FP16 operators, if the input data type is FP32, the backend of MindSpore will automatically handle it with reduced precision. Users could check the reduced-precision operators by enabling INFO log and then searching 鈥榬educe precision鈥�. - -# [Environment Requirements](#contents) - -- Hardware:Ascend - - Prepare hardware environment with Ascend. -- Framework - - [MindSpore](https://www.mindspore.cn/install/en) -- For more information, please check the resources below锛� - - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/en/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/en/master/index.html) - -# [Script description](#contents) - -## [Script and sample code](#contents) - -```python -鈹溾攢鈹€ resnet50_quant - 鈹溾攢鈹€ README.md # descriptions about Resnet50-Quant - 鈹溾攢鈹€ ascend310_infer # application for 310 inference - 鈹溾攢鈹€ scripts - 鈹� 鈹溾攢鈹€run_train.sh # shell script for train on Ascend - 鈹� 鈹溾攢鈹€run_infer.sh # shell script for evaluation on Ascend - 鈹� 鈹溾攢鈹€run_infer_310.sh # shell script for 310 inference - 鈹溾攢鈹€ models - 鈹� 鈹溾攢鈹€resnet_quant.py # define the network model of resnet50-quant - 鈹� 鈹溾攢鈹€resnet_quant_manual.py # define the manually quantized network model of resnet50-quant - 鈹溾攢鈹€ src - 鈹� 鈹溾攢鈹€config.py # parameter configuration - 鈹� 鈹溾攢鈹€dataset.py # creating dataset - 鈹� 鈹溾攢鈹€launch.py # start python script - 鈹� 鈹溾攢鈹€lr_generator.py # learning rate config - 鈹� 鈹溾攢鈹€crossentropy.py # define the crossentropy of resnet50-quant - 鈹溾攢鈹€ train.py # training script - 鈹溾攢鈹€ eval.py # evaluation script - 鈹溾攢鈹€ export.py # export script - 鈹溾攢鈹€ export_bin_file.py # export bin file of ImageNet for 310 inference - 鈹溾攢鈹€ postprocess.py # post process for 310 inference - -``` - -## [Script Parameters](#contents) - -Parameters for both training and evaluation can be set in config.py - -- config for Resnet50-quant, ImageNet2012 dataset - - ```python - 'class_num': 10 # the number of classes in the dataset - 'batch_size': 32 # training batch size - 'loss_scale': 1024 # the initial loss_scale value - 'momentum': 0.9 # momentum - 'weight_decay': 1e-4 # weight decay value - 'epoch_size': 120 # total training epochs - 'pretrained_epoch_size': 90 # pretraining epochs of resnet50, which is unquantative network of resnet50_quant - 'data_load_mode': 'original' # the style of loading data into device, support 'original' or 'mindrecord' - 'save_checkpoint':True # whether save checkpoint file after training finish - 'save_checkpoint_epochs': 1 # the step from which start to save checkpoint file. - 'keep_checkpoint_max': 50 # only keep the last keep_checkpoint_max checkpoint - 'save_checkpoint_path': './' # the absolute full path to save the checkpoint file - "warmup_epochs": 0 # number of warmup epochs - 'lr_decay_mode': "cosine" # learning rate decay mode, including steps, steps_decay, cosine or liner - 'use_label_smooth': True # whether use label smooth - 'label_smooth_factor': 0.1 # label smooth factor - 'lr_init': 0 # initial learning rate - 'lr_max': 0.005 # the max learning rate - ``` - -## [Training process](#contents) - -### Usage - -- Ascend: bash run_train.sh Ascend [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\(optional) - -### Launch - -```bash - # training example - Ascend: bash run_train.sh Ascend ~/hccl.json ~/imagenet/train/ ~/pretrained_ckeckpoint -``` - -### Result - -Training result will be stored in the example path. Checkpoints will be stored at `./train/device$i/` by default, and training log will be redirected to `./train/device$i/train.log` like following. - -```bash -epoch: 1 step: 5004, loss is 4.8995576 -epoch: 2 step: 5004, loss is 3.9235563 -epoch: 3 step: 5004, loss is 3.833077 -epoch: 4 step: 5004, loss is 3.2795618 -epoch: 5 step: 5004, loss is 3.1978393 -``` - -## [Evaluation process](#contents) - -### Usage - -You can start training using python or shell scripts. The usage of shell scripts as follows: - -- Ascend: bash run_infer.sh Ascend [DATASET_PATH] [CHECKPOINT_PATH] - -### Launch - -```bash -# infer example - shell: - Ascend: sh run_infer.sh Ascend ~/imagenet/val/ ~/train/Resnet50-30_5004.ckpt -``` - -> checkpoint can be produced in training process. - -### Result - -Inference result will be stored in the example path, you can find result like the following in `./eval/infer.log`. - -```bash -result: {'acc': 0.76576314102564111} -``` - -## [Model Export](#contents) - -```shell -python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --device_target [PLATFORM] -``` - -`EXPORT_FORMAT` should be in ["AIR", "MINDIR"]. - -## [Ascend 310 inference](#contents) - -You should export AIR model at Ascend 910 before running the command below. -You can use export_bin_file.py to export ImageNet bin and label for 310 inference. - -```shell -python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH] -``` - -Run run_infer_310.sh and get the accuracy锛� - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] -``` - -You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows: - -```bash -'Accuracy':0.77052 -``` - -# [Model description](#contents) - -## [Performance](#contents) - -### Evaluation Performance - -| Parameters | Ascend | -| -------------------------- | ----------------------------------------------------------- | -| Model Version | ResNet50 V1.5 | -| Resource | Ascend 910; CPU 2.60GHz, 56cores; Memory 314G; OS Euler2.8 | -| uploaded Date | 07/05/2021 (month/day/year) | -| MindSpore Version | 1.3.0 | -| Dataset | ImageNet | -| Training Parameters | epoch=30(with pretrained) or 120, steps per epoch=5004, batch_size=32 | -| Optimizer | Momentum | -| Loss Function | Softmax Cross Entropy | -| outputs | probability | -| Loss | 1.8 | -| Speed | 8pcs: 407 ms/step | -| Total time | 8pcs: 17 hours(30 epochs with pretrained) | -| Parameters (M) | 25.5 | -| Checkpoint for Fine tuning | 197M (.ckpt file) | -| Scripts | [resnet50-quant script](https://gitee.com/mindspore/models/tree/master/official/cv/resnet50_quant) | - -### Inference Performance - -| Parameters | Ascend | -| ------------------- | --------------------------- | -| Model Version | ResNet50 V1.5 | -| Resource | Ascend 910; CPU 2.60GHz, 56cores; Memory 314G; OS Euler2.8 | -| Uploaded Date | 07/05/2021 (month/day/year) | -| MindSpore Version | 1.3.0 | -| Dataset | ImageNet | -| batch_size | 32 | -| outputs | probability | -| Accuracy | ACC1[76.57%] ACC5[92.90%] | -| Model for inference | 197M (.ckpt file) | - -# [Description of Random Situation](#contents) - -In dataset.py, we set the seed inside 鈥渃reate_dataset" function. We also use random seed in train.py. - -# [ModelZoo Homepage](#contents) - -Please check the official [homepage](https://gitee.com/mindspore/models). diff --git a/official/cv/resnet50_quant/README_CN.md b/official/cv/resnet50_quant/README_CN.md deleted file mode 100644 index b7a45a662b68a65019f68cde16c88d77e1d6f93d..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/README_CN.md +++ /dev/null @@ -1,262 +0,0 @@ -# 鐩綍 - -<!-- TOC --> - -- [鐩綍](#鐩綍) -- [ResNet-50姒傝堪](#resnet-50姒傝堪) - - [妯″瀷鏋舵瀯](#妯″瀷鏋舵瀯) - - [鏁版嵁闆哴(#鏁版嵁闆�) - - [鐗规€(#鐗规€�) - - [娣峰悎绮惧害](#娣峰悎绮惧害) -- [鐜瑕佹眰](#鐜瑕佹眰) - - [鑴氭湰璇存槑](#鑴氭湰璇存槑) - - [鑴氭湰鍜屾牱渚嬩唬鐮乚(#鑴氭湰鍜屾牱渚嬩唬鐮�) - - [鑴氭湰鍙傛暟](#鑴氭湰鍙傛暟) - - [璁粌杩囩▼](#璁粌杩囩▼) - - [鐢ㄦ硶](#鐢ㄦ硶) - - [鍚姩](#鍚姩) - - [缁撴灉](#缁撴灉) - - [璇勪及杩囩▼](#璇勪及杩囩▼) - - [鐢ㄦ硶](#鐢ㄦ硶-1) - - [鍚姩](#鍚姩-1) - - [缁撴灉](#缁撴灉-1) - - [妯″瀷瀵煎嚭](#妯″瀷瀵煎嚭) - - [Ascend 310 鎺ㄧ悊](#ascend-310-鎺ㄧ悊) -- [妯″瀷鎻忚堪](#妯″瀷鎻忚堪) - - [鎬ц兘](#鎬ц兘) - - [璁粌鎬ц兘](#璁粌鎬ц兘) - - [璇勪及鎬ц兘](#璇勪及鎬ц兘) - - [闅忔満鎯呭喌璇存槑](#闅忔満鎯呭喌璇存槑) - - [ModelZoo涓婚〉](#modelzoo涓婚〉) - -<!-- /TOC --> - -# ResNet-50姒傝堪 - -ResNet-50鏄竴涓�50灞傜殑鍗风Н绁炵粡缃戠粶锛屽彲浠ュ皢ImageNet鍥惧儚鍒嗘垚1000涓洰鏍囩被锛屽噯纭巼杈�76%銆� - -[璁烘枃](https://arxiv.org/abs/1512.03385)锛� Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun."Deep Residual Learning for Image Recognition."锛� He, Kaiming , et al. "Deep Residual Learning for Image Recognition." IEEE Conference on Computer Vision & Pattern Recognition IEEE Computer Society, 2016. - -姝や负ResNet-50鐨勯噺鍖栧垎鏋愮綉缁溿€� - -## 妯″瀷鏋舵瀯 - -ResNet-50鎬讳綋缃戠粶鏋舵瀯濡備笅锛� - -[閾炬帴](https://arxiv.org/pdf/1512.03385.pdf) - -## 鏁版嵁闆� - -浣跨敤鐨勬暟鎹泦锛歔imagenet](http://www.image-net.org/) - -- 鏁版嵁闆嗗ぇ灏忥細125G锛屽叡1000涓被銆�1.2涓囧紶褰╄壊鍥惧儚 - - 璁粌闆嗭細120G锛屽叡1.2涓囧紶鍥惧儚 - - 娴嬭瘯闆嗭細5G锛屽叡5涓囧紶鍥惧儚 - -- 鏁版嵁鏍煎紡锛歊GB - - 娉細鏁版嵁鍦╯rc/dataset.py涓鐞嗐€� - -## 鐗规€� - -## 娣峰悎绮惧害 - -閲囩敤[娣峰悎绮惧害](https://www.mindspore.cn/docs/programming_guide/zh-CN/master/enable_mixed_precision.html)鐨勮缁冩柟娉曚娇鐢ㄦ敮鎸佸崟绮惧害鍜屽崐绮惧害鏁版嵁鏉ユ彁楂樻繁搴﹀涔犵缁忕綉缁滅殑璁粌閫熷害锛屽悓鏃朵繚鎸佸崟绮惧害璁粌鎵€鑳借揪鍒扮殑缃戠粶绮惧害銆傛贩鍚堢簿搴﹁缁冩彁楂樿绠楅€熷害銆佸噺灏戝唴瀛樹娇鐢ㄧ殑鍚屾椂锛屾敮鎸佸湪鐗瑰畾纭欢涓婅缁冩洿澶х殑妯″瀷鎴栧疄鐜版洿澶ф壒娆$殑璁粌銆� -浠P16绠楀瓙涓轰緥锛屽鏋滆緭鍏ユ暟鎹被鍨嬩负FP32锛孧indSpore鍚庡彴浼氳嚜鍔ㄩ檷浣庣簿搴︽潵澶勭悊鏁版嵁銆傜敤鎴峰彲鎵撳紑INFO鏃ュ織锛屾悳绱⑩€渞educe precision鈥濇煡鐪嬬簿搴﹂檷浣庣殑绠楀瓙銆� - -# 鐜瑕佹眰 - -- 纭欢锛氭槆鑵惧鐞嗗櫒锛圓scend锛� - - 浣跨敤鏄囪吘澶勭悊鍣ㄦ潵鎼缓纭欢鐜銆� - -- 妗嗘灦 - - [MindSpore](https://www.mindspore.cn/install) - -- 濡傞渶鏌ョ湅璇︽儏锛岃鍙傝濡備笅璧勬簮锛� - - - [MindSpore鏁欑▼](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) - - - [MindSpore Python API](https://www.mindspore.cn/docs/api/zh-CN/master/index.html) - -## 鑴氭湰璇存槑 - -## 鑴氭湰鍜屾牱渚嬩唬鐮� - -```python -鈹溾攢鈹€ resnet50_quant - 鈹溾攢鈹€ Readme.md # ResNet-50-Quant鐩稿叧鎻忚堪 - 鈹溾攢鈹€ ascend310_infer # 瀹炵幇310鎺ㄧ悊婧愪唬鐮� - 鈹溾攢鈹€ scripts - 鈹� 鈹溾攢鈹€run_train.sh # 浣跨敤鏄囪吘澶勭悊鍣ㄨ繘琛岃缁冪殑shell鑴氭湰 - 鈹� 鈹溾攢鈹€run_infer.sh # 浣跨敤鏄囪吘澶勭悊鍣ㄨ繘琛岃瘎浼扮殑shell鑴氭湰 - 鈹� 鈹溾攢鈹€run_infer_310.sh # Ascend 310 鎺ㄧ悊shell鑴氭湰 - 鈹溾攢鈹€ model - 鈹� 鈹溾攢鈹€resnet_quant.py # 瀹氫箟ResNet50-Quant鐨勭綉缁滄ā鍨� - 鈹溾攢鈹€src - 鈹� 鈹溾攢鈹€config.py # 鍙傛暟閰嶇疆 - 鈹� 鈹溾攢鈹€dataset.py # 鍒涘缓鏁版嵁闆� - 鈹� 鈹溾攢鈹€launch.py # 鍚姩Python鑴氭湰 - 鈹� 鈹溾攢鈹€lr_generator.py # 閰嶇疆瀛︿範閫熺巼 - 鈹� 鈹溾攢鈹€crossentropy.py # 瀹氫箟ResNet-50-Quant鐨勪氦鍙夌喌 - 鈹溾攢鈹€ train.py # 璁粌鑴氭湰 - 鈹溾攢鈹€ eval.py # 璇勪及鑴氭湰 - 鈹溾攢鈹€ export.py # 瀵煎嚭鑴氭湰 - 鈹溾攢鈹€ export_bin_file.py # 瀵煎嚭ImageNet鏁版嵁闆嗙殑bin鏂囦欢鐢ㄤ簬310鎺ㄧ悊 - 鈹溾攢鈹€ postprocess.py # 310鎺ㄧ悊鍚庡鐞嗚剼鏈� - -``` - -### 鑴氭湰鍙傛暟 - -鍦╟onfig.py涓彲浠ュ悓鏃堕厤缃缁冨弬鏁板拰璇勪及鍙傛暟銆� - -- 閰嶇疆Resnet50-quent鍜孖mageNet2012鏁版嵁闆嗐€� - - ```python - 'class_num'锛�10 # 鏁版嵁闆嗙殑绫绘暟 - "batch_size"锛�32 # 璁粌鎵规澶у皬 - "loss_scale"锛�1024 # loss_scale鍒濆鍊� - 'momentum': 0.9 # 鍔ㄩ噺 - 'weight_decay'锛�1e-4 # 鏉冮噸琛板噺鍊� - 'epoch_size'锛�120 # 璁粌杞鏁� - 'pretrained_epoch_size'锛�90 # 闈為噺鍖栫綉缁滈璁粌杞鏁� - 'data_load_mode': 'original' # 鏁版嵁鍔犺浇妯″紡锛屾敮鎸�'original'鍜�'mindrecord' - 'save_checkpoint'锛歍rue # 璁粌缁撴潫鍚庢槸鍚︿繚瀛樻鏌ョ偣鏂囦欢 - "save_checkpoint_epochs": 1 # 寮€濮嬩繚瀛樻鏌ョ偣鏂囦欢鐨勬楠� - 'keep_checkpoint_max'锛�50 # 鍙繚鐣欐渶鍚庝竴涓猭eep_checkpoint_max妫€鏌ョ偣 - 'save_checkpoint_path'锛�'./' # 妫€鏌ョ偣鏂囦欢淇濆瓨鐨勭粷瀵瑰叏璺緞 - "warmup_epochs"锛�0 # 鐑韩杞鏁� - 'lr_decay_mode'锛�"cosine" # 瀛︿範閫熺巼琛板噺妯″紡锛屽寘鎷瑂tep銆乻tep_decay銆乧osine鍙妉iner - 'use_label_smooth'锛歍rue # 鏄惁浣跨敤鏍囩骞虫粦 - 'label_smooth_factor': 0.1 # 鏍囩骞虫粦鍥犲瓙 - "lr_init": 0 # 鍒濆瀛︿範閫熺巼 - 'lr_max'锛�0.005 # 鏈€澶у涔犻€熺巼 - ``` - -## 璁粌杩囩▼ - -### 鐢ㄦ硶 - -- 鏅熻吘锛圓scend锛�: bash run_train.sh Ascend [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH]\锛堝彲閫夛級 - -### 鍚姩 - -```python - # 璁粌绀轰緥 - Ascend:bash run_train.sh Ascend ~/hccl_4p_0123_x.x.x.json ~/imagenet/train/ -``` - -### 缁撴灉 - -璁粌缁撴灉淇濆瓨鍦ㄧず渚嬭矾寰勪腑銆傛鏌ョ偣榛樿淇濆瓨鍦╜./train/device$i/`锛岃缁冩棩蹇楅噸瀹氬悜鍒癭./train/device$i/train.log`锛屽唴瀹瑰涓嬶細 - -```python -epoch: 1 step: 5004, loss is 4.8995576 -epoch: 2 step: 5004, loss is 3.9235563 -epoch: 3 step: 5004, loss is 3.833077 -epoch: 4 step: 5004, loss is 3.2795618 -epoch: 5 step: 5004, loss is 3.1978393 -``` - -## 璇勪及杩囩▼ - -### 鐢ㄦ硶 - -浣跨敤python鎴杝hell鑴氭湰寮€濮嬭缁冦€俿hell鑴氭湰鐨勪娇鐢ㄦ柟娉曞涓嬶細 - -- 鏄囪吘锛圓scend锛夛細sh run_infer.sh Ascend[DATASET_PATH] [CHECKPOINT_PATH] - -### 鍚姩 - -```shell -# 鎺ㄧ悊绀轰緥 - shell: - Ascend: bash run_infer.sh Ascend ~/imagenet/val/ ~/train/Resnet50-30_5004.ckpt -``` - -> 璁粌杩囩▼涓彲浠ョ敓鎴愭鏌ョ偣銆� - -### 缁撴灉 - -鎺ㄧ悊缁撴灉淇濆瓨鍦ㄧず渚嬭矾寰勪腑锛屽彲浠ュ湪`./eval/infer.log`涓壘鍒板涓嬬粨鏋滐細 - -```python -result:{'acc'锛�0.76576314102564111} -``` - -## 妯″瀷瀵煎嚭 - -```shell -python export.py --checkpoint_path [CKPT_PATH] --file_format [EXPORT_FORMAT] --device_target [PLATFORM] -``` - -`EXPORT_FORMAT` 鍙€� ["AIR", "MINDIR"]. - -## Ascend 310 鎺ㄧ悊 - -鍦ㄦ帹鐞嗕箣鍓嶉渶瑕佸湪鏄囪吘910鐜涓婂畬鎴怉IR妯″瀷鐨勫鍑恒€� -骞朵娇鐢╡xport_bin_file.py瀵煎嚭ImageNet鏁版嵁闆嗙殑bin鏂囦欢鍜屽搴旂殑label鏂囦欢锛� - -```shell -python export_bin_file.py --dataset_dir [EVAL_DATASET_PATH] --save_dir [SAVE_PATH] -``` - -鎵ц鎺ㄧ悊骞跺緱鍒版帹鐞嗙簿搴︼細 - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] -``` - -鎮ㄥ彲浠ラ€氳繃acc.log鏂囦欢鏌ョ湅缁撴灉銆傛帹鐞嗗噯纭€у涓嬶細 - -```bash -'Accuracy':0.77052 -``` - -# 妯″瀷鎻忚堪 - -## 鎬ц兘 - -### 璁粌鎬ц兘 - -| 鍙傛暟 | Resnet50 | -| -------------------------- | ---------------------------------------------------------- | -| 妯″瀷鐗堟湰 | V1 | -| 璧勬簮 | Ascend 910锛� CPU 2.60GHz锛�192鏍革紱鍐呭瓨 755G锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2021-07-05 | -| MindSpore鐗堟湰 | 1.3.0 | -| 鏁版嵁闆� | ImageNet | -| 璁粌鍙傛暟 | src/config.py | -| 浼樺寲鍣� | Momentum | -| 鎹熷け鍑芥暟 | SoftmaxCrossEntropy | -| 杈撳嚭 | ckpt file | -| 鎹熷け | 1.8 | -| 鍑嗙‘鐜� | -| 鎬绘椂闀� | 16h | -| 鍙傛暟(M) | batch_size=32, epoch=30 | -| 寰皟妫€鏌ョ偣 | -| 鎺ㄧ悊妯″瀷 | - -### 璇勪及鎬ц兘 - -| 鍙傛暟鍒楄〃 | Resnet50 | -| -------------------------- | ----------------------------- | -| 妯″瀷鐗堟湰 | V1 | -| 璧勬簮 | Ascend 910锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2021-07-05 | -| MindSpore鐗堟湰 | 1.3.0 | -| 鏁版嵁闆� | ImageNet, 1.2W | -| batch_size | 130锛�8鍗★級 | -| 杈撳嚭 | 姒傜巼 | -| 鍑嗙‘鐜� | ACC1[76.57%] ACC5[92.90%] | -| 閫熷害 | 5姣/姝� | -| 鎬绘椂闂� | 5鍒嗛挓 | -| 鎺ㄧ悊妯″瀷 | - -## 闅忔満鎯呭喌璇存槑 - -dataset.py涓缃簡鈥渃reate_dataset鈥濆嚱鏁板唴鐨勭瀛愶紝鍚屾椂杩樹娇鐢ㄤ簡train.py涓殑闅忔満绉嶅瓙銆� - -## ModelZoo涓婚〉 - -璇锋祻瑙堝畼缃慬涓婚〉](https://gitee.com/mindspore/models)銆� diff --git a/official/cv/resnet50_quant/ascend310_infer/inc/ModelProcess.h b/official/cv/resnet50_quant/ascend310_infer/inc/ModelProcess.h deleted file mode 100644 index 9acb683bee2a037a98878d98c0605985701f913a..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/inc/ModelProcess.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MODELPROCESS_H -#define MODELPROCESS_H - -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* ModelProcess -*/ -class ModelProcess { - public: - /** - * @brief Constructor - */ - ModelProcess(); - - /** - * @brief Destructor - */ - ~ModelProcess(); - - /** - * @brief load model from file with mem - * @param [in] modelPath: model path - * @return result - */ - Result LoadModelFromFileWithMem(const char *modelPath); - - /** - * @brief unload model - */ - void Unload(); - - /** - * @brief create model desc - * @return result - */ - Result CreateDesc(); - - /** - * @brief destroy desc - */ - void DestroyDesc(); - - /** - * @brief create model input - * @param [in] inputDataBuffer: input buffer - * @param [in] bufferSize: input buffer size - * @return result - */ - Result CreateInput(void *inputDataBuffer, size_t bufferSize); - - /** - * @brief destroy input resource - */ - void DestroyInput(); - - /** - * @brief create output buffer - * @return result - */ - Result CreateOutput(); - - /** - * @brief destroy output resource - */ - void DestroyOutput(); - - /** - * @brief model execute - * @return result - */ - Result Execute(); - - /** - * @brief dump model output result to file - */ - void DumpModelOutputResult(char *output_name); - - /** - * @brief get model output result - */ - void OutputModelResult(); - - private: - uint32_t modelId_; - size_t modelMemSize_; - size_t modelWeightSize_; - void *modelMemPtr_; - void *modelWeightPtr_; - bool loadFlag_; // model load flag - aclmdlDesc *modelDesc_; - aclmdlDataset *input_; - aclmdlDataset *output_; -}; -#endif diff --git a/official/cv/resnet50_quant/ascend310_infer/inc/SampleProcess.h b/official/cv/resnet50_quant/ascend310_infer/inc/SampleProcess.h deleted file mode 100644 index 30a77f4248c948b83d019ee05aaf56dce9a08e26..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/inc/SampleProcess.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef SAMPLEPROCESS_H -#define SAMPLEPROCESS_H - -#include <string> -#include <vector> -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* SampleProcess -*/ -class SampleProcess { - public: - /** - * @brief Constructor - */ - explicit SampleProcess(int32_t deviceId); - - /** - * @brief Destructor - */ - ~SampleProcess(); - - /** - * @brief init reousce - * @return result - */ - Result InitResource(const char *acl_config_path); - - /** - * @brief sample process - * @return result - */ - Result Process(const char *om_path, const char *input_folder); - - void GetAllFiles(std::string path, std::vector<std::string> *files); - - private: - void DestroyResource(); - - int32_t deviceId_; - aclrtContext context_; - aclrtStream stream_; -}; - -#endif diff --git a/official/cv/resnet50_quant/ascend310_infer/inc/utils.h b/official/cv/resnet50_quant/ascend310_infer/inc/utils.h deleted file mode 100644 index b21e418a1f4ad2b8fc0331cf0b37adf73f2703f6..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/inc/utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MINDSPORE_INFERENCE_UTILS_H_ -#define MINDSPORE_INFERENCE_UTILS_H_ - -#include <iostream> -#include <string> - -#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args) -#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args) -#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args) - -typedef enum Result { - SUCCESS = 0, - FAILED = 1 -} Result; - -/** -* Utils -*/ -class Utils { - public: - /** - * @brief create device buffer of file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return device buffer of file - */ - static void *GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize); - - /** - * @brief Read bin file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return buffer of pic - */ - static void* ReadBinFile(std::string fileName, uint32_t *fileSize); -}; -#endif diff --git a/official/cv/resnet50_quant/ascend310_infer/src/CMakeLists.txt b/official/cv/resnet50_quant/ascend310_infer/src/CMakeLists.txt deleted file mode 100644 index 65961330a3219658f5c46fa430e6c5844f2536a4..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - -# CMake lowest version requirement -cmake_minimum_required(VERSION 3.5.1) -# project information -project(InferClassification) -# Check environment variable -if(NOT DEFINED ENV{ASCEND_HOME}) - message(FATAL_ERROR "please define environment variable:ASCEND_HOME") -endif() - -# Compile options -add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined") - -# Skip build rpath -set(CMAKE_SKIP_BUILD_RPATH True) - -# Set output directory -set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out) - -# Set include directory and library directory -set(FWKACL_LIB_DIR $ENV{ASCEND_HOME}/fwkacllib) -set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib) -set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib) - -# Header path -include_directories(${ACL_LIB_DIR}/include/) -include_directories(${FWKACL_LIB_DIR}/include/) -include_directories(${ATLAS_ACL_LIB_DIR}/include/) -include_directories(${PROJECT_SRC_ROOT}/../inc) - -# add host lib path -link_directories(${ACL_LIB_DIR} ${FWKACL_LIB_DIR}) -find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${FWKACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64) - -add_executable(main utils.cpp - SampleProcess.cpp - ModelProcess.cpp - main.cpp) - -target_link_libraries(main ${acl} gflags pthread) diff --git a/official/cv/resnet50_quant/ascend310_infer/src/ModelProcess.cpp b/official/cv/resnet50_quant/ascend310_infer/src/ModelProcess.cpp deleted file mode 100644 index 72744284906a6d1b6ee9bc1051ada5872526c101..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/ModelProcess.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/ModelProcess.h" -#include <iostream> -#include <map> -#include <sstream> -#include <algorithm> -#include "../inc/utils.h" - -extern bool g_isDevice; - -ModelProcess::ModelProcess() :modelId_(0), modelMemSize_(0), modelWeightSize_(0), modelMemPtr_(nullptr), -modelWeightPtr_(nullptr), loadFlag_(false), modelDesc_(nullptr), input_(nullptr), output_(nullptr) { -} - -ModelProcess::~ModelProcess() { - Unload(); - DestroyDesc(); - DestroyInput(); - DestroyOutput(); -} - -Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath) { - if (loadFlag_) { - ERROR_LOG("has already loaded a model"); - return FAILED; - } - - aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("query model failed, model file is %s", modelPath); - return FAILED; - } - - ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_); - return FAILED; - } - - ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_); - return FAILED; - } - - ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, - modelMemSize_, modelWeightPtr_, modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("load model from file failed, model file is %s", modelPath); - return FAILED; - } - - loadFlag_ = true; - INFO_LOG("load model %s success", modelPath); - return SUCCESS; -} - -Result ModelProcess::CreateDesc() { - modelDesc_ = aclmdlCreateDesc(); - if (modelDesc_ == nullptr) { - ERROR_LOG("create model description failed"); - return FAILED; - } - - aclError ret = aclmdlGetDesc(modelDesc_, modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("get model description failed"); - return FAILED; - } - - INFO_LOG("create model description success"); - - return SUCCESS; -} - -void ModelProcess::DestroyDesc() { - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } -} - -Result ModelProcess::CreateInput(void *inputDataBuffer, size_t bufferSize) { - input_ = aclmdlCreateDataset(); - if (input_ == nullptr) { - ERROR_LOG("can't create dataset, create input failed"); - return FAILED; - } - - aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer, bufferSize); - if (inputData == nullptr) { - ERROR_LOG("can't create data buffer, create input failed"); - return FAILED; - } - - aclError ret = aclmdlAddDatasetBuffer(input_, inputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("add input dataset buffer failed"); - aclDestroyDataBuffer(inputData); - inputData = nullptr; - return FAILED; - } - - return SUCCESS; -} - -void ModelProcess::DestroyInput() { - if (input_ == nullptr) { - return; - } - - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); - aclDestroyDataBuffer(dataBuffer); - } - aclmdlDestroyDataset(input_); - input_ = nullptr; -} - -Result ModelProcess::CreateOutput() { - if (modelDesc_ == nullptr) { - ERROR_LOG("no model description, create output failed"); - return FAILED; - } - - output_ = aclmdlCreateDataset(); - if (output_ == nullptr) { - ERROR_LOG("can't create dataset, create output failed"); - return FAILED; - } - - size_t outputSize = aclmdlGetNumOutputs(modelDesc_); - for (size_t i = 0; i < outputSize; ++i) { - size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i); - void *outputBuffer = nullptr; - aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size); - return FAILED; - } - - aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't create data buffer, create output failed"); - aclrtFree(outputBuffer); - return FAILED; - } - - ret = aclmdlAddDatasetBuffer(output_, outputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't add data buffer, create output failed"); - aclrtFree(outputBuffer); - aclDestroyDataBuffer(outputData); - return FAILED; - } - } - - INFO_LOG("create model output success"); - return SUCCESS; -} - -void ModelProcess::DumpModelOutputResult(char *output_name) { - size_t outputNum = aclmdlGetDatasetNumBuffers(output_); - std::string homePath = "./result_Files"; - for (size_t i = 0; i < outputNum; ++i) { - std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin"; - std::string outputFileName = homePath + "/" + fileName; - FILE *outputFile = fopen(outputFileName.c_str(), "wb"); - if (outputFile != nullptr) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void* outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - (void)aclrtFreeHost(outHostData); - return; - } - fwrite(outHostData, len, sizeof(char), outputFile); - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } else { - fwrite(data, len, sizeof(char), outputFile); - } - fclose(outputFile); - outputFile = nullptr; - } else { - ERROR_LOG("create output file [%s] failed", outputFileName.c_str()); - return; - } - } - INFO_LOG("dump data success"); - return; -} - -void ModelProcess::OutputModelResult() { - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void *outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - float *outData = NULL; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - return; - } - outData = reinterpret_cast<float*>(outHostData); - } else { - outData = reinterpret_cast<float*>(data); - } - std::map<float, unsigned int, std::greater<float> > resultMap; - for (unsigned int j = 0; j < len / sizeof(float); ++j) { - resultMap[*outData] = j; - outData++; - } - int cnt = 0; - for (auto it = resultMap.begin(); it != resultMap.end(); ++it) { - // print top 5 - if (++cnt > 5) { - break; - } - INFO_LOG("top %d: index[%d] value[%lf]", cnt, it->second, it->first); - } - if (!g_isDevice) { - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } - } - INFO_LOG("output data success"); - return; -} - -void ModelProcess::DestroyOutput() { - if (output_ == nullptr) { - return; - } - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - (void)aclrtFree(data); - (void)aclDestroyDataBuffer(dataBuffer); - } - - (void)aclmdlDestroyDataset(output_); - output_ = nullptr; -} - -Result ModelProcess::Execute() { - aclError ret = aclmdlExecute(modelId_, input_, output_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("execute model failed, modelId is %u", modelId_); - return FAILED; - } - - INFO_LOG("model execute success"); - return SUCCESS; -} - -void ModelProcess::Unload() { - if (!loadFlag_) { - WARN_LOG("no model had been loaded, unload failed"); - return; - } - - aclError ret = aclmdlUnload(modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("unload model failed, modelId is %u", modelId_); - } - - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } - - if (modelMemPtr_ != nullptr) { - aclrtFree(modelMemPtr_); - modelMemPtr_ = nullptr; - modelMemSize_ = 0; - } - - if (modelWeightPtr_ != nullptr) { - aclrtFree(modelWeightPtr_); - modelWeightPtr_ = nullptr; - modelWeightSize_ = 0; - } - - loadFlag_ = false; - INFO_LOG("unload model success, modelId is %u", modelId_); -} diff --git a/official/cv/resnet50_quant/ascend310_infer/src/SampleProcess.cpp b/official/cv/resnet50_quant/ascend310_infer/src/SampleProcess.cpp deleted file mode 100644 index 6870f9d8e438e6794f11d7f44ea61136ac8089f3..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/SampleProcess.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/SampleProcess.h" -#include <sys/types.h> -#include <dirent.h> -#include <string.h> -#include <iostream> -#include <fstream> -#include "../inc/utils.h" -#include "../inc/ModelProcess.h" -#include "acl/acl.h" - -extern bool g_isDevice; -using std::string; -using std::vector; - -SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) { - deviceId_ = deviceId; -} - -SampleProcess::~SampleProcess() { - DestroyResource(); -} - -Result SampleProcess::InitResource(const char *aclConfigPath) { - // ACL init - aclError ret = aclInit(aclConfigPath); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl init failed"); - return FAILED; - } - INFO_LOG("acl init success"); - - // open device - ret = aclrtSetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl open device %d failed", deviceId_); - return FAILED; - } - INFO_LOG("open device %d success", deviceId_); - - // create context (set current) - ret = aclrtCreateContext(&context_, deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create context failed"); - return FAILED; - } - INFO_LOG("create context success"); - - // create stream - ret = aclrtCreateStream(&stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create stream failed"); - return FAILED; - } - INFO_LOG("create stream success"); - - // get run mode - aclrtRunMode runMode; - ret = aclrtGetRunMode(&runMode); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl get run mode failed"); - return FAILED; - } - g_isDevice = (runMode == ACL_DEVICE); - INFO_LOG("get run mode success"); - return SUCCESS; -} - -void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) { - DIR *pDir = nullptr; - struct dirent* ptr = nullptr; - if (!(pDir = opendir(path.c_str()))) - return; - while ((ptr = readdir(pDir)) != 0) { - if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) - files->push_back(path + "/" + ptr->d_name); - } - closedir(pDir); -} - -Result SampleProcess::Process(const char *om_path, const char *input_folder) { - // model init - ModelProcess processModel; - - Result ret = processModel.LoadModelFromFileWithMem(om_path); - if (ret != SUCCESS) { - ERROR_LOG("execute LoadModelFromFileWithMem failed"); - return FAILED; - } - - ret = processModel.CreateDesc(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateDesc failed"); - return FAILED; - } - - ret = processModel.CreateOutput(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateOutput failed"); - return FAILED; - } - - std::vector<string> testFile; - GetAllFiles(input_folder, &testFile); - - if (testFile.size() == 0) { - WARN_LOG("no input data under folder"); - } - - // loop begin - for (size_t index = 0; index < testFile.size(); ++index) { - INFO_LOG("start to process file:%s", testFile[index].c_str()); - // model process - uint32_t devBufferSize; - void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize); - if (picDevBuffer == nullptr) { - ERROR_LOG("get pic device buffer failed,index is %zu", index); - return FAILED; - } - ret = processModel.CreateInput(picDevBuffer, devBufferSize); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateInput failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - ret = processModel.Execute(); - if (ret != SUCCESS) { - ERROR_LOG("execute inference failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - int pos = testFile[index].find_last_of('/'); - std::string name = testFile[index].substr(pos+1); - std::string outputname = name.substr(0, name.rfind(".")); - - // print the top 5 confidence values - processModel.OutputModelResult(); - // dump output result to file in the current directory - processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str())); - - // release model input buffer - aclrtFree(picDevBuffer); - processModel.DestroyInput(); - } - // loop end - - return SUCCESS; -} - -void SampleProcess::DestroyResource() { - aclError ret; - if (stream_ != nullptr) { - ret = aclrtDestroyStream(stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy stream failed"); - } - stream_ = nullptr; - } - INFO_LOG("end to destroy stream"); - - if (context_ != nullptr) { - ret = aclrtDestroyContext(context_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy context failed"); - } - context_ = nullptr; - } - INFO_LOG("end to destroy context"); - - ret = aclrtResetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("reset device failed"); - } - INFO_LOG("end to reset device is %d", deviceId_); - - ret = aclFinalize(); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("finalize acl failed"); - } - INFO_LOG("end to finalize acl"); -} - diff --git a/official/cv/resnet50_quant/ascend310_infer/src/acl.json b/official/cv/resnet50_quant/ascend310_infer/src/acl.json deleted file mode 100644 index 9e26dfeeb6e641a33dae4961196235bdb965b21b..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/acl.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/official/cv/resnet50_quant/ascend310_infer/src/build.sh b/official/cv/resnet50_quant/ascend310_infer/src/build.sh deleted file mode 100644 index b5979b68e60b673f763a3cac98c5e147e7085291..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/build.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -path_cur=$(cd "`dirname $0`" || exit; pwd) - -function preparePath() { - rm -rf $1 - mkdir -p $1 - cd $1 || exit -} - -function buildA300() { - if [ ! "${ARCH_PATTERN}" ]; then - # set ARCH_PATTERN to acllib when it was not specified by user - export ARCH_PATTERN=acllib - echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}" - else - echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib" - export ARCH_PATTERN=${ARCH_PATTERN}/acllib - fi - - path_build=$path_cur/build - preparePath $path_build - cmake .. - make -j - ret=$? - cd .. - return ${ret} -} - -# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user -if [ ! "${ASCEND_VERSION}" ]; then - export ASCEND_VERSION=ascend-toolkit/latest - echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}" -else - echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user" -fi - -buildA300 - -if [ $? -ne 0 ]; then - exit 1 -fi diff --git a/official/cv/resnet50_quant/ascend310_infer/src/main.cpp b/official/cv/resnet50_quant/ascend310_infer/src/main.cpp deleted file mode 100644 index ca47f0635efd1618ba9fd85fe63186f55c54e421..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include <gflags/gflags.h> -#include <iostream> -#include <fstream> -#include <memory> -#include "../inc/SampleProcess.h" -#include "../inc/utils.h" - -bool g_isDevice = false; - -DEFINE_string(om_path, "", "om path"); -DEFINE_string(dataset_path, "", "dataset path"); -DEFINE_string(acljson_path, "", "acl json path"); -DEFINE_int32(device_id, 0, "device id"); - -int main(int argc, char **argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - std::string om_path = FLAGS_om_path; - std::string dataset_path = FLAGS_dataset_path; - std::string acljson_path = FLAGS_acljson_path; - int32_t device_id = FLAGS_device_id; - std::ifstream fin(om_path); - if (!fin) { - std::cout << "Invalid om path." << std::endl; - return FAILED; - } - SampleProcess processSample(device_id); - // acl.json is deployed for dump data. - Result ret = processSample.InitResource(acljson_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample init resource failed"); - return FAILED; - } - - ret = processSample.Process(om_path.c_str(), dataset_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample process failed"); - return FAILED; - } - - INFO_LOG("execute sample success"); - return SUCCESS; -} diff --git a/official/cv/resnet50_quant/ascend310_infer/src/utils.cpp b/official/cv/resnet50_quant/ascend310_infer/src/utils.cpp deleted file mode 100644 index 6e669f3f329be5ecfba41595c72f525d4fb428d0..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/ascend310_infer/src/utils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/utils.h" -#include <sys/stat.h> -#include <iostream> -#include <fstream> -#include <cstring> -#include "acl/acl.h" - -extern bool g_isDevice; - -void* Utils::ReadBinFile(std::string fileName, uint32_t *fileSize) { - struct stat sBuf; - int fileStatus = stat(fileName.data(), &sBuf); - if (fileStatus == -1) { - ERROR_LOG("failed to get file"); - return nullptr; - } - if (S_ISREG(sBuf.st_mode) == 0) { - ERROR_LOG("%s is not a file, please enter a file", fileName.c_str()); - return nullptr; - } - - std::ifstream binFile(fileName, std::ifstream::binary); - if (binFile.is_open() == false) { - ERROR_LOG("open file %s failed", fileName.c_str()); - return nullptr; - } - - binFile.seekg(0, binFile.end); - uint32_t binFileBufferLen = binFile.tellg(); - if (binFileBufferLen == 0) { - ERROR_LOG("binfile is empty, filename is %s", fileName.c_str()); - binFile.close(); - return nullptr; - } - - binFile.seekg(0, binFile.beg); - - void* binFileBufferData = nullptr; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&binFileBufferData, binFileBufferLen); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc for binFileBufferData failed"); - binFile.close(); - return nullptr; - } - if (binFileBufferData == nullptr) { - ERROR_LOG("malloc binFileBufferData failed"); - binFile.close(); - return nullptr; - } - } else { - ret = aclrtMalloc(&binFileBufferData, binFileBufferLen, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", binFileBufferLen); - binFile.close(); - return nullptr; - } - } - binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen); - binFile.close(); - *fileSize = binFileBufferLen; - return binFileBufferData; -} - -void* Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize) { - uint32_t inputHostBuffSize = 0; - void* inputHostBuff = Utils::ReadBinFile(fileName, &inputHostBuffSize); - if (inputHostBuff == nullptr) { - return nullptr; - } - if (!g_isDevice) { - void *inBufferDev = nullptr; - uint32_t inBufferSize = inputHostBuffSize; - aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - - ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u", - inBufferSize, inputHostBuffSize); - aclrtFree(inBufferDev); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - aclrtFreeHost(inputHostBuff); - *fileSize = inBufferSize; - return inBufferDev; - } else { - *fileSize = inputHostBuffSize; - return inputHostBuff; - } -} diff --git a/official/cv/resnet50_quant/eval.py b/official/cv/resnet50_quant/eval.py deleted file mode 100644 index ea8d3c11d3ed347bb7ff2d4c59bf13f85229c765..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/eval.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Evaluate Resnet50 on ImageNet""" - -import os -import argparse - -from src.config import config_quant -from src.dataset import create_dataset -from src.crossentropy import CrossEntropy -from models.resnet_quant_manual import resnet50_quant #manually construct quantative network of resnet50 - -from mindspore import context -from mindspore.train.model import Model -from mindspore.train.serialization import load_checkpoint, load_param_into_net - -parser = argparse.ArgumentParser(description='Image classification') -parser.add_argument('--checkpoint_path', type=str, default=None, help='Checkpoint file path') -parser.add_argument('--dataset_path', type=str, default=None, help='Dataset path') -parser.add_argument('--device_target', type=str, default='Ascend', help='Device target') -args_opt = parser.parse_args() - -context.set_context(mode=context.GRAPH_MODE, device_target=args_opt.device_target, save_graphs=False) -config = config_quant - -if args_opt.device_target == "Ascend": - device_id = int(os.getenv('DEVICE_ID')) - context.set_context(device_id=device_id) - -if __name__ == '__main__': - # define manual quantization network - network = resnet50_quant(class_num=config.class_num) - - # define network loss - 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) - - # define dataset - dataset = create_dataset(dataset_path=args_opt.dataset_path, - do_train=False, - batch_size=config.batch_size, - target=args_opt.device_target) - step_size = dataset.get_dataset_size() - - # load checkpoint - if args_opt.checkpoint_path: - param_dict = load_checkpoint(args_opt.checkpoint_path) - not_load_param = load_param_into_net(network, param_dict) - if not_load_param: - raise ValueError("Load param into network fail!") - network.set_train(False) - - # define model - model = Model(network, loss_fn=loss, metrics={'acc'}) - - print("============== Starting Validation ==============") - res = model.eval(dataset) - print("result:", res, "ckpt=", args_opt.checkpoint_path) - print("============== End Validation ==============") diff --git a/official/cv/resnet50_quant/export.py b/official/cv/resnet50_quant/export.py deleted file mode 100644 index 8424a125a6d9a7fb68c92c3fb180ec1cb6c466e9..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/export.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Export Resnet50 on ImageNet""" - -import argparse -import numpy as np - -import mindspore -from mindspore import Tensor, context, load_checkpoint, load_param_into_net, export - -from models.resnet_quant_manual import resnet50_quant -from src.config import config_quant - -parser = argparse.ArgumentParser(description='Image classification') -parser.add_argument('--checkpoint_path', type=str, default=None, help='Checkpoint file path') -parser.add_argument('--file_format', type=str, choices=["AIR", "MINDIR"], default="MINDIR", help="file format") -parser.add_argument('--device_target', type=str, default=None, help='Run device target') -args_opt = parser.parse_args() - -if __name__ == '__main__': - context.set_context(mode=context.GRAPH_MODE, device_target=args_opt.device_target, save_graphs=False) - # define manual quantization network - network = resnet50_quant(class_num=config_quant.class_num) - - # load checkpoint - if args_opt.checkpoint_path: - param_dict = load_checkpoint(args_opt.checkpoint_path) - not_load_param = load_param_into_net(network, param_dict) - if not_load_param: - raise ValueError("Load param into network fail!") - # export network - print("============== Starting export ==============") - inputs = Tensor(np.ones([1, 3, 224, 224]), mindspore.float32) - export(network, inputs, file_name="resnet50_quant", file_format=args_opt.file_format, - quant_mode='QUANT', mean=0., std_dev=48.106) - print("============== End export ==============") diff --git a/official/cv/resnet50_quant/export_bin_file.py b/official/cv/resnet50_quant/export_bin_file.py deleted file mode 100644 index 0f4e44fd321e032a3a746d5d936f7787544ecdd0..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/export_bin_file.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -export imagenet2012 dataset to bin. -""" -import os -import argparse -from mindspore import context -from src.dataset import create_dataset - -def parse_args(): - parser = argparse.ArgumentParser(description='ImageNet2012 to bin') - 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('--dataset_dir', type=str, default='', help='dataset path') - parser.add_argument('--save_dir', type=str, default='', help='path to save bin file') - parser.add_argument('--batch_size', type=int, default=1, help='batch size for bin') - args_, _ = parser.parse_known_args() - return args_ - -if __name__ == "__main__": - args = parse_args() - os.environ["RANK_SIZE"] = '1' - os.environ["RANK_ID"] = '0' - device_id = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0 - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=device_id) - imagenet2012_path = args.dataset_dir - batch_size = args.batch_size - save_dir = os.path.join(args.save_dir, 'imagenet2012_310_infer_data') - folder = os.path.join(save_dir, 'imagenet2012_bs_' + str(batch_size) + '_bin') - if not os.path.exists(folder): - os.makedirs(folder) - ds = create_dataset(imagenet2012_path, do_train=False, repeat_num=1, batch_size=batch_size, - target=args.device_target) - iter_num = 0 - label_file = os.path.join(save_dir, './imagenet2012_bs_' + str(batch_size) + '_label.txt') - with open(label_file, 'w') as f: - for data in ds.create_dict_iterator(): - image = data['image'] - label = data['label'] - file_name = "imagenet2012_" + str(iter_num) + ".bin" - file_path = folder + "/" + file_name - image.asnumpy().tofile(file_path) - f.write(file_name) - for i in label: - f.write(',' + str(i)) - f.write('\n') - iter_num += 1 - print("=====iter_num:{}=====".format(iter_num)) - print("=====image_data:{}=====".format(image)) - print("=====label_data:{}=====".format(label)) diff --git a/official/cv/resnet50_quant/mindspore_hub_conf.py b/official/cv/resnet50_quant/mindspore_hub_conf.py deleted file mode 100644 index f6ba53e9ee575853f5a334fdb6a712d2cd614f77..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/mindspore_hub_conf.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""hub config""" -#from models.resnet_quant import resnet50_quant #auto construct quantative network of resnet50 -from models.resnet_quant_manual import resnet50_quant #manually construct quantative network of resnet50 -from src.config import config_quant as config - -def resnet50_quant_net(*args, **kwargs): - return resnet50_quant(*args, **kwargs) - -def create_network(name, *args, **kwargs): - """create_network about resnet50_quant""" - if name == "resnet50_quant": - return resnet50_quant_net(class_num=config.class_num, *args, **kwargs) - raise NotImplementedError(f"{name} is not implemented in the repo") diff --git a/official/cv/resnet50_quant/models/resnet_quant.py b/official/cv/resnet50_quant/models/resnet_quant.py deleted file mode 100644 index 437ff2d744375be05496ef1abe1524ba13c8082e..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/models/resnet_quant.py +++ /dev/null @@ -1,233 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""ResNet.""" -import numpy as np -import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore.common.tensor import Tensor - -def _weight_variable(shape, factor=0.01): - init_value = np.random.randn(*shape).astype(np.float32) * factor - return Tensor(init_value) - -def ConvBNReLU(in_channel, out_channel, kernel_size, stride=1): - """ - Convolution/Depthwise fused with Batchnorm and ReLU block definition. - """ - weight_shape = (out_channel, in_channel, kernel_size, kernel_size) - weight = _weight_variable(weight_shape) - padding = (kernel_size - 1) // 2 - return nn.Conv2dBnAct(in_channel, out_channel, kernel_size, stride, weight_init=weight, - pad_mode='pad', padding=padding, has_bn=True, activation='relu') - -class ResidualBlock(nn.Cell): - """ - ResNet V1 residual block definition. - - Args: - in_channel (int): Input channel. - out_channel (int): Output channel. - stride (int): Stride size for the first convolutional layer. Default: 1. - - Returns: - Tensor, output tensor. - - Examples: - >>> ResidualBlock(3, 256, stride=2) - """ - expansion = 4 - - def __init__(self, - in_channel, - out_channel, - stride=1): - super(ResidualBlock, self).__init__() - - channel = out_channel // self.expansion - self.conv1 = ConvBNReLU(in_channel, channel, kernel_size=1, stride=1) - self.conv2 = ConvBNReLU(channel, channel, kernel_size=3, stride=stride) - self.conv3 = nn.Conv2dBnAct(channel, out_channel, kernel_size=1, stride=1, pad_mode='same', has_bn=True) - - self.down_sample = False - if stride != 1 or in_channel != out_channel: - self.down_sample = True - self.down_sample_layer = None - - if self.down_sample: - self.down_sample_layer = nn.Conv2dBnAct(in_channel, out_channel, 1, stride, has_bn=True) - self.add = P.Add() - self.relu = P.ReLU() - - def construct(self, x): - identity = x - out = self.conv1(x) - out = self.conv2(out) - out = self.conv3(out) - - if self.down_sample: - identity = self.down_sample_layer(identity) - - out = self.add(out, identity) - out = self.relu(out) - - return out - - -class ResNet(nn.Cell): - """ - ResNet architecture. - - Args: - block (Cell): Block for network. - layer_nums (list): Numbers of block in different layers. - in_channels (list): Input channel in each layer. - out_channels (list): Output channel in each layer. - strides (list): Stride size in each layer. - num_classes (int): The number of classes that the training images are belonging to. - Returns: - Tensor, output tensor. - - Examples: - >>> ResNet(ResidualBlock, - >>> [3, 4, 6, 3], - >>> [64, 256, 512, 1024], - >>> [256, 512, 1024, 2048], - >>> [1, 2, 2, 2], - >>> 10) - """ - - def __init__(self, - block, - layer_nums, - in_channels, - out_channels, - strides, - num_classes): - super(ResNet, self).__init__() - - if not len(layer_nums) == len(in_channels) == len(out_channels) == 4: - raise ValueError("the length of layer_num, in_channels, out_channels list must be 4!") - - self.conv1 = ConvBNReLU(3, 64, kernel_size=7, stride=2) - self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same") - - self.layer1 = self._make_layer(block, - layer_nums[0], - in_channel=in_channels[0], - out_channel=out_channels[0], - stride=strides[0]) - self.layer2 = self._make_layer(block, - layer_nums[1], - in_channel=in_channels[1], - out_channel=out_channels[1], - stride=strides[1]) - self.layer3 = self._make_layer(block, - layer_nums[2], - in_channel=in_channels[2], - out_channel=out_channels[2], - stride=strides[2]) - self.layer4 = self._make_layer(block, - layer_nums[3], - in_channel=in_channels[3], - out_channel=out_channels[3], - stride=strides[3]) - - self.mean = P.ReduceMean(keep_dims=True) - self.flatten = nn.Flatten() - self.end_point = nn.DenseBnAct(out_channels[3], num_classes, has_bn=False) - - def _make_layer(self, block, layer_num, in_channel, out_channel, stride): - """ - Make stage network of ResNet. - - Args: - block (Cell): Resnet block. - layer_num (int): Layer number. - in_channel (int): Input channel. - out_channel (int): Output channel. - stride (int): Stride size for the first convolutional layer. - - Returns: - SequentialCell, the output layer. - - Examples: - >>> _make_layer(ResidualBlock, 3, 128, 256, 2) - """ - layers = [] - - resnet_block = block(in_channel, out_channel, stride=stride) - layers.append(resnet_block) - - for _ in range(1, layer_num): - resnet_block = block(out_channel, out_channel, stride=1) - layers.append(resnet_block) - - return nn.SequentialCell(layers) - - def construct(self, x): - x = self.conv1(x) - c1 = self.maxpool(x) - - c2 = self.layer1(c1) - c3 = self.layer2(c2) - c4 = self.layer3(c3) - c5 = self.layer4(c4) - - out = self.mean(c5, (2, 3)) - out = self.flatten(out) - out = self.end_point(out) - return out - - -def resnet50_quant(class_num=10): - """ - Get ResNet50_quant neural network. - - Args: - class_num (int): Class number. - - Returns: - Cell, cell instance of ResNet50 neural network. - - Examples: - >>> net = resnet50_quant(10) - """ - return ResNet(ResidualBlock, - [3, 4, 6, 3], - [64, 256, 512, 1024], - [256, 512, 1024, 2048], - [1, 2, 2, 2], - class_num) - - -def resnet101_quant(class_num=1001): - """ - Get ResNet101_quant neural network. - - Args: - class_num (int): Class number. - - Returns: - Cell, cell instance of ResNet101 neural network. - - Examples: - >>> net = resnet101_quant(1001) - """ - return ResNet(ResidualBlock, - [3, 4, 23, 3], - [64, 256, 512, 1024], - [256, 512, 1024, 2048], - [1, 2, 2, 2], - class_num) diff --git a/official/cv/resnet50_quant/models/resnet_quant_manual.py b/official/cv/resnet50_quant/models/resnet_quant_manual.py deleted file mode 100644 index edd87e9ae77d51733d6b83ffd7760ee03dcd7b16..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/models/resnet_quant_manual.py +++ /dev/null @@ -1,325 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""ResNet.""" -import numpy as np -import mindspore.nn as nn -from mindspore.ops import operations as P -from mindspore import Tensor -from mindspore.nn import FakeQuantWithMinMaxObserver, Conv2dBnFoldQuant -from mindspore.compression.quant import create_quant_config - -_ema_decay = 0.999 -_symmetric = True -_fake = True -_per_channel = True -_quant_config = create_quant_config(per_channel=(_per_channel, False), symmetric=(_symmetric, False)) - - -def _weight_variable(shape, factor=0.01): - init_value = np.random.randn(*shape).astype(np.float32) * factor - return Tensor(init_value) - - -def _conv3x3(in_channel, out_channel, stride=1): - weight_shape = (out_channel, in_channel, 3, 3) - weight = _weight_variable(weight_shape) - return nn.Conv2d(in_channel, out_channel, - kernel_size=3, stride=stride, padding=0, pad_mode='same', weight_init=weight) - - -def _conv1x1(in_channel, out_channel, stride=1): - weight_shape = (out_channel, in_channel, 1, 1) - weight = _weight_variable(weight_shape) - return nn.Conv2d(in_channel, out_channel, - kernel_size=1, stride=stride, padding=0, pad_mode='same', weight_init=weight) - - -def _conv7x7(in_channel, out_channel, stride=1): - weight_shape = (out_channel, in_channel, 7, 7) - weight = _weight_variable(weight_shape) - return nn.Conv2d(in_channel, out_channel, - kernel_size=7, stride=stride, padding=0, pad_mode='same', weight_init=weight) - - -def _bn(channel): - return nn.BatchNorm2d(channel, eps=1e-4, momentum=0.9, - gamma_init=1, beta_init=0, moving_mean_init=0, moving_var_init=1) - - -def _bn_last(channel): - return nn.BatchNorm2d(channel, eps=1e-4, momentum=0.9, - gamma_init=0, beta_init=0, moving_mean_init=0, moving_var_init=1) - - -def _fc(in_channel, out_channel): - weight_shape = (out_channel, in_channel) - weight = _weight_variable(weight_shape) - return nn.Dense(in_channel, out_channel, has_bias=True, weight_init=weight, bias_init=0) - - -class ConvBNReLU(nn.Cell): - """ - Convolution/Depthwise fused with Batchnorm and ReLU block definition. - - Args: - in_planes (int): Input channel. - out_planes (int): Output channel. - kernel_size (int): Input kernel size. - stride (int): Stride size for the first convolutional layer. Default: 1. - groups (int): channel group. Convolution is 1 while Depthiwse is input channel. Default: 1. - - Returns: - Tensor, output tensor. - - Examples: - >>> ConvBNReLU(16, 256, kernel_size=1, stride=1, groups=1) - """ - - def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1): - super(ConvBNReLU, self).__init__() - padding = (kernel_size - 1) // 2 - conv = Conv2dBnFoldQuant(in_planes, out_planes, kernel_size, stride, pad_mode='pad', padding=padding, - group=groups, fake=_fake, quant_config=_quant_config) - layers = [conv, nn.ActQuant(nn.ReLU())] if _fake else [conv, nn.ReLU()] - self.features = nn.SequentialCell(layers) - - def construct(self, x): - output = self.features(x) - return output - - -class ResidualBlock(nn.Cell): - """ - ResNet V1 residual block definition. - - Args: - in_channel (int): Input channel. - out_channel (int): Output channel. - stride (int): Stride size for the first convolutional layer. Default: 1. - - Returns: - Tensor, output tensor. - - Examples: - >>> ResidualBlock(3, 256, stride=2) - """ - expansion = 4 - - def __init__(self, - in_channel, - out_channel, - stride=1): - super(ResidualBlock, self).__init__() - - channel = out_channel // self.expansion - self.conv1 = ConvBNReLU(in_channel, channel, kernel_size=1, stride=1) - self.conv2 = ConvBNReLU(channel, channel, kernel_size=3, stride=stride) - self.conv3 = nn.SequentialCell([Conv2dBnFoldQuant(channel, out_channel, fake=_fake, - quant_config=_quant_config, - kernel_size=1, stride=1, pad_mode='same', padding=0), - FakeQuantWithMinMaxObserver(ema=True, ema_decay=_ema_decay, symmetric=False) - ]) if _fake else Conv2dBnFoldQuant(channel, out_channel, fake=_fake, - quant_config=_quant_config, - kernel_size=1, stride=1, - pad_mode='same', padding=0) - - self.down_sample = False - - if stride != 1 or in_channel != out_channel: - self.down_sample = True - self.down_sample_layer = None - - if self.down_sample: - self.down_sample_layer = nn.SequentialCell([Conv2dBnFoldQuant(in_channel, out_channel, - quant_config=_quant_config, - kernel_size=1, stride=stride, - pad_mode='same', padding=0), - FakeQuantWithMinMaxObserver(ema=True, ema_decay=_ema_decay, - symmetric=False) - ]) if _fake else Conv2dBnFoldQuant(in_channel, out_channel, - fake=_fake, - quant_config=_quant_config, - kernel_size=1, - stride=stride, - pad_mode='same', - padding=0) - self.add = nn.TensorAddQuant() - self.relu = nn.ActQuant(nn.ReLU()) - - def construct(self, x): - identity = x - out = self.conv1(x) - out = self.conv2(out) - out = self.conv3(out) - - if self.down_sample: - identity = self.down_sample_layer(identity) - - out = self.add(out, identity) - out = self.relu(out) - - return out - - -class ResNet(nn.Cell): - """ - ResNet architecture. - - Args: - block (Cell): Block for network. - layer_nums (list): Numbers of block in different layers. - in_channels (list): Input channel in each layer. - out_channels (list): Output channel in each layer. - strides (list): Stride size in each layer. - num_classes (int): The number of classes that the training images are belonging to. - Returns: - Tensor, output tensor. - - Examples: - >>> ResNet(ResidualBlock, - >>> [3, 4, 6, 3], - >>> [64, 256, 512, 1024], - >>> [256, 512, 1024, 2048], - >>> [1, 2, 2, 2], - >>> 10) - """ - - def __init__(self, - block, - layer_nums, - in_channels, - out_channels, - strides, - num_classes): - super(ResNet, self).__init__() - - if not len(layer_nums) == len(in_channels) == len(out_channels) == 4: - raise ValueError("the length of layer_num, in_channels, out_channels list must be 4!") - - self.conv1 = ConvBNReLU(3, 64, kernel_size=7, stride=2) - self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode="same") - - self.layer1 = self._make_layer(block, - layer_nums[0], - in_channel=in_channels[0], - out_channel=out_channels[0], - stride=strides[0]) - self.layer2 = self._make_layer(block, - layer_nums[1], - in_channel=in_channels[1], - out_channel=out_channels[1], - stride=strides[1]) - self.layer3 = self._make_layer(block, - layer_nums[2], - in_channel=in_channels[2], - out_channel=out_channels[2], - stride=strides[2]) - self.layer4 = self._make_layer(block, - layer_nums[3], - in_channel=in_channels[3], - out_channel=out_channels[3], - stride=strides[3]) - - self.mean = P.ReduceMean(keep_dims=True) - self.reduce_fake = nn.FakeQuantWithMinMaxObserver(ema=True, ema_decay=_ema_decay) - self.flatten = nn.Flatten() - self.end_point = nn.DenseQuant(out_channels[3], num_classes, has_bias=True, quant_config=_quant_config) - self.output_fake = nn.FakeQuantWithMinMaxObserver(ema=True, ema_decay=_ema_decay) - - def _make_layer(self, block, layer_num, in_channel, out_channel, stride): - """ - Make stage network of ResNet. - - Args: - block (Cell): Resnet block. - layer_num (int): Layer number. - in_channel (int): Input channel. - out_channel (int): Output channel. - stride (int): Stride size for the first convolutional layer. - - Returns: - SequentialCell, the output layer. - - Examples: - >>> _make_layer(ResidualBlock, 3, 128, 256, 2) - """ - layers = [] - - resnet_block = block(in_channel, out_channel, stride=stride) - layers.append(resnet_block) - - for _ in range(1, layer_num): - resnet_block = block(out_channel, out_channel, stride=1) - layers.append(resnet_block) - - return nn.SequentialCell(layers) - - def construct(self, x): - x = self.conv1(x) - c1 = self.maxpool(x) - - c2 = self.layer1(c1) - c3 = self.layer2(c2) - c4 = self.layer3(c3) - c5 = self.layer4(c4) - - out = self.mean(c5, (2, 3)) - out = self.reduce_fake(out) - out = self.flatten(out) - out = self.end_point(out) - out = self.output_fake(out) - return out - - -def resnet50_quant(class_num=10): - """ - Get ResNet50 neural network. - - Args: - class_num (int): Class number. - - Returns: - Cell, cell instance of ResNet50 neural network. - - Examples: - >>> net = resnet50_quant(10) - """ - return ResNet(ResidualBlock, - [3, 4, 6, 3], - [64, 256, 512, 1024], - [256, 512, 1024, 2048], - [1, 2, 2, 2], - class_num) - - -def resnet101_quant(class_num=1001): - """ - Get ResNet101 neural network. - - Args: - class_num (int): Class number. - - Returns: - Cell, cell instance of ResNet101 neural network. - - Examples: - >>> net = resnet101(1001) - """ - return ResNet(ResidualBlock, - [3, 4, 23, 3], - [64, 256, 512, 1024], - [256, 512, 1024, 2048], - [1, 2, 2, 2], - class_num) diff --git a/official/cv/resnet50_quant/postprocess.py b/official/cv/resnet50_quant/postprocess.py deleted file mode 100644 index 9bbc3301b3cf24e226141c834773489fc94c590b..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/postprocess.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -post process for 310 inference. -""" -import os -import argparse -import numpy as np - -def parse_args(): - parser = argparse.ArgumentParser(description='resnet50_quant inference') - parser.add_argument('--result_path', type=str, default='', help='result files path') - parser.add_argument('--label_path', type=str, default='', help='label file path') - args_, _ = parser.parse_known_args() - return args_ - -if __name__ == "__main__": - args = parse_args() - path = args.result_path - label_path = args.label_path - files = os.listdir(path) - step = 0 - sum_right = 0 - label_dict = {} - with open(label_path, 'r') as f: - for line in f.readlines(): - batch_label = line.strip().split(',') - label_dict[batch_label[0]] = batch_label[1:] - for file in files: - full_file_path = os.path.join(path, file) - if os.path.isfile(full_file_path): - label_file = file.split('_0.bin')[0] + '.bin' - label_array = np.array(label_dict[label_file]) - line = np.fromfile(full_file_path, dtype=np.float32) - batch_size = label_array.shape[0] - line_comp = line.reshape(batch_size, int(line.shape[0] / batch_size)) - for i in range(0, batch_size): - pred = np.argmax(line_comp[i], axis=0) - step += 1 - if pred == label_array[i].astype(np.int64): - sum_right += 1 - print("=====step:{}=====".format(step)) - print("=====sum_right:{}=====".format(sum_right)) - accuracy = sum_right * 100.0 / step - print("=====accuracy:{}=====".format(accuracy)) diff --git a/official/cv/resnet50_quant/requirements.txt b/official/cv/resnet50_quant/requirements.txt deleted file mode 100644 index 34fbd13367133f98ccadd17dfcd80df72e3cd0ba..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -easydict -numpy diff --git a/official/cv/resnet50_quant/scripts/run_infer.sh b/official/cv/resnet50_quant/scripts/run_infer.sh deleted file mode 100644 index 7136d5ab43efb360095d4c5959ef07af441b9608..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/scripts/run_infer.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -if [ $# != 3 ] -then - echo "Ascend: sh run_infer.sh [PLATFORM] [DATASET_PATH] [CHECKPOINT_PATH]" -exit 1 -fi - -# check dataset path -if [ ! -d $2 ] && [ ! -f $2 ] -then - echo "error: DATASET_PATH=$2 is not a directory or file" -exit 1 -fi - -# check checkpoint file -if [ ! -f $3 ] -then - echo "error: CHECKPOINT_PATH=$3 is not a file" -exit 1 -fi - -# set environment -BASEPATH=$(cd "`dirname $0`" || exit; pwd) -export PYTHONPATH=${BASEPATH}:$PYTHONPATH -export DEVICE_ID=0 -export RANK_ID=0 -export RANK_SIZE=1 -if [ -d "../eval" ]; -then - rm -rf ../eval -fi -mkdir ../eval -cd ../eval || exit - -# launch -python ${BASEPATH}/../eval.py \ - --device_target=$1 \ - --dataset_path=$2 \ - --checkpoint_path=$3 \ - &> infer.log & # dataset val folder path diff --git a/official/cv/resnet50_quant/scripts/run_infer_310.sh b/official/cv/resnet50_quant/scripts/run_infer_310.sh deleted file mode 100644 index 0409d00e805e1f9ec113648a2af0378092909b58..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/scripts/run_infer_310.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [[ $# -lt 3 || $# -gt 4 ]]; then - echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [LABEL_PATH] [DEVICE_ID] - DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} -model=$(get_real_path $1) -data_path=$(get_real_path $2) -label_path=$(get_real_path $3) - -device_id=0 -if [ $# == 4 ]; then - device_id=$4 -fi - -echo "air name: "$model -echo "dataset path: "$data_path -echo "label path: "$label_path -echo "device id: "$device_id - -export ASCEND_HOME=/usr/local/Ascend/ -if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then - export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH - export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp -else - export PATH=$ASCEND_HOME/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/fwkacllib/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=$PYTHONPATH:$TBE_IMPL_PATH - export ASCEND_OPP_PATH=$ASCEND_HOME/opp -fi - -function air_to_om() -{ - atc --input_format=NCHW --framework=1 --model=$model --output=resnet50_quant --soc_version=Ascend310 &> atc.log -} - -function compile_app() -{ - cd ../ascend310_infer/src || exit - bash build.sh &> build.log -} - -function infer() -{ - cd - || exit - if [ -d result_Files ]; then - rm -rf ./result_Files - fi - if [ -d time_Result ]; then - rm -rf ./time_Result - fi - mkdir result_Files - mkdir time_Result - ../ascend310_infer/src/out/main --om_path=./resnet50_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log -} - -function cal_acc() -{ - python ../postprocess.py --result_path=./result_Files --label_path=$label_path &> acc.log -} - -air_to_om -if [ $? -ne 0 ]; then - echo " air to om failed" - exit 1 -fi -compile_app -if [ $? -ne 0 ]; then - echo "compile app code failed" - exit 1 -fi -infer -if [ $? -ne 0 ]; then - echo " execute inference failed" - exit 1 -fi -cal_acc -if [ $? -ne 0 ]; then - echo "calculate accuracy failed" - exit 1 -fi diff --git a/official/cv/resnet50_quant/scripts/run_train.sh b/official/cv/resnet50_quant/scripts/run_train.sh deleted file mode 100644 index 83ed280a13fdb68af850ecd92170e8eb7e9d066d..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/scripts/run_train.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} - -run_ascend(){ - - if [ $# != 3 ] && [ $# != 4 ] - then - echo "Usage: bash run_train.sh [Ascend] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH](optional)\n" - exit 1 - fi - - PATH1=$(get_real_path $2) - PATH2=$(get_real_path $3) - - if [ $# == 4 ] - then - PATH3=$(get_real_path $4) - fi - - if [ ! -f $PATH1 ] - then - echo "error: RANK_TABLE_FILE=$PATH1 is not a file" - exit 1 - fi - - if [ ! -d $PATH2 ] - then - echo "error: DATASET_PATH=$PATH2 is not a directory" - exit 1 - fi - - if [ $# == 4 ] && [ ! -f $PATH3 ] - then - echo "error: PRETRAINED_CKPT_PATH=$PATH3 is not a file" - exit 1 - fi - - cat $2 | grep device_id >temp.log - array=$(cat temp.log | awk -F "[:]" '{print$2}') - IFS=" " read -ra device_list <<<$array - first_device=${device_list[0]:1:1} - device_num=$(cat temp.log | wc -l) - rm temp.log - - ulimit -u unlimited - export DEVICE_NUM=${device_num} - export RANK_SIZE=${device_num} - export RANK_TABLE_FILE=$PATH1 - - export SERVER_ID=0 - rank_start=$((DEVICE_NUM * SERVER_ID)) - - rm -rf ./train - mkdir ./train - for((i=0; i<${device_num}; i++)) - do - export DEVICE_ID=$((first_device+i)) - export RANK_ID=$((rank_start + i)) - mkdir ./train/device$i - cp ../*.py ./train/device$i - cp *.sh ./train/device$i - cp -r ../src ./train/device$i - cp -r ../models ./train/device$i - cd ./train/device$i || exit - echo "start training for rank $RANK_ID, device $DEVICE_ID" - env > env.log - if [ $# == 3 ] - then - python train.py --device_target=$1 --run_distribute=True --device_num=$DEVICE_NUM --dataset_path=$PATH2 &> train.log & - fi - - if [ $# == 4 ] - then - python train.py --device_target=$1 --run_distribute=True --device_num=$DEVICE_NUM --dataset_path=$PATH2 --pre_trained=$PATH3 &> train.log & - fi - - cd ../.. || exit - done -} - - -if [ $1 = "Ascend" ] ; then - run_ascend "$@" -else - echo "Unsupported device target: $1" -fi; diff --git a/official/cv/resnet50_quant/src/config.py b/official/cv/resnet50_quant/src/config.py deleted file mode 100644 index 3ccecf995a2e33e6ce9439abd7275ebb5cc0e34c..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/src/config.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -network config setting, will be used in train.py and eval.py -""" -from easydict import EasyDict as ed -config_quant = ed({ - "class_num": 1001, - "batch_size": 32, - "loss_scale": 1024, - "momentum": 0.9, - "weight_decay": 1e-4, - "epoch_size": 120, - "pretrained_epoch_size": 90, - "data_load_mode": "original", - "save_checkpoint": True, - "save_checkpoint_epochs": 1, - "keep_checkpoint_max": 50, - "save_checkpoint_path": "./", - "warmup_epochs": 0, - "lr_decay_mode": "cosine", - "use_label_smooth": True, - "label_smooth_factor": 0.1, - "lr_init": 0, - "lr_max": 0.005, -}) diff --git a/official/cv/resnet50_quant/src/crossentropy.py b/official/cv/resnet50_quant/src/crossentropy.py deleted file mode 100644 index 2732c81fbc13f7a5e3adddb93c70df352ff0408c..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/src/crossentropy.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""define loss function for network""" -from mindspore.nn.loss.loss import LossBase -from mindspore.ops import operations as P -from mindspore.ops import functional as F -from mindspore import Tensor -from mindspore.common import dtype as mstype -import mindspore.nn as nn - - -class CrossEntropy(LossBase): - """the redefined loss function with SoftmaxCrossEntropyWithLogits""" - - def __init__(self, smooth_factor=0, num_classes=1001): - 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 diff --git a/official/cv/resnet50_quant/src/dataset.py b/official/cv/resnet50_quant/src/dataset.py deleted file mode 100644 index 48d19fa3379e6dbf099f5c8556ca16b2207c8080..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/src/dataset.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -""" -create train or eval dataset. -""" -import os -from functools import partial -import mindspore.common.dtype as mstype -import mindspore.dataset as ds -import mindspore.dataset.transforms.c_transforms as C2 -import mindspore.dataset.vision.c_transforms as C -import mindspore.dataset.transforms.py_transforms as P2 -import mindspore.dataset.vision.py_transforms as P -from mindspore.communication.management import init, get_rank, get_group_size -from src.config import config_quant - -config = config_quant - - -def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, target="Ascend"): - """ - create a train or eval dataset - - Args: - dataset_path(string): the path of dataset. - do_train(bool): whether dataset is used for train or eval. - repeat_num(int): the repeat times of dataset. Default: 1 - batch_size(int): the batch size of dataset. Default: 32 - target(str): the device target. Default: Ascend - - Returns: - dataset - """ - if target == "Ascend": - device_num = int(os.getenv("RANK_SIZE")) - rank_id = int(os.getenv("RANK_ID")) - else: - init() - rank_id = get_rank() - device_num = get_group_size() - - columns_list = ['image', 'label'] - if config.data_load_mode == "mindrecord": - load_func = partial(ds.MindDataset, dataset_path, columns_list) - else: - load_func = partial(ds.ImageFolderDataset, dataset_path) - if device_num == 1: - data_set = load_func(num_parallel_workers=8, shuffle=True) - else: - data_set = load_func(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) - - data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=8) - data_set = data_set.map(operations=type_cast_op, input_columns="label", num_parallel_workers=8) - - # apply batch operations - data_set = data_set.batch(batch_size, drop_remainder=True) - - # apply dataset repeat operation - data_set = data_set.repeat(repeat_num) - - return data_set - - -def create_dataset_py(dataset_path, do_train, repeat_num=1, batch_size=32, target="Ascend"): - """ - create a train or eval dataset - - Args: - dataset_path(string): the path of dataset. - do_train(bool): whether dataset is used for train or eval. - repeat_num(int): the repeat times of dataset. Default: 1 - batch_size(int): the batch size of dataset. Default: 32 - target(str): the device target. Default: Ascend - - Returns: - dataset - """ - if target == "Ascend": - device_num = int(os.getenv("RANK_SIZE")) - rank_id = int(os.getenv("RANK_ID")) - else: - init() - rank_id = get_rank() - device_num = get_group_size() - - if do_train: - if device_num == 1: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True) - else: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=True, - num_shards=device_num, shard_id=rank_id) - else: - data_set = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8, shuffle=False) - - image_size = 224 - - # define map operations - decode_op = P.Decode() - resize_crop_op = P.RandomResizedCrop(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)) - horizontal_flip_op = P.RandomHorizontalFlip(prob=0.5) - - resize_op = P.Resize(256) - center_crop = P.CenterCrop(image_size) - to_tensor = P.ToTensor() - normalize_op = P.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) - - # define map operations - if do_train: - trans = [decode_op, resize_crop_op, horizontal_flip_op, to_tensor, normalize_op] - else: - trans = [decode_op, resize_op, center_crop, to_tensor, normalize_op] - - compose = P2.Compose(trans) - data_set = data_set.map(operations=compose, input_columns="image", num_parallel_workers=8, - python_multiprocessing=True) - - # apply batch operations - data_set = data_set.batch(batch_size, drop_remainder=True) - - # apply dataset repeat operation - data_set = data_set.repeat(repeat_num) - - return data_set diff --git a/official/cv/resnet50_quant/src/launch.py b/official/cv/resnet50_quant/src/launch.py deleted file mode 100644 index 9e7ecb26c4aa32f07897a11061b6084f3ef55621..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/src/launch.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""launch train script""" -import os -import sys -import json -import subprocess -import shutil -import platform -from argparse import ArgumentParser - -def parse_args(): - """ - parse args . - - Args: - - Returns: - args. - - Examples: - >>> parse_args() - """ - parser = ArgumentParser(description="mindspore distributed training launch " - "helper utility that will spawn up " - "multiple distributed processes") - parser.add_argument("--nproc_per_node", type=int, default=1, - help="The number of processes to launch on each node, " - "for D training, this is recommended to be set " - "to the number of D in your system so that " - "each process can be bound to a single D.") - parser.add_argument("--visible_devices", type=str, default="0,1,2,3,4,5,6,7", - help="will use the visible devices sequentially") - parser.add_argument("--server_id", type=str, default="", - help="server ip") - parser.add_argument("--training_script", type=str, - help="The full path to the single D training " - "program/script to be launched in parallel, " - "followed by all the arguments for the " - "training script") - # rest from the training program - args, unknown = parser.parse_known_args() - args.training_script_args = unknown - return args - - -def main(): - print("start", __file__) - args = parse_args() - print(args) - visible_devices = args.visible_devices.split(',') - assert os.path.isfile(args.training_script) - assert len(visible_devices) >= args.nproc_per_node - print('visible_devices:{}'.format(visible_devices)) - if not args.server_id: - print('pleaser input server ip!!!') - exit(0) - print('server_id:{}'.format(args.server_id)) - - # construct hccn_table - hccn_configs = open('/etc/hccn.conf', 'r').readlines() - device_ips = {} - for hccn_item in hccn_configs: - hccn_item = hccn_item.strip() - if hccn_item.startswith('address_'): - device_id, device_ip = hccn_item.split('=') - device_id = device_id.split('_')[1] - device_ips[device_id] = device_ip - print('device_id:{}, device_ip:{}'.format(device_id, device_ip)) - hccn_table = {} - arch = platform.processor() - hccn_table['board_id'] = {'aarch64': '0x002f', 'x86_64': '0x0000'}[arch] - hccn_table['chip_info'] = '910' - hccn_table['deploy_mode'] = 'lab' - hccn_table['group_count'] = '1' - hccn_table['group_list'] = [] - instance_list = [] - usable_dev = '' - for instance_id in range(args.nproc_per_node): - instance = {} - instance['devices'] = [] - device_id = visible_devices[instance_id] - device_ip = device_ips[device_id] - usable_dev += str(device_id) - instance['devices'].append({ - 'device_id': device_id, - 'device_ip': device_ip, - }) - instance['rank_id'] = str(instance_id) - instance['server_id'] = args.server_id - instance_list.append(instance) - hccn_table['group_list'].append({ - 'device_num': str(args.nproc_per_node), - 'server_num': '1', - 'group_name': '', - 'instance_count': str(args.nproc_per_node), - 'instance_list': instance_list, - }) - hccn_table['para_plane_nic_location'] = 'device' - hccn_table['para_plane_nic_name'] = [] - for instance_id in range(args.nproc_per_node): - eth_id = visible_devices[instance_id] - hccn_table['para_plane_nic_name'].append('eth{}'.format(eth_id)) - hccn_table['para_plane_nic_num'] = str(args.nproc_per_node) - hccn_table['status'] = 'completed' - - # save hccn_table to file - table_path = os.getcwd() - if not os.path.exists(table_path): - os.mkdir(table_path) - table_fn = os.path.join(table_path, - 'rank_table_{}p_{}_{}.json'.format(args.nproc_per_node, usable_dev, args.server_id)) - with open(table_fn, 'w') as table_fp: - json.dump(hccn_table, table_fp, indent=4) - sys.stdout.flush() - - # spawn the processes - processes = [] - cmds = [] - log_files = [] - env = os.environ.copy() - env['RANK_SIZE'] = str(args.nproc_per_node) - cur_path = os.getcwd() - for rank_id in range(0, args.nproc_per_node): - os.chdir(cur_path) - device_id = visible_devices[rank_id] - device_dir = os.path.join(cur_path, 'device{}'.format(rank_id)) - env['RANK_ID'] = str(rank_id) - env['DEVICE_ID'] = str(device_id) - if args.nproc_per_node > 1: - env['RANK_TABLE_FILE'] = table_fn - env['RANK_TABLE_FILE'] = table_fn - if os.path.exists(device_dir): - shutil.rmtree(device_dir) - os.mkdir(device_dir) - os.chdir(device_dir) - cmd = [sys.executable, '-u'] - cmd.append(args.training_script) - cmd.extend(args.training_script_args) - log_file = open('{dir}/log{id}.log'.format(dir=device_dir, id=rank_id), 'w') - process = subprocess.Popen(cmd, stdout=log_file, stderr=log_file, env=env) - processes.append(process) - cmds.append(cmd) - log_files.append(log_file) - for process, cmd, log_file in zip(processes, cmds, log_files): - process.wait() - if process.returncode != 0: - raise subprocess.CalledProcessError(returncode=process, cmd=cmd) - log_file.close() - - -if __name__ == "__main__": - main() diff --git a/official/cv/resnet50_quant/src/lr_generator.py b/official/cv/resnet50_quant/src/lr_generator.py deleted file mode 100644 index 1e89467c3d6b304d45e17ac208971a6b3576c46a..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/src/lr_generator.py +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""learning rate generator""" -import math -import numpy as np - - -def _generate_steps_lr(lr_init, lr_max, total_steps, warmup_steps): - """ - Applies three steps decay to generate learning rate array. - - Args: - lr_init(float): init learning rate. - lr_max(float): max learning rate. - total_steps(int): all steps in training. - warmup_steps(int): all steps in warmup epochs. - - Returns: - np.array, learning rate array. - """ - decay_epoch_index = [0.3 * total_steps, 0.6 * total_steps, 0.8 * total_steps] - lr_each_step = [] - for i in range(total_steps): - if i < warmup_steps: - lr = lr_init + (lr_max - lr_init) * i / warmup_steps - else: - if i < decay_epoch_index[0]: - lr = lr_max - elif i < decay_epoch_index[1]: - lr = lr_max * 0.1 - elif i < decay_epoch_index[2]: - lr = lr_max * 0.01 - else: - lr = lr_max * 0.001 - lr_each_step.append(lr) - return lr_each_step - - -def _generate_poly_lr(lr_init, lr_end, lr_max, total_steps, warmup_steps): - """ - Applies polynomial decay to generate learning rate array. - - Args: - lr_init(float): init learning rate. - lr_end(float): end learning rate - lr_max(float): max learning rate. - total_steps(int): all steps in training. - warmup_steps(int): all steps in warmup epochs. - - Returns: - np.array, learning rate array. - """ - lr_each_step = [] - if warmup_steps != 0: - inc_each_step = (float(lr_max) - float(lr_init)) / float(warmup_steps) - else: - inc_each_step = 0 - for i in range(total_steps): - if i < warmup_steps: - lr = float(lr_init) + inc_each_step * float(i) - else: - base = (1.0 - (float(i) - float(warmup_steps)) / (float(total_steps) - float(warmup_steps))) - lr = float(lr_max) * base * base - if lr < 0.0: - lr = 0.0 - lr_each_step.append(lr) - return lr_each_step - - -def _generate_cosine_lr(lr_init, lr_end, lr_max, total_steps, warmup_steps): - """ - Applies cosine decay to generate learning rate array. - - Args: - lr_init(float): init learning rate. - lr_end(float): end learning rate - lr_max(float): max learning rate. - total_steps(int): all steps in training. - warmup_steps(int): all steps in warmup epochs. - - Returns: - np.array, learning rate array. - """ - decay_steps = total_steps - warmup_steps - lr_each_step = [] - for i in range(total_steps): - if i < warmup_steps: - lr_inc = (float(lr_max) - float(lr_init)) / float(warmup_steps) - lr = float(lr_init) + lr_inc * (i + 1) - else: - cosine_decay = 0.5 * (1 + math.cos(math.pi * (i-warmup_steps) / decay_steps)) - lr = (lr_max-lr_end)*cosine_decay + lr_end - lr_each_step.append(lr) - return lr_each_step - - -def _generate_liner_lr(lr_init, lr_end, lr_max, total_steps, warmup_steps): - """ - Applies liner decay to generate learning rate array. - - Args: - lr_init(float): init learning rate. - lr_end(float): end learning rate - lr_max(float): max learning rate. - total_steps(int): all steps in training. - warmup_steps(int): all steps in warmup epochs. - - Returns: - np.array, learning rate array. - """ - lr_each_step = [] - for i in range(total_steps): - if i < warmup_steps: - lr = lr_init + (lr_max - lr_init) * i / warmup_steps - else: - lr = lr_max - (lr_max - lr_end) * (i - warmup_steps) / (total_steps - warmup_steps) - lr_each_step.append(lr) - return lr_each_step - - - -def get_lr(lr_init, lr_end, lr_max, warmup_epochs, total_epochs, steps_per_epoch, lr_decay_mode): - """ - generate learning rate array - - Args: - lr_init(float): init learning rate - lr_end(float): end learning rate - lr_max(float): max learning rate - warmup_epochs(int): number of warmup epochs - total_epochs(int): total epoch of training - steps_per_epoch(int): steps of one epoch - lr_decay_mode(string): learning rate decay mode, including steps, poly, cosine or liner(default) - - Returns: - np.array, learning rate array - """ - lr_each_step = [] - total_steps = steps_per_epoch * total_epochs - warmup_steps = steps_per_epoch * warmup_epochs - - if lr_decay_mode == 'steps': - lr_each_step = _generate_steps_lr(lr_init, lr_max, total_steps, warmup_steps) - elif lr_decay_mode == 'poly': - lr_each_step = _generate_poly_lr(lr_init, lr_end, lr_max, total_steps, warmup_steps) - elif lr_decay_mode == 'cosine': - lr_each_step = _generate_cosine_lr(lr_init, lr_end, lr_max, total_steps, warmup_steps) - else: - lr_each_step = _generate_liner_lr(lr_init, lr_end, lr_max, total_steps, warmup_steps) - - lr_each_step = np.array(lr_each_step).astype(np.float32) - return lr_each_step diff --git a/official/cv/resnet50_quant/train.py b/official/cv/resnet50_quant/train.py deleted file mode 100644 index 7eff117735697ba5cefb8741204af6c931d1a0bb..0000000000000000000000000000000000000000 --- a/official/cv/resnet50_quant/train.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Train Resnet50 on ImageNet""" - -import os -import argparse - -from mindspore import context -from mindspore import Tensor -from mindspore.nn.optim.momentum import Momentum -from mindspore.train.model import Model -from mindspore.context import ParallelMode -from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor -from mindspore.train.loss_scale_manager import FixedLossScaleManager -from mindspore.train.serialization import load_checkpoint -from mindspore.compression.quant.quant_utils import load_nonquant_param_into_quant_net -from mindspore.communication.management import init -import mindspore.nn as nn -import mindspore.common.initializer as weight_init -from mindspore.common import set_seed - -from models.resnet_quant_manual import resnet50_quant #manually construct quantative network of resnet50 -from src.dataset import create_dataset -from src.lr_generator import get_lr -from src.config import config_quant -from src.crossentropy import CrossEntropy - -set_seed(1) - -parser = argparse.ArgumentParser(description='Image classification') -parser.add_argument('--run_distribute', type=bool, default=False, help='Run distribute') -parser.add_argument('--device_num', type=int, default=1, help='Device num.') -parser.add_argument('--dataset_path', type=str, default=None, help='Dataset path') -parser.add_argument('--device_target', type=str, default='Ascend', help='Device target') -parser.add_argument('--pre_trained', type=str, default=None, help='Pertained checkpoint path') -args_opt = parser.parse_args() -config = config_quant - -if args_opt.device_target == "Ascend": - device_id = int(os.getenv('DEVICE_ID')) - rank_id = int(os.getenv('RANK_ID')) - rank_size = int(os.getenv('RANK_SIZE')) - run_distribute = rank_size > 1 - context.set_context(mode=context.GRAPH_MODE, - device_target="Ascend", - save_graphs=False, - device_id=device_id) -else: - raise ValueError("Unsupported device target.") - -if __name__ == '__main__': - # train on ascend - print("training args: {}".format(args_opt)) - print("training configure: {}".format(config)) - print("parallel args: rank_id {}, device_id {}, rank_size {}".format(rank_id, device_id, rank_size)) - epoch_size = config.epoch_size - - # distribute init - if run_distribute: - context.set_auto_parallel_context(device_num=rank_size, - parallel_mode=ParallelMode.DATA_PARALLEL, - gradients_mean=True) - init() - context.set_auto_parallel_context(device_num=args_opt.device_num, - parallel_mode=ParallelMode.DATA_PARALLEL, - gradients_mean=True, all_reduce_fusion_config=[107, 160]) - - # define manual quantization network - net = resnet50_quant(class_num=config.class_num) - net.set_train(True) - - # weight init and load checkpoint file - if args_opt.pre_trained: - param_dict = load_checkpoint(args_opt.pre_trained) - load_nonquant_param_into_quant_net(net, param_dict, ['step']) - epoch_size = config.epoch_size - config.pretrained_epoch_size - else: - for _, cell in net.cells_and_names(): - if isinstance(cell, nn.Conv2d): - cell.weight.set_data(weight_init.initializer(weight_init.XavierUniform(), - cell.weight.shape, - cell.weight.dtype)) - if isinstance(cell, nn.Dense): - cell.weight.set_data(weight_init.initializer(weight_init.TruncatedNormal(), - cell.weight.shape, - cell.weight.dtype)) - 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) - loss_scale = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False) - - # define dataset - dataset = create_dataset(dataset_path=args_opt.dataset_path, - do_train=True, - repeat_num=1, - batch_size=config.batch_size, - target=args_opt.device_target) - step_size = dataset.get_dataset_size() - - # get learning rate - lr = get_lr(lr_init=config.lr_init, - lr_end=0.0, - lr_max=config.lr_max, - warmup_epochs=config.warmup_epochs, - total_epochs=config.epoch_size, - steps_per_epoch=step_size, - lr_decay_mode='cosine') - if args_opt.pre_trained: - lr = lr[config.pretrained_epoch_size * step_size:] - lr = Tensor(lr) - - # define optimization - opt = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), lr, config.momentum, - config.weight_decay, config.loss_scale) - - # define model - model = Model(net, loss_fn=loss, optimizer=opt, loss_scale_manager=loss_scale, metrics={'acc'}) - - print("============== Starting Training ==============") - time_callback = TimeMonitor(data_size=step_size) - loss_callback = LossMonitor() - callbacks = [time_callback, loss_callback] - if rank_id == 0: - if config.save_checkpoint: - config_ckpt = CheckpointConfig(save_checkpoint_steps=config.save_checkpoint_epochs * step_size, - keep_checkpoint_max=config.keep_checkpoint_max) - ckpt_callback = ModelCheckpoint(prefix="ResNet50", - directory=config.save_checkpoint_path, - config=config_ckpt) - callbacks += [ckpt_callback] - model.train(epoch_size, dataset, callbacks=callbacks) - print("============== End Training ==============") diff --git a/official/cv/yolov3_darknet53_quant/README.md b/official/cv/yolov3_darknet53_quant/README.md deleted file mode 100644 index 7b9fe87b09d908cc40036548ea7b082f63e5d051..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/README.md +++ /dev/null @@ -1,350 +0,0 @@ -# Contents - -- [YOLOv3-DarkNet53-Quant Description](#yolov3-darknet53-quant-description) -- [Model Architecture](#model-architecture) -- [Dataset](#dataset) -- [Environment Requirements](#environment-requirements) -- [Quick Start](#quick-start) -- [Script Description](#script-description) - - [Script and Sample Code](#script-and-sample-code) - - [Script Parameters](#script-parameters) - - [Training Process](#training-process) - - [Training](#training) - - [Distributed Training](#distributed-training) - - [Evaluation Process](#evaluation-process) - - [Evaluation](#evaluation) -- [Model Description](#model-description) - - [Performance](#performance) - - [Evaluation Performance](#evaluation-performance) - - [Inference Performance](#evaluation-performance) -- [Description of Random Situation](#description-of-random-situation) -- [ModelZoo Homepage](#modelzoo-homepage) - -## [YOLOv3-DarkNet53-Quant Description](#contents) - -You only look once (YOLO) is a state-of-the-art, real-time object detection system. YOLOv3 is extremely fast and accurate. - -Prior detection systems repurpose classifiers or localizers to perform detection. They apply the model to an image at multiple locations and scales. High scoring regions of the image are considered detections. - YOLOv3 use a totally different approach. It apply a single neural network to the full image. This network divides the image into regions and predicts bounding boxes and probabilities for each region. These bounding boxes are weighted by the predicted probabilities. - -YOLOv3 uses a few tricks to improve training and increase performance, including: multi-scale predictions, a better backbone classifier, and more. The full details are in the paper! - -In order to reduce the size of the weight and improve the low-bit computing performance, int8 quantization is used. - -[Paper](https://pjreddie.com/media/files/papers/YOLOv3.pdf): YOLOv3: An Incremental Improvement. Joseph Redmon, Ali Farhadi, -University of Washington - -## [Model Architecture](#contents) - -YOLOv3 use DarkNet53 for performing feature extraction, which is a hybrid approach between the network used in YOLOv2, Darknet-19, and that newfangled residual network stuff. DarkNet53 uses successive 3 脳 3 and 1 脳 1 convolutional layers and has some shortcut connections as well and is significantly larger. It has 53 convolutional layers. - -## [Dataset](#contents) - -Note that you can run the scripts based on the dataset mentioned in original paper or widely used in relevant domain/network architecture. In the following sections, we will introduce how to run the scripts using the related dataset below. - -Dataset used: [COCO2014](https://cocodataset.org/#download) - -- Dataset size: 19G, 123,287 images, 80 object categories. - - Train锛�13G, 82,783 images - - Val锛�6GM, 40,504 images - - Annotations: 241M, Train/Val annotations -- Data format锛歾ip files - - Note锛欴ata will be processed in yolo_dataset.py, and unzip files before uses it. - -## [Environment Requirements](#contents) - -- Hardware锛圓scend锛� - - Prepare hardware environment with Ascend processor. -- Framework - - [MindSpore](https://www.mindspore.cn/install/en) -- For more information, please check the resources below锛� - - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/en/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/en/master/index.html) - -## [Quick Start](#contents) - -After installing MindSpore via the official website, you can start training and evaluation in Ascend as follows: - -```bash -# The yolov3_darknet53_noquant.ckpt in the follow script is got from yolov3-darknet53 training like paper. -# The parameter of resume_yolov3 is necessary. -# The parameter of training_shape define image shape for network, default is "". -# It means use 10 kinds of shape as input shape, or it can be set some kind of shape. -# run training example(1p) by python command. -python train.py \ - --data_dir=./dataset/coco2014 \ - --resume_yolov3=yolov3_darknet53_noquant.ckpt \ - --is_distributed=0 \ - --per_batch_size=16 \ - --lr=0.012 \ - --T_max=135 \ - --max_epoch=135 \ - --warmup_epochs=5 \ - --lr_scheduler=cosine_annealing > log.txt 2>&1 & - -# standalone training example(1p) by shell script -bash run_standalone_train.sh dataset/coco2014 yolov3_darknet53_noquant.ckpt - -# distributed training example(8p) by shell script -bash run_distribute_train.sh dataset/coco2014 yolov3_darknet53_noquant.ckpt rank_table_8p.json - -# run evaluation by python command -python eval.py \ - --data_dir=./dataset/coco2014 \ - --pretrained=yolov3_quant.ckpt \ - --testing_shape=416 > log.txt 2>&1 & - -# run evaluation by shell script -bash run_eval.sh dataset/coco2014/ checkpoint/yolov3_quant.ckpt 0 -``` - -## [Script Description](#contents) - -### [Script and Sample Code](#contents) - -```bash -. -鈹斺攢yolov3_darknet53_quant - 鈹溾攢README.md - 鈹溾攢ascend310_infer # application for 310 inference - 鈹溾攢mindspore_hub_conf.md # config for mindspore hub - 鈹溾攢scripts - 鈹溾攢run_standalone_train.sh # launch standalone training(1p) in ascend - 鈹溾攢run_distribute_train.sh # launch distributed training(8p) in ascend - 鈹斺攢run_eval.sh # launch evaluating in ascend - 鈹斺攢run_infer_310.sh # shell script for 310 inference - 鈹溾攢src - 鈹溾攢__init__.py # python init file - 鈹溾攢config.py # parameter configuration - 鈹溾攢darknet.py # backbone of network - 鈹溾攢distributed_sampler.py # iterator of dataset - 鈹溾攢initializer.py # initializer of parameters - 鈹溾攢logger.py # log function - 鈹溾攢loss.py # loss function - 鈹溾攢lr_scheduler.py # generate learning rate - 鈹溾攢transforms.py # Preprocess data - 鈹溾攢util.py # util function - 鈹溾攢yolo.py # yolov3 network - 鈹溾攢yolo_dataset.py # create dataset for YOLOV3 - 鈹溾攢eval.py # eval net - 鈹斺攢train.py # train net - 鈹斺攢export_bin_file.py # export bin file of coco2014 for 310 inference - 鈹斺攢postprocess.py # post process for 310 inference -``` - -### [Script Parameters](#contents) - -```bash -Major parameters in train.py as follow. - -optional arguments: - -h, --help show this help message and exit - --data_dir DATA_DIR Train dataset directory. Default: "". - --per_batch_size PER_BATCH_SIZE - Batch size for per device. Default: 16. - --resume_yolov3 RESUME_YOLOV3 - The ckpt file of YOLOv3, which used to fine tune. - Default: "" - --lr_scheduler LR_SCHEDULER - Learning rate scheduler, options: exponential, - cosine_annealing. Default: exponential - --lr LR Learning rate. Default: 0.012 - --lr_epochs LR_EPOCHS - Epoch of changing of lr changing, split with ",". - Default: 92, 105 - --lr_gamma LR_GAMMA Decrease lr by a factor of exponential lr_scheduler. - Default: 0.1 - --eta_min ETA_MIN Eta_min in cosine_annealing scheduler. Default: 0 - --T_max T_MAX T-max in cosine_annealing scheduler. Default: 135 - --max_epoch MAX_EPOCH - Max epoch num to train the model. Default: 135 - --warmup_epochs WARMUP_EPOCHS - Warmup epochs. Default: 0 - --weight_decay WEIGHT_DECAY - Weight decay factor. Default: 0.0005 - --momentum MOMENTUM Momentum. Default: 0.9 - --loss_scale LOSS_SCALE - Static loss scale. Default: 1024 - --label_smooth LABEL_SMOOTH - Whether to use label smooth in CE. Default:0 - --label_smooth_factor LABEL_SMOOTH_FACTOR - Smooth strength of original one-hot. Default: 0.1 - --log_interval LOG_INTERVAL - Logging interval steps. Default: 100 - --ckpt_path CKPT_PATH - Checkpoint save location. Default: "outputs/" - --ckpt_interval CKPT_INTERVAL - Save checkpoint interval. Default: None - --is_save_on_master IS_SAVE_ON_MASTER - Save ckpt on master or all rank, 1 for master, 0 for - all ranks. Default: 1 - --is_distributed IS_DISTRIBUTED - Distribute train or not, 1 for yes, 0 for no. Default: 0 - --rank RANK Local rank of distributed. Default: 0 - --group_size GROUP_SIZE - World size of device. Default: 1 - --need_profiler NEED_PROFILER - Whether use profiler. 1 for yes. 0 for no. Default: 0 - --training_shape TRAINING_SHAPE - Fix training shape. Default: "" - --resize_rate RESIZE_RATE - Resize rate for multi-scale training. Default: None -``` - -### [Training Process](#contents) - -#### Training on Ascend - -##### Distributed Training - -```bash -bash run_distribute_train.sh dataset/coco2014 yolov3_darknet53_noquant.ckpt rank_table_8p.json -``` - -The above shell script will run distribute training in the background. You can view the results through the file `train_parallel0/log.txt`. The loss value will be achieved as follows: - -```bash -# distribute training result(8p) -epoch[0], iter[0], loss:483.341675, 0.31 imgs/sec, lr:0.0 -epoch[0], iter[100], loss:55.690952, 3.46 imgs/sec, lr:0.0 -epoch[0], iter[200], loss:54.045728, 126.54 imgs/sec, lr:0.0 -epoch[0], iter[300], loss:48.771608, 133.04 imgs/sec, lr:0.0 -epoch[0], iter[400], loss:48.486769, 139.69 imgs/sec, lr:0.0 -epoch[0], iter[500], loss:48.649275, 143.29 imgs/sec, lr:0.0 -epoch[0], iter[600], loss:44.731309, 144.03 imgs/sec, lr:0.0 -epoch[1], iter[700], loss:43.037023, 136.08 imgs/sec, lr:0.0 -epoch[1], iter[800], loss:41.514788, 132.94 imgs/sec, lr:0.0 - -鈥� -epoch[133], iter[85700], loss:33.326716, 136.14 imgs/sec, lr:6.497331924038008e-06 -epoch[133], iter[85800], loss:34.968744, 136.76 imgs/sec, lr:6.497331924038008e-06 -epoch[134], iter[85900], loss:35.868543, 137.08 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86000], loss:35.740817, 139.49 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86100], loss:34.600463, 141.47 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86200], loss:36.641916, 137.91 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86300], loss:32.819769, 138.17 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86400], loss:35.603033, 142.23 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86500], loss:34.303755, 145.18 imgs/sec, lr:1.6245529650404933e-06 -``` - -### [Evaluation Process](#contents) - -#### Evaluation on Ascend - -Before running the command below. - -```bash -python eval.py \ - --data_dir=./dataset/coco2014 \ - --pretrained=0-130_83330.ckpt \ - --testing_shape=416 > log.txt 2>&1 & -OR -bash run_eval.sh dataset/coco2014/ checkpoint/0-130_83330.ckpt 0 -``` - -The above python command will run in the background. You can view the results through the file "log.txt". The mAP of the test dataset will be as follows: - -```bash -# log.txt -=============coco eval reulst========= -Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.310 -Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.531 -Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.322 -Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.130 -Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.326 -Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.425 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.260 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.402 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.429 -Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.232 -Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.450 -Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.558 -``` - -## [Model Export](#contents) - -```shell -python export.py --ckpt_file [CKPT_PATH] --file_format [EXPORT_FORMAT] -``` - -`EXPORT_FORMAT` should be in ["AIR", "MINDIR"]. - -## [Ascend 310 inference](#contents) - -You should export AIR model at Ascend 910 before running the command below. -You can use export_bin_file.py to export coco2014 bin, image_shape.npy and image_id.npy for 310 inference. - -```shell -python export_bin_file.py --data_dir [DATASET_PATH] --save_path [SAVE_PATH] -``` - -Run run_infer_310.sh and get the accuracy锛� - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANNO_PATH] [IMAGESHAPE_PATH] [IMAGEID_PATH] [DEVICE_ID] -``` - -You can view the results through the file "acc.log". The accuracy of the test dataset will be as follows: - -```bash -=============coco eval reulst========= -Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.306 -Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.528 -Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.315 -Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.122 -Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.322 -Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.426 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.259 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.398 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.423 -Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.226 -Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.442 -Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.555 -``` - -## [Model Description](#contents) - -### [Performance](#contents) - -#### Evaluation Performance - -| Parameters | Ascend | -| -------------------------- | ---------------------------------------------------------------------------------------------- | -| Model Version | YOLOv3_Darknet53_Quant V1 | -| Resource | Ascend 910; CPU 2.60GHz, 192cores; Memory 755G; OS Euler2.8 | -| uploaded Date | 09/15/2020 (month/day/year) | -| MindSpore Version | 1.0.0 | -| Dataset | COCO2014 | -| Training Parameters | epoch=135, batch_size=16, lr=0.012, momentum=0.9 | -| Optimizer | Momentum | -| Loss Function | Sigmoid Cross Entropy with logits | -| outputs | boxes and label | -| Loss | 34 | -| Speed | 1pc: 135 ms/step; | -| Total time | 8pc: 23.5 hours | -| Parameters (M) | 62.1 | -| Checkpoint for Fine tuning | 474M (.ckpt file) | -| Scripts | [YoloV3-DarkNet53-Quant Script](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_darknet53_quant) | - -#### Inference Performance - -| Parameters | Ascend | -| ------------------- | --------------------------- | -| Model Version | YOLOv3_Darknet53_Quant V1 | -| Resource | Ascend 910; OS Euler2.8 | -| Uploaded Date | 09/15/2020 (month/day/year) | -| MindSpore Version | 1.0.0 | -| Dataset | COCO2014, 40,504 images | -| batch_size | 1 | -| outputs | mAP | -| Accuracy | 8pcs: 31.0% | -| Model for inference | 474M (.ckpt file) | - -## [Description of Random Situation](#contents) - -There are random seeds in distributed_sampler.py, transforms.py, yolo_dataset.py files. - -## [ModelZoo Homepage](#contents) - -Please check the official [homepage](https://gitee.com/mindspore/models). diff --git a/official/cv/yolov3_darknet53_quant/README_CN.md b/official/cv/yolov3_darknet53_quant/README_CN.md deleted file mode 100644 index 0703b4ab79fdf5cbcab8618104cda887f8fc69cc..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/README_CN.md +++ /dev/null @@ -1,361 +0,0 @@ -# 鐩綍 - -<!-- TOC --> - -- [鐩綍](#鐩綍) - - [YOLOv3-DarkNet53-Quant鎻忚堪](#yolov3-darknet53-quant鎻忚堪) - - [妯″瀷鏋舵瀯](#妯″瀷鏋舵瀯) - - [鏁版嵁闆哴(#鏁版嵁闆�) - - [鐜瑕佹眰](#鐜瑕佹眰) - - [蹇€熷叆闂╙(#蹇€熷叆闂�) - - [鑴氭湰璇存槑](#鑴氭湰璇存槑) - - [鑴氭湰鍙婃牱渚嬩唬鐮乚(#鑴氭湰鍙婃牱渚嬩唬鐮�) - - [鑴氭湰鍙傛暟](#鑴氭湰鍙傛暟) - - [璁粌杩囩▼](#璁粌杩囩▼) - - [Ascend涓婅缁僝(#ascend涓婅缁�) - - [鍒嗗竷寮忚缁僝(#鍒嗗竷寮忚缁�) - - [璇勪及杩囩▼](#璇勪及杩囩▼) - - [Ascend璇勪及](#ascend璇勪及) - - [妯″瀷瀵煎嚭](#妯″瀷瀵煎嚭) - - [Ascend 310 鎺ㄧ悊](#ascend-310-鎺ㄧ悊) - - [妯″瀷鎻忚堪](#妯″瀷鎻忚堪) - - [鎬ц兘](#鎬ц兘) - - [璇勪及鎬ц兘](#璇勪及鎬ц兘) - - [鎺ㄧ悊鎬ц兘](#鎺ㄧ悊鎬ц兘) - - [闅忔満鎯呭喌璇存槑](#闅忔満鎯呭喌璇存槑) - - [ModelZoo涓婚〉](#modelzoo涓婚〉) - -<!-- /TOC --> - -## YOLOv3-DarkNet53-Quant鎻忚堪 - -You only look once锛圷OLO锛夋槸鏈€鍏堣繘鐨勫疄鏃剁墿浣撴娴嬬郴缁熴€俌OLOv3闈炲父蹇€熷拰鍑嗙‘銆� - -鍏堝墠鐨勬娴嬬郴缁熼噸鏂板埄鐢ㄥ垎绫诲櫒鎴栧畾浣嶅櫒鏉ユ墽琛屾娴嬶紝灏嗘ā鍨嬪簲鐢ㄤ簬澶氫釜浣嶇疆鍜屽昂搴︾殑鍥惧儚銆傚浘鍍忕殑楂樺垎鍖哄煙琚涓烘槸妫€娴嬨€� - YOLOv3浣跨敤浜嗗畬鍏ㄤ笉鍚岀殑鏂规硶銆傝鏂规硶灏嗗崟涓缁忕綉缁滃簲鐢ㄤ簬鍏ㄥ浘鍍忥紝灏嗗浘鍍忓垝鍒嗕负鍖哄煙锛屽苟棰勬祴姣忎釜鍖哄煙鐨勮竟鐣屾鍜屾鐜囥€傝繖浜涜竟鐣屾鐢遍娴嬫鐜囧姞鏉冦€� - -YOLOv3浣跨敤浜嗕竴浜涙妧宸ф潵鏀硅繘璁粌锛屾彁楂樻€ц兘锛屽寘鎷灏哄害棰勬祴銆佹洿濂界殑涓诲共鍒嗙被鍣ㄧ瓑绛夛紝璇︽儏瑙佽鏂囥€� - -涓轰簡鍑忓皬鏉冮噸鐨勫ぇ灏忥紝鎻愰珮浣庝綅璁$畻鎬ц兘锛岄噰鐢ㄤ簡int8閲忓寲銆� - -[璁烘枃](https://pjreddie.com/media/files/papers/YOLOv3.pdf)锛� YOLOv3: An Incremental Improvement.Joseph Redmon, Ali Farhadi, University of Washington - -## 妯″瀷鏋舵瀯 - -YOLOv3浣跨敤DarkNet53鎵ц鐗瑰緛鎻愬彇锛岃繖鏄痀OLOv2涓殑Darknet-19鍜屾畫宸綉缁滅殑涓€绉嶆贩鍚堟柟娉曘€侱arkNet53浣跨敤杩炵画鐨�3脳3鍜�1脳1鍗风Н灞傦紝骞朵笖鏈変竴浜涘揩鎹疯繛鎺ワ紝鑰屼笖DarkNet53鏄庢樉鏇村ぇ锛屽畠鏈�53灞傚嵎绉眰銆� - -## 鏁版嵁闆� - -浣跨敤鐨勬暟鎹泦锛歔COCO 2014](https://cocodataset.org/#download) - -- 鏁版嵁闆嗗ぇ灏忥細19G锛�123287寮犲浘鐗囷紝80涓墿浣撶被鍒� - - 璁粌闆嗭細13G锛�82783寮犲浘鐗� - - 楠岃瘉闆嗭細6GM锛�40504寮犲浘鐗� - - 鏍囨敞锛�241M锛岃缁�/楠岃瘉鏍囨敞 -- 鏁版嵁鏍煎紡锛歾ip鏂囦欢 - - 娉細鏁版嵁灏嗗湪yolo_dataset.py涓鐞嗭紝骞跺湪浣跨敤鍓嶈В鍘嬫枃浠躲€� - -## 鐜瑕佹眰 - -- 纭欢锛圓scend澶勭悊鍣級 - - 鍑嗗Ascend鎴朑PU澶勭悊鍣ㄦ惌寤虹‖浠剁幆澧冦€� -- 妗嗘灦 - - [MindSpore](https://www.mindspore.cn/install/) -- 濡傞渶鏌ョ湅璇︽儏锛岃鍙傝濡備笅璧勬簮锛� - - [MindSpore鏁欑▼](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/zh-CN/master/index.html) - -## 蹇€熷叆闂� - -閫氳繃瀹樻柟缃戠珯瀹夎MindSpore鍚庯紝鎮ㄥ彲浠ユ寜鐓у涓嬫楠よ繘琛岃缁冨拰璇勪及锛� - -```python -# 涓嬮潰鐨勮剼鏈腑鐨剏olov3_darknet53_noquin.ckpt鏄粠yolov3-darknet53璁粌寰楀埌鐨勩€� -# resume_yolov3鍙傛暟鏄繀闇€鐨勩€� -# training_shape鍙傛暟瀹氫箟缃戠粶鍥惧儚褰㈢姸锛岄粯璁や负""銆� -# 鎰忔€濇槸浣跨敤10绉嶅舰鐘朵綔涓鸿緭鍏ュ舰鐘讹紝鎴栬€呭彲浠ヨ缃煇绉嶅舰鐘躲€� -# 閫氳繃python鍛戒护鎵ц璁粌绀轰緥(1鍗�)銆� -python train.py \ - --data_dir=./dataset/coco2014 \ - --resume_yolov3=yolov3_darknet53_noquant.ckpt \ - --is_distributed=0 \ - --per_batch_size=16 \ - --lr=0.012 \ - --T_max=135 \ - --max_epoch=135 \ - --warmup_epochs=5 \ - --lr_scheduler=cosine_annealing > log.txt 2>&1 & -``` - -```shell script -# shell鑴氭湰鍗曟満璁粌绀轰緥(1鍗�) -bash run_standalone_train.sh dataset/coco2014 yolov3_darknet53_noquant.ckpt -``` - -```shell script -# shell鑴氭湰鍒嗗竷寮忚缁冪ず渚�(8鍗�) -bash run_distribute_train.sh dataset/coco2014 yolov3_darknet53_noquant.ckpt rank_table_8p.json -``` - -```python -# 浣跨敤python鍛戒护璇勪及 -python eval.py \ - --data_dir=./dataset/coco2014 \ - --pretrained=yolov3_quent.ckpt \ - --testing_shape=416 > log.txt 2>&1 & -``` - -```shell script -# 閫氳繃shell鑴氭湰杩愯璇勪及 -bash run_eval.sh dataset/coco2014/ checkpoint/yolov3_quant.ckpt 0 -``` - -## 鑴氭湰璇存槑 - -### 鑴氭湰鍙婃牱渚嬩唬鐮� - -```text -. -鈹斺攢yolov3_darknet53_quant - 鈹溾攢README.md - 鈹溾攢ascend310_infer # 瀹炵幇310鎺ㄧ悊婧愪唬鐮� - 鈹溾攢mindspore_hub_conf.md # Mindspore Hub閰嶇疆 - 鈹溾攢scripts - 鈹溾攢run_standalone_train.sh # 鍦ˋscend涓惎鍔ㄥ崟鏈鸿缁�(1鍗�) - 鈹溾攢run_distribute_train.sh # 鍦ˋscend涓惎鍔ㄥ垎甯冨紡璁粌(8鍗�) - 鈹溾攢run_eval.sh # 鍦ˋscend涓惎鍔ㄨ瘎浼� - 鈹溾攢run_infer_310.sh # Ascend 310 鎺ㄧ悊shell鑴氭湰 - 鈹溾攢src - 鈹溾攢__init__.py # python鍒濆鍖栨枃浠� - 鈹溾攢config.py # 鍙傛暟閰嶇疆 - 鈹溾攢darknet.py # 缃戠粶楠ㄥ共 - 鈹溾攢distributed_sampler.py # 鏁版嵁闆嗚凯浠e櫒 - 鈹溾攢initializer.py # 鍙傛暟鍒濆鍖栧櫒 - 鈹溾攢logger.py # 鏃ュ織鍑芥暟 - 鈹溾攢loss.py # 鎹熷け鍑芥暟 - 鈹溾攢lr_scheduler.py # 鐢熸垚瀛︿範鐜� - 鈹溾攢transforms.py # 棰勫鐞嗘暟鎹� - 鈹溾攢util.py # 宸ュ叿鍑芥暟 - 鈹溾攢yolo.py # YOLOV3缃戠粶 - 鈹溾攢yolo_dataset.py # 涓篩OLOV3鍒涘缓鏁版嵁闆� - 鈹溾攢eval.py # 璇勪及缃戠粶 - 鈹斺攢train.py # 璁粌缃戠粶 - 鈹溾攢export_bin_file.py # 瀵煎嚭coco2014鏁版嵁闆嗙殑bin鏂囦欢鐢ㄤ簬310鎺ㄧ悊 - 鈹溾攢postprocess.py # 310鎺ㄧ悊鍚庡鐞嗚剼鏈� -``` - -### 鑴氭湰鍙傛暟 - -```text -train.py涓富瑕佸弬鏁板涓嬶細 - -鍙€夊弬鏁帮細 - -h, --help 鏄剧ず姝ゅ府鍔╂秷鎭苟閫€鍑恒€� - --data_dir DATA_DIR 璁粌鏁版嵁闆嗙洰褰曘€傞粯璁よ缃細""銆� - --per_batch_size PER_BATCH_SIZE - 姣忎釜璁惧鐨勬壒娆″ぇ灏忋€傞粯璁よ缃細16銆� - --resume_yolov3 RESUME_YOLOV3 - YOLOv3鐨刢kpt鏂囦欢锛岀敤浜庡井璋冦€傞粯璁よ缃細""銆� - --lr_scheduler LR_SCHEDULER - 瀛︿範鐜囪皟搴﹀櫒锛岄€夐」锛歟xponential锛宑osine_annealing銆傞粯璁よ缃細exponential銆� - --lr LR 瀛︿範鐜囥€傞粯璁よ缃細0.012銆� - --lr_epochs LR_EPOCHS - lr changing杞锛岀敤鈥�,鈥濆垎闅斻€傞粯璁よ缃細92, 105銆� - --lr_gamma LR_GAMMA 闄嶄綆lr鐨別xponential lr_scheduler鍥犲瓙銆傞粯璁よ缃細0.1銆� - --eta_min ETA_MIN cosine_annealing璋冨害鍣ㄤ腑鐨別ta_min銆傞粯璁よ缃細0銆� - --T_max T_MAX cosine_annealing璋冨害鍣ㄤ腑鐨凾-max銆傞粯璁よ缃細135銆� - --max_epoch MAX_EPOCH - 璁粌妯″瀷鐨勬渶澶ц疆娆℃暟銆傞粯璁よ缃細135銆� - --warmup_epochs WARMUP_EPOCHS - 鐑韩杞銆傞粯璁よ缃細0銆� - --weight_decay WEIGHT_DECAY - 鏉冮噸琛板噺鍥犲瓙銆傞粯璁よ缃細0.0005銆� - --momentum MOMENTUM 鍔ㄩ噺銆傞粯璁よ缃細0.9銆� - --loss_scale LOSS_SCALE - 闈欐€佹崯澶辩瓑绾с€傞粯璁よ缃細1024銆� - --label_smooth LABEL_SMOOTH - CE涓槸鍚︿娇鐢ㄦ爣绛惧钩婊戙€傞粯璁よ缃細0銆� - --label_smooth_factor LABEL_SMOOTH_FACTOR - 鐙儹骞虫粦寮哄害銆傞粯璁よ缃細0.1銆� - --log_interval LOG_INTERVAL - 鏃ュ織璁板綍杩唬闂撮殭銆傞粯璁よ缃細100銆� - --ckpt_path CKPT_PATH - 妫€鏌ョ偣淇濆瓨浣嶇疆銆傞粯璁よ缃細"outputs/"銆� - --ckpt_interval CKPT_INTERVAL - 淇濆瓨妫€鏌ョ偣闂撮殧銆傞粯璁よ缃細None銆� - --is_save_on_master IS_SAVE_ON_MASTER - 鍦ㄤ富杩涚▼搴忓彿鎴栨墍鏈夎繘绋嬪簭鍙蜂笂淇濆瓨ckpt銆�1涓轰富杩涚▼搴忓彿锛� 0涓烘墍鏈夎繘绋嬪簭鍙枫€傞粯璁よ缃細1銆� - --is_distributed IS_DISTRIBUTED - 鏄惁鍒嗗竷璁粌锛�1琛ㄧず鏄紝0琛ㄧず鍚︺€� 榛樿璁剧疆锛�0銆� - --rank RANK 鍒嗗竷寮忔湰鍦拌繘绋嬪簭鍙枫€傞粯璁よ缃細0銆� - --group_size GROUP_SIZE - 璁惧杩涚▼鎬绘暟銆傞粯璁よ缃細1銆� - --need_profiler NEED_PROFILER - 鏄惁浣跨敤璋冧紭鍣ㄣ€�1琛ㄧず鏄紝0琛ㄧず鍚︺€傞粯璁よ缃細0銆� - --training_shape TRAINING_SHAPE - 鍥哄畾璁粌褰㈢姸銆傞粯璁よ缃細""銆� - --resize_rate RESIZE_RATE - 澶氬昂搴﹁缁冪殑璋冩暣鐜囥€傞粯璁よ缃細None銆� -``` - -### 璁粌杩囩▼ - -#### Ascend涓婅缁� - -##### 鍒嗗竷寮忚缁� - -```shell script -bash run_distribute_train.sh dataset/coco2014 yolov3_darknet53_noquant.ckpt rank_table_8p.json -``` - -涓婅堪shell鑴氭湰灏嗗湪鍚庡彴杩愯鍒嗗竷璁粌銆傛偍鍙互閫氳繃`train_parallel0/log.txt`鏂囦欢鏌ョ湅缁撴灉銆傛崯澶卞€肩殑瀹炵幇濡備笅锛� - -```text -# 鍒嗗竷寮忚缁冪ず渚�(8鍗�) -epoch[0], iter[0], loss:483.341675, 0.31 imgs/sec, lr:0.0 -epoch[0], iter[100], loss:55.690952, 3.46 imgs/sec, lr:0.0 -epoch[0], iter[200], loss:54.045728, 126.54 imgs/sec, lr:0.0 -epoch[0], iter[300], loss:48.771608, 133.04 imgs/sec, lr:0.0 -epoch[0], iter[400], loss:48.486769, 139.69 imgs/sec, lr:0.0 -epoch[0], iter[500], loss:48.649275, 143.29 imgs/sec, lr:0.0 -epoch[0], iter[600], loss:44.731309, 144.03 imgs/sec, lr:0.0 -epoch[1], iter[700], loss:43.037023, 136.08 imgs/sec, lr:0.0 -epoch[1], iter[800], loss:41.514788, 132.94 imgs/sec, lr:0.0 - -鈥� -epoch[133], iter[85700], loss:33.326716, 136.14 imgs/sec, lr:6.497331924038008e-06 -epoch[133], iter[85800], loss:34.968744, 136.76 imgs/sec, lr:6.497331924038008e-06 -epoch[134], iter[85900], loss:35.868543, 137.08 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86000], loss:35.740817, 139.49 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86100], loss:34.600463, 141.47 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86200], loss:36.641916, 137.91 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86300], loss:32.819769, 138.17 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86400], loss:35.603033, 142.23 imgs/sec, lr:1.6245529650404933e-06 -epoch[134], iter[86500], loss:34.303755, 145.18 imgs/sec, lr:1.6245529650404933e-06 -``` - -### 璇勪及杩囩▼ - -#### Ascend璇勪及 - -杩愯浠ヤ笅鍛戒护銆� - -```python -python eval.py \ - --data_dir=./dataset/coco2014 \ - --pretrained=0-130_83330.ckpt \ - --testing_shape=416 > log.txt 2>&1 & -``` - -鎴栬€� - -```shell script -bash run_eval.sh dataset/coco2014/ checkpoint/0-130_83330.ckpt 0 -``` - -涓婅堪python鍛戒护灏嗗湪鍚庡彴杩愯锛屾偍鍙互閫氳繃log.txt鏂囦欢鏌ョ湅缁撴灉銆傛祴璇曟暟鎹泦鐨刴AP濡備笅锛� - -```text -# log.txt -=============coco eval reulst========= -Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.310 -Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.531 -Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.322 -Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.130 -Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.326 -Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.425 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.260 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.402 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.429 -Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.232 -Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.450 -Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.558 -``` - -## 妯″瀷瀵煎嚭 - -```shell -python export.py --ckpt_file [CKPT_PATH] --file_format [EXPORT_FORMAT] -``` - -`EXPORT_FORMAT` 鍙€� ["AIR", "MINDIR"]. - -## Ascend 310 鎺ㄧ悊 - -鍦ㄦ帹鐞嗕箣鍓嶉渶瑕佸湪鏄囪吘910鐜涓婂畬鎴怉IR妯″瀷鐨勫鍑恒€� -骞朵娇鐢╡xport_bin_file.py瀵煎嚭coco2014鏁版嵁闆嗙殑bin鏂囦欢鍜屽搴旂殑image_shape, image_id鏂囦欢锛� - -```shell -python export_bin_file.py --data_dir [DATASET_PATH] --save_path [SAVE_PATH] -``` - -鎵ц鎺ㄧ悊骞跺緱鍒版帹鐞嗙簿搴︼細 - -```shell -# Ascend310 inference -bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANNO_PATH] [IMAGESHAPE_PATH] [IMAGEID_PATH] [DEVICE_ID] -``` - -鎮ㄥ彲浠ラ€氳繃acc.log鏂囦欢鏌ョ湅缁撴灉銆傛帹鐞嗗噯纭€у涓嬶細 - -```bash -=============coco eval reulst========= -Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.306 -Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.528 -Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.315 -Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.122 -Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.322 -Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.426 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.259 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.398 -Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.423 -Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.226 -Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.442 -Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.555 -``` - -## 妯″瀷鎻忚堪 - -### 鎬ц兘 - -#### 璇勪及鎬ц兘 - -| 鍙傛暟 | Ascend | -| -------------------------- | ---------------------------------------------------------------------------------------------- | -| 妯″瀷鐗堟湰 | YOLOv3_Darknet53_Quant V1 | -| 璧勬簮 | Ascend 910锛汣PU 2.60GHz锛�192鏍革紱鍐呭瓨 755G锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2020-06-31 | -| MindSpore鐗堟湰 | 0.6.0-alpha | -| 鏁版嵁闆� | COCO2014 | -| 璁粌鍙傛暟 | epoch=135锛宐atch_size=16锛宭r=0.012锛宮omentum=0.9 | -| 浼樺寲鍣� | Momentum | -| 鎹熷け鍑芥暟 | 甯ogits鐨凷igmoid浜ゅ弶鐔� | -| 杈撳嚭 | 杈圭晫妗嗗拰鏍囩 | -| 鎹熷け | 34 | -| 閫熷害 | 1鍗★細135姣/姝�; | -| 鎬绘椂闀� | 8鍗★細23.5灏忔椂 | -| 鍙傛暟 (M) | 62.1 | -| 寰皟妫€鏌ョ偣 | 474M (.ckpt鏂囦欢) | -| 鑴氭湰 | [YoloV3-DarkNet53-Quant鑴氭湰](https://gitee.com/mindspore/models/tree/master/official/cv/yolov3_darknet53_quant) | - -#### 鎺ㄧ悊鎬ц兘 - -| 鍙傛暟 | Ascend | -| ------------------- | --------------------------- | -| 妯″瀷鐗堟湰 | YOLOv3_Darknet53_Quant V1 | -| 璧勬簮 |Ascend 910锛涚郴缁� Euler2.8 | -| 涓婁紶鏃ユ湡 | 2020-06-31 | -| MindSpore鐗堟湰 | 0.6.0-alpha | -| 鏁版嵁闆� | COCO2014锛�40,504寮犲浘鐗� | -| batch_size | 1 | -| 杈撳嚭 | mAP | -| 鍑嗙‘鐜� | 8pcs锛�31.0% | -| 鎺ㄧ悊妯″瀷 | 474M (.ckpt鏂囦欢) | - -## 闅忔満鎯呭喌璇存槑 - -鍦╠istributed_sampler.py銆乼ransforms.py銆亂olo_dataset.py鏂囦欢涓湁闅忔満绉嶅瓙銆� - -## ModelZoo涓婚〉 - -璇锋祻瑙堝畼缃慬涓婚〉](https://gitee.com/mindspore/models)銆� diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/ModelProcess.h b/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/ModelProcess.h deleted file mode 100644 index e0a91396f09eed78e2c55f4900813323706878b0..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/ModelProcess.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MODELPROCESS_H -#define MODELPROCESS_H - -#include <iostream> -#include <vector> -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* ModelProcess -*/ -class ModelProcess { - public: - /** - * @brief Constructor - */ - ModelProcess(); - - /** - * @brief Destructor - */ - ~ModelProcess(); - - /** - * @brief load model from file with mem - * @param [in] modelPath: model path - * @return result - */ - Result LoadModelFromFileWithMem(const char *modelPath); - - /** - * @brief unload model - */ - void Unload(); - - /** - * @brief create model desc - * @return result - */ - Result CreateDesc(); - - /** - * @brief destroy desc - */ - void DestroyDesc(); - - /** - * @brief create model input - * @param [in] inputDataBuffer: input buffer - * @param [in] bufferSize: input buffer size - * @return result - */ - Result CreateInput(const std::vector<void *> &inputDataBuffer, const std::vector<size_t> &bufferSize); - - /** - * @brief destroy input resource - */ - void DestroyInput(); - - /** - * @brief create output buffer - * @return result - */ - Result CreateOutput(); - - /** - * @brief destroy output resource - */ - void DestroyOutput(); - - /** - * @brief model execute - * @return result - */ - Result Execute(); - - /** - * @brief dump model output result to file - */ - void DumpModelOutputResult(char *output_name); - - /** - * @brief get model output result - */ - void OutputModelResult(); - - private: - uint32_t modelId_; - size_t modelMemSize_; - size_t modelWeightSize_; - void *modelMemPtr_; - void *modelWeightPtr_; - bool loadFlag_; // model load flag - aclmdlDesc *modelDesc_; - aclmdlDataset *input_; - aclmdlDataset *output_; -}; -#endif diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/SampleProcess.h b/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/SampleProcess.h deleted file mode 100644 index 30a77f4248c948b83d019ee05aaf56dce9a08e26..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/SampleProcess.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef SAMPLEPROCESS_H -#define SAMPLEPROCESS_H - -#include <string> -#include <vector> -#include "acl/acl.h" -#include "../inc/utils.h" - -/** -* SampleProcess -*/ -class SampleProcess { - public: - /** - * @brief Constructor - */ - explicit SampleProcess(int32_t deviceId); - - /** - * @brief Destructor - */ - ~SampleProcess(); - - /** - * @brief init reousce - * @return result - */ - Result InitResource(const char *acl_config_path); - - /** - * @brief sample process - * @return result - */ - Result Process(const char *om_path, const char *input_folder); - - void GetAllFiles(std::string path, std::vector<std::string> *files); - - private: - void DestroyResource(); - - int32_t deviceId_; - aclrtContext context_; - aclrtStream stream_; -}; - -#endif diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/utils.h b/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/utils.h deleted file mode 100644 index b21e418a1f4ad2b8fc0331cf0b37adf73f2703f6..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/inc/utils.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#ifndef MINDSPORE_INFERENCE_UTILS_H_ -#define MINDSPORE_INFERENCE_UTILS_H_ - -#include <iostream> -#include <string> - -#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args) -#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args) -#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args) - -typedef enum Result { - SUCCESS = 0, - FAILED = 1 -} Result; - -/** -* Utils -*/ -class Utils { - public: - /** - * @brief create device buffer of file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return device buffer of file - */ - static void *GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize); - - /** - * @brief Read bin file - * @param [in] fileName: file name - * @param [out] fileSize: size of file - * @return buffer of pic - */ - static void* ReadBinFile(std::string fileName, uint32_t *fileSize); -}; -#endif diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/CMakeLists.txt b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/CMakeLists.txt deleted file mode 100644 index 571955fcbd304e5b00e27782859e40bc0c9b1d09..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. - -# CMake lowest version requirement -cmake_minimum_required(VERSION 3.5.1) -# project information -project(InferClassification) -# Check environment variable -if(NOT DEFINED ENV{ASCEND_HOME}) - message(FATAL_ERROR "please define environment variable:ASCEND_HOME") -endif() - -# Compile options -add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined") - -# Skip build rpath -set(CMAKE_SKIP_BUILD_RPATH True) - -# Set output directory -set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SRC_ROOT}/out) - -# Set include directory and library directory -set(FWKACL_LIB_DIR $ENV{ASCEND_HOME}/fwkacllib) -set(ACL_LIB_DIR $ENV{ASCEND_HOME}/acllib) -set(ATLAS_ACL_LIB_DIR $ENV{ASCEND_HOME}/ascend-toolkit/latest/acllib) - -# Header path -include_directories(${ACL_LIB_DIR}/include/) -include_directories(${FWKACL_LIB_DIR}/include/) -include_directories(${ATLAS_ACL_LIB_DIR}/include/) -include_directories(${PROJECT_SRC_ROOT}/../inc) - -# add host lib path -link_directories(${ACL_LIB_DIR} ${FWKACL_LIB_DIR}) -find_library(acl libascendcl.so ${ACL_LIB_DIR}/lib64 ${FWKACL_LIB_DIR}/lib64 ${ATLAS_ACL_LIB_DIR}/lib64) - -add_executable(main utils.cpp - SampleProcess.cpp - ModelProcess.cpp - main.cpp) - -target_link_libraries(main ${acl} gflags pthread) - diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/ModelProcess.cpp b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/ModelProcess.cpp deleted file mode 100644 index 339bdcd09f61ba5edbccf316cd3f42593fe0843d..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/ModelProcess.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/ModelProcess.h" -#include <iostream> -#include <map> -#include <sstream> -#include <algorithm> -#include "../inc/utils.h" - -extern bool g_isDevice; - -ModelProcess::ModelProcess() :modelId_(0), modelMemSize_(0), modelWeightSize_(0), modelMemPtr_(nullptr), -modelWeightPtr_(nullptr), loadFlag_(false), modelDesc_(nullptr), input_(nullptr), output_(nullptr) { -} - -ModelProcess::~ModelProcess() { - Unload(); - DestroyDesc(); - DestroyInput(); - DestroyOutput(); -} - -Result ModelProcess::LoadModelFromFileWithMem(const char *modelPath) { - if (loadFlag_) { - ERROR_LOG("has already loaded a model"); - return FAILED; - } - - aclError ret = aclmdlQuerySize(modelPath, &modelMemSize_, &modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("query model failed, model file is %s", modelPath); - return FAILED; - } - - ret = aclrtMalloc(&modelMemPtr_, modelMemSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for mem failed, require size is %zu", modelMemSize_); - return FAILED; - } - - ret = aclrtMalloc(&modelWeightPtr_, modelWeightSize_, ACL_MEM_MALLOC_HUGE_FIRST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc buffer for weight failed, require size is %zu", modelWeightSize_); - return FAILED; - } - - ret = aclmdlLoadFromFileWithMem(modelPath, &modelId_, modelMemPtr_, - modelMemSize_, modelWeightPtr_, modelWeightSize_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("load model from file failed, model file is %s", modelPath); - return FAILED; - } - - loadFlag_ = true; - INFO_LOG("load model %s success", modelPath); - return SUCCESS; -} - -Result ModelProcess::CreateDesc() { - modelDesc_ = aclmdlCreateDesc(); - if (modelDesc_ == nullptr) { - ERROR_LOG("create model description failed"); - return FAILED; - } - - aclError ret = aclmdlGetDesc(modelDesc_, modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("get model description failed"); - return FAILED; - } - - INFO_LOG("create model description success"); - - return SUCCESS; -} - -void ModelProcess::DestroyDesc() { - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } -} - -Result ModelProcess::CreateInput(const std::vector<void *> &inputDataBuffer, const std::vector<size_t> &bufferSize) { - input_ = aclmdlCreateDataset(); - if (input_ == nullptr) { - ERROR_LOG("can't create dataset, create input failed"); - return FAILED; - } - for (size_t i = 0; i < inputDataBuffer.size(); ++i) { - aclDataBuffer* inputData = aclCreateDataBuffer(inputDataBuffer[i], bufferSize[i]); - if (inputData == nullptr) { - ERROR_LOG("can't create data buffer, create input failed"); - return FAILED; - } - aclError ret = aclmdlAddDatasetBuffer(input_, inputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("add input dataset buffer failed"); - aclDestroyDataBuffer(inputData); - inputData = nullptr; - return FAILED; - } - } - return SUCCESS; -} - -void ModelProcess::DestroyInput() { - if (input_ == nullptr) { - return; - } - - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(input_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(input_, i); - aclDestroyDataBuffer(dataBuffer); - } - aclmdlDestroyDataset(input_); - input_ = nullptr; -} - -Result ModelProcess::CreateOutput() { - if (modelDesc_ == nullptr) { - ERROR_LOG("no model description, create output failed"); - return FAILED; - } - - output_ = aclmdlCreateDataset(); - if (output_ == nullptr) { - ERROR_LOG("can't create dataset, create output failed"); - return FAILED; - } - - size_t outputSize = aclmdlGetNumOutputs(modelDesc_); - for (size_t i = 0; i < outputSize; ++i) { - size_t buffer_size = aclmdlGetOutputSizeByIndex(modelDesc_, i); - - void *outputBuffer = nullptr; - aclError ret = aclrtMalloc(&outputBuffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't malloc buffer, size is %zu, create output failed", buffer_size); - return FAILED; - } - - aclDataBuffer* outputData = aclCreateDataBuffer(outputBuffer, buffer_size); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't create data buffer, create output failed"); - aclrtFree(outputBuffer); - return FAILED; - } - - ret = aclmdlAddDatasetBuffer(output_, outputData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("can't add data buffer, create output failed"); - aclrtFree(outputBuffer); - aclDestroyDataBuffer(outputData); - return FAILED; - } - } - - INFO_LOG("create model output success"); - return SUCCESS; -} - -void ModelProcess::DumpModelOutputResult(char *output_name) { - size_t outputNum = aclmdlGetDatasetNumBuffers(output_); - std::string homePath = "./result_Files"; - for (size_t i = 0; i < outputNum; ++i) { - std::string fileName = std::string(output_name) + '_' + std::to_string(i) + ".bin"; - std::string outputFileName = homePath + "/" + fileName; - FILE *outputFile = fopen(outputFileName.c_str(), "wb"); - if (outputFile != nullptr) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - void* outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - (void)aclrtFreeHost(outHostData); - return; - } - - fwrite(outHostData, len, sizeof(char), outputFile); - - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } else { - fwrite(data, len, sizeof(char), outputFile); - } - fclose(outputFile); - outputFile = nullptr; - } else { - ERROR_LOG("create output file [%s] failed", outputFileName.c_str()); - return; - } - } - - INFO_LOG("dump data success"); - return; -} - -void ModelProcess::OutputModelResult() { - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - uint32_t len = aclGetDataBufferSizeV2(dataBuffer); - - void *outHostData = NULL; - aclError ret = ACL_ERROR_NONE; - float *outData = NULL; - if (!g_isDevice) { - ret = aclrtMallocHost(&outHostData, len); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMallocHost failed, ret[%d]", ret); - return; - } - - ret = aclrtMemcpy(outHostData, len, data, len, ACL_MEMCPY_DEVICE_TO_HOST); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtMemcpy failed, ret[%d]", ret); - return; - } - - outData = reinterpret_cast<float*>(outHostData); - } else { - outData = reinterpret_cast<float*>(data); - } - std::map<float, unsigned int, std::greater<float> > resultMap; - for (unsigned int j = 0; j < len / sizeof(float); ++j) { - resultMap[*outData] = j; - outData++; - } - - int cnt = 0; - for (auto it = resultMap.begin(); it != resultMap.end(); ++it) { - // print top 5 - if (++cnt > 5) { - break; - } - - INFO_LOG("top %d: index[%d] value[%lf]", cnt, it->second, it->first); - } - if (!g_isDevice) { - ret = aclrtFreeHost(outHostData); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("aclrtFreeHost failed, ret[%d]", ret); - return; - } - } - } - - INFO_LOG("output data success"); - return; -} - -void ModelProcess::DestroyOutput() { - if (output_ == nullptr) { - return; - } - - for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(output_); ++i) { - aclDataBuffer* dataBuffer = aclmdlGetDatasetBuffer(output_, i); - void* data = aclGetDataBufferAddr(dataBuffer); - (void)aclrtFree(data); - (void)aclDestroyDataBuffer(dataBuffer); - } - - (void)aclmdlDestroyDataset(output_); - output_ = nullptr; -} - -Result ModelProcess::Execute() { - aclError ret = aclmdlExecute(modelId_, input_, output_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("execute model failed, modelId is %u", modelId_); - return FAILED; - } - - INFO_LOG("model execute success"); - return SUCCESS; -} - -void ModelProcess::Unload() { - if (!loadFlag_) { - WARN_LOG("no model had been loaded, unload failed"); - return; - } - - aclError ret = aclmdlUnload(modelId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("unload model failed, modelId is %u", modelId_); - } - - if (modelDesc_ != nullptr) { - (void)aclmdlDestroyDesc(modelDesc_); - modelDesc_ = nullptr; - } - - if (modelMemPtr_ != nullptr) { - aclrtFree(modelMemPtr_); - modelMemPtr_ = nullptr; - modelMemSize_ = 0; - } - - if (modelWeightPtr_ != nullptr) { - aclrtFree(modelWeightPtr_); - modelWeightPtr_ = nullptr; - modelWeightSize_ = 0; - } - - loadFlag_ = false; - INFO_LOG("unload model success, modelId is %u", modelId_); -} diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/SampleProcess.cpp b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/SampleProcess.cpp deleted file mode 100644 index fb8a1813492ae91c861912de7800d7cb045957ad..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/SampleProcess.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/SampleProcess.h" -#include <sys/types.h> -#include <dirent.h> -#include <string.h> -#include <iostream> -#include <fstream> -#include "../inc/utils.h" -#include "../inc/ModelProcess.h" -#include "acl/acl.h" - -extern bool g_isDevice; -using std::string; -using std::vector; - -SampleProcess::SampleProcess(int32_t deviceId) : context_(nullptr), stream_(nullptr) { - deviceId_ = deviceId; -} - -SampleProcess::~SampleProcess() { - DestroyResource(); -} - -Result SampleProcess::InitResource(const char *aclConfigPath) { - // ACL init - aclError ret = aclInit(aclConfigPath); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl init failed"); - return FAILED; - } - INFO_LOG("acl init success"); - - // open device - ret = aclrtSetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl open device %d failed", deviceId_); - return FAILED; - } - INFO_LOG("open device %d success", deviceId_); - - // create context (set current) - ret = aclrtCreateContext(&context_, deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create context failed"); - return FAILED; - } - INFO_LOG("create context success"); - - // create stream - ret = aclrtCreateStream(&stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl create stream failed"); - return FAILED; - } - INFO_LOG("create stream success"); - - // get run mode - aclrtRunMode runMode; - ret = aclrtGetRunMode(&runMode); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("acl get run mode failed"); - return FAILED; - } - g_isDevice = (runMode == ACL_DEVICE); - INFO_LOG("get run mode success"); - return SUCCESS; -} - -void SampleProcess::GetAllFiles(std::string path, std::vector<string> *files) { - DIR *pDir = nullptr; - struct dirent* ptr = nullptr; - if (!(pDir = opendir(path.c_str()))) - return; - while ((ptr = readdir(pDir)) != 0) { - if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) - files->push_back(path + "/" + ptr->d_name); - } - closedir(pDir); -} - -Result SampleProcess::Process(const char *om_path, const char *input_folder) { - // model init - ModelProcess processModel; - - Result ret = processModel.LoadModelFromFileWithMem(om_path); - if (ret != SUCCESS) { - ERROR_LOG("execute LoadModelFromFileWithMem failed"); - return FAILED; - } - - ret = processModel.CreateDesc(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateDesc failed"); - return FAILED; - } - - ret = processModel.CreateOutput(); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateOutput failed"); - return FAILED; - } - - std::vector<string> testFile; - GetAllFiles(input_folder, &testFile); - - if (testFile.size() == 0) { - WARN_LOG("no input data under folder"); - } - float *inputShape = reinterpret_cast<float *>(malloc(sizeof(float) * 2)); - inputShape[0] = 416; - inputShape[1] = 416; - void *inputShapeBuffer = nullptr; - int mret = aclrtMalloc(&inputShapeBuffer, 8, ACL_MEM_MALLOC_NORMAL_ONLY); - if (mret != ACL_ERROR_NONE) { - aclrtFree(inputShape); - aclrtFree(inputShapeBuffer); - return FAILED; - } - mret = aclrtMemcpy(reinterpret_cast<uint8_t *>(inputShapeBuffer), 8, inputShape, 8, ACL_MEMCPY_HOST_TO_DEVICE); - if (mret != ACL_ERROR_NONE) { - aclrtFree(inputShape); - aclrtFree(inputShapeBuffer); - return FAILED; - } - // loop begin - for (size_t index = 0; index < testFile.size(); ++index) { - INFO_LOG("start to process file:%s", testFile[index].c_str()); - // model process - uint32_t devBufferSize; - void *picDevBuffer = Utils::GetDeviceBufferOfFile(testFile[index], &devBufferSize); - if (picDevBuffer == nullptr) { - ERROR_LOG("get pic device buffer failed,index is %zu", index); - return FAILED; - } - std::vector<void *> inputBuffers({picDevBuffer, inputShapeBuffer}); - std::vector<size_t> inputSizes({devBufferSize, 8}); - ret = processModel.CreateInput(inputBuffers, inputSizes); - if (ret != SUCCESS) { - ERROR_LOG("execute CreateInput failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - ret = processModel.Execute(); - if (ret != SUCCESS) { - ERROR_LOG("execute inference failed"); - aclrtFree(picDevBuffer); - return FAILED; - } - - int pos = testFile[index].find_last_of('/'); - std::string name = testFile[index].substr(pos+1); - std::string outputname = name.substr(0, name.rfind(".")); - - // print the top 5 confidence values - processModel.OutputModelResult(); - // dump output result to file in the current directory - processModel.DumpModelOutputResult(const_cast<char *>(outputname.c_str())); - - // release model input buffer - aclrtFree(picDevBuffer); - processModel.DestroyInput(); - } - // loop end - - return SUCCESS; -} - -void SampleProcess::DestroyResource() { - aclError ret; - if (stream_ != nullptr) { - ret = aclrtDestroyStream(stream_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy stream failed"); - } - stream_ = nullptr; - } - INFO_LOG("end to destroy stream"); - - if (context_ != nullptr) { - ret = aclrtDestroyContext(context_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("destroy context failed"); - } - context_ = nullptr; - } - INFO_LOG("end to destroy context"); - - ret = aclrtResetDevice(deviceId_); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("reset device failed"); - } - INFO_LOG("end to reset device is %d", deviceId_); - - ret = aclFinalize(); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("finalize acl failed"); - } - INFO_LOG("end to finalize acl"); -} - diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/acl.json b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/acl.json deleted file mode 100644 index 9e26dfeeb6e641a33dae4961196235bdb965b21b..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/acl.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/build.sh b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/build.sh deleted file mode 100644 index b5979b68e60b673f763a3cac98c5e147e7085291..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/build.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -path_cur=$(cd "`dirname $0`" || exit; pwd) - -function preparePath() { - rm -rf $1 - mkdir -p $1 - cd $1 || exit -} - -function buildA300() { - if [ ! "${ARCH_PATTERN}" ]; then - # set ARCH_PATTERN to acllib when it was not specified by user - export ARCH_PATTERN=acllib - echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}" - else - echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user, reset it to ${ARCH_PATTERN}/acllib" - export ARCH_PATTERN=${ARCH_PATTERN}/acllib - fi - - path_build=$path_cur/build - preparePath $path_build - cmake .. - make -j - ret=$? - cd .. - return ${ret} -} - -# set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user -if [ ! "${ASCEND_VERSION}" ]; then - export ASCEND_VERSION=ascend-toolkit/latest - echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}" -else - echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user" -fi - -buildA300 - -if [ $? -ne 0 ]; then - exit 1 -fi diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/main.cpp b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/main.cpp deleted file mode 100644 index 0f1354613bc9ba6b5d4dc6189fe16cdc7d6f4015..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include <gflags/gflags.h> -#include <iostream> -#include <fstream> -#include <memory> -#include "../inc/SampleProcess.h" -#include "../inc/utils.h" - -bool g_isDevice = false; - -DEFINE_string(om_path, "", "om path"); -DEFINE_string(dataset_path, "", "dataset path"); -DEFINE_string(acljson_path, "", "acl json path"); -DEFINE_int32(device_id, 0, "device id"); - -int main(int argc, char **argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - std::string om_path = FLAGS_om_path; - std::string dataset_path = FLAGS_dataset_path; - std::string acljson_path = FLAGS_acljson_path; - int32_t device_id = FLAGS_device_id; - std::ifstream fin(om_path); - if (!fin) { - std::cout << "Invalid om path." << std::endl; - return FAILED; - } - SampleProcess processSample(device_id); - // acl.json is deployed for dump data. - Result ret = processSample.InitResource(acljson_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample init resource failed"); - return FAILED; - } - - ret = processSample.Process(om_path.c_str(), dataset_path.c_str()); - if (ret != SUCCESS) { - ERROR_LOG("sample process failed"); - return FAILED; - } - - INFO_LOG("execute sample success"); - return SUCCESS; -} diff --git a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/utils.cpp b/official/cv/yolov3_darknet53_quant/ascend310_infer/src/utils.cpp deleted file mode 100644 index 6e669f3f329be5ecfba41595c72f525d4fb428d0..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/ascend310_infer/src/utils.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright 2021 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -#include "../inc/utils.h" -#include <sys/stat.h> -#include <iostream> -#include <fstream> -#include <cstring> -#include "acl/acl.h" - -extern bool g_isDevice; - -void* Utils::ReadBinFile(std::string fileName, uint32_t *fileSize) { - struct stat sBuf; - int fileStatus = stat(fileName.data(), &sBuf); - if (fileStatus == -1) { - ERROR_LOG("failed to get file"); - return nullptr; - } - if (S_ISREG(sBuf.st_mode) == 0) { - ERROR_LOG("%s is not a file, please enter a file", fileName.c_str()); - return nullptr; - } - - std::ifstream binFile(fileName, std::ifstream::binary); - if (binFile.is_open() == false) { - ERROR_LOG("open file %s failed", fileName.c_str()); - return nullptr; - } - - binFile.seekg(0, binFile.end); - uint32_t binFileBufferLen = binFile.tellg(); - if (binFileBufferLen == 0) { - ERROR_LOG("binfile is empty, filename is %s", fileName.c_str()); - binFile.close(); - return nullptr; - } - - binFile.seekg(0, binFile.beg); - - void* binFileBufferData = nullptr; - aclError ret = ACL_ERROR_NONE; - if (!g_isDevice) { - ret = aclrtMallocHost(&binFileBufferData, binFileBufferLen); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc for binFileBufferData failed"); - binFile.close(); - return nullptr; - } - if (binFileBufferData == nullptr) { - ERROR_LOG("malloc binFileBufferData failed"); - binFile.close(); - return nullptr; - } - } else { - ret = aclrtMalloc(&binFileBufferData, binFileBufferLen, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", binFileBufferLen); - binFile.close(); - return nullptr; - } - } - binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen); - binFile.close(); - *fileSize = binFileBufferLen; - return binFileBufferData; -} - -void* Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t *fileSize) { - uint32_t inputHostBuffSize = 0; - void* inputHostBuff = Utils::ReadBinFile(fileName, &inputHostBuffSize); - if (inputHostBuff == nullptr) { - return nullptr; - } - if (!g_isDevice) { - void *inBufferDev = nullptr; - uint32_t inBufferSize = inputHostBuffSize; - aclError ret = aclrtMalloc(&inBufferDev, inBufferSize, ACL_MEM_MALLOC_NORMAL_ONLY); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - - ret = aclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, ACL_MEMCPY_HOST_TO_DEVICE); - if (ret != ACL_ERROR_NONE) { - ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u", - inBufferSize, inputHostBuffSize); - aclrtFree(inBufferDev); - aclrtFreeHost(inputHostBuff); - return nullptr; - } - aclrtFreeHost(inputHostBuff); - *fileSize = inBufferSize; - return inBufferDev; - } else { - *fileSize = inputHostBuffSize; - return inputHostBuff; - } -} diff --git a/official/cv/yolov3_darknet53_quant/eval.py b/official/cv/yolov3_darknet53_quant/eval.py deleted file mode 100644 index 0eccd2f439f7f3d7e9719cdadbb291f53274c44a..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/eval.py +++ /dev/null @@ -1,338 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YoloV3 eval.""" -import os -import argparse -import datetime -import time -import sys -from collections import defaultdict - -import numpy as np -from pycocotools.coco import COCO -from pycocotools.cocoeval import COCOeval - -from mindspore import Tensor -from mindspore.context import ParallelMode -from mindspore import context -from mindspore.train.serialization import load_checkpoint, load_param_into_net -import mindspore as ms -from mindspore.compression.quant import QuantizationAwareTraining - -from src.yolo import YOLOV3DarkNet53 -from src.logger import get_logger -from src.yolo_dataset import create_yolo_dataset -from src.config import ConfigYOLOV3DarkNet53 - -devid = int(os.getenv('DEVICE_ID')) -context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", save_graphs=False, device_id=devid) - - -class Redirct: - def __init__(self): - self.content = "" - - def write(self, content): - self.content += content - - def flush(self): - self.content = "" - - -class DetectionEngine: - """Detection engine.""" - def __init__(self, args): - self.ignore_threshold = args.ignore_threshold - self.labels = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', - 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', - 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', - 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', - 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', - 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', - 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', - 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', - 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', - 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'] - self.num_classes = len(self.labels) - self.results = {} - self.file_path = '' - self.save_prefix = args.outputs_dir - self.annFile = args.annFile - self._coco = COCO(self.annFile) - self._img_ids = list(sorted(self._coco.imgs.keys())) - self.det_boxes = [] - self.nms_thresh = args.nms_thresh - self.coco_catIds = self._coco.getCatIds() - - def do_nms_for_results(self): - """Get result boxes.""" - for img_id in self.results: - for clsi in self.results[img_id]: - dets = self.results[img_id][clsi] - dets = np.array(dets) - keep_index = self._nms(dets, self.nms_thresh) - - keep_box = [{'image_id': int(img_id), - 'category_id': int(clsi), - 'bbox': list(dets[i][:4].astype(float)), - 'score': dets[i][4].astype(float)} - for i in keep_index] - self.det_boxes.extend(keep_box) - - def _nms(self, dets, thresh): - """Calculate NMS.""" - # convert xywh -> xmin ymin xmax ymax - x1 = dets[:, 0] - y1 = dets[:, 1] - x2 = x1 + dets[:, 2] - y2 = y1 + dets[:, 3] - scores = dets[:, 4] - - areas = (x2 - x1 + 1) * (y2 - y1 + 1) - order = scores.argsort()[::-1] - - keep = [] - while order.size > 0: - i = order[0] - keep.append(i) - xx1 = np.maximum(x1[i], x1[order[1:]]) - yy1 = np.maximum(y1[i], y1[order[1:]]) - xx2 = np.minimum(x2[i], x2[order[1:]]) - yy2 = np.minimum(y2[i], y2[order[1:]]) - - w = np.maximum(0.0, xx2 - xx1 + 1) - h = np.maximum(0.0, yy2 - yy1 + 1) - inter = w * h - ovr = inter / (areas[i] + areas[order[1:]] - inter) - - inds = np.where(ovr <= thresh)[0] - order = order[inds + 1] - return keep - - def write_result(self): - """Save result to file.""" - import json - t = datetime.datetime.now().strftime('_%Y_%m_%d_%H_%M_%S') - try: - self.file_path = self.save_prefix + '/predict' + t + '.json' - f = open(self.file_path, 'w') - json.dump(self.det_boxes, f) - except IOError as e: - raise RuntimeError("Unable to open json file to dump. What(): {}".format(str(e))) - else: - f.close() - return self.file_path - - def get_eval_result(self): - """Get eval result.""" - cocoGt = COCO(self.annFile) - cocoDt = cocoGt.loadRes(self.file_path) - cocoEval = COCOeval(cocoGt, cocoDt, 'bbox') - cocoEval.evaluate() - cocoEval.accumulate() - rdct = Redirct() - stdout = sys.stdout - sys.stdout = rdct - cocoEval.summarize() - sys.stdout = stdout - return rdct.content - - def detect(self, outputs, batch, image_shape, image_id): - """Detect boxes.""" - outputs_num = len(outputs) - # output [|32, 52, 52, 3, 85| ] - for batch_id in range(batch): - for out_id in range(outputs_num): - # 32, 52, 52, 3, 85 - out_item = outputs[out_id] - # 52, 52, 3, 85 - out_item_single = out_item[batch_id, :] - # get number of items in one head, [B, gx, gy, anchors, 5+80] - dimensions = out_item_single.shape[:-1] - out_num = 1 - for d in dimensions: - out_num *= d - ori_w, ori_h = image_shape[batch_id] - img_id = int(image_id[batch_id]) - x = out_item_single[..., 0] * ori_w - y = out_item_single[..., 1] * ori_h - w = out_item_single[..., 2] * ori_w - h = out_item_single[..., 3] * ori_h - - conf = out_item_single[..., 4:5] - cls_emb = out_item_single[..., 5:] - - cls_argmax = np.expand_dims(np.argmax(cls_emb, axis=-1), axis=-1) - x = x.reshape(-1) - y = y.reshape(-1) - w = w.reshape(-1) - h = h.reshape(-1) - cls_emb = cls_emb.reshape(-1, 80) - conf = conf.reshape(-1) - cls_argmax = cls_argmax.reshape(-1) - - x_top_left = x - w / 2. - y_top_left = y - h / 2. - # create all False - flag = np.random.random(cls_emb.shape) > sys.maxsize - for i in range(flag.shape[0]): - c = cls_argmax[i] - flag[i, c] = True - confidence = cls_emb[flag] * conf - for x_lefti, y_lefti, wi, hi, confi, clsi in zip(x_top_left, y_top_left, w, h, confidence, cls_argmax): - if confi < self.ignore_threshold: - continue - if img_id not in self.results: - self.results[img_id] = defaultdict(list) - x_lefti = max(0, x_lefti) - y_lefti = max(0, y_lefti) - wi = min(wi, ori_w) - hi = min(hi, ori_h) - # transform catId to match coco - coco_clsi = self.coco_catIds[clsi] - self.results[img_id][coco_clsi].append([x_lefti, y_lefti, wi, hi, confi]) - - -def parse_args(): - """Parse arguments.""" - parser = argparse.ArgumentParser('mindspore coco testing') - - # dataset related - parser.add_argument('--data_dir', type=str, default="", help='Train data dir. Default: ""') - parser.add_argument('--per_batch_size', default=1, type=int, help='Batch size for per device, Default: 1') - - # network related - parser.add_argument('--pretrained', default="", type=str,\ - help='The model path, local pretrained model to load, Default: ""') - - # logging related - parser.add_argument('--log_path', type=str, default="outputs/", help='Log save location, Default: "outputs/"') - - # detect_related - parser.add_argument('--nms_thresh', type=float, default=0.5, help='Threshold for NMS. Default: 0.5') - parser.add_argument('--annFile', type=str, default="", help='The path to annotation. Default: ""') - parser.add_argument('--testing_shape', type=str, default="", help='Shape for test. Default: ""') - parser.add_argument('--ignore_threshold', type=float, default=0.001,\ - help='Threshold to throw low quality boxes, Default: 0.001') - - args, _ = parser.parse_known_args() - - args.data_root = os.path.join(args.data_dir, 'val2014') - args.annFile = os.path.join(args.data_dir, 'annotations/instances_val2014.json') - - return args - - -def conver_testing_shape(args): - """Convert testing shape to list.""" - testing_shape = [int(args.testing_shape), int(args.testing_shape)] - return testing_shape - - -def test(): - """The function of eval.""" - start_time = time.time() - args = parse_args() - - # logger - args.outputs_dir = os.path.join(args.log_path, - datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S')) - rank_id = int(os.environ.get('RANK_ID')) - args.logger = get_logger(args.outputs_dir, rank_id) - - context.reset_auto_parallel_context() - parallel_mode = ParallelMode.STAND_ALONE - context.set_auto_parallel_context(parallel_mode=parallel_mode, gradients_mean=True, device_num=1) - - args.logger.info('Creating Network....') - network = YOLOV3DarkNet53(is_training=False) - - config = ConfigYOLOV3DarkNet53() - if args.testing_shape: - config.test_img_shape = conver_testing_shape(args) - - # convert fusion network to quantization aware network - if config.quantization_aware: - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, False]) - network = quantizer.quantize(network) - - args.logger.info(args.pretrained) - if os.path.isfile(args.pretrained): - param_dict = load_checkpoint(args.pretrained) - param_dict_new = {} - for key, values in param_dict.items(): - if key.startswith('moments.'): - continue - elif key.startswith('yolo_network.'): - param_dict_new[key[13:]] = values - else: - param_dict_new[key] = values - load_param_into_net(network, param_dict_new) - args.logger.info('load_model {} success'.format(args.pretrained)) - else: - args.logger.info('{} not exists or not a pre-trained file'.format(args.pretrained)) - assert FileNotFoundError('{} not exists or not a pre-trained file'.format(args.pretrained)) - exit(1) - - data_root = args.data_root - ann_file = args.annFile - - ds, data_size = create_yolo_dataset(data_root, ann_file, is_training=False, batch_size=args.per_batch_size, - max_epoch=1, device_num=1, rank=rank_id, shuffle=False, - config=config) - - args.logger.info('testing shape : {}'.format(config.test_img_shape)) - args.logger.info('totol {} images to eval'.format(data_size)) - - network.set_train(False) - - # init detection engine - detection = DetectionEngine(args) - - input_shape = Tensor(tuple(config.test_img_shape), ms.float32) - args.logger.info('Start inference....') - for i, data in enumerate(ds.create_dict_iterator(num_epochs=1)): - image = data["image"] - - image_shape = data["image_shape"] - image_id = data["img_id"] - - prediction = network(image, input_shape) - output_big, output_me, output_small = prediction - output_big = output_big.asnumpy() - output_me = output_me.asnumpy() - output_small = output_small.asnumpy() - image_id = image_id.asnumpy() - image_shape = image_shape.asnumpy() - - detection.detect([output_small, output_me, output_big], args.per_batch_size, image_shape, image_id) - if i % 1000 == 0: - args.logger.info('Processing... {:.2f}% '.format(i * args.per_batch_size / data_size * 100)) - - args.logger.info('Calculating mAP...') - detection.do_nms_for_results() - result_file_path = detection.write_result() - args.logger.info('result file path: {}'.format(result_file_path)) - eval_result = detection.get_eval_result() - - cost_time = time.time() - start_time - args.logger.info('\n=============coco eval reulst=========\n' + eval_result) - args.logger.info('testing cost time {:.2f}h'.format(cost_time / 3600.)) - - -if __name__ == "__main__": - test() diff --git a/official/cv/yolov3_darknet53_quant/export.py b/official/cv/yolov3_darknet53_quant/export.py deleted file mode 100644 index 09856164d2db82ed80b44420061e2e92e59315cd..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/export.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -import argparse -import numpy as np - -import mindspore as ms -from mindspore import context, Tensor -from mindspore.train.serialization import export, load_checkpoint, load_param_into_net -from mindspore.compression.quant import QuantizationAwareTraining - -from src.yolo import YOLOV3DarkNet53 -from src.config import ConfigYOLOV3DarkNet53 - -parser = argparse.ArgumentParser(description='yolov3_darknet53_quant export') -parser.add_argument("--device_id", type=int, default=0, help="Device id") -parser.add_argument("--batch_size", type=int, default=1, help="batch size") -parser.add_argument("--ckpt_file", type=str, required=True, help="Checkpoint file path.") -parser.add_argument("--file_name", type=str, default="yolov3_darknet53_quant", help="output file name.") -parser.add_argument('--file_format', type=str, choices=["AIR", "MINDIR"], default='MINDIR', help='file format') -args = parser.parse_args() - -context.set_context(mode=context.GRAPH_MODE, device_target="Ascend", device_id=args.device_id) - -if __name__ == "__main__": - network = YOLOV3DarkNet53(is_training=False) - config = ConfigYOLOV3DarkNet53() - - if config.quantization_aware: - quantizer = QuantizationAwareTraining(bn_fold=True, per_channel=[True, False], symmetric=[True, False]) - network = quantizer.quantize(network) - - param_dict = load_checkpoint(args.ckpt_file) - load_param_into_net(network, param_dict) - - network.set_train(False) - - shape = [args.batch_size, 3] + config.test_img_shape - input_data = Tensor(np.zeros(shape), ms.float32) - input_shape = Tensor(tuple(config.test_img_shape), ms.float32) - - export(network, input_data, input_shape, file_name=args.file_name, file_format=args.file_format, - quant_mode='QUANT', mean=0., std_dev=48.106) diff --git a/official/cv/yolov3_darknet53_quant/export_bin_file.py b/official/cv/yolov3_darknet53_quant/export_bin_file.py deleted file mode 100644 index ccbad7ff5e7377ee7384243e51de596095ebfd40..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/export_bin_file.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YoloV3_quant export coco bin.""" -import os -import argparse -import datetime -import numpy as np -import mindspore as ms -from mindspore import Tensor -from mindspore.context import ParallelMode -from mindspore import context - -from src.logger import get_logger -from src.yolo_dataset import create_yolo_dataset -from src.config import ConfigYOLOV3DarkNet53 - -def parse_args(): - """Parse arguments.""" - parser = argparse.ArgumentParser('mindspore coco export bin') - parser.add_argument('--device_target', type=str, default="Ascend", - choices=['Ascend', 'GPU'], - help='device where the code will be implemented (default: Ascend)') - # dataset related - parser.add_argument('--data_dir', type=str, default="", help='Eval data dir. Default: ""') - parser.add_argument('--per_batch_size', default=1, type=int, help='Batch size for per device, Default: 1') - - # logging related - parser.add_argument('--log_path', type=str, default="outputs/", help='Log save location, Default: "outputs/"') - parser.add_argument('--save_path', type=str, default="", help='Bin file save location') - - # detect_related - parser.add_argument('--nms_thresh', type=float, default=0.5, help='Threshold for NMS. Default: 0.5') - parser.add_argument('--annFile', type=str, default="", help='The path to annotation. Default: ""') - parser.add_argument('--testing_shape', type=str, default="", help='Shape for test. Default: ""') - - args_, _ = parser.parse_known_args() - - args_.data_root = os.path.join(args_.data_dir, 'val2014') - args_.annFile = os.path.join(args_.data_dir, 'annotations/instances_val2014.json') - - return args_ - -def conver_testing_shape(args_org): - """Convert testing shape to list.""" - testing_shape = [int(args_org.testing_shape), int(args_org.testing_shape)] - return testing_shape - -if __name__ == "__main__": - args = parse_args() - devid = int(os.getenv('DEVICE_ID')) if os.getenv('DEVICE_ID') else 0 - context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, device_id=devid) - - # logger - args.outputs_dir = os.path.join(args.log_path, - datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S')) - rank_id = int(os.environ.get('RANK_ID')) if os.environ.get('RANK_ID') else 0 - args.logger = get_logger(args.outputs_dir, rank_id) - - context.reset_auto_parallel_context() - parallel_mode = ParallelMode.STAND_ALONE - context.set_auto_parallel_context(parallel_mode=parallel_mode, gradients_mean=True, device_num=1) - - config = ConfigYOLOV3DarkNet53() - if args.testing_shape: - config.test_img_shape = conver_testing_shape(args) - data_root = args.data_root - ann_file = args.annFile - - ds, data_size = create_yolo_dataset(data_root, ann_file, is_training=False, batch_size=args.per_batch_size, - max_epoch=1, device_num=1, rank=rank_id, shuffle=False, - config=config) - - args.logger.info('testing shape : {}'.format(config.test_img_shape)) - args.logger.info('totol {} images to eval'.format(data_size)) - - cur_dir = args.save_path - save_folder = os.path.join(cur_dir, "yolov3_quant_coco_310_infer_data") - image_folder = os.path.join(save_folder, "image_bin") - if not os.path.exists(image_folder): - os.makedirs(image_folder) - - list_image_shape = [] - list_image_id = [] - - input_shape = Tensor(tuple(config.test_img_shape), ms.float32) - args.logger.info('Start inference....') - for i, data in enumerate(ds.create_dict_iterator()): - image = data["image"].asnumpy() - image_shape = data["image_shape"] - image_id = data["img_id"] - file_name = "YoloV3-DarkNet_coco_bs_" + str(args.per_batch_size) + "_" + str(i) + ".bin" - file_path = image_folder + "/" + file_name - image.tofile(file_path) - list_image_shape.append(image_shape.asnumpy()) - list_image_id.append(image_id.asnumpy()) - shapes = np.array(list_image_shape) - ids = np.array(list_image_id) - np.save(save_folder + "/image_shape.npy", shapes) - np.save(save_folder + "/image_id.npy", ids) diff --git a/official/cv/yolov3_darknet53_quant/mindspore_hub_conf.py b/official/cv/yolov3_darknet53_quant/mindspore_hub_conf.py deleted file mode 100644 index 658d81b15f37d9be3641c08aab435dd609d477e0..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/mindspore_hub_conf.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""hub config.""" -from mindspore.compression.quant import QuantizationAwareTraining -from src.yolo import YOLOV3DarkNet53 -from src.config import ConfigYOLOV3DarkNet53 - - -def create_network(name, *args, **kwargs): - if name == "yolov3_darknet53_quant": - yolov3_darknet53_quant = YOLOV3DarkNet53(is_training=False) - config = ConfigYOLOV3DarkNet53() - # convert fusion network to quantization aware network - if config.quantization_aware: - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, False]) - yolov3_darknet53_quant = quantizer.quantize(yolov3_darknet53_quant) - return yolov3_darknet53_quant - raise NotImplementedError(f"{name} is not implemented in the repo") diff --git a/official/cv/yolov3_darknet53_quant/postprocess.py b/official/cv/yolov3_darknet53_quant/postprocess.py deleted file mode 100644 index 6ce52b97a2602aca943e2f14e0b6d4d29928609c..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/postprocess.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YoloV3 postprocess.""" -import os -import argparse -import datetime -import numpy as np -from eval import DetectionEngine - -parser = argparse.ArgumentParser('YoloV3_quant postprocess') -parser.add_argument('--result_path', type=str, required=True, help='result files path.') -parser.add_argument('--per_batch_size', default=1, type=int, help='batch size for per gpu') -parser.add_argument('--nms_thresh', type=float, default=0.5, help='threshold for NMS') -parser.add_argument('--annFile', type=str, default='', help='path to annotation') -parser.add_argument('--image_shape', type=str, default='./image_shape.npy', help='path to image_shape.npy') -parser.add_argument('--image_id', type=str, default='./image_id.npy', help='path to image_id.npy') -parser.add_argument('--ignore_threshold', type=float, default=0.001, help='threshold to throw low quality boxes') -parser.add_argument('--log_path', type=str, default='outputs/', help='inference result save location') - -args, _ = parser.parse_known_args() - -if __name__ == "__main__": - args.outputs_dir = os.path.join(args.log_path, - datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S')) - if not os.path.exists(args.outputs_dir): - os.makedirs(args.outputs_dir) - - detection = DetectionEngine(args) - bs = args.per_batch_size - - f_list = os.listdir(args.result_path) - shape_list = np.load(args.image_shape) - id_list = np.load(args.image_id) - prefix = "YoloV3-DarkNet_coco_bs_" + str(bs) + "_" - iter_num = 0 - for image_id in id_list: - image_shape = shape_list[iter_num] - path_small = os.path.join(args.result_path, prefix + str(iter_num) + '_0.bin') - path_medium = os.path.join(args.result_path, prefix + str(iter_num) + '_1.bin') - path_big = os.path.join(args.result_path, prefix + str(iter_num) + '_2.bin') - if os.path.exists(path_small) and os.path.exists(path_medium) and os.path.exists(path_big): - output_small = np.fromfile(path_small, np.float32).reshape(bs, 13, 13, 3, 85) - output_medium = np.fromfile(path_medium, np.float32).reshape(bs, 26, 26, 3, 85) - output_big = np.fromfile(path_big, np.float32).reshape(bs, 52, 52, 3, 85) - detection.detect([output_small, output_medium, output_big], bs, image_shape, image_id) - else: - print("Error: Image ", iter_num, " is not exist.") - iter_num += 1 - - detection.do_nms_for_results() - result_file_path = detection.write_result() - eval_result = detection.get_eval_result() - - print('\n=============coco eval result=========\n' + eval_result) diff --git a/official/cv/yolov3_darknet53_quant/requirements.txt b/official/cv/yolov3_darknet53_quant/requirements.txt deleted file mode 100644 index 5d9508a782ecf235c3c4dcb28de4308e5b787b71..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -numpy -pillow -opencv-python -pycocotools diff --git a/official/cv/yolov3_darknet53_quant/scripts/run_distribute_train.sh b/official/cv/yolov3_darknet53_quant/scripts/run_distribute_train.sh deleted file mode 100644 index fe024c8433923d439776d2775bbdb32801db6053..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/scripts/run_distribute_train.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [ $# != 3 ] -then - echo "Usage: sh run_distribute_train.sh [DATASET_PATH] [RESUME_YOLOV3] [RANK_TABLE_FILE]" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} - -DATASET_PATH=$(get_real_path $1) -RESUME_YOLOV3=$(get_real_path $2) -RANK_TABLE_FILE=$(get_real_path $3) - -echo $DATASET_PATH -echo $RESUME_YOLOV3 -echo $RANK_TABLE_FILE - -if [ ! -d $DATASET_PATH ] -then - echo "error: DATASET_PATH=$DATASET_PATH is not a directory" -exit 1 -fi - -if [ ! -f $RESUME_YOLOV3 ] -then - echo "error: PRETRAINED_PATH=$RESUME_YOLOV3 is not a file" -exit 1 -fi - -if [ ! -f $RANK_TABLE_FILE ] -then - echo "error: RANK_TABLE_FILE=$RANK_TABLE_FILE is not a file" -exit 1 -fi - -export DEVICE_NUM=8 -export RANK_SIZE=8 -export RANK_TABLE_FILE=$RANK_TABLE_FILE - -for((i=0; i<${DEVICE_NUM}; i++)) -do - export DEVICE_ID=$i - export RANK_ID=$i - rm -rf ./train_parallel$i - mkdir ./train_parallel$i - cp ../*.py ./train_parallel$i - cp -r ../src ./train_parallel$i - cd ./train_parallel$i || exit - echo "start training for rank $RANK_ID, device $DEVICE_ID" - env > env.log - python train.py \ - --data_dir=$DATASET_PATH \ - --resume_yolov3=$RESUME_YOLOV3 \ - --is_distributed=1 \ - --per_batch_size=16 \ - --lr=0.012 \ - --T_max=135 \ - --max_epoch=135 \ - --warmup_epochs=5 \ - --lr_scheduler=cosine_annealing > log.txt 2>&1 & - cd .. -done diff --git a/official/cv/yolov3_darknet53_quant/scripts/run_eval.sh b/official/cv/yolov3_darknet53_quant/scripts/run_eval.sh deleted file mode 100644 index 9343f0df46eba5a84c7b7d46be54553d7a209f80..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/scripts/run_eval.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [ $# != 3 ] -then - echo "Usage: sh run_eval.sh [DATASET_PATH] [CHECKPOINT_PATH] [DEVICE_ID]" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} -DATASET_PATH=$(get_real_path $1) -CHECKPOINT_PATH=$(get_real_path $2) -echo $DATASET_PATH -echo $CHECKPOINT_PATH - -if [ ! -d $DATASET_PATH ] -then - echo "error: DATASET_PATH=$PATH1 is not a directory" -exit 1 -fi - -if [ ! -f $CHECKPOINT_PATH ] -then - echo "error: CHECKPOINT_PATH=$PATH2 is not a file" -exit 1 -fi - -export DEVICE_NUM=1 -export DEVICE_ID=$3 -export RANK_SIZE=$DEVICE_NUM -export RANK_ID=0 - -if [ -d "eval$3" ]; -then - rm -rf ./eval$3 -fi - -mkdir ./eval$3 -cp ../*.py ./eval$3 -cp -r ../src ./eval$3 -cd ./eval$3 || exit -env > env.log -echo "start inferring for device $DEVICE_ID" -python eval.py \ - --data_dir=$DATASET_PATH \ - --pretrained=$CHECKPOINT_PATH \ - --testing_shape=416 > log.txt 2>&1 & -cd .. diff --git a/official/cv/yolov3_darknet53_quant/scripts/run_infer_310.sh b/official/cv/yolov3_darknet53_quant/scripts/run_infer_310.sh deleted file mode 100644 index dcbbb38609376bc66e3eac6c1b608f37dba95733..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/scripts/run_infer_310.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [[ $# -lt 5 || $# -gt 6 ]]; then - echo "Usage: bash run_infer_310.sh [AIR_PATH] [DATA_PATH] [ANNO_PATH] [IMAGESHAPE_PATH] [IMAGEID_PATH] [DEVICE_ID] - DEVICE_ID is optional, it can be set by environment variable device_id, otherwise the value is zero" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} -model=$(get_real_path $1) -data_path=$(get_real_path $2) -anno_path=$(get_real_path $3) -image_shape_path=$(get_real_path $4) -image_id_path=$(get_real_path $5) - -device_id=0 -if [ $# == 6 ]; then - device_id=$6 -fi - -echo "air name: "$model -echo "dataset path: "$data_path -echo "annotation path: "$anno_path -echo "image shape path: "$image_shape_path -echo "image id path: "$image_id_path -echo "device id: "$device_id - -export ASCEND_HOME=/usr/local/Ascend/ -if [ -d ${ASCEND_HOME}/ascend-toolkit ]; then - export PATH=$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/ascend-toolkit/latest/atc/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/ascend-toolkit/latest/atc/lib64:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$ASCEND_HOME/add-ons:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=${TBE_IMPL_PATH}:$ASCEND_HOME/ascend-toolkit/latest/fwkacllib/python/site-packages:$PYTHONPATH - export ASCEND_OPP_PATH=$ASCEND_HOME/ascend-toolkit/latest/opp -else - export PATH=$ASCEND_HOME/fwkacllib/ccec_compiler/bin:$ASCEND_HOME/fwkacllib/bin:$PATH - export LD_LIBRARY_PATH=/usr/local/lib:$ASCEND_HOME/fwkacllib/lib64:$ASCEND_HOME/driver/lib64:$LD_LIBRARY_PATH - export TBE_IMPL_PATH=$ASCEND_HOME/opp/op_impl/built-in/ai_core/tbe - export PYTHONPATH=$PYTHONPATH:$TBE_IMPL_PATH - export ASCEND_OPP_PATH=$ASCEND_HOME/opp -fi - -function air_to_om() -{ - atc --input_format=NCHW --framework=1 --model=$model --output=yolov3_darknet53_quant --soc_version=Ascend310 &> atc.log -} - -function compile_app() -{ - cd ../ascend310_infer/src || exit - bash build.sh &> build.log -} - -function infer() -{ - cd - || exit - if [ -d result_Files ]; then - rm -rf ./result_Files - fi - if [ -d time_Result ]; then - rm -rf ./time_Result - fi - mkdir result_Files - mkdir time_Result - - ../ascend310_infer/src/out/main --om_path=./yolov3_darknet53_quant.om --dataset_path=$data_path --acljson_path=../ascend310_infer/src/acl.json --device_id=$device_id &> infer.log - -} - -function cal_acc() -{ - python ../postprocess.py --result_path=./result_Files --img_path=$data_path --annFile=$anno_path --image_shape=$image_shape_path --image_id=$image_id_path &> acc.log -} - -air_to_om -if [ $? -ne 0 ]; then - echo "air to om code failed" - exit 1 -fi - -compile_app -if [ $? -ne 0 ]; then - echo "compile app code failed" - exit 1 -fi -infer -if [ $? -ne 0 ]; then - echo " execute inference failed" - exit 1 -fi -cal_acc -if [ $? -ne 0 ]; then - echo "calculate accuracy failed" - exit 1 -fi diff --git a/official/cv/yolov3_darknet53_quant/scripts/run_standalone_train.sh b/official/cv/yolov3_darknet53_quant/scripts/run_standalone_train.sh deleted file mode 100644 index bf642f9e28cc367f815c95bdbbe34c6a8a1bdd5c..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/scripts/run_standalone_train.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [ $# != 2 ] -then - echo "Usage: sh run_standalone_train.sh [DATASET_PATH] [RESUME_YOLOV3]" -exit 1 -fi - -get_real_path(){ - if [ "${1:0:1}" == "/" ]; then - echo "$1" - else - echo "$(realpath -m $PWD/$1)" - fi -} - -DATASET_PATH=$(get_real_path $1) -echo $DATASET_PATH -RESUME_YOLOV3=$(get_real_path $2) -echo $RESUME_YOLOV3 - -if [ ! -d $DATASET_PATH ] -then - echo "error: DATASET_PATH=$DATASET_PATH is not a directory" -exit 1 -fi - -if [ ! -f $RESUME_YOLOV3 ] -then - echo "error: PRETRAINED_PATH=$RESUME_YOLOV3 is not a file" -exit 1 -fi - -export DEVICE_NUM=1 -export DEVICE_ID=0 -export RANK_ID=0 -export RANK_SIZE=1 - -if [ -d "train" ]; -then - rm -rf ./train -fi -mkdir ./train -cp ../*.py ./train -cp -r ../src ./train -cd ./train || exit -echo "start training for device $DEVICE_ID" -env > env.log - -python train.py \ - --data_dir=$DATASET_PATH \ - --resume_yolov3=$RESUME_YOLOV3 \ - --is_distributed=0 \ - --per_batch_size=16 \ - --lr=0.004 \ - --T_max=135 \ - --max_epoch=135 \ - --warmup_epochs=5 \ - --lr_scheduler=cosine_annealing > log.txt 2>&1 & -cd .. diff --git a/official/cv/yolov3_darknet53_quant/src/__init__.py b/official/cv/yolov3_darknet53_quant/src/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/official/cv/yolov3_darknet53_quant/src/config.py b/official/cv/yolov3_darknet53_quant/src/config.py deleted file mode 100644 index b3bd5d1c0ce521eae82f28df4e61e97ec1470ff2..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/config.py +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Config parameters for Darknet based yolov3_darknet53 models.""" - - -class ConfigYOLOV3DarkNet53: - """ - Config parameters for the yolov3_darknet53. - - Examples: - ConfigYOLOV3DarkNet53() - """ - # train_param - # data augmentation related - hue = 0.1 - saturation = 1.5 - value = 1.5 - jitter = 0.3 - - resize_rate = 1 - multi_scale = [[320, 320], - [352, 352], - [384, 384], - [416, 416], - [448, 448], - [480, 480], - [512, 512], - [544, 544], - [576, 576], - [608, 608] - ] - - num_classes = 80 - max_box = 50 - - backbone_input_shape = [32, 64, 128, 256, 512] - backbone_shape = [64, 128, 256, 512, 1024] - backbone_layers = [1, 2, 8, 8, 4] - - # confidence under ignore_threshold means no object when training - ignore_threshold = 0.7 - - # h->w - anchor_scales = [(10, 13), - (16, 30), - (33, 23), - (30, 61), - (62, 45), - (59, 119), - (116, 90), - (156, 198), - (373, 326)] - out_channel = 255 - - quantization_aware = True - # test_param - test_img_shape = [416, 416] diff --git a/official/cv/yolov3_darknet53_quant/src/darknet.py b/official/cv/yolov3_darknet53_quant/src/darknet.py deleted file mode 100644 index b32f6b74a39a8b2dcbf19262725d347c218999d7..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/darknet.py +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""DarkNet model.""" -import mindspore.nn as nn -from mindspore.ops import operations as P - - -def conv_block(in_channels, - out_channels, - kernel_size, - stride, - dilation=1): - """Get a conv2d batchnorm and relu layer""" - pad_mode = 'same' - padding = 0 - - return nn.Conv2dBnAct(in_channels, out_channels, kernel_size, - stride=stride, - pad_mode=pad_mode, - padding=padding, - dilation=dilation, - has_bn=True, - momentum=0.9, - activation='relu') - - -class ResidualBlock(nn.Cell): - """ - DarkNet V1 residual block definition. - - Args: - in_channels: Integer. Input channel. - out_channels: Integer. Output channel. - - Returns: - Tensor, output tensor. - Examples: - ResidualBlock(3, 208) - """ - expansion = 4 - - def __init__(self, - in_channels, - out_channels): - - super(ResidualBlock, self).__init__() - out_chls = out_channels//2 - self.conv1 = conv_block(in_channels, out_chls, kernel_size=1, stride=1) - self.conv2 = conv_block(out_chls, out_channels, kernel_size=3, stride=1) - self.add = P.Add() - - def construct(self, x): - identity = x - out = self.conv1(x) - out = self.conv2(out) - out = self.add(out, identity) - - return out - - -class DarkNet(nn.Cell): - """ - DarkNet V1 network. - - Args: - block: Cell. Block for network. - layer_nums: List. Numbers of different layers. - in_channels: Integer. Input channel. - out_channels: Integer. Output channel. - detect: Bool. Whether detect or not. Default:False. - - Returns: - Tuple, tuple of output tensor,(f1,f2,f3,f4,f5). - - Examples: - DarkNet(ResidualBlock, - [1, 2, 8, 8, 4], - [32, 64, 128, 256, 512], - [64, 128, 256, 512, 1024], - 100) - """ - def __init__(self, - block, - layer_nums, - in_channels, - out_channels, - detect=False): - super(DarkNet, self).__init__() - - self.outchannel = out_channels[-1] - self.detect = detect - - if not len(layer_nums) == len(in_channels) == len(out_channels) == 5: - raise ValueError("the length of layer_num, inchannel, outchannel list must be 5!") - self.conv0 = conv_block(3, - in_channels[0], - kernel_size=3, - stride=1) - self.conv1 = conv_block(in_channels[0], - out_channels[0], - kernel_size=3, - stride=2) - self.conv2 = conv_block(in_channels[1], - out_channels[1], - kernel_size=3, - stride=2) - self.conv3 = conv_block(in_channels[2], - out_channels[2], - kernel_size=3, - stride=2) - self.conv4 = conv_block(in_channels[3], - out_channels[3], - kernel_size=3, - stride=2) - self.conv5 = conv_block(in_channels[4], - out_channels[4], - kernel_size=3, - stride=2) - - self.layer1 = self._make_layer(block, - layer_nums[0], - in_channel=out_channels[0], - out_channel=out_channels[0]) - self.layer2 = self._make_layer(block, - layer_nums[1], - in_channel=out_channels[1], - out_channel=out_channels[1]) - self.layer3 = self._make_layer(block, - layer_nums[2], - in_channel=out_channels[2], - out_channel=out_channels[2]) - self.layer4 = self._make_layer(block, - layer_nums[3], - in_channel=out_channels[3], - out_channel=out_channels[3]) - self.layer5 = self._make_layer(block, - layer_nums[4], - in_channel=out_channels[4], - out_channel=out_channels[4]) - - def _make_layer(self, block, layer_num, in_channel, out_channel): - """ - Make Layer for DarkNet. - - :param block: Cell. DarkNet block. - :param layer_num: Integer. Layer number. - :param in_channel: Integer. Input channel. - :param out_channel: Integer. Output channel. - - Examples: - _make_layer(ConvBlock, 1, 128, 256) - """ - layers = [] - darkblk = block(in_channel, out_channel) - layers.append(darkblk) - - for _ in range(1, layer_num): - darkblk = block(out_channel, out_channel) - layers.append(darkblk) - - return nn.SequentialCell(layers) - - def construct(self, x): - c1 = self.conv0(x) - c2 = self.conv1(c1) - c3 = self.layer1(c2) - c4 = self.conv2(c3) - c5 = self.layer2(c4) - c6 = self.conv3(c5) - c7 = self.layer3(c6) - c8 = self.conv4(c7) - c9 = self.layer4(c8) - c10 = self.conv5(c9) - c11 = self.layer5(c10) - if self.detect: - return c7, c9, c11 - - return c11 - - def get_out_channels(self): - return self.outchannel - - -def darknet53(): - """ - Get DarkNet53 neural network. - - Returns: - Cell, cell instance of DarkNet53 neural network. - - Examples: - darknet53() - """ - return DarkNet(ResidualBlock, [1, 2, 8, 8, 4], - [32, 64, 128, 256, 512], - [64, 128, 256, 512, 1024]) diff --git a/official/cv/yolov3_darknet53_quant/src/distributed_sampler.py b/official/cv/yolov3_darknet53_quant/src/distributed_sampler.py deleted file mode 100644 index 265999430fc867395dbe55231ba0014a645fc329..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/distributed_sampler.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Yolo dataset distributed sampler.""" -from __future__ import division -import math -import numpy as np - - -class DistributedSampler: - """Distributed sampler.""" - def __init__(self, dataset_size, num_replicas=None, rank=None, shuffle=True): - if num_replicas is None: - print("***********Setting world_size to 1 since it is not passed in ******************") - num_replicas = 1 - if rank is None: - print("***********Setting rank to 0 since it is not passed in ******************") - rank = 0 - self.dataset_size = dataset_size - self.num_replicas = num_replicas - self.rank = rank - self.epoch = 0 - self.num_samples = int(math.ceil(dataset_size * 1.0 / self.num_replicas)) - self.total_size = self.num_samples * self.num_replicas - self.shuffle = shuffle - - def __iter__(self): - # deterministically shuffle based on epoch - if self.shuffle: - indices = np.random.RandomState(seed=self.epoch).permutation(self.dataset_size) - # np.array type. number from 0 to len(dataset_size)-1, used as index of dataset - indices = indices.tolist() - self.epoch += 1 - # change to list type - else: - indices = list(range(self.dataset_size)) - - # add extra samples to make it evenly divisible - indices += indices[:(self.total_size - len(indices))] - assert len(indices) == self.total_size - - # subsample - indices = indices[self.rank:self.total_size:self.num_replicas] - assert len(indices) == self.num_samples - - return iter(indices) - - def __len__(self): - return self.num_samples diff --git a/official/cv/yolov3_darknet53_quant/src/initializer.py b/official/cv/yolov3_darknet53_quant/src/initializer.py deleted file mode 100644 index c12c73e2869139bd401fe8c2f756f6ba6261223e..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/initializer.py +++ /dev/null @@ -1,225 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Parameter init.""" -import math -import numpy as np -from mindspore.common import initializer as init -from mindspore.common.initializer import Initializer as MeInitializer -import mindspore.nn as nn -from mindspore import Tensor -from mindspore.train.serialization import load_checkpoint, load_param_into_net - - -def calculate_gain(nonlinearity, param=None): - r"""Return the recommended gain value for the given nonlinearity function. - The values are as follows: - - ================= ==================================================== - nonlinearity gain - ================= ==================================================== - Linear / Identity :math:`1` - Conv{1,2,3}D :math:`1` - Sigmoid :math:`1` - Tanh :math:`\frac{5}{3}` - ReLU :math:`\sqrt{2}` - Leaky Relu :math:`\sqrt{\frac{2}{1 + \text{negative\_slope}^2}}` - ================= ==================================================== - - Args: - nonlinearity: the non-linear function (`nn.functional` name) - param: optional parameter for the non-linear function - - Examples: - >>> gain = nn.init.calculate_gain('leaky_relu', 0.2) # leaky_relu with negative_slope=0.2 - """ - linear_fns = ['linear', 'conv1d', 'conv2d', 'conv3d', 'conv_transpose1d', 'conv_transpose2d', 'conv_transpose3d'] - if nonlinearity in linear_fns or nonlinearity == 'sigmoid': - return 1 - if nonlinearity == 'tanh': - return 5.0 / 3 - if nonlinearity == 'relu': - return math.sqrt(2.0) - if nonlinearity == 'leaky_relu': - if param is None: - negative_slope = 0.01 - elif not isinstance(param, bool) and isinstance(param, int) or isinstance(param, float): - # True/False are instances of int, hence check above - negative_slope = param - else: - raise ValueError("negative_slope {} not a valid number".format(param)) - return math.sqrt(2.0 / (1 + negative_slope ** 2)) - - raise ValueError("Unsupported nonlinearity {}".format(nonlinearity)) - - -def _assignment(arr, num): - """Assign the value of 'num' and 'arr'.""" - if arr.shape == (): - arr = arr.reshape((1)) - arr[:] = num - arr = arr.reshape(()) - else: - if isinstance(num, np.ndarray): - arr[:] = num[:] - else: - arr[:] = num - return arr - - -def _calculate_correct_fan(array, mode): - mode = mode.lower() - valid_modes = ['fan_in', 'fan_out'] - if mode not in valid_modes: - raise ValueError("Mode {} not supported, please use one of {}".format(mode, valid_modes)) - - fan_in, fan_out = _calculate_fan_in_and_fan_out(array) - return fan_in if mode == 'fan_in' else fan_out - - -def kaiming_uniform_(arr, a=0, mode='fan_in', nonlinearity='leaky_relu'): - r"""Fills the input `Tensor` with values according to the method - described in `Delving deep into rectifiers: Surpassing human-level - performance on ImageNet classification` - He, K. et al. (2015), using a - uniform distribution. The resulting tensor will have values sampled from - :math:`\mathcal{U}(-\text{bound}, \text{bound})` where - - .. math:: - \text{bound} = \text{gain} \times \sqrt{\frac{3}{\text{fan\_mode}}} - - Also known as He initialization. - - Args: - tensor: an n-dimensional `Tensor` - a: the negative slope of the rectifier used after this layer (only - used with ``'leaky_relu'``) - mode: either ``'fan_in'`` (default) or ``'fan_out'``. Choosing ``'fan_in'`` - preserves the magnitude of the variance of the weights in the - forward pass. Choosing ``'fan_out'`` preserves the magnitudes in the - backwards pass. - nonlinearity: the non-linear function (`nn.functional` name), - recommended to use only with ``'relu'`` or ``'leaky_relu'`` (default). - - Examples: - >>> w = np.empty(3, 5) - >>> nn.init.kaiming_uniform_(w, mode='fan_in', nonlinearity='relu') - """ - fan = _calculate_correct_fan(arr, mode) - gain = calculate_gain(nonlinearity, a) - std = gain / math.sqrt(fan) - bound = math.sqrt(3.0) * std # Calculate uniform bounds from standard deviation - return np.random.uniform(-bound, bound, arr.shape) - - -def _calculate_fan_in_and_fan_out(arr): - """Calculate fan in and fan out.""" - dimensions = len(arr.shape) - if dimensions < 2: - raise ValueError("Fan in and fan out can not be computed for array with fewer than 2 dimensions") - - num_input_fmaps = arr.shape[1] - num_output_fmaps = arr.shape[0] - receptive_field_size = 1 - if dimensions > 2: - receptive_field_size = arr[0][0].size - fan_in = num_input_fmaps * receptive_field_size - fan_out = num_output_fmaps * receptive_field_size - - return fan_in, fan_out - - -class KaimingUniform(MeInitializer): - """Kaiming uniform initializer.""" - def __init__(self, a=0, mode='fan_in', nonlinearity='leaky_relu'): - super(KaimingUniform, self).__init__() - self.a = a - self.mode = mode - self.nonlinearity = nonlinearity - - def _initialize(self, arr): - tmp = kaiming_uniform_(arr, self.a, self.mode, self.nonlinearity) - _assignment(arr, tmp) - - -def default_recurisive_init(custom_cell): - """Initialize parameter.""" - for _, cell in custom_cell.cells_and_names(): - if isinstance(cell, nn.Conv2d): - cell.weight.set_data(init.initializer(KaimingUniform(a=math.sqrt(5)), - cell.weight.data.shape, - cell.weight.data.dtype)) - if cell.bias is not None: - fan_in, _ = _calculate_fan_in_and_fan_out(cell.weight.data.asnumpy()) - bound = 1 / math.sqrt(fan_in) - cell.bias.set_data(Tensor(np.random.uniform(-bound, bound, cell.bias.data.shape), - cell.bias.data.dtype)) - elif isinstance(cell, nn.Dense): - cell.weight.set_data(init.initializer(KaimingUniform(a=math.sqrt(5)), - cell.weight.data.shape, - cell.weight.data.dtype)) - if cell.bias is not None: - fan_in, _ = _calculate_fan_in_and_fan_out(cell.weight.data.asnumpy()) - bound = 1 / math.sqrt(fan_in) - cell.bias.set_data(Tensor(np.random.uniform(-bound, bound, cell.bias.data.shape), - cell.bias.data.dtype)) - elif isinstance(cell, (nn.BatchNorm2d, nn.BatchNorm1d)): - pass - -def load_yolov3_quant_params(args, network): - """Load quant yolov3 darknet parameter from checkpoint.""" - if args.resume_yolov3: - param_dict = load_checkpoint(args.resume_yolov3) - param_dict_new = {} - for key, values in param_dict.items(): - args.logger.info('ckpt param name = {}'.format(key)) - if key.startswith('moments.') or key.startswith('global_') or \ - key.startswith('learning_rate') or key.startswith('momentum'): - continue - elif key.startswith('yolo_network.'): - key_new = key[13:] - - if key_new.endswith('1.beta'): - key_new = key_new.replace('1.beta', 'batchnorm.beta') - - if key_new.endswith('1.gamma'): - key_new = key_new.replace('1.gamma', 'batchnorm.gamma') - - if key_new.endswith('1.moving_mean'): - key_new = key_new.replace('1.moving_mean', 'batchnorm.moving_mean') - - if key_new.endswith('1.moving_variance'): - key_new = key_new.replace('1.moving_variance', 'batchnorm.moving_variance') - - if key_new.endswith('.weight'): - if key_new.endswith('0.weight'): - key_new = key_new.replace('0.weight', 'conv.weight') - else: - key_new = key_new.replace('.weight', '.conv.weight') - - if key_new.endswith('.bias'): - key_new = key_new.replace('.bias', '.conv.bias') - param_dict_new[key_new] = values - - args.logger.info('in resume {}'.format(key_new)) - else: - param_dict_new[key] = values - args.logger.info('in resume {}'.format(key)) - - args.logger.info('resume finished') - for _, param in network.parameters_and_names(): - args.logger.info('network param name = {}'.format(param.name)) - if param.name not in param_dict_new: - args.logger.info('not match param name = {}'.format(param.name)) - load_param_into_net(network, param_dict_new) - args.logger.info('load_model {} success'.format(args.resume_yolov3)) diff --git a/official/cv/yolov3_darknet53_quant/src/logger.py b/official/cv/yolov3_darknet53_quant/src/logger.py deleted file mode 100644 index b41ab405fc05054775613be8a93357009ac33521..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/logger.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Custom Logger.""" -import os -import sys -import logging -from datetime import datetime - - -class LOGGER(logging.Logger): - """ - Logger. - - Args: - logger_name: String. Logger name. - rank: Integer. Rank id. - """ - def __init__(self, logger_name, rank=0): - super(LOGGER, self).__init__(logger_name) - self.rank = rank - if rank % 8 == 0: - console = logging.StreamHandler(sys.stdout) - console.setLevel(logging.INFO) - formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s') - console.setFormatter(formatter) - self.addHandler(console) - - def setup_logging_file(self, log_dir, rank=0): - """Setup logging file.""" - self.rank = rank - if not os.path.exists(log_dir): - os.makedirs(log_dir, exist_ok=True) - log_name = datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S') + '_rank_{}.log'.format(rank) - self.log_fn = os.path.join(log_dir, log_name) - fh = logging.FileHandler(self.log_fn) - fh.setLevel(logging.INFO) - formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s') - fh.setFormatter(formatter) - self.addHandler(fh) - - def info(self, msg, *args, **kwargs): - if self.isEnabledFor(logging.INFO): - self._log(logging.INFO, msg, args, **kwargs) - - def save_args(self, args): - self.info('Args:') - args_dict = vars(args) - for key in args_dict.keys(): - self.info('--> %s: %s', key, args_dict[key]) - self.info('') - - def important_info(self, msg, *args, **kwargs): - if self.isEnabledFor(logging.INFO) and self.rank == 0: - line_width = 2 - important_msg = '\n' - important_msg += ('*'*70 + '\n')*line_width - important_msg += ('*'*line_width + '\n')*2 - important_msg += '*'*line_width + ' '*8 + msg + '\n' - important_msg += ('*'*line_width + '\n')*2 - important_msg += ('*'*70 + '\n')*line_width - self.info(important_msg, *args, **kwargs) - - -def get_logger(path, rank): - """Get Logger.""" - logger = LOGGER('yolov3_darknet53', rank) - logger.setup_logging_file(path, rank) - return logger diff --git a/official/cv/yolov3_darknet53_quant/src/loss.py b/official/cv/yolov3_darknet53_quant/src/loss.py deleted file mode 100644 index acdc6dba604c31593253f1be360de78e3b99fdf4..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/loss.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YOLOV3 loss.""" -from mindspore.ops import operations as P -import mindspore.nn as nn - - -class XYLoss(nn.Cell): - """Loss for x and y.""" - def __init__(self): - super(XYLoss, self).__init__() - self.cross_entropy = P.SigmoidCrossEntropyWithLogits() - self.reduce_sum = P.ReduceSum() - - def construct(self, object_mask, box_loss_scale, predict_xy, true_xy): - xy_loss = object_mask * box_loss_scale * self.cross_entropy(predict_xy, true_xy) - xy_loss = self.reduce_sum(xy_loss, ()) - return xy_loss - - -class WHLoss(nn.Cell): - """Loss for w and h.""" - def __init__(self): - super(WHLoss, self).__init__() - self.square = P.Square() - self.reduce_sum = P.ReduceSum() - - def construct(self, object_mask, box_loss_scale, predict_wh, true_wh): - wh_loss = object_mask * box_loss_scale * 0.5 * P.Square()(true_wh - predict_wh) - wh_loss = self.reduce_sum(wh_loss, ()) - return wh_loss - - -class ConfidenceLoss(nn.Cell): - """Loss for confidence.""" - def __init__(self): - super(ConfidenceLoss, self).__init__() - self.cross_entropy = P.SigmoidCrossEntropyWithLogits() - self.reduce_sum = P.ReduceSum() - - def construct(self, object_mask, predict_confidence, ignore_mask): - confidence_loss = self.cross_entropy(predict_confidence, object_mask) - confidence_loss = object_mask * confidence_loss + (1 - object_mask) * confidence_loss * ignore_mask - confidence_loss = self.reduce_sum(confidence_loss, ()) - return confidence_loss - - -class ClassLoss(nn.Cell): - """Loss for classification.""" - def __init__(self): - super(ClassLoss, self).__init__() - self.cross_entropy = P.SigmoidCrossEntropyWithLogits() - self.reduce_sum = P.ReduceSum() - - def construct(self, object_mask, predict_class, class_probs): - class_loss = object_mask * self.cross_entropy(predict_class, class_probs) - class_loss = self.reduce_sum(class_loss, ()) - return class_loss diff --git a/official/cv/yolov3_darknet53_quant/src/lr_scheduler.py b/official/cv/yolov3_darknet53_quant/src/lr_scheduler.py deleted file mode 100644 index 597769614283d6b23b68d717d9303c32ea8686e2..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/lr_scheduler.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Learning rate scheduler.""" -import math -from collections import Counter - -import numpy as np - - -def linear_warmup_lr(current_step, warmup_steps, base_lr, init_lr): - """Linear learning rate.""" - lr_inc = (float(base_lr) - float(init_lr)) / float(warmup_steps) - lr = float(init_lr) + lr_inc * current_step - return lr - - -def warmup_step_lr(lr, lr_epochs, steps_per_epoch, warmup_epochs, max_epoch, gamma=0.1): - """Warmup step learning rate.""" - base_lr = lr - warmup_init_lr = 0 - total_steps = int(max_epoch * steps_per_epoch) - warmup_steps = int(warmup_epochs * steps_per_epoch) - milestones = lr_epochs - milestones_steps = [] - for milestone in milestones: - milestones_step = milestone * steps_per_epoch - milestones_steps.append(milestones_step) - - lr_each_step = [] - lr = base_lr - milestones_steps_counter = Counter(milestones_steps) - for i in range(total_steps): - if i < warmup_steps: - lr = linear_warmup_lr(i + 1, warmup_steps, base_lr, warmup_init_lr) - else: - lr = lr * gamma**milestones_steps_counter[i] - lr_each_step.append(lr) - - return np.array(lr_each_step).astype(np.float32) - - -def multi_step_lr(lr, milestones, steps_per_epoch, max_epoch, gamma=0.1): - return warmup_step_lr(lr, milestones, steps_per_epoch, 0, max_epoch, gamma=gamma) - - -def step_lr(lr, epoch_size, steps_per_epoch, max_epoch, gamma=0.1): - lr_epochs = [] - for i in range(1, max_epoch): - if i % epoch_size == 0: - lr_epochs.append(i) - return multi_step_lr(lr, lr_epochs, steps_per_epoch, max_epoch, gamma=gamma) - - -def warmup_cosine_annealing_lr(lr, steps_per_epoch, warmup_epochs, max_epoch, T_max, eta_min=0): - """Cosine annealing learning rate.""" - base_lr = lr - total_steps = int(max_epoch * steps_per_epoch) - warmup_steps = int(warmup_epochs * steps_per_epoch) - - lr_each_step = [] - for i in range(total_steps): - last_epoch = i // steps_per_epoch - if i < warmup_steps: - lr = 0 - else: - lr = eta_min + (base_lr - eta_min) * (1. + math.cos(math.pi*last_epoch / T_max)) / 2 - lr_each_step.append(lr) - - return np.array(lr_each_step).astype(np.float32) - - -def warmup_cosine_annealing_lr_V2(lr, steps_per_epoch, warmup_epochs, max_epoch, T_max, eta_min=0): - """Cosine annealing learning rate V2.""" - base_lr = lr - warmup_init_lr = 0 - total_steps = int(max_epoch * steps_per_epoch) - warmup_steps = int(warmup_epochs * steps_per_epoch) - - last_lr = 0 - last_epoch_V1 = 0 - - T_max_V2 = int(max_epoch*1/3) - - lr_each_step = [] - for i in range(total_steps): - last_epoch = i // steps_per_epoch - if i < warmup_steps: - lr = linear_warmup_lr(i + 1, warmup_steps, base_lr, warmup_init_lr) - else: - if i < total_steps*2/3: - lr = eta_min + (base_lr - eta_min) * (1. + math.cos(math.pi*last_epoch / T_max)) / 2 - last_lr = lr - last_epoch_V1 = last_epoch - else: - base_lr = last_lr - last_epoch = last_epoch-last_epoch_V1 - lr = eta_min + (base_lr - eta_min) * (1. + math.cos(math.pi * last_epoch / T_max_V2)) / 2 - - lr_each_step.append(lr) - return np.array(lr_each_step).astype(np.float32) - - -def warmup_cosine_annealing_lr_sample(lr, steps_per_epoch, warmup_epochs, max_epoch, T_max, eta_min=0): - """Warmup cosine annealing learning rate.""" - start_sample_epoch = 60 - step_sample = 2 - tobe_sampled_epoch = 60 - end_sampled_epoch = start_sample_epoch + step_sample*tobe_sampled_epoch - max_sampled_epoch = max_epoch+tobe_sampled_epoch - T_max = max_sampled_epoch - - base_lr = lr - warmup_init_lr = 0 - total_steps = int(max_epoch * steps_per_epoch) - total_sampled_steps = int(max_sampled_epoch * steps_per_epoch) - warmup_steps = int(warmup_epochs * steps_per_epoch) - - lr_each_step = [] - - for i in range(total_sampled_steps): - last_epoch = i // steps_per_epoch - if last_epoch in range(start_sample_epoch, end_sampled_epoch, step_sample): - continue - if i < warmup_steps: - lr = linear_warmup_lr(i + 1, warmup_steps, base_lr, warmup_init_lr) - else: - lr = eta_min + (base_lr - eta_min) * (1. + math.cos(math.pi*last_epoch / T_max)) / 2 - lr_each_step.append(lr) - - assert total_steps == len(lr_each_step) - return np.array(lr_each_step).astype(np.float32) - - -def get_lr(args): - """generate learning rate.""" - if args.lr_scheduler == 'exponential': - lr = warmup_step_lr(args.lr, - args.lr_epochs, - args.steps_per_epoch, - args.warmup_epochs, - args.max_epoch, - gamma=args.lr_gamma, - ) - elif args.lr_scheduler == 'cosine_annealing': - lr = warmup_cosine_annealing_lr(args.lr, - args.steps_per_epoch, - args.warmup_epochs, - args.max_epoch, - args.T_max, - args.eta_min) - elif args.lr_scheduler == 'cosine_annealing_V2': - lr = warmup_cosine_annealing_lr_V2(args.lr, - args.steps_per_epoch, - args.warmup_epochs, - args.max_epoch, - args.T_max, - args.eta_min) - elif args.lr_scheduler == 'cosine_annealing_sample': - lr = warmup_cosine_annealing_lr_sample(args.lr, - args.steps_per_epoch, - args.warmup_epochs, - args.max_epoch, - args.T_max, - args.eta_min) - else: - raise NotImplementedError(args.lr_scheduler) - return lr diff --git a/official/cv/yolov3_darknet53_quant/src/transforms.py b/official/cv/yolov3_darknet53_quant/src/transforms.py deleted file mode 100644 index 83efe6cd7f3bf08dd708a9a07cb9ca0e08834a51..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/transforms.py +++ /dev/null @@ -1,577 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Preprocess dataset.""" -import random -import threading -import copy - -import numpy as np -from PIL import Image -import cv2 - - -def _rand(a=0., b=1.): - return np.random.rand() * (b - a) + a - - -def bbox_iou(bbox_a, bbox_b, offset=0): - """Calculate Intersection-Over-Union(IOU) of two bounding boxes. - - Parameters - ---------- - bbox_a : numpy.ndarray - An ndarray with shape :math:`(N, 4)`. - bbox_b : numpy.ndarray - An ndarray with shape :math:`(M, 4)`. - offset : float or int, default is 0 - The ``offset`` is used to control the whether the width(or height) is computed as - (right - left + ``offset``). - Note that the offset must be 0 for normalized bboxes, whose ranges are in ``[0, 1]``. - - Returns - ------- - numpy.ndarray - An ndarray with shape :math:`(N, M)` indicates IOU between each pairs of - bounding boxes in `bbox_a` and `bbox_b`. - - """ - if bbox_a.shape[1] < 4 or bbox_b.shape[1] < 4: - raise IndexError("Bounding boxes axis 1 must have at least length 4") - - tl = np.maximum(bbox_a[:, None, :2], bbox_b[:, :2]) - br = np.minimum(bbox_a[:, None, 2:4], bbox_b[:, 2:4]) - - area_i = np.prod(br - tl + offset, axis=2) * (tl < br).all(axis=2) - area_a = np.prod(bbox_a[:, 2:4] - bbox_a[:, :2] + offset, axis=1) - area_b = np.prod(bbox_b[:, 2:4] - bbox_b[:, :2] + offset, axis=1) - return area_i / (area_a[:, None] + area_b - area_i) - - -def statistic_normalize_img(img, statistic_norm): - """Statistic normalize images.""" - # img: RGB - if isinstance(img, Image.Image): - img = np.array(img) - img = img/255. - mean = np.array([0.485, 0.456, 0.406]) - std = np.array([0.229, 0.224, 0.225]) - if statistic_norm: - img = (img - mean) / std - return img - - -def get_interp_method(interp, sizes=()): - """Get the interpolation method for resize functions. - The major purpose of this function is to wrap a random interp method selection - and a auto-estimation method. - - Parameters - ---------- - interp : int - interpolation method for all resizing operations - - Possible values: - 0: Nearest Neighbors Interpolation. - 1: Bilinear interpolation. - 2: Bicubic interpolation over 4x4 pixel neighborhood. - 3: Nearest Neighbors. [Originally it should be Area-based, - as we cannot find Area-based, so we use NN instead. - Area-based (resampling using pixel area relation). It may be a - preferred method for image decimation, as it gives moire-free - results. But when the image is zoomed, it is similar to the Nearest - Neighbors method. (used by default). - 4: Lanczos interpolation over 8x8 pixel neighborhood. - 9: Cubic for enlarge, area for shrink, bilinear for others - 10: Random select from interpolation method mentioned above. - Note: - When shrinking an image, it will generally look best with AREA-based - interpolation, whereas, when enlarging an image, it will generally look best - with Bicubic (slow) or Bilinear (faster but still looks OK). - More details can be found in the documentation of OpenCV, please refer to - http://docs.opencv.org/master/da/d54/group__imgproc__transform.html. - sizes : tuple of int - (old_height, old_width, new_height, new_width), if None provided, auto(9) - will return Area(2) anyway. - - Returns - ------- - int - interp method from 0 to 4 - """ - if interp == 9: - if sizes: - assert len(sizes) == 4 - oh, ow, nh, nw = sizes - if nh > oh and nw > ow: - return 2 - if nh < oh and nw < ow: - return 0 - return 1 - return 2 - if interp == 10: - return random.randint(0, 4) - if interp not in (0, 1, 2, 3, 4): - raise ValueError('Unknown interp method %d' % interp) - return interp - - -def pil_image_reshape(interp): - """Reshape pil image.""" - reshape_type = { - 0: Image.NEAREST, - 1: Image.BILINEAR, - 2: Image.BICUBIC, - 3: Image.NEAREST, - 4: Image.LANCZOS, - } - return reshape_type[interp] - - -def _preprocess_true_boxes(true_boxes, anchors, in_shape, num_classes, - max_boxes, label_smooth, label_smooth_factor=0.1): - """Preprocess annotation boxes.""" - anchors = np.array(anchors) - num_layers = anchors.shape[0] // 3 - anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2]] - true_boxes = np.array(true_boxes, dtype='float32') - input_shape = np.array(in_shape, dtype='int32') - boxes_xy = (true_boxes[..., 0:2] + true_boxes[..., 2:4]) // 2. - # trans to box center point - boxes_wh = true_boxes[..., 2:4] - true_boxes[..., 0:2] - # input_shape is [h, w] - true_boxes[..., 0:2] = boxes_xy / input_shape[::-1] - true_boxes[..., 2:4] = boxes_wh / input_shape[::-1] - # true_boxes [x, y, w, h] - - grid_shapes = [input_shape // 32, input_shape // 16, input_shape // 8] - # grid_shape [h, w] - y_true = [np.zeros((grid_shapes[l][0], grid_shapes[l][1], len(anchor_mask[l]), - 5 + num_classes), dtype='float32') for l in range(num_layers)] - # y_true [gridy, gridx] - anchors = np.expand_dims(anchors, 0) - anchors_max = anchors / 2. - anchors_min = -anchors_max - valid_mask = boxes_wh[..., 0] > 0 - - wh = boxes_wh[valid_mask] - if wh.size > 0: - wh = np.expand_dims(wh, -2) - boxes_max = wh / 2. - boxes_min = -boxes_max - - intersect_min = np.maximum(boxes_min, anchors_min) - intersect_max = np.minimum(boxes_max, anchors_max) - intersect_wh = np.maximum(intersect_max - intersect_min, 0.) - intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1] - box_area = wh[..., 0] * wh[..., 1] - anchor_area = anchors[..., 0] * anchors[..., 1] - iou = intersect_area / (box_area + anchor_area - intersect_area) - - best_anchor = np.argmax(iou, axis=-1) - for t, n in enumerate(best_anchor): - for l in range(num_layers): - if n in anchor_mask[l]: - i = np.floor(true_boxes[t, 0] * grid_shapes[l][1]).astype('int32') # grid_y - j = np.floor(true_boxes[t, 1] * grid_shapes[l][0]).astype('int32') # grid_x - - k = anchor_mask[l].index(n) - c = true_boxes[t, 4].astype('int32') - y_true[l][j, i, k, 0:4] = true_boxes[t, 0:4] - y_true[l][j, i, k, 4] = 1. - - # lable-smooth - if label_smooth: - sigma = label_smooth_factor/(num_classes-1) - y_true[l][j, i, k, 5:] = sigma - y_true[l][j, i, k, 5+c] = 1-label_smooth_factor - else: - y_true[l][j, i, k, 5 + c] = 1. - - # pad_gt_boxes for avoiding dynamic shape - pad_gt_box0 = np.zeros(shape=[max_boxes, 4], dtype=np.float32) - pad_gt_box1 = np.zeros(shape=[max_boxes, 4], dtype=np.float32) - pad_gt_box2 = np.zeros(shape=[max_boxes, 4], dtype=np.float32) - - mask0 = np.reshape(y_true[0][..., 4:5], [-1]) - gt_box0 = np.reshape(y_true[0][..., 0:4], [-1, 4]) - # gt_box [boxes, [x,y,w,h]] - gt_box0 = gt_box0[mask0 == 1] - # gt_box0: get all boxes which have object - pad_gt_box0[:gt_box0.shape[0]] = gt_box0 - # gt_box0.shape[0]: total number of boxes in gt_box0 - # top N of pad_gt_box0 is real box, and after are pad by zero - - mask1 = np.reshape(y_true[1][..., 4:5], [-1]) - gt_box1 = np.reshape(y_true[1][..., 0:4], [-1, 4]) - gt_box1 = gt_box1[mask1 == 1] - pad_gt_box1[:gt_box1.shape[0]] = gt_box1 - - mask2 = np.reshape(y_true[2][..., 4:5], [-1]) - gt_box2 = np.reshape(y_true[2][..., 0:4], [-1, 4]) - - gt_box2 = gt_box2[mask2 == 1] - pad_gt_box2[:gt_box2.shape[0]] = gt_box2 - return y_true[0], y_true[1], y_true[2], pad_gt_box0, pad_gt_box1, pad_gt_box2 - - -def _reshape_data(image, image_size): - """Reshape image.""" - if not isinstance(image, Image.Image): - image = Image.fromarray(image) - ori_w, ori_h = image.size - ori_image_shape = np.array([ori_w, ori_h], np.int32) - # original image shape fir:H sec:W - h, w = image_size - interp = get_interp_method(interp=9, sizes=(ori_h, ori_w, h, w)) - image = image.resize((w, h), pil_image_reshape(interp)) - image_data = statistic_normalize_img(image, statistic_norm=True) - if len(image_data.shape) == 2: - image_data = np.expand_dims(image_data, axis=-1) - image_data = np.concatenate([image_data, image_data, image_data], axis=-1) - image_data = image_data.astype(np.float32) - return image_data, ori_image_shape - - -def color_distortion(img, hue, sat, val, device_num): - """Color distortion.""" - hue = _rand(-hue, hue) - sat = _rand(1, sat) if _rand() < .5 else 1 / _rand(1, sat) - val = _rand(1, val) if _rand() < .5 else 1 / _rand(1, val) - if device_num != 1: - cv2.setNumThreads(1) - x = cv2.cvtColor(img, cv2.COLOR_RGB2HSV_FULL) - x = x / 255. - x[..., 0] += hue - x[..., 0][x[..., 0] > 1] -= 1 - x[..., 0][x[..., 0] < 0] += 1 - x[..., 1] *= sat - x[..., 2] *= val - x[x > 1] = 1 - x[x < 0] = 0 - x = x * 255. - x = x.astype(np.uint8) - image_data = cv2.cvtColor(x, cv2.COLOR_HSV2RGB_FULL) - return image_data - - -def filp_pil_image(img): - return img.transpose(Image.FLIP_LEFT_RIGHT) - - -def convert_gray_to_color(img): - if len(img.shape) == 2: - img = np.expand_dims(img, axis=-1) - img = np.concatenate([img, img, img], axis=-1) - return img - - -def _is_iou_satisfied_constraint(min_iou, max_iou, box, crop_box): - iou = bbox_iou(box, crop_box) - return min_iou <= iou.min() and max_iou >= iou.max() - - -def _choose_candidate_by_constraints(max_trial, input_w, input_h, image_w, image_h, jitter, box, use_constraints): - """Choose candidate by constraints.""" - if use_constraints: - constraints = ( - (0.1, None), - (0.3, None), - (0.5, None), - (0.7, None), - (0.9, None), - (None, 1), - ) - else: - constraints = ( - (None, None), - ) - # add default candidate - candidates = [(0, 0, input_w, input_h)] - for constraint in constraints: - min_iou, max_iou = constraint - min_iou = -np.inf if min_iou is None else min_iou - max_iou = np.inf if max_iou is None else max_iou - - for _ in range(max_trial): - # box_data should have at least one box - new_ar = float(input_w) / float(input_h) * _rand(1 - jitter, 1 + jitter) / _rand(1 - jitter, 1 + jitter) - scale = _rand(0.25, 2) - - if new_ar < 1: - nh = int(scale * input_h) - nw = int(nh * new_ar) - else: - nw = int(scale * input_w) - nh = int(nw / new_ar) - - dx = int(_rand(0, input_w - nw)) - dy = int(_rand(0, input_h - nh)) - - if box.size > 0: - t_box = copy.deepcopy(box) - t_box[:, [0, 2]] = t_box[:, [0, 2]] * float(nw) / float(image_w) + dx - t_box[:, [1, 3]] = t_box[:, [1, 3]] * float(nh) / float(image_h) + dy - - crop_box = np.array((0, 0, input_w, input_h)) - if not _is_iou_satisfied_constraint(min_iou, max_iou, t_box, crop_box[np.newaxis]): - continue - else: - candidates.append((dx, dy, nw, nh)) - else: - raise Exception("!!! annotation box is less than 1") - return candidates - - -def _correct_bbox_by_candidates(candidates, input_w, input_h, image_w, - image_h, flip, box, box_data, allow_outside_center): - """Calculate correct boxes.""" - while candidates: - if len(candidates) > 1: - # ignore default candidate which do not crop - candidate = candidates.pop(np.random.randint(1, len(candidates))) - else: - candidate = candidates.pop(np.random.randint(0, len(candidates))) - dx, dy, nw, nh = candidate - t_box = copy.deepcopy(box) - t_box[:, [0, 2]] = t_box[:, [0, 2]] * float(nw) / float(image_w) + dx - t_box[:, [1, 3]] = t_box[:, [1, 3]] * float(nh) / float(image_h) + dy - if flip: - t_box[:, [0, 2]] = input_w - t_box[:, [2, 0]] - - if allow_outside_center: - pass - else: - t_box = t_box[np.logical_and((t_box[:, 0] + t_box[:, 2])/2. >= 0., (t_box[:, 1] + t_box[:, 3])/2. >= 0.)] - t_box = t_box[np.logical_and((t_box[:, 0] + t_box[:, 2]) / 2. <= input_w, - (t_box[:, 1] + t_box[:, 3]) / 2. <= input_h)] - - # recorrect x, y for case x,y < 0 reset to zero, after dx and dy, some box can smaller than zero - t_box[:, 0:2][t_box[:, 0:2] < 0] = 0 - # recorrect w,h not higher than input size - t_box[:, 2][t_box[:, 2] > input_w] = input_w - t_box[:, 3][t_box[:, 3] > input_h] = input_h - box_w = t_box[:, 2] - t_box[:, 0] - box_h = t_box[:, 3] - t_box[:, 1] - # discard invalid box: w or h smaller than 1 pixel - t_box = t_box[np.logical_and(box_w > 1, box_h > 1)] - - if t_box.shape[0] > 0: - # break if number of find t_box - box_data[: len(t_box)] = t_box - return box_data, candidate - raise Exception('all candidates can not satisfied re-correct bbox') - - -def _data_aug(image, box, jitter, hue, sat, val, image_input_size, max_boxes, - anchors, num_classes, max_trial=10, device_num=1): - """Crop an image randomly with bounding box constraints. - - This data augmentation is used in training of - Single Shot Multibox Detector [#]_. More details can be found in - data augmentation section of the original paper. - .. [#] Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, - Scott Reed, Cheng-Yang Fu, Alexander C. Berg. - SSD: Single Shot MultiBox Detector. ECCV 2016.""" - - if not isinstance(image, Image.Image): - image = Image.fromarray(image) - - image_w, image_h = image.size - input_h, input_w = image_input_size - - np.random.shuffle(box) - if len(box) > max_boxes: - box = box[:max_boxes] - flip = _rand() < .5 - box_data = np.zeros((max_boxes, 5)) - - candidates = _choose_candidate_by_constraints(use_constraints=False, - max_trial=max_trial, - input_w=input_w, - input_h=input_h, - image_w=image_w, - image_h=image_h, - jitter=jitter, - box=box) - box_data, candidate = _correct_bbox_by_candidates(candidates=candidates, - input_w=input_w, - input_h=input_h, - image_w=image_w, - image_h=image_h, - flip=flip, - box=box, - box_data=box_data, - allow_outside_center=True) - dx, dy, nw, nh = candidate - interp = get_interp_method(interp=10) - image = image.resize((nw, nh), pil_image_reshape(interp)) - # place image, gray color as back graoud - new_image = Image.new('RGB', (input_w, input_h), (128, 128, 128)) - new_image.paste(image, (dx, dy)) - image = new_image - - if flip: - image = filp_pil_image(image) - - image = np.array(image) - - image = convert_gray_to_color(image) - - image_data = color_distortion(image, hue, sat, val, device_num) - image_data = statistic_normalize_img(image_data, statistic_norm=True) - - image_data = image_data.astype(np.float32) - - return image_data, box_data - - -def preprocess_fn(image, box, config, input_size, device_num): - """Preprocess data function.""" - config_anchors = config.anchor_scales - anchors = np.array([list(x) for x in config_anchors]) - max_boxes = config.max_box - num_classes = config.num_classes - jitter = config.jitter - hue = config.hue - sat = config.saturation - val = config.value - image, anno = _data_aug(image, box, jitter=jitter, hue=hue, sat=sat, val=val, - image_input_size=input_size, max_boxes=max_boxes, - num_classes=num_classes, anchors=anchors, device_num=device_num) - return image, anno - - -def reshape_fn(image, img_id, config): - input_size = config.test_img_shape - image, ori_image_shape = _reshape_data(image, image_size=input_size) - return image, ori_image_shape, img_id - - -class MultiScaleTrans: - """Multi scale transform.""" - def __init__(self, config, device_num): - self.config = config - self.seed = 0 - self.size_list = [] - self.resize_rate = config.resize_rate - self.dataset_size = config.dataset_size - self.size_dict = {} - self.seed_num = int(1e6) - self.seed_list = self.generate_seed_list(seed_num=self.seed_num) - self.resize_count_num = int(np.ceil(self.dataset_size / self.resize_rate)) - self.device_num = device_num - - def generate_seed_list(self, init_seed=1234, seed_num=int(1e6), seed_range=(1, 1000)): - seed_list = [] - random.seed(init_seed) - for _ in range(seed_num): - seed = random.randint(seed_range[0], seed_range[1]) - seed_list.append(seed) - return seed_list - - def __call__(self, imgs, annos, batchInfo): - epoch_num = batchInfo.get_epoch_num() - size_idx = int(batchInfo.get_batch_num() / self.resize_rate) - seed_key = self.seed_list[(epoch_num * self.resize_count_num + size_idx) % self.seed_num] - ret_imgs = [] - ret_annos = [] - - if self.size_dict.get(seed_key, None) is None: - random.seed(seed_key) - new_size = random.choice(self.config.multi_scale) - self.size_dict[seed_key] = new_size - seed = seed_key - - input_size = self.size_dict[seed] - for img, anno in zip(imgs, annos): - img, anno = preprocess_fn(img, anno, self.config, input_size, self.device_num) - ret_imgs.append(img.transpose(2, 0, 1).copy()) - ret_annos.append(anno) - return np.array(ret_imgs), np.array(ret_annos) - - -def thread_batch_preprocess_true_box(annos, config, input_shape, result_index, batch_bbox_true_1, batch_bbox_true_2, - batch_bbox_true_3, batch_gt_box1, batch_gt_box2, batch_gt_box3): - """Preprocess true box for multi-thread.""" - i = 0 - for anno in annos: - bbox_true_1, bbox_true_2, bbox_true_3, gt_box1, gt_box2, gt_box3 = \ - _preprocess_true_boxes(true_boxes=anno, anchors=config.anchor_scales, in_shape=input_shape, - num_classes=config.num_classes, max_boxes=config.max_box, - label_smooth=config.label_smooth, label_smooth_factor=config.label_smooth_factor) - batch_bbox_true_1[result_index + i] = bbox_true_1 - batch_bbox_true_2[result_index + i] = bbox_true_2 - batch_bbox_true_3[result_index + i] = bbox_true_3 - batch_gt_box1[result_index + i] = gt_box1 - batch_gt_box2[result_index + i] = gt_box2 - batch_gt_box3[result_index + i] = gt_box3 - i = i + 1 - - -def batch_preprocess_true_box(annos, config, input_shape): - """Preprocess true box with multi-thread.""" - batch_bbox_true_1 = [] - batch_bbox_true_2 = [] - batch_bbox_true_3 = [] - batch_gt_box1 = [] - batch_gt_box2 = [] - batch_gt_box3 = [] - threads = [] - - step = 4 - for index in range(0, len(annos), step): - for _ in range(step): - batch_bbox_true_1.append(None) - batch_bbox_true_2.append(None) - batch_bbox_true_3.append(None) - batch_gt_box1.append(None) - batch_gt_box2.append(None) - batch_gt_box3.append(None) - step_anno = annos[index: index + step] - t = threading.Thread(target=thread_batch_preprocess_true_box, - args=(step_anno, config, input_shape, index, batch_bbox_true_1, batch_bbox_true_2, - batch_bbox_true_3, batch_gt_box1, batch_gt_box2, batch_gt_box3)) - t.start() - threads.append(t) - - for t in threads: - t.join() - - return np.array(batch_bbox_true_1), np.array(batch_bbox_true_2), np.array(batch_bbox_true_3), \ - np.array(batch_gt_box1), np.array(batch_gt_box2), np.array(batch_gt_box3) - - -def batch_preprocess_true_box_single(annos, config, input_shape): - """Preprocess true boxes.""" - batch_bbox_true_1 = [] - batch_bbox_true_2 = [] - batch_bbox_true_3 = [] - batch_gt_box1 = [] - batch_gt_box2 = [] - batch_gt_box3 = [] - for anno in annos: - bbox_true_1, bbox_true_2, bbox_true_3, gt_box1, gt_box2, gt_box3 = \ - _preprocess_true_boxes(true_boxes=anno, anchors=config.anchor_scales, in_shape=input_shape, - num_classes=config.num_classes, max_boxes=config.max_box, - label_smooth=config.label_smooth, label_smooth_factor=config.label_smooth_factor) - batch_bbox_true_1.append(bbox_true_1) - batch_bbox_true_2.append(bbox_true_2) - batch_bbox_true_3.append(bbox_true_3) - batch_gt_box1.append(gt_box1) - batch_gt_box2.append(gt_box2) - batch_gt_box3.append(gt_box3) - - return np.array(batch_bbox_true_1), np.array(batch_bbox_true_2), np.array(batch_bbox_true_3), \ - np.array(batch_gt_box1), np.array(batch_gt_box2), np.array(batch_gt_box3) diff --git a/official/cv/yolov3_darknet53_quant/src/util.py b/official/cv/yolov3_darknet53_quant/src/util.py deleted file mode 100644 index fa609c6ced89ba10317cbb439b60df1bcfa56a9d..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/util.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""Util class or function.""" -from mindspore.train.serialization import load_checkpoint -import mindspore.nn as nn - - -class AverageMeter: - """Computes and stores the average and current value""" - - def __init__(self, name, fmt=':f', tb_writer=None): - self.name = name - self.fmt = fmt - self.reset() - self.tb_writer = tb_writer - self.cur_step = 1 - self.val = 0 - self.avg = 0 - self.sum = 0 - self.count = 0 - - def reset(self): - self.val = 0 - self.avg = 0 - self.sum = 0 - self.count = 0 - - def update(self, val, n=1): - self.val = val - self.sum += val * n - self.count += n - self.avg = self.sum / self.count - if self.tb_writer is not None: - self.tb_writer.add_scalar(self.name, self.val, self.cur_step) - self.cur_step += 1 - - def __str__(self): - fmtstr = '{name}:{avg' + self.fmt + '}' - return fmtstr.format(**self.__dict__) - - -def load_backbone(net, ckpt_path, args): - """Load darknet53 backbone checkpoint.""" - param_dict = load_checkpoint(ckpt_path) - yolo_backbone_prefix = 'feature_map.backbone' - darknet_backbone_prefix = 'network.backbone' - find_param = [] - not_found_param = [] - - for name, cell in net.cells_and_names(): - if name.startswith(yolo_backbone_prefix): - name = name.replace(yolo_backbone_prefix, darknet_backbone_prefix) - if isinstance(cell, (nn.Conv2d, nn.Dense)): - darknet_weight = '{}.weight'.format(name) - darknet_bias = '{}.bias'.format(name) - if darknet_weight in param_dict: - cell.weight.set_data(param_dict[darknet_weight].data) - find_param.append(darknet_weight) - else: - not_found_param.append(darknet_weight) - if darknet_bias in param_dict: - cell.bias.set_data(param_dict[darknet_bias].data) - find_param.append(darknet_bias) - else: - not_found_param.append(darknet_bias) - elif isinstance(cell, (nn.BatchNorm2d, nn.BatchNorm1d)): - darknet_moving_mean = '{}.moving_mean'.format(name) - darknet_moving_variance = '{}.moving_variance'.format(name) - darknet_gamma = '{}.gamma'.format(name) - darknet_beta = '{}.beta'.format(name) - if darknet_moving_mean in param_dict: - cell.moving_mean.set_data(param_dict[darknet_moving_mean].data) - find_param.append(darknet_moving_mean) - else: - not_found_param.append(darknet_moving_mean) - if darknet_moving_variance in param_dict: - cell.moving_variance.set_data(param_dict[darknet_moving_variance].data) - find_param.append(darknet_moving_variance) - else: - not_found_param.append(darknet_moving_variance) - if darknet_gamma in param_dict: - cell.gamma.set_data(param_dict[darknet_gamma].data) - find_param.append(darknet_gamma) - else: - not_found_param.append(darknet_gamma) - if darknet_beta in param_dict: - cell.beta.set_data(param_dict[darknet_beta].data) - find_param.append(darknet_beta) - else: - not_found_param.append(darknet_beta) - - args.logger.info('================found_param {}========='.format(len(find_param))) - args.logger.info(find_param) - args.logger.info('================not_found_param {}========='.format(len(not_found_param))) - args.logger.info(not_found_param) - args.logger.info('=====load {} successfully ====='.format(ckpt_path)) - - return net - - -def default_wd_filter(x): - """default weight decay filter.""" - parameter_name = x.name - if parameter_name.endswith('.bias'): - # all bias not using weight decay - return False - if parameter_name.endswith('.gamma'): - # bn weight bias not using weight decay, be carefully for now x not include BN - return False - if parameter_name.endswith('.beta'): - # bn weight bias not using weight decay, be carefully for now x not include BN - return False - - return True - - -def get_param_groups(network): - """Param groups for optimizer.""" - decay_params = [] - no_decay_params = [] - for x in network.trainable_params(): - parameter_name = x.name - if parameter_name.endswith('.bias'): - # all bias not using weight decay - no_decay_params.append(x) - elif parameter_name.endswith('.gamma'): - # bn weight bias not using weight decay, be carefully for now x not include BN - no_decay_params.append(x) - elif parameter_name.endswith('.beta'): - # bn weight bias not using weight decay, be carefully for now x not include BN - no_decay_params.append(x) - else: - decay_params.append(x) - - return [{'params': no_decay_params, 'weight_decay': 0.0}, {'params': decay_params}] - - -class ShapeRecord: - """Log image shape.""" - def __init__(self): - self.shape_record = { - 320: 0, - 352: 0, - 384: 0, - 416: 0, - 448: 0, - 480: 0, - 512: 0, - 544: 0, - 576: 0, - 608: 0, - 'total': 0 - } - - def set(self, shape): - if len(shape) > 1: - shape = shape[0] - shape = int(shape) - self.shape_record[shape] += 1 - self.shape_record['total'] += 1 - - def show(self, logger): - for key in self.shape_record: - rate = self.shape_record[key] / float(self.shape_record['total']) - logger.info('shape {}: {:.2f}%'.format(key, rate*100)) diff --git a/official/cv/yolov3_darknet53_quant/src/yolo.py b/official/cv/yolov3_darknet53_quant/src/yolo.py deleted file mode 100644 index 35f4d41110bb76de975081e4f5365e879292c0ea..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/yolo.py +++ /dev/null @@ -1,440 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YOLOv3 based on DarkNet.""" -import mindspore as ms -import mindspore.nn as nn -from mindspore.common.tensor import Tensor -from mindspore import context -from mindspore.context import ParallelMode -from mindspore.parallel._auto_parallel_context import auto_parallel_context -from mindspore.communication.management import get_group_size -from mindspore.ops import operations as P -from mindspore.ops import functional as F -from mindspore.ops import composite as C - -from src.darknet import DarkNet, ResidualBlock -from src.config import ConfigYOLOV3DarkNet53 -from src.loss import XYLoss, WHLoss, ConfidenceLoss, ClassLoss - - -def _conv_bn_relu(in_channel, - out_channel, - ksize, - stride=1, - padding=0, - dilation=1, - alpha=0.1, - momentum=0.1, - eps=1e-5, - pad_mode="same"): - """Get a conv2d batchnorm and relu layer""" - return nn.Conv2dBnAct(in_channel, out_channel, ksize, - stride=stride, - pad_mode=pad_mode, - padding=padding, - dilation=dilation, - has_bn=True, - momentum=momentum, - eps=eps, - activation='leakyrelu', - alpha=alpha) - - -class YoloBlock(nn.Cell): - """ - YoloBlock for YOLOv3. - - Args: - in_channels: Integer. Input channel. - out_chls: Integer. Middle channel. - out_channels: Integer. Output channel. - - Returns: - Tuple, tuple of output tensor,(f1,f2,f3). - - Examples: - YoloBlock(1024, 512, 255) - - """ - def __init__(self, in_channels, out_chls, out_channels): - super(YoloBlock, self).__init__() - out_chls_2 = out_chls*2 - - self.conv0 = _conv_bn_relu(in_channels, out_chls, ksize=1) - self.conv1 = _conv_bn_relu(out_chls, out_chls_2, ksize=3) - - self.conv2 = _conv_bn_relu(out_chls_2, out_chls, ksize=1) - self.conv3 = _conv_bn_relu(out_chls, out_chls_2, ksize=3) - - self.conv4 = _conv_bn_relu(out_chls_2, out_chls, ksize=1) - self.conv5 = _conv_bn_relu(out_chls, out_chls_2, ksize=3) - - self.conv6 = nn.Conv2dBnAct(out_chls_2, out_channels, kernel_size=1, stride=1, - has_bias=True, has_bn=False, activation=None, after_fake=False) - - def construct(self, x): - c1 = self.conv0(x) - c2 = self.conv1(c1) - - c3 = self.conv2(c2) - c4 = self.conv3(c3) - - c5 = self.conv4(c4) - c6 = self.conv5(c5) - - out = self.conv6(c6) - return c5, out - - -class YOLOv3(nn.Cell): - """ - YOLOv3 Network. - - Note: - backbone = darknet53 - - Args: - backbone_shape: List. Darknet output channels shape. - backbone: Cell. Backbone Network. - out_channel: Integer. Output channel. - - Returns: - Tensor, output tensor. - - Examples: - YOLOv3(backbone_shape=[64, 128, 256, 512, 1024] - backbone=darknet53(), - out_channel=255) - """ - def __init__(self, backbone_shape, backbone, out_channel): - super(YOLOv3, self).__init__() - self.out_channel = out_channel - self.backbone = backbone - self.backblock0 = YoloBlock(backbone_shape[-1], out_chls=backbone_shape[-2], out_channels=out_channel) - - self.conv1 = _conv_bn_relu(in_channel=backbone_shape[-2], out_channel=backbone_shape[-2]//2, ksize=1) - self.backblock1 = YoloBlock(in_channels=backbone_shape[-2]+backbone_shape[-3], - out_chls=backbone_shape[-3], - out_channels=out_channel) - - self.conv2 = _conv_bn_relu(in_channel=backbone_shape[-3], out_channel=backbone_shape[-3]//2, ksize=1) - self.backblock2 = YoloBlock(in_channels=backbone_shape[-3]+backbone_shape[-4], - out_chls=backbone_shape[-4], - out_channels=out_channel) - self.concat = P.Concat(axis=1) - - def construct(self, x): - # input_shape of x is (batch_size, 3, h, w) - # feature_map1 is (batch_size, backbone_shape[2], h/8, w/8) - # feature_map2 is (batch_size, backbone_shape[3], h/16, w/16) - # feature_map3 is (batch_size, backbone_shape[4], h/32, w/32) - img_hight = P.Shape()(x)[2] - img_width = P.Shape()(x)[3] - feature_map1, feature_map2, feature_map3 = self.backbone(x) - con1, big_object_output = self.backblock0(feature_map3) - - con1 = self.conv1(con1) - ups1 = P.ResizeNearestNeighbor((img_hight // 16, img_width // 16))(con1) - con1 = self.concat((ups1, feature_map2)) - con2, medium_object_output = self.backblock1(con1) - - con2 = self.conv2(con2) - ups2 = P.ResizeNearestNeighbor((img_hight // 8, img_width // 8))(con2) - con3 = self.concat((ups2, feature_map1)) - _, small_object_output = self.backblock2(con3) - - return big_object_output, medium_object_output, small_object_output - - -class DetectionBlock(nn.Cell): - """ - YOLOv3 detection Network. It will finally output the detection result. - - Args: - scale: Character. - config: ConfigYOLOV3DarkNet53, Configuration instance. - is_training: Bool, Whether train or not, default True. - - Returns: - Tuple, tuple of output tensor,(f1,f2,f3). - - Examples: - DetectionBlock(scale='l',stride=32) - """ - - def __init__(self, scale, config=ConfigYOLOV3DarkNet53(), is_training=True): - super(DetectionBlock, self).__init__() - self.config = config - if scale == 's': - idx = (0, 1, 2) - elif scale == 'm': - idx = (3, 4, 5) - elif scale == 'l': - idx = (6, 7, 8) - else: - raise KeyError("Invalid scale value for DetectionBlock") - self.anchors = Tensor([self.config.anchor_scales[i] for i in idx], ms.float32) - self.num_anchors_per_scale = 3 - self.num_attrib = 4+1+self.config.num_classes - self.lambda_coord = 1 - - self.sigmoid = nn.Sigmoid() - self.reshape = P.Reshape() - self.tile = P.Tile() - self.concat = P.Concat(axis=-1) - self.conf_training = is_training - - def construct(self, x, input_shape): - num_batch = P.Shape()(x)[0] - grid_size = P.Shape()(x)[2:4] - - # Reshape and transpose the feature to [n, grid_size[0], grid_size[1], 3, num_attrib] - prediction = P.Reshape()(x, (num_batch, - self.num_anchors_per_scale, - self.num_attrib, - grid_size[0], - grid_size[1])) - prediction = P.Transpose()(prediction, (0, 3, 4, 1, 2)) - - range_x = range(grid_size[1]) - range_y = range(grid_size[0]) - grid_x = P.Cast()(F.tuple_to_array(range_x), ms.float32) - grid_y = P.Cast()(F.tuple_to_array(range_y), ms.float32) - # Tensor of shape [grid_size[0], grid_size[1], 1, 1] representing the coordinate of x/y axis for each grid - # [batch, gridx, gridy, 1, 1] - grid_x = self.tile(self.reshape(grid_x, (1, 1, -1, 1, 1)), (1, grid_size[0], 1, 1, 1)) - grid_y = self.tile(self.reshape(grid_y, (1, -1, 1, 1, 1)), (1, 1, grid_size[1], 1, 1)) - # Shape is [grid_size[0], grid_size[1], 1, 2] - grid = self.concat((grid_x, grid_y)) - - box_xy = prediction[:, :, :, :, :2] - box_wh = prediction[:, :, :, :, 2:4] - box_confidence = prediction[:, :, :, :, 4:5] - box_probs = prediction[:, :, :, :, 5:] - - # gridsize1 is x - # gridsize0 is y - box_xy = (self.sigmoid(box_xy) + grid) / P.Cast()(F.tuple_to_array((grid_size[1], grid_size[0])), ms.float32) - # box_wh is w->h - box_wh = P.Exp()(box_wh) * self.anchors / input_shape - box_confidence = self.sigmoid(box_confidence) - box_probs = self.sigmoid(box_probs) - - if self.conf_training: - return grid, prediction, box_xy, box_wh - return self.concat((box_xy, box_wh, box_confidence, box_probs)) - - -class Iou(nn.Cell): - """Calculate the iou of boxes""" - def __init__(self): - super(Iou, self).__init__() - self.min = P.Minimum() - self.max = P.Maximum() - - def construct(self, box1, box2): - # box1: pred_box [batch, gx, gy, anchors, 1, 4] ->4: [x_center, y_center, w, h] - # box2: gt_box [batch, 1, 1, 1, maxbox, 4] - # convert to topLeft and rightDown - box1_xy = box1[:, :, :, :, :, :2] - box1_wh = box1[:, :, :, :, :, 2:4] - box1_mins = box1_xy - box1_wh / F.scalar_to_array(2.0) # topLeft - box1_maxs = box1_xy + box1_wh / F.scalar_to_array(2.0) # rightDown - - box2_xy = box2[:, :, :, :, :, :2] - box2_wh = box2[:, :, :, :, :, 2:4] - box2_mins = box2_xy - box2_wh / F.scalar_to_array(2.0) - box2_maxs = box2_xy + box2_wh / F.scalar_to_array(2.0) - - intersect_mins = self.max(box1_mins, box2_mins) - intersect_maxs = self.min(box1_maxs, box2_maxs) - intersect_wh = self.max(intersect_maxs - intersect_mins, F.scalar_to_array(0.0)) - # P.squeeze: for effiecient slice - intersect_area = P.Squeeze(-1)(intersect_wh[:, :, :, :, :, 0:1]) * \ - P.Squeeze(-1)(intersect_wh[:, :, :, :, :, 1:2]) - box1_area = P.Squeeze(-1)(box1_wh[:, :, :, :, :, 0:1]) * P.Squeeze(-1)(box1_wh[:, :, :, :, :, 1:2]) - box2_area = P.Squeeze(-1)(box2_wh[:, :, :, :, :, 0:1]) * P.Squeeze(-1)(box2_wh[:, :, :, :, :, 1:2]) - iou = intersect_area / (box1_area + box2_area - intersect_area) - # iou : [batch, gx, gy, anchors, maxboxes] - return iou - - -class YoloLossBlock(nn.Cell): - """ - Loss block cell of YOLOV3 network. - """ - def __init__(self, scale, config=ConfigYOLOV3DarkNet53()): - super(YoloLossBlock, self).__init__() - self.config = config - if scale == 's': - # anchor mask - idx = (0, 1, 2) - elif scale == 'm': - idx = (3, 4, 5) - elif scale == 'l': - idx = (6, 7, 8) - else: - raise KeyError("Invalid scale value for DetectionBlock") - self.anchors = Tensor([self.config.anchor_scales[i] for i in idx], ms.float32) - self.ignore_threshold = Tensor(self.config.ignore_threshold, ms.float32) - self.concat = P.Concat(axis=-1) - self.iou = Iou() - self.reduce_max = P.ReduceMax(keep_dims=False) - self.xy_loss = XYLoss() - self.wh_loss = WHLoss() - self.confidenceLoss = ConfidenceLoss() - self.classLoss = ClassLoss() - - def construct(self, grid, prediction, pred_xy, pred_wh, y_true, gt_box, input_shape): - # prediction : origin output from yolo - # pred_xy: (sigmoid(xy)+grid)/grid_size - # pred_wh: (exp(wh)*anchors)/input_shape - # y_true : after normalize - # gt_box: [batch, maxboxes, xyhw] after normalize - - object_mask = y_true[:, :, :, :, 4:5] - class_probs = y_true[:, :, :, :, 5:] - - grid_shape = P.Shape()(prediction)[1:3] - grid_shape = P.Cast()(F.tuple_to_array(grid_shape[::-1]), ms.float32) - - pred_boxes = self.concat((pred_xy, pred_wh)) - true_xy = y_true[:, :, :, :, :2] * grid_shape - grid - true_wh = y_true[:, :, :, :, 2:4] - true_wh = P.Select()(P.Equal()(true_wh, 0.0), - P.Fill()(P.DType()(true_wh), - P.Shape()(true_wh), 1.0), - true_wh) - true_wh = P.Log()(true_wh / self.anchors * input_shape) - # 2-w*h for large picture, use small scale, since small obj need more precise - box_loss_scale = 2 - y_true[:, :, :, :, 2:3] * y_true[:, :, :, :, 3:4] - - gt_shape = P.Shape()(gt_box) - gt_box = P.Reshape()(gt_box, (gt_shape[0], 1, 1, 1, gt_shape[1], gt_shape[2])) - - # add one more dimension for broadcast - iou = self.iou(P.ExpandDims()(pred_boxes, -2), gt_box) - # gt_box is x,y,h,w after normalize - # [batch, grid[0], grid[1], num_anchor, num_gt] - best_iou = self.reduce_max(iou, -1) - # [batch, grid[0], grid[1], num_anchor] - - # ignore_mask IOU too small - ignore_mask = best_iou < self.ignore_threshold - ignore_mask = P.Cast()(ignore_mask, ms.float32) - ignore_mask = P.ExpandDims()(ignore_mask, -1) - # ignore_mask backpro will cause a lot maximunGrad and minimumGrad time consume. - # so we turn off its gradient - ignore_mask = F.stop_gradient(ignore_mask) - - xy_loss = self.xy_loss(object_mask, box_loss_scale, prediction[:, :, :, :, :2], true_xy) - wh_loss = self.wh_loss(object_mask, box_loss_scale, prediction[:, :, :, :, 2:4], true_wh) - confidence_loss = self.confidenceLoss(object_mask, prediction[:, :, :, :, 4:5], ignore_mask) - class_loss = self.classLoss(object_mask, prediction[:, :, :, :, 5:], class_probs) - loss = xy_loss + wh_loss + confidence_loss + class_loss - batch_size = P.Shape()(prediction)[0] - return loss / batch_size - - -class YOLOV3DarkNet53(nn.Cell): - """ - Darknet based YOLOV3 network. - - Args: - is_training: Bool. Whether train or not. - - Returns: - Cell, cell instance of Darknet based YOLOV3 neural network. - - Examples: - YOLOV3DarkNet53(True) - """ - - def __init__(self, is_training): - super(YOLOV3DarkNet53, self).__init__() - self.config = ConfigYOLOV3DarkNet53() - - # YOLOv3 network - self.feature_map = YOLOv3(backbone=DarkNet(ResidualBlock, self.config.backbone_layers, - self.config.backbone_input_shape, - self.config.backbone_shape, - detect=True), - backbone_shape=self.config.backbone_shape, - out_channel=self.config.out_channel) - - # prediction on the default anchor boxes - self.detect_1 = DetectionBlock('l', is_training=is_training) - self.detect_2 = DetectionBlock('m', is_training=is_training) - self.detect_3 = DetectionBlock('s', is_training=is_training) - - def construct(self, x, input_shape): - big_object_output, medium_object_output, small_object_output = self.feature_map(x) - output_big = self.detect_1(big_object_output, input_shape) - output_me = self.detect_2(medium_object_output, input_shape) - output_small = self.detect_3(small_object_output, input_shape) - # big is the final output which has smallest feature map - return output_big, output_me, output_small - - -class YoloWithLossCell(nn.Cell): - """YOLOV3 loss.""" - def __init__(self, network): - super(YoloWithLossCell, self).__init__() - self.yolo_network = network - self.config = ConfigYOLOV3DarkNet53() - self.loss_big = YoloLossBlock('l', self.config) - self.loss_me = YoloLossBlock('m', self.config) - self.loss_small = YoloLossBlock('s', self.config) - - def construct(self, x, y_true_0, y_true_1, y_true_2, gt_0, gt_1, gt_2, input_shape): - yolo_out = self.yolo_network(x, input_shape) - loss_l = self.loss_big(*yolo_out[0], y_true_0, gt_0, input_shape) - loss_m = self.loss_me(*yolo_out[1], y_true_1, gt_1, input_shape) - loss_s = self.loss_small(*yolo_out[2], y_true_2, gt_2, input_shape) - return loss_l + loss_m + loss_s - - -class TrainingWrapper(nn.Cell): - """Training wrapper.""" - def __init__(self, network, optimizer, sens=1.0): - super(TrainingWrapper, self).__init__(auto_prefix=False) - self.network = network - self.network.set_grad() - self.weights = optimizer.parameters - self.optimizer = optimizer - self.grad = C.GradOperation(get_by_list=True, sens_param=True) - self.sens = sens - self.reducer_flag = False - self.grad_reducer = None - self.parallel_mode = context.get_auto_parallel_context("parallel_mode") - if self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL]: - self.reducer_flag = True - if self.reducer_flag: - mean = context.get_auto_parallel_context("gradients_mean") - if auto_parallel_context().get_device_num_is_set(): - degree = context.get_auto_parallel_context("device_num") - else: - degree = get_group_size() - self.grad_reducer = nn.DistributedGradReducer(optimizer.parameters, mean, degree) - - def construct(self, *args): - weights = self.weights - loss = self.network(*args) - sens = P.Fill()(P.DType()(loss), P.Shape()(loss), self.sens) - grads = self.grad(self.network, weights)(*args, sens) - if self.reducer_flag: - grads = self.grad_reducer(grads) - self.optimizer(grads) - return loss diff --git a/official/cv/yolov3_darknet53_quant/src/yolo_dataset.py b/official/cv/yolov3_darknet53_quant/src/yolo_dataset.py deleted file mode 100644 index 7f8d9f0ec47566c991b13e5e8dfdc99084b829fb..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/src/yolo_dataset.py +++ /dev/null @@ -1,187 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YOLOV3 dataset.""" -import os - -import cv2 -from PIL import Image -from pycocotools.coco import COCO -import mindspore.dataset as de -import mindspore.dataset.vision.c_transforms as CV - -from src.distributed_sampler import DistributedSampler -from src.transforms import reshape_fn, MultiScaleTrans - - -min_keypoints_per_image = 10 - - -def _has_only_empty_bbox(anno): - return all(any(o <= 1 for o in obj["bbox"][2:]) for obj in anno) - - -def _count_visible_keypoints(anno): - return sum(sum(1 for v in ann["keypoints"][2::3] if v > 0) for ann in anno) - - -def has_valid_annotation(anno): - """Check annotation file.""" - # if it's empty, there is no annotation - if not anno: - return False - # if all boxes have close to zero area, there is no annotation - if _has_only_empty_bbox(anno): - return False - # keypoints task have a slight different criteria for considering - # if an annotation is valid - if "keypoints" not in anno[0]: - return True - # for keypoint detection tasks, only consider valid images those - # containing at least min_keypoints_per_image - if _count_visible_keypoints(anno) >= min_keypoints_per_image: - return True - return False - - -class COCOYoloDataset: - """YOLOV3 Dataset for COCO.""" - def __init__(self, root, ann_file, remove_images_without_annotations=True, - filter_crowd_anno=True, is_training=True): - self.coco = COCO(ann_file) - self.root = root - self.img_ids = list(sorted(self.coco.imgs.keys())) - self.filter_crowd_anno = filter_crowd_anno - self.is_training = is_training - - # filter images without any annotations - if remove_images_without_annotations: - img_ids = [] - for img_id in self.img_ids: - ann_ids = self.coco.getAnnIds(imgIds=img_id, iscrowd=None) - anno = self.coco.loadAnns(ann_ids) - if has_valid_annotation(anno): - img_ids.append(img_id) - self.img_ids = img_ids - - self.categories = {cat["id"]: cat["name"] for cat in self.coco.cats.values()} - - self.cat_ids_to_continuous_ids = { - v: i for i, v in enumerate(self.coco.getCatIds()) - } - self.continuous_ids_cat_ids = { - v: k for k, v in self.cat_ids_to_continuous_ids.items() - } - - def __getitem__(self, index): - """ - Args: - index (int): Index - - Returns: - (img, target) (tuple): target is a dictionary contains "bbox", "segmentation" or "keypoints", - generated by the image's annotation. img is a PIL image. - """ - coco = self.coco - img_id = self.img_ids[index] - img_path = coco.loadImgs(img_id)[0]["file_name"] - img = Image.open(os.path.join(self.root, img_path)).convert("RGB") - if not self.is_training: - return img, img_id - - ann_ids = coco.getAnnIds(imgIds=img_id) - target = coco.loadAnns(ann_ids) - # filter crowd annotations - if self.filter_crowd_anno: - annos = [anno for anno in target if anno["iscrowd"] == 0] - else: - annos = [anno for anno in target] - - target = {} - boxes = [anno["bbox"] for anno in annos] - target["bboxes"] = boxes - - classes = [anno["category_id"] for anno in annos] - classes = [self.cat_ids_to_continuous_ids[cl] for cl in classes] - target["labels"] = classes - - bboxes = target['bboxes'] - labels = target['labels'] - out_target = [] - for bbox, label in zip(bboxes, labels): - tmp = [] - # convert to [x_min y_min x_max y_max] - bbox = self._convetTopDown(bbox) - tmp.extend(bbox) - tmp.append(int(label)) - # tmp [x_min y_min x_max y_max, label] - out_target.append(tmp) - return img, out_target - - def __len__(self): - return len(self.img_ids) - - def _convetTopDown(self, bbox): - x_min = bbox[0] - y_min = bbox[1] - w = bbox[2] - h = bbox[3] - return [x_min, y_min, x_min+w, y_min+h] - - -def create_yolo_dataset(image_dir, anno_path, batch_size, max_epoch, device_num, rank, - config=None, is_training=True, shuffle=True): - """Create dataset for YOLOV3.""" - cv2.setNumThreads(0) - - if is_training: - filter_crowd = True - remove_empty_anno = True - else: - filter_crowd = False - remove_empty_anno = False - - yolo_dataset = COCOYoloDataset(root=image_dir, ann_file=anno_path, filter_crowd_anno=filter_crowd, - remove_images_without_annotations=remove_empty_anno, is_training=is_training) - distributed_sampler = DistributedSampler(len(yolo_dataset), device_num, rank, shuffle=shuffle) - hwc_to_chw = CV.HWC2CHW() - - config.dataset_size = len(yolo_dataset) - num_parallel_workers1 = int(64 / device_num) - num_parallel_workers2 = int(16 / device_num) - if is_training: - multi_scale_trans = MultiScaleTrans(config, device_num) - if device_num != 8: - ds = de.GeneratorDataset(yolo_dataset, column_names=["image", "annotation"], - num_parallel_workers=num_parallel_workers1, - sampler=distributed_sampler) - ds = ds.batch(batch_size, per_batch_map=multi_scale_trans, input_columns=['image', 'annotation'], - num_parallel_workers=num_parallel_workers2, drop_remainder=True) - else: - ds = de.GeneratorDataset(yolo_dataset, column_names=["image", "annotation"], sampler=distributed_sampler) - ds = ds.batch(batch_size, per_batch_map=multi_scale_trans, input_columns=['image', 'annotation'], - num_parallel_workers=8, drop_remainder=True) - else: - ds = de.GeneratorDataset(yolo_dataset, column_names=["image", "img_id"], - sampler=distributed_sampler) - compose_map_func = (lambda image, img_id: reshape_fn(image, img_id, config)) - ds = ds.map(operations=compose_map_func, input_columns=["image", "img_id"], - output_columns=["image", "image_shape", "img_id"], - column_order=["image", "image_shape", "img_id"], - num_parallel_workers=8) - ds = ds.map(operations=hwc_to_chw, input_columns=["image"], num_parallel_workers=8) - ds = ds.batch(batch_size, drop_remainder=True) - ds = ds.repeat(max_epoch) - - return ds, len(yolo_dataset) diff --git a/official/cv/yolov3_darknet53_quant/train.py b/official/cv/yolov3_darknet53_quant/train.py deleted file mode 100644 index a0f99717b4c1e279750bcac2d1c0186660486857..0000000000000000000000000000000000000000 --- a/official/cv/yolov3_darknet53_quant/train.py +++ /dev/null @@ -1,296 +0,0 @@ -# Copyright 2020 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ -"""YoloV3-Darknet53-Quant train.""" - -import os -import time -import argparse -import datetime - -from mindspore.context import ParallelMode -from mindspore.nn.optim.momentum import Momentum -from mindspore import Tensor -from mindspore import context -from mindspore.communication.management import init, get_rank, get_group_size -from mindspore.train.callback import ModelCheckpoint, RunContext -from mindspore.train.callback import CheckpointConfig -import mindspore as ms -from mindspore.compression.quant import QuantizationAwareTraining -from mindspore.common import set_seed - -from src.yolo import YOLOV3DarkNet53, YoloWithLossCell, TrainingWrapper -from src.logger import get_logger -from src.util import AverageMeter, get_param_groups -from src.lr_scheduler import get_lr -from src.yolo_dataset import create_yolo_dataset -from src.initializer import default_recurisive_init, load_yolov3_quant_params -from src.config import ConfigYOLOV3DarkNet53 -from src.transforms import batch_preprocess_true_box, batch_preprocess_true_box_single -from src.util import ShapeRecord - -set_seed(1) - -devid = int(os.getenv('DEVICE_ID')) -context.set_context(mode=context.GRAPH_MODE, - device_target="Ascend", save_graphs=False, device_id=devid) - - -def parse_args(): - """Parse train arguments.""" - parser = argparse.ArgumentParser('mindspore coco training') - - # dataset related - parser.add_argument('--data_dir', type=str, default='', help='Train data dir. Default: ""') - parser.add_argument('--per_batch_size', default=16, type=int, help='Batch size for per device. Default: 16') - - # network related - parser.add_argument('--resume_yolov3', default='', type=str,\ - help='The ckpt file of yolov3-darknet53, which used to yolov3-darknet53 quant. Default: ""') - - # optimizer and lr related - parser.add_argument('--lr_scheduler', default='exponential', type=str,\ - help='Learning rate scheduler, option type: exponential, ' - 'cosine_annealing. Default: exponential') - parser.add_argument('--lr', default=0.012, type=float, help='Learning rate of the training') - parser.add_argument('--lr_epochs', type=str, default='92,105',\ - help='Epoch of lr changing. Default: 92,105') - parser.add_argument('--lr_gamma', type=float, default=0.1,\ - help='Decrease lr by a factor of exponential lr_scheduler. Default: 0.1') - parser.add_argument('--eta_min', type=float, default=0.,\ - help='Eta_min in cosine_annealing scheduler. Default: 0.') - parser.add_argument('--T_max', type=int, default=135,\ - help='T-max in cosine_annealing scheduler. Default: 135') - parser.add_argument('--max_epoch', type=int, default=135,\ - help='Max epoch num to train the model. Default: 135') - parser.add_argument('--warmup_epochs', type=float, default=0, help='Warmup epochs. Default: 0') - parser.add_argument('--weight_decay', type=float, default=0.0005, help='Weight decay. Default: 0.0005') - parser.add_argument('--momentum', type=float, default=0.9, help='Momentum. Default: 0.9') - - # loss related - parser.add_argument('--loss_scale', type=int, default=1024, help='Static loss scale. Default: 1024') - parser.add_argument('--label_smooth', type=int, default=0, help='Whether to use label smooth in CE. Default: 0') - parser.add_argument('--label_smooth_factor', type=float, default=0.1,\ - help='Smooth strength of original one-hot. Default: 0.1') - - # logging related - parser.add_argument('--log_interval', type=int, default=100, help='Logging interval steps. Default: 100') - parser.add_argument('--ckpt_path', type=str, default='outputs/',\ - help='Checkpoint save location. Default: "outputs/"') - parser.add_argument('--ckpt_interval', type=int, default=None, help='Save checkpoint interval. Default: None') - parser.add_argument('--is_save_on_master', type=int, default=1,\ - help='Save ckpt on master or all rank, 1 for master, 0 for all ranks. Default: 1') - - # distributed related - parser.add_argument('--is_distributed', type=int, default=0,\ - help='Distribute train or not, 1 for yes, 0 for no. Default: 0') - parser.add_argument('--rank', type=int, default=0, help='Local rank of distributed, Default: 0') - parser.add_argument('--group_size', type=int, default=1, help='World size of device, Default: 1') - - # profiler init - parser.add_argument('--need_profiler', type=int, default=0,\ - help='Whether use profiler, 1 for yes, 0 for no, Default: 0') - - # reset default config - parser.add_argument('--training_shape', type=str, default="", help='Fix training shape. Default: ""') - parser.add_argument('--resize_rate', type=int, default=None,\ - help='Resize rate for multi-scale training. Default: None') - - args, _ = parser.parse_known_args() - if args.lr_scheduler == 'cosine_annealing' and args.max_epoch > args.T_max: - args.T_max = args.max_epoch - - args.lr_epochs = list(map(int, args.lr_epochs.split(','))) - args.data_root = os.path.join(args.data_dir, 'train2014') - args.annFile = os.path.join(args.data_dir, 'annotations/instances_train2014.json') - - # init distributed - if args.is_distributed: - init() - args.rank = get_rank() - args.group_size = get_group_size() - - # select for master rank save ckpt or all rank save, compatible for model parallel - args.rank_save_ckpt_flag = 0 - if args.is_save_on_master: - if args.rank == 0: - args.rank_save_ckpt_flag = 1 - else: - args.rank_save_ckpt_flag = 1 - - # logger - args.outputs_dir = os.path.join(args.ckpt_path, - datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S')) - args.logger = get_logger(args.outputs_dir, args.rank) - return args - - -def conver_training_shape(args): - training_shape = [int(args.training_shape), int(args.training_shape)] - return training_shape - -def build_quant_network(network): - quantizer = QuantizationAwareTraining(bn_fold=True, - per_channel=[True, False], - symmetric=[True, False], - one_conv_fold=False) - network = quantizer.quantize(network) - return network - - -class InternalCallbackParam(dict): - """Internal callback object's parameters.""" - - def __getattr__(self, key): - return self[key] - - def __setattr__(self, key, value): - self[key] = value - - -def train(): - """Train function.""" - args = parse_args() - args.logger.save_args(args) - - if args.need_profiler: - from mindspore.profiler.profiling import Profiler - profiler = Profiler(output_path=args.outputs_dir, is_detail=True, is_show_op_path=True) - - loss_meter = AverageMeter('loss') - - context.reset_auto_parallel_context() - parallel_mode = ParallelMode.STAND_ALONE - degree = 1 - if args.is_distributed: - parallel_mode = ParallelMode.DATA_PARALLEL - degree = get_group_size() - context.set_auto_parallel_context(parallel_mode=parallel_mode, gradients_mean=True, device_num=degree) - - network = YOLOV3DarkNet53(is_training=True) - # default is kaiming-normal - default_recurisive_init(network) - load_yolov3_quant_params(args, network) - - config = ConfigYOLOV3DarkNet53() - # convert fusion network to quantization aware network - if config.quantization_aware: - network = build_quant_network(network) - - network = YoloWithLossCell(network) - args.logger.info('finish get network') - - config.label_smooth = args.label_smooth - config.label_smooth_factor = args.label_smooth_factor - - if args.training_shape: - config.multi_scale = [conver_training_shape(args)] - - if args.resize_rate: - config.resize_rate = args.resize_rate - - ds, data_size = create_yolo_dataset(image_dir=args.data_root, anno_path=args.annFile, is_training=True, - batch_size=args.per_batch_size, max_epoch=args.max_epoch, - device_num=args.group_size, rank=args.rank, config=config) - args.logger.info('Finish loading dataset') - - args.steps_per_epoch = int(data_size / args.per_batch_size / args.group_size) - - if not args.ckpt_interval: - args.ckpt_interval = args.steps_per_epoch - - lr = get_lr(args) - - opt = Momentum(params=get_param_groups(network), learning_rate=Tensor(lr), momentum=args.momentum, - weight_decay=args.weight_decay, loss_scale=args.loss_scale) - - network = TrainingWrapper(network, opt) - network.set_train() - - if args.rank_save_ckpt_flag: - # checkpoint save - ckpt_max_num = args.max_epoch * args.steps_per_epoch // args.ckpt_interval - ckpt_config = CheckpointConfig(save_checkpoint_steps=args.ckpt_interval, - keep_checkpoint_max=ckpt_max_num) - save_ckpt_path = os.path.join(args.outputs_dir, 'ckpt_' + str(args.rank) + '/') - ckpt_cb = ModelCheckpoint(config=ckpt_config, directory=save_ckpt_path, prefix='{}'.format(args.rank)) - cb_params = InternalCallbackParam() - cb_params.train_network = network - cb_params.epoch_num = ckpt_max_num - cb_params.cur_epoch_num = 1 - run_context = RunContext(cb_params) - ckpt_cb.begin(run_context) - - old_progress = -1 - t_end = time.time() - data_loader = ds.create_dict_iterator(output_numpy=True, num_epochs=1) - - shape_record = ShapeRecord() - for i, data in enumerate(data_loader): - images = data["image"] - input_shape = images.shape[2:4] - args.logger.info('iter[{}], shape{}'.format(i, input_shape[0])) - shape_record.set(input_shape) - - images = Tensor.from_numpy(images) - annos = data["annotation"] - if args.group_size == 1: - batch_y_true_0, batch_y_true_1, batch_y_true_2, batch_gt_box0, batch_gt_box1, batch_gt_box2 = \ - batch_preprocess_true_box(annos, config, input_shape) - else: - batch_y_true_0, batch_y_true_1, batch_y_true_2, batch_gt_box0, batch_gt_box1, batch_gt_box2 = \ - batch_preprocess_true_box_single(annos, config, input_shape) - - batch_y_true_0 = Tensor.from_numpy(batch_y_true_0) - batch_y_true_1 = Tensor.from_numpy(batch_y_true_1) - batch_y_true_2 = Tensor.from_numpy(batch_y_true_2) - batch_gt_box0 = Tensor.from_numpy(batch_gt_box0) - batch_gt_box1 = Tensor.from_numpy(batch_gt_box1) - batch_gt_box2 = Tensor.from_numpy(batch_gt_box2) - - input_shape = Tensor(tuple(input_shape[::-1]), ms.float32) - loss = network(images, batch_y_true_0, batch_y_true_1, batch_y_true_2, batch_gt_box0, batch_gt_box1, - batch_gt_box2, input_shape) - loss_meter.update(loss.asnumpy()) - - if args.rank_save_ckpt_flag: - # ckpt progress - cb_params.cur_step_num = i + 1 # current step number - cb_params.batch_num = i + 2 - ckpt_cb.step_end(run_context) - - if i % args.log_interval == 0: - time_used = time.time() - t_end - epoch = int(i / args.steps_per_epoch) - fps = args.per_batch_size * (i - old_progress) * args.group_size / time_used - if args.rank == 0: - args.logger.info( - 'epoch[{}], iter[{}], {}, {:.2f} imgs/sec, lr:{}'.format(epoch, i, loss_meter, fps, lr[i])) - t_end = time.time() - loss_meter.reset() - old_progress = i - - if (i + 1) % args.steps_per_epoch == 0 and args.rank_save_ckpt_flag: - cb_params.cur_epoch_num += 1 - - if args.need_profiler: - if i == 10: - profiler.analyse() - break - - args.logger.info('==========end training===============') - - -if __name__ == "__main__": - train() diff --git a/official/nlp/q8bert/README.md b/official/nlp/q8bert/README.md deleted file mode 100644 index 340820d465d096c1ebbbb23fe6cfcae825936ff8..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/README.md +++ /dev/null @@ -1,220 +0,0 @@ - -# Contents - -- [Contents](#Contents) -- [Q8BERT Description](#Q8BERT-Description) -- [Model Architecture](#Model-architecture) -- [Dataset](#Dataset) -- [Environment Requirements](#Environment-requirements) -- [Quick Start](#Quick-start) -- [Script Description](#Script-description) - - [Script and Sample Code](#Script-and-sample-code) - - [Parameters](#Parameters) - - [Training Process](#Training-Process) - - [Running on Ascend and GPU platform](#Running-on-Ascend-and-GPU-platform) - - [Training based STS-B dataset](#Training-based-STS-B-dataset) - - [Evaling Process](#Evaling-process) - - [Evaling based STS-B dataset](#Evaling-based-STS-B-dataset) - - [Export model](#Export-model) - - [Performance](#Performance) - - [Performance Evaluation](#Performance-Evaluation) -- [Description of Random Situation](#Description-of-random-situation) -- [ModelZoo Homepage](#Modelzoo-homepage) - -# [Q8BERT Description](#contents) - -[Q8BERT](https://arxiv.org/abs/1910.06188) is the model where the quantization-aware training is applied into [BERT](https://arxiv.org/abs/1810.04805) -in order to compress BERT size under minimal accuracy loss. Furthermore, the -produced quantized model can accelerate inference speed if it is optimized for 8bit Integer supporting hardware. - -[Paper](https://arxiv.org/abs/1910.06188): Ofir Zafrir, Guy Boudoukh, Peter Izsak and Moshe Wasserblat. [Q8BERT: Quantized 8Bit BERT](https://arxiv.org/abs/1910.06188). arXiv preprint arXiv:2009.12812. - -# [Model Architecture](#contents) - -The backbone structure of Q8BERT is transformer, the transformer contains 12 encoder modules, one encoder contains one self-attention module and one self-attention module contains one attention module. - -# [Dataset](#contents) - -- Download glue dataset for fine-tuning. Convert dataset files from json format to tfrecord format, please refer to run_classifier.py which in [BERT](https://github.com/google-research/bert) repository. - -# [Environment Requirements](#contents) - -- Hardware - - Prepare hardware environment with Ascend or GPU processor. -- Framework - - [MindSpore](https://gitee.com/mindspore/mindspore) -- For more information, please check the resources below锛� - - [MindSpore Tutorials](https://www.mindspore.cn/tutorials/en/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/en/master/index.html) -- Software锛� - - numpy, sklearn - -# [Quick Start](#contents) - -After installing MindSpore via the official website, you can start training and evaluation as follows: - -```bash - -# run training example -bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -# run evaling example -bash run_eval.sh [TASK_NAME] [DEVICE_TARGET] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -``` - -# [Script Description](#contents) - -## [Script and Sample Code](#contents) - -```text -鈹斺攢q8bert - 鈹溾攢README.md # document in English - 鈹溾攢README_CN.md # document in Chinese - 鈹溾攢scripts - 鈹溾攢run_standalone_train.sh # shell script for training phase - 鈹溾攢run_eval.sh # shell script for evaling phase - 鈹溾攢src - 鈹溾攢__init__.py - 鈹溾攢dataset.py # data processing - 鈹溾攢bert_model.py # backbone code of bert - 鈹溾攢q8bert_model.py # quantization for Bert - 鈹溾攢q8bert.py # backbone code of Q8BERT - 鈹溾攢utils.py # some utils function of Q8BERT - 鈹溾攢__init__.py - 鈹溾攢train.py # train net - 鈹溾攢eval.py # eval net - 鈹溾攢export.py # export model - -## [Script Parameters] - -### Train - -```text - -usage: -bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] - -options: - [TASK_NAME] The name of the task to train: "STS-B"锝� "QNLI"锝� SST-2" - [DEVICE_TARGET] Device where the code will be implemented: "GPU" | "Ascend" - [TRAIN_DATA_DIR] Train Data directory - [EVAL_DATA_DIR] Eval Data directory - [LOAD_CKPT_PATH] The checkpoint directory of model -or - -python train.py [--h] [--device_target {GPU,Ascend}] [--epoch_num EPOCH_NUM] [--task_name {SST-2, QNLI, STS-B}] - [--do_shuffle {True,False}] [--enable_data_sink {True,False}] [--do_eval {True,False}] - [--device_id DEVICE_ID] [--save_ckpt_step SAVE_CKPT_STEP] [--eval_ckpt_step EVAL_CKPT_STEP] - [--max_ckpt_num MAX_CKPT_NUM] [--load_ckpt_path LOAD_CKPT_PATH] [--train_data_dir TRAIN_DATA_DIR] - [--eval_data_dir EVAL_DATA_DIR] [--device_id DEVICE_ID] [--logging_step LOGGIND_STEP] - [--do_quant {True,False}] - -options: - --device_target Device where the code will be implemented: "GPU" | "Ascend", default is "GPU" - --do_eval Do eval task during training or not: "True" | "False", default is "True" - --epoch_num Epoch num for train phase: N, default is 3 - --device_id Device id: N, default is 0 - --do_shuffle Enable shuffle for train dataset: "True" | "False", default is "True" - --enable_data_sink Enable data sink: "True" | "False", default is "True" - --save_ckpt_step If do_eval is False, the checkpoint will be saved every save_ckpt_step: N, default is 50 - --eval_ckpt_step If do_eval is True, the evaluation will be ran every eval_ckpt_step: N, default is 50 - --max_ckpt_num The number of checkpoints will not be larger than max_ckpt_num: N, default is 50 - --data_sink_steps Sink steps for each epoch: N, default is 1 - --load_ckpt_path The checkpoint directory of model: PATH, default is "" - --train_data_dir Train Data directory: PATH, default is "" - --eval_data_dir Eval Data directory: PATH, default is "" - --task_name The name of the task to train: "STS-B"锝� "QNLI"锝� SST-2" - --dataset_type The name of the task to train: "tfrecord" | "mindrecord", default is "tfrecord" - --train_batch_size Batch size for training: N, default is 16 - --eval_batch_size Eval Batch size in callback: N, default is 32 - -``` - -## [Training Process](#contents) - -### Running on Ascend and GPU platform - -Before running the command below, please check that all required parameters have been set. The parameter of path would better be the absolute path. The options of parameter DEVICE_TARGET contains Ascend and GPU, which means the model will run in Ascend and GPU platform respectively. - -### Training based STS-B dataset - -This model currently supports STS-B, QNLI and SST-2 datasets, following example is based on STS-B dataset. - -```text - -shell - bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -example: - bash run_standalone_train.sh STS-B Ascend /path/sts-b/train.tf_record /path/sts-b/eval.tf_record /path/xxx.ckpt - -``` - -The shell command above will run in the background, you can view the results the file train_log.txt. The python command will run in the console, you can view the results on the interface. - -```text - -epoch: 1, step: 100, loss: 0.526506 -The current result is {'pearson': 0.8407084843799768, 'spearmanr': 0.8405771469597393, 'corr': 0.840642815669858}, the best result is 0.8407084843799768 -epoch time: 147446.514 ms, per step time: 1474.465 ms -epoch: 2, step: 200, loss: 0.406012 -The current result is {'pearson': 0.826509808575773, 'spearmanr': 0.8274141859302444, 'corr': 0.8269619972530087}, the best result is 0.8407084843799768 -epoch time: 93688.080 ms, per step time: 936.881 ms -... - - After training, checkpoint files will be saved at relative folder under the root folder of the project. - -``` - -## [Evaling Process](#contents) - -### Evaling based STS-B dataset - -```text - -shell - bash run_eval.sh [TASK_NAME] [DEVICE_TARGET] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -example: - bash run_eval.sh STS-B Ascend /path/sts-b/eval.tf_record /path/xxx.ckpt - -``` - -The shell command above will run in the background, you can view the results the file eval_log.txt. The python command will run in the console, you can view the results on the interface. - -```text - -The current result is {'pearson': 0.826509808575773, 'spearmanr': 0.8274141859302444, 'corr': 0.8269619972530087}, the best result is 0.8407084843799768 - -``` - -## [Export model](#contents) - -```text - -python export.py --task_name [TASK_NAME] --ckpt_file [CKPT_FILE] --file_format [FILE_FORMAT] - -``` - -The file_format parameter should be inside ["AIR", "MINDIR"] - -## [Performance](#contents) - -### Performance Evaluation - -| Parameters | Ascend | GPU | -| -------------------------- | ---------------------------------------------------------- | ------------------------- | -| Model Version | Q8BERT | Q8BERT | -| Resource | Ascend 910, cpu 2.60GHz, cores 172, mem 755G, os Euler2.8 | NV GeForce GTX1080ti, cpu 2.00GHz, cores 56, mem 251G, os Ubuntu 16.04 | -| Date | 2021-6-8 | 2021-6-8 | -| MindSpore Version | 1.2.0 | 1.2.0 | -| Dataset | STS-B | STS-B | -| Total Time | 11mins (3epoch, 1p) | 18mins (3epoch, 1p) | -| Metric value | 89.14 | 89.18 | - -# [Description of Random Situation](#contents) - -In train.py, we set do_shuffle to shuffle the dataset. - -In config.py, we set the hidden_dropout_prob, attention_pros_dropout_prob and cls_dropout_prob to dropout some network node. - -# [ModelZoo Homepage](#contents) - -Please check the official [homepage](https://gitee.com/mindspore/models). diff --git a/official/nlp/q8bert/README_CN.md b/official/nlp/q8bert/README_CN.md deleted file mode 100644 index 52dc9d4fdb3ec79c2ef3ee4b67301193cdbd0559..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/README_CN.md +++ /dev/null @@ -1,217 +0,0 @@ - -# 鐩綍 - -<!-- TOC --> - -- [鐩綍](#鐩綍) -- [Q8BERT姒傝堪](#Q8BERT姒傝堪) -- [妯″瀷鏋舵瀯](#妯″瀷鏋舵瀯) -- [鏁版嵁闆哴(#鏁版嵁闆�) -- [鐜瑕佹眰](#鐜瑕佹眰) -- [蹇€熷叆闂╙(#蹇€熷叆闂�) -- [鑴氭湰璇存槑](#鑴氭湰璇存槑) - - [鑴氭湰鍜屾牱渚嬩唬鐮乚(#鑴氭湰鍜屾牱渚嬩唬鐮�) - - [鑴氭湰鍙傛暟](#鑴氭湰鍙傛暟) - - [閫夐」鍙婂弬鏁癩(#閫夐」鍙婂弬鏁�) - - [閫夐」](#閫夐」) - - [鍙傛暟](#鍙傛暟) - - [璁粌娴佺▼](#璁粌娴佺▼) - - [Ascend鍜孏PU骞冲彴涓婅繍琛宂(#Ascend鍜孏PU骞冲彴涓婅繍琛�) - - [鍩轰簬STS-B鏁版嵁闆嗚繘琛岃缁僝(#鍩轰簬STS-B鏁版嵁闆嗚繘琛岃缁�) - - [璇勪及娴佺▼](#璇勪及娴佺▼) - - [鍩轰簬STS-B鏁版嵁闆嗚繘琛岃瘎浼癩(#鍩轰簬STS-B鏁版嵁闆嗚繘琛岃瘎浼�) - - [妯″瀷瀵煎嚭](#妯″瀷瀵煎嚭) - - [鎬ц兘](#鎬ц兘) - - [璇勪及鎬ц兘](#璇勪及鎬ц兘) -- [闅忔満鎯呭喌璇存槑](#闅忔満鎯呭喌璇存槑) -- [ModelZoo涓婚〉](#modelzoo涓婚〉) - -<!-- /TOC --> - -# Q8BERT姒傝堪 - -[Q8BERT](https://arxiv.org/abs/1910.06188)鏄竴绉嶅皢璁粌涓噺鍖栫瓥鐣ュ簲鐢ㄥ埌BERT鐨勬ā鍨嬶紝璁粌鐢熸垚鐨勬ā鍨嬪湪绮惧害鎹熷け杈冨皬鐨勬儏鍐典笅锛屽彲浠ュ噺灏忔ā鍨嬪瓨鍌ㄥ昂瀵革紝鑰屼笖鍦ㄦ敮鎸�8bit閲忓寲绠楀瓙鐨勭‖浠跺钩鍙颁笂锛屽彲浠ュ姞閫熸帹鐞嗐€� - -[璁烘枃](https://arxiv.org/abs/1910.06188): Ofir Zafrir, Guy Boudoukh, Peter Izsak and Moshe Wasserblat. [Q8BERT: Quantized 8Bit BERT](https://arxiv.org/abs/1910.06188).arXiv preprint arXiv:2009.12812. - -# 妯″瀷鏋舵瀯 - -Q8BERT妯″瀷鐨勪富骞茬粨鏋勬槸transformer锛屼竴涓浆鎹㈠櫒鍖呭惈12涓紪鐮佸櫒妯″潡銆� - -# 鏁版嵁闆� - -- 涓嬭浇GLUE鏁版嵁闆嗚繘琛屽井璋冦€傚皢鏁版嵁闆嗙敱JSON鏍煎紡杞寲涓篢FRecord鏍煎紡銆傝瑙乕BERT](https://github.com/google-research/bert)浠g爜搴撲腑鐨剅un_classifier.py鏂囦欢銆� - -# 鐜瑕佹眰 - -- 纭欢 - - 浣跨敤Ascend鎴朑PU骞冲彴銆� -- 妗嗘灦 - - [MindSpore](https://gitee.com/mindspore/mindspore) -- 鏇村鍏充簬Mindspore鐨勪俊鎭紝璇锋煡鐪嬩互涓嬭祫婧愶細 - - [MindSpore鏁欑▼](https://www.mindspore.cn/tutorials/zh-CN/master/index.html) - - [MindSpore Python API](https://www.mindspore.cn/docs/api/zh-CN/master/index.html) -- 杞欢鍖咃細 - - numpy, sklearn - -# 蹇€熷叆闂� - -浠庡畼缃戜笅杞藉畨瑁匨indSpore涔嬪悗锛屽彲浠ュ紑濮嬩娇鐢ㄥ涓嬭剼鏈缁冨拰鎺ㄧ悊锛� - -```bash -# 杩愯璁粌鑴氭湰 -bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -# 杩愯鎺ㄧ悊鑴氭湰 -bash run_eval.sh [TASK_NAME] [DEVICE_TARGET] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] - -``` - -# 鑴氭湰璇存槑 - -## 鑴氭湰鍜屾牱渚嬩唬鐮� - -```shell - -鈹斺攢q8bert - 鈹溾攢README.md # 鑻辨枃璇存槑鏂囨。 - 鈹溾攢README_CN.md # 涓枃璇存槑鏂囨。 - 鈹溾攢scripts - 鈹溾攢run_standalone_train.sh # 杩愯shell璁粌鑴氭湰 - 鈹溾攢run_eval.sh # 杩愯shell鎺ㄧ悊鑴氭湰 - 鈹溾攢src - 鈹溾攢__init__.py - 鈹溾攢dataset.py # 鏁版嵁澶勭悊 - 鈹溾攢bert_model.py # bert妯″瀷涓讳綋缁撴瀯 - 鈹溾攢q8bert_model.py # bert妯″瀷閲忓寲鎰熺煡绠楁硶 - 鈹溾攢q8bert.py # Q8BERT涓讳綋缁撴瀯 - 鈹溾攢utils.py # utils鍑芥暟 - 鈹溾攢__init__.py - 鈹溾攢train.py # 鎵ц璁粌 - 鈹溾攢eval.py # 鎵ц鎺ㄧ悊 - 鈹溾攢export.py # 妯″瀷瀵煎嚭 -``` - -## 鑴氭湰鍜岃剼鏈弬鏁� - -```text -鐢ㄦ硶 -bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] - -閫夐」锛� - [TASK_NAME] Glue鏁版嵁闆嗕换鍔�: "STS-B"锝� "QNLI"锝� SST-2" - [DEVICE_TARGET] 浠g爜杩愯骞冲彴锛屽彲閫夐」涓篈scend鎴朑PU - [TRAIN_DATA_DIR] 璁粌闆嗚矾寰� - [EVAL_DATA_DIR] 楠岃瘉闆嗚矾寰� - [LOAD_CKPT_PATH] 鍔犺浇妫€鏌ョ偣鏂囦欢鐨勮矾寰� - -鎴栬€� - -python train.py [--h] [--device_target {GPU,Ascend}] [--epoch_num EPOCH_NUM] [--task_name {SST-2, QNLI, STS-B}] - [--do_shuffle {True,False}] [--enable_data_sink {True,False}] [--do_eval {True,False}] - [--device_id DEVICE_ID] [--save_ckpt_step SAVE_CKPT_STEP] [--eval_ckpt_step EVAL_CKPT_STEP] - [--max_ckpt_num MAX_CKPT_NUM] [--load_ckpt_path LOAD_CKPT_PATH] [--train_data_dir TRAIN_DATA_DIR] - [--eval_data_dir EVAL_DATA_DIR] [--device_id DEVICE_ID] [--logging_step LOGGIND_STEP] - [--do_quant {True,False}] -閫夐」锛� - --device_target 浠g爜杩愯骞冲彴锛屽彲閫夐」涓篈scend鎴朑PU锛岄粯璁や负Ascend - --do_eval 鏄惁鍦ㄨ缁冪殑杩囩▼涓姞涓婃帹鐞嗛粯璁や负True - --epoch_num Epoch鏁帮紝榛樿涓�3 - --device_id 璁惧ID锛岄粯璁や负0 - --do_shuffle 鏄惁鏁版嵁杞崲锛屽彲閫夐」涓篢rue鎴朏alse锛岄粯璁や负True - --enable_data_sink 鏄惁鏁版嵁涓嬫矇锛屽彲閫夐」涓篢rue鎴朏alse锛岄粯璁や负True - --save_ckpt_step 淇濆瓨妫€鏌ョ偣鏂囦欢鐨勬鏁帮紝榛樿涓�1000 - --eval_ckpt_step 褰揹o_eval涓篢rue锛� 鍦ㄨ缁冭繃绋嬩腑鎵ц鎺ㄧ悊鐨勬鏁� - --max_ckpt_num 淇濆瓨妫€鏌ョ偣鏂囦欢鐨勬渶澶ф暟锛岄粯璁や负1 - --data_sink_steps 璁剧疆鏁版嵁涓嬫矇姝ユ暟锛岄粯璁や负1 - --load_ckpt_path 鍔犺浇妫€鏌ョ偣鏂囦欢鐨勮矾寰勶紝榛樿涓�"" - --train_data_dir 璁粌闆嗚矾寰勶紝 榛樿涓� "" - --eval_data_dir 楠岃瘉闆嗚矾寰勶紝 榛樿涓� "" - --task_name Glue鏁版嵁闆嗕换鍔�: "STS-B"锝� "QNLI"锝� SST-2" - --dataset_type 鏁版嵁闆嗙被鍨嬶紝鍙€夐」涓簍frecord鎴杕indrecord锛岄粯璁や负tfrecord - --train_batch_size 璁粌batchsize锛岄粯璁�16 - --eval_batch_size 鎺ㄧ悊batchsize锛岄粯璁�32 - -``` - -## 璁粌娴佺▼ - -### Ascend鍜孏PU骞冲彴涓婅繍琛� - -杩愯浠ヤ笅鍛戒护鍓嶏紝纭繚宸茶缃墍鏈夊繀闇€鍙傛暟銆傚缓璁矾寰勫弬鏁拌缃垚缁濆璺緞銆侱EVICE_TARGET鍙傛暟鍙€夐」涓篈scend鍜孏PU锛屽垎鍒唬琛ㄦā鍨嬪湪Ascend鍜孏PU骞冲彴杩愯銆� - -### 鍩轰簬STS-B鏁版嵁闆嗚繘琛岃缁� - -鏈ā鍨嬬洰鍓嶆敮鎸佲€漇TS-B鈥滐紝鈥漄NLI鈥滐紝鈥淪ST-2鈥濇暟鎹泦锛屼互鈥漇TS-B鈥滀负渚嬭繘琛岃瘎浼般€� - -```text -shell - bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -example: - bash run_standalone_train.sh STS-B Ascend /path/sts-b/train.tf_record /path/sts-b/eval.tf_record /path/xxx.ckpt - -``` - -浠ヤ笂鍛戒护鍚庡彴杩愯锛屽彲浠ュ湪train_log.txt鏂囦欢涓煡鐪嬭繍琛岀粨鏋滐細 - -```text -epoch: 1, step: 100, loss: 0.526506 -The current result is {'pearson': 0.8407084843799768, 'spearmanr': 0.8405771469597393, 'corr': 0.840642815669858}, the best result is 0.8407084843799768 -epoch time: 147446.514 ms, per step time: 1474.465 ms -epoch: 2, step: 200, loss: 0.406012 -The current result is {'pearson': 0.826509808575773, 'spearmanr': 0.8274141859302444, 'corr': 0.8269619972530087}, the best result is 0.8407084843799768 -epoch time: 93688.080 ms, per step time: 936.881 ms -... - -璁粌缁撴潫鍚庯紝鍙互鍦ㄥ伐绋嬫牴鐩綍瀵瑰簲鐨勬枃浠跺す涓壘鍒版鏌ョ偣鏂囦欢銆� - -``` - -## 璇勪及娴佺▼ - -### 鍩轰簬STS-B鏁版嵁闆嗚繘琛岃瘎浼� - -```text -shell - bash run_eval.sh [TASK_NAME] [DEVICE_TARGET] [EVAL_DATA_DIR] [LOAD_CKPT_PATH] -example: - bash run_eval.sh STS-B Ascend /path/sts-b/eval.tf_record /path/xxx.ckpt -``` - -浠ヤ笂鍛戒护鍚庡彴杩愯锛屽彲浠ュ湪eval_log.txt鏂囦欢涓煡鐪嬭繍琛岀粨鏋滐細 - -```text -The current result is {'pearson': 0.826509808575773, 'spearmanr': 0.8274141859302444, 'corr': 0.8269619972530087}, the best result is 0.8407084843799768 - -``` - -## 妯″瀷瀵煎嚭 - -```text -python export.py --task_name [TASK_NAME] --ckpt_file [CKPT_FILE] --file_format [FILE_FORMAT] -``` - -妯″瀷瀵煎嚭鏍煎紡閫夐」锛歔"AIR", "MINDIR"] - -## 鎬ц兘 - -### 璇勪及鎬ц兘 - -| 鍙傛暟 | Ascend | GPU | -| -------------------------- | ---------------------------------------------------------- | ------------------------- | -| 妯″瀷鐗堟湰 | Q8BERT | Q8BERT | -| 璧勬簮 | Ascend 910锛宑pu 2.60GHz锛�192鏍革紝鍐呭瓨 755G锛岀郴缁� Euler2.8 | NV GeForce GTX1080ti锛宑pu 2.00GHz锛�56鏍革紝鍐呭瓨 251G锛岀郴缁� Ubuntu16.04 | -| 涓婁紶鏃ユ湡 | 2021-6-8 | 2021-6-8 | -| MindSpore鐗堟湰 | 1.2.0 | 1.2.0 | -| 鏁版嵁闆� | STS-B | STS-B | -| 鎬绘椂闀� | 11鍒嗛挓 (3杞�, 1鍗�) | 18鍒嗛挓 (3杞�, 1鍗�) | -| 绮惧害 | 89.14 | 89.18 | - -# 闅忔満鎯呭喌璇存槑 - -train.py鑴氭湰涓缃簡do_shuffle鍙傛暟鐢ㄤ簬杞崲鏁版嵁闆嗐€� - -config.py鏂囦欢涓缃甴idden_dropout_prob鍜宎ttention_pros_dropout_prob鍙傛暟锛屼娇缃戠粶鑺傜偣闅忔満澶辨椿銆� - -# ModelZoo涓婚〉 - -璇锋祻瑙堝畼缃慬涓婚〉](https://gitee.com/mindspore/models)銆� diff --git a/official/nlp/q8bert/__init__.py b/official/nlp/q8bert/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/official/nlp/q8bert/eval.py b/official/nlp/q8bert/eval.py deleted file mode 100644 index e0075fce8e8c944f172673a3916d3e4adc54fc03..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/eval.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""q8bert eval""" - -import argparse -import ast -import numpy as np - -from mindspore import context - -from src.dataset import create_dataset -from src.q8bert import BertNetworkWithLoss_td -from src.config import eval_cfg, model_cfg, glue_output_modes, task_params -from src.utils import glue_compute_metrics - - -def parse_args(): - """ - parse args - """ - parser = argparse.ArgumentParser(description='Q8Bert task eval') - 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("--device_id", type=int, default=0, help="Device id, default is 0.") - parser.add_argument("--eval_data_dir", type=str, default="", - help="Eval data path, it is better to use absolute path") - parser.add_argument("--load_ckpt_path", type=str, default="", help="Load checkpoint file path") - parser.add_argument("--do_quant", type=ast.literal_eval, default=True, help="Do quant for model") - parser.add_argument("--task_name", type=str, default="STS-B", choices=["STS-B", "QNLI", "SST-2"], - help="The name of the task to eval.") - parser.add_argument("--dataset_type", type=str, default="tfrecord", - help="dataset type tfrecord/mindrecord, default is tfrecord") - args = parser.parse_args() - return args - - -args_opt = parse_args() - -DEFAULT_NUM_LABELS = 2 -DEFAULT_SEQ_LENGTH = 128 - - -class Task: - """ - Encapsulation class of get the task parameter. - """ - def __init__(self, task_name): - self.task_name = task_name - - @property - def num_labels(self): - if self.task_name in task_params and "num_labels" in task_params[self.task_name]: - return task_params[self.task_name]["num_labels"] - return DEFAULT_NUM_LABELS - - @property - def seq_length(self): - if self.task_name in task_params and "seq_length" in task_params[self.task_name]: - return task_params[self.task_name]["seq_length"] - return DEFAULT_SEQ_LENGTH - - -task = Task(args_opt.task_name) - - -def do_eval(): - """ - do eval - """ - ckpt_file = args_opt.load_ckpt_path - - if ckpt_file == '': - raise ValueError("Student ckpt file should not be None") - - if args_opt.device_target == "Ascend": - context.set_context(mode=context.GRAPH_MODE, device_target=args_opt.device_target, device_id=args_opt.device_id) - elif args_opt.device_target == "GPU": - context.set_context(mode=context.GRAPH_MODE, device_target=args_opt.device_target) - else: - raise Exception("Target error, GPU or Ascend is supported.") - - load_student_checkpoint_path = ckpt_file - netwithloss = BertNetworkWithLoss_td(student_config=model_cfg, student_ckpt=load_student_checkpoint_path, - do_quant=args_opt.do_quant, is_training=True, - task_type=glue_output_modes[args_opt.task_name.lower()], - num_labels=task.num_labels, is_predistill=False) - eval_network = netwithloss.bert - rank = 0 - device_num = 1 - - eval_dataset = create_dataset(eval_cfg.batch_size, - device_num, rank, - do_shuffle=False, - data_dir=args_opt.eval_data_dir, - data_type=args_opt.dataset_type, - seq_length=task.seq_length, - drop_remainder=False) - dataset_size = eval_dataset.get_dataset_size() - print('eval dataset size: ', dataset_size) - - label_nums = 2 - if args_opt.task_name.lower == 'mnli': - label_nums = 3 - eval_network.set_train(False) - columns_list = ["input_ids", "input_mask", "segment_ids", "label_ids"] - preds = None - out_label_ids = None - for data in eval_dataset.create_dict_iterator(num_epochs=1): - input_data = [] - for i in columns_list: - input_data.append(data[i]) - input_ids, input_mask, token_type_id, label_ids = input_data - _, _, logits, _ = eval_network(input_ids, token_type_id, input_mask) - if preds is None: - preds = logits.asnumpy() - preds = np.reshape(preds, [-1, label_nums]) - out_label_ids = label_ids.asnumpy() - else: - preds = np.concatenate((preds, np.reshape(logits.asnumpy(), [-1, label_nums])), axis=0) - out_label_ids = np.append(out_label_ids, label_ids.asnumpy()) - if glue_output_modes[args_opt.task_name.lower()] == "classification": - preds = np.argmax(preds, axis=1) - elif glue_output_modes[args_opt.task_name.lower()] == "regression": - preds = np.reshape(preds, [-1]) - result = glue_compute_metrics(args_opt.task_name.lower(), preds, out_label_ids) - print("The current result is {}".format(result)) - - -if __name__ == '__main__': - model_cfg.seq_length = task.seq_length - do_eval() diff --git a/official/nlp/q8bert/export.py b/official/nlp/q8bert/export.py deleted file mode 100644 index f3b08bd0929f37a7c9a234559726f3ebfd22a85c..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/export.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""export checkpoint file into model""" - -import argparse -import numpy as np - -from mindspore import Tensor, context -from mindspore.train.serialization import load_checkpoint, load_param_into_net, export - -from src.config import model_cfg, task_params -from src.q8bert_model import BertModelCLS - -parser = argparse.ArgumentParser(description="Q8Bert export model") -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("--task_name", type=str, default="STS-B", choices=["STS-B", "QNLI", "SST-2"], - help="The name of the task to eval.") -parser.add_argument("--file_name", type=str, default="q8bert", help="The name of the output file.") -parser.add_argument("--file_format", type=str, default="AIR", choices=["AIR", "MINDIR"], - help="output model type") -parser.add_argument("--ckpt_file", type=str, required=True, help="pretrained checkpoint file") -args = parser.parse_args() - -context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target) - -DEFAULT_NUM_LABELS = 2 -DEFAULT_SEQ_LENGTH = 128 -DEFAULT_BS = 32 - - -class Task: - """ - Encapsulation class of get the task parameter. - """ - - def __init__(self, task_name): - self.task_name = task_name - - @property - def num_labels(self): - if self.task_name in task_params and "num_labels" in task_params[self.task_name]: - return task_params[self.task_name]["num_labels"] - return DEFAULT_NUM_LABELS - - @property - def seq_length(self): - if self.task_name in task_params and "seq_length" in task_params[self.task_name]: - return task_params[self.task_name]["seq_length"] - return DEFAULT_SEQ_LENGTH - - -if __name__ == "__main__": - task = Task(args.task_name) - model_cfg.seq_length = task.seq_length - model_cfg.batch_size = DEFAULT_BS - eval_model = BertModelCLS(model_cfg, False, task.num_labels, 0.0, phase_type="student") - param_dict = load_checkpoint(args.ckpt_file) - load_param_into_net(eval_model, param_dict) - eval_model.set_train(False) - - input_ids = Tensor(np.zeros((model_cfg.batch_size, task.seq_length), np.int32)) - token_type_id = Tensor(np.zeros((model_cfg.batch_size, task.seq_length), np.int32)) - input_mask = Tensor(np.zeros((model_cfg.batch_size, task.seq_length), np.int32)) - - input_data = [input_ids, token_type_id, input_mask] - export(eval_model, *input_data, file_name=args.file_name, file_format=args.file_format, quant_model="QUANT") diff --git a/official/nlp/q8bert/requirements.txt b/official/nlp/q8bert/requirements.txt deleted file mode 100644 index 2a8dd72343ded4e440547739891022d2ab242a33..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -numpy -scipy -sklearn -easydict diff --git a/official/nlp/q8bert/scripts/run_eval.sh b/official/nlp/q8bert/scripts/run_eval.sh deleted file mode 100644 index 9bef1f54fd2004a04f5adf9fbcf3c9779170fb26..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/scripts/run_eval.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [ $# != 4 ] -then - echo "============================================================================================================" - echo "Please run the script as: " - echo "bash run_eval.sh [TASK_NAME] [DEVICE_TARGET] [EVAL_DATA_DIR] [LOAD_CKPT_PATH]" - echo "for example: bash run_eval.sh STS-B Ascend /path/sts-b/eval.tf_record /path/xxx.ckpt" - echo "============================================================================================================" -exit 1 -fi - -echo "===============================================start evaling================================================" - -task_name=$1 -device_target=$2 -eval_data_dir=$3 -load_ckpt_path=$4 - -mkdir -p ms_log -PROJECT_DIR=$(cd "$(dirname "$0")" || exit; pwd) -CUR_DIR=`pwd` -export GLOG_log_dir=${CUR_DIR}/ms_log -export GLOG_logtostderr=0 - -python ${PROJECT_DIR}/../eval.py \ - --task_name=$task_name \ - --device_target=$device_target \ - --device_id=0 \ - --load_ckpt_path=$load_ckpt_path \ - --eval_data_dir=$eval_data_dir \ - --do_quant=True > eval_log.txt 2>&1 & - diff --git a/official/nlp/q8bert/scripts/run_standalone_train.sh b/official/nlp/q8bert/scripts/run_standalone_train.sh deleted file mode 100644 index 52ef0070512e9a0fbea0be3c3216cafe59d46671..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/scripts/run_standalone_train.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/bash -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# ============================================================================ - -if [ $# != 5 ] -then - echo "============================================================================================================" - echo "Please run the script as: " - echo "bash run_standalone_train.sh [TASK_NAME] [DEVICE_TARGET] [TRAIN_DATA_DIR] [EVAL_DATA_DIR] [LOAD_CKPT_PATH]" - echo "for example: bash run_standalone_train.sh STS-B Ascend /path/sts-b/train.tf_record /path/sts-b/eval.tf_record /path/xxx.ckpt" - echo "============================================================================================================" -exit 1 -fi - -echo "===============================================start training===============================================" - -task_name=$1 -device_target=$2 -train_data_dir=$3 -eval_data_dir=$4 -load_ckpt_path=$5 - -mkdir -p ms_log -PROJECT_DIR=$(cd "$(dirname "$0")" || exit; pwd) -CUR_DIR=`pwd` -export GLOG_log_dir=${CUR_DIR}/ms_log -export GLOG_logtostderr=0 -export MS_COMPILER_OP_LEVEL=1 - -python ${PROJECT_DIR}/../train.py \ - --task_name=$task_name \ - --device_target=$device_target \ - --device_id=0 \ - --do_eval=True \ - --load_ckpt_path=$load_ckpt_path \ - --train_data_dir=$train_data_dir \ - --eval_data_dir=$eval_data_dir \ - --epoch_num=3 \ - --logging_step=100 \ - --data_sink_steps=100 \ - --save_ckpt_step=100 \ - --do_quant=True > train_log.txt 2>&1 & diff --git a/official/nlp/q8bert/src/__init__.py b/official/nlp/q8bert/src/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/official/nlp/q8bert/src/bert_model.py b/official/nlp/q8bert/src/bert_model.py deleted file mode 100644 index 8031a86102553b0dfd070f3db2bf179e025800fe..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/src/bert_model.py +++ /dev/null @@ -1,1011 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== -"""Bert model.""" -import math -import copy -import numpy as np -import mindspore.common.dtype as mstype -import mindspore.nn as nn -import mindspore.ops.functional as F -from mindspore.common.initializer import Normal, initializer -from mindspore.ops import operations as P -from mindspore.ops import composite as C -from mindspore.common.tensor import Tensor -from mindspore.common.parameter import Parameter -from mindspore import context - - -class BertConfig: - """ - Configuration for `BertModel`. - - Args: - seq_length (int): Length of input sequence. Default: 128. - vocab_size (int): The shape of each embedding vector. Default: 32000. - hidden_size (int): Size of the bert encoder layers. Default: 768. - num_hidden_layers (int): Number of hidden layers in the BertTransformer encoder - cell. Default: 12. - num_attention_heads (int): Number of attention heads in the BertTransformer - encoder cell. Default: 12. - intermediate_size (int): Size of intermediate layer in the BertTransformer - encoder cell. Default: 3072. - hidden_act (str): Activation function used in the BertTransformer encoder - cell. Default: "gelu". - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.1. - max_position_embeddings (int): Maximum length of sequences used in this - model. Default: 512. - type_vocab_size (int): Size of token type vocab. Default: 16. - initializer_range (float): Initialization value of Normal. Default: 0.02. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - dtype (:class:`mindspore.dtype`): Data type of the input. Default: mstype.float32. - compute_type (:class:`mindspore.dtype`): Compute type in BertTransformer. Default: mstype.float32. - """ - - def __init__(self, - seq_length=128, - vocab_size=32000, - hidden_size=768, - num_hidden_layers=12, - num_attention_heads=12, - intermediate_size=3072, - hidden_act="gelu", - hidden_dropout_prob=0.1, - attention_probs_dropout_prob=0.1, - max_position_embeddings=512, - type_vocab_size=16, - initializer_range=0.02, - use_relative_positions=False, - dtype=mstype.float32, - compute_type=mstype.float32): - self.seq_length = seq_length - self.vocab_size = vocab_size - self.hidden_size = hidden_size - self.num_hidden_layers = num_hidden_layers - self.num_attention_heads = num_attention_heads - self.hidden_act = hidden_act - self.intermediate_size = intermediate_size - self.hidden_dropout_prob = hidden_dropout_prob - self.attention_probs_dropout_prob = attention_probs_dropout_prob - self.max_position_embeddings = max_position_embeddings - self.type_vocab_size = type_vocab_size - self.initializer_range = initializer_range - self.use_relative_positions = use_relative_positions - self.dtype = dtype - self.compute_type = compute_type - - -class EmbeddingLookup(nn.Cell): - """ - A embeddings lookup table with a fixed dictionary and size. - - Args: - vocab_size (int): Size of the dictionary of embeddings. - embedding_size (int): The size of each embedding vector. - embedding_shape (list): [batch_size, seq_length, embedding_size], the shape of - each embedding vector. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - """ - - def __init__(self, - vocab_size, - embedding_size, - embedding_shape, - use_one_hot_embeddings=False, - initializer_range=0.02): - super(EmbeddingLookup, self).__init__() - self.vocab_size = vocab_size - self.use_one_hot_embeddings = use_one_hot_embeddings - self.embedding_table = Parameter(initializer - (Normal(initializer_range), - [vocab_size, embedding_size])) - self.expand = P.ExpandDims() - self.shape_flat = (-1,) - self.gather = P.Gather() - self.one_hot = P.OneHot() - self.on_value = Tensor(1.0, mstype.float32) - self.off_value = Tensor(0.0, mstype.float32) - self.array_mul = P.MatMul() - self.reshape = P.Reshape() - self.shape = tuple(embedding_shape) - - def construct(self, input_ids): - """embedding lookup""" - extended_ids = self.expand(input_ids, -1) - flat_ids = self.reshape(extended_ids, self.shape_flat) - if self.use_one_hot_embeddings: - one_hot_ids = self.one_hot(flat_ids, self.vocab_size, self.on_value, self.off_value) - output_for_reshape = self.array_mul( - one_hot_ids, self.embedding_table) - else: - output_for_reshape = self.gather(self.embedding_table, flat_ids, 0) - output = self.reshape(output_for_reshape, self.shape) - return output, self.embedding_table - - -class EmbeddingPostprocessor(nn.Cell): - """ - Postprocessors apply positional and token type embeddings to word embeddings. - - Args: - embedding_size (int): The size of each embedding vector. - embedding_shape (list): [batch_size, seq_length, embedding_size], the shape of - each embedding vector. - use_token_type (bool): Specifies whether to use token type embeddings. Default: False. - token_type_vocab_size (int): Size of token type vocab. Default: 16. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - max_position_embeddings (int): Maximum length of sequences used in this - model. Default: 512. - dropout_prob (float): The dropout probability. Default: 0.1. - """ - - def __init__(self, - use_relative_positions, - embedding_size, - embedding_shape, - use_token_type=False, - token_type_vocab_size=16, - use_one_hot_embeddings=False, - initializer_range=0.02, - max_position_embeddings=512, - dropout_prob=0.1): - super(EmbeddingPostprocessor, self).__init__() - self.use_token_type = use_token_type - self.token_type_vocab_size = token_type_vocab_size - self.use_one_hot_embeddings = use_one_hot_embeddings - self.max_position_embeddings = max_position_embeddings - self.embedding_table = Parameter(initializer - (Normal(initializer_range), - [token_type_vocab_size, - embedding_size])) - self.shape_flat = (-1,) - self.one_hot = P.OneHot() - self.on_value = Tensor(1.0, mstype.float32) - self.off_value = Tensor(0.1, mstype.float32) - self.array_mul = P.MatMul() - self.reshape = P.Reshape() - self.shape = tuple(embedding_shape) - self.layernorm = nn.LayerNorm((embedding_size,)) - self.dropout = nn.Dropout(1 - dropout_prob) - self.gather = P.Gather() - self.use_relative_positions = use_relative_positions - self.slice = P.StridedSlice() - self.full_position_embeddings = Parameter(initializer - (Normal(initializer_range), - [max_position_embeddings, - embedding_size])) - - def construct(self, token_type_ids, word_embeddings): - """embedding postprocessor""" - output = word_embeddings - if self.use_token_type: - flat_ids = self.reshape(token_type_ids, self.shape_flat) - if self.use_one_hot_embeddings: - one_hot_ids = self.one_hot(flat_ids, - self.token_type_vocab_size, self.on_value, self.off_value) - token_type_embeddings = self.array_mul(one_hot_ids, - self.embedding_table) - else: - token_type_embeddings = self.gather(self.embedding_table, flat_ids, 0) - token_type_embeddings = self.reshape(token_type_embeddings, self.shape) - output += token_type_embeddings - if not self.use_relative_positions: - _, seq, width = self.shape - position_embeddings = self.slice(self.full_position_embeddings, (0, 0), (seq, width), (1, 1)) - position_embeddings = self.reshape(position_embeddings, (1, seq, width)) - output += position_embeddings - output = self.layernorm(output) - output = self.dropout(output) - return output - -class BertOutput(nn.Cell): - """ - Apply a linear computation to hidden status and a residual computation to input. - - Args: - in_channels (int): Input channels. - out_channels (int): Output channels. - initializer_range (float): Initialization value of Normal. Default: 0.02. - dropout_prob (float): The dropout probability. Default: 0.1. - compute_type (:class:`mindspore.dtype`): Compute type in BertTransformer. Default: mstype.float32. - """ - - def __init__(self, - in_channels, - out_channels, - initializer_range=0.02, - dropout_prob=0.1, - compute_type=mstype.float32,): - super(BertOutput, self).__init__() - self.dense = nn.Dense(in_channels, out_channels, - weight_init=Normal(initializer_range)).to_float(compute_type) - self.dropout = nn.Dropout(1 - dropout_prob) - self.add = P.Add() - self.is_gpu = context.get_context('device_target') == "GPU" - if self.is_gpu: - self.layernorm = nn.LayerNorm((out_channels,)).to_float(mstype.float32) - self.compute_type = compute_type - else: - self.layernorm = nn.LayerNorm((out_channels,)).to_float(compute_type) - self.cast = P.Cast() - - def construct(self, hidden_status, input_tensor): - """bert output""" - output = self.dense(hidden_status) - output = self.dropout(output) - output = self.add(input_tensor, output) - output = self.layernorm(output) - if self.is_gpu: - output = self.cast(output, self.compute_type) - return output - - -class RelaPosMatrixGenerator(nn.Cell): - """ - Generates matrix of relative positions between inputs. - - Args: - length (int): Length of one dim for the matrix to be generated. - max_relative_position (int): Max value of relative position. - """ - - def __init__(self, length, max_relative_position): - super(RelaPosMatrixGenerator, self).__init__() - self._length = length - self._max_relative_position = Tensor(max_relative_position, dtype=mstype.int32) - self._min_relative_position = Tensor(-max_relative_position, dtype=mstype.int32) - self.range_length = -length + 1 - self.tile = P.Tile() - self.range_mat = P.Reshape() - self.sub = P.Sub() - self.expanddims = P.ExpandDims() - self.cast = P.Cast() - - def construct(self): - """position matrix generator""" - range_vec_row_out = self.cast(F.tuple_to_array(F.make_range(self._length)), mstype.int32) - range_vec_col_out = self.range_mat(range_vec_row_out, (self._length, -1)) - tile_row_out = self.tile(range_vec_row_out, (self._length,)) - tile_col_out = self.tile(range_vec_col_out, (1, self._length)) - range_mat_out = self.range_mat(tile_row_out, (self._length, self._length)) - transpose_out = self.range_mat(tile_col_out, (self._length, self._length)) - distance_mat = self.sub(range_mat_out, transpose_out) - distance_mat_clipped = C.clip_by_value(distance_mat, - self._min_relative_position, - self._max_relative_position) - # Shift values to be >=0. Each integer still uniquely identifies a - # relative position difference. - final_mat = distance_mat_clipped + self._max_relative_position - return final_mat - - -class RelaPosEmbeddingsGenerator(nn.Cell): - """ - Generates tensor of size [length, length, depth]. - - Args: - length (int): Length of one dim for the matrix to be generated. - depth (int): Size of each attention head. - max_relative_position (int): Maxmum value of relative position. - initializer_range (float): Initialization value of Normal. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - """ - - def __init__(self, - length, - depth, - max_relative_position, - initializer_range, - use_one_hot_embeddings=False): - super(RelaPosEmbeddingsGenerator, self).__init__() - self.depth = depth - self.vocab_size = max_relative_position * 2 + 1 - self.use_one_hot_embeddings = use_one_hot_embeddings - self.embeddings_table = Parameter( - initializer(Normal(initializer_range), - [self.vocab_size, self.depth])) - self.relative_positions_matrix = RelaPosMatrixGenerator(length=length, - max_relative_position=max_relative_position) - self.reshape = P.Reshape() - self.one_hot = P.OneHot() - self.on_value = Tensor(1.0, mstype.float32) - self.off_value = Tensor(0.0, mstype.float32) - self.shape = P.Shape() - self.gather = P.Gather() # index_select - self.matmul = P.BatchMatMul() - - def construct(self): - """position embedding generation""" - relative_positions_matrix_out = self.relative_positions_matrix() - # Generate embedding for each relative position of dimension depth. - if self.use_one_hot_embeddings: - flat_relative_positions_matrix = self.reshape(relative_positions_matrix_out, (-1,)) - one_hot_relative_positions_matrix = self.one_hot( - flat_relative_positions_matrix, self.vocab_size, self.on_value, self.off_value) - embeddings = self.matmul(one_hot_relative_positions_matrix, self.embeddings_table) - my_shape = self.shape(relative_positions_matrix_out) + (self.depth,) - embeddings = self.reshape(embeddings, my_shape) - else: - embeddings = self.gather(self.embeddings_table, - relative_positions_matrix_out, 0) - return embeddings - - -class SaturateCast(nn.Cell): - """ - Performs a safe saturating cast. This operation applies proper clamping before casting to prevent - the danger that the value will overflow or underflow. - - Args: - src_type (:class:`mindspore.dtype`): The type of the elements of the input tensor. Default: mstype.float32. - dst_type (:class:`mindspore.dtype`): The type of the elements of the output tensor. Default: mstype.float32. - """ - - def __init__(self, src_type=mstype.float32, dst_type=mstype.float32): - super(SaturateCast, self).__init__() - np_type = mstype.dtype_to_nptype(dst_type) - min_type = np.finfo(np_type).min - max_type = np.finfo(np_type).max - self.tensor_min_type = Tensor([min_type], dtype=src_type) - self.tensor_max_type = Tensor([max_type], dtype=src_type) - self.min_op = P.Minimum() - self.max_op = P.Maximum() - self.cast = P.Cast() - self.dst_type = dst_type - - def construct(self, x): - """saturate cast""" - out = self.max_op(x, self.tensor_min_type) - out = self.min_op(out, self.tensor_max_type) - return self.cast(out, self.dst_type) - - -class BertAttention(nn.Cell): - """ - Apply multi-headed attention from "from_tensor" to "to_tensor". - - Args: - from_tensor_width (int): Size of last dim of from_tensor. - to_tensor_width (int): Size of last dim of to_tensor. - from_seq_length (int): Length of from_tensor sequence. - to_seq_length (int): Length of to_tensor sequence. - num_attention_heads (int): Number of attention heads. Default: 1. - size_per_head (int): Size of each attention head. Default: 512. - query_act (str): Activation function for the query transform. Default: None. - key_act (str): Activation function for the key transform. Default: None. - value_act (str): Activation function for the value transform. Default: None. - has_attention_mask (bool): Specifies whether to use attention mask. Default: False. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.0. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - do_return_2d_tensor (bool): True for return 2d tensor. False for return 3d - tensor. Default: False. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - compute_type (:class:`mindspore.dtype`): Compute type in BertAttention. Default: mstype.float32. - """ - - def __init__(self, - from_tensor_width, - to_tensor_width, - from_seq_length, - to_seq_length, - num_attention_heads=1, - size_per_head=512, - query_act=None, - key_act=None, - value_act=None, - has_attention_mask=False, - attention_probs_dropout_prob=0.0, - use_one_hot_embeddings=False, - initializer_range=0.02, - do_return_2d_tensor=False, - use_relative_positions=False, - compute_type=mstype.float32): - super(BertAttention, self).__init__() - self.from_seq_length = from_seq_length - self.to_seq_length = to_seq_length - self.num_attention_heads = num_attention_heads - self.size_per_head = size_per_head - self.has_attention_mask = has_attention_mask - self.use_relative_positions = use_relative_positions - self.scores_mul = Tensor([1.0 / math.sqrt(float(self.size_per_head))], dtype=compute_type) - self.reshape = P.Reshape() - self.shape_from_2d = (-1, from_tensor_width) - self.shape_to_2d = (-1, to_tensor_width) - weight = Normal(initializer_range) - units = num_attention_heads * size_per_head - self.query_layer = nn.Dense(from_tensor_width, - units, - activation=query_act, - weight_init=weight).to_float(compute_type) - self.key_layer = nn.Dense(to_tensor_width, - units, - activation=key_act, - weight_init=weight).to_float(compute_type) - self.value_layer = nn.Dense(to_tensor_width, - units, - activation=value_act, - weight_init=weight).to_float(compute_type) - self.shape_from = (-1, from_seq_length, num_attention_heads, size_per_head) - self.shape_to = (-1, to_seq_length, num_attention_heads, size_per_head) - self.matmul_trans_b = P.BatchMatMul(transpose_b=True) - self.multiply = P.Mul() - self.transpose = P.Transpose() - self.trans_shape = (0, 2, 1, 3) - self.trans_shape_relative = (2, 0, 1, 3) - self.trans_shape_position = (1, 2, 0, 3) - self.multiply_data = Tensor([-10000.0,], dtype=compute_type) - self.matmul = P.BatchMatMul() - self.softmax = nn.Softmax() - self.dropout = nn.Dropout(1 - attention_probs_dropout_prob) - if self.has_attention_mask: - self.expand_dims = P.ExpandDims() - self.sub = P.Sub() - self.add = P.Add() - self.cast = P.Cast() - self.get_dtype = P.DType() - if do_return_2d_tensor: - self.shape_return = (-1, num_attention_heads * size_per_head) - else: - self.shape_return = (-1, from_seq_length, num_attention_heads * size_per_head) - self.cast_compute_type = SaturateCast(dst_type=compute_type) - if self.use_relative_positions: - self._generate_relative_positions_embeddings = \ - RelaPosEmbeddingsGenerator(length=to_seq_length, - depth=size_per_head, - max_relative_position=16, - initializer_range=initializer_range, - use_one_hot_embeddings=use_one_hot_embeddings) - - def construct(self, from_tensor, to_tensor, attention_mask): - """bert attention""" - # reshape 2d/3d input tensors to 2d - from_tensor_2d = self.reshape(from_tensor, self.shape_from_2d) - to_tensor_2d = self.reshape(to_tensor, self.shape_to_2d) - query_out = self.query_layer(from_tensor_2d) - key_out = self.key_layer(to_tensor_2d) - value_out = self.value_layer(to_tensor_2d) - query_layer = self.reshape(query_out, self.shape_from) - query_layer = self.transpose(query_layer, self.trans_shape) - key_layer = self.reshape(key_out, self.shape_to) - key_layer = self.transpose(key_layer, self.trans_shape) - attention_scores = self.matmul_trans_b(query_layer, key_layer) - # use_relative_position, supplementary logic - if self.use_relative_positions: - # relations_keys is [F|T, F|T, H] - relations_keys = self._generate_relative_positions_embeddings() - relations_keys = self.cast_compute_type(relations_keys) - # query_layer_t is [F, B, N, H] - query_layer_t = self.transpose(query_layer, self.trans_shape_relative) - # query_layer_r is [F, B * N, H] - query_layer_r = self.reshape(query_layer_t, - (self.from_seq_length, - -1, - self.size_per_head)) - # key_position_scores is [F, B * N, F|T] - key_position_scores = self.matmul_trans_b(query_layer_r, - relations_keys) - # key_position_scores_r is [F, B, N, F|T] - key_position_scores_r = self.reshape(key_position_scores, - (self.from_seq_length, - -1, - self.num_attention_heads, - self.from_seq_length)) - # key_position_scores_r_t is [B, N, F, F|T] - key_position_scores_r_t = self.transpose(key_position_scores_r, - self.trans_shape_position) - attention_scores = attention_scores + key_position_scores_r_t - attention_scores = self.multiply(self.scores_mul, attention_scores) - if self.has_attention_mask: - attention_mask = self.expand_dims(attention_mask, 1) - multiply_out = self.sub(self.cast(F.tuple_to_array((1.0,)), self.get_dtype(attention_scores)), - self.cast(attention_mask, self.get_dtype(attention_scores))) - adder = self.multiply(multiply_out, self.multiply_data) - attention_scores = self.add(adder, attention_scores) - attention_probs = self.softmax(attention_scores) - attention_probs = self.dropout(attention_probs) - value_layer = self.reshape(value_out, self.shape_to) - value_layer = self.transpose(value_layer, self.trans_shape) - context_layer = self.matmul(attention_probs, value_layer) - # use_relative_position, supplementary logic - if self.use_relative_positions: - # relations_values is [F|T, F|T, H] - relations_values = self._generate_relative_positions_embeddings() - relations_values = self.cast_compute_type(relations_values) - # attention_probs_t is [F, B, N, T] - attention_probs_t = self.transpose(attention_probs, self.trans_shape_relative) - # attention_probs_r is [F, B * N, T] - attention_probs_r = self.reshape( - attention_probs_t, - (self.from_seq_length, - -1, - self.to_seq_length)) - # value_position_scores is [F, B * N, H] - value_position_scores = self.matmul(attention_probs_r, - relations_values) - # value_position_scores_r is [F, B, N, H] - value_position_scores_r = self.reshape(value_position_scores, - (self.from_seq_length, - -1, - self.num_attention_heads, - self.size_per_head)) - # value_position_scores_r_t is [B, N, F, H] - value_position_scores_r_t = self.transpose(value_position_scores_r, - self.trans_shape_position) - context_layer = context_layer + value_position_scores_r_t - context_layer = self.transpose(context_layer, self.trans_shape) - context_layer = self.reshape(context_layer, self.shape_return) - return context_layer, attention_scores - - -class BertSelfAttention(nn.Cell): - """ - Apply self-attention. - - Args: - seq_length (int): Length of input sequence. - hidden_size (int): Size of the bert encoder layers. - num_attention_heads (int): Number of attention heads. Default: 12. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.1. - use_one_hot_embeddings (bool): Specifies whether to use one_hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - compute_type (:class:`mindspore.dtype`): Compute type in BertSelfAttention. Default: mstype.float32. - """ - - def __init__(self, - seq_length, - hidden_size, - num_attention_heads=12, - attention_probs_dropout_prob=0.1, - use_one_hot_embeddings=False, - initializer_range=0.02, - hidden_dropout_prob=0.1, - use_relative_positions=False, - compute_type=mstype.float32): - super(BertSelfAttention, self).__init__() - if hidden_size % num_attention_heads != 0: - raise ValueError("The hidden size (%d) is not a multiple of the number " - "of attention heads (%d)" % (hidden_size, num_attention_heads)) - self.size_per_head = int(hidden_size / num_attention_heads) - self.attention = BertAttention( - from_tensor_width=hidden_size, - to_tensor_width=hidden_size, - from_seq_length=seq_length, - to_seq_length=seq_length, - num_attention_heads=num_attention_heads, - size_per_head=self.size_per_head, - attention_probs_dropout_prob=attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=initializer_range, - use_relative_positions=use_relative_positions, - has_attention_mask=True, - do_return_2d_tensor=True, - compute_type=compute_type) - self.output = BertOutput(in_channels=hidden_size, - out_channels=hidden_size, - initializer_range=initializer_range, - dropout_prob=hidden_dropout_prob, - compute_type=compute_type) - self.reshape = P.Reshape() - self.shape = (-1, hidden_size) - - def construct(self, input_tensor, attention_mask): - """bert self attention""" - input_tensor = self.reshape(input_tensor, self.shape) - attention_output, attention_scores = self.attention(input_tensor, input_tensor, attention_mask) - output = self.output(attention_output, input_tensor) - return output, attention_scores - - -class BertEncoderCell(nn.Cell): - """ - Encoder cells used in BertTransformer. - - Args: - hidden_size (int): Size of the bert encoder layers. Default: 768. - seq_length (int): Length of input sequence. Default: 512. - num_attention_heads (int): Number of attention heads. Default: 12. - intermediate_size (int): Size of intermediate layer. Default: 3072. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.02. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - hidden_act (str): Activation function. Default: "gelu". - compute_type (:class:`mindspore.dtype`): Compute type in attention. Default: mstype.float32. - """ - - def __init__(self, - hidden_size=768, - seq_length=512, - num_attention_heads=12, - intermediate_size=3072, - attention_probs_dropout_prob=0.02, - use_one_hot_embeddings=False, - initializer_range=0.02, - hidden_dropout_prob=0.1, - use_relative_positions=False, - hidden_act="gelu", - compute_type=mstype.float32): - super(BertEncoderCell, self).__init__() - self.attention = BertSelfAttention( - hidden_size=hidden_size, - seq_length=seq_length, - num_attention_heads=num_attention_heads, - attention_probs_dropout_prob=attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=initializer_range, - hidden_dropout_prob=hidden_dropout_prob, - use_relative_positions=use_relative_positions, - compute_type=compute_type) - self.intermediate = nn.Dense(in_channels=hidden_size, - out_channels=intermediate_size, - activation=hidden_act, - weight_init=Normal(initializer_range)).to_float(compute_type) - self.output = BertOutput(in_channels=intermediate_size, - out_channels=hidden_size, - initializer_range=initializer_range, - dropout_prob=hidden_dropout_prob, - compute_type=compute_type) - - def construct(self, hidden_states, attention_mask): - """bert encoder cell""" - # self-attention - attention_output, attention_scores = self.attention(hidden_states, attention_mask) - # feed construct - intermediate_output = self.intermediate(attention_output) - # add and normalize - output = self.output(intermediate_output, attention_output) - return output, attention_scores - - -class BertTransformer(nn.Cell): - """ - Multi-layer bert transformer. - - Args: - hidden_size (int): Size of the encoder layers. - seq_length (int): Length of input sequence. - num_hidden_layers (int): Number of hidden layers in encoder cells. - num_attention_heads (int): Number of attention heads in encoder cells. Default: 12. - intermediate_size (int): Size of intermediate layer in encoder cells. Default: 3072. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.1. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - hidden_act (str): Activation function used in the encoder cells. Default: "gelu". - compute_type (:class:`mindspore.dtype`): Compute type in BertTransformer. Default: mstype.float32. - return_all_encoders (bool): Specifies whether to return all encoders. Default: False. - """ - - def __init__(self, - hidden_size, - seq_length, - num_hidden_layers, - num_attention_heads=12, - intermediate_size=3072, - attention_probs_dropout_prob=0.1, - use_one_hot_embeddings=False, - initializer_range=0.02, - hidden_dropout_prob=0.1, - use_relative_positions=False, - hidden_act="gelu", - compute_type=mstype.float32, - return_all_encoders=False): - super(BertTransformer, self).__init__() - self.return_all_encoders = return_all_encoders - layers = [] - for _ in range(num_hidden_layers): - layer = BertEncoderCell(hidden_size=hidden_size, - seq_length=seq_length, - num_attention_heads=num_attention_heads, - intermediate_size=intermediate_size, - attention_probs_dropout_prob=attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=initializer_range, - hidden_dropout_prob=hidden_dropout_prob, - use_relative_positions=use_relative_positions, - hidden_act=hidden_act, - compute_type=compute_type) - layers.append(layer) - self.layers = nn.CellList(layers) - self.reshape = P.Reshape() - self.shape = (-1, hidden_size) - self.out_shape = (-1, seq_length, hidden_size) - - def construct(self, input_tensor, attention_mask): - """bert transformer""" - prev_output = self.reshape(input_tensor, self.shape) - all_encoder_layers = () - all_encoder_atts = () - all_encoder_outputs = () - all_encoder_outputs += (prev_output,) - for layer_module in self.layers: - layer_output, encoder_att = layer_module(prev_output, attention_mask) - prev_output = layer_output - if self.return_all_encoders: - all_encoder_outputs += (layer_output,) - layer_output = self.reshape(layer_output, self.out_shape) - all_encoder_layers += (layer_output,) - all_encoder_atts += (encoder_att,) - if not self.return_all_encoders: - prev_output = self.reshape(prev_output, self.out_shape) - all_encoder_layers += (prev_output,) - return all_encoder_layers, all_encoder_outputs, all_encoder_atts - - -class CreateAttentionMaskFromInputMask(nn.Cell): - """ - Create attention mask according to input mask. - - Args: - config (Class): Configuration for BertModel. - """ - - def __init__(self, config): - super(CreateAttentionMaskFromInputMask, self).__init__() - self.input_mask = None - self.cast = P.Cast() - self.reshape = P.Reshape() - self.shape = (-1, 1, config.seq_length) - - def construct(self, input_mask): - attention_mask = self.cast(self.reshape(input_mask, self.shape), mstype.float32) - return attention_mask - - -class BertModel(nn.Cell): - """ - Bidirectional Encoder Representations from Transformers. - - Args: - config (Class): Configuration for BertModel. - is_training (bool): True for training mode. False for eval mode. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - """ - - def __init__(self, - config, - is_training, - use_one_hot_embeddings=False): - super(BertModel, self).__init__() - config = copy.deepcopy(config) - if not is_training: - config.hidden_dropout_prob = 0.0 - config.attention_probs_dropout_prob = 0.0 - self.seq_length = config.seq_length - self.hidden_size = config.hidden_size - self.num_hidden_layers = config.num_hidden_layers - self.embedding_size = config.hidden_size - self.token_type_ids = None - self.last_idx = self.num_hidden_layers - 1 - output_embedding_shape = [-1, self.seq_length, - self.embedding_size] - self.bert_embedding_lookup = EmbeddingLookup( - vocab_size=config.vocab_size, - embedding_size=self.embedding_size, - embedding_shape=output_embedding_shape, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=config.initializer_range) - self.bert_embedding_postprocessor = EmbeddingPostprocessor( - use_relative_positions=config.use_relative_positions, - embedding_size=self.embedding_size, - embedding_shape=output_embedding_shape, - use_token_type=True, - token_type_vocab_size=config.type_vocab_size, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=0.02, - max_position_embeddings=config.max_position_embeddings, - dropout_prob=config.hidden_dropout_prob) - self.bert_encoder = BertTransformer( - hidden_size=self.hidden_size, - seq_length=self.seq_length, - num_attention_heads=config.num_attention_heads, - num_hidden_layers=self.num_hidden_layers, - intermediate_size=config.intermediate_size, - attention_probs_dropout_prob=config.attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=config.initializer_range, - hidden_dropout_prob=config.hidden_dropout_prob, - use_relative_positions=config.use_relative_positions, - hidden_act=config.hidden_act, - compute_type=config.compute_type, - return_all_encoders=True) - self.cast = P.Cast() - self.dtype = config.dtype - self.cast_compute_type = SaturateCast(dst_type=config.compute_type) - self.slice = P.StridedSlice() - self.squeeze_1 = P.Squeeze(axis=1) - self.dense = nn.Dense(self.hidden_size, self.hidden_size, - activation="tanh", - weight_init=Normal(config.initializer_range)).to_float(config.compute_type) - self._create_attention_mask_from_input_mask = CreateAttentionMaskFromInputMask(config) - - def construct(self, input_ids, token_type_ids, input_mask): - """bert model""" - # embedding - word_embeddings, embedding_tables = self.bert_embedding_lookup(input_ids) - embedding_output = self.bert_embedding_postprocessor(token_type_ids, word_embeddings) - # attention mask [batch_size, seq_length, seq_length] - attention_mask = self._create_attention_mask_from_input_mask(input_mask) - # bert encoder - encoder_output, encoder_layers, layer_atts = self.bert_encoder(self.cast_compute_type(embedding_output), - attention_mask) - sequence_output = self.cast(encoder_output[self.last_idx], self.dtype) - # pooler - batch_size = P.Shape()(input_ids)[0] - sequence_slice = self.slice(sequence_output, - (0, 0, 0), - (batch_size, 1, self.hidden_size), - (1, 1, 1)) - first_token = self.squeeze_1(sequence_slice) - pooled_output = self.dense(first_token) - pooled_output = self.cast(pooled_output, self.dtype) - encoder_outputs = () - for output in encoder_layers: - encoder_outputs += (self.cast(output, self.dtype),) - attention_outputs = () - for output in layer_atts: - attention_outputs += (self.cast(output, self.dtype),) - return sequence_output, pooled_output, embedding_tables, encoder_outputs, attention_outputs - - -class TinyBertModel(nn.Cell): - """ - Bidirectional Encoder Representations from Transformers. - - Args: - config (Class): Configuration for BertModel. - is_training (bool): True for training mode. False for eval mode. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - """ - - def __init__(self, - config, - is_training, - use_one_hot_embeddings=False): - super(TinyBertModel, self).__init__() - config = copy.deepcopy(config) - if not is_training: - config.hidden_dropout_prob = 0.0 - config.attention_probs_dropout_prob = 0.0 - self.seq_length = config.seq_length - self.hidden_size = config.hidden_size - self.num_hidden_layers = config.num_hidden_layers - self.embedding_size = config.hidden_size - self.token_type_ids = None - self.last_idx = self.num_hidden_layers - 1 - output_embedding_shape = [-1, self.seq_length, - self.embedding_size] - self.tinybert_embedding_lookup = EmbeddingLookup( - vocab_size=config.vocab_size, - embedding_size=self.embedding_size, - embedding_shape=output_embedding_shape, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=config.initializer_range) - self.tinybert_embedding_postprocessor = EmbeddingPostprocessor( - use_relative_positions=config.use_relative_positions, - embedding_size=self.embedding_size, - embedding_shape=output_embedding_shape, - use_token_type=True, - token_type_vocab_size=config.type_vocab_size, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=0.02, - max_position_embeddings=config.max_position_embeddings, - dropout_prob=config.hidden_dropout_prob) - self.tinybert_encoder = BertTransformer( - hidden_size=self.hidden_size, - seq_length=self.seq_length, - num_attention_heads=config.num_attention_heads, - num_hidden_layers=self.num_hidden_layers, - intermediate_size=config.intermediate_size, - attention_probs_dropout_prob=config.attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=config.initializer_range, - hidden_dropout_prob=config.hidden_dropout_prob, - use_relative_positions=config.use_relative_positions, - hidden_act=config.hidden_act, - compute_type=config.compute_type, - return_all_encoders=True) - self.cast = P.Cast() - self.dtype = config.dtype - self.cast_compute_type = SaturateCast(dst_type=config.compute_type) - self.slice = P.StridedSlice() - self.squeeze_1 = P.Squeeze(axis=1) - self.dense = nn.Dense(self.hidden_size, self.hidden_size, - activation="tanh", - weight_init=Normal(config.initializer_range)).to_float(config.compute_type) - self._create_attention_mask_from_input_mask = CreateAttentionMaskFromInputMask(config) - - def construct(self, input_ids, token_type_ids, input_mask): - """tiny bert model""" - # embedding - word_embeddings, embedding_tables = self.tinybert_embedding_lookup(input_ids) - embedding_output = self.tinybert_embedding_postprocessor(token_type_ids, - word_embeddings) - # attention mask [batch_size, seq_length, seq_length] - attention_mask = self._create_attention_mask_from_input_mask(input_mask) - # bert encoder - encoder_output, encoder_layers, layer_atts = self.tinybert_encoder(self.cast_compute_type(embedding_output), - attention_mask) - sequence_output = self.cast(encoder_output[self.last_idx], self.dtype) - # pooler - batch_size = P.Shape()(input_ids)[0] - sequence_slice = self.slice(sequence_output, - (0, 0, 0), - (batch_size, 1, self.hidden_size), - (1, 1, 1)) - first_token = self.squeeze_1(sequence_slice) - pooled_output = self.dense(first_token) - pooled_output = self.cast(pooled_output, self.dtype) - encoder_outputs = () - for output in encoder_layers: - encoder_outputs += (self.cast(output, self.dtype),) - attention_outputs = () - for output in layer_atts: - attention_outputs += (self.cast(output, self.dtype),) - return sequence_output, pooled_output, embedding_tables, encoder_outputs, attention_outputs - - -class BertModelCLS(nn.Cell): - """ - This class is responsible for classification task evaluation, - i.e. XNLI(num_labels=3), LCQMC(num_labels=2), Chnsenti(num_labels=2). - The returned output represents the final logits as the results of log_softmax is proportional to that of softmax. - """ - - def __init__(self, config, is_training, num_labels=2, dropout_prob=0.0, - use_one_hot_embeddings=False, phase_type="student"): - super(BertModelCLS, self).__init__() - self.bert = BertModel(config, is_training, use_one_hot_embeddings) - self.cast = P.Cast() - self.weight_init = Normal(config.initializer_range) - self.log_softmax = P.LogSoftmax(axis=-1) - self.dtype = config.dtype - self.num_labels = num_labels - self.phase_type = phase_type - if self.phase_type == "teacher": - self.dense = nn.Dense(config.hidden_size, self.num_labels, weight_init=self.weight_init, - has_bias=True).to_float(config.compute_type) - else: - self.dense_1 = nn.Dense(config.hidden_size, self.num_labels, weight_init=self.weight_init, - has_bias=True).to_float(config.compute_type) - self.dropout = nn.ReLU() - - def construct(self, input_ids, token_type_id, input_mask): - """classification bert model""" - _, pooled_output, _, seq_output, att_output = self.bert(input_ids, token_type_id, input_mask) - cls = self.cast(pooled_output, self.dtype) - cls = self.dropout(cls) - if self.phase_type == "teacher": - logits = self.dense(cls) - else: - logits = self.dense_1(cls) - logits = self.cast(logits, self.dtype) - log_probs = self.log_softmax(logits) - if self._phase == 'train' or self.phase_type == "teacher": - return seq_output, att_output, logits, log_probs - # return log_probs - return seq_output, att_output, logits, log_probs diff --git a/official/nlp/q8bert/src/config.py b/official/nlp/q8bert/src/config.py deleted file mode 100644 index 4a8d1b11fe4190b6e979f85dd117b2ef8ad5b729..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/src/config.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""config script for task distill""" - -import mindspore.common.dtype as mstype -from easydict import EasyDict as edict -from .q8bert_model import BertConfig -train_cfg = edict({ - 'batch_size': 16, - 'loss_scale_value': 1, - 'scale_factor': 2, - 'scale_window': 50, - 'optimizer_cfg': edict({ - 'AdamWeightDecay': edict({ - 'learning_rate': 1e-5, - 'end_learning_rate': 1e-14, - 'power': 1.0, - 'weight_decay': 1e-4, - 'eps': 1e-6, - 'decay_filter': lambda x: 'layernorm' not in x.name.lower() and 'bias' not in x.name.lower(), - 'warmup_ratio': 0.1 - }), - }), -}) - -eval_cfg = edict({ - 'batch_size': 32, -}) - -model_cfg = BertConfig( - seq_length=128, - vocab_size=30522, - hidden_size=768, - num_hidden_layers=12, - num_attention_heads=12, - intermediate_size=3072, - hidden_act="gelu", - hidden_dropout_prob=0.0, - attention_probs_dropout_prob=0.0, - max_position_embeddings=512, - type_vocab_size=2, - initializer_range=0.02, - use_relative_positions=False, - dtype=mstype.float32, - compute_type=mstype.float32, -) - -glue_output_modes = { - "cola": "classification", - "mnli": "classification", - "mnli-mm": "classification", - "mrpc": "classification", - "sst-2": "classification", - "sts-b": "regression", - "qqp": "classification", - "qnli": "classification", - "rte": "classification", - "wnli": "classification", -} - -task_params = {"SST-2": {"num_labels": 2, "seq_length": 64}, - "QNLI": {"num_labels": 2, "seq_length": 128}, - "STS-B": {"num_labels": 1, "seq_length": 128}} diff --git a/official/nlp/q8bert/src/dataset.py b/official/nlp/q8bert/src/dataset.py deleted file mode 100644 index 1edfbcb47d84b440647fbd76da6c08f856b82a7d..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/src/dataset.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""create q8bert dataset""" - -from enum import Enum -import mindspore.common.dtype as mstype -import mindspore.dataset as de -import mindspore.dataset.transforms.c_transforms as C - - -class DataType(Enum): - """Enumerate supported dataset format""" - TFRECORD = 1 - MINDRECORD = 2 - - -def create_dataset(batch_size=32, device_num=1, rank=0, do_shuffle=True, data_dir=None, data_type=DataType.TFRECORD, - seq_length=128, drop_remainder=True): - """create q8bert dataset""" - if isinstance(data_dir, list): - data_files = data_dir - else: - data_files = [data_dir] - - columns_list = ["input_ids", "input_mask", "segment_ids", "label_ids"] - shard_equal_rows = True - if device_num == 1: - shard_equal_rows = False - if data_type == DataType.MINDRECORD: - ds = de.MindDataset(data_files, columns_list=columns_list, shuffle=do_shuffle, - num_shards=device_num, shard_id=rank) - else: - ds = de.TFRecordDataset(data_files, None, columns_list=columns_list, shuffle=do_shuffle, - num_shards=device_num, shard_id=rank, - shard_equal_rows=shard_equal_rows) - if device_num == 1 and do_shuffle is True: - ds = ds.shuffle(10000) - type_cast_op = C.TypeCast(mstype.int32) - slice_op = C.Slice(slice(0, seq_length, 1)) - label_type = mstype.float32 - ds = ds.map(operations=[type_cast_op, slice_op], input_columns=["segment_ids"]) - ds = ds.map(operations=[type_cast_op, slice_op], input_columns=["input_mask"]) - ds = ds.map(operations=[type_cast_op, slice_op], input_columns=["input_ids"]) - ds = ds.map(operations=[C.TypeCast(label_type), slice_op], input_columns=["label_ids"]) - # apply batch operations - ds = ds.batch(batch_size, drop_remainder=drop_remainder) - return ds diff --git a/official/nlp/q8bert/src/q8bert.py b/official/nlp/q8bert/src/q8bert.py deleted file mode 100644 index e752e5d97ed1f14a3ca8f2964e83b2fedeece8f4..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/src/q8bert.py +++ /dev/null @@ -1,505 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""q8bert model""" - -import re -import mindspore.nn as nn -from mindspore import context -from mindspore.ops import operations as P -from mindspore.ops import functional as F -from mindspore.ops import composite as C -from mindspore.common.tensor import Tensor -from mindspore.common import dtype as mstype -from mindspore.common.parameter import Parameter -from mindspore.communication.management import get_group_size -from mindspore.nn.wrap.grad_reducer import DistributedGradReducer -from mindspore.context import ParallelMode -from mindspore.train.serialization import load_checkpoint -from mindspore.compression.quant.quant_utils import load_nonquant_param_into_quant_net -from .q8bert_model import BertModelCLS - -GRADIENT_CLIP_TYPE = 1 -GRADIENT_CLIP_VALUE = 1.0 - -clip_grad = C.MultitypeFuncGraph("clip_grad") -@clip_grad.register("Number", "Number", "Tensor") -def _clip_grad(clip_type, clip_value, grad): - """ - Clip gradients. - - Inputs: - clip_type (int): The way to clip, 0 for 'value', 1 for 'norm'. - clip_value (float): Specifies how much to clip. - grad (tuple[Tensor]): Gradients. - - Outputs: - tuple[Tensor], clipped gradients. - """ - if clip_type not in (0, 1): - return grad - dt = F.dtype(grad) - if clip_type == 0: - new_grad = C.clip_by_value(grad, F.cast(F.tuple_to_array((-clip_value,)), dt), - F.cast(F.tuple_to_array((clip_value,)), dt)) - else: - new_grad = nn.ClipByNorm()(grad, F.cast(F.tuple_to_array((clip_value,)), dt)) - return new_grad - - -_grad_overflow = C.MultitypeFuncGraph("_grad_overflow") -grad_overflow = P.FloatStatus() -@_grad_overflow.register("Tensor") -def _tensor_grad_overflow(grad): - return grad_overflow(grad) - - -grad_scale = C.MultitypeFuncGraph("grad_scale") -reciprocal = P.Reciprocal() - - -@grad_scale.register("Tensor", "Tensor") -def tensor_grad_scale(scale, grad): - return grad * reciprocal(scale) - - -class ClipGradients(nn.Cell): - """ - Clip gradients. - - Args: - grads (list): List of gradient tuples. - clip_type (Tensor): The way to clip, 'value' or 'norm'. - clip_value (Tensor): Specifies how much to clip. - - Returns: - List, a list of clipped_grad tuples. - """ - def __init__(self): - super(ClipGradients, self).__init__() - self.clip_by_norm = nn.ClipByNorm() - self.cast = P.Cast() - self.dtype = P.DType() - - def construct(self, - grads, - clip_type, - clip_value): - """clip gradients""" - if clip_type not in (0, 1): - return grads - new_grads = () - for grad in grads: - dt = self.dtype(grad) - if clip_type == 0: - t = C.clip_by_value(grad, self.cast(F.tuple_to_array((-clip_value,)), dt), - self.cast(F.tuple_to_array((clip_value,)), dt)) - else: - t = self.clip_by_norm(grad, self.cast(F.tuple_to_array((clip_value,)), dt)) - new_grads = new_grads + (t,) - return new_grads - - -class SoftCrossEntropy(nn.Cell): - """SoftCrossEntropy loss""" - def __init__(self): - super(SoftCrossEntropy, self).__init__() - self.log_softmax = P.LogSoftmax(axis=-1) - self.softmax = P.Softmax(axis=-1) - self.reduce_mean = P.ReduceMean() - self.cast = P.Cast() - - def construct(self, predicts, targets): - likelihood = self.log_softmax(predicts) - target_prob = self.softmax(targets) - loss = self.reduce_mean(-target_prob * likelihood) - - return self.cast(loss, mstype.float32) - - -class BertTrainWithLossScaleCell(nn.Cell): - """ - Encapsulation class of bert network training. - - Append an optimizer to the training network after that the construct - function can be called to create the backward graph. - - Args: - network (Cell): The training network. Note that loss function should have been added. - optimizer (Optimizer): Optimizer for updating the weights. - scale_update_cell (Cell): Cell to do the loss scale. Default: None. - """ - def __init__(self, network, optimizer, scale_update_cell=None): - super(BertTrainWithLossScaleCell, self).__init__(auto_prefix=False) - self.network = network - self.network.set_grad() - self.weights = optimizer.parameters - self.optimizer = optimizer - self.grad = C.GradOperation(get_by_list=True, - sens_param=True) - self.reducer_flag = False - self.allreduce = P.AllReduce() - self.parallel_mode = context.get_auto_parallel_context("parallel_mode") - if self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL]: - self.reducer_flag = True - self.grad_reducer = F.identity - self.degree = 1 - if self.reducer_flag: - self.degree = get_group_size() - self.grad_reducer = DistributedGradReducer(optimizer.parameters, False, self.degree) - self.is_distributed = (self.parallel_mode != ParallelMode.STAND_ALONE) - self.cast = P.Cast() - self.alloc_status = P.NPUAllocFloatStatus() - self.get_status = P.NPUGetFloatStatus() - self.clear_before_grad = P.NPUClearFloatStatus() - self.reduce_sum = P.ReduceSum(keep_dims=False) - self.depend_parameter_use = P.Depend() - self.base = Tensor(1, mstype.float32) - self.less_equal = P.LessEqual() - self.hyper_map = C.HyperMap() - self.loss_scale = None - self.loss_scaling_manager = scale_update_cell - if scale_update_cell: - self.loss_scale = Parameter(Tensor(scale_update_cell.get_loss_scale(), dtype=mstype.float32)) - - @C.add_flags(has_effect=True) - def construct(self, - input_ids, - input_mask, - token_type_id, - sens=None): - """Defines the computation performed.""" - weights = self.weights - loss = self.network(input_ids, - input_mask, - token_type_id) - if sens is None: - scaling_sens = self.loss_scale - else: - scaling_sens = sens - # alloc status and clear should be right before gradoperation - init = self.alloc_status() - self.clear_before_grad(init) - grads = self.grad(self.network, weights)(input_ids, - input_mask, - token_type_id, - self.cast(scaling_sens, - mstype.float32)) - # apply grad reducer on grads - grads = self.grad_reducer(grads) - grads = self.hyper_map(F.partial(grad_scale, scaling_sens * self.degree), grads) - grads = self.hyper_map(F.partial(clip_grad, GRADIENT_CLIP_TYPE, GRADIENT_CLIP_VALUE), grads) - self.get_status(init) - flag_sum = self.reduce_sum(init, (0,)) - if self.is_distributed: - # sum overflow flag over devices - flag_reduce = self.allreduce(flag_sum) - cond = self.less_equal(self.base, flag_reduce) - else: - cond = self.less_equal(self.base, flag_sum) - overflow = cond - if sens is None: - overflow = self.loss_scaling_manager(self.loss_scale, cond) - if not overflow: - self.optimizer(grads) - return (loss, cond, scaling_sens) - - -class BertTrainCell(nn.Cell): - """ - Encapsulation class of bert network training. - - Append an optimizer to the training network after that the construct - function can be called to create the backward graph. - - Args: - network (Cell): The training network. Note that loss function should have been added. - optimizer (Optimizer): Optimizer for updating the weights. - sens (Number): The adjust parameter. Default: 1.0. - """ - def __init__(self, network, optimizer, sens=1.0): - super(BertTrainCell, self).__init__(auto_prefix=False) - self.network = network - self.network.set_grad() - self.weights = optimizer.parameters - self.optimizer = optimizer - self.sens = sens - self.grad = C.GradOperation(get_by_list=True, - sens_param=True) - self.reducer_flag = False - self.parallel_mode = context.get_auto_parallel_context("parallel_mode") - if self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL]: - self.reducer_flag = True - self.grad_reducer = F.identity - self.degree = 1 - if self.reducer_flag: - mean = context.get_auto_parallel_context("gradients_mean") - self.degree = get_group_size() - self.grad_reducer = DistributedGradReducer(optimizer.parameters, mean, self.degree) - self.cast = P.Cast() - self.hyper_map = C.HyperMap() - - def construct(self, - input_ids, - input_mask, - token_type_id): - """Defines the computation performed.""" - weights = self.weights - loss = self.network(input_ids, - input_mask, - token_type_id) - grads = self.grad(self.network, weights)(input_ids, - input_mask, - token_type_id, - self.cast(F.tuple_to_array((self.sens,)), - mstype.float32)) - # apply grad reducer on grads - grads = self.grad_reducer(grads) - grads = self.hyper_map(F.partial(clip_grad, GRADIENT_CLIP_TYPE, GRADIENT_CLIP_VALUE), grads) - self.optimizer(grads) - return loss - - -class BertNetworkWithLoss_td(nn.Cell): - """ - Provide bert pre-training loss through network. - Args: - config (BertConfig): The config of BertModel. - is_training (bool): Specifies whether to use the training mode. - use_one_hot_embeddings (bool): Specifies whether to use one-hot for embeddings. Default: False. - Returns: - Tensor, the loss of the network. - """ - def __init__(self, student_config, student_ckpt, do_quant, - is_training, task_type, num_labels, use_one_hot_embeddings=False, - is_predistill=True, is_att_fit=True, is_rep_fit=True, - temperature=1.0, dropout_prob=0.1): - super(BertNetworkWithLoss_td, self).__init__() - - # load student model - self.bert = BertModelCLS(student_config, is_training, num_labels, dropout_prob, - use_one_hot_embeddings, "student") - if do_quant: - import src.q8bert_model as quant_bert_model - self.bert = quant_bert_model.BertModelCLS(student_config, is_training, num_labels, dropout_prob, - use_one_hot_embeddings, "student") - else: - import src.bert_model as bert_model - self.bert = bert_model.BertModelCLS(student_config, is_training, num_labels, dropout_prob, - use_one_hot_embeddings, "student") - - param_dict = load_checkpoint(student_ckpt) - if is_predistill: - new_param_dict = {} - for key, value in param_dict.items(): - new_key = re.sub('tinybert_', 'bert_', 'bert.' + key) - new_param_dict[new_key] = value - load_nonquant_param_into_quant_net(self.bert, new_param_dict) - else: - new_param_dict = {} - for key, value in param_dict.items(): - new_key = re.sub('tinybert_', 'bert_', key) - new_param_dict[new_key] = value - load_nonquant_param_into_quant_net(self.bert, new_param_dict) - self.cast = P.Cast() - self.student_layers_num = student_config.num_hidden_layers - self.is_predistill = is_predistill - self.is_att_fit = is_att_fit - self.is_rep_fit = is_rep_fit - self.task_type = task_type - self.temperature = temperature - self.loss_mse = nn.MSELoss() - self.select = P.Select() - self.zeroslike = P.ZerosLike() - self.dtype = student_config.dtype - self.num_labels = num_labels - self.soft_cross_entropy = SoftCrossEntropy() - self.reshape = P.Reshape() - self.lgt_fct = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') - - def construct(self, - input_ids, - input_mask, - token_type_id, - label_ids): - """task distill network with loss""" - # student model - _, _, student_logits, _ = self.bert(input_ids, token_type_id, input_mask) - total_loss = 0 - - if self.task_type == "classification": - student_logits = self.cast(student_logits, mstype.float32) - label_ids_reshape = self.reshape(self.cast(label_ids, mstype.int32), (-1,)) - cls_loss = self.lgt_fct(student_logits, label_ids_reshape) - else: - student_logits = self.reshape(student_logits, (-1,)) - label_ids = self.reshape(label_ids, (-1,)) - cls_loss = self.loss_mse(student_logits, label_ids) - total_loss += cls_loss - return self.cast(total_loss, mstype.float32) - - -class BertEvaluationWithLossScaleCell(nn.Cell): - """ - specifically defined for finetuning where only four inputs tensor are needed. - """ - def __init__(self, network, optimizer, scale_update_cell=None): - super(BertEvaluationWithLossScaleCell, self).__init__(auto_prefix=False) - self.network = network - self.network.set_grad() - self.weights = optimizer.parameters - self.optimizer = optimizer - self.grad = C.GradOperation(get_by_list=True, - sens_param=True) - self.reducer_flag = False - self.allreduce = P.AllReduce() - self.parallel_mode = context.get_auto_parallel_context("parallel_mode") - if self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL]: - self.reducer_flag = True - self.grad_reducer = F.identity - self.degree = 1 - if self.reducer_flag: - self.degree = get_group_size() - self.grad_reducer = DistributedGradReducer(optimizer.parameters, False, self.degree) - self.is_distributed = (self.parallel_mode != ParallelMode.STAND_ALONE) - self.cast = P.Cast() - self.gpu_target = False - if context.get_context("device_target") == "GPU": - self.gpu_target = True - self.float_status = P.FloatStatus() - self.addn = P.AddN() - self.reshape = P.Reshape() - else: - self.alloc_status = P.NPUAllocFloatStatus() - self.get_status = P.NPUGetFloatStatus() - self.clear_before_grad = P.NPUClearFloatStatus() - self.reduce_sum = P.ReduceSum(keep_dims=False) - self.depend_parameter_use = P.Depend() - self.base = Tensor(1, mstype.float32) - self.less_equal = P.LessEqual() - self.hyper_map = C.HyperMap() - self.loss_scale = None - self.loss_scaling_manager = scale_update_cell - if scale_update_cell: - self.loss_scale = Parameter(Tensor(scale_update_cell.get_loss_scale(), dtype=mstype.float32)) - - @C.add_flags(has_effect=True) - def construct(self, - input_ids, - input_mask, - token_type_id, - label_ids, - sens=None): - """Defines the computation performed.""" - weights = self.weights - init = False - loss = self.network(input_ids, - input_mask, - token_type_id, - label_ids) - if sens is None: - scaling_sens = self.loss_scale - else: - scaling_sens = sens - if not self.gpu_target: - init = self.alloc_status() - clear_before_grad = self.clear_before_grad(init) - F.depend(loss, init) - self.depend_parameter_use(clear_before_grad, scaling_sens) - # alloc status and clear should be right before gradoperation - grads = self.grad(self.network, weights)(input_ids, - input_mask, - token_type_id, - label_ids, - self.cast(scaling_sens, - mstype.float32)) - # apply grad reducer on grads - grads = self.hyper_map(F.partial(grad_scale, scaling_sens), grads) - grads = self.hyper_map(F.partial(clip_grad, GRADIENT_CLIP_TYPE, GRADIENT_CLIP_VALUE), grads) - if self.reducer_flag: - grads = self.grad_reducer(grads) - if not self.gpu_target: - flag = self.get_status(init) - flag_sum = self.reduce_sum(init, (0,)) - F.depend(grads, flag) - F.depend(flag, flag_sum) - else: - flag_sum = self.hyper_map(F.partial(_grad_overflow), grads) - flag_sum = self.addn(flag_sum) - flag_sum = self.reshape(flag_sum, (())) - if self.is_distributed: - # sum overflow flag over devices - flag_reduce = self.allreduce(flag_sum) - cond = self.less_equal(self.base, flag_reduce) - else: - cond = self.less_equal(self.base, flag_sum) - overflow = cond - if sens is None: - overflow = self.loss_scaling_manager(self.loss_scale, cond) - if not overflow: - self.optimizer(grads) - return (loss, cond) - - -class BertEvaluationCell(nn.Cell): - """ - specifically defined for finetuning where only four inputs tensor are needed. - """ - def __init__(self, network, optimizer, sens=1.0): - super(BertEvaluationCell, self).__init__(auto_prefix=False) - self.network = network - self.network.set_grad() - self.weights = optimizer.parameters - self.optimizer = optimizer - self.sens = sens - self.grad = C.GradOperation(get_by_list=True, - sens_param=True) - self.reducer_flag = False - self.parallel_mode = context.get_auto_parallel_context("parallel_mode") - if self.parallel_mode in [ParallelMode.DATA_PARALLEL, ParallelMode.HYBRID_PARALLEL]: - self.reducer_flag = True - self.grad_reducer = F.identity - self.degree = 1 - if self.reducer_flag: - mean = context.get_auto_parallel_context("gradients_mean") - self.degree = get_group_size() - self.grad_reducer = DistributedGradReducer(optimizer.parameters, mean, self.degree) - self.is_distributed = (self.parallel_mode != ParallelMode.STAND_ALONE) - self.cast = P.Cast() - self.hyper_map = C.HyperMap() - - def construct(self, - input_ids, - input_mask, - token_type_id, - label_ids): - """Defines the computation performed.""" - # return input_ids - weights = self.weights - loss = self.network(input_ids, - input_mask, - token_type_id, - label_ids) - grads = self.grad(self.network, weights)(input_ids, - input_mask, - token_type_id, - label_ids, - self.cast(F.tuple_to_array((self.sens,)), - mstype.float32)) - # apply grad reducer on grads - grads = self.grad_reducer(grads) - grads = self.hyper_map(F.partial(clip_grad, GRADIENT_CLIP_TYPE, GRADIENT_CLIP_VALUE), grads) - self.optimizer(grads) - return loss diff --git a/official/nlp/q8bert/src/q8bert_model.py b/official/nlp/q8bert/src/q8bert_model.py deleted file mode 100644 index 4d111599086813111029014aa22ae80329269d5f..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/src/q8bert_model.py +++ /dev/null @@ -1,949 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== -"""Bert model.""" -import math -import copy -import numpy as np -import mindspore.common.dtype as mstype -import mindspore.nn as nn -import mindspore.ops.functional as F -from mindspore.common.initializer import Normal, initializer -from mindspore.ops import operations as P -from mindspore.ops import composite as C -from mindspore.common.tensor import Tensor -from mindspore.common.parameter import Parameter -from mindspore import context -from mindspore.nn.layer.quant import FakeQuantWithMinMaxObserver as FakeQuantWithMinMax - - -class BertConfig: - """ - Configuration for `BertModel`. - - Args: - seq_length (int): Length of input sequence. Default: 128. - vocab_size (int): The shape of each embedding vector. Default: 32000. - hidden_size (int): Size of the bert encoder layers. Default: 768. - num_hidden_layers (int): Number of hidden layers in the BertTransformer encoder - cell. Default: 12. - num_attention_heads (int): Number of attention heads in the BertTransformer - encoder cell. Default: 12. - intermediate_size (int): Size of intermediate layer in the BertTransformer - encoder cell. Default: 3072. - hidden_act (str): Activation function used in the BertTransformer encoder - cell. Default: "gelu". - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.1. - max_position_embeddings (int): Maximum length of sequences used in this - model. Default: 512. - type_vocab_size (int): Size of token type vocab. Default: 16. - initializer_range (float): Initialization value of Normal. Default: 0.02. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - dtype (:class:`mindspore.dtype`): Data type of the input. Default: mstype.float32. - compute_type (:class:`mindspore.dtype`): Compute type in BertTransformer. Default: mstype.float32. - """ - - def __init__(self, - seq_length=128, - vocab_size=32000, - hidden_size=768, - num_hidden_layers=12, - num_attention_heads=12, - intermediate_size=3072, - hidden_act="gelu", - hidden_dropout_prob=0.1, - attention_probs_dropout_prob=0.1, - max_position_embeddings=512, - type_vocab_size=16, - initializer_range=0.02, - use_relative_positions=False, - dtype=mstype.float32, - compute_type=mstype.float32): - self.seq_length = seq_length - self.vocab_size = vocab_size - self.hidden_size = hidden_size - self.num_hidden_layers = num_hidden_layers - self.num_attention_heads = num_attention_heads - self.hidden_act = hidden_act - self.intermediate_size = intermediate_size - self.hidden_dropout_prob = hidden_dropout_prob - self.attention_probs_dropout_prob = attention_probs_dropout_prob - self.max_position_embeddings = max_position_embeddings - self.type_vocab_size = type_vocab_size - self.initializer_range = initializer_range - self.use_relative_positions = use_relative_positions - self.dtype = dtype - self.compute_type = compute_type - - -class EmbeddingLookup(nn.Cell): - """ - A embeddings lookup table with a fixed dictionary and size. - - Args: - vocab_size (int): Size of the dictionary of embeddings. - embedding_size (int): The size of each embedding vector. - embedding_shape (list): [batch_size, seq_length, embedding_size], the shape of - each embedding vector. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - """ - - def __init__(self, - vocab_size, - embedding_size, - embedding_shape, - use_one_hot_embeddings=False, - initializer_range=0.02): - super(EmbeddingLookup, self).__init__() - self.vocab_size = vocab_size - self.use_one_hot_embeddings = use_one_hot_embeddings - self.embedding_table = Parameter(initializer - (Normal(initializer_range), - [vocab_size, embedding_size])) - self.expand = P.ExpandDims() - self.shape_flat = (-1,) - self.gather = P.Gather() - self.one_hot = P.OneHot() - self.on_value = Tensor(1.0, mstype.float32) - self.off_value = Tensor(0.0, mstype.float32) - self.array_mul = P.MatMul() - self.reshape = P.Reshape() - self.shape = tuple(embedding_shape) - - def construct(self, input_ids): - """embedding lookup""" - extended_ids = self.expand(input_ids, -1) - flat_ids = self.reshape(extended_ids, self.shape_flat) - if self.use_one_hot_embeddings: - one_hot_ids = self.one_hot(flat_ids, self.vocab_size, self.on_value, self.off_value) - output_for_reshape = self.array_mul( - one_hot_ids, self.embedding_table) - else: - output_for_reshape = self.gather(self.embedding_table, flat_ids, 0) - output = self.reshape(output_for_reshape, self.shape) - return output, self.embedding_table - - -class EmbeddingPostprocessor(nn.Cell): - """ - Postprocessors apply positional and token type embeddings to word embeddings. - - Args: - embedding_size (int): The size of each embedding vector. - embedding_shape (list): [batch_size, seq_length, embedding_size], the shape of - each embedding vector. - use_token_type (bool): Specifies whether to use token type embeddings. Default: False. - token_type_vocab_size (int): Size of token type vocab. Default: 16. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - max_position_embeddings (int): Maximum length of sequences used in this - model. Default: 512. - dropout_prob (float): The dropout probability. Default: 0.1. - """ - - def __init__(self, - use_relative_positions, - embedding_size, - embedding_shape, - use_token_type=False, - token_type_vocab_size=16, - use_one_hot_embeddings=False, - initializer_range=0.02, - max_position_embeddings=512, - dropout_prob=0.1): - super(EmbeddingPostprocessor, self).__init__() - self.use_token_type = use_token_type - self.token_type_vocab_size = token_type_vocab_size - self.use_one_hot_embeddings = use_one_hot_embeddings - self.max_position_embeddings = max_position_embeddings - self.embedding_table = Parameter(initializer - (Normal(initializer_range), - [token_type_vocab_size, - embedding_size])) - self.shape_flat = (-1,) - self.one_hot = P.OneHot() - self.on_value = Tensor(1.0, mstype.float32) - self.off_value = Tensor(0.1, mstype.float32) - self.array_mul = P.MatMul() - self.reshape = P.Reshape() - self.shape = tuple(embedding_shape) - self.layernorm = nn.LayerNorm((embedding_size,)) - self.dropout = nn.Dropout(1 - dropout_prob) - self.gather = P.Gather() - self.use_relative_positions = use_relative_positions - self.slice = P.StridedSlice() - self.full_position_embeddings = Parameter(initializer - (Normal(initializer_range), - [max_position_embeddings, - embedding_size])) - - def construct(self, token_type_ids, word_embeddings): - """embedding postprocessor""" - output = word_embeddings - if self.use_token_type: - flat_ids = self.reshape(token_type_ids, self.shape_flat) - if self.use_one_hot_embeddings: - one_hot_ids = self.one_hot(flat_ids, - self.token_type_vocab_size, self.on_value, self.off_value) - token_type_embeddings = self.array_mul(one_hot_ids, - self.embedding_table) - else: - token_type_embeddings = self.gather(self.embedding_table, flat_ids, 0) - token_type_embeddings = self.reshape(token_type_embeddings, self.shape) - output += token_type_embeddings - if not self.use_relative_positions: - _, seq, width = self.shape - position_embeddings = self.slice(self.full_position_embeddings, (0, 0), (seq, width), (1, 1)) - position_embeddings = self.reshape(position_embeddings, (1, seq, width)) - output += position_embeddings - output = self.layernorm(output) - output = self.dropout(output) - return output - - -class BertOutput(nn.Cell): - """ - Apply a linear computation to hidden status and a residual computation to input. - - Args: - in_channels (int): Input channels. - out_channels (int): Output channels. - initializer_range (float): Initialization value of Normal. Default: 0.02. - dropout_prob (float): The dropout probability. Default: 0.1. - compute_type (:class:`mindspore.dtype`): Compute type in BertTransformer. Default: mstype.float32. - """ - - def __init__(self, - in_channels, - out_channels, - initializer_range=0.02, - dropout_prob=0.1, - compute_type=mstype.float32, - activation_init=2.5): - super(BertOutput, self).__init__() - self.dense = nn.DenseQuant(in_channels, out_channels, - weight_init=Normal(initializer_range)).to_float(compute_type) - self.dropout = nn.Dropout(1 - dropout_prob) - self.add = P.Add() - self.is_gpu = context.get_context('device_target') == "GPU" - if self.is_gpu: - self.layernorm = nn.LayerNorm((out_channels,)).to_float(mstype.float32) - self.compute_type = compute_type - else: - self.layernorm = nn.LayerNorm((out_channels,)).to_float(compute_type) - self.cast = P.Cast() - self.quant_bert_in = FakeQuantWithMinMax(min_init=-activation_init, - max_init=activation_init, - ema=True) - self.quant_bert_out = FakeQuantWithMinMax(min_init=-activation_init, - max_init=activation_init, - ema=True) - - def construct(self, hidden_status, input_tensor): - """bert output""" - hidden_status = self.quant_bert_in(hidden_status) - output = self.dense(hidden_status) - output = self.quant_bert_out(output) - output = self.dropout(output) - output = self.add(input_tensor, output) - output = self.layernorm(output) - if self.is_gpu: - output = self.cast(output, self.compute_type) - return output - - -class RelaPosMatrixGenerator(nn.Cell): - """ - Generates matrix of relative positions between inputs. - - Args: - length (int): Length of one dim for the matrix to be generated. - max_relative_position (int): Max value of relative position. - """ - - def __init__(self, length, max_relative_position): - super(RelaPosMatrixGenerator, self).__init__() - self._length = length - self._max_relative_position = Tensor(max_relative_position, dtype=mstype.int32) - self._min_relative_position = Tensor(-max_relative_position, dtype=mstype.int32) - self.range_length = -length + 1 - self.tile = P.Tile() - self.range_mat = P.Reshape() - self.sub = P.Sub() - self.expanddims = P.ExpandDims() - self.cast = P.Cast() - - def construct(self): - """position matrix generator""" - range_vec_row_out = self.cast(F.tuple_to_array(F.make_range(self._length)), mstype.int32) - range_vec_col_out = self.range_mat(range_vec_row_out, (self._length, -1)) - tile_row_out = self.tile(range_vec_row_out, (self._length,)) - tile_col_out = self.tile(range_vec_col_out, (1, self._length)) - range_mat_out = self.range_mat(tile_row_out, (self._length, self._length)) - transpose_out = self.range_mat(tile_col_out, (self._length, self._length)) - distance_mat = self.sub(range_mat_out, transpose_out) - distance_mat_clipped = C.clip_by_value(distance_mat, - self._min_relative_position, - self._max_relative_position) - # Shift values to be >=0. Each integer still uniquely identifies a - # relative position difference. - final_mat = distance_mat_clipped + self._max_relative_position - return final_mat - - -class RelaPosEmbeddingsGenerator(nn.Cell): - """ - Generates tensor of size [length, length, depth]. - - Args: - length (int): Length of one dim for the matrix to be generated. - depth (int): Size of each attention head. - max_relative_position (int): Maxmum value of relative position. - initializer_range (float): Initialization value of Normal. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - """ - - def __init__(self, - length, - depth, - max_relative_position, - initializer_range, - use_one_hot_embeddings=False): - super(RelaPosEmbeddingsGenerator, self).__init__() - self.depth = depth - self.vocab_size = max_relative_position * 2 + 1 - self.use_one_hot_embeddings = use_one_hot_embeddings - self.embeddings_table = Parameter( - initializer(Normal(initializer_range), - [self.vocab_size, self.depth])) - self.relative_positions_matrix = RelaPosMatrixGenerator(length=length, - max_relative_position=max_relative_position) - self.reshape = P.Reshape() - self.one_hot = P.OneHot() - self.on_value = Tensor(1.0, mstype.float32) - self.off_value = Tensor(0.0, mstype.float32) - self.shape = P.Shape() - self.gather = P.Gather() # index_select - self.matmul = P.BatchMatMul() - - def construct(self): - """position embedding generation""" - relative_positions_matrix_out = self.relative_positions_matrix() - # Generate embedding for each relative position of dimension depth. - if self.use_one_hot_embeddings: - flat_relative_positions_matrix = self.reshape(relative_positions_matrix_out, (-1,)) - one_hot_relative_positions_matrix = self.one_hot( - flat_relative_positions_matrix, self.vocab_size, self.on_value, self.off_value) - embeddings = self.matmul(one_hot_relative_positions_matrix, self.embeddings_table) - my_shape = self.shape(relative_positions_matrix_out) + (self.depth,) - embeddings = self.reshape(embeddings, my_shape) - else: - embeddings = self.gather(self.embeddings_table, - relative_positions_matrix_out, 0) - return embeddings - - -class SaturateCast(nn.Cell): - """ - Performs a safe saturating cast. This operation applies proper clamping before casting to prevent - the danger that the value will overflow or underflow. - - Args: - src_type (:class:`mindspore.dtype`): The type of the elements of the input tensor. Default: mstype.float32. - dst_type (:class:`mindspore.dtype`): The type of the elements of the output tensor. Default: mstype.float32. - """ - - def __init__(self, src_type=mstype.float32, dst_type=mstype.float32): - super(SaturateCast, self).__init__() - np_type = mstype.dtype_to_nptype(dst_type) - min_type = np.finfo(np_type).min - max_type = np.finfo(np_type).max - self.tensor_min_type = Tensor([min_type], dtype=src_type) - self.tensor_max_type = Tensor([max_type], dtype=src_type) - self.min_op = P.Minimum() - self.max_op = P.Maximum() - self.cast = P.Cast() - self.dst_type = dst_type - - def construct(self, x): - """saturate cast""" - out = self.max_op(x, self.tensor_min_type) - out = self.min_op(out, self.tensor_max_type) - return self.cast(out, self.dst_type) - - -class BertAttention(nn.Cell): - """ - Apply multi-headed attention from "from_tensor" to "to_tensor". - - Args: - from_tensor_width (int): Size of last dim of from_tensor. - to_tensor_width (int): Size of last dim of to_tensor. - from_seq_length (int): Length of from_tensor sequence. - to_seq_length (int): Length of to_tensor sequence. - num_attention_heads (int): Number of attention heads. Default: 1. - size_per_head (int): Size of each attention head. Default: 512. - query_act (str): Activation function for the query transform. Default: None. - key_act (str): Activation function for the key transform. Default: None. - value_act (str): Activation function for the value transform. Default: None. - has_attention_mask (bool): Specifies whether to use attention mask. Default: False. - attention_probs_dropout_prob (float): The dropout probability for BertAttention. Default: 0.0. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - do_return_2d_tensor (bool): True for return 2d tensor. False for return 3d tensor. Default: False. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - compute_type (:class:`mindspore.dtype`): Compute type in BertAttention. Default: mstype.float32. - """ - - def __init__(self, - from_tensor_width, - to_tensor_width, - from_seq_length, - to_seq_length, - num_attention_heads=1, - size_per_head=512, - query_act=None, - key_act=None, - value_act=None, - has_attention_mask=False, - attention_probs_dropout_prob=0.0, - use_one_hot_embeddings=False, - initializer_range=0.02, - do_return_2d_tensor=False, - use_relative_positions=False, - compute_type=mstype.float32, - activation_init=2.5): - super(BertAttention, self).__init__() - self.from_seq_length = from_seq_length - self.to_seq_length = to_seq_length - self.num_attention_heads = num_attention_heads - self.size_per_head = size_per_head - self.has_attention_mask = has_attention_mask - self.use_relative_positions = use_relative_positions - self.compute_type = compute_type - self.scores_mul = Tensor([1.0 / math.sqrt(float(self.size_per_head))], dtype=self.compute_type) - self.reshape = P.Reshape() - self.shape_from_2d = (-1, from_tensor_width) - self.shape_to_2d = (-1, to_tensor_width) - weight = Normal(initializer_range) - units = num_attention_heads * size_per_head - # do quant: - self.activation_init = activation_init - self.activation = {"query_act": query_act, "key_act": key_act, "value_act": value_act} - self._quant_init(from_tensor_width, to_tensor_width, units, weight) - - self.shape_from = (-1, from_seq_length, num_attention_heads, size_per_head) - self.shape_to = (-1, to_seq_length, num_attention_heads, size_per_head) - self.matmul_trans_b = P.BatchMatMul(transpose_b=True) - self.multiply = P.Mul() - self.transpose = P.Transpose() - self.trans_shape = (0, 2, 1, 3) - self.trans_shape_relative = (2, 0, 1, 3) - self.trans_shape_position = (1, 2, 0, 3) - self.multiply_data = Tensor([-10000.0,], dtype=compute_type) - self.matmul = P.BatchMatMul() - self.softmax = nn.Softmax() - self.dropout = nn.Dropout(1 - attention_probs_dropout_prob) - if self.has_attention_mask: - self.expand_dims = P.ExpandDims() - self.sub = P.Sub() - self.add = P.Add() - self.cast = P.Cast() - self.get_dtype = P.DType() - if do_return_2d_tensor: - self.shape_return = (-1, num_attention_heads * size_per_head) - else: - self.shape_return = (-1, from_seq_length, num_attention_heads * size_per_head) - self.cast_compute_type = SaturateCast(dst_type=compute_type) - if self.use_relative_positions: - self._generate_relative_positions_embeddings = \ - RelaPosEmbeddingsGenerator(length=to_seq_length, depth=size_per_head, max_relative_position=16, - initializer_range=initializer_range, - use_one_hot_embeddings=use_one_hot_embeddings) - - def _quant_init(self, from_tensor_width, to_tensor_width, units, weight): - """Init quantization operations""" - self.quant_from_tensor_2d = FakeQuantWithMinMax(min_init=-self.activation_init, - max_init=self.activation_init, - ema=True) - self.quant_to_tensor_2d = FakeQuantWithMinMax(min_init=-self.activation_init, - max_init=self.activation_init, - ema=True) - self.quant_query_out = FakeQuantWithMinMax(min_init=-self.activation_init, - max_init=self.activation_init, - ema=True) - self.quant_key_out = FakeQuantWithMinMax(min_init=-self.activation_init, - max_init=self.activation_init, - ema=True) - self.quant_value_out = FakeQuantWithMinMax(min_init=-self.activation_init, - max_init=self.activation_init, - ema=True) - self.query_layer = nn.DenseQuant(from_tensor_width, units, activation=self.activation["query_act"], - weight_init=weight).to_float(self.compute_type) - self.key_layer = nn.DenseQuant(to_tensor_width, units, activation=self.activation["key_act"], - weight_init=weight).to_float(self.compute_type) - self.value_layer = nn.DenseQuant(to_tensor_width, units, activation=self.activation["value_act"], - weight_init=weight).to_float(self.compute_type) - - def construct(self, from_tensor, to_tensor, attention_mask): - """bert attention""" - # reshape 2d/3d input tensors to 2d - from_tensor_2d = self.reshape(from_tensor, self.shape_from_2d) - to_tensor_2d = self.reshape(to_tensor, self.shape_to_2d) - # do quant: - to_tensor_2d = self.quant_to_tensor_2d(to_tensor_2d) - query_out = self.query_layer(self.quant_from_tensor_2d(from_tensor_2d)) - query_out = self.quant_query_out(query_out) - key_out = self.key_layer(to_tensor_2d) - key_out = self.quant_key_out(key_out) - value_out = self.quant_value_out(self.value_layer(to_tensor_2d)) - - query_layer = self.reshape(query_out, self.shape_from) - query_layer = self.transpose(query_layer, self.trans_shape) - key_layer = self.reshape(key_out, self.shape_to) - key_layer = self.transpose(key_layer, self.trans_shape) - attention_scores = self.matmul_trans_b(query_layer, key_layer) - # use_relative_position, supplementary logic - if self.use_relative_positions: - # relations_keys is [F|T, F|T, H] - relations_keys = self._generate_relative_positions_embeddings() - relations_keys = self.cast_compute_type(relations_keys) - # query_layer_t is [F, B, N, H] - query_layer_t = self.transpose(query_layer, self.trans_shape_relative) - # query_layer_r is [F, B * N, H] - query_layer_r = self.reshape(query_layer_t, (self.from_seq_length, -1, self.size_per_head)) - # key_position_scores is [F, B * N, F|T] - key_position_scores = self.matmul_trans_b(query_layer_r, relations_keys) - # key_position_scores_r is [F, B, N, F|T] - key_position_scores_r = self.reshape(key_position_scores, (self.from_seq_length, -1, - self.num_attention_heads, self.from_seq_length)) - # key_position_scores_r_t is [B, N, F, F|T] - key_position_scores_r_t = self.transpose(key_position_scores_r, self.trans_shape_position) - attention_scores = attention_scores + key_position_scores_r_t - attention_scores = self.multiply(self.scores_mul, attention_scores) - if self.has_attention_mask: - attention_mask = self.expand_dims(attention_mask, 1) - multiply_out = self.sub(self.cast(F.tuple_to_array((1.0,)), self.get_dtype(attention_scores)), - self.cast(attention_mask, self.get_dtype(attention_scores))) - adder = self.multiply(multiply_out, self.multiply_data) - attention_scores = self.add(adder, attention_scores) - attention_probs = self.softmax(attention_scores) - attention_probs = self.dropout(attention_probs) - value_layer = self.reshape(value_out, self.shape_to) - value_layer = self.transpose(value_layer, self.trans_shape) - context_layer = self.matmul(attention_probs, value_layer) - # use_relative_position, supplementary logic - if self.use_relative_positions: - # relations_values is [F|T, F|T, H] - relations_values = self._generate_relative_positions_embeddings() - relations_values = self.cast_compute_type(relations_values) - # attention_probs_t is [F, B, N, T] - attention_probs_t = self.transpose(attention_probs, self.trans_shape_relative) - # attention_probs_r is [F, B * N, T] - attention_probs_r = self.reshape(attention_probs_t, (self.from_seq_length, -1, self.to_seq_length)) - value_position_scores = self.matmul(attention_probs_r, relations_values) - value_position_scores_r = self.reshape(value_position_scores, (self.from_seq_length, -1, - self.num_attention_heads, - self.size_per_head)) - value_position_scores_r_t = self.transpose(value_position_scores_r, self.trans_shape_position) - context_layer = context_layer + value_position_scores_r_t - context_layer = self.transpose(context_layer, self.trans_shape) - context_layer = self.reshape(context_layer, self.shape_return) - return context_layer, attention_scores - - -class BertSelfAttention(nn.Cell): - """ - Apply self-attention. - - Args: - seq_length (int): Length of input sequence. - hidden_size (int): Size of the bert encoder layers. - num_attention_heads (int): Number of attention heads. Default: 12. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.1. - use_one_hot_embeddings (bool): Specifies whether to use one_hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - compute_type (:class:`mindspore.dtype`): Compute type in BertSelfAttention. Default: mstype.float32. - """ - - def __init__(self, - seq_length, - hidden_size, - num_attention_heads=12, - attention_probs_dropout_prob=0.1, - use_one_hot_embeddings=False, - initializer_range=0.02, - hidden_dropout_prob=0.1, - use_relative_positions=False, - compute_type=mstype.float32, - activation_init=2.5): - super(BertSelfAttention, self).__init__() - if hidden_size % num_attention_heads != 0: - raise ValueError("The hidden size (%d) is not a multiple of the number " - "of attention heads (%d)" % (hidden_size, num_attention_heads)) - self.size_per_head = int(hidden_size / num_attention_heads) - self.attention = BertAttention( - from_tensor_width=hidden_size, - to_tensor_width=hidden_size, - from_seq_length=seq_length, - to_seq_length=seq_length, - num_attention_heads=num_attention_heads, - size_per_head=self.size_per_head, - attention_probs_dropout_prob=attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=initializer_range, - use_relative_positions=use_relative_positions, - has_attention_mask=True, - do_return_2d_tensor=True, - compute_type=compute_type, - activation_init=activation_init - ) - self.output = BertOutput(in_channels=hidden_size, - out_channels=hidden_size, - initializer_range=initializer_range, - dropout_prob=hidden_dropout_prob, - compute_type=compute_type, - activation_init=activation_init) - self.reshape = P.Reshape() - self.shape = (-1, hidden_size) - - def construct(self, input_tensor, attention_mask): - """bert self attention""" - input_tensor = self.reshape(input_tensor, self.shape) - attention_output, attention_scores = self.attention(input_tensor, input_tensor, attention_mask) - output = self.output(attention_output, input_tensor) - return output, attention_scores - - -class BertEncoderCell(nn.Cell): - """ - Encoder cells used in BertTransformer. - - Args: - hidden_size (int): Size of the bert encoder layers. Default: 768. - seq_length (int): Length of input sequence. Default: 512. - num_attention_heads (int): Number of attention heads. Default: 12. - intermediate_size (int): Size of intermediate layer. Default: 3072. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.02. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - hidden_act (str): Activation function. Default: "gelu". - compute_type (:class:`mindspore.dtype`): Compute type in attention. Default: mstype.float32. - """ - - def __init__(self, - hidden_size=768, - seq_length=512, - num_attention_heads=12, - intermediate_size=3072, - attention_probs_dropout_prob=0.02, - use_one_hot_embeddings=False, - initializer_range=0.02, - hidden_dropout_prob=0.1, - use_relative_positions=False, - hidden_act="gelu", - compute_type=mstype.float32, - activation_init=2.5): - super(BertEncoderCell, self).__init__() - self.attention = BertSelfAttention( - hidden_size=hidden_size, - seq_length=seq_length, - num_attention_heads=num_attention_heads, - attention_probs_dropout_prob=attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=initializer_range, - hidden_dropout_prob=hidden_dropout_prob, - use_relative_positions=use_relative_positions, - compute_type=compute_type, - activation_init=activation_init) - self.intermediate = nn.DenseQuant(in_channels=hidden_size, - out_channels=intermediate_size, - activation=hidden_act, - weight_init=Normal(initializer_range)).to_float(compute_type) - self.output = BertOutput(in_channels=intermediate_size, - out_channels=hidden_size, - initializer_range=initializer_range, - dropout_prob=hidden_dropout_prob, - compute_type=compute_type, - activation_init=activation_init) - self.quant_encoder_in = FakeQuantWithMinMax(min_init=-activation_init, - max_init=activation_init, - ema=True) - self.quant_encoder_out = FakeQuantWithMinMax(min_init=-activation_init, - max_init=activation_init, - ema=True) - - def construct(self, hidden_states, attention_mask): - """bert encoder cell""" - # self-attention - attention_output, attention_scores = self.attention(hidden_states, attention_mask) - # feed construct - attention_output = self.quant_encoder_in(attention_output) - intermediate_output = self.intermediate(attention_output) - intermediate_output = self.quant_encoder_out(intermediate_output) - # add and normalize - output = self.output(intermediate_output, attention_output) - return output, attention_scores - - -class BertTransformer(nn.Cell): - """ - Multi-layer bert transformer. - - Args: - hidden_size (int): Size of the encoder layers. - seq_length (int): Length of input sequence. - num_hidden_layers (int): Number of hidden layers in encoder cells. - num_attention_heads (int): Number of attention heads in encoder cells. Default: 12. - intermediate_size (int): Size of intermediate layer in encoder cells. Default: 3072. - attention_probs_dropout_prob (float): The dropout probability for - BertAttention. Default: 0.1. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - initializer_range (float): Initialization value of Normal. Default: 0.02. - hidden_dropout_prob (float): The dropout probability for BertOutput. Default: 0.1. - use_relative_positions (bool): Specifies whether to use relative positions. Default: False. - hidden_act (str): Activation function used in the encoder cells. Default: "gelu". - compute_type (:class:`mindspore.dtype`): Compute type in BertTransformer. Default: mstype.float32. - return_all_encoders (bool): Specifies whether to return all encoders. Default: False. - """ - - def __init__(self, - hidden_size, - seq_length, - num_hidden_layers, - num_attention_heads=12, - intermediate_size=3072, - attention_probs_dropout_prob=0.1, - use_one_hot_embeddings=False, - initializer_range=0.02, - hidden_dropout_prob=0.1, - use_relative_positions=False, - hidden_act="gelu", - compute_type=mstype.float32, - return_all_encoders=False): - super(BertTransformer, self).__init__() - self.return_all_encoders = return_all_encoders - layers = [] - for _ in range(num_hidden_layers): - layer = BertEncoderCell(hidden_size=hidden_size, - seq_length=seq_length, - num_attention_heads=num_attention_heads, - intermediate_size=intermediate_size, - attention_probs_dropout_prob=attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=initializer_range, - hidden_dropout_prob=hidden_dropout_prob, - use_relative_positions=use_relative_positions, - hidden_act=hidden_act, - compute_type=compute_type,) - layers.append(layer) - self.layers = nn.CellList(layers) - self.reshape = P.Reshape() - self.shape = (-1, hidden_size) - self.out_shape = (-1, seq_length, hidden_size) - - def construct(self, input_tensor, attention_mask): - """bert transformer""" - prev_output = self.reshape(input_tensor, self.shape) - all_encoder_layers = () - all_encoder_atts = () - all_encoder_outputs = () - all_encoder_outputs += (prev_output,) - for layer_module in self.layers: - layer_output, encoder_att = layer_module(prev_output, attention_mask) - prev_output = layer_output - if self.return_all_encoders: - all_encoder_outputs += (layer_output,) - layer_output = self.reshape(layer_output, self.out_shape) - all_encoder_layers += (layer_output,) - all_encoder_atts += (encoder_att,) - if not self.return_all_encoders: - prev_output = self.reshape(prev_output, self.out_shape) - all_encoder_layers += (prev_output,) - return all_encoder_layers, all_encoder_outputs, all_encoder_atts - - -class CreateAttentionMaskFromInputMask(nn.Cell): - """ - Create attention mask according to input mask. - - Args: - config (Class): Configuration for BertModel. - """ - - def __init__(self, config): - super(CreateAttentionMaskFromInputMask, self).__init__() - self.input_mask = None - self.cast = P.Cast() - self.reshape = P.Reshape() - self.shape = (-1, 1, config.seq_length) - - def construct(self, input_mask): - attention_mask = self.cast(self.reshape(input_mask, self.shape), mstype.float32) - return attention_mask - - -class BertModel(nn.Cell): - """ - Bidirectional Encoder Representations from Transformers. - - Args: - config (Class): Configuration for BertModel. - is_training (bool): True for training mode. False for eval mode. - use_one_hot_embeddings (bool): Specifies whether to use one hot encoding form. Default: False. - """ - - def __init__(self, - config, - is_training, - use_one_hot_embeddings=False, activation_init=2.5): - super(BertModel, self).__init__() - config = copy.deepcopy(config) - if not is_training: - config.hidden_dropout_prob = 0.0 - config.attention_probs_dropout_prob = 0.0 - self.seq_length = config.seq_length - self.hidden_size = config.hidden_size - self.num_hidden_layers = config.num_hidden_layers - self.embedding_size = config.hidden_size - self.token_type_ids = None - self.last_idx = self.num_hidden_layers - 1 - output_embedding_shape = [-1, self.seq_length, - self.embedding_size] - self.bert_embedding_lookup = EmbeddingLookup( - vocab_size=config.vocab_size, - embedding_size=self.embedding_size, - embedding_shape=output_embedding_shape, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=config.initializer_range) - self.bert_embedding_postprocessor = EmbeddingPostprocessor( - use_relative_positions=config.use_relative_positions, - embedding_size=self.embedding_size, - embedding_shape=output_embedding_shape, - use_token_type=True, - token_type_vocab_size=config.type_vocab_size, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=0.02, - max_position_embeddings=config.max_position_embeddings, - dropout_prob=config.hidden_dropout_prob) - self.bert_encoder = BertTransformer( - hidden_size=self.hidden_size, - seq_length=self.seq_length, - num_attention_heads=config.num_attention_heads, - num_hidden_layers=self.num_hidden_layers, - intermediate_size=config.intermediate_size, - attention_probs_dropout_prob=config.attention_probs_dropout_prob, - use_one_hot_embeddings=use_one_hot_embeddings, - initializer_range=config.initializer_range, - hidden_dropout_prob=config.hidden_dropout_prob, - use_relative_positions=config.use_relative_positions, - hidden_act=config.hidden_act, - compute_type=config.compute_type, - return_all_encoders=True) - self.cast = P.Cast() - self.dtype = config.dtype - self.cast_compute_type = SaturateCast(dst_type=config.compute_type) - self.slice = P.StridedSlice() - self.squeeze_1 = P.Squeeze(axis=1) - self.dense = nn.DenseQuant(self.hidden_size, self.hidden_size, - activation="tanh", - weight_init=Normal(config.initializer_range)).to_float(config.compute_type) - self.quant_model_in = FakeQuantWithMinMax(min_init=-activation_init, - max_init=activation_init, - ema=True) - self.quant_model_out = FakeQuantWithMinMax(min_init=-activation_init, - max_init=activation_init, - ema=True) - self._create_attention_mask_from_input_mask = CreateAttentionMaskFromInputMask(config) - - def construct(self, input_ids, token_type_ids, input_mask): - """bert model""" - # embedding - word_embeddings, embedding_tables = self.bert_embedding_lookup(input_ids) - embedding_output = self.bert_embedding_postprocessor(token_type_ids, word_embeddings) - # attention mask [batch_size, seq_length, seq_length] - attention_mask = self._create_attention_mask_from_input_mask(input_mask) - # bert encoder - encoder_output, encoder_layers, layer_atts = self.bert_encoder(self.cast_compute_type(embedding_output), - attention_mask) - sequence_output = self.cast(encoder_output[self.last_idx], self.dtype) - # pooler - batch_size = P.Shape()(input_ids)[0] - sequence_slice = self.slice(sequence_output, - (0, 0, 0), - (batch_size, 1, self.hidden_size), - (1, 1, 1)) - first_token = self.squeeze_1(sequence_slice) - first_token = self.quant_model_in(first_token) - pooled_output = self.dense(first_token) - pooled_output = self.quant_model_out(pooled_output) - pooled_output = self.cast(pooled_output, self.dtype) - encoder_outputs = () - for output in encoder_layers: - encoder_outputs += (self.cast(output, self.dtype),) - attention_outputs = () - for output in layer_atts: - attention_outputs += (self.cast(output, self.dtype),) - return sequence_output, pooled_output, embedding_tables, encoder_outputs, attention_outputs - - -class BertModelCLS(nn.Cell): - """ - This class is responsible for classification task evaluation, - i.e. XNLI(num_labels=3), LCQMC(num_labels=2), Chnsenti(num_labels=2). - The returned output represents the final logits as the results of log_softmax is proportional to that of softmax. - """ - - def __init__(self, config, is_training, num_labels=2, dropout_prob=0.0, - use_one_hot_embeddings=False, phase_type="student"): - super(BertModelCLS, self).__init__() - - self.bert = BertModel(config, is_training, use_one_hot_embeddings) - self.cast = P.Cast() - self.weight_init = Normal(config.initializer_range) - self.log_softmax = P.LogSoftmax(axis=-1) - self.dtype = config.dtype - self.num_labels = num_labels - self.phase_type = phase_type - if self.phase_type == "teacher": - self.dense = nn.Dense(config.hidden_size, self.num_labels, weight_init=self.weight_init, - has_bias=True).to_float(config.compute_type) - else: - self.dense_1 = nn.DenseQuant(config.hidden_size, self.num_labels, weight_init=self.weight_init, - has_bias=True).to_float(config.compute_type) - self.dropout = nn.ReLU() - - def construct(self, input_ids, token_type_id, input_mask): - """classification bert model""" - _, pooled_output, _, seq_output, att_output = self.bert(input_ids, token_type_id, input_mask) - cls = self.cast(pooled_output, self.dtype) - cls = self.dropout(cls) - if self.phase_type == "teacher": - logits = self.dense(cls) - else: - logits = self.dense_1(cls) - logits = self.cast(logits, self.dtype) - log_probs = self.log_softmax(logits) - if self._phase == 'train' or self.phase_type == "teacher": - return seq_output, att_output, logits, log_probs - return seq_output, att_output, logits, log_probs diff --git a/official/nlp/q8bert/src/utils.py b/official/nlp/q8bert/src/utils.py deleted file mode 100644 index 38c426aec80140b773528ea17b5f4708ecfb25b9..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/src/utils.py +++ /dev/null @@ -1,268 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""q8bert utils""" - -import os -import logging -import numpy as np -from mindspore import Tensor -from mindspore.common import dtype as mstype -from mindspore.train.callback import Callback -from mindspore.train.serialization import save_checkpoint -from mindspore.ops import operations as P -from mindspore.nn.learning_rate_schedule import LearningRateSchedule, PolynomialDecayLR, WarmUpLR -from .config import glue_output_modes - -logger = logging.getLogger(__name__) - -try: - from scipy.stats import pearsonr, spearmanr - from sklearn.metrics import matthews_corrcoef, f1_score - _has_sklearn = True -except (AttributeError, ImportError) as e: - logger.warning("To use data.metrics please install scikit-learn. See https://scikit-learn.org/stable/index.html") - _has_sklearn = False - - -def is_sklearn_available(): - return _has_sklearn - - -if _has_sklearn: - - def simple_accuracy(preds, labels): - return (preds == labels).mean() - - def acc_and_f1(preds, labels): - acc = simple_accuracy(preds, labels) - f1 = f1_score(y_true=labels, y_pred=preds) - return { - "acc": acc, - "f1": f1, - "acc_and_f1": (acc + f1) / 2, - } - - def pearson_and_spearman(preds, labels): - pearson_corr = pearsonr(preds, labels)[0] - spearman_corr = spearmanr(preds, labels)[0] - return { - "pearson": pearson_corr, - "spearmanr": spearman_corr, - "corr": (pearson_corr + spearman_corr) / 2, - } - - def glue_compute_metrics(task_name, preds, labels): - """different dataset evaluation.""" - assert len(preds) == len(labels) - if task_name == "cola": - result = {"mcc": matthews_corrcoef(labels, preds)} - elif task_name == "sst-2": - result = {"acc": simple_accuracy(preds, labels)} - elif task_name == "mrpc": - result = acc_and_f1(preds, labels) - elif task_name == "sts-b": - result = pearson_and_spearman(preds, labels) - elif task_name == "qqp": - result = acc_and_f1(preds, labels) - elif task_name == "mnli": - result = {"acc": simple_accuracy(preds, labels)} - elif task_name == "mnli-mm": - result = {"acc": simple_accuracy(preds, labels)} - elif task_name == "qnli": - result = {"acc": simple_accuracy(preds, labels)} - elif task_name == "rte": - result = {"acc": simple_accuracy(preds, labels)} - elif task_name == "wnli": - result = {"acc": simple_accuracy(preds, labels)} - else: - raise KeyError(task_name) - return result - - -prior_index = { - "cola": "mcc", - "mnli": "acc", - "mnli-mm": "acc", - "mrpc": "acc", - "sst-2": "acc", - "sts-b": "pearson", - "qqp": "acc", - "qnli": "acc", - "rte": "acc", - "wnli": "acc", -} - - -class ModelSaveCkpt(Callback): - """ - Saves checkpoint. - If the loss in NAN or INF terminating training. - Args: - network (Network): The train network for training. - save_ckpt_num (int): The number to save checkpoint, default is 1000. - max_ckpt_num (int): The max checkpoint number, default is 3. - """ - def __init__(self, network, save_ckpt_step, max_ckpt_num, output_dir): - super(ModelSaveCkpt, self).__init__() - self.count = 0 - self.network = network - self.save_ckpt_step = save_ckpt_step - self.max_ckpt_num = max_ckpt_num - self.output_dir = output_dir - - def step_end(self, run_context): - """step end and save ckpt""" - cb_params = run_context.original_args() - if cb_params.cur_step_num % self.save_ckpt_step == 0: - saved_ckpt_num = cb_params.cur_step_num / self.save_ckpt_step - if saved_ckpt_num > self.max_ckpt_num: - oldest_ckpt_index = saved_ckpt_num - self.max_ckpt_num - path = os.path.join(self.output_dir, "q8bert_{}_{}.ckpt".format(int(oldest_ckpt_index), - cb_params.cur_step_num)) - if os.path.exists(path): - os.remove(path) - save_checkpoint(self.network, os.path.join(self.output_dir, - "q8bert_{}_{}.ckpt".format(int(saved_ckpt_num), - cb_params.cur_step_num))) - - -def make_directory(path: str): - """Make directory.""" - if path is None or not isinstance(path, str) or path.strip() == "": - logger.error("The path(%r) is invalid type.", path) - raise TypeError("Input path is invalid type") - - # convert the relative paths - path = os.path.realpath(path) - logger.debug("The abs path is %r", path) - - # check the path is exist and write permissions? - if os.path.exists(path): - real_path = path - else: - # All exceptions need to be caught because create directory maybe have some limit(permissions) - logger.debug("The directory(%s) doesn't exist, will create it", path) - try: - os.makedirs(path, exist_ok=True) - real_path = path - except PermissionError as e: - logger.error("No write permission on the directory(%r), error = %r", path, e) - raise TypeError("No write permission on the directory.") - return real_path - - -class LossCallBack(Callback): - """ - Monitor the loss in training. - If the loss in NAN or INF terminating training. - Note: - if per_print_times is 0 do not print loss. - Args: - per_print_times (int): Print loss every times. Default: 1. - """ - def __init__(self, per_print_times=1): - super(LossCallBack, self).__init__() - if not isinstance(per_print_times, int) or per_print_times < 0: - raise ValueError("print_step must be int and >= 0") - self._per_print_times = per_print_times - - def step_end(self, run_context): - """step end and print loss""" - cb_params = run_context.original_args() - loss, _ = cb_params.net_outputs - print("epoch: {}, step: {}, loss: {}".format(cb_params.cur_epoch_num, - cb_params.cur_step_num, - loss)) - - -class EvalCallBack(Callback): - """Evaluation callback""" - def __init__(self, network, dataset, task_name, logging_step, save_ckpt_dir): - super(EvalCallBack, self).__init__() - self.network = network - self.global_acc = 0.0 - self.dataset = dataset - self.task_name = task_name - self.logging_step = logging_step - self.best_result = 0.0 - self.save_ckpt_dir = save_ckpt_dir - - def step_end(self, run_context): - """step end and do evaluation""" - cb_params = run_context.original_args() - label_nums = 2 - if self.task_name.lower == 'mnli': - label_nums = 3 - if cb_params.cur_step_num % self.logging_step == 0: - self.network.set_train(False) - columns_list = ["input_ids", "input_mask", "segment_ids", "label_ids"] - preds = None - out_label_ids = None - for data in self.dataset.create_dict_iterator(num_epochs=1): - input_data = [] - for i in columns_list: - input_data.append(data[i]) - input_ids, input_mask, token_type_id, label_ids = input_data - _, _, logits, _ = self.network(input_ids, token_type_id, input_mask) - if preds is None: - preds = logits.asnumpy() - preds = np.reshape(preds, [-1, label_nums]) - out_label_ids = label_ids.asnumpy() - else: - preds = np.concatenate((preds, np.reshape(logits.asnumpy(), [-1, label_nums])), axis=0) - out_label_ids = np.append(out_label_ids, label_ids.asnumpy()) - if glue_output_modes[self.task_name.lower()] == "classification": - preds = np.argmax(preds, axis=1) - elif glue_output_modes[self.task_name.lower()] == "regression": - preds = np.reshape(preds, [-1]) - result = glue_compute_metrics(self.task_name.lower(), preds, out_label_ids) - prior_result = result[prior_index[self.task_name.lower()]] - if prior_result > self.best_result: - self.best_result = prior_result - eval_model_ckpt_file = os.path.join(self.save_ckpt_dir, self.task_name.lower() + "_eval_model.ckpt") - if os.path.exists(eval_model_ckpt_file): - os.remove(eval_model_ckpt_file) - save_checkpoint(self.network, eval_model_ckpt_file) - print("The current result is {}, the best result is {}".format(result, self.best_result)) - self.network.set_train(True) - - -class BertLearningRate(LearningRateSchedule): - """ - Warmup-decay learning rate for Bert network. - """ - def __init__(self, learning_rate, end_learning_rate, warmup_steps, decay_steps, power): - super(BertLearningRate, self).__init__() - self.warmup_flag = False - if warmup_steps > 0: - self.warmup_flag = True - self.warmup_lr = WarmUpLR(learning_rate, warmup_steps) - self.decay_lr = PolynomialDecayLR(learning_rate, end_learning_rate, decay_steps, power) - self.warmup_steps = Tensor(np.array([warmup_steps]).astype(np.float32)) - - self.greater = P.Greater() - self.one = Tensor(np.array([1.0]).astype(np.float32)) - self.cast = P.Cast() - - def construct(self, global_step): - decay_lr = self.decay_lr(global_step) - if self.warmup_flag: - is_warmup = self.cast(self.greater(self.warmup_steps, global_step), mstype.float32) - warmup_lr = self.warmup_lr(global_step) - lr = (self.one - is_warmup) * decay_lr + is_warmup * warmup_lr - else: - lr = decay_lr - return lr diff --git a/official/nlp/q8bert/train.py b/official/nlp/q8bert/train.py deleted file mode 100644 index 05b09f6d5bd44126344c7d4ec50b8bd6feb2bee4..0000000000000000000000000000000000000000 --- a/official/nlp/q8bert/train.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright 2021 Huawei Technologies Co., Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# 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. -# =========================================================================== - -"""q8bert train""" - -import argparse -import os -import ast - -from mindspore import context -from mindspore import set_seed -from mindspore.nn.optim import AdamWeightDecay -from mindspore.nn.wrap.loss_scale import DynamicLossScaleUpdateCell -from mindspore.train.callback import TimeMonitor -from mindspore.train.model import Model -import mindspore.common.dtype as mstype - -from src.dataset import create_dataset -from src.q8bert import BertEvaluationWithLossScaleCell, BertNetworkWithLoss_td, BertEvaluationCell -from src.config import train_cfg, eval_cfg, model_cfg, glue_output_modes, task_params -from src.utils import LossCallBack, ModelSaveCkpt, EvalCallBack, BertLearningRate - - -def parse_args(): - """ - parse args - """ - parser = argparse.ArgumentParser(description="Q8Bert task train") - 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("--do_eval", type=ast.literal_eval, default=True, help="Do eval task, default is True.") - parser.add_argument("--epoch_num", type=int, default=3, help="default is 3.") - parser.add_argument("--device_id", type=int, default=0, help="Device id, default is 0.") - parser.add_argument("--do_shuffle", type=ast.literal_eval, default=True, - help="Enable shuffle for dataset, default is True.") - parser.add_argument("--enable_data_sink", type=ast.literal_eval, default=True, - help="Enable data sink, default is True.") - parser.add_argument("--save_ckpt_step", type=int, default=100, help="Enable save ckpt.") - parser.add_argument("--max_ckpt_num", type=int, default=1, help="Number of saved pretrained models, default is 1.") - parser.add_argument("--data_sink_steps", type=int, default=1, help="Sink steps for each epoch, default is 1.") - parser.add_argument("--load_ckpt_path", type=str, default="", help="Load checkpoint file path") - parser.add_argument("--train_data_dir", type=str, default="", - help="Train data path, it is better to use absolute path") - parser.add_argument("--eval_data_dir", type=str, default="", - help="Eval data path, it is better to use absolute path") - parser.add_argument("--do_quant", type=ast.literal_eval, default=True, help="Do quant for model") - parser.add_argument("--logging_step", type=int, default=100, help="Do evalate each logging step") - parser.add_argument("--task_name", type=str, default="STS-B", choices=["STS-B", "QNLI", "SST-2"], - help="The name of the task to train.") - parser.add_argument("--dataset_type", type=str, default="tfrecord", - help="dataset type tfrecord/mindrecord, default is tfrecord") - args = parser.parse_args() - return args - - -args_opt = parse_args() -_cur_dir = os.getcwd() -save_ckpt_dir = os.path.join(_cur_dir, "Q8Bert_" + args_opt.task_name + "_model") -if not os.path.exists(save_ckpt_dir): - os.makedirs(save_ckpt_dir) - -DEFAULT_NUM_LABELS = 2 -DEFAULT_SEQ_LENGTH = 128 - - -class Task: - """ - Encapsulation class of get the task parameter. - """ - def __init__(self, task_name): - self.task_name = task_name - - @property - def num_labels(self): - if self.task_name in task_params and "num_labels" in task_params[self.task_name]: - return task_params[self.task_name]["num_labels"] - return DEFAULT_NUM_LABELS - - @property - def seq_length(self): - if self.task_name in task_params and "seq_length" in task_params[self.task_name]: - return task_params[self.task_name]["seq_length"] - return DEFAULT_SEQ_LENGTH - - -task = Task(args_opt.task_name) - - -def do_train(): - """ - do train - """ - ckpt_file = args_opt.load_ckpt_path - - if not ckpt_file: - raise ValueError("Student ckpt file should not be None") - cfg = train_cfg - - if args_opt.device_target == "Ascend": - context.set_context(mode=context.GRAPH_MODE, device_target=args_opt.device_target, device_id=args_opt.device_id) - model_cfg.compute_type = mstype.float16 - train_cfg.loss_scale_value = 2 ** 10 - elif args_opt.device_target == "GPU": - context.set_context(mode=context.GRAPH_MODE, device_target=args_opt.device_target) - else: - raise Exception("Target error, GPU or Ascend is supported.") - - load_student_checkpoint_path = ckpt_file - netwithloss = BertNetworkWithLoss_td(student_config=model_cfg, student_ckpt=load_student_checkpoint_path, - do_quant=args_opt.do_quant, is_training=True, - task_type=glue_output_modes[args_opt.task_name.lower()], - num_labels=task.num_labels, is_predistill=False) - rank = 0 - device_num = 1 - train_dataset = create_dataset(cfg.batch_size, - device_num, rank, args_opt.do_shuffle, - args_opt.train_data_dir, - data_type=args_opt.dataset_type, - seq_length=task.seq_length, - drop_remainder=True) - - dataset_size = train_dataset.get_dataset_size() - print("train dataset size: ", dataset_size) - if args_opt.enable_data_sink: - repeat_count = args_opt.epoch_num * train_dataset.get_dataset_size() // args_opt.data_sink_steps - time_monitor_steps = args_opt.data_sink_steps - else: - repeat_count = args_opt.epoch_num - time_monitor_steps = dataset_size - - optimizer_cfg = cfg.optimizer_cfg - - lr_schedule = BertLearningRate(learning_rate=optimizer_cfg.AdamWeightDecay.learning_rate, - end_learning_rate=optimizer_cfg.AdamWeightDecay.end_learning_rate, - warmup_steps=int(dataset_size * args_opt.epoch_num / 10), - decay_steps=int(dataset_size * args_opt.epoch_num), - power=optimizer_cfg.AdamWeightDecay.power) - params = netwithloss.trainable_params() - decay_params = list(filter(optimizer_cfg.AdamWeightDecay.decay_filter, params)) - other_params = list(filter(lambda x: not optimizer_cfg.AdamWeightDecay.decay_filter(x), params)) - group_params = [{"params": decay_params, "weight_decay": optimizer_cfg.AdamWeightDecay.weight_decay}, - {"params": other_params, "weight_decay": 0.0}, - {"order_params": params}] - - optimizer = AdamWeightDecay(group_params, learning_rate=lr_schedule, eps=optimizer_cfg.AdamWeightDecay.eps) - - eval_dataset = create_dataset(eval_cfg.batch_size, - device_num, rank, args_opt.do_shuffle, - args_opt.eval_data_dir, - data_type=args_opt.dataset_type, - seq_length=task.seq_length, - drop_remainder=False) - print("eval dataset size: ", eval_dataset.get_dataset_size()) - - if args_opt.do_eval: - callback = [TimeMonitor(time_monitor_steps), LossCallBack(), - EvalCallBack(netwithloss.bert, eval_dataset, args_opt.task_name, args_opt.logging_step, - save_ckpt_dir)] - else: - callback = [TimeMonitor(time_monitor_steps), LossCallBack(), - ModelSaveCkpt(netwithloss.bert, - args_opt.save_ckpt_step, - args_opt.max_ckpt_num, - save_ckpt_dir)] - if enable_loss_scale: - update_cell = DynamicLossScaleUpdateCell(loss_scale_value=cfg.loss_scale_value, - scale_factor=cfg.scale_factor, - scale_window=cfg.scale_window) - netwithgrads = BertEvaluationWithLossScaleCell(netwithloss, optimizer=optimizer, scale_update_cell=update_cell) - else: - netwithgrads = BertEvaluationCell(netwithloss, optimizer=optimizer) - model = Model(netwithgrads) - model.train(repeat_count, train_dataset, callbacks=callback, - dataset_sink_mode=args_opt.enable_data_sink, - sink_size=args_opt.data_sink_steps) - - -if __name__ == "__main__": - set_seed(1) - enable_loss_scale = True - model_cfg.seq_length = task.seq_length - do_train()