diff --git a/research/cv/S-GhostNet/README.md b/research/cv/S-GhostNet/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..1db33d19d6620a2d4c2c54948c81bfd7fd1de43c
--- /dev/null
+++ b/research/cv/S-GhostNet/README.md
@@ -0,0 +1,165 @@
+# 鐩綍
+
+<!-- TOC -->
+
+- [鐩綍](#鐩綍)
+    - [姒傝堪](#姒傝堪)
+    - [璁烘枃](#璁烘枃)
+- [妯″瀷鏋舵瀯](#妯″瀷鏋舵瀯)
+- [鏁版嵁闆哴(#鏁版嵁闆�)
+- [鐜瑕佹眰](#鐜瑕佹眰)
+- [鑴氭湰璇存槑](#鑴氭湰璇存槑)
+    - [鑴氭湰缁撴瀯涓庤鏄嶿(#鑴氭湰缁撴瀯涓庤鏄�)
+- [璁粌杩囩▼](#璁粌杩囩▼)
+    - [鐢ㄦ硶](#鐢ㄦ硶)
+        - [Ascend澶勭悊鍣ㄧ幆澧冭繍琛宂(#ascend澶勭悊鍣ㄧ幆澧冭繍琛�)
+- [璇勪及杩囩▼](#璇勪及杩囩▼)
+    - [鐢ㄦ硶](#鐢ㄦ硶-1)
+        - [Ascend澶勭悊鍣ㄧ幆澧冭繍琛宂(#ascend澶勭悊鍣ㄧ幆澧冭繍琛�-1)
+    - [缁撴灉](#缁撴灉-1)
+- [妯″瀷鎻忚堪](#妯″瀷鎻忚堪)
+    - [鎬ц兘](#鎬ц兘)
+        - [璇勪及鎬ц兘](#璇勪及鎬ц兘)
+- [闅忔満鎯呭喌璇存槑](#闅忔満鎯呭喌璇存槑)
+- [ModelZoo涓婚〉](#modelzoo涓婚〉)
+
+<!-- /TOC -->
+
+# GhostNet鎻忚堪
+
+## 姒傝堪
+
+S-GhostNet鐢卞崕涓鸿浜氭柟鑸熷疄楠屽鍦�2021骞存彁鍑猴紝姝ょ綉缁滃湪GhostNet鐨勫熀纭€涓婏紝閫氳繃缃戠粶缁撴瀯鎼滅储鏂规硶鎺㈢储浜嗗ぇ妯″瀷鐨勬瀯寤烘柟娉曘€傛棬鍦ㄦ洿浣庤绠椾唬浠蜂笅锛屾彁渚涙洿浼樼殑鎬ц兘銆傝鏋舵瀯鍙互鍦ㄥ悓鏍疯绠楅噺涓嬶紝绮惧害浼樹簬SOTA绠楁硶銆�
+
+濡備笅涓篗indSpore浣跨敤ImageNet2012鏁版嵁闆嗗GhostNet杩涜璁粌鐨勭ず渚嬨€�
+
+## 璁烘枃
+
+1. [璁烘枃](https://arxiv.org/pdf/2108.00177.pdf): Chuanjian Liu, Kai Han, An Xiao, Yiping Deng, Wei Zhang, Chunjing Xu, Yunhe Wang."Greedy Network Enlarging"
+
+# 妯″瀷鏋舵瀯
+
+GhostNet鐨勬€讳綋缃戠粶鏋舵瀯濡備笅锛歔閾炬帴](https://arxiv.org/pdf/1911.11907.pdf)
+
+# 鏁版嵁闆�
+
+浣跨敤鐨勬暟鎹泦锛歔ImageNet2012](http://www.image-net.org/)
+
+- 鏁版嵁闆嗗ぇ灏忥細鍏�1000涓被銆�224*224褰╄壊鍥惧儚
+    - 璁粌闆嗭細鍏�1,281,167寮犲浘鍍�
+    - 娴嬭瘯闆嗭細鍏�50,000寮犲浘鍍�
+- 鏁版嵁鏍煎紡锛欽PEG
+    - 娉細鏁版嵁鍦╠ataset.py涓鐞嗐€�
+- 涓嬭浇鏁版嵁闆嗭紝鐩綍缁撴瀯濡備笅锛�
+
+```text
+鈹斺攢dataset
+    鈹溾攢imagenet
+        鈹溾攢train                  # 璁粌鏁版嵁闆�
+        鈹斺攢val                    # 璇勪及鏁版嵁闆�
+```
+
+# 鐜瑕佹眰
+
+- 纭欢
+    - 鍑嗗Ascend澶勭悊鍣ㄦ惌寤虹‖浠剁幆澧冦€�
+- 妗嗘灦
+    - [MindSpore](https://www.mindspore.cn/install/en)
+- 濡傞渶鏌ョ湅璇︽儏锛岃鍙傝濡備笅璧勬簮锛�
+    - [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)
+
+# 鑴氭湰璇存槑
+
+## 鑴氭湰缁撴瀯涓庤鏄�
+
+```text
+鈹斺攢鈹€S-GhostNet
+  鈹溾攢鈹€ README.md
+  鈹溾攢鈹€ script
+    鈹溾攢鈹€ ma-pre-start.sh                    # Modelarts璁粌鏃ュ織淇濆瓨
+    鈹溾攢鈹€ train_distributed_ascend.sh        # 鍗曟満鍒嗗竷寮忚缁冭剼鏈�
+  鈹溾攢鈹€ src
+    鈹溾攢鈹€ autoaug.py                         # 鏁版嵁鑷姩澧炲己
+    鈹溾攢鈹€ dataset.py                         # 鏁版嵁棰勫鐞�
+    鈹溾攢鈹€ bignet.py                          # S-GhostNet缃戠粶瀹氫箟
+    鈹溾攢鈹€ callback.py                        # 妯″瀷鍙傛暟婊戝姩骞冲潎
+    鈹溾攢鈹€ eval_callback.py                   # 璁粌杩囩▼涓妯″瀷娴嬭瘯
+    鈹溾攢鈹€ loss.py                            # 妯″瀷璁粌鎹熷け瀹氫箟
+    鈹溾攢鈹€ utils.py
+    鈹斺攢鈹€ ghostnet.py                        # ghostnet缃戠粶
+  鈹溾攢鈹€ eval_b1.py                           # 璇勪及缃戠粶S-GhostNet-b1
+  鈹溾攢鈹€ eval_b4.py                           # 璇勪及缃戠粶S-GhostNet-b4
+  鈹斺攢鈹€ train.py                             # 璁粌缃戠粶
+  鈹斺攢鈹€ compute_acc.py                       # 缁熻鍑嗙‘鐜�
+```
+
+# 璁粌杩囩▼
+
+## 鐢ㄦ硶
+
+### ascend澶勭悊鍣ㄧ幆澧冭繍琛�
+
+```Shell
+# 鍒嗗竷寮忚缁�
+鐢ㄦ硶:bash train_distributed_ascend.sh [bignet] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH](optional)
+
+# 鍗曟満璁粌
+鐢ㄦ硶:python train.py --model big_net --data_path path-to-imagent --drop 0.2 --drop-path 0.2 --large --layers 2,4,5,12,6,14 --channels 36,68,108,164,216,336 --batch-size 4
+
+Modelarts璁粌
+python train.py --model big_net --amp_level=O0 --autoaugment --batch-size=32 --channels=36,60,108,168,232,336 --ckpt_save_epoch=20 --cloud= --data_url=obs://path-to-imagenet --decay-epochs=2.4 --decay-rate=0.97 --device_num=8 --distributed --drop=0.3 --drop-path=0.1 --ema-decay=0.97 --epochs=450 --input_size=384 --large --layers=3,5,5,12,6,14 --loss_scale=1024 --lr=0.0001 --lr_decay_style=cosine --lr_end=1e-6 --lr_max=0.6 --model=big_net --opt=momentum --opt-eps=0.0001 --sync_bn --warmup-epochs=20 --warmup-lr=1e-6 --weight-decay=2e-5 --workers=8
+
+```
+
+鍒嗗竷寮忚缁冮渶瑕佹彁鍓嶅垱寤篔SON鏍煎紡鐨凥CCL閰嶇疆鏂囦欢銆�
+
+鍏蜂綋鎿嶄綔锛屽弬瑙乕hccl_tools](https://gitee.com/mindspore/models/tree/master/utils/hccl_tools)涓殑璇存槑銆�
+
+# 璇勪及杩囩▼
+
+## 鐢ㄦ硶
+
+### ascend澶勭悊鍣ㄧ幆澧冭繍琛�
+
+```Shell
+# Modelarts璇勪及
+Usage: python eval_b4.py --data_url=obs://path-to-imagenet --large= --model=big_net --test_mode=ema_best --train_url=obs://path-to-pretrained-model --trained_model_dir=s3://path-to-output
+```
+
+璁粌杩囩▼涓彲浠ョ敓鎴愭鏌ョ偣銆�
+
+## 缁撴灉
+
+璇勪及缁撴灉淇濆瓨鍦ㄦ棩蹇楁枃浠朵腑銆傛偍鍙€氳繃compute_acc.py缁熻鍒嗗竷寮忚缁冧笅涓嶅悓checkpoint鐨勭粨鏋滐細
+
+# 妯″瀷鎻忚堪
+
+S-GhostNet_b1 --channels=28,44,72,140,196,280 --layers=1,2,3,4,3,6 --input_size=240 --large
+Top-1=79.844
+S-GhostNet_b4 --channels=36,60,108,168,232,336 --layers=3,5,5,12,6,14 --input_size=384 --large
+Top-1=83.024
+
+## 鎬ц兘
+
+### 璇勪及鎬ц兘
+
+| 鍙傛暟 | Ascend 910  |
+|---|---|
+| 妯″瀷鐗堟湰  | S-GhostNet |
+| 璧勬簮  |  Ascend 910锛汣PU锛�2.60GHz锛�192鏍革紱鍐呭瓨锛�755G |
+| 涓婁紶鏃ユ湡  |2022-04-29 ;  |
+| MindSpore鐗堟湰  | 1.5.1 |
+| 鏁版嵁闆�  |  ImageNet2012 |
+| 璁粌鍙傛暟  | epoch=450 |
+| 浼樺寲鍣�  | Momentum  |
+| 鎹熷け鍑芥暟  |Softmax浜ゅ弶鐔�  |
+|鎬绘椂闀�   |  S-GhostNet_b4 32鍗� 112灏忔椂 |
+
+# 闅忔満鎯呭喌璇存槑
+
+dataset.py涓缃簡鈥渃reate_dataset鈥濆嚱鏁板唴鐨勭瀛愶紝鍚屾椂杩樹娇鐢ㄤ簡train.py涓殑闅忔満绉嶅瓙銆�
+
+# ModelZoo涓婚〉
+
+璇锋祻瑙堝畼缃慬涓婚〉](https://gitee.com/mindspore/mindspore/tree/r1.3/model_zoo)銆�
diff --git a/research/cv/S-GhostNet/compute_acc.py b/research/cv/S-GhostNet/compute_acc.py
new file mode 100644
index 0000000000000000000000000000000000000000..26c266d3f064a989b2a16612657cc2b2937bfaef
--- /dev/null
+++ b/research/cv/S-GhostNet/compute_acc.py
@@ -0,0 +1,44 @@
+# Copyright 2022 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.
+# ============================================================================
+
+accuracy = {}
+acc_nums = {}
+with open('modelarts-job-c0a748c1-47a8-45d0-9603-2097883482c0-worker-0.log') as f:
+    lines = f.readlines()
+    for line in lines:
+        if 'Validation-Loss' in line:
+            contents = line.strip().split(' ')
+            ckpt_index = int(contents[1].strip(','))
+            if str(ckpt_index) not in accuracy.keys():
+                acc_nums[str(ckpt_index)] = 1
+                accuracy[str(ckpt_index)] = float(contents[8].strip(','))
+            else:
+                acc_nums[str(ckpt_index)] += 1
+                accuracy[str(ckpt_index)] += float(contents[8].strip(','))
+
+print(accuracy)
+print(acc_nums)
+
+mean_acc = []
+acc_go = acc_nums.keys()
+acc_lo = accuracy.keys()
+for key in acc_lo:
+    if key not in acc_go:
+        print('Wrong key!!!!!!!')
+    else:
+        mean_acc.append(accuracy[key]/acc_nums[key])
+
+print(mean_acc)
+print(max(mean_acc))
diff --git a/research/cv/S-GhostNet/eval_b1.py b/research/cv/S-GhostNet/eval_b1.py
new file mode 100644
index 0000000000000000000000000000000000000000..3397b6919e929bb12252603a9cd1f912cdbbbe75
--- /dev/null
+++ b/research/cv/S-GhostNet/eval_b1.py
@@ -0,0 +1,247 @@
+# Copyright 2022 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.
+# ============================================================================
+"""Inference Interface"""
+import sys
+import os
+import argparse
+import zipfile
+import time
+import moxing as mox
+from mindspore.communication.management import init, get_rank, get_group_size
+from mindspore.train.model import Model
+from mindspore.train.serialization import load_checkpoint, load_param_into_net
+from mindspore.nn import Loss, Top1CategoricalAccuracy, Top5CategoricalAccuracy
+from mindspore import context
+
+from src.dataset import create_dataset_val
+from src.utils import count_params
+from src.loss import LabelSmoothingCrossEntropy
+from src.tinynet import tinynet
+from src.ghostnet import ghostnet_1x
+from src.big_net import GhostNet
+
+os.environ["GLOG_v"] = '3'
+os.environ["ASCEND_SLOG_PRINT_TO_STDOUT"] = '0'
+os.environ["ASCEND_GLOBAL_LOG_LEVEL"] = '2'
+os.environ["ASCEND_GLOBAL_EVENT_ENABLE"] = '0'
+
+parser = argparse.ArgumentParser(description='Evaluation')
+parser.add_argument('--data_path', type=str, default='/autotest/liuchuanjian/data/imagenet/',
+                    metavar='DIR', help='path to dataset')
+parser.add_argument('--model', default='tinynet_c', type=str, metavar='MODEL',
+                    help='Name of model to train (default: "tinynet_c") ghostnet, big_net')
+parser.add_argument('--num-classes', type=int, default=1000, metavar='N',
+                    help='number of label classes (default: 1000)')
+parser.add_argument('--channels', type=str, default='24,32,64,112,160,280',
+                    help='channel config of model architecure')
+parser.add_argument('--layers', type=str, default='2,2,5,10,2,10',
+                    help='layer config of model architecure')
+parser.add_argument('--large', action='store_true', default=False,
+                    help='ghostnet1x or ghostnet larger')
+parser.add_argument('--input_size', type=int, default=248,
+                    help='input size of model.')
+parser.add_argument('--smoothing', type=float, default=0.1,
+                    help='label smoothing (default: 0.1)')
+parser.add_argument('-b', '--batch-size', type=int, default=125, metavar='N',
+                    help='input batch size for training (default: 32)')
+parser.add_argument('-j', '--workers', type=int, default=8, metavar='N',
+                    help='how many training processes to use (default: 1)')
+parser.add_argument('--GPU', action='store_true', default=False,
+                    help='Use GPU for training (default: False)')
+parser.add_argument('--dataset_sink', action='store_false', default=True)
+parser.add_argument('--drop', type=float, default=0.2, metavar='DROP',
+                    help='Dropout rate (default: 0.) for big_net, use "1-drop", for others, use "drop"')
+parser.add_argument('--drop-path', type=float, default=0.0, metavar='DROP',
+                    help='Drop connect rate (default: 0.)')
+parser.add_argument('--sync_bn', action='store_true', default=False,
+                    help='Use sync bn in distributed mode. (default: False)')
+parser.add_argument('--test_mode', default=None,
+                    help='Use ema saved model to test, "ema_best", "ema_last", ')
+
+# eval on cloud
+parser.add_argument('--cloud', action='store_true', default=False, help='Whether train on cloud.')
+parser.add_argument('--data_url', type=str, default="/home/ma-user/work/data/imagenet", help='path to dataset.')
+parser.add_argument('--zip_url', type=str, default="s3://bucket-800/liuchuanjian/data/imagenet_zip/imagenet.zip")
+parser.add_argument('--train_url', type=str, default=" ", help='train_dir.')
+parser.add_argument('--tmp_data_dir', default='/cache/data/', help='temp data dir')
+parser.add_argument('--trained_model_dir', default='s3://bucket-800/liuchuanjian/results/bignet/1291/',
+                    help='temp save dir')
+parser.add_argument('--tmp_save_dir', default='/cache/liuchuanjian/', help='temp save dir')
+
+_global_sync_count = 0
+
+def get_device_id():
+    device_id = os.getenv('DEVICE_ID', '0')
+    return int(device_id)
+
+def get_device_num():
+    device_num = os.getenv('RANK_SIZE', '1')
+    return int(device_num)
+
+def unzip_file(zip_src, dst_dir):
+    r = zipfile.is_zipfile(zip_src)
+    if r:
+        fz = zipfile.ZipFile(zip_src, 'r')
+        for file_item in fz.namelist():
+            fz.extract(file_item, dst_dir)
+    else:
+        raise Exception('This is not zip')
+
+def sync_data(opts):
+    """
+    Download data from remote obs to local directory if the first url is remote url and the second one is local path
+    Upload data from local directory to remote obs in contrast.
+    """
+    global _global_sync_count
+    sync_lock = "/tmp/copy_sync.lock" + str(_global_sync_count)
+    _global_sync_count += 1
+
+    if not mox.file.exists(opts.tmp_data_dir):
+        mox.file.make_dirs(opts.tmp_data_dir)
+    target_file = os.path.join(opts.tmp_data_dir, 'imagenet.zip')
+    # Each server contains 8 devices as most.
+    if get_device_id() % min(get_device_num(), 8) == 0 and not os.path.exists(sync_lock):
+        print("from path: ", opts.zip_url)
+        print("to path: ", target_file)
+        mox.file.copy_parallel(opts.zip_url, target_file)
+        print('Zip file copy success.')
+        print('Starting unzip file.')
+        unzip_file(target_file, opts.tmp_data_dir)
+        print('Unzip file success.')
+        print("===finish data synchronization===")
+        ## ckpt copy
+        print('Moving ckpt file')
+        if not mox.file.exists(opts.tmp_save_dir):
+            mox.file.make_dirs(opts.tmp_save_dir)
+        for i in range(8):
+            print('copying ckpt_ ', str(i))
+            if opts.test_mode == 'ema_best':
+                source_ckpt = os.path.join(opts.trained_model_dir, 'ckpt_'+str(i), 'ema_best.ckpt')
+                target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_best.ckpt')
+            elif opts.test_mode == 'ema_last':
+                source_ckpt = os.path.join(opts.trained_model_dir, 'ckpt_'+str(i), 'ema_last.ckpt')
+                target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_last.ckpt')
+            else:
+                source_ckpt = os.path.join(opts.trained_model_dir, 'ckpt_'+str(i), 'big_net-500_1251.ckpt')
+                target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'big_net-500_1251.ckpt')
+            if mox.file.exists(source_ckpt):
+                mox.file.copy(source_ckpt, target_ckpt)
+            else:
+                print(source_ckpt, 'does not exist.')
+
+        try:
+            os.mknod(sync_lock)
+        except IOError:
+            pass
+        print("===save flag===")
+
+    while True:
+        if os.path.exists(sync_lock):
+            break
+        time.sleep(1)
+
+    opts.data_url = os.path.join(opts.tmp_data_dir, 'imagenet')
+    opts.data_path = opts.data_url
+    print("Finish sync data from {} to {}.".format(opts.zip_url, target_file))
+
+def main(opts):
+    """Main entrance for training"""
+    print(sys.argv)
+    if opts.channels:
+        channel_config = []
+        for item in opts.channels.split(','):
+            channel_config.append(int(item.strip()))
+    if opts.layers:
+        layer_config = []
+        for item in opts.layers.split(','):
+            layer_config.append(int(item.strip()))
+    print(opts)
+
+    context.set_context(mode=context.GRAPH_MODE, device_target='Ascend')
+    devid = int(os.getenv('DEVICE_ID'))
+    context.set_context(device_id=devid,
+                        reserve_class_name_in_scope=True)
+    context.set_auto_parallel_context(device_num=8)
+    init()
+    opts.rank = get_rank()
+    opts.group_size = get_group_size()
+    print('Rank {}, group_size {}'.format(opts.rank, opts.group_size))
+
+    val_data_url = os.path.join(opts.data_path, 'val')
+    val_dataset = create_dataset_val(opts.batch_size,
+                                     val_data_url,
+                                     workers=opts.workers,
+                                     target='Ascend',
+                                     distributed=False,
+                                     input_size=opts.input_size)
+
+    # parse model argument
+    if opts.model == 'tinynet_c':
+        _, sub_name = opts.model.split("_")
+        net = tinynet(sub_model=sub_name,
+                      num_classes=opts.num_classes,
+                      drop_rate=0.0,
+                      drop_connect_rate=0.0,
+                      global_pool="avg",
+                      bn_tf=False,
+                      bn_momentum=None,
+                      bn_eps=None)
+    elif opts.model == 'ghostnet':
+        net = ghostnet_1x(num_classes=opts.num_classes)
+    else:
+        net = GhostNet(layers=layer_config,
+                       channels=channel_config,
+                       num_classes=opts.num_classes,
+                       final_drop=opts.drop,
+                       drop_path_rate=opts.drop_path,
+                       large=opts.large,
+                       zero_init_residual=False,
+                       sync_bn=opts.sync_bn)
+
+    print("Total number of parameters:", count_params(net))
+    if opts.model == 'tinynet_c':
+        opts.input_size = net.default_cfg['input_size'][1]
+
+    loss = LabelSmoothingCrossEntropy(smooth_factor=opts.smoothing,
+                                      num_classes=opts.num_classes)
+
+    loss.add_flags_recursive(fp32=True, fp16=False)
+    eval_metrics = {'Validation-Loss': Loss(),
+                    'Top1-Acc': Top1CategoricalAccuracy(),
+                    'Top5-Acc': Top5CategoricalAccuracy()}
+    for i in range(8):
+        if opts.test_mode == 'ema_best':
+            target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_best.ckpt')
+        elif opts.test_mode == 'ema_last':
+            target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_last.ckpt')
+        else:
+            target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'big_net-500_1251.ckpt')
+        if mox.file.exists(target_ckpt):
+            print('Loading checkpoint: ', target_ckpt)
+            ckpt = load_checkpoint(target_ckpt)
+            load_param_into_net(net, ckpt)
+            net.set_train(False)
+
+            model = Model(net, loss, metrics=eval_metrics)
+
+            metrics = model.eval(val_dataset, dataset_sink_mode=False)
+            print('ckpt {}, Rank {}, Accuracy {}'.format(i, opts.rank, metrics))
+
+
+if __name__ == '__main__':
+    args, unparsed = parser.parse_known_opts()
+    # copy data
+    sync_data(args)
+    main(args)
diff --git a/research/cv/S-GhostNet/eval_b4.py b/research/cv/S-GhostNet/eval_b4.py
new file mode 100644
index 0000000000000000000000000000000000000000..2db4b5743e3c61eef81bd9f57cea211bb9bb929b
--- /dev/null
+++ b/research/cv/S-GhostNet/eval_b4.py
@@ -0,0 +1,248 @@
+# Copyright 2022 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.
+# ============================================================================
+"""Inference Interface"""
+import sys
+import os
+import argparse
+import zipfile
+import time
+import moxing as mox
+from mindspore.communication.management import init, get_rank, get_group_size
+from mindspore.train.model import Model
+from mindspore.train.serialization import load_checkpoint, load_param_into_net
+from mindspore.nn import Loss, Top1CategoricalAccuracy, Top5CategoricalAccuracy
+from mindspore import context
+
+from src.dataset import create_dataset_val
+from src.utils import count_params
+from src.loss import LabelSmoothingCrossEntropy
+from src.tinynet import tinynet
+from src.ghostnet import ghostnet_1x
+from src.big_net import GhostNet
+
+os.environ["GLOG_v"] = '3'
+os.environ["ASCEND_SLOG_PRINT_TO_STDOUT"] = '0'
+os.environ["ASCEND_GLOBAL_LOG_LEVEL"] = '2'
+os.environ["ASCEND_GLOBAL_EVENT_ENABLE"] = '0'
+
+parser = argparse.ArgumentParser(description='Evaluation')
+parser.add_argument('--data_path', type=str, default='/autotest/liuchuanjian/data/imagenet/',
+                    metavar='DIR', help='path to dataset')
+parser.add_argument('--model', default='tinynet_c', type=str, metavar='MODEL',
+                    help='Name of model to train (default: "tinynet_c") ghostnet, big_net')
+parser.add_argument('--num-classes', type=int, default=1000, metavar='N',
+                    help='number of label classes (default: 1000)')
+parser.add_argument('--channels', type=str, default='36,60,108,168,232,336',
+                    help='channel config of model architecure')
+parser.add_argument('--layers', type=str, default='3,5,5,12,6,14',
+                    help='layer config of model architecure')
+parser.add_argument('--large', action='store_true', default=False,
+                    help='ghostnet1x or ghostnet larger')
+parser.add_argument('--input_size', type=int, default=384,
+                    help='input size of model.')
+parser.add_argument('--smoothing', type=float, default=0.1,
+                    help='label smoothing (default: 0.1)')
+parser.add_argument('-b', '--batch-size', type=int, default=25, metavar='N',
+                    help='input batch size for training (default: 32)')
+parser.add_argument('-j', '--workers', type=int, default=4, metavar='N',
+                    help='how many training processes to use (default: 1)')
+parser.add_argument('--GPU', action='store_true', default=False,
+                    help='Use GPU for training (default: False)')
+parser.add_argument('--dataset_sink', action='store_false', default=True)
+parser.add_argument('--drop', type=float, default=0.2, metavar='DROP',
+                    help='Dropout rate (default: 0.) for big_net, use "1-drop", for others, use "drop"')
+parser.add_argument('--drop-path', type=float, default=0.0, metavar='DROP',
+                    help='Drop connect rate (default: 0.)')
+parser.add_argument('--sync_bn', action='store_true', default=False,
+                    help='Use sync bn in distributed mode. (default: False)')
+parser.add_argument('--test_mode', default=None,
+                    help='Use ema saved model to test, "ema_best", "ema_last", ')
+
+# eval on cloud
+parser.add_argument('--cloud', action='store_true', default=False, help='Whether train on cloud.')
+parser.add_argument('--data_url', type=str, default="/home/ma-user/work/data/imagenet", help='path to dataset.')
+parser.add_argument('--zip_url', type=str, default="s3://bucket-800/liuchuanjian/data/imagenet_zip/imagenet.zip")
+parser.add_argument('--train_url', type=str, default=" ", help='train_dir.')
+parser.add_argument('--tmp_data_dir', default='/cache/data/', help='temp data dir')
+parser.add_argument('--trained_model_dir', default='s3://bucket-800/liuchuanjian/results/bignet/1311/',
+                    help='temp save dir')
+parser.add_argument('--tmp_save_dir', default='/cache/liuchuanjian/', help='temp save dir')
+
+_global_sync_count = 0
+
+def get_device_id():
+    device_id = os.getenv('DEVICE_ID', '0')
+    return int(device_id)
+
+def get_device_num():
+    device_num = os.getenv('RANK_SIZE', '1')
+    return int(device_num)
+
+def unzip_file(zip_src, dst_dir):
+    r = zipfile.is_zipfile(zip_src)
+    if r:
+        fz = zipfile.ZipFile(zip_src, 'r')
+        for file_item in fz.namelist():
+            fz.extract(file_item, dst_dir)
+    else:
+        raise Exception('This is not zip')
+
+def sync_data(opts):
+    """
+    Download data from remote obs to local directory if the first url is remote url and the second one is local path
+    Upload data from local directory to remote obs in contrast.
+    """
+
+    global _global_sync_count
+    sync_lock = "/tmp/copy_sync.lock" + str(_global_sync_count)
+    _global_sync_count += 1
+
+    if not mox.file.exists(opts.tmp_data_dir):
+        mox.file.make_dirs(opts.tmp_data_dir)
+    target_file = os.path.join(opts.tmp_data_dir, 'imagenet.zip')
+    # Each server contains 8 devices as most.
+    if get_device_id() % min(get_device_num(), 8) == 0 and not os.path.exists(sync_lock):
+        print("from path: ", opts.zip_url)
+        print("to path: ", target_file)
+        mox.file.copy_parallel(opts.zip_url, target_file)
+        print('Zip file copy success.')
+        print('Starting unzip file.')
+        unzip_file(target_file, opts.tmp_data_dir)
+        print('Unzip file success.')
+        print("===finish data synchronization===")
+        ## ckpt copy
+        print('Moving ckpt file')
+        if not mox.file.exists(opts.tmp_save_dir):
+            mox.file.make_dirs(opts.tmp_save_dir)
+        for i in range(32):
+            print('copying ckpt_ ', str(i))
+            if opts.test_mode == 'ema_best':
+                source_ckpt = os.path.join(opts.trained_model_dir, 'ckpt_'+str(i), 'ema_best.ckpt')
+                target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_best.ckpt')
+            elif opts.test_mode == 'ema_last':
+                source_ckpt = os.path.join(opts.trained_model_dir, 'ckpt_'+str(i), 'ema_last.ckpt')
+                target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_last.ckpt')
+            else:
+                source_ckpt = os.path.join(opts.trained_model_dir, 'ckpt_'+str(i), 'big_net-450_1251.ckpt')
+                target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'big_net-450_1251.ckpt')
+            if mox.file.exists(source_ckpt):
+                mox.file.copy(source_ckpt, target_ckpt)
+            else:
+                print(source_ckpt, 'does not exist.')
+
+        try:
+            os.mknod(sync_lock)
+        except IOError:
+            pass
+        print("===save flag===")
+
+    while True:
+        if os.path.exists(sync_lock):
+            break
+        time.sleep(1)
+
+    opts.data_url = os.path.join(opts.tmp_data_dir, 'imagenet')
+    opts.data_path = opts.data_url
+    print("Finish sync data from {} to {}.".format(opts.zip_url, target_file))
+
+def main(opts):
+    """Main entrance for training"""
+    print(sys.argv)
+    if opts.channels:
+        channel_config = []
+        for item in opts.channels.split(','):
+            channel_config.append(int(item.strip()))
+    if opts.layers:
+        layer_config = []
+        for item in opts.layers.split(','):
+            layer_config.append(int(item.strip()))
+    print(opts)
+
+    context.set_context(mode=context.GRAPH_MODE, device_target='Ascend')
+    devid = int(os.getenv('DEVICE_ID'))
+    context.set_context(device_id=devid,
+                        reserve_class_name_in_scope=True)
+    context.set_auto_parallel_context(device_num=8)
+    init()
+    opts.rank = get_rank()
+    opts.group_size = get_group_size()
+    print('Rank {}, group_size {}'.format(opts.rank, opts.group_size))
+
+    val_data_url = os.path.join(opts.data_path, 'val')
+    val_dataset = create_dataset_val(opts.batch_size,
+                                     val_data_url,
+                                     workers=opts.workers,
+                                     target='Ascend',
+                                     distributed=False,
+                                     input_size=opts.input_size)
+
+    # parse model argument
+    if opts.model == 'tinynet_c':
+        _, sub_name = opts.model.split("_")
+        net = tinynet(sub_model=sub_name,
+                      num_classes=opts.num_classes,
+                      drop_rate=0.0,
+                      drop_connect_rate=0.0,
+                      global_pool="avg",
+                      bn_tf=False,
+                      bn_momentum=None,
+                      bn_eps=None)
+    elif opts.model == 'ghostnet':
+        net = ghostnet_1x(num_classes=opts.num_classes)
+    else:
+        net = GhostNet(layers=layer_config,
+                       channels=channel_config,
+                       num_classes=opts.num_classes,
+                       final_drop=opts.drop,
+                       drop_path_rate=opts.drop_path,
+                       large=opts.large,
+                       zero_init_residual=False,
+                       sync_bn=opts.sync_bn)
+
+    print("Total number of parameters:", count_params(net))
+    if opts.model == 'tinynet_c':
+        opts.input_size = net.default_cfg['input_size'][1]
+
+    loss = LabelSmoothingCrossEntropy(smooth_factor=opts.smoothing,
+                                      num_classes=opts.num_classes)
+
+    loss.add_flags_recursive(fp32=True, fp16=False)
+    eval_metrics = {'Validation-Loss': Loss(),
+                    'Top1-Acc': Top1CategoricalAccuracy(),
+                    'Top5-Acc': Top5CategoricalAccuracy()}
+    for i in range(32):
+        if opts.test_mode == 'ema_best':
+            target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_best.ckpt')
+        elif opts.test_mode == 'ema_last':
+            target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'ema_last.ckpt')
+        else:
+            target_ckpt = os.path.join(opts.tmp_save_dir, 'ckpt_'+str(i), 'big_net-450_1251.ckpt')
+        if mox.file.exists(target_ckpt):
+            print('Loading checkpoint: ', target_ckpt)
+            ckpt = load_checkpoint(target_ckpt)
+            load_param_into_net(net, ckpt)
+            net.set_train(False)
+
+            model = Model(net, loss, metrics=eval_metrics)
+
+            metrics = model.eval(val_dataset, dataset_sink_mode=False)
+            print('ckpt {}, Rank {}, Accuracy {}'.format(i, opts.rank, metrics))
+
+
+if __name__ == '__main__':
+    args, unparsed = parser.parse_known_opts()
+    # copy data
+    sync_data(args)
+    main(args)
diff --git a/research/cv/S-GhostNet/script/train_distributed_ascend.sh b/research/cv/S-GhostNet/script/train_distributed_ascend.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9f35108ea8aec1f12092c8a644996255aad7b982
--- /dev/null
+++ b/research/cv/S-GhostNet/script/train_distributed_ascend.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+# Copyright 2022 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 ] && [ $# != 4 ]
+then
+  echo "Usage: bash train_distribute_ascend.sh [bignet] [RANK_TABLE_FILE] [DATASET_PATH] [PRETRAINED_CKPT_PATH](optional)"
+  exit 1
+fi
+
+get_real_path(){
+  if [ "${1:0:1}" == "/" ]; then
+    echo "$1"
+  else
+    echo "$(realpath -m $PWD/$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
+
+ulimit -u unlimited
+export DEVICE_NUM=8
+export RANK_SIZE=8
+export RANK_TABLE_FILE=$PATH1
+
+export SERVER_ID=0
+rank_start=$((DEVICE_NUM * SERVER_ID))
+
+for((i=0; i<${DEVICE_NUM}; i++))
+do
+    export DEVICE_ID=${i}
+    export RANK_ID=$((rank_start + i))
+    rm -rf ./train_parallel$i
+    mkdir ./train_parallel$i
+    cp ../*.py ./train_parallel$i
+    cp *.sh ./train_parallel$i
+    cp -r ../src ./train_parallel$i
+    cd ./train_parallel$i || exit
+    echo "start training for rank $RANK_ID, device $DEVICE_ID, device_num $DEVICE_NUM"
+    env > env.log
+    if [ $# == 3 ]
+    then    
+        python train.py \
+            --distributed \
+            --device_num=$DEVICE_NUM \
+            --model $1 \
+            --data_path $PATH2  \
+            --num-classes 1000 \
+            --channels 16,24,40,80,112,160 \
+            --layers 1,2,2,4,2,5 \
+            --batch-size 256 \
+            --drop 0.2 \
+            --drop-path 0 \
+            --opt rmsprop \
+            --opt-eps 0.001 \
+            --lr 0.048 \
+            --decay-epochs 2.4 \
+            --warmup-lr 1e-6 \
+            --warmup-epochs 3 \
+            --decay-rate 0.97 \
+            --ema-decay 0.9999 \
+            --weight-decay 1e-5 \
+            --per_print_times 100 \
+            --epochs 300 \
+            --ckpt_save_epoch 5 \
+            --workers 8 \
+            --amp_level O2 > $1.log 2>&1 &
+    fi
+    
+    if [ $# == 4 ]
+    then
+        python train.py --model=$1 --distributed --device_num=$DEVICE_NUM --data_path=$PATH2 --pre_trained=$PATH3 &> log &
+    fi
+
+    cd ..
+done
diff --git a/research/cv/S-GhostNet/src/autoaug.py b/research/cv/S-GhostNet/src/autoaug.py
new file mode 100644
index 0000000000000000000000000000000000000000..414d625318f2127cbb309735a9130e02abafa289
--- /dev/null
+++ b/research/cv/S-GhostNet/src/autoaug.py
@@ -0,0 +1,156 @@
+# Copyright 2022 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 mindspore.dataset as ds
+import mindspore.dataset.transforms.c_transforms as c_transforms
+import mindspore.dataset.vision.c_transforms as c_vision
+from mindspore import dtype as mstype
+
+# define Auto Augmentation operators
+PARAMETER_MAX = 10
+
+def float_parameter(level, maxval):
+    return float(level) * maxval /  PARAMETER_MAX
+
+def int_parameter(level, maxval):
+    return int(level * maxval / PARAMETER_MAX)
+
+def shear_x(level):
+    v = float_parameter(level, 0.3)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(-v, -v)),
+                                      c_vision.RandomAffine(degrees=0, shear=(v, v))])
+
+def shear_y(level):
+    v = float_parameter(level, 0.3)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(0, 0, -v, -v)),
+                                      c_vision.RandomAffine(degrees=0, shear=(0, 0, v, v))])
+
+def translate_x(level):
+    v = float_parameter(level, 150 / 331)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(-v, -v)),
+                                      c_vision.RandomAffine(degrees=0, translate=(v, v))])
+
+def translate_y(level):
+    v = float_parameter(level, 150 / 331)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(0, 0, -v, -v)),
+                                      c_vision.RandomAffine(degrees=0, translate=(0, 0, v, v))])
+
+def color_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomColor(degrees=(v, v))
+
+def rotate_impl(level):
+    v = int_parameter(level, 30)
+    return c_transforms.RandomChoice([c_vision.RandomRotation(degrees=(-v, -v)),
+                                      c_vision.RandomRotation(degrees=(v, v))])
+
+def solarize_impl(level):
+    level = int_parameter(level, 256)
+    v = 256 - level
+    return c_vision.RandomSolarize(threshold=(0, v))
+
+def posterize_impl(level):
+    level = int_parameter(level, 4)
+    v = 4 - level
+    return c_vision.RandomPosterize(bits=(v, v))
+
+def contrast_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomColorAdjust(contrast=(v, v))
+
+def autocontrast_impl(level):
+    v = level
+    assert v == level
+    return c_vision.AutoContrast()
+
+def sharpness_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomSharpness(degrees=(v, v))
+
+def brightness_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomColorAdjust(brightness=(v, v))
+
+# define the Auto Augmentation policy
+imagenet_policy = [
+    [(posterize_impl(8), 0.4), (rotate_impl(9), 0.6)],
+    [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)],
+    [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)],
+    [(posterize_impl(7), 0.6), (posterize_impl(6), 0.6)],
+    [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)],
+
+    [(c_vision.Equalize(), 0.4), (rotate_impl(8), 0.8)],
+    [(solarize_impl(3), 0.6), (c_vision.Equalize(), 0.6)],
+    [(posterize_impl(5), 0.8), (c_vision.Equalize(), 1.0)],
+    [(rotate_impl(3), 0.2), (solarize_impl(8), 0.6)],
+    [(c_vision.Equalize(), 0.6), (posterize_impl(6), 0.4)],
+
+    [(rotate_impl(8), 0.8), (color_impl(0), 0.4)],
+    [(rotate_impl(9), 0.4), (c_vision.Equalize(), 0.6)],
+    [(c_vision.Equalize(), 0.0), (c_vision.Equalize(), 0.8)],
+    [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)],
+    [(color_impl(4), 0.6), (contrast_impl(8), 1.0)],
+
+    [(rotate_impl(8), 0.8), (color_impl(2), 1.0)],
+    [(color_impl(8), 0.8), (solarize_impl(7), 0.8)],
+    [(sharpness_impl(7), 0.4), (c_vision.Invert(), 0.6)],
+    [(shear_x(5), 0.6), (c_vision.Equalize(), 1.0)],
+    [(color_impl(0), 0.4), (c_vision.Equalize(), 0.6)],
+
+    [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)],
+    [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)],
+    [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)],
+    [(color_impl(4), 0.6), (contrast_impl(8), 1.0)],
+    [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)],
+]
+
+def create_dataset(dataset_path, do_train, repeat_num=1, batch_size=32, shuffle=True, num_samples=5):
+    # create a train or eval imagenet2012 dataset for ResNet-50
+    dataset = ds.ImageFolderDataset(dataset_path, num_parallel_workers=8,
+                                    shuffle=shuffle, num_samples=num_samples)
+
+    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_vision.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
+        ]
+
+        post_trans = [
+            c_vision.RandomHorizontalFlip(prob=0.5),
+        ]
+    else:
+        trans = [
+            c_vision.Decode(),
+            c_vision.Resize(256),
+            c_vision.CenterCrop(image_size),
+            c_vision.Normalize(mean=mean, std=std),
+            c_vision.HWC2CHW()
+        ]
+    dataset = dataset.map(operations=trans, input_columns="image")
+    if do_train:
+        dataset = dataset.map(operations=c_vision.RandomSelectSubpolicy(imagenet_policy), input_columns=["image"])
+        dataset = dataset.map(operations=post_trans, input_columns="image")
+    type_cast_op = c_transforms.TypeCast(mstype.int32)
+    dataset = dataset.map(operations=type_cast_op, input_columns="label")
+    # apply the batch operation
+    dataset = dataset.batch(batch_size, drop_remainder=True)
+    # apply the repeat operation
+    dataset = dataset.repeat(repeat_num)
+
+    return dataset
diff --git a/research/cv/S-GhostNet/src/big_net.py b/research/cv/S-GhostNet/src/big_net.py
new file mode 100644
index 0000000000000000000000000000000000000000..81d03a607e98292a6079a2c03af4bb779c97c1cc
--- /dev/null
+++ b/research/cv/S-GhostNet/src/big_net.py
@@ -0,0 +1,441 @@
+# Copyright 2022 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 math
+import numpy as np
+import mindspore.nn as nn
+from mindspore.ops import operations as P
+from mindspore import Tensor
+import mindspore.common.initializer as weight_init
+
+groups_npu_1 = [[0, 1, 2, 3, 4, 5, 6, 7]]
+groups_npu_4 = [[0, 1, 2, 3, 4, 5, 6, 7],
+                [8, 9, 10, 11, 12, 13, 14, 15],
+                [16, 17, 18, 19, 20, 21, 22, 23],
+                [24, 25, 26, 27, 28, 29, 30, 31]]
+groups_npu_16 = [[0, 1, 2, 3, 4, 5, 6, 7],
+                 [8, 9, 10, 11, 12, 13, 14, 15],
+                 [16, 17, 18, 19, 20, 21, 22, 23],
+                 [24, 25, 26, 27, 28, 29, 30, 31],
+                 [32, 33, 34, 35, 36, 37, 38, 39],
+                 [40, 41, 42, 43, 44, 45, 46, 47],
+                 [48, 49, 50, 51, 52, 53, 54, 55],
+                 [56, 57, 58, 59, 60, 61, 62, 63],
+                 [64, 65, 66, 67, 68, 69, 70, 71],
+                 [72, 73, 74, 75, 76, 77, 78, 79],
+                 [80, 81, 82, 83, 84, 85, 86, 87],
+                 [88, 89, 90, 91, 92, 93, 94, 95],
+                 [96, 97, 98, 99, 100, 101, 102, 103],
+                 [104, 105, 106, 107, 108, 109, 110, 111],
+                 [112, 113, 114, 115, 116, 117, 118, 119],
+                 [120, 121, 122, 123, 124, 125, 126, 127]]
+
+def _make_divisible(x, divisor=4, min_value=None):
+    if min_value is None:
+        min_value = divisor
+    new_v = max(min_value, int(x + divisor / 2) // divisor * divisor)
+    # Make sure that round down does not go down by more than 10%.
+    if new_v < 0.9 * x:
+        new_v += divisor
+    return new_v
+
+class HardSwish(nn.Cell):
+    def __init__(self):
+        super(HardSwish, self).__init__()
+        self.relu6 = nn.ReLU6()
+        self.mul = P.Mul()
+
+    def construct(self, x):
+        return self.mul(x, self.relu6(x + 3.)/6)
+
+class MyHSigmoid(nn.Cell):
+    def __init__(self):
+        super(MyHSigmoid, self).__init__()
+        self.relu6 = nn.ReLU6()
+
+    def construct(self, x):
+        return self.relu6(x + 3.) * 0.16666667
+
+
+class Activation(nn.Cell):
+    def __init__(self, act_func):
+        super(Activation, self).__init__()
+        if act_func == 'relu':
+            self.act = nn.ReLU()
+        elif act_func == 'relu6':
+            self.act = nn.ReLU6()
+        elif act_func in ('hsigmoid', 'hard_sigmoid'):
+            self.act = MyHSigmoid()
+        elif act_func in ('hswish', 'hard_swish'):
+            self.act = nn.HSwish()
+        else:
+            raise NotImplementedError
+
+    def construct(self, x):
+        return self.act(x)
+
+class DropConnect(nn.Cell):
+    def __init__(self, drop_connect_rate=0.):
+        super(DropConnect, self).__init__()
+        self.shape = P.Shape()
+        self.dtype = P.DType()
+        self.keep_prob = 1 - drop_connect_rate
+        self.dropout = P.Dropout(keep_prob=self.keep_prob)
+
+    def construct(self, x):
+        shape = self.shape(x)
+        dtype = self.dtype(x)
+        ones_tensor = P.Fill()(dtype, (shape[0], 1, 1, 1), 1)
+        mask, _ = self.dropout(ones_tensor)
+        x = x * mask
+        return x
+
+def drop_connect(inputs, training=False, drop_connect_rate=0.):
+    if not training or drop_connect_rate == 0:
+        return inputs
+    return DropConnect(drop_connect_rate)(inputs)
+
+class GlobalAvgPooling(nn.Cell):
+    def __init__(self, keep_dims=False):
+        super(GlobalAvgPooling, self).__init__()
+        self.mean = P.ReduceMean(keep_dims=keep_dims)
+
+    def construct(self, x):
+        x = self.mean(x, (2, 3))
+        return x
+
+class SeModule(nn.Cell):
+    def __init__(self, num_out, se_ratio=0.25, divisor=8):
+        super(SeModule, self).__init__()
+        num_mid = _make_divisible(num_out*se_ratio, divisor)
+        self.pool = GlobalAvgPooling(keep_dims=True)
+        self.conv_reduce = nn.Conv2d(in_channels=num_out, out_channels=num_mid,
+                                     kernel_size=1, has_bias=True, pad_mode='pad')
+        self.act1 = Activation('relu')
+        self.conv_expand = nn.Conv2d(in_channels=num_mid, out_channels=num_out,
+                                     kernel_size=1, has_bias=True, pad_mode='pad')
+        self.act2 = Activation('hsigmoid')
+        self.mul = P.Mul()
+
+    def construct(self, x):
+        out = self.pool(x)
+        out = self.conv_reduce(out)
+        out = self.act1(out)
+        out = self.conv_expand(out)
+        out = self.act2(out)
+        out = self.mul(x, out)
+        return out
+
+class ConvBnAct(nn.Cell):
+    def __init__(self, num_in, num_out, kernel_size, stride=1, padding=0, num_groups=1,
+                 use_act=True, act_type='relu', sync_bn=False):
+        super(ConvBnAct, self).__init__()
+        self.conv = nn.Conv2d(in_channels=num_in,
+                              out_channels=num_out,
+                              kernel_size=kernel_size,
+                              stride=stride,
+                              padding=padding,
+                              group=num_groups,
+                              has_bias=False,
+                              pad_mode='pad')
+        if sync_bn:
+            self.bn = nn.SyncBatchNorm(num_out)
+        else:
+            self.bn = nn.BatchNorm2d(num_out)
+        self.use_act = use_act
+        self.act = Activation(act_type) if use_act else None
+
+    def construct(self, x):
+        out = self.conv(x)
+        out = self.bn(out)
+        if self.use_act:
+            out = self.act(out)
+        return out
+
+class GhostModule(nn.Cell):
+    def __init__(self, num_in, num_out, kernel_size=1, stride=1, padding=0, ratio=2, dw_size=3,
+                 use_act=True, act_type='relu', sync_bn=False):
+        super(GhostModule, self).__init__()
+        init_channels = math.ceil(num_out / ratio)
+        new_channels = init_channels * (ratio - 1)
+
+        self.primary_conv = ConvBnAct(num_in, init_channels, kernel_size=kernel_size, stride=stride, padding=padding,
+                                      num_groups=1, use_act=use_act, act_type=act_type, sync_bn=sync_bn)
+        self.cheap_operation = ConvBnAct(init_channels, new_channels, kernel_size=dw_size, stride=1, padding=dw_size//2,
+                                         num_groups=init_channels, use_act=use_act, act_type=act_type, sync_bn=sync_bn)
+        self.concat = P.Concat(axis=1)
+
+    def construct(self, x):
+        x1 = self.primary_conv(x)
+        x2 = self.cheap_operation(x1)
+        return self.concat((x1, x2))
+
+class GhostBottleneck(nn.Cell):
+    def __init__(self, num_in, num_mid, num_out, dw_kernel_size, stride=1,
+                 act_type='relu', se_ratio=0., divisor=8, drop_path_rate=0., sync_bn=False):
+        super(GhostBottleneck, self).__init__()
+
+        use_se = se_ratio is not None and se_ratio > 0.
+        self.drop_path_rate = drop_path_rate
+        self.ghost1 = GhostModule(num_in, num_mid, kernel_size=1,
+                                  stride=1, padding=0, act_type=act_type, sync_bn=sync_bn)
+
+        self.use_dw = stride > 1
+        if self.use_dw:
+            self.dw = ConvBnAct(num_mid, num_mid, kernel_size=dw_kernel_size, stride=stride,
+                                padding=(dw_kernel_size-1)//2, act_type=act_type,
+                                num_groups=num_mid, use_act=False, sync_bn=sync_bn)
+
+        self.use_se = use_se
+        if use_se:
+            self.se = SeModule(num_mid, se_ratio=se_ratio, divisor=divisor)
+
+        self.ghost2 = GhostModule(num_mid, num_out, kernel_size=1, stride=1,
+                                  padding=0, act_type=act_type, use_act=False, sync_bn=sync_bn)
+
+        self.down_sample = False
+        if num_in != num_out or stride != 1:
+            self.down_sample = True
+
+        if self.down_sample:
+            self.shortcut = nn.SequentialCell([
+                ConvBnAct(num_in, num_in, kernel_size=dw_kernel_size, stride=stride,
+                          padding=(dw_kernel_size-1)//2, num_groups=num_in, use_act=False, sync_bn=sync_bn),
+                ConvBnAct(num_in, num_out, kernel_size=1, stride=1,
+                          padding=0, num_groups=1, use_act=False, sync_bn=sync_bn),
+            ])
+
+        self.add = P.Add()
+
+    def construct(self, x):
+        shortcut = x
+        out = self.ghost1(x)
+        if self.use_dw:
+            out = self.dw(out)
+        if self.use_se:
+            out = self.se(out)
+        out = self.ghost2(out)
+        if self.down_sample:
+            shortcut = self.shortcut(shortcut)
+        ## drop path
+        if self.drop_path_rate > 0.:
+            out = drop_connect(out, self.training, self.drop_path_rate)
+        out = self.add(shortcut, out)
+        return out
+
+def gen_cfgs_1x(layers, channels):
+    # generate configs of ghostnet
+    cfgs = []
+    for i in range(len(layers)):
+        cfgs.append([])
+        for j in range(layers[i]):
+            if i == 0:
+                cfgs[i].append([3, channels[i], channels[i], 0, 1])
+            elif i == 1:
+                if j == 0:
+                    cfgs[i].append([3, channels[i-1]*3, channels[i], 0, 2])
+                else:
+                    cfgs[i].append([3, channels[i]*3, channels[i], 0, 1])
+            elif i == 2:
+                if j == 0:
+                    cfgs[i].append([5, channels[i-1]*3, channels[i], 0.25, 2])
+                else:
+                    cfgs[i].append([5, channels[i]*3, channels[i], 0.25, 1])
+            elif i == 3:
+                if j == 0:
+                    cfgs[i].append([3, channels[i-1]*6, channels[i], 0, 2])
+                elif j == 1:
+                    cfgs[i].append([3, 200, channels[i], 0, 1])
+                else:
+                    cfgs[i].append([3, 184, channels[i], 0, 1])
+            elif i == 4:
+                if j == 0:
+                    cfgs[i].append([3, channels[i-1]*6, channels[i], 0.25, 1])
+                else:
+                    cfgs[i].append([3, channels[i]*6, channels[i], 0.25, 1])
+            elif i == 5:
+                if j == 0:
+                    cfgs[i].append([5, channels[i-1]*6, channels[i], 0.25, 2])
+                elif j%2 == 0:
+                    cfgs[i].append([5, channels[i]*6, channels[i], 0.25, 1])
+                else:
+                    cfgs[i].append([5, channels[i]*6, channels[i], 0, 1])
+
+    return cfgs
+
+
+def gen_cfgs_large(layers, channels):
+    # generate configs of ghostnet
+    cfgs = []
+    for i in range(len(layers)):
+        cfgs.append([])
+        if i == 0:
+            for j in range(layers[i]):
+                cfgs[i].append([3, channels[i], channels[i], 0.1, 1])
+        elif i == 1:
+            for j in range(layers[i]):
+                if j == 0:
+                    cfgs[i].append([3, channels[i-1]*3, channels[i], 0.1, 2])
+                else:
+                    cfgs[i].append([3, channels[i]*3, channels[i], 0.1, 1])
+        elif i == 2:
+            for j in range(layers[i]):
+                if j == 0:
+                    cfgs[i].append([5, channels[i-1]*3, channels[i], 0.1, 2])
+                else:
+                    cfgs[i].append([5, channels[i]*3, channels[i], 0.1, 1])
+        elif i == 3:
+            for j in range(layers[i]):
+                if j == 0:
+                    cfgs[i].append([3, channels[i-1]*6, channels[i], 0.1, 2])
+                else:
+                    cfgs[i].append([3, channels[i]*2.5, channels[i], 0.1, 1])
+        elif i == 4:
+            for j in range(layers[i]):
+                if j == 0:
+                    cfgs[i].append([3, channels[i-1]*6, channels[i], 0.1, 1])
+                else:
+                    cfgs[i].append([3, channels[i]*6, channels[i], 0.1, 1])
+        elif i == 5:
+            for j in range(layers[i]):
+                if j == 0:
+                    cfgs[i].append([5, channels[i-1]*6, channels[i], 0.1, 2])
+                else:
+                    cfgs[i].append([5, channels[i]*6, channels[i], 0.1, 1])
+    return cfgs
+
+class GhostNet(nn.Cell):
+    def __init__(self, layers, channels, num_classes=1000, multiplier=1.,
+                 final_drop=0., drop_path_rate=0., large=False, zero_init_residual=False, sync_bn=False):
+        super(GhostNet, self).__init__()
+        if layers is None:
+            layers = [1, 2, 2, 4, 2, 5]
+        if channels is None:
+            channels = [16, 24, 40, 80, 112, 160]
+        self.large = large
+        if self.large:
+            self.cfgs = gen_cfgs_large(layers, channels)
+        else:
+            self.cfgs = gen_cfgs_1x(layers, channels)
+
+        self.drop_path_rate = drop_path_rate
+        self.inplanes = 16
+        first_conv_in_channel = 3
+        first_conv_out_channel = _make_divisible(multiplier * channels[0], 4)
+
+        self.conv_stem = nn.Conv2d(in_channels=first_conv_in_channel,
+                                   out_channels=first_conv_out_channel,
+                                   kernel_size=3, padding=1, stride=2,
+                                   has_bias=False, pad_mode='pad')
+        if sync_bn:
+            self.bn1 = nn.SyncBatchNorm(first_conv_out_channel)
+        else:
+            self.bn1 = nn.BatchNorm2d(first_conv_out_channel)
+        if self.large:
+            self.act1 = HardSwish()
+        else:
+            self.act1 = Activation('relu')
+        input_channel = first_conv_out_channel
+        stages = []
+        block = GhostBottleneck
+        block_idx = 0
+        block_count = sum(layers)
+        for cfg in self.cfgs:
+            layers = []
+            for k, exp_size, c, se_ratio, s in cfg:
+                output_channel = _make_divisible(c * multiplier, 4)
+                hidden_channel = _make_divisible(exp_size * multiplier, 4)
+                drop_path_rate = self.drop_path_rate * block_idx / block_count
+                if self.large:
+                    layers.append(block(input_channel, hidden_channel, output_channel, k, s, act_type='relu',
+                                        se_ratio=se_ratio, divisor=8, drop_path_rate=drop_path_rate, sync_bn=sync_bn))
+                else:
+                    layers.append(block(input_channel, hidden_channel, output_channel, k, s, act_type='relu',
+                                        se_ratio=se_ratio, divisor=4, drop_path_rate=drop_path_rate, sync_bn=sync_bn))
+                input_channel = output_channel
+                block_idx += 1
+                output_channel = _make_divisible(multiplier * exp_size, 4)
+            stages.append(nn.SequentialCell(layers))
+
+        if self.large:
+            stages.append(ConvBnAct(input_channel, output_channel, 1, act_type='relu', sync_bn=sync_bn))  ###HardSuishMe
+        else:
+            stages.append(ConvBnAct(input_channel, output_channel, 1, act_type='relu', sync_bn=sync_bn))
+
+        head_output_channel = max(1280, int(input_channel*5))
+        input_channel = output_channel
+        self.blocks = nn.SequentialCell(stages)
+
+        self.global_pool = GlobalAvgPooling(keep_dims=True)
+        self.conv_head = nn.Conv2d(input_channel,
+                                   head_output_channel,
+                                   kernel_size=1, padding=0, stride=1,
+                                   has_bias=True, pad_mode='pad')
+        if self.large:
+            self.act2 = HardSwish()
+        else:
+            self.act2 = Activation('relu')
+        self.squeeze = P.Flatten()
+        self.final_drop = 1-final_drop
+        if self.final_drop > 0:
+            self.dropout = nn.Dropout(self.final_drop)
+
+        self.classifier = nn.Dense(head_output_channel, num_classes, has_bias=True)
+
+        self._initialize_weights()
+        if zero_init_residual:
+            for _, m in self.cellsand_names():
+                if isinstance(m, GhostBottleneck):
+                    tmp_x = Tensor(np.zeros(m.ghost2.primary_conv[1].weight.data.shape, dtype="float32"))
+                    m.ghost2.primary_conv[1].weight.set_data(tmp_x)
+                    tmp_y = Tensor(np.zeros(m.ghost2.cheap_operation[1].weight.data.shape, dtype="float32"))
+                    m.ghost2.cheap_operation[1].weight.set_data(tmp_y)
+
+    def construct(self, x):
+        r"""construct of GhostNet"""
+        x = self.conv_stem(x)
+        x = self.bn1(x)
+        x = self.act1(x)
+        x = self.blocks(x)
+        x = self.global_pool(x)
+        x = self.conv_head(x)
+        x = self.act2(x)
+        x = self.squeeze(x)
+        if self.final_drop > 0:
+            x = self.dropout(x)
+        x = self.classifier(x)
+        return x
+
+    def _initialize_weights(self):
+        self.init_parameters_data()
+        for _, m in self.cells_and_names():
+            if isinstance(m, (nn.Conv2d)):
+                m.weight.set_data(weight_init.initializer(weight_init.HeUniform(),
+                                                          m.weight.shape,
+                                                          m.weight.dtype))
+                if m.bias is not None:
+                    m.bias.set_data(
+                        Tensor(np.zeros(m.bias.data.shape, dtype="float32")))
+            elif isinstance(m, (nn.BatchNorm2d, nn.SyncBatchNorm)):
+                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(weight_init.initializer(weight_init.HeNormal(),
+                                                          m.weight.shape,
+                                                          m.weight.dtype))
+                if m.bias is not None:
+                    m.bias.set_data(Tensor(np.zeros(m.bias.data.shape, dtype="float32")))
diff --git a/research/cv/S-GhostNet/src/callback.py b/research/cv/S-GhostNet/src/callback.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa77026c4647115dee33e9576828f3d4e503c2f8
--- /dev/null
+++ b/research/cv/S-GhostNet/src/callback.py
@@ -0,0 +1,74 @@
+# Copyright 2022 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 callbacks for ema and loss"""
+import numpy as np
+from mindspore.train.callback import Callback
+from mindspore import Tensor
+
+
+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:
+        lr_array (numpy.array): scheduled learning rate.
+        total_epochs (int): Total number of epochs for training.
+        per_print_times (int): Print the loss every time. Default: 1.
+        start_epoch (int): which epoch to start, used when resume from a
+        certain epoch.
+
+    Raises:
+        ValueError: If print_step is not an integer or less than zero.
+    """
+
+    def __init__(self, lr_array, total_epochs, per_print_times=1, start_epoch=0):
+        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_array = lr_array
+        self._total_epochs = total_epochs
+        self._start_epoch = start_epoch
+
+    def step_end(self, run_context):
+        """log epoch, step, loss and learning rate"""
+        cb_params = run_context.original_args()
+        loss = cb_params.net_outputs
+        cur_epoch_num = cb_params.cur_epoch_num + self._start_epoch - 1
+        if isinstance(loss, (tuple, list)):
+            if isinstance(loss[0], Tensor) and isinstance(loss[0].asnumpy(), np.ndarray):
+                loss = loss[0]
+
+        if isinstance(loss, Tensor) and isinstance(loss.asnumpy(), np.ndarray):
+            loss = np.mean(loss.asnumpy())
+        global_step = cb_params.cur_step_num - 1
+        cur_step_in_epoch = global_step % cb_params.batch_num + 1
+
+        if isinstance(loss, float) and (np.isnan(loss) or np.isinf(loss)):
+            raise ValueError("epoch: {} step: {}. Invalid loss, terminating training.".format(
+                cur_epoch_num, cur_step_in_epoch))
+
+        if self._per_print_times != 0 and cur_step_in_epoch % self._per_print_times == 0:
+            print("epoch: {}/{}, step: {}/{}, loss is {}, learning rate: {}".format(cur_epoch_num,
+                                                                                    self._total_epochs,
+                                                                                    cur_step_in_epoch,
+                                                                                    cb_params.batch_num,
+                                                                                    loss,
+                                                                                    self._lr_array[global_step]))
diff --git a/research/cv/S-GhostNet/src/dataset.py b/research/cv/S-GhostNet/src/dataset.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba239e0a92b4b1e1947c090ff6b4dbf50ef5c2f1
--- /dev/null
+++ b/research/cv/S-GhostNet/src/dataset.py
@@ -0,0 +1,279 @@
+# Copyright 2022 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.
+# ============================================================================
+"""Data operations, will be used in train.py and eval.py"""
+import math
+import os
+
+import numpy as np
+import mindspore.dataset.vision.c_transforms as c_vision
+import mindspore.dataset.transforms.c_transforms as c_transforms
+import mindspore.common.dtype as mstype
+import mindspore.dataset as ds
+from mindspore.communication.management import init, get_rank, get_group_size
+from mindspore.dataset.vision import Inter
+
+# values that should remain constant
+DEFAULT_CROP_PCT = 0.875
+IMAGENET_DEFAULT_MEAN = (0.485*255, 0.456*255, 0.406*255)
+IMAGENET_DEFAULT_STD = (0.229*255, 0.224*255, 0.225*255)
+
+# data preprocess configs
+SCALE = (0.08, 1.0)
+RATIO = (3./4., 4./3.)
+
+ds.config.set_seed(1)
+
+# define Auto Augmentation operators
+PARAMETER_MAX = 10
+
+def float_parameter(level, maxval):
+    return float(level) * maxval /  PARAMETER_MAX
+
+def int_parameter(level, maxval):
+    return int(level * maxval / PARAMETER_MAX)
+
+def shear_x(level):
+    v = float_parameter(level, 0.3)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(-v, -v)),
+                                      c_vision.RandomAffine(degrees=0, shear=(v, v))])
+
+def shear_y(level):
+    v = float_parameter(level, 0.3)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, shear=(0, 0, -v, -v)),
+                                      c_vision.RandomAffine(degrees=0, shear=(0, 0, v, v))])
+
+def translate_x(level):
+    v = float_parameter(level, 150 / 331)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(-v, -v)),
+                                      c_vision.RandomAffine(degrees=0, translate=(v, v))])
+
+def translate_y(level):
+    v = float_parameter(level, 150 / 331)
+    return c_transforms.RandomChoice([c_vision.RandomAffine(degrees=0, translate=(0, 0, -v, -v)),
+                                      c_vision.RandomAffine(degrees=0, translate=(0, 0, v, v))])
+
+def color_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomColor(degrees=(v, v))
+
+def rotate_impl(level):
+    v = int_parameter(level, 30)
+    return c_transforms.RandomChoice([c_vision.RandomRotation(degrees=(-v, -v)),
+                                      c_vision.RandomRotation(degrees=(v, v))])
+
+def solarize_impl(level):
+    level = int_parameter(level, 256)
+    v = 256 - level
+    return c_vision.RandomSolarize(threshold=(0, v))
+
+def posterize_impl(level):
+    level = int_parameter(level, 4)
+    v = 4 - level
+    return c_vision.RandomPosterize(bits=(v, v))
+
+def contrast_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomColorAdjust(contrast=(v, v))
+
+def autocontrast_impl(level):
+    v = level
+    assert v == level
+    return c_vision.AutoContrast()
+
+def sharpness_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomSharpness(degrees=(v, v))
+
+def brightness_impl(level):
+    v = float_parameter(level, 1.8) + 0.1
+    return c_vision.RandomColorAdjust(brightness=(v, v))
+
+# define the Auto Augmentation policy
+imagenet_policy = [
+    [(posterize_impl(8), 0.4), (rotate_impl(9), 0.6)],
+    [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)],
+    [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)],
+    [(posterize_impl(7), 0.6), (posterize_impl(6), 0.6)],
+    [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)],
+
+    [(c_vision.Equalize(), 0.4), (rotate_impl(8), 0.8)],
+    [(solarize_impl(3), 0.6), (c_vision.Equalize(), 0.6)],
+    [(posterize_impl(5), 0.8), (c_vision.Equalize(), 1.0)],
+    [(rotate_impl(3), 0.2), (solarize_impl(8), 0.6)],
+    [(c_vision.Equalize(), 0.6), (posterize_impl(6), 0.4)],
+
+    [(rotate_impl(8), 0.8), (color_impl(0), 0.4)],
+    [(rotate_impl(9), 0.4), (c_vision.Equalize(), 0.6)],
+    [(c_vision.Equalize(), 0.0), (c_vision.Equalize(), 0.8)],
+    [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)],
+    [(color_impl(4), 0.6), (contrast_impl(8), 1.0)],
+
+    [(rotate_impl(8), 0.8), (color_impl(2), 1.0)],
+    [(color_impl(8), 0.8), (solarize_impl(7), 0.8)],
+    [(sharpness_impl(7), 0.4), (c_vision.Invert(), 0.6)],
+    [(shear_x(5), 0.6), (c_vision.Equalize(), 1.0)],
+    [(color_impl(0), 0.4), (c_vision.Equalize(), 0.6)],
+
+    [(c_vision.Equalize(), 0.4), (solarize_impl(4), 0.2)],
+    [(solarize_impl(5), 0.6), (autocontrast_impl(5), 0.6)],
+    [(c_vision.Invert(), 0.6), (c_vision.Equalize(), 1.0)],
+    [(color_impl(4), 0.6), (contrast_impl(8), 1.0)],
+    [(c_vision.Equalize(), 0.8), (c_vision.Equalize(), 0.6)],
+]
+
+def split_imgs_and_labels(imgs, labels):
+    """split data into labels and images"""
+    ret_imgs = []
+    ret_labels = []
+
+    for i, image in enumerate(imgs):
+        ret_imgs.append(image)
+        ret_labels.append(labels[i])
+    return np.array(ret_imgs), np.array(ret_labels)
+
+
+def create_dataset(batch_size, train_data_url='', workers=8, target='Ascend', distributed=False,
+                   input_size=224, color_jitter=0.5, autoaugment=False):
+    """Create ImageNet training dataset"""
+    if not os.path.exists(train_data_url):
+        raise ValueError('Path not exists')
+    if target == "Ascend":
+        device_num, rank_id = _get_rank_info()
+    else:
+        if distributed:
+            init()
+            rank_id = get_rank()
+            device_num = get_group_size()
+        else:
+            device_num = 1
+            rank_id = 1
+    if device_num == 1:
+        dataset_train = ds.ImageFolderDataset(train_data_url, num_parallel_workers=workers, shuffle=True)
+    else:
+        dataset_train = ds.ImageFolderDataset(train_data_url, num_parallel_workers=workers, shuffle=True,
+                                              num_shards=device_num, shard_id=rank_id)
+
+
+    type_cast_op = c_transforms.TypeCast(mstype.int32)
+
+    random_resize_crop_bicubic = c_vision.RandomCropDecodeResize(input_size, scale=SCALE,
+                                                                 ratio=RATIO, interpolation=Inter.BICUBIC)
+
+    random_horizontal_flip_op = c_vision.RandomHorizontalFlip(prob=0.5)
+    adjust_range = (max(0, 1 - color_jitter), 1 + color_jitter)
+    random_color_jitter_op = c_vision.RandomColorAdjust(brightness=adjust_range,
+                                                        contrast=adjust_range,
+                                                        saturation=adjust_range)
+    normalize_op = c_vision.Normalize(
+        IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)
+    channel_op = c_vision.HWC2CHW()
+
+    # assemble all the transforms
+    if autoaugment:
+        dataset_train = dataset_train.map(input_columns=["image"],
+                                          operations=[random_resize_crop_bicubic],
+                                          num_parallel_workers=workers)
+        dataset_train = dataset_train.map(input_columns=["image"],
+                                          operations=c_vision.RandomSelectSubpolicy(imagenet_policy),
+                                          num_parallel_workers=workers)
+        dataset_train = dataset_train.map(input_columns=["image"],
+                                          operations=[random_horizontal_flip_op, normalize_op, channel_op],
+                                          num_parallel_workers=workers)
+    else:
+        image_ops = [random_resize_crop_bicubic, random_horizontal_flip_op,
+                     random_color_jitter_op, normalize_op, channel_op]
+
+        dataset_train = dataset_train.map(input_columns=["image"],
+                                          operations=image_ops,
+                                          num_parallel_workers=workers)
+
+    dataset_train = dataset_train.map(input_columns=["label"],
+                                      operations=type_cast_op,
+                                      num_parallel_workers=workers)
+
+    # batch dealing
+    ds_train = dataset_train.batch(batch_size, drop_remainder=True)
+
+    ds_train = ds_train.repeat(1)
+    return ds_train
+
+
+def create_dataset_val(batch_size=128, val_data_url='', workers=8, target='Ascend', distributed=False,
+                       input_size=224):
+    """Create ImageNet validation dataset"""
+    if not os.path.exists(val_data_url):
+        raise ValueError('Path not exists')
+
+    if target == "Ascend":
+        device_num, rank_id = _get_rank_info()
+    else:
+        if distributed:
+            init()
+            rank_id = get_rank()
+            device_num = get_group_size()
+        else:
+            device_num = 1
+
+    if device_num == 1:
+        dataset = ds.ImageFolderDataset(val_data_url, num_parallel_workers=workers)
+    else:
+        dataset = ds.ImageFolderDataset(val_data_url, num_parallel_workers=workers,
+                                        num_shards=device_num, shard_id=rank_id)
+
+    scale_size = None
+
+    if isinstance(input_size, tuple):
+        assert len(input_size) == 2
+        if input_size[-1] == input_size[-2]:
+            scale_size = int(math.floor(input_size[0] / DEFAULT_CROP_PCT))
+        else:
+            scale_size = tuple([int(x / DEFAULT_CROP_PCT) for x in input_size])
+    else:
+        scale_size = int(math.floor(input_size / DEFAULT_CROP_PCT))
+
+    type_cast_op = c_transforms.TypeCast(mstype.int32)
+    decode_op = c_vision.Decode()
+    resize_op = c_vision.Resize(size=scale_size, interpolation=Inter.BICUBIC)
+    center_crop = c_vision.CenterCrop(size=input_size)
+    normalize_op = c_vision.Normalize(
+        IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)
+    channel_op = c_vision.HWC2CHW()
+
+    image_ops = [decode_op, resize_op, center_crop, normalize_op, channel_op]
+
+    dataset = dataset.map(input_columns=["label"], operations=type_cast_op,
+                          num_parallel_workers=workers)
+    dataset = dataset.map(input_columns=["image"], operations=image_ops,
+                          num_parallel_workers=workers)
+
+    dataset = dataset.batch(batch_size, drop_remainder=True)
+
+    dataset = dataset.repeat(1)
+    return dataset
+
+def _get_rank_info():
+    """
+    get rank size and rank id
+    """
+    rank_size = int(os.environ.get("RANK_SIZE", 1))
+
+    if rank_size > 1:
+        rank_size = get_group_size()
+        rank_id = get_rank()
+    else:
+        rank_size = 1
+        rank_id = 0
+
+    return rank_size, rank_id
diff --git a/research/cv/S-GhostNet/src/eval_callback.py b/research/cv/S-GhostNet/src/eval_callback.py
new file mode 100644
index 0000000000000000000000000000000000000000..8300fa0a42ff8f65a28567282585514e4b027507
--- /dev/null
+++ b/research/cv/S-GhostNet/src/eval_callback.py
@@ -0,0 +1,73 @@
+# Copyright 2022 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 os
+import stat
+import time
+from mindspore import save_checkpoint
+from mindspore import log as logger
+from mindspore.train.callback import Callback
+
+
+class EvalCallBack(Callback):
+    def __init__(self, eval_function, eval_param_dict, interval=1, eval_start_epoch=1, save_best_ckpt=True,
+                 ckpt_directory="./", besk_ckpt_name="best.ckpt", metrics_name="acc"):
+        super(EvalCallBack, self).__init__()
+        self.eval_param_dict = eval_param_dict
+        self.eval_function = eval_function
+        self.eval_start_epoch = eval_start_epoch
+        if interval < 1:
+            raise ValueError("interval should >= 1.")
+        self.interval = interval
+        self.save_best_ckpt = save_best_ckpt
+        self.best_res = 0
+        self.best_epoch = 0
+        if not os.path.isdir(ckpt_directory):
+            os.makedirs(ckpt_directory)
+        self.bast_ckpt_path = os.path.join(ckpt_directory, besk_ckpt_name)
+        self.metrics_name = metrics_name
+
+    def remove_ckpoint_file(self, file_name):
+        try:
+            os.chmod(file_name, stat.S_IWRITE)
+            os.remove(file_name)
+        except OSError:
+            logger.warning("OSError, failed to remove the older ckpt file %s.", file_name)
+        except ValueError:
+            logger.warning("ValueError, failed to remove the older ckpt file %s.", file_name)
+
+    def epoch_end(self, run_context):
+        cb_params = run_context.original_args()
+        cur_epoch = cb_params.cur_epoch_num
+        if cur_epoch >= self.eval_start_epoch and (cur_epoch - self.eval_start_epoch) % self.interval == 0:
+            eval_start = time.time()
+            res = self.eval_function(self.eval_param_dict)
+            eval_cost = time.time() - eval_start
+            print("epoch: {}, {}: {}, eval_cost:{:.2f}".format(cur_epoch, self.metrics_name, res, eval_cost))
+            if res >= self.best_res:
+                self.best_res = res
+                self.best_epoch = cur_epoch
+                print("update best result: {}".format(res))
+                if self.save_best_ckpt:
+                    if os.path.exists(self.bast_ckpt_path):
+                        self.remove_ckpoint_file(self.bast_ckpt_path)
+                    save_checkpoint(cb_params.train_network, self.bast_ckpt_path)
+                    print("update best checkpoint at: {}".format(self.bast_ckpt_path))
+
+    def end(self, run_context):
+        v = run_context
+        assert v == run_context
+        print("End training, the best {0} is: {1}, the best {0} epoch is {2}".format(self.metrics_name,
+                                                                                     self.best_res,
+                                                                                     self.best_epoch))
diff --git a/research/cv/S-GhostNet/src/ghostnet.py b/research/cv/S-GhostNet/src/ghostnet.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffd9aa3112b827e7dcf5ff1ef0ebcdf25c44761d
--- /dev/null
+++ b/research/cv/S-GhostNet/src/ghostnet.py
@@ -0,0 +1,491 @@
+# Copyright 2022 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.
+# ============================================================================
+"""GhostNet model define"""
+from functools import partial
+import math
+import numpy as np
+import mindspore.nn as nn
+from mindspore.ops import operations as P
+from mindspore import Tensor
+import mindspore.common.initializer as weight_init
+
+__all__ = ['ghostnet']
+
+
+def _make_divisible(x, divisor=4):
+    return int(np.ceil(x * 1. / divisor) * divisor)
+
+
+class MyHSigmoid(nn.Cell):
+    """
+    Hard Sigmoid definition.
+
+    Args:
+
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> MyHSigmoid()
+    """
+
+    def __init__(self):
+        super(MyHSigmoid, self).__init__()
+        self.relu6 = nn.ReLU6()
+
+    def construct(self, x):
+        return self.relu6(x + 3.) * 0.16666667
+
+
+class Activation(nn.Cell):
+    """
+    Activation definition.
+
+    Args:
+        act_func(string): activation name.
+
+    Returns:
+         Tensor, output tensor.
+    """
+
+    def __init__(self, act_func):
+        super(Activation, self).__init__()
+        if act_func == 'relu':
+            self.act = nn.ReLU()
+        elif act_func == 'relu6':
+            self.act = nn.ReLU6()
+        elif act_func in ('hsigmoid', 'hard_sigmoid'):
+            self.act = MyHSigmoid()
+        elif act_func in ('hswish', 'hard_swish'):
+            self.act = nn.HSwish()
+        else:
+            raise NotImplementedError
+
+    def construct(self, x):
+        return self.act(x)
+
+
+class GlobalAvgPooling(nn.Cell):
+    """
+    Global avg pooling definition.
+
+    Args:
+
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> GlobalAvgPooling()
+    """
+
+    def __init__(self, keep_dims=False):
+        super(GlobalAvgPooling, self).__init__()
+        self.mean = P.ReduceMean(keep_dims=keep_dims)
+
+    def construct(self, x):
+        x = self.mean(x, (2, 3))
+        return x
+
+
+class SE(nn.Cell):
+    """
+    SE warpper definition.
+
+    Args:
+        num_out (int): Output channel.
+        ratio (int): middle output ratio.
+
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> SE(4)
+    """
+
+    def __init__(self, num_out, ratio=4):
+        super(SE, self).__init__()
+        num_mid = _make_divisible(num_out // ratio)
+        self.pool = GlobalAvgPooling(keep_dims=True)
+        self.conv_reduce = nn.Conv2d(in_channels=num_out, out_channels=num_mid,
+                                     kernel_size=1, has_bias=True, pad_mode='pad')
+        self.act1 = Activation('relu')
+        self.conv_expand = nn.Conv2d(in_channels=num_mid, out_channels=num_out,
+                                     kernel_size=1, has_bias=True, pad_mode='pad')
+        self.act2 = Activation('hsigmoid')
+        self.mul = P.Mul()
+
+    def construct(self, x):
+        out = self.pool(x)
+        out = self.conv_reduce(out)
+        out = self.act1(out)
+        out = self.conv_expand(out)
+        out = self.act2(out)
+        out = self.mul(x, out)
+        return out
+
+
+class ConvUnit(nn.Cell):
+    """
+    ConvUnit warpper definition.
+
+    Args:
+        num_in (int): Input channel.
+        num_out (int): Output channel.
+        kernel_size (int): Input kernel size.
+        stride (int): Stride size.
+        padding (int): Padding number.
+        num_groups (int): Output num group.
+        use_act (bool): Used activation or not.
+        act_type (string): Activation type.
+
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> ConvUnit(3, 3)
+    """
+
+    def __init__(self, num_in, num_out, kernel_size=1, stride=1, padding=0, num_groups=1,
+                 use_act=True, act_type='relu'):
+        super(ConvUnit, self).__init__()
+        self.conv = nn.Conv2d(in_channels=num_in,
+                              out_channels=num_out,
+                              kernel_size=kernel_size,
+                              stride=stride,
+                              padding=padding,
+                              group=num_groups,
+                              has_bias=False,
+                              pad_mode='pad')
+        self.bn = nn.BatchNorm2d(num_out)
+        self.use_act = use_act
+        self.act = Activation(act_type) if use_act else None
+
+    def construct(self, x):
+        out = self.conv(x)
+        out = self.bn(out)
+        if self.use_act:
+            out = self.act(out)
+        return out
+
+
+class GhostModule(nn.Cell):
+    """
+    GhostModule warpper definition.
+
+    Args:
+        num_in (int): Input channel.
+        num_out (int): Output channel.
+        kernel_size (int): Input kernel size.
+        stride (int): Stride size.
+        padding (int): Padding number.
+        ratio (int): Reduction ratio.
+        dw_size (int): kernel size of cheap operation.
+        use_act (bool): Used activation or not.
+        act_type (string): Activation type.
+
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> GhostModule(3, 3)
+    """
+
+    def __init__(self, num_in, num_out, kernel_size=1, stride=1, padding=0, ratio=2, dw_size=3,
+                 use_act=True, act_type='relu'):
+        super(GhostModule, self).__init__()
+        init_channels = math.ceil(num_out / ratio)
+        new_channels = init_channels * (ratio - 1)
+
+        self.primary_conv = ConvUnit(num_in, init_channels, kernel_size=kernel_size, stride=stride, padding=padding,
+                                     num_groups=1, use_act=use_act, act_type=act_type)
+        self.cheap_operation = ConvUnit(init_channels, new_channels, kernel_size=dw_size, stride=1, padding=dw_size//2,
+                                        num_groups=init_channels, use_act=use_act, act_type=act_type)
+        self.concat = P.Concat(axis=1)
+
+    def construct(self, x):
+        x1 = self.primary_conv(x)
+        x2 = self.cheap_operation(x1)
+        return self.concat((x1, x2))
+
+
+class GhostBottleneck(nn.Cell):
+    """
+    GhostBottleneck warpper definition.
+
+    Args:
+        num_in (int): Input channel.
+        num_mid (int): Middle channel.
+        num_out (int): Output channel.
+        kernel_size (int): Input kernel size.
+        stride (int): Stride size.
+        act_type (str): Activation type.
+        use_se (bool): Use SE warpper or not.
+
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> GhostBottleneck(16, 3, 1, 1)
+    """
+
+    def __init__(self, num_in, num_mid, num_out, kernel_size, stride=1, act_type='relu', use_se=False):
+        super(GhostBottleneck, self).__init__()
+        self.ghost1 = GhostModule(num_in, num_mid, kernel_size=1,
+                                  stride=1, padding=0, act_type=act_type)
+
+        self.use_dw = stride > 1
+        self.dw = None
+        if self.use_dw:
+            self.dw = ConvUnit(num_mid, num_mid, kernel_size=kernel_size, stride=stride,
+                               padding=self._get_pad(kernel_size), act_type=act_type, num_groups=num_mid, use_act=False)
+
+        self.use_se = use_se
+        if use_se:
+            self.se = SE(num_mid)
+
+        self.ghost2 = GhostModule(num_mid, num_out, kernel_size=1, stride=1,
+                                  padding=0, act_type=act_type, use_act=False)
+
+        self.down_sample = False
+        if num_in != num_out or stride != 1:
+            self.down_sample = True
+        self.shortcut = None
+        if self.down_sample:
+            self.shortcut = nn.SequentialCell([
+                ConvUnit(num_in, num_in, kernel_size=kernel_size, stride=stride,
+                         padding=self._get_pad(kernel_size), num_groups=num_in, use_act=False),
+                ConvUnit(num_in, num_out, kernel_size=1, stride=1,
+                         padding=0, num_groups=1, use_act=False),
+            ])
+        self.add = P.Add()
+
+    def construct(self, x):
+        r"""construct of ghostnet"""
+        shortcut = x
+        out = self.ghost1(x)
+        if self.use_dw:
+            out = self.dw(out)
+        if self.use_se:
+            out = self.se(out)
+        out = self.ghost2(out)
+        if self.down_sample:
+            shortcut = self.shortcut(shortcut)
+        out = self.add(shortcut, out)
+        return out
+
+    def _get_pad(self, kernel_size):
+        """set the padding number"""
+        pad = 0
+        if kernel_size == 1:
+            pad = 0
+        elif kernel_size == 3:
+            pad = 1
+        elif kernel_size == 5:
+            pad = 2
+        elif kernel_size == 7:
+            pad = 3
+        else:
+            raise NotImplementedError
+        return pad
+
+
+class GhostNet(nn.Cell):
+    """
+    GhostNet architecture.
+
+    Args:
+        model_cfgs (Cell): number of classes.
+        num_classes (int): Output number classes.
+        multiplier (int): Channels multiplier for round to 8/16 and others. Default is 1.
+        final_drop (float): Dropout number.
+        round_nearest (list): Channel round to . Default is 8.
+    Returns:
+        Tensor, output tensor.
+
+    Examples:
+        >>> GhostNet(num_classes=1000)
+    """
+
+    def __init__(self, model_cfgs, num_classes=1000, multiplier=1., final_drop=0.):
+        super(GhostNet, self).__init__()
+        self.cfgs = model_cfgs['cfg']
+        self.inplanes = 16
+        first_conv_in_channel = 3
+        first_conv_out_channel = _make_divisible(multiplier * self.inplanes)
+
+        self.conv_stem = nn.Conv2d(in_channels=first_conv_in_channel,
+                                   out_channels=first_conv_out_channel,
+                                   kernel_size=3, padding=1, stride=2,
+                                   has_bias=False, pad_mode='pad')
+        self.bn1 = nn.BatchNorm2d(first_conv_out_channel)
+        self.act1 = Activation('relu')
+
+        self.blocks = []
+        for layer_cfg in self.cfgs:
+            self.blocks.append(self._make_layer(kernel_size=layer_cfg[0],
+                                                exp_ch=_make_divisible(
+                                                    multiplier * layer_cfg[1]),
+                                                out_channel=_make_divisible(
+                                                    multiplier * layer_cfg[2]),
+                                                use_se=layer_cfg[3],
+                                                act_func=layer_cfg[4],
+                                                stride=layer_cfg[5]))
+        output_channel = _make_divisible(
+            multiplier * model_cfgs["cls_ch_squeeze"])
+        self.blocks.append(ConvUnit(_make_divisible(multiplier * self.cfgs[-1][2]), output_channel,
+                                    kernel_size=1, stride=1, padding=0, num_groups=1, use_act=True))
+        self.blocks = nn.SequentialCell(self.blocks)
+
+        self.global_pool = GlobalAvgPooling(keep_dims=True)
+        self.conv_head = nn.Conv2d(in_channels=output_channel,
+                                   out_channels=model_cfgs['cls_ch_expand'],
+                                   kernel_size=1, padding=0, stride=1,
+                                   has_bias=True, pad_mode='pad')
+        self.act2 = Activation('relu')
+        self.squeeze = P.Flatten()
+        self.final_drop = final_drop
+        if self.final_drop > 0:
+            self.dropout = nn.Dropout(self.final_drop)
+
+        self.classifier = nn.Dense(
+            model_cfgs['cls_ch_expand'], num_classes, has_bias=True)
+
+        self._initialize_weights()
+
+    def construct(self, x):
+        r"""construct of GhostNet"""
+        x = self.conv_stem(x)
+        x = self.bn1(x)
+        x = self.act1(x)
+        x = self.blocks(x)
+        x = self.global_pool(x)
+        x = self.conv_head(x)
+        x = self.act2(x)
+        x = self.squeeze(x)
+        if self.final_drop > 0:
+            x = self.dropout(x)
+        x = self.classifier(x)
+        return x
+
+    def _make_layer(self, kernel_size, exp_ch, out_channel, use_se, act_func, stride=1):
+        mid_planes = exp_ch
+        out_planes = out_channel
+        layer = GhostBottleneck(self.inplanes, mid_planes, out_planes,
+                                kernel_size, stride=stride, act_type=act_func, use_se=use_se)
+        self.inplanes = out_planes
+        return layer
+
+    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)):
+                m.weight.set_data(weight_init.initializer(weight_init.HeUniform(),
+                                                          m.weight.shape,
+                                                          m.weight.dtype))
+                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")))
+            elif isinstance(m, nn.Dense):
+                m.weight.set_data(weight_init.initializer(weight_init.HeNormal(),
+                                                          m.weight.shape,
+                                                          m.weight.dtype))
+                if m.bias is not None:
+                    m.bias.set_data(
+                        Tensor(np.zeros(m.bias.data.shape, dtype="float32")))
+
+
+def ghostnet(model_name, **kwargs):
+    """
+    Constructs a GhostNet model
+    """
+    model_cfgs = {
+        "1x": {
+            "cfg": [
+                # k, exp, c,  se,     nl,  s,
+                # stage1
+                [3, 16, 16, False, 'relu', 1],
+                # stage2
+                [3, 48, 24, False, 'relu', 2],
+                [3, 72, 24, False, 'relu', 1],
+                # stage3
+                [5, 72, 40, True, 'relu', 2],
+                [5, 120, 40, True, 'relu', 1],
+                # stage4
+                [3, 240, 80, False, 'relu', 2],
+                [3, 200, 80, False, 'relu', 1],
+                [3, 184, 80, False, 'relu', 1],
+                [3, 184, 80, False, 'relu', 1],
+                [3, 480, 112, True, 'relu', 1],
+                [3, 672, 112, True, 'relu', 1],
+                # stage5
+                [5, 672, 160, True, 'relu', 2],
+                [5, 960, 160, False, 'relu', 1],
+                [5, 960, 160, True, 'relu', 1],
+                [5, 960, 160, False, 'relu', 1],
+                [5, 960, 160, True, 'relu', 1]],
+            "cls_ch_squeeze": 960,
+            "cls_ch_expand": 1280,
+        },
+
+        "nose_1x": {
+            "cfg": [
+                # k, exp, c,  se,     nl,  s,
+                # stage1
+                [3, 16, 16, False, 'relu', 1],
+                # stage2
+                [3, 48, 24, False, 'relu', 2],
+                [3, 72, 24, False, 'relu', 1],
+                # stage3
+                [5, 72, 40, False, 'relu', 2],
+                [5, 120, 40, False, 'relu', 1],
+                # stage4
+                [3, 240, 80, False, 'relu', 2],
+                [3, 200, 80, False, 'relu', 1],
+                [3, 184, 80, False, 'relu', 1],
+                [3, 184, 80, False, 'relu', 1],
+                [3, 480, 112, False, 'relu', 1],
+                [3, 672, 112, False, 'relu', 1],
+                # stage5
+                [5, 672, 160, False, 'relu', 2],
+                [5, 960, 160, False, 'relu', 1],
+                [5, 960, 160, False, 'relu', 1],
+                [5, 960, 160, False, 'relu', 1],
+                [5, 960, 160, False, 'relu', 1]],
+            "cls_ch_squeeze": 960,
+            "cls_ch_expand": 1280,
+        }
+    }
+
+    return GhostNet(model_cfgs[model_name], **kwargs)
+
+
+ghostnet_1x = partial(ghostnet, model_name="1x", final_drop=0.8)
+ghostnet_nose_1x = partial(ghostnet, model_name="nose_1x", final_drop=0.8)
diff --git a/research/cv/S-GhostNet/src/loss.py b/research/cv/S-GhostNet/src/loss.py
new file mode 100644
index 0000000000000000000000000000000000000000..3fa00be2392d208d16022ae144bb9cc40f7c9416
--- /dev/null
+++ b/research/cv/S-GhostNet/src/loss.py
@@ -0,0 +1,43 @@
+# Copyright 2022 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 _Loss
+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 LabelSmoothingCrossEntropy(_Loss):
+    """cross-entropy with label smoothing"""
+
+    def __init__(self, smooth_factor=0.1, num_classes=1000):
+        super(LabelSmoothingCrossEntropy, 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(reduction='mean')
+        self.cast = P.Cast()
+
+    def construct(self, logits, label):
+        label = self.cast(label, mstype.int32)
+        one_hot_label = self.onehot(label, F.shape(
+            logits)[1], self.on_value, self.off_value)
+        loss_logit = self.ce(logits, one_hot_label)
+        return loss_logit
+      
\ No newline at end of file
diff --git a/research/cv/S-GhostNet/src/utils.py b/research/cv/S-GhostNet/src/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..6ff82d7252d9ece2e315e61605b59c7a3147b15b
--- /dev/null
+++ b/research/cv/S-GhostNet/src/utils.py
@@ -0,0 +1,124 @@
+# Copyright 2022 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.
+# ============================================================================
+"""model utils"""
+import math
+import argparse
+
+import numpy as np
+
+
+def str2bool(value):
+    """Convert string arguments to bool type"""
+    if value.lower() in ('yes', 'true', 't', 'y', '1'):
+        return True
+    if value.lower() in ('no', 'false', 'f', 'n', '0'):
+        return False
+    raise argparse.ArgumentTypeError('Boolean value expected.')
+
+
+def get_lr_tinynet_c(base_lr, total_epochs, steps_per_epoch, decay_epochs=1, decay_rate=0.9,
+                     warmup_epochs=0., warmup_lr_init=0., global_epoch=0):
+    """Get scheduled learning rate"""
+    lr_each_step = []
+    total_steps = steps_per_epoch * total_epochs
+    global_steps = steps_per_epoch * global_epoch
+    self_warmup_delta = ((base_lr - warmup_lr_init) / \
+                         warmup_epochs) if warmup_epochs > 0 else 0
+    self_decay_rate = decay_rate if decay_rate < 1 else 1/decay_rate
+    for i in range(total_steps):
+        epochs = math.floor(i/steps_per_epoch)
+        cond = 1 if (epochs < warmup_epochs) else 0
+        warmup_lr = warmup_lr_init + epochs * self_warmup_delta
+        decay_nums = math.floor(epochs / decay_epochs)
+        decay_rate = math.pow(self_decay_rate, decay_nums)
+        decay_lr = base_lr * decay_rate
+        lr = cond * warmup_lr + (1 - cond) * decay_lr
+        lr_each_step.append(lr)
+    lr_each_step = lr_each_step[global_steps:]
+    lr_each_step = np.array(lr_each_step).astype(np.float32)
+    return lr_each_step
+
+
+def get_lr(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)
+    lr_each_step = np.array(lr_each_step).astype(np.float32)
+
+    return lr_each_step
+
+
+def add_weight_decay(net, weight_decay=1e-5, skip_list=None):
+    """Apply weight decay to only conv and dense layers (len(shape) > =2)
+    Args:
+        net (mindspore.nn.Cell): Mindspore network instance
+        weight_decay (float): weight decay tobe used.
+        skip_list (tuple): list of parameter names without weight decay
+    Returns:
+        A list of group of parameters, separated by different weight decay.
+    """
+    decay = []
+    no_decay = []
+    if not skip_list:
+        skip_list = ()
+    for param in net.trainable_params():
+        if len(param.shape) == 1 or \
+           param.name.endswith(".bias") or \
+           param.name in skip_list:
+            no_decay.append(param)
+        else:
+            decay.append(param)
+    return [
+        {'params': no_decay, 'weight_decay': 0.},
+        {'params': decay, 'weight_decay': weight_decay}]
+
+
+def count_params(net):
+    """Count number of parameters in the network
+    Args:
+        net (mindspore.nn.Cell): Mindspore network instance
+    Returns:
+        total_params (int): Total number of trainable params
+    """
+    total_params = 0
+    for param in net.trainable_params():
+        total_params += np.prod(param.shape)
+    return total_params
diff --git a/research/cv/S-GhostNet/train.py b/research/cv/S-GhostNet/train.py
new file mode 100644
index 0000000000000000000000000000000000000000..390189dfd5a81a31acab8751da9c6c7a2659fb98
--- /dev/null
+++ b/research/cv/S-GhostNet/train.py
@@ -0,0 +1,402 @@
+# Copyright 2022 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.
+# ============================================================================
+"""Training Interface"""
+import sys
+import os
+import zipfile
+import argparse
+import hashlib
+from pathlib import Path
+
+from mindspore.communication.management import init, get_rank, get_group_size
+from mindspore import Model
+from mindspore.context import ParallelMode
+from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, TimeMonitor
+from mindspore.train.serialization import load_checkpoint, load_param_into_net
+from mindspore.train.loss_scale_manager import FixedLossScaleManager
+from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits
+from mindspore.nn import SGD, RMSProp, Momentum, Loss, Top1CategoricalAccuracy, \
+    Top5CategoricalAccuracy
+from mindspore import context, Tensor
+from mindspore.common import set_seed
+
+from src.dataset import create_dataset, create_dataset_val
+from src.utils import add_weight_decay, str2bool, get_lr_tinynet_c, get_lr
+from src.callback import LossMonitor
+from src.loss import LabelSmoothingCrossEntropy
+from src.eval_callback import EvalCallBack
+from src.big_net import GhostNet
+
+local_plog_path = os.path.join(Path.home(), 'ascend/log/')
+
+os.environ["GLOG_v"] = '3'
+os.environ["ASCEND_SLOG_PRINT_TO_STDOUT"] = '0'
+os.environ["ASCEND_GLOBAL_LOG_LEVEL"] = '2'
+os.environ["ASCEND_GLOBAL_EVENT_ENABLE"] = '0'
+
+parser = argparse.ArgumentParser(description='Training')
+
+# model architecture parameters
+parser.add_argument('--data_path', type=str, default="", metavar="DIR",
+                    help='path to dataset')
+parser.add_argument('--model', default='tinynet_c', type=str, metavar='MODEL',
+                    help='Name of model to train (default: "tinynet_c") ghostnet, big_net')
+parser.add_argument('--num-classes', type=int, default=1000, metavar='N',
+                    help='number of label classes (default: 1000)')
+parser.add_argument('--channels', type=str, default='16,24,40,80,112,160',
+                    help='channel config of model architecure')
+parser.add_argument('--layers', type=str, default='1,2,2,4,2,5',
+                    help='layer config of model architecure')
+parser.add_argument('--large', action='store_true', default=False,
+                    help='ghostnet1x or ghostnet larger')
+parser.add_argument('--input_size', type=int, default=224,
+                    help='input size of model.')
+
+# preprocess parameters
+parser.add_argument('--autoaugment', action='store_true', default=False,
+                    help='whether use autoaugment for training images')
+
+# training parameters
+parser.add_argument('--epochs', type=int, default=200, metavar='N',
+                    help='number of epochs to train (default: 2)')
+parser.add_argument('-b', '--batch-size', type=int, default=256, metavar='N',
+                    help='input batch size for training (default: 32)')
+parser.add_argument('--drop', type=float, default=0.0, metavar='DROP',
+                    help='Dropout rate (default: 0.) for big_net, use "1-drop", for others, use "drop"')
+parser.add_argument('--drop-path', type=float, default=0.0, metavar='DROP',
+                    help='Drop connect rate (default: 0.)')
+parser.add_argument('--opt', default='sgd', type=str, metavar='OPTIMIZER',
+                    help='Optimizer (default: "sgd"')
+parser.add_argument('--opt-eps', default=1e-8, type=float, metavar='EPSILON',
+                    help='Optimizer Epsilon (default: 1e-8)')
+parser.add_argument('--momentum', type=float, default=0.9, metavar='M',
+                    help='SGD momentum (default: 0.9)')
+parser.add_argument('--weight-decay', type=float, default=0.0001,
+                    help='weight decay (default: 0.0001)')
+parser.add_argument('--lr_decay_style', type=str, default='cosine',
+                    help='learning rate decay method(default: cosine), cosine_step')
+parser.add_argument('--lr', type=float, default=0.01, metavar='LR',
+                    help='learning rate (default: 0.01)')
+parser.add_argument('--lr_end', type=float, default=1e-6,
+                    help='The end of training learning rate (default: 1e-6)')
+parser.add_argument('--lr_max', type=float, default=0.4,
+                    help='the max of training learning rate (default: 0.4)')
+parser.add_argument('--warmup-lr', type=float, default=0.0001, metavar='LR',
+                    help='warmup learning rate (default: 0.0001)')
+parser.add_argument('--decay-epochs', type=float, default=30, metavar='N',
+                    help='epoch interval to decay LR')
+parser.add_argument('--warmup-epochs', type=int, default=3, metavar='N',
+                    help='epochs to warmup LR, if scheduler supports')
+parser.add_argument('--decay-rate', '--dr', type=float, default=0.1, metavar='RATE',
+                    help='LR decay rate (default: 0.1)')
+
+parser.add_argument('--smoothing', type=float, default=0.1,
+                    help='label smoothing (default: 0.1)')
+parser.add_argument('--ema-decay', type=float, default=0.9999,
+                    help='decay factor for model weights moving average \
+                    (default: 0.999)')
+
+# training information parameters
+parser.add_argument('--amp_level', type=str, default='O0')
+parser.add_argument('--per_print_times', type=int, default=1)
+
+# batch norm parameters
+parser.add_argument('--sync_bn', action='store_true', default=False,
+                    help='Use sync bn in distributed mode. (default: False)')
+parser.add_argument('--bn-tf', action='store_true', default=False,
+                    help='Use Tensorflow BatchNorm defaults for models that \
+                    support it (default: False)')
+parser.add_argument('--bn-momentum', type=float, default=None,
+                    help='BatchNorm momentum override (if not None)')
+parser.add_argument('--bn-eps', type=float, default=None,
+                    help='BatchNorm epsilon override (if not None)')
+
+# parallel parameters
+parser.add_argument('-j', '--workers', type=int, default=4, metavar='N',
+                    help='how many training processes to use (default: 1)')
+parser.add_argument('--distributed', action='store_true', default=False)
+parser.add_argument('--dataset_sink', action='store_false', default=True)
+parser.add_argument('--device_num', type=int, default=8, help='Device num.')
+
+# checkpoint config
+parser.add_argument('--save_checkpoint', action='store_false', default=True)
+parser.add_argument('--ckpt', type=str, default=None)
+parser.add_argument('--ckpt_save_path', type=str, default='./')
+parser.add_argument('--ckpt_save_epoch', type=int, default=5)
+parser.add_argument('--loss_scale', type=int,
+                    default=128, help='static loss scale')
+parser.add_argument('--train', type=str2bool, default=1, help='train or eval')
+parser.add_argument('--device_target', type=str, default='Ascend', choices=("Ascend", "GPU", "CPU"),
+                    help="Device target, support Ascend, GPU and CPU.")
+# train on cloud
+parser.add_argument('--cloud', action='store_true', default=False, help='Whether train on cloud.')
+parser.add_argument('--data_url', type=str, default="/home/ma-user/work/data/imagenet", help='path to dataset.')
+parser.add_argument('--zip_url', type=str, default="s3://bucket-800/liuchuanjian/data/imagenet_zip/imagenet.zip")
+parser.add_argument('--train_url', type=str, default=" ", help='train_dir.')
+parser.add_argument('--tmp_data_dir', default='/cache/data/', help='temp data dir')
+parser.add_argument('--tmp_save_dir', default='/cache/liuchuanjian/', help='temp save dir')
+parser.add_argument('--save_dir', default='/autotest/liuchuanjian/result/big_model', help='temp save dir')
+
+_global_sync_count = 0
+
+def get_file_md5(file_name):
+    m = hashlib.md5()
+    with open(file_name, 'rb') as fobj:
+        while True:
+            data = fobj.read(4096)
+            if not data:
+                break
+            m.update(data)
+
+    return m.hexdigest()
+
+def get_device_id():
+    device_id = os.getenv('DEVICE_ID', '0')
+    return int(device_id)
+
+def get_device_num():
+    device_num = os.getenv('RANK_SIZE', '1')
+    return int(device_num)
+
+def unzip_file(zip_src, dst_dir):
+    r = zipfile.is_zipfile(zip_src)
+    if r:
+        fz = zipfile.ZipFile(zip_src, 'r')
+        for file_item in fz.namelist():
+            fz.extract(file_item, dst_dir)
+    else:
+        raise Exception('This is not zip')
+
+def sync_data(args):
+    """
+    Download data from remote obs to local directory if the first url is remote url and the second one is local path
+    Upload data from local directory to remote obs in contrast.
+    """
+    import time
+    global _global_sync_count
+    sync_lock = "/tmp/copy_sync.lock" + str(_global_sync_count)
+    _global_sync_count += 1
+
+    if not mox.file.exists(args.tmp_data_dir):
+        mox.file.make_dirs(args.tmp_data_dir)
+    target_file = os.path.join(args.tmp_data_dir, 'imagenet.zip')
+    # Each server contains 8 devices as most.
+    if get_device_id() % min(get_device_num(), 8) == 0 and not os.path.exists(sync_lock):
+        print("from path: ", args.zip_url)
+        print("to path: ", target_file)
+        mox.file.copy_parallel(args.zip_url, target_file)
+        print('Zip file copy success.')
+        os.system('ls /cache/data/')
+        print('Computing MD5 of copied file.')
+        file_md5 = get_file_md5(target_file)
+        print('MD5 is: ', file_md5)
+        re_upload_num = 20
+        while file_md5 != '674b2e3a185c2c82c8d211a0465c386e' and re_upload_num >= 0:
+            mox.file.copy_parallel(args.zip_url, target_file)
+            print('Zip file copy success.')
+            print('Computing MD5 of copied file.')
+            file_md5 = get_file_md5(target_file)
+            print('MD5 is: ', file_md5)
+            re_upload_num -= 1
+            print('reupload num is: ', re_upload_num)
+
+        print('Starting unzip file.')
+        unzip_file(target_file, args.tmp_data_dir)
+        print('Unzip file success.')
+        print("===finish data synchronization===")
+        try:
+            os.mknod(sync_lock)
+        except IOError:
+            pass
+        print("===save flag===")
+
+    while True:
+        if os.path.exists(sync_lock):
+            break
+        time.sleep(1)
+
+    args.data_url = os.path.join(args.tmp_data_dir, 'imagenet')
+    args.data_path = args.data_url
+    print("Finish sync data from {} to {}.".format(args.zip_url, target_file))
+
+def apply_eval(eval_param):
+    eval_model = eval_param["model"]
+    eval_ds = eval_param["dataset"]
+    metrics_name = eval_param["metrics_name"]
+    res = eval_model.eval(eval_ds)
+    return res[metrics_name]
+
+def main(args):
+    """Main entrance for training"""
+    if args.channels:
+        channel_config = []
+        for item in args.channels.split(','):
+            channel_config.append(int(item.strip()))
+    if args.layers:
+        layer_config = []
+        for item in args.layers.split(','):
+            layer_config.append(int(item.strip()))
+    print(sys.argv)
+    set_seed(1)
+    target = args.device_target
+
+    ckpt_save_dir = args.save_dir
+    context.set_context(mode=context.GRAPH_MODE, device_target=target, save_graphs=False)
+    device_num = get_device_num()
+    if args.distributed:
+        devid = int(os.getenv('DEVICE_ID'))
+        context.set_context(device_id=devid,
+                            reserve_class_name_in_scope=True)
+        init()
+        context.set_auto_parallel_context(device_num=device_num, parallel_mode=ParallelMode.DATA_PARALLEL,
+                                          gradients_mean=True, parameter_broadcast=True)
+        print('device_num: ', context.get_auto_parallel_context("device_num"))
+        args.rank = get_rank()
+        args.group_size = get_group_size()
+        print('Rank {}, group_size {}'.format(args.rank, args.group_size))
+
+        # create save dir
+        if args.cloud:
+            if not mox.file.exists(os.path.join(args.tmp_save_dir, str(args.rank))):
+                mox.file.make_dirs(os.path.join(args.tmp_save_dir, str(args.rank)))
+
+            args.save_dir = os.path.join(args.tmp_save_dir, str(args.rank))
+        else:
+            # Check the save_dir exists or not
+            if not os.path.exists(args.save_dir):
+                os.makedirs(args.save_dir)
+        print('Imagenet dir: ', args.data_path)
+
+        ckpt_save_dir = os.path.join(args.save_dir, "ckpt_" + str(get_rank()))
+
+    net = GhostNet(layers=layer_config, channels=channel_config, num_classes=args.num_classes,
+                   final_drop=args.drop, drop_path_rate=args.drop_path,
+                   large=args.large, zero_init_residual=False, sync_bn=args.sync_bn)
+    print(net)
+
+    time_cb = TimeMonitor(data_size=batches_per_epoch)
+
+    if args.lr_decay_style == 'cosine_step':
+        # original tinynet_c lr_decay method
+        lr_array = get_lr_tinynet_c(base_lr=args.lr, total_epochs=args.epochs,
+                                    steps_per_epoch=batches_per_epoch, decay_epochs=args.decay_epochs,
+                                    decay_rate=args.decay_rate, warmup_epochs=args.warmup_epochs,
+                                    warmup_lr_init=args.warmup_lr, global_epoch=0)
+    elif args.lr_decay_style == 'cosine':
+        # standard cosine lr_decay method, used in official mindspore ghostnet
+        lr_array = get_lr(lr_init=args.lr, lr_end=args.lr_end,
+                          lr_max=args.lr_max, warmup_epochs=args.warmup_epochs,
+                          total_epochs=args.epochs, steps_per_epoch=batches_per_epoch)
+    else:
+        raise Exception('Unknown lr decay method!!!!!')
+    lr = Tensor(lr_array)
+
+    loss_cb = LossMonitor(lr_array, args.epochs, per_print_times=args.per_print_times,
+                          start_epoch=0)
+
+    if args.opt == 'sgd':
+        param_group = add_weight_decay(net, weight_decay=args.weight_decay)
+        optimizer = SGD(param_group, learning_rate=lr,
+                        momentum=args.momentum, weight_decay=args.weight_decay,
+                        loss_scale=args.loss_scale)
+
+    elif args.opt == 'rmsprop':
+        param_group = add_weight_decay(net, weight_decay=args.weight_decay)
+        optimizer = RMSProp(param_group, learning_rate=lr,
+                            decay=0.9, weight_decay=args.weight_decay,
+                            momentum=args.momentum, epsilon=args.opt_eps,
+                            loss_scale=args.loss_scale)
+    elif args.opt == 'momentum':
+        optimizer = Momentum(net.trainable_params(), learning_rate=lr,
+                             momentum=args.momentum, loss_scale=args.loss_scale,
+                             weight_decay=args.weight_decay)
+
+    if args.smoothing == 0.0:
+        loss = SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
+    else:
+        loss = LabelSmoothingCrossEntropy(smooth_factor=args.smoothing, num_classes=args.num_classes)
+
+    loss_scale_manager = FixedLossScaleManager(args.loss_scale, drop_overflow_update=False)
+
+    loss.add_flags_recursive(fp32=True, fp16=False)
+    eval_metrics = {'Validation-Loss': Loss(),
+                    'Top1-Acc': Top1CategoricalAccuracy(),
+                    'Top5-Acc': Top5CategoricalAccuracy()}
+
+    if args.ckpt:
+        ckpt = load_checkpoint(args.ckpt)
+        load_param_into_net(net, ckpt)
+        net.set_train(False)
+
+    model = Model(net, loss, optimizer, metrics=eval_metrics,
+                  loss_scale_manager=loss_scale_manager,
+                  amp_level=args.amp_level)
+
+    eval_param_dict = {"model": model, "dataset": val_dataset, "metrics_name": "Top1-Acc"}
+    eval_cb = EvalCallBack(apply_eval, eval_param_dict, interval=1,
+                           eval_start_epoch=0, save_best_ckpt=False,
+                           ckpt_directory=ckpt_save_dir, besk_ckpt_name="best_acc.ckpt",
+                           metrics_name="Top1-Acc")
+
+    callbacks = [loss_cb, eval_cb, time_cb]
+    if args.save_checkpoint:
+        config_ck = CheckpointConfig(save_checkpoint_steps=args.ckpt_save_epoch* batches_per_epoch,
+                                     keep_checkpoint_max=5)
+        ckpt_cb = ModelCheckpoint(prefix=args.model, directory=ckpt_save_dir, config=config_ck)
+        callbacks += [ckpt_cb]
+
+    print('dataset_sink_mode: ', args.dataset_sink)
+    model.train(args.epochs, train_dataset, callbacks=callbacks,
+                dataset_sink_mode=args.dataset_sink)
+
+
+if __name__ == '__main__':
+    opts, unparsed = parser.parse_known_args()
+    # copy data
+    if opts.cloud:
+        import moxing as mox
+        sync_data(opts)
+
+    # input image size of the network
+    train_dataset = val_dataset = None
+    train_data_url = os.path.join(opts.data_path, 'train')
+    val_data_url = os.path.join(opts.data_path, 'val')
+    print('train data path: ', train_data_url)
+    print('val data path: ', val_data_url)
+    val_dataset = create_dataset_val(opts.batch_size,
+                                     val_data_url,
+                                     workers=opts.workers,
+                                     target=opts.device_target,
+                                     distributed=False,
+                                     input_size=opts.input_size)
+
+    if opts.train:
+        train_dataset = create_dataset(opts.batch_size,
+                                       train_data_url,
+                                       workers=opts.workers,
+                                       target=opts.device_target,
+                                       distributed=opts.distributed,
+                                       input_size=opts.input_size,
+                                       autoaugment=opts.autoaugment)
+        batches_per_epoch = train_dataset.get_dataset_size()
+        print('Number of batches:', batches_per_epoch)
+    main(opts)
+
+    if opts.cloud:
+        mox.file.copy_parallel(opts.save_dir, opts.train_url)
+        if os.path.exists(local_plog_path):
+            mox.file.copy_parallel(local_plog_path, opts.train_url)
+        else:
+            print('{} not exist....'.format(local_plog_path))