|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- # Contents
-
- - [CenterFace Description](#CenterFace-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)
- - [Testing Process](#testing-process)
- - [Evaluation](#testing)
- - [Evaluation Process](#evaluation-process)
- - [Evaluation](#evaluation)
- - [Convert Process](#convert-process)
- - [Convert](#convert)
- - [Model Description](#model-description)
- - [Performance](#performance)
- - [Evaluation Performance](#evaluation-performance)
- - [Inference Performance](#inference-performance)
- - [ModelZoo Homepage](#modelzoo-homepage)
-
-
- # [CenterFace Description](#contents)
-
- CenterFace is a practical anchor-free face detection and alignment method for edge devices, we support training and evaluation on Ascend910.
-
- Face detection and alignment in unconstrained environment is always deployed on edge devices which have limited memory storage and low computing power.
- CenterFace proposes a one-stage method to simultaneously predict facial box and landmark location with real-time speed and high accuracy.
-
- [Paper](https://arxiv.org/ftp/arxiv/papers/1911/1911.03599.pdf): CenterFace: Joint Face Detection and Alignment Using Face as Point.
- Xu, Yuanyuan(Huaqiao University) and Yan, Wan(StarClouds) and Sun, Haixin(Xiamen University)
- and Yang, Genke(Shanghai Jiaotong University) and Luo, Jiliang(Huaqiao University)
-
- # [Model Architecture](#contents)
-
- CenterFace uses mobilenet_v2 as pretrained backbone, add 4 layer fpn, with four head.
- Four loss is presented, total loss is their weighted mean.
-
- # [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 support: [WiderFace] or datasetd with the same format as WiderFace
- Annotation support: [WiderFace] or annotation as the same format as WiderFace
-
- - The directory structure is as follows, the name of directory and file is user define:
- ```
- ├── dataset
- ├── centerface
- ├── annotations
- │ ├─ train.json
- │ └─ val.json
- ├─ images
- │ ├─ train
- │ │ └─images
- │ │ ├─class1_image_folder
- │ │ ├─ ...
- │ │ └─classn_image_folder
- │ └─ val
- │ └─images
- │ ├─class1_image_folder
- │ ├─ ...
- │ └─classn_image_folder
- └─ ground_truth
- ├─val.mat
- ├─ ...
- └─xxx.mat
- ```
- we suggest user to use WiderFace dataset to experience our model,
- other datasets need to use the same format as WiderFace.
-
- # [Environment Requirements](#contents)
-
- - Hardware(Ascend)
- - Prepare hardware environment with Ascend processor. If you want to try Ascend, please send the [application form](https://obs-9be7.obs.cn-east-2.myhuaweicloud.com/file/other/Ascend%20Model%20Zoo%E4%BD%93%E9%AA%8C%E8%B5%84%E6%BA%90%E7%94%B3%E8%AF%B7%E8%A1%A8.docx) to ascend@huawei.com. Once approved, you can get the resources.
- - Framework
- - [MindSpore](https://cmc-szv.clouddragon.huawei.com/cmcversion/index/search?searchKey=Do-MindSpore%20V100R001C00B622)
- - For more information, please check the resources below:
- - [MindSpore tutorials](https://www.mindspore.cn/tutorial/zh-CN/master/index.html)
- - [MindSpore API](https://www.mindspore.cn/api/zh-CN/master/index.html)
-
- # [Quick Start](#contents)
-
- After installing MindSpore via the official website, you can start training and evaluation as follows:
-
- step1: prepare pretrained model: train a mobilenet_v2 model by mindspore or use the script below:
- ```python
- #CenterFace need a pretrained mobilenet_v2 model:
- # mobilenet_v2_key.ckpt is a model with all value zero, we need the key/cell/module name for this model.
- # you must first use this script to convert your mobilenet_v2 pytorch model to mindspore model as a pretrain model.
- # The key/cell/module name must as follow, otherwise you need to modify "name_map" function:
- # --mindspore: as the same as mobilenet_v2_key.ckpt
- # --pytorch: same as official pytorch model(e.g., official mobilenet_v2-b0353104.pth)
- python torch_to_ms_mobilenetv2.py --ckpt_fn=./mobilenet_v2_key.ckpt --pt_fn=./mobilenet_v2-b0353104.pth --out_ckpt_fn=./mobilenet_v2.ckpt
- ```
- step2: prepare user rank_table
- ```python
- # user can use your own rank table file
- # or use the [hccl_tools](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/utils/hccl_tools) to generate rank table file
- # e.g., python hccl_tools.py --device_num "[0,8)"
- python hccl_tools.py --device_num "[0,8)"
- ```
- step3: train
- ```python
- cd scripts;
- # prepare data_path, use symbolic link
- ln -sf [USE_DATA_DIR] dataset
- # check you dir to make sure your datas are in the right path
- ls ./dataset/centerface # data path
- ls ./dataset/centerface/annotations/train.json # annot_path
- ls ./dataset/centerface/images/train/images # img_dir
- ```
- ```python
- # enter script dir, train CenterFace
- sh train_distribute.sh
- # after training
- mkdir ./model
- cp device0/outputs/*/*.ckpt ./model # cp model to [MODEL_PATH]
- ```
- step4: test
- ```python
- # test CenterFace preparing
- cd ../dependency/centernet/src/lib/external;
- python setup.py install;
- make;
- cd -; #cd ../../../../../scripts;
- cd ../dependency/evaluate;
- python setup.py install; # used for eval
- cd -; #cd ../../scripts;
- mkdir ./output
- mkdir ./output/centerface
- # check you dir to make sure your datas are in the right path
- ls ./dataset/images/val/images/ # data path
- ls ./dataset/centerface/ground_truth/val.mat # annot_path
- ```
- ```python
- # test CenterFace
- sh test_distribute.sh
- ```
- step5: eval
- ```python
- # after test, eval CenterFace, get MAP
- # cd ../dependency/evaluate;
- # python setup.py install;
- # cd -; #cd ../../scripts;
- sh eval_all.sh
- ```
-
- # [Script Description](#contents)
-
- ## [Script and Sample Code](#contents)
-
- ```
- ├── cv
- ├── centerface
- ├── train.py // training scripts
- ├── test.py // testing training outputs
- ├── export.py // convert mindspore model to air model
- ├── README.md // descriptions about CenterFace
- ├── scripts
- │ ├──eval.sh // evaluate a single testing result
- │ ├──eval_all.sh // choose a range of testing results to evaluate
- │ ├──test.sh // testing a single model
- │ ├──test_distribute.sh // testing a range of models
- │ ├──test_and_eval.sh // test then evaluate a single model
- │ ├──train_standalone.sh // train in ascend with single npu
- │ ├──train_distribute.sh // train in ascend with multi npu
- ├── src
- │ ├──__init__.py
- │ ├──centerface.py // centerface networks, training entry
- │ ├──dataset.py // generate dataloader and data processing entry
- │ ├──config.py // centerface unique configs
- │ ├──losses.py // losses for centerface
- │ ├──lr_scheduler.py // learning rate scheduler
- │ ├──mobile_v2.py // modified mobilenet_v2 backbone
- │ ├──utils.py // auxiliary functions for train, to log and preload
- │ ├──var_init.py // weight initilization
- │ ├──convert_weight_mobilenetv2.py // convert pretrained backbone to mindspore
- │ ├──convert_weight.py // CenterFace model convert to mindspore
- └── dependency // third party codes: MIT License
- ├──extd // training dependency: data augmentation
- │ ├──utils
- │ │ └──augmentations.py // data anchor sample of PyramidBox to generate small images
- ├──evaluate // evaluate dependency
- │ ├──box_overlaps.pyx // box overlaps
- │ ├──setup.py // setupfile for box_overlaps.pyx
- │ ├──eval.py // evaluate testing results
- └──centernet // modified from 'centernet'
- └──src
- └──lib
- ├──datasets
- │ ├──dataset // train dataset core
- │ │ ├──coco_hp.py // read and formatting data
- │ ├──sample
- │ │ └──multi_pose.py // core for data processing
- ├──detectors // test core, including running, pre-processing and post-processing
- │ ├──base_detector.py // user can add your own test core; for example, use pytorch or tf for pre/post processing
- ├──external // test dependency
- │ ├──__init__.py
- │ ├──Makefile // makefile for nms
- │ ├──nms.pyx // use soft_nms
- │ ├──setup.py // setupfile for nms.pyx
- └──utils
- └──image.py // image processing functions
- ```
-
- ## [Script Parameters](#contents)
- 1. train scripts parameters
- the command is: python train.py [train parameters]
- Major parameters train.py as follows:
- ```python
- --lr: learning rate
- --per_batch_size: batch size on each device
- --is_distributed: multi-device or not
- --t_max: for cosine lr_scheduler
- --max_epoch: training epochs
- --warmup_epochs: warmup_epochs, not needed for adam, needed for sgd
- --lr scheduler: learning rate scheduler, default is multistep
- --lr_epochs: decrease lr steps
- --lr_gamma: decrease lr by a factor
- --weight_decay: weight decay
- --loss_scale: mix precision training
- --pretrained_backbone: pretrained mobilenet_v2 model path
- --data_dir: data dir
- --annot_path: annotations path
- --img_dir: img dir in data_dir
- ```
- 2. centerface unique configs: in config.py; not recommend user to change
-
- 3. test scripts parameters:
- the command is: python test.py [test parameters]
- Major parameters test.py as follows:
- ```python
- test_script_path: test.py path;
- --is_distributed: multi-device or not
- --data_dir: img dir
- --test_model: test model dir
- --ground_truth_mat: ground_truth file, mat type
- --save_dir: save_path for evaluate
- --rank: use device id
- --ckpt_name: test model name
- # blow are used for calculate ckpt/model name
- # model/ckpt name is "0-" + str(ckpt_num) + "_" + str(steps_per_epoch*ckpt_num) + ".ckpt";
- # ckpt_num is epoch number, can be calculated by device_num
- # detail can be found in "test.py"
- # if ckpt is specified not need below 4 parameter
- --device_num: training device number
- --steps_per_epoch: steps for each epoch
- --start: start loop number, used to calculate first epoch number
- --end: end loop number, used to calculate last epoch number
- ```
-
- 4. eval scripts parameters:
- the command is: python eval.py [pred] [gt]
- Major parameters eval.py as follows:
- ```python
- --pred: pred path, test output test.py->[--save_dir]
- --gt: ground truth path
- ```
-
- ## [Training Process](#contents)
-
- ### Training
-
- 'task_set' is important for multi-npu train to get higher speed
- --task_set: 0, not task_set; 1 task_set;
- --task_set_core: task_set core number, most time = cpu number/nproc_per_node
-
- step1: user need train a mobilenet_v2 model by mindspore or use the script below:
- ```python
- python torch_to_ms_mobilenetv2.py --ckpt_fn=./mobilenet_v2_key.ckpt --pt_fn=./mobilenet_v2-b0353104.pth --out_ckpt_fn=./mobilenet_v2.ckpt
- ```
- step2: prepare user rank_table
- ```python
- # user can use your own rank table file
- # or use the [hccl_tools](https://gitee.com/mindspore/mindspore/tree/master/model_zoo/utils/hccl_tools) to generate rank table file
- # e.g., python hccl_tools.py --device_num "[0,8)"
- python hccl_tools.py --device_num "[0,8)"
- ```
- step3: train
- - Single device
- ```python
- # enter script dir, train CenterFace
- cd scripts
- # you need to change the parameter in train_standalone.sh
- # or use symbolic link as quick start
- # or use the command as follow:
- # USE_DEVICE_ID: your device
- # PRETRAINED_BACKBONE: your pretrained model path
- # DATASET: dataset path
- # ANNOTATIONS: annotation path
- # images: img_dir in dataset path
- sh train_standalone.sh [USE_DEVICE_ID] [PRETRAINED_BACKBONE] [DATASET] [ANNOTATIONS] [IMAGES]
- # after training
- cp device0/outputs/*/*.ckpt [MODEL_PATH]
- ```
- - multi-device (recommended)
- ```python
- # enter script dir, train CenterFace
- cd scripts;
- # you need to change the parameter in train_distribute.sh
- # or use symbolic link as quick start
- # or use the command as follow, most are the same as train_standalone.sh, the different is RANK_TABLE
- # RANK_TABLE: for multi-device only, from generate_rank_table.py or user writing
- sh train_distribute.sh [RANK_TABLE] [PRETRAINED_BACKBONE] [DATASET] [ANNOTATIONS] [IMAGES]
- # after training
- cp device0/outputs/*/*.ckpt [MODEL_PATH]
- ```
- After training with 8 device, the loss value will be achieved as follows:
- ```python
- # grep "loss is " device0/xxx.log
- # epoch: 1 step: 1, loss is greater than 500 and less than 5000
- 2020-09-24 19:00:53,550:INFO:epoch:1, iter:0, average_loss:loss:1148.415649, loss:1148.4156494140625, overflow:False, loss_scale:1024.0
- [WARNING] DEBUG(51499,python):2020-09-24-19:00:53.590.008 [mindspore/ccsrc/debug/dump_proto.cc:218] SetValueToProto] Unsupported type UInt
- 2020-09-24 19:00:53,784:INFO:epoch:1, iter:1, average_loss:loss:798.286713, loss:448.15777587890625, overflow:False, loss_scale:1024.0
- ...
- 2020-09-24 19:01:58,095:INFO:epoch:2, iter:197, average_loss:loss:1.942609, loss:1.5492267608642578, overflow:False, loss_scale:1024.0
- 2020-09-24 19:01:58,501:INFO:epoch[2], loss:1.942609, 477.97 imgs/sec, lr:0.004000000189989805
- 2020-09-24 19:01:58,502:INFO:==========end epoch===============
- 2020-09-24 19:02:00,780:INFO:epoch:3, iter:0, average_loss:loss:2.107658, loss:2.1076583862304688, overflow:False, loss_scale:1024.0
- ...
- # epoch: 140 average loss is greater than 0.3 and less than 1.5:
- 2020-09-24 20:19:16,255:INFO:epoch:140, iter:196, average_loss:loss:0.906300, loss:1.1071504354476929, overflow:False, loss_scale:1024.0
- 2020-09-24 20:19:16,347:INFO:epoch:140, iter:197, average_loss:loss:0.904684, loss:0.586264967918396, overflow:False, loss_scale:1024.0
- 2020-09-24 20:19:16,747:INFO:epoch[140], loss:0.904684, 480.10 imgs/sec, lr:3.9999998989515007e-05
- 2020-09-24 20:19:16,748:INFO:==========end epoch===============
- 2020-09-24 20:19:16,748:INFO:==========end training===============
- ```
- The model checkpoint will be saved in the scripts/device0/output/xxx/xxx.ckpt
-
- ## [Testing Process](#contents)
-
- ### Testing
-
- ```python
- # after train, prepare for test CenterFace
- cd scripts;
- cd ../dependency/centernet/src/lib/external;
- python setup.py install;
- make;
- cd ../../../scripts;
- mkdir [SAVE_PATH]
- ```
- 1. test a single ckpt file
- ```python
- # you need to change the parameter in test.sh
- # or use symbolic link as quick start
- # or use the command as follow:
- # MODEL_PATH: ckpt path saved during training
- # DATASET: img dir
- # GROUND_TRUTH_MAT: ground_truth file, mat type
- # SAVE_PATH: save_path for evaluate
- # DEVICE_ID: use device id
- # CKPT: test model name
- sh test.sh [MODEL_PATH] [DATASET] [GROUND_TRUTH_MAT] [SAVE_PATH] [DEVICE_ID] [CKPT]
- ```
- 2. test many out ckpt for user to choose the best one
- ```python
- # you need to change the parameter in test.sh
- # or use symbolic link as quick start
- # or use the command as follow, most are the same as test.sh, the different are:
- # DEVICE_NUM: training device number
- # STEPS_PER_EPOCH: steps for each epoch
- # START: start loop number, used to calculate first epoch number
- # END: end loop number, used to calculate last epoch number
- sh test_distribute.sh [MODEL_PATH] [DATASET] [GROUND_TRUTH_MAT] [SAVE_PATH] [DEVICE_NUM] [STEPS_PER_EPOCH] [START] [END]
- ```
- After testing, you can find many txt file save the box information and scores,
- open it you can see:
- ```python
- 646.3 189.1 42.1 51.8 0.747 # left top hight weight score
- 157.4 408.6 43.1 54.1 0.667
- 120.3 212.4 38.7 42.8 0.650
- ...
- ```
- ## [Evaluation Process](#contents)
-
- ### Evaluation
-
- ```python
- # after test, prepare for eval CenterFace, get MAP
- cd ../dependency/evaluate;
- python setup.py install;
- cd ../../../scripts;
- ```
- 1. eval a single testing output
- ```python
- # you need to change the parameter in eval.sh
- # default eval the ckpt saved in ./scripts/output/centerface/999
- sh eval.sh
- ```
- 2. eval many testing output for user to choose the best one
- ```python
- # you need to change the parameter in eval_all.sh
- # default eval the ckpt saved in ./scripts/output/centerface/[89-140]
- sh eval_all.sh
- ```
- 3. test+eval
- ```python
- # you need to change the parameter in test_and_eval.sh
- # or use symbolic link as quick start, default eval the ckpt saved in ./scripts/output/centerface/999
- # or use the command as follow, most are the same as test.sh, the different are:
- # GROUND_TRUTH_PATH: ground truth path
- sh test_and_eval.sh [MODEL_PATH] [DATASET] [GROUND_TRUTH_MAT] [SAVE_PATH] [CKPT] [GROUND_TRUTH_PATH]
- ```
- you can see the MAP below by eval.sh
- ```
- (ci3.7) [root@bms-aiserver scripts]# ./eval.sh
- start eval
- ==================== Results = ==================== ./scripts/output/centerface/999
- Easy Val AP: 0.923914407045363
- Medium Val AP: 0.9166100571371586
- Hard Val AP: 0.7810750535799462
- =================================================
- end eval
- ```
-
- you can see the MAP below by eval_all.sh
- ```
- (ci3.7) [root@bms-aiserver scripts]# ./eval_all.sh
- ==================== Results = ==================== ./scripts/output/centerface/89
- Easy Val AP: 0.8884892849068273
- Medium Val AP: 0.8928813452811216
- Hard Val AP: 0.7721131614294564
- =================================================
- ==================== Results = ==================== ./scripts/output/centerface/90
- Easy Val AP: 0.8836073914165545
- Medium Val AP: 0.8875938506473486
- Hard Val AP: 0.775956751740446
- ...
- ==================== Results = ==================== ./scripts/output/centerface/125
- Easy Val AP: 0.923914407045363
- Medium Val AP: 0.9166100571371586
- Hard Val AP: 0.7810750535799462
- =================================================
- ==================== Results = ==================== ./scripts/output/centerface/126
- Easy Val AP: 0.9218741197149122
- Medium Val AP: 0.9151860193570651
- Hard Val AP: 0.7825645670331809
- ...
- ==================== Results = ==================== ./scripts/output/centerface/140
- Easy Val AP: 0.9250715236965638
- Medium Val AP: 0.9170429723233877
- Hard Val AP: 0.7822182013830674
- =================================================
- ```
- ## [Convert Process](#contents)
-
- ### Convert
- If you want to infer the network on Ascend 310, you should convert the model to AIR:
-
- ```python
- python export.py [BATCH_SIZE] [PRETRAINED_BACKBONE]
- ```
-
- # [Model Description](#contents)
-
- ## [Performance](#contents)
-
- ### Evaluation Performance
- CenterFace on 13K images(The annotation and data format must be the same as widerFace)
-
- | Parameters | CenterFace |
- | -------------------------- | ----------------------------------------------------------- |
- | Resource | Ascend 910; CPU 2.60GHz, 192cores; Memory, 755G |
- | uploaded Date | 10/29/2020 (month/day/year) |
- | MindSpore Version | 1.0.0 |
- | Dataset | 13K images |
- | Training Parameters | epoch=140, steps=198 * epoch, batch_size = 8, lr=0.004 |
- | Optimizer | Adam |
- | Loss Function | Focal Loss, L1 Loss, Smooth L1 Loss |
- | outputs | heatmaps |
- | Loss | 0.3-1.5, average loss for last epoch is in 0.8-1.0 |
- | Speed | 1p 65 img/s, 8p 475 img/s |
- | Total time | train(8p) 1.1h, test 50min, eval 5-10min |
- | Checkpoint for Fine tuning | 22M (.ckpt file) |
- | Scripts | https://gitee.com/mindspore/mindspore/tree/master/model_zoo/official/cv/centerface |
-
- ### Inference Performance
- CenterFace on 3.2K images(The annotation and data format must be the same as widerFace)
-
- | Parameters | CenterFace |
- | -------------------------- | ----------------------------------------------------------- |
- | Resource | Ascend 910; CPU 2.60GHz, 192cores; Memory, 755G |
- | uploaded Date | 10/29/2020 (month/day/year) |
- | MindSpore Version | 1.0.0 |
- | Dataset | 3.2K images |
- | batch_size | 1 |
- | outputs | box position and sorces, and probability |
- | Accuracy | Easy 92.2% Medium 91.5% Hard 78.2% (+-0.5%) |
- | Model for inference | 22M (.ckpt file) |
-
- # [Description of Random Situation](#contents)
-
- In dataset.py, we set the seed inside ```create_dataset``` function.
- In var_init.py, we set seed for weight initilization
-
- # [ModelZoo Homepage](#contents)
- Please check the official [homepage](https://gitee.com/mindspore/mindspore/tree/master/model_zoo).
|