MXNet官方文档中文版教程(6):线性回归(LinearRegression)

文档英文原版参见Linear Regression

在本教程中,我们将介绍如何使用MXNet API实现线性回归。

我们尝试学习的函数是: y=x1+2x2 ,其中 (x1,x2) 是输入特征,y是相应的标签。

前提条件

为了完成以下教程,我们需要:

pip install jupyter

数据准备

在MXNet中,数据通过数据迭代器输入。 这里我们将说明如何将数据集编码成MXNet可以使用的迭代器。 示例中使用的数据由具有相应整数标签的2维数据点组成。

#Training data
train_data = np.random.uniform(0, 1, [100, 2])
train_label = np.array([train_data[i][0] + 2 * train_data[i][1] for i in range(100)])
batch_size = 1

#Evaluation Data
eval_data = np.array([[7,2],[6,10],[12,2]])
eval_label = np.array([11,26,16])

一旦我们准备好数据,我们需要将其放入一个迭代器中,并指定诸如batch_sizeshuffle 之类的参数。 batch_size 指定每次更新其参数时输入到模型中的样本数,shuffle 将输入给模型的样本数的顺序随机化。

train_iter = mx.io.NDArrayIter(train_data,train_label, batch_size, shuffle=True,label_name='lin_reg_label')
eval_iter = mx.io.NDArrayIter(eval_data, eval_label, batch_size, shuffle=False)

在上面的例子中,我们已经使用了NDArrayIter,它既可以用于迭代numpy ndarrays,也可以用于迭代MXNet NDArrays。 一般来说,MXNet中有不同类型的迭代器,你可以根据正在处理的数据类型使用迭代器。

MXNet类

  1. IO:IO类用于数据,进行批量输入数据和混洗数据等操作。
  2. Symbol:实际的MXNet神经网络由符号组成。 MXNet具有不同类型的符号,包括数据输入的多种占位符,神经网络层和操作NDArrays的操作符。
  3. Module:MXNet中的模块类用于定义整体计算。 它使用我们要训练的模型,训练输入(数据和标签)以及一些附加参数(如学习率和优化算法)来进行初始化。

定义模型

MXNet使用符号来定义模型。符号是构建模块的组成部分。 符号用于定义:

  1. 变量:变量是未来数据的占位符。该符号用于定义在开始训练时用于将来填补训练数据/标签的节点。
  2. 神经网络层:网络层或任何其他类型的模型也由符号定义。 这样的符号将一个或多个之前的符号作为输入,对它们执行一些变换,并创建一个或多个输出。一个这样的例子是FullyConnected 符号,它定义了神经网络的全连接层。
  3. 输出:输出符号是MXNet定义损失函数的方式。它们后面加上“输出”一词(例如SoftmaxOutput 层)。 你也可以创建自己的损失函数。现有的损失函数如:LinearRegressionOutput,它计算输入符号与提供的标签之间的L2-loss; SoftmaxOutput 计算分类交叉熵。

上面描述的和其他符号链接在一起构成一个符号的输出,这个输出又作为下一个输入,从而构建网络拓扑结构。

X = mx.sym.Variable('data')
Y = mx.symbol.Variable('lin_reg_label')
fully_connected_layer  = mx.sym.FullyConnected(data=X, name='fc1', num_hidden = 1)
lro = mx.sym.LinearRegressionOutput(data=fully_connected_layer, label=Y, name="lro")

上述网络使用了以下层:

  1. FullyConnected:全连接符号表示神经网络的全连接层(没有使用任何激活),这本质上仅仅是输入特征的线性回归。 它需要以下参数:
    • data :层的输入(指定在此输出的符号)
    • num_hidden:层中隐藏的神经元数量,与层输出的维数相同
  2. LinearRegressionOutput :MXNet中计算训练损失的输出层,这是模型预测中错误率的度量。 训练的目标是尽量减少训练损失。在我们的示例中,LinearRegressionOutput 层根据其输入和提供的标签来计算L2-loss。 此层的参数有:
    • data : 层的输入(指定在此输出的符号)
    • label : 我们将层的输入与训练标签做比较计算L2-loss

关于命名约定的注意事项:标签变量的名称应与传递给训练数据迭代器的label_name 参数相同。默认值是softmax_label,但是我们已经在本教程中将其更新为lin_reg_label,你可以在Y = mx.symbol.Variable(’lin_reg_label’)train_iter = mx.io.NDArrayIter(…,label_name =’lin_reg_label’) 看到。

扫描二维码关注公众号,回复: 2490590 查看本文章

最后,网络被输入到一个模块,在模块中指定需要最小化输出的符号(本例中是lro 或者lin_reg_output),优化时要使用的学习率,以及训练模型的批次。

model = mx.mod.Module(
    symbol = lro ,
    data_names=['data'],
    label_names = ['lin_reg_label']# network structure
)

我们可以通过绘图来可视化我们创建的网络:

mx.viz.plot_network(symbol=lro)

训练模型

一旦我们定义了模型结构,下一步是训练模型的参数来拟合训练数据。可以使用Module 类的fit() 函数来完成。

model.fit(train_iter, eval_iter,
            optimizer_params={'learning_rate':0.005, 'momentum': 0.9},
            num_epoch=50,
            eval_metric='mse',
            batch_end_callback = mx.callback.Speedometer(batch_size, 2))

使用训练好的模型(测试和预测)

当我们有一个训练好的模型,我们可以用它来做几件事情 - 我们可以使用它来预测,或者我们可以在测试集上评估训练的模型,后者如下:

model.predict(eval_iter).asnumpy()

我们也可以根据一些指标来评估我们的模型。在这个例子中,我们在验证集上评估我们的模型的均方误差(MSE)。

metric = mx.metric.MSE()
model.score(eval_iter, metric)

让我们尝试加一些噪声给验证集,看看MSE如何改变:

eval_data = np.array([[7,2],[6,10],[12,2]])
eval_label = np.array([11.1,26.1,16.1]) #Adding 0.1 to each of the values
eval_iter = mx.io.NDArrayIter(eval_data, eval_label, batch_size, shuffle=False)
model.score(eval_iter, metric)

我们还可以创建自定义指标并使用它来评估模型

猜你喜欢

转载自blog.csdn.net/qq_36165459/article/details/78394352