利用Gluon简洁实现线性回归——动手学深度学习笔记

在使用gluon接口之前,我们首先需要下载好mxnet包pip install mxnet

生成数据集

在这里插入图片描述
根据公式基础去理解,并加上噪声

from mxnet import autograd, nd
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4]
true_b = 4.2
features = nd.random.normal(scale=1, shape=(num_examples, num_inputs))
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += nd.random.normal(scale=0.01, shape=labels.shape)#生成噪声,其中噪声项ϵ服从均值为0、标准差为0.01的正态分布。噪声代表了数据集中⽆意义的⼲扰

读取数据集

from mxnet.gluon import data as gdata
batch_size = 10
# 将训练数据的特征和标签组合
dataset = gdata.ArrayDataset(features, labels)
# 随机读取⼩批量
data_iter = gdata.DataLoader(dataset, batch_size, shuffle=True)
#读取并打印第⼀个小批量数据样本
for X, y in data_iter:
	print(X, y)
	break

对于data_iter,实现原理如下,在gluon中进行了简单定义方便使用。

def data_iter(batch_size, features, labels): 
    num_examples = len(features)         # 特征个数
    indices = list(range(num_examples))  # 特征个数索引列表
    random.shuffle(indices)              # 样本的读取顺序是随机的 
    for i in range(0, num_examples, batch_size):
        j = nd.array(indices[i: min(i + batch_size, num_examples)]) 
        # 切片得索引(包含最后没有达到batch_size得一个切片索引)
        yield features.take(j), labels.take(j) # take函数根据索引返回对应元素  

定义模型

当模型结构变得更复杂时,定义模型参数将变得更烦琐。其实,Gluon提供了⼤量预定义的层,这使我们只需关注使⽤哪些层来构造模型。下⾯将介绍如何使⽤Gluon更简洁地定义线性回归。
首先,导入nn模块。该模块定义了大量神经网络的层。我们先定义⼀个模型变量net,它是⼀个Sequential实例。在Gluon中,Sequential实例可以看作是⼀个串联各个层的容器。在构造模型时,我们在该容器中依次添加层。当给定输⼊数据时,容器中的每⼀层将依次计算并将输出作为下⼀层的输入。

from mxnet.gluon import nn
net = nn.Sequential()

作为⼀个单层神经⽹络,线性回归输出层中的神经元和输入层中各个输入完全连接。因此,线性回归的输出层⼜叫全连接层。在Gluon中,全连接层是⼀个Dense实例。我们定义该层输出个数为1。

net.add(nn.Dense(1))

在Gluon中我们⽆须指定每⼀层输⼊的形状,例如线性回归的输入个数。当模型得到数据时,例如后面执行net(X)时,模型将⾃动推断出每⼀层的输入个数。

初始化模型参数

在使用net前,我们需要初始化模型参数,如线性回归模型中的权重和偏差。我们从MXNet导入init模块。该模块提供了模型参数初始化的各种方法。

from mxnet import init
net.initialize(init.Normal(sigma=0.01))
#随机采样于均值为0、标准差为0.01的正态分布

定义损失函数

from mxnet.gluon import loss as gloss
loss = gloss.L2Loss() # 平⽅损失⼜称L2范数损失

定义优化算法

from mxnet import gluon
trainer = gluon.Trainer(net.collect_params(), 'sgd', {
    
    'learning_rate': 0.03})
#指定学习率为0.03的小批量随机梯度下降(sgd)为优化算法

该优化算法将⽤来迭代net实例所有通过add函数嵌套的层所包含的全部参数。这些参数可以通过collect_params函数获取。

训练模型

在使⽤Gluon训练模型时,我们通过调用Trainer实例的step函数来迭代模型参数。上一节中我们提到,由于变量l是长度为batch_size的一维NDArray,执行l.backward()等价于执行l.
sum().backward()。按照小批量随机梯度下降的定义,我们在step函数中指明批量大小,从
而对批量中样本梯度求平均

 num_epochs = 3
for epoch in range(1, num_epochs + 1):
	for X, y in data_iter:
		with autograd.record():#记录梯度运算
			l = loss(net(X), y)
		l.backward()#求梯度
		trainer.step(batch_size)#迭代模型参数
l = loss(net(features), labels)
print('epoch %d, loss: %f' % (epoch, l.mean().asnumpy()))

猜你喜欢

转载自blog.csdn.net/fcxgfdjy/article/details/127377296