MindSpore ResNet50性能调优分享

本文介绍了使用MindSpore进行ResNet50网络性能调优的过程。通过MindInsight的Profiler模块分析,发现在数据处理阶段存在性能瓶颈。调整map算子的num_parallel_workers参数至12后,成功将单step时间从90ms降低到18.07ms,显著提升了训练效率。
摘要由CSDN通过智能技术生成

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

作者:ttandtt

网络训练跑通了,精度OK了,对很多人来说可能已经万事大吉了,但如果网络需要在生产环境跑,还有一个点不得不去关注,那就是性能。对于大的网络,训练一次可能需要上月的时间,这时候就真正的体会到时间就是金钱了。提高网络的性能,缩短训练的时间,可能会节省上百万的金钱。
下面给大家介绍下之前对ResNet50网络的性能调优案例,希望能帮助到大家。调优过程中用到了MindSpore中的调试调优工具:MindInsight,不仅可以调试性能,还可以调试精度,感兴趣的同学可以到官网了解下:https://www.mindspore.cn/mindinsight

现象

我们将ResNet50网络batch size设置为32(代码可参考MindSpore ModelZoo中的ResNet50网络,当前代码已经是调优后的。本次主要给大家介绍下调优的经历),跑网络训练后发现单step时间约为90ms,性能很差。通常batch size为32时,单step耗时应在20ms以内。

原因分析

分析过程中,我们主要用到了MindInsight中的Profiler模块。如何跑Profiler收集性能数据大家可以到官网上查看教程,此次不再赘述。
将性能数据用UI页面可视化后,我们开始了此次的性能调优过程。
首先我们先看页面里的迭代轨迹部分。迭代轨迹将训练过程分为了3部分:迭代间隙表示前一个迭代结束到后一个迭代开始的时间,该段时间可以认为是后一个迭代等待数据的时间;前反向时间表示的是真正的前反向计算的时间;迭代拖尾表示的是反向完成后进行梯度更新的时间。从下图中我们看到迭代间隙的时间占了整个迭代的很大部分,因此我们需要重点关注数据处理的性能。

第二步,我们到数据准备详情页面,确认数据处理是否是性能瓶颈点。查看数据准备详情页面中的迭代间隙标签页,我们观察到,数据队列在前期有较多的数据,后期数据的个数变为0,分析原因是前期在图编译阶段已经开始了数据集的加载和增强,队列中随即缓存了多条数据;而后期正常训练开始后,队列中的数据被消费的速度要快于被生产的速度,因此数据队列逐渐变为空,说明此时数据变成了瓶颈。观察主机队列也是同样的情况。综合分析,正常训练过程中,数据处理为性能瓶颈点。

第三步,我们到数据准备详情页面中的数据处理标签页来查看具体问题。通过观察数据处理标签页的算子间队列关系,我们发现,Queue_3及其之后的队列使用率较低,即MapOp_3作为生产者生产数据的速度较慢,因此可以判定MapOp_3的性能还有优化空间,需要对该算子进行性能优化。

我们查看了数据处理的代码,发现map算子的num_parallel_workers参数没有设置,而该参数的默认为1,代码如下:

if do_train:
    trans = [
        C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
        C.RandomHorizontalFlip(prob=0.5),
        C.Normalize(mean=mean, std=std),
        C.HWC2CHW()
    ]
else:
    trans = [
        C.Decode(),
        C.Resize(256),
        C.CenterCrop(image_size),
        C.Normalize(mean=mean, std=std),
        C.HWC2CHW()
    ]

data_set = data_set.map(operations=trans, input_columns="image")

因此我们分析可以尝试提高该算子的并发数来提高网络的性能。

效果验证

我们将num_parallel_workers参数调整为12后,再次运行训练脚本,优化参考代码如下:
data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=12)
通过MindInsight性能分析页面观察迭代轨迹,可以看到迭代间隙时长由72.8ms缩短到0.25ms,单step时长由90ms缩短到18.07ms。

至此,我们完成了ResNet50网络的性能调优工作。

总结

MindInsight调优工具对性能调优和精度调优提供了大量的数据,并形成了一套完整的方法论,需要的同学可以参考奥。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您的问题是关于MindSpore框架中ResNet50模型在CIFAR-10数据集上的应用。 ResNet50一个深度卷积神经网络模型,用于图像分类任务。CIFAR-10是一个经典的图像分类数据集,包含10个类别的60000张32x32的彩色图像。 在MindSpore框架中,您可以使用ResNet50模型对CIFAR-10数据集进行训练和测试。首先,您需要准备好CIFAR-10数据集并将其转换为MindSpore支持的数据格式。然后,您可以使用MindSpore提供的ResNet50模型进行训练和测试。 以下是一个示例代码片段,演示如何在MindSpore中使用ResNet50模型对CIFAR-10数据集进行训练和测试: ``` import mindspore.nn as nn import mindspore.ops.operations as P from mindspore import Model from mindspore import Tensor from mindspore import context from mindspore import dataset as ds from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor from mindspore.train.serialization import load_checkpoint, load_param_into_net from mindspore.nn.metrics import Accuracy # Define the ResNet50 model class ResNet50(nn.Cell): def __init__(self, num_classes=10): super(ResNet50, self).__init__() self.resnet50 = nn.ResNet50(num_classes=num_classes) def construct(self, x): x = self.resnet50(x) return x # Load the CIFAR-10 dataset data_home = "/path/to/cifar-10/" train_data = ds.Cifar10Dataset(data_home, num_parallel_workers=8, shuffle=True) test_data = ds.Cifar10Dataset(data_home, num_parallel_workers=8, shuffle=False) # Define the hyperparameters learning_rate = 0.1 momentum = 0.9 epoch_size = 200 batch_size = 32 # Define the optimizer optimizer = nn.Momentum(filter(lambda x: x.requires_grad, resnet50.get_parameters()), learning_rate, momentum) # Define the loss function loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') # Define the model net = ResNet50() # Define the model checkpoint config_ck = CheckpointConfig(save_checkpoint_steps=1000, keep_checkpoint_max=10) ckpt_cb = ModelCheckpoint(prefix="resnet50", directory="./checkpoints/", config=config_ck) # Define the training dataset train_data = train_data.batch(batch_size, drop_remainder=True) # Define the testing dataset test_data = test_data.batch(batch_size, drop_remainder=True) # Define the model and train it model = Model(net, loss_fn=loss_fn, optimizer=optimizer, metrics={"Accuracy": Accuracy()}) model.train(epoch_size, train_data, callbacks=[ckpt_cb, LossMonitor()], dataset_sink_mode=True) # Load the trained model and test it param_dict = load_checkpoint("./checkpoints/resnet50-200_1000.ckpt") load_param_into_net(net, param_dict) model = Model(net, loss_fn=loss_fn, metrics={"Accuracy": Accuracy()}) result = model.eval(test_data) print("Accuracy: ", result["Accuracy"]) ``` 注意:在上述示例代码中,我们使用的是ResNet50网络的一个变体,该变体适用于CIFAR-10数据集的图像大小。如果您想使用标准的ResNet50网络,您需要调整输入图像的大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值