转载地址:https://bbs.huaweicloud.com/forum/thread-83710-1-1.html

作者: archimekai

使用MobileNetV2网络实现微调(Fine Tune)

实验介绍

本实验介绍使用MindSpore,在CPU环境下,mobileNetV2网络做微调训练与验证。

实验目的

  • 掌握如何使用MindSpore进行微调实验开发。

  • 理解微调方法的原理、方法。

  • 了解如何使用MindSpore进行MobileNetV2网络训练与验证.

实验环境

  • MindSpore 1.0.0-CPU

实验准备

数据集准备

准备ImageFolder格式管理的数据集,运行train.py时加入--dataset_path [dataset_path]参数。

这里采用花分类数据集。下载地址为:

  • 训练数据集链接:https://professional.obs.cn-north-4.myhuaweicloud.com/flower_photos_train.zip

  • 测试数据集链接:https://professional.obs.cn-north-4.myhuaweicloud.com/flower_photos_test.zip

预训练模型准备

下载预训练模型(mobilenetv2_cpu_gpu.ckpt)到以下目录: ./pretrain_checkpoint/[pretrain_checkpoint_file]

1

2

mkdir pretrain_checkpoint

wget -P ./pretrain_checkpoint

脚本准备

从课程gitee仓库上下载本实验相关脚本。

在Gitee中克隆MindSpore开源项目仓库,进入./model_zoo/official/cv/mobilenetv2/直接下载。

1

2

3

git clone https://gitee.com/mindspore/mindspore.git -b r1.0

mkdir mobilenetv2

cp -r ./mindspore/model_zoo/official/cv/mobilenetv2 ./mobilenetv2/code

文件结构

mobilenetv2
├── code
│   ├── src
│   │   ├── config.py           # parameter configuration
│   │   ├── dataset.py         # creating dataset
│   │   ├── launch.py           # start Python script
│   │   ├── lr_generator.py     # learning rate config
│   │   ├── mobilenetV2.py     # MobileNetV2 architecture
│   │   ├── models.py           # net utils to load ckpt_file, define_net...
│   │   └── utils.py           # net utils to switch precision, set_context
│   ├── train.py               # training script
│   └── .py                 # uation script
├── pretrain_checkpoint
│   └── mobilenetv2_cpu_gpu.ckpt       # Pre-trained model
└── data├── flower_photos_train│   └── *           # daisy, dandelion, roses, sunflowers, tulips└──flower_photos_test└── *           # daisy, dandelion, roses, sunflowers, tulips

实验原理

mobileNetV1是由google在2017年发布的一个轻量级深度神经网络,其主要特点是采用深度可分离卷积(Depthwise Separable Convolution)替换了普通卷积,2018年提出的mobileNetV2在V1的基础上引入了线性瓶颈 (Linear Bottleneck)和倒残差 (Inverted Residual)来提高网络的表征能力。

mobileNetV1的深度可分离卷积

Depthwise Separable Convolution实质上是将标准卷积分成了两步:depthwise卷积和pointwise卷积,大大减少了普通卷积的计算量。

  • depthwise卷积:对每个输入通道单独使用一个卷积核处理,输入输出维度是相同的;

  • pointwise卷积:1×1卷积,用于将depthwise卷积的输出组合起来;

卷积类型 输入维度 输出通道数 卷积核 卷积核参数量 输出维度 计算量
标准卷积 C1*H*W C2 K*K K*K*C1*C2 C2*H*W K*K*C1*C2*H*W
depthwise卷积 C1*H*W C1 K*K K*K*C1 C1*H*W K*K*C1*H*W
pointwise卷积 C1*H*W C2 1*1 1*1*C1*C2 C2*H*W 1*1*C1*C2*H*W
深度可分离卷积 C1*H*W C2 C2*H*W (K*K+C2)*C1*H*W

从表格可以看出:深度可分离卷积利用两个可分离的卷积(depthwise卷积和pointwise卷积)替换标准卷积,增加的深度,但却大大减少了计算量。

mobileNetV2的改进

MobileNet V1的结构较为简单,Depthwise Convolution确实降低了计算量,但是 Depthwise 部分的 kernel 训练容易废掉,最终再经过ReLU出现输出为0的情况。

Resnet及Densenet等一系列采用shortcut的网络的成功,表明了shortcut是个非常好的东西,于是MobileNet-V2就将这个好东西拿来用。

