网络模型类

数据处理 环境准备 模型导出 模型训练 初级 中级 高级

Q:MindSpore中model.traindataset_sink_mode参数该如何理解?

A:当dataset_sink_mode=True时,数据处理会和网络计算构成Pipeline方式,即:数据处理在逐步处理数据时,处理完一个batch的数据,会把数据放到一个队列里,这个队列用于缓存已经处理好的数据,然后网络计算从这个队列里面取数据用于训练,那么此时数据处理与网络计算就Pipeline起来了,整个训练耗时就是数据处理/网络计算耗时最长的那个。

dataset_sink_mode=False时,数据处理会和网络计算构成串行的过程,即:数据处理在处理完一个batch后,把这个batch的数据传递给网络用于计算,在计算完成后,数据处理再处理下一个batch,然后把这个新的batch数据传递给网络用于计算,如此的循环往复,直到训练完。该方法的总耗时是数据处理的耗时+网络计算的耗时=训练总耗时。


Q:MindSpore能否支持按批次对不同尺寸的图片数据进行训练?

A:你可以参考yolov3对于此场景的使用,里面有对于图像的不同缩放,脚本见yolo_dataset


Q:通过Hub可以使用GPU加载vgg16模型以及是否可以做迁移模型吗?

A:请手动修改规避,修改如下两点即可:

# 增加**kwargs参数:如下
def vgg16(num_classes=1000, args=None, phase="train", **kwargs):
# 增加**kwargs参数:如下
net = Vgg(cfg['16'], num_classes=num_classes, args=args, batch_norm=args.batch_norm, phase=phase, **kwargs)

Q:如何得到VGG模型中间层特征?

A:你好,获取网络中间层的特征,其实跟具体框架没有太大关系了。torchvison里定义的vgg模型,可以通过features字段获取”中间层特征”,torchvisonvgg源码如下:

class VGG(nn.Module):

    def __init__(self, features, num_classes=1000, init_weights=True):
        super(VGG, self).__init__()
        self.features = features
        self.avgpool = nn.AdaptiveAvgPool2d((7, 7))

在MindSpore的ModelZoo里定义的vgg16,可以通过layers字段获取,如下:

network = vgg16()
print(network.layers)

Q:使用MindSpore进行模型训练时,CTCLoss的输入参数有四个:inputs, labels_indices, labels_values, sequence_length,如何使用CTCLoss进行训练?

A:定义的model.train接口里接收的dataset可以是多个数据组成,形如(data1, data2, data3, …),所以dataset是可以包含inputs,labels_indices,labels_values,sequence_length的信息的。只需要定义好相应形式的dataset,传入model.train里就可以。具体的可以了解下相应的数据处理接口


Q:模型转移时如何把PyTorch的权重加载到MindSpore中?

A:首先输入PyTorch的pth文件,以ResNet-18为例,MindSpore的网络结构和PyTorch保持一致,转完之后可直接加载进网络,这边参数只用到BNConv2D,若有其他层ms和PyTorch名称不一致,需要同样的修改名称。


Q:模型已经训练好,如何将模型的输出结果保存为文本或者npy的格式?

A:您好,我们网络的输出为Tensor,需要使用asnumpy()方法将Tensor转换为numpy,再进行下一步保存。具体可参考:

out = net(x)

np.save("output.npy", out.asnumpy())

Q:使用MindSpore做分割训练,必须将数据转为MindRecords吗?

A:build_seg_data.py是将数据集生成MindRecord的脚本,可以直接使用/适配下你的数据集。或者如果你想尝试自己实现数据集的读取,可以使用GeneratorDataset自定义数据集加载。

GenratorDataset 示例

GenratorDataset API说明


Q:MindSpore可以读取TensorFlow的ckpt文件吗?

A:MindSpore的ckpt和TensorFlow的ckpt格式是不通用的,虽然都是使用protobuf协议,但是proto的定义是不同的。当前MindSpore不支持读取TensorFlow或PyTorch的ckpt文件。


Q:如何不将数据处理为MindRecord格式,直接进行训练呢?

A:可以使用自定义的数据加载方式 GeneratorDataset,具体可以参考数据集加载文档中的自定义数据集加载。


Q:MindSpore现支持直接读取哪些其他框架的模型和哪些格式呢?比如PyTorch下训练得到的pth模型可以加载到MindSpore框架下使用吗?

