MXNet官方文档教程(7):训练和推断模型

    xiaoxiao2021-03-25  134

    训练和推断模型

    我们在module(缩写mod)包中模块化了经常用到的训练和推断模型的代码。这个包提供了中层和高层接口来执行已定义好的网络。

     

    基础用法

    准备

    在本部分教程中,我们将使用一个十类的多层感知机和一个综合数据集。

    import mxnet as mx

    from data_iter import  SyntheticData

     

    # mlp

    net = mx.sym.Variable('data')

    net = mx.sym.FullyConnected(net,name='fc1', num_hidden=64)

    net = mx.sym.Activation(net,name='relu1', act_type="relu")

    net = mx.sym.FullyConnected(net,name='fc2', num_hidden=10)

    net = mx.sym.SoftmaxOutput(net,name='softmax')

    # synthetic 10classes dataset with 128 dimension

    data = SyntheticData(10, 128)

    mx.viz.plot_network(net)

    建立模型

    最常应用的模块类是包括一个Symbol和一个或多个Executor的Module。

     

    为了构建一个模型,我们需要指定:

    l  symbol:网络符号

    l  context:执行设备(设备列表)

    l  data_names:数据变量名称列表

    l  label_names:标签变量名称列表

     

    可以通过参考data.ipynb获得后两个参数的详细及信息。这里我们仅有一个名称为data的数据,和一个名称为softmax_label的标签。softmax_label是由名称softname自动得到的名称,softname是我们指定的SoftmaxOutput 操作符的名称。

    mod= mx.mod.Module(symbol=net,                     context=mx.cpu(),                     data_names=['data'],                     label_names=['softmax_label'])

     

    训练,预测和评估

    Modules提供训练/预测/评估的高层API。为了适配一个模型,只需要使用fit函数和一些DataIters。

    # @@@ AUTOTEST_OUTPUT_IGNORED_CELL import logging logging.basicConfig(level=logging.INFO)   batch_size=32 mod.fit(data.get_iter(batch_size),         eval_data=data.get_iter(batch_size),         optimizer='sgd',         optimizer_params={'learning_rate':0.1},         eval_metric='acc',         num_epoch=5)

    输出

    INFO:root:Epoch[0] Train-accuracy=0.081250 INFO:root:Epoch[0] Time cost=0.103 INFO:root:Epoch[0] Validation-accuracy=0.228125 INFO:root:Epoch[1] Train-accuracy=0.178125 INFO:root:Epoch[1] Time cost=0.070 INFO:root:Epoch[1] Validation-accuracy=0.181250 INFO:root:Epoch[2] Train-accuracy=0.150000 INFO:root:Epoch[2] Time cost=0.061 INFO:root:Epoch[2] Validation-accuracy=0.112500 INFO:root:Epoch[3] Train-accuracy=0.196875 INFO:root:Epoch[3] Time cost=0.073 INFO:root:Epoch[3] Validation-accuracy=0.187500 INFO:root:Epoch[4] Train-accuracy=0.250000 INFO:root:Epoch[4] Time cost=0.076 INFO:root:Epoch[4] Validation-accuracy=0.078125

    为了使用一个模型进行预测,只需要使用predict函数和一个DataIter。它会收集并返回所有的预测结果。

    y= mod.predict(data.get_iter(batch_size)) 'shape of predict: %s'% (y.shape,)

    输出

    'shape of predict: (320L, 10L)'

    当预测结果过大以至于存储器无法满足时,另一个的方便的API是iter_predict:

    # @@@ AUTOTEST_OUTPUT_IGNORED_CELL for preds, i_batch, batch in mod.iter_predict(data.get_iter(batch_size)):     pred_label = preds[0].asnumpy().argmax(axis=1)     label = batch.label[0].asnumpy().astype('int32')     print('batch %d, accuracy %f'% (i_batch, float(sum(pred_label==label))/len(label)))

    输出

    batch 0, accuracy 0.062500 batch 1, accuracy 0.156250 batch 2, accuracy 0.187500 batch 3, accuracy 0.000000 batch 4, accuracy 0.062500 batch 5, accuracy 0.000000 batch 6, accuracy 0.062500 batch 7, accuracy 0.093750 batch 8, accuracy 0.062500 batch 9, accuracy 0.062500

    如果我们不需要预测输出结果,只需要在一个数据集上评估性能,我们可以使用score函数与一个DataIter以及一个EvalMetric:

    # @@@ AUTOTEST_OUTPUT_IGNORED_CELL mod.score(data.get_iter(batch_size), ['mse','acc'])

    输出

    [('mse', 27.438781929016113), ('accuracy', 0.115625)]

     

    保存与载入

    我们可以通过使用一个检查点回调函数,来保存每一轮训练的模型参数。

    # @@@ AUTOTEST_OUTPUT_IGNORED_CELL # construct a callback function to save checkpoints model_prefix='mx_mlp' checkpoint= mx.callback.do_checkpoint(model_prefix)   mod= mx.mod.Module(symbol=net) mod.fit(data.get_iter(batch_size), num_epoch=5, epoch_end_callback=checkpoint)

    输出

    INFO:root:Epoch[0] Train-accuracy=0.140625 INFO:root:Epoch[0] Time cost=0.062 INFO:root:Saved checkpoint to "mx_mlp-0001.params" INFO:root:Epoch[1] Train-accuracy=0.106250 INFO:root:Epoch[1] Time cost=0.075 INFO:root:Saved checkpoint to "mx_mlp-0002.params" INFO:root:Epoch[2] Train-accuracy=0.146875 INFO:root:Epoch[2] Time cost=0.084 INFO:root:Saved checkpoint to "mx_mlp-0003.params" INFO:root:Epoch[3] Train-accuracy=0.140625 INFO:root:Epoch[3] Time cost=0.077 INFO:root:Saved checkpoint to "mx_mlp-0004.params" INFO:root:Epoch[4] Train-accuracy=0.190625 INFO:root:Epoch[4] Time cost=0.073 INFO:root:Saved checkpoint to "mx_mlp-0005.params"

    使用load_checkpoint函数来载入保存的模型参数。load_checkpoint载入符号和与其相关的参数。之后,我们可以将载入的参数设置到模型中。

    sym, arg_params, aux_params = mx.model.load_checkpoint(model_prefix,3) print(sym.tojson()== net.tojson())   # assign the loaded parameters to the module mod.set_params(arg_params, aux_params)

    输出

    True

    或者我们只是想在保存的检查点继续训练,我们可以直接使用fit函数代替set_params函数传递载入的参数。这样fit函数就知道使用这些参数开始训练,而不是随机初始化参数。我们也可以设置begin_epoch ,这样fit函数知道我们是在一个之前保存的训练轮次上继续的。

    # @@@ AUTOTEST_OUTPUT_IGNORED_CELL mod= mx.mod.Module(symbol=sym) mod.fit(data.get_iter(batch_size),         num_epoch=5,         arg_params=arg_params,         aux_params=aux_params,         begin_epoch=3)

    输出

    INFO:root:Epoch[3] Train-accuracy=0.115625 INFO:root:Epoch[3] Time cost=0.064 INFO:root:Epoch[4] Train-accuracy=0.115625 INFO:root:Epoch[4] Time cost=0.058

     

     

    使用Module作为计算“机”

    我们已经知道如何使用module来进行基本的训练和推断。现在我们将展示module的一个更加灵活的用法。

     

    一个module代表着一个计算组成。module的设计目的就是抽象一个可以接收Symbol程序和数据的计算“机”。然后我们可以在其上执行正向传播算法、反向传播算法、更新参数等。

     

    我们致力于使API简单灵活,尤其是当我们需要使用必要的API来处理多模型的情况时(例如随机深度网络)。

     

    module包括以下声明:

    l 初始化声明:此时还未为其分配初始化空间,也还未准备好开始计算。

    l 绑定:输入输出的大小和参数都已知,内存被分配,为计算做好了准备。

    l 变量初始化:对于带参数的module,在初始化参数之前执行计算可能会导致未定义的输出。

    l 优化器安装:优化器可被安装到一个module上。之后,在计算出梯度后,模型的参数可以根据优化器进行更新。

    以下代码实现了一个简化的fit()。在此我们用到的初始化器(Initalizer)、优化器(Optimizer)和度量(Metric)在其他的教程中有所解释。

    # @@@ AUTOTEST_OUTPUT_IGNORED_CELL # initial state mod= mx.mod.Module(symbol=net)   # bind, tell the module the data and label shapes, so # that memory could be allocated on the devices for computation train_iter= data.get_iter(batch_size) mod.bind(data_shapes=train_iter.provide_data, label_shapes=train_iter.provide_label)   # init parameters mod.init_params(initializer=mx.init.Xavier(magnitude=2.))   # init optimizer mod.init_optimizer(optimizer='sgd', optimizer_params=(('learning_rate',0.1), ))   # use accuracy as the metric metric= mx.metric.create('acc')   # train one epoch, i.e. going over the data iter one pass for batch in train_iter:     mod.forward(batch, is_train=True)       # compute predictions     mod.update_metric(metric, batch.label)  # accumulate prediction accuracy     mod.backward()                          # compute gradients     mod.update()                            # update parameters using SGD     # training accuracy print(metric.get())

    输出

    ('accuracy', 0.59375)

    除了优化器之外,module还提供了大量有用的信息。

     

    基本名称:

    l data_name:所需数据的名称的string列表。

    l output_name:输出名称的string列表。

    声明信息:

    l binded:bool类型,表示计算所需的存储空间是否已被分配。

    l for_training:module是否已经绑定了训练数据(如果已被分配空间)。

    l params_initialized:bool类型,表示模型的参数是否已经初始化。

    l inputs_need_grad:bool类型,表示是否需要输入数据的梯度。在实现模型组成时有用。

    输入输出信息:

    l data_shape:(name,shape)列表。理论上,只要内存分配好了,我们可以直接提供数据数组。但是在数据并行的情况下,数据数组大小在外界世界看了可能不是同样的大小。

    l label_shape:(name,shape)列表。这个变量有可能为空如果模型不需要标签(例如在顶层不包含损失函数loss function),或者module没被绑定为训练。

    l output_shanpe:module输出的(name,shape)列表。

    参数变量(模型参数):

    l get_params():返回(arg_params,aux_params)元组。每一个元素为一个从名称到NDArray映射的字典。这些NDArray通常位于CPU。真实的用于计算的参数也可能位于其他设备(GPU),这个函数将返回最新的参数(的复制)。

    l get_outputs():获取前一个操作的输出。

    l get_input_grads():获取之前由反向传播操作计算出的输入的梯度。

    print((mod.data_shapes, mod.label_shapes, mod.output_shapes)) print(mod.get_params())

    输出

    ([DataDesc[data,(32, 128),<type 'numpy.float32'>,NCHW]], [DataDesc[softmax_label,(32,),<type 'numpy.float32'>,NCHW]], [('softmax_output', (32, 10L))]) ({'fc2_bias': <NDArray 10 @cpu(0)>, 'fc2_weight': <NDArray 10x64 @cpu(0)>, 'fc1_bias': <NDArray 64 @cpu(0)>, 'fc1_weight': <NDArray 64x128 @cpu(0)>}, {})

     

    转载请注明原文地址: https://ju.6miu.com/read-3545.html

    最新回复(0)