拿来主义,最重要的就是要结合自身的特点,MobileNet的特点就是depth-wise separable convolution,但是直接把depth-wise separable convolution应用到 residual block中,会碰到如下问题:

  1. DWConv layer层提取得到的特征受限于输入的通道数,若是采用以往的residual block,先“压缩”,再卷积提特征,那么DWConv layer可提取得特征就太少了,因此一开始不“压缩”,MobileNetV2反其道而行,一开始先“扩张”。 通常residual block里面是 “压缩”→“卷积提特征”→“扩张”,MobileNetV2就变成了 “扩张”→“卷积提特征”→ “压缩”,因此称为Inverted residuals。

  2. 当采用“扩张”→“卷积提特征”→ “压缩”时,在“压缩”之后会碰到一个问题,那就是Relu会破坏特征。为什么这里的Relu会破坏特征呢?这得从Relu的性质说起,Relu对于负的输入,输出全为零;而本来特征就已经被“压缩”,再经过Relu的话,又要“损失”一部分特征,因此这里不采用Relu,实验结果表明这样做是正确的,这就称为Linear bottlenecks。

下图分别展示了有无shortcut连接的mobileNetV2对depth-wise separable convolution的改进。

  • 当stride=1时,使用short cut连接,将输入和输出特征连接(下图左侧);

  • 当stride=2时,无short cut连接(下图右侧)。

mobileNetV2网络的总体结构,请参照src/MobileNetV2.py

微调

前面下载的模型mobilenetv2_cpu_gpu.ckpt是mobileNetV2网络在ImageNet数据集上面训练得到的。ImageNet数据集数据量大,不适合在CPU上运行。

为了加快训练速度,突出微调的优势,使CPU上训练大网络成为可能。我们采用mobilenetv2_cpu_gpu.ckpt模型作为花卉分类模型的预训练模型,只训练MobileNetV2Head(两个全连接层)网络。具体训练流程为:

  • 加载mobilenetv2_cpu_gpu.ckpt模型,并利用模型将数据集特征化,生成特征数据。

  • 定义MobileNetV2Head网络,以特征数据作为其输入,训练MobileNetV2Head网络。

注意: 定义MobileNetV2Head网络的输入维度和mobilenetv2_cpu_gpu.ckpt网络的输出维度保持一致。

微调让CPU训练大型网络成为可能,并且实现了不同数据集的迁移学习。

实验步骤

MobileNetV2实验包含2种训练方式,分别为:

  • train: 不使用预训练模型。从头到尾训练MobileNetV2网络(参数freeze_layer为“none”,参数pretrain_ckpt为None)。网络定义参考src/MobileNetV2.py 中的MobileNetV2类。

  • fine_tune:微调,使用预训练模型(大数据集)训练网络,根据是否冻结一部分网络分为两种。

    • 不冻结MobileNetV2Backbone部分(参数freeze_layer为“none”)。网络包含MobileNetV2Backbone和MobileNetV2Head两部分,其中MobileNetV2Backbone网络参数是从一个已经训练好的ckpt模型中得到(参数pretrain_ckpt非空)。网络定义参考src/MobileNetV2.py 中的MobileNetV2Backbone、MobileNetV2Head类。

    • 冻结MobileNetV2Backbone部分(参数freeze_layer为"backbone")。只训练MobileNetV2Head网络,其中MobileNetV2Backbone网络参数是从一个已经训练好的ckpt模型中得到(参数pretrain_ckpt非空)。

注意: CPU运行速度慢,所以仅支持fine_tune方式下的冻结MobileNetV2Backbone部分。即:参数freeze_layer为"backbone",参数pretrain_ckpt非空。

重要代码解读

定义MobileNetV2Backbone网络(src/MobileNetV2.py)

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