A: MindSpore采用protbuf存储训练参数,无法直接读取其他框架的模型。对于模型文件本质保存的就是参数和对应的值,可以用其他框架的API将参数读取出来之后,拿到参数的键值对,然后再加载到MindSpore中使用。比如想用其他框架训练好的ckpt文件,可以先把参数读取出来,再调用MindSpore的save_checkpoint接口,就可以保存成MindSpore可以读取的ckpt文件格式了。


Q:用MindSpore训练出的模型如何在Ascend 310上使用?可以转换成适用于HiLens Kit用的吗?

A:Ascend 310需要运行专用的OM模型,先使用MindSpore导出ONNX或AIR模型,再转化为Ascend 310支持的OM模型。具体可参考多平台推理。可以,HiLens Kit是以Ascend 310为推理核心,所以前后两个问题本质上是一样的,需要转换为OM模型.


Q:MindSpore如何进行参数(如dropout值)修改?

A:在构造网络的时候可以通过 if self.training: x = dropput(x),验证的时候,执行前设置network.set_train(mode_false),就可以不适用dropout,训练时设置为True就可以使用dropout。


Q:从哪里可以查看MindSpore训练及推理的样例代码或者教程?

A:可以访问MindSpore官网教程训练MindSpore官网教程推理


Q:MindSpore支持哪些模型的训练?

A:MindSpore针对典型场景均有模型训练支持,支持情况详见Release note


Q:MindSpore有哪些现成的推荐类或生成类网络或模型可用?

A:目前正在开发Wide & Deep、DeepFM、NCF等推荐类模型,NLP领域已经支持Bert_NEZHA,正在开发MASS等模型,用户可根据场景需要改造为生成类网络,可以关注MindSpore Model Zoo


Q:MindSpore模型训练代码能有多简单?

A:除去网络定义,MindSpore提供了Model类的接口,大多数场景只需几行代码就可完成模型训练。


Q:如何使用MindSpore拟合\(f(x)=a \times sin(x)+b\)这类函数?

A:以下拟合案例是基于MindSpore线性拟合官方案例改编而成。

# The fitting function is:f(x)=2*sin(x)+3.
import numpy as np
from mindspore import dataset as ds
from mindspore.common.initializer import Normal
from mindspore import nn, Model, context
from mindspore.train.callback import LossMonitor

context.set_context(mode=context.GRAPH_MODE, device_target="CPU")

 def get_data(num, w=2.0, b=3.0):
    # f(x)=w * sin(x) + b
    # f(x)=2 * sin(x) +3
    for i in range(num):
        x = np.random.uniform(-np.pi, np.pi)
        noise = np.random.normal(0, 1)
        y = w * np.sin(x) + b + noise
        yield np.array([np.sin(x)]).astype(np.float32), np.array([y]).astype(np.float32)

def create_dataset(num_data, batch_size=16, repeat_size=1):
    input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data','label'])
    input_data = input_data.batch(batch_size)
    input_data = input_data.repeat(repeat_size)
    return input_data

class LinearNet(nn.Cell):
    def __init__(self):
        super(LinearNet, self).__init__()
        self.fc = nn.Dense(1, 1, Normal(0.02), Normal(0.02))

    def construct(self, x):
        x = self.fc(x)
        return x

if __name__ == "__main__":
    num_data = 1600
    batch_size = 16
    repeat_size = 1
    lr = 0.005
    momentum = 0.9

    net = LinearNet()
    net_loss = nn.loss.MSELoss()
    opt = nn.Momentum(net.trainable_params(), lr, momentum)
    model = Model(net, net_loss, opt)

    ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size)

    model.train(1, ds_train, callbacks=LossMonitor(), dataset_sink_mode=False)

    print(net.trainable_params()[0], "\n%s" % net.trainable_params()[1])

Q:如何使用MindSpore拟合\(f(x)=ax^2+bx+c\)这类的二次函数?

A:以下代码引用自MindSpore的官方教程的代码仓

在以下几处修改即可很好的拟合\(f(x)=ax^2+bx+c\)

  1. 数据集生成。

  2. 拟合网络。

  3. 优化器。

修改的详细信息如下,附带解释。

# Since the selected optimizer does not support CPU, so the training computing platform is changed to GPU, which requires readers to install the corresponding GPU version of MindSpore.
context.set_context(mode=context.GRAPH_MODE, device_target="GPU")

# Assuming that the function to be fitted this time is f(x)=2x^2+3x+4, the data generation function is modified as follows:
def get_data(num, a=2.0, b=3.0 ,c = 4):
    for i in range(num):
        x = np.random.uniform(-10.0, 10.0)
        noise = np.random.normal(0, 1)
        # The y value is generated by the fitting target function ax^2+bx+c.
        y = x * x * a + x * b + c + noise
        # When a*x^2+b*x+c is fitted, a and b are weight parameters and c is offset parameter bias. The training data corresponding to the two weights are x^2 and x respectively, so the data set generation mode  is changed as follows:
        yield np.array([x*x, x]).astype(np.float32), np.array([y]).astype(np.float32)

def create_dataset(num_data, batch_size=16, repeat_size=1):
    input_data = ds.GeneratorDataset(list(get_data(num_data)), column_names=['data','label'])
    input_data = input_data.batch(batch_size)
    input_data = input_data.repeat(repeat_size)
    return input_data

class LinearNet(nn.Cell):
    def __init__(self):
        super(LinearNet, self).__init__()
        # Because the full join function inputs two training parameters, the input value is changed to 2, the first Nomral(0.02) will automatically assign random weights to the input two parameters, and the second Normal is the random bias.
        self.fc = nn.Dense(2, 1, Normal(0.02), Normal(0.02))

    def construct(self, x):
        x = self.fc(x)
        return x

if __name__ == "__main__":
    num_data = 1600
    batch_size = 16
    repeat_size = 1
    lr = 0.005
    momentum = 0.9

    net = LinearNet()
    net_loss = nn.loss.MSELoss()
    # RMSProp optimalizer with better effect is selected for quadratic function fitting, Currently, Ascend and GPU computing platforms are supported.
    opt = nn.RMSProp(net.trainable_params(), learning_rate=0.1)
    model = Model(net, net_loss, opt)

    ds_train = create_dataset(num_data, batch_size=batch_size, repeat_size=repeat_size)
    model.train(1, ds_train, callbacks=LossMonitor(), dataset_sink_mode=False)

    print(net.trainable_params()[0], "\n%s" % net.trainable_params()[1])

Q:在使用ckpt或导出模型的过程中,报Protobuf内存限制错误,如何处理?

A:当单条Protobuf数据过大时,因为Protobuf自身对数据流大小的限制,会报出内存限制的错误。这时可通过设置环境变量PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python解除限制。

Q: 训练nlp类网络,当使用第三方组件gensim时,可能会报错:ValueError,如何解决?

A:以下为报错信息:

>>> import gensim
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/miniconda3/envs/ci39_cj/lib/python3.9/site-packages/gensim/__init__.py", line 11, in <module>
    from gensim import parsing, corpora, matutils, interfaces, models, similarities, utils  # noqa:F401
  File "/home/miniconda3/envs/ci39_cj/lib/python3.9/site-packages/gensim/corpora/__init__.py", line 6, in <module>
    from .indexedcorpus import IndexedCorpus  # noqa:F401 must appear before the other classes
  File "/home/miniconda3/envs/ci39_cj/lib/python3.9/site-packages/gensim/corpora/indexedcorpus.py", line 14, in <module>
    from gensim import interfaces, utils
  File "/home/miniconda3/envs/ci39_cj/lib/python3.9/site-packages/gensim/interfaces.py", line 19, in <module>
    from gensim import utils, matutils
  File "/home/miniconda3/envs/ci39_cj/lib/python3.9/site-packages/gensim/matutils.py", line 1024, in <module>
    from gensim._matutils import logsumexp, mean_absolute_difference, dirichlet_expectation
  File "gensim/_matutils.pyx", line 1, in init gensim._matutils
ValueError: numpy.ndarray size changed, may indicate binary incompatibility. Expected 88 from C header, got 80 from PyObject

报错原因请参考gensim官网,或者numpy官网:

解决方案: 方法一:重新安装numpy及gensim, 执行命令:pip uninstall gensim numpy -y && pip install numpy gensim ; 方法二:如果还是有问题,请删除wheel安装包的缓存文件,然后执行方法一(wheel安装包缓存目录为:~/.cache/pip/wheels)。