【经验分享】mindspore模型开发&modelarts;多卡训练经验分享

转载地址:https://bbs.huaweicloud.com/f...
作者: 陈霸霸
开发一个模型的训练部分大致分为数据处理,网络,损失函数,训练。由于我们主要是实现的从pytorch到mindspore的复现,所以两者相同的部分就不再详细介绍。
1.数据处理:

在图像领域常用的数据集可以直接调用mindspore.dateset接口实现,非常方便。大家可以在mindspore官网的编程指南查到。其他的一些数据集我们可以制作成MindRecord(MindSpore的自研数据格式,具有读写高效、易于分布式处理等优势。),会在当前目录下生成.mindrecord类型文件。也可以调用mindspore.dateset.GeneratorDataset进行自定义加载。使用MindRecord能够获得更好的性能提升,缺点就是文件大小比原数据集要大,并且如果图片个数多的话,在制作的过程中我是用cv.imread读的,需要一次性读完再进行处理,所以处理的速度比较慢,每次数据处理改动的话就要重新进行制作。总之,如果数据集较大的话还是建议调用GeneratorDataset。

2.网络:
实现的话和pytorch大致相同,但是在训练时,如果采用图模式,mindspore会先进行图编译,在本地会生成kernel_meta,然后才开始跑网络,所以一开始会比较慢。

3.损失函数:
和pytorch不同,如果要自定义损失函数,也需要像写网络那样,继承nn.cell,定义init以及construct。在损失函数里只能用mindspore里的操作,并且需要在init里初始化操作,在construct里调用。在接口转化部分,大部分可以通过编程指南里的算子匹配里找到。这里说下一些找不到的:

pytorch里的Interpolate可以通过ops.ResizeBilinear实现;
pytorch里两个张量a,b实现a[b>0]这个操作mindspore里可以用select算子,例如:
cond = Tensor([True, False])
x = Tensor([4,9])#你的张量A
y = Tensor([0,0]) #临时
select = P.Select()
z=select(cond,x,y),最后虽然shape和pytorch不一样,但最后会进行求和啥的;
损失中只计算一部分的值,如(10,1)只需要计算其中的5个值的损失。这种情况可以将其他值变成0,使用equal算子可以得到要计算的index,使用select算子可以吧不需要的值变成0。使用算子其中需要注意Tensor的数据类型,有的只支持float。
使用cast算子就可以吧Tensor数据类型相互转换;
4.训练:
训练主要步骤为:定义网络,定义损失函数,定义优化器,正常情况可以直接调用model.train将网络,损失函数以及优化器同时封装起来进行训练。如果损失函数的输入参数不是两个例如img,label还需要自定义WithLossCell将网络和损失函数结合起来,调用TrainOneStepCell将优化器和网络以及损失函数结合起来最后传到model.train里。

5.自定义callback函数使用技巧:
Mindspore给的Callback函数确实好用,申明使用,快速就可以使用,但同时对于不同网络,不同人来说,个性化需求会无法满足。所以有时候使用自定义Callback可能对于一些刚接触Mindspore的人来说更可以发现模型中的问题。

官方Callback类:
一般使用官方定义好的Callback函数使用方法:
1.png
2.png
3.png
运行结果如下:
4.png
自定义Callback:
一般就我而言,使用就是后面的六个函数,主要就是step_begin,step_end。从函数名就知道该函数是什么时候调用的,这里我就不做更多说明。Callback主要就是要对run_context内容要有所了解,这个可以自行去看源码。我这里主要就是想了解自己运行中每个epoch每步对平均损失的影响,就使用了这个自定义。
5.png
6.png
7.png
运行结果如下:
8.png
【【经验分享】mindspore模型开发&modelarts;多卡训练经验分享】6.modelarts多卡训练:
在云上训练和本地最大不同就是需要调用mix接口将数据集等文件从obs通过mix接口传到catch里,训练完成得到ckpt文件再通过mix接口传到obs桶里。

    推荐阅读