class MobileNetV2Backbone(nn.Cell):

   """

  MobileNetV2 architecture.

  Args:

      class_num (int): number of classes.

      width_mult (int): Channels multiplier for round to 8/16 and others. Default is 1.

      has_dropout (bool): Is dropout used. Default is false

      inverted_residual_setting (list): Inverted residual settings. Default is None

      round_nearest (list): Channel round to . Default is 8

  Returns:

      Tensor, output tensor.

  Examples:

      >>> MobileNetV2(num_classes=1000)

  """

   def __init__(self, width_mult=1., inverted_residual_setting=None, round_nearest=8,

                input_channel=32, last_channel=1280):

       super(MobileNetV2Backbone, self).__init__()

       block = InvertedResidual

       # setting of inverted residual blocks

       self.cfgs = inverted_residual_setting

       if inverted_residual_setting is None:

           self.cfgs = [

               # t, c, n, s

              [11611],

              [62422],

              [63232],

              [66442],

              [69631],

              [616032],

              [632011],

          ]

       # building first layer

       input_channel = _make_divisible(input_channel * width_mult, round_nearest)

       self.out_channels = _make_divisible(last_channel * max(1.0, width_mult), round_nearest)

       features = [ConvBNReLU(3, input_channel, stride=2)]

       # building inverted residual blocks

       for t, c, n, s in self.cfgs:

           output_channel = _make_divisible(c * width_mult, round_nearest)

           for in range(n):

               stride = if == 0 else 1

               features.append(block(input_channel, output_channel, stride, expand_ratio=t))

               input_channel = output_channel

       # building last several layers

       features.append(ConvBNReLU(input_channel, self.out_channels, kernel_size=1))

       # make it nn.CellList

       self.features = nn.SequentialCell(features)

       self._initialize_weights()

   def construct(self, x):

       = self.features(x)

       return x

   def _initialize_weights(self):

       """

      Initialize weights.

      Args:

      Returns:

          None.

      Examples:

          >>> _initialize_weights()

      """

       self.init_parameters_data()

       for _, m in self.cells_and_names():

           if isinstance(m, nn.Conv2d):

               = m.kernel_size[0* m.kernel_size[1* m.out_channels

               m.weight.set_data(Tensor(np.random.normal(0, np.sqrt(2. / n),

                                                         m.weight.data.shape).astype("float32")))

               if m.bias is not None:

                   m.bias.set_data(

                       Tensor(np.zeros(m.bias.data.shape, dtype="float32")))

           elif isinstance(m, nn.BatchNorm2d):

               m.gamma.set_data(

                   Tensor(np.ones(m.gamma.data.shape, dtype="float32")))

               m.beta.set_data(

                   Tensor(np.zeros(m.beta.data.shape, dtype="float32")))

   @property

   def get_features(self):

       return self.features

定义MobileNetV2Head网络(src/MobileNetV2.py)

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

class MobileNetV2Head(nn.Cell):

   """

  MobileNetV2 architecture.

  Args:

      class_num (int): Number of classes. Default is 1000.

      has_dropout (bool): Is dropout used. Default is false

  Returns:

      Tensor, output tensor.

  Examples:

      >>> MobileNetV2(num_classes=1000)

  """

   def __init__(self, input_channel=1280, num_classes=1000, has_dropout=False, activation="None"):

       super(MobileNetV2Head, self).__init__()

       # mobilenet head

       head = ([GlobalAvgPooling(), nn.Dense(input_channel, num_classes, has_bias=True)]

               if not has_dropout else

              [GlobalAvgPooling(), nn.Dropout(0.2), nn.Dense(input_channel, num_classes, has_bias=True)])

       self.head = nn.SequentialCell(head)

       self.need_activation = True

       if activation == "Sigmoid":

           self.activation = P.Sigmoid()

       elif activation == "Softmax":

           self.activation = P.Softmax()

       else:

           self.need_activation = False

       self._initialize_weights()

   def construct(self, x):

       = self.head(x)

       if self.need_activation:

           = self.activation(x)

       return x

   def _initialize_weights(self):

       """

      Initialize weights.

      Args:

      Returns:

          None.

      Examples:

          >>> _initialize_weights()

      """

       self.init_parameters_data()

       for _, m in self.cells_and_names():

           if isinstance(m, nn.Dense):

               m.weight.set_data(Tensor(np.random.normal(

                   00.01, m.weight.data.shape).astype("float32")))

               if m.bias is not None:

                   m.bias.set_data(

                       Tensor(np.zeros(m.bias.data.shape, dtype="float32")))

   @property

   def get_head(self):

       return self.head

定义初始化网络函数(src/model.py)

1

2

3

4

5

6

7

8

def define_net(config, is_training):

   backbone_net = MobileNetV2Backbone()

   activation = config.activation if not is_training else "None"

   head_net = MobileNetV2Head(input_channel=backbone_net.out_channels,

                              num_classes=config.num_classes,

                              activation=activation)

   net = mobilenet_v2(backbone_net, head_net)

   return backbone_net, head_net, net

定义特征化函数extract_features(src/dataset.py)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

def extract_features(net, dataset_path, config):

   features_folder = os.path.abspath(dataset_path) + '_features'

   if not os.path.exists(features_folder):

       os.makedirs(features_folder)

   dataset = create_dataset(dataset_path=dataset_path,

                            do_train=False,

                            config=config)

   step_size = dataset.get_dataset_size()

   if step_size == 0:

       raise ValueError("The step_size of dataset is zero. Check if the images count of train dataset \

                        is more than batch_size in config.py")

   model = Model(net)

   for i, data in enumerate(dataset.create_dict_iterator(output_numpy=True)):

       features_path = os.path.join(features_folder, f"feature_{i}.npy")

       label_path = os.path.join(features_folder, f"label_{i}.npy")

       if not os.path.exists(features_path) or not os.path.exists(label_path):

           image = data["image"]

           label = data["label"]

           features = model.predict(Tensor(image))

           np.save(features_path, features.asnumpy())

           np.save(label_path, label)

       print(f"Complete the batch {i+1}/{step_size}")

   return step_size

初始化网络并特征化(train.py)

1

2

3

4

5

6

# define network

backbone_net, head_net, net = define_net(config, args_opt.is_training)

if args_opt.pretrain_ckpt and args_opt.freeze_layer == "backbone":

   load_ckpt(backbone_net, args_opt.pretrain_ckpt, trainable=False)

   step_size = extract_features(backbone_net, args_opt.dataset_path, config)

微调(train.py)

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

if args_opt.pretrain_ckpt is None or args_opt.freeze_layer == "none":

   loss_scale = FixedLossScaleManager(config.loss_scale, drop_overflow_update=False)

   opt = Momentum(filter(lambda x: x.requires_grad, net.get_parameters()), lr, config.momentum, \

           config.weight_decay, config.loss_scale)

   model = Model(net, loss_fn=loss, optimizer=opt, loss_scale_manager=loss_scale)

   cb = config_ckpoint(config, lr, step_size)

   print("============== Starting Training ==============")

   model.train(epoch_size, dataset, callbacks=cb)

   print("============== End Training ==============")

else:

   opt = Momentum(filter(lambda x: x.requires_grad, head_net.get_parameters()), lr, config.momentum,\      

                  config.weight_decay)

   network = WithLossCell(head_net, loss)

   network = TrainOneStepCell(network, opt)

   network.set_train()

   features_path = args_opt.dataset_path + '_features'

   idx_list = list(range(step_size))

   rank = 0

   if config.run_distribute:

       rank = get_rank()

   save_ckpt_path = os.path.join(config.save_checkpoint_path, 'ckpt_' + str(rank) + '/')

   if not os.path.isdir(save_ckpt_path):

       os.mkdir(save_ckpt_path)

   for epoch in range(epoch_size):

       random.shuffle(idx_list)

       epoch_start = time.time()

       losses = []

       for in idx_list:

           feature = Tensor(np.load(os.path.join(features_path, f"feature_{j}.npy")))

           label = Tensor(np.load(os.path.join(features_path, f"label_{j}.npy")))

           losses.append(network(feature, label).asnumpy())

       epoch_mseconds = (time.time()-epoch_start) * 1000

       per_step_mseconds = epoch_mseconds / step_size

       print("epoch[{}/{}], iter[{}] cost: {:5.3f}, per step time: {:5.3f}, avg loss: {:5.3f}"\

      .format(epoch + 1, epoch_size, step_size, epoch_mseconds, per_step_mseconds,

               np.mean(np.array(losses))))

       if (epoch + 1% config.save_checkpoint_epochs == 0:

           save_checkpoint(net, os.path.join(save_ckpt_path, f"mobilenetv2_{epoch+1}.ckpt"))

   print("total cost {:5.4f} s".format(time.time() - start))

网络参数设定

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

config_cpu = ed({

   "num_classes"5,        # 类别数,根据实验数据集调整

   "image_height"224,     # 参与训练的图片高度

   "image_width"224,      # 参与训练的图片宽度

   "batch_size"64,        # 每批次样本数

   "epoch_size"20,        # 训练次数

   "warmup_epochs"0,      # 学习率变换步数

   "lr_init": .0,           # 初始化学习率

   "lr_end"0.0,           # 最终学习率

   "lr_max"0.01,          # 最大学习率

   "momentum"0.9,         # momentum优化器参数

   "weight_decay"4e-5,    # momentum优化器正则化参数

   "label_smooth"0.1,     # 损失函数参数:smooth factor

   "loss_scale"1024,      # "none"方式下损失函数参数,"backbone"方式下无用

   "save_checkpoint"True# 是否保存模型

   "save_checkpoint_epochs"5,    # "backbone"方式下,多少个epochs保存一次模型,"none"方式下无用

   "keep_checkpoint_max"20,      # "none"方式下最多保存多少个模型,"backbone"方式下无用.

   "save_checkpoint_path""./",   # 保存模型路径

   "platform": args.platform,      # 平台.可选"CPU", "GPU", "Ascend",这里固定"CPU"

   "run_distribute"False,        # 是否并行执行,"CPU"环境下默认False

   "activation""Softmax"         # 最后一层激活函数

})

注意: 验证实验batch_size设为1,其他参数与训练时一致。

微调训练

MobileNetV2做微调时,只需要运行train.py。目前运行train.py时仅支持单处理器。

运行train.py时需要传入dataset_pathplatform--run_distributefreeze_layerpretrain_ckpt五个参数。

  • --dataset_path:训练数据集地址,无默认值,用户训练时必须输入。

  • --platform:处理器类型,默认为Ascend,可以设置为CPUGPU

  • --freeze_layer:冻结网络,选填"none"或"backbone" 。"none"代表不冻结网络,"backbone" 代表冻结网络"backbone" 部分。CPU只支持微调head网络,不支持微调整个网络。所以这里填"backbone"。

  • --pretrain_ckpt:微调时,需要传入pretrain_checkpoint文件路径以加载预训练好的模型参数权重。

  • --run_distribute:是否使用分布式运行。默认为True。CPU不支持分布式运行。

方式一: args文件指定运行参数

  1. 打开src/args配置文件,更改train_parse_args函数为如下所示,以此来指定运行默认参数。

1

2

3

4

5

6

7

8

9

10

11

12

13

def train_parse_args():

   train_parser = argparse.ArgumentParser(description='Image classification trian')

   train_parser.add_argument('--platform'type=str, default="CPU", choices=("CPU""GPU""Ascend"), \

       help='run platform, only support CPU, GPU and Ascend')

   train_parser.add_argument('--dataset_path'type=str, default="../data/flower_photos_train"help='Dataset path')

   train_parser.add_argument('--pretrain_ckpt'type=str, default="../pretrain_checkpoint/mobilenetv2_cpu_gpu.ckpt"help='Pretrained checkpoint path \

      for fine tune or incremental learning')

   train_parser.add_argument('--freeze_layer'type=str, default="backbone", choices=["none""backbone"], \

       help="freeze the weights of network from start to which layers")

   train_parser.add_argument('--run_distribute'type=ast.literal_, default=Truehelp='Run distribute')

   train_args = train_parser.parse_args()

   train_args.is_training = True

   return train_args

  1. 打开命令框,cd到train.py文件目录。输入python train.py来训练网络。

方式二 命令行指定运行

1

python train.py --platform CPU --dataset_path ../data/flower_photos_train --freeze_layer backbone --pretrain_ckpt ../pretrain_checkpoint/mobilenetv2_cpu_gpu.ckpt --run_distribute False

运行Python文件时在交互式命令行中查看打印信息,输出结果如下:

train args: Namespace(dataset_path='../data/flower_photos_train', freeze_layer='backbone', is_training=True, platform='CPU', pretrain_ckpt='../pretrain_checkpoint/mobilenetv2_cpu_gpu.ckpt', run_distribute=True)
cfg: {'num_classes': 5, 'image_height': 224, 'image_width': 224, 'batch_size': 64, 'epoch_size': 20, 'warmup_epochs': 0, 'lr_init': 0.0, 'lr_end': 0.0, 'lr_max': 0.01, 'momentum': 0.9, 'weight_decay': 4e-05, 'label_smooth': 0.1, 'loss_scale': 1024, 'save_checkpoint': True, 'save_checkpoint_epochs': 5, 'keep_checkpoint_max': 20, 'save_checkpoint_path': './', 'platform': 'CPU', 'run_distribute': False, 'activation': 'Softmax'}
Complete the batch 1/56
Complete the batch 2/56
Complete the batch 3/56
...
Complete the batch 53/56
Complete the batch 54/56
Complete the batch 55/56
Complete the batch 56/56
epoch[1/20], iter[56] cost: 8033.059, per step time: 143.447, avg loss: 1.276
epoch[2/20], iter[56] cost: 7573.483, per step time: 135.241, avg loss: 0.880
epoch[3/20], iter[56] cost: 7492.869, per step time: 133.801, avg loss: 0.784
epoch[4/20], iter[56] cost: 7391.710, per step time: 131.995, avg loss: 0.916
epoch[5/20], iter[56] cost: 7421.159, per step time: 132.521, avg loss: 0.827
epoch[6/20], iter[56] cost: 7474.850, per step time: 133.479, avg loss: 0.828
epoch[7/20], iter[56] cost: 7415.375, per step time: 132.417, avg loss: 0.796
epoch[8/20], iter[56] cost: 7369.605, per step time: 131.600, avg loss: 0.714
epoch[9/20], iter[56] cost: 7457.325, per step time: 133.167, avg loss: 0.700
epoch[10/20], iter[56] cost: 7545.579, per step time: 134.742, avg loss: 0.739
epoch[11/20], iter[56] cost: 8036.823, per step time: 143.515, avg loss: 0.685
epoch[12/20], iter[56] cost: 7922.403, per step time: 141.471, avg loss: 0.666
epoch[13/20], iter[56] cost: 8000.985, per step time: 142.875, avg loss: 0.665
epoch[14/20], iter[56] cost: 7997.285, per step time: 142.809, avg loss: 0.657
epoch[15/20], iter[56] cost: 7973.143, per step time: 142.378, avg loss: 0.655
epoch[16/20], iter[56] cost: 7872.075, per step time: 140.573, avg loss: 0.649
epoch[17/20], iter[56] cost: 7925.634, per step time: 141.529, avg loss: 0.646
epoch[18/20], iter[56] cost: 7949.169, per step time: 141.949, avg loss: 0.645
epoch[19/20], iter[56] cost: 7692.628, per step time: 137.368, avg loss: 0.641
epoch[20/20], iter[56] cost: 7353.783, per step time: 131.318, avg loss: 0.640
total cost 156.8277 s

注意: 当改变batch_size、image_height、image_width参数时,需要删除 ../data/flower_photos_train_features 文件夹,重新生成。因为当特征文件夹(flower_photos_train_features)存在时,为了节约时间,运行时不再特征化(特征化与batch_size、image_height、image_width参数有关,不同的batch_size、image_height、image_width参数生成的特征文件不同)。

验证模型

使用验证集测试模型性能,需要输入必要参数,--platform默认为“Ascend”,可自行设置为"CPU"或"GPU"。最终在交互式命令行中展示标准输出与错误输出。

验证时,运行.py并且传入dataset_pathplatformpretrain_ckpt--run_distribute四个参数。

  • --dataset_path:测试数据集地址,无默认值,用户测试时必须输入。

  • --platform:处理器类型,默认为“Ascend”,可以设置为“CPU”或“GPU”。本实验设置为“CPU”

  • --pretrain_ckpt:pretrain_checkpoint文件路径以加载训练好的模型

  • --run_distribute:是否使用分布式运行。CPU不支持分布式运行,默认值为False。

方式一:略

方式二: 命令行指定运行

1

python .py --platform CPU --dataset_path ../data/flower_photos_test  --pretrain_ckpt ./ckpt_0/mobilenetv2_{epoch_num}.ckpt  --run_distribute False

运行Python文件时在交互式命令行中输出验证结果,结果如下:

result:{'acc': 0.9038461538461539}
pretrain_ckpt=./ckpt_0/mobilenetv2_20.ckpt

实验课程】MindSpore1.0:MobileNetV2网络实现微调(关键词:MobileNetV2、Fine Tune)相关推荐

  1. [网络安全课程实验]:基于nmap 的网络扫描和信息分析

    实验:基于nmap 的网络扫描和信息分析 一.实验目的 1)熟悉TCP.UDP协议基础: 2)掌握nmap扫描原理,能够使用命令行与图形界面进行信息收集: 3)熟练使用nmap常用参数对不同网络环境进 ...

  2. 计算机网络王盛邦pdf,依据网络的技术计算机CP网络实验课程体系.pdf

    第29卷第4期 实验室研究与探索 V01.29No.4 2010年4月 ANDEXPLORATIONINLABORATORY Apr.2010 RESEARCH 基于网络技术的计算机网络实验课程体系 ...

  3. springboot实验课程辅助管理系统 毕业设计-附源码191113

    实验课程辅助管理系统的设计与实现 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用.信息时代的到来已成为不可阻挡的时尚潮流 ...

  4. java计算机毕业设计物联网实验课程考勤网站源码+lw文档+系统+数据库

    java计算机毕业设计物联网实验课程考勤网站源码+lw文档+系统+数据库 java计算机毕业设计物联网实验课程考勤网站源码+lw文档+系统+数据库 本源码技术栈: 项目架构:B/S架构 开发语言:Ja ...

  5. java计算机毕业设计计算机实验课程学习系统源码+mysql数据库+系统+lw文档+部署

    java计算机毕业设计计算机实验课程学习系统源码+mysql数据库+系统+lw文档+部署 java计算机毕业设计计算机实验课程学习系统源码+mysql数据库+系统+lw文档+部署 本源码技术栈: 项目 ...

  6. MobileNet系列(2):MobileNet-V2 网络详解

    MobileNet-V2论文:Inverted Residuals and Linear Bottlenecks, MobileNet-V2网络是由google团队在2018年提出的,相比Mobile ...

  7. 用计算机做科学实验评课,科学小实验课程听课心得

    010在线为您甄选多篇描写科学小实验课程听课心得,科学小实验课程听课心得精选,科学小实验课程听课心得大全,有议论,叙事 ,想象等形式.文章字数有400字.600字.800字....缓存时间: 2021 ...

  8. 计算机网络实验仿真系统设计,计算机网络实验课程仿真系统平台的研究与设计...

    摘要: 随着计算机技术和网络技术不断发展,<计算机网络>课程成为高校许多工科专业的骨干必修课程.课程涉及到的知识内容主要以理论教学为基础,以实验实践为辅助教学.由于受实验室建设资金.网络环 ...

  9. 4. 吴恩达机器学习课程-作业4-神经网络学习

    fork了别人的项目,自己重新填写,我的代码如下 https://gitee.com/fakerlove/machine-learning/tree/master/code 代码原链接 文章目录 4. ...

最新文章

  1. js 为什么0.1+0.2不等于0.3
  2. Cpp / shared_ptr 配置删除器的方法
  3. 1096: 字符逆序
  4. 周鸿祎:希望将互联网基因与汽车制造企业基因进行重组
  5. 本地mysql数据库初始密码_忘记本地MySQL数据库密码的解决方法
  6. UVA - 473 Raucous Rocker 多维dp
  7. 微信公众平台开发实例 php,php微信公众平台开发类实例,php公众平台实例_PHP教程...
  8. 随心玩玩(七)ELK日志系统配置部署
  9. zbb20180921 spring事物的七种事物传播属性行为及五种隔离级别
  10. python之变量类型
  11. 【计算机网络】思科实验(8):网络地址转换之路由器动态NAT模拟
  12. win10 64bit 深度学习环境搭建完整版
  13. centos7安装lua查看lua版本
  14. 计算机网络第八章ppt,计算机网络-第八章.ppt
  15. MathType快捷键大全
  16. 屏蔽CSDN广告最佳方法
  17. Rime输入法之五笔自动上屏
  18. jsoup 使用教程
  19. CMMI评估--SCAMPI
  20. Py之pymssql:Python库之pymssql的简介、安装、使用方法之详细攻略

热门文章

  1. 几篇关于乐高现状的文章
  2. 实时观测程序运行状态——火焰图(Flame Graphs)
  3. iOS开发---如何查看iPhone手机的UUID
  4. PyQt5安装及Pycharm配置详细教程(win10)
  5. hp9000 e25服务器 显示器,DIY瞎折腾 篇十五:又挽救了一台显示器-HP 2011X-附翻车过程...
  6. 如何将html与css链接,如何将CSS链接到HTML
  7. 借助第八代智能英特尔® 酷睿™ i7 处理器和 Unreal Swarm* 的强大性能快速构建光照
  8. 数据科学中费米估算法的应用:如何估算一个城市加油站的数量?
  9. 元气骑士多终端跨网远程联机解决方案
  10. 苹果应用商店登陆服务器出现问题,这几天苹果应用商店登录不上,请问怎么回事?...