1、基于MXNET框架的线性回归从零实现例子
下面博客是基于MXNET框架下的线性回归从零实现,以一个简单的房屋价格预测作为例子来解释线性回归的基本要素。这个应用的目标是预测一栋房子的售出价格(元)。
为了简单起见,这里我们假设价格只取决于房屋状况的两个因素,即面积(平方米)和房龄(年)。接下来我们希望探索价格与这两个因素的具体关系:
设房屋的面积为x1,房龄为x2,售出价格为y。我们需要建立基于输入x1和x2来计算输出yy的表达式,也就是模型(model)。顾名思义,线性回归假设输出与各个输入之间是线性关系:y'=x1w1+x2w2+b
其中w1和w2是权重(weight),b是偏差(bias),且均为标量。它们是线性回归模型的参数(parameter)。模型输出y'是线性回归对真实价格y的预测或估计。我们通常允许它们之间有一定误差。
2、实现部分(各个部分见代码注释)
2.1、生成数据集(随机生成批量样本数据与高斯噪声)
2.2、读取数据集(遍历数据集并不断读取小批量数据样本)
2.3、初始化模型参数(均值为0、标准差为0.01的正态随机数,偏差则初始化成0)
2.4、定义模型
2.5、定义损失函数(平方损失函数)
2.6、定义优化算法(sgd小批量随机梯度下降算法)
2.7、训练模型(过调用反向函数backward
计算小批量随机梯度,并调用优化算法sgd
迭代模型参数)
3、代码实现
1 from IPython import display 2 from matplotlib import pyplot as plt 3 from mxnet import autograd, nd 4 import random 5 6 7 # 生成数据集 8 num_inputs = 2 9 num_examples = 1000 10 11 true_w = [2, -3.4] 12 true_b = 4.2 13 features = nd.random.normal(scale=1, shape=(num_examples, num_inputs)) 14 15 labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b 16 labels += nd.random.normal(scale=0.01, shape=labels.shape) 17 18 print(features[0], labels[0]) 19 20 21 def use_svg_display(): 22 # 用矢量图显示 23 display.set_matplotlib_formats('svg') 24 25 26 def set_figsize(figsize=(3.5, 2.5)): 27 use_svg_display() 28 # 设置图的尺寸 29 plt.rcParams['figure.figsize'] = figsize 30 31 32 set_figsize() 33 plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(), 1) 34 35 # plt.scatter(features[:, 0].asnumpy(), labels.asnumpy(), 1) 36 # help(plt.scatter) 37 38 39 # 读取数据集 40 def data_iter(batch_size, features, labels): 41 num_examples = len(features) 42 indices = list(range(num_examples)) 43 random.shuffle(indices) 44 for i in range(0, num_examples, batch_size): 45 j = nd.array(indices[i: min(i + batch_size, num_examples)]) 46 yield features.take(j), labels.take(j) 47 48 49 batch_size = 10 50 51 for X, y in data_iter(batch_size, features, labels): 52 print(X, y) 53 break 54 55 56 # 初始化模型参数 57 w = nd.random.normal(scale=0.01, shape=(num_inputs, 1)) 58 b = nd.zeros(shape=(1,)) 59 # 之后的模型训练中,需要对这些参数求梯度来迭代参数的值,因此我们需要创建它们的梯度 60 w.attach_grad() 61 b.attach_grad() 62 63 64 # 定义模型 65 def linreg(X, w, b): 66 return nd.dot(X, w) + b 67 68 69 # 定义平方损失函数 70 def squared_loss(y_hat, y): 71 return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2 72 73 74 #定义优化算法 75 def sgd(params, lr , batch_size): 76 for param in params: 77 param[:] = param - lr * param.grad / batch_size 78 79 80 #训练模型 81 lr = 0.03 82 num_epochs = 3 83 net = linreg 84 loss = squared_loss 85 86 for epoch in range(num_epochs): 87 for X, y in data_iter(batch_size, features, labels): 88 with autograd.record(): 89 l = loss(net(X, w, b), y) 90 l.backward() 91 sgd([w, b], lr, batch_size) 92 train_l = loss(net(features, w, b), labels) 93 print('epoch %d, loss %f' % (epoch + 1, train_l.mean().asnumpy())) 94 95 96 97 plt.show()
4、结果
4.1、特征features[1, :]和[:, 1]与labels之间的散点图
4.2、迭代结果
4.3、线性回归模型真实权重参数与训练得到的参数比较:print(true_w, w) print(true_b, b)