当前位置:   article > 正文

利用神经网络来实现线性回归_神经网络解决线性回归问题

神经网络解决线性回归问题

先导入包

  1. %matplotlib inline
  2. from IPython import display
  3. from matplotlib import pyplot as plt
  4. from mxnet import autograd, nd
  5. import random

features为随机生成服从(0,1)正态分布的数据2000个,形状为1000*2,labels就是目标变量,这里已经设定好权重w1,w2分别为2,-3.4,还有b为4.2,最后一行是给目标变量加上噪声,这样跟真实数据更为接近。

  1. num_inputs = 2
  2. num_examples = 1000
  3. true_w = [2, -3.4]
  4. true_b = 4.2
  5. features = nd.random.normal(scale=1, shape=(num_examples, num_inputs)) #1000*2
  6. labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b #1000*1
  7. labels += nd.random.normal(scale=0.01, shape=labels.shape) #加上噪声
  1. def use_svg_display(): # 用矢量图显示 特点 放大后图像不会失真
  2. display.set_matplotlib_formats('svg')
  3. def set_figsize(figsize=(3.5, 2.5)):
  4. use_svg_display()
  5. # 设置图的尺寸
  6. plt.rcParams['figure.figsize'] = figsize
  7. set_figsize(figsize=(5,5))
  8. plt.scatter(features[:, 1].asnumpy(), labels.asnumpy(),10); # 加分号只显示图
  9. plt.scatter(features[:, 0].asnumpy(), labels.asnumpy(),10);

画了个图,看看x1和x2与labels的关系:

可以看到x1与labels大体成正相关,x2与labels大体成负相关

  1. # 该函数作用是从样本中随机提取大小为batch_size的数据
  2. def data_iter(batch_size, features, labels):
  3. num_examples = len(features)
  4. indices = list(range(num_examples))
  5. random.shuffle(indices) # 样本的读取顺序是随机的 indices列表随机排列
  6. for i in range(0, num_examples, batch_size):
  7. j = nd.array(indices[i: min(i + batch_size, num_examples)])
  8. yield features.take(j), labels.take(j) # take函数根据索引返回对应元素 最后结果为生成器

接着设定函数data_iter为后面小批量随机梯度下降算法做准备,该函数的作用是从features样本中随机提取若干个数据,例如batch_size 为10时,随机的将这1000条数据(每条数据有两个值)分成100份,生成一个生成器,生成器可以当成列表,能用for循环依次提取。

正式开始:

  1. w = nd.random.normal(scale=0.01, shape=(num_inputs, 1))
  2. b = nd.zeros(shape=(1,))
  3. w.attach_grad()#申请相应内存来存x的导数。
  4. b.attach_grad()
  5. def linreg(X, w, b): # 本函数已保存在d2lzh包中方便以后使用
  6. return nd.dot(X, w) + b
  7. def squared_loss(y_hat, y): # 本函数已保存在d2lzh包中方便以后使用
  8. return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
  9. def sgd(params, lr, batch_size): # 本函数已保存在d2lzh包中方便以后使用
  10. for param in params:
  11. param[:] = param - lr * param.grad / batch_size

根据(0,0.01)正态分布随机生成w,b直接设置为0,attach_grad申请内存,linreg函数根据w,b,x的值来计算估计的y,squared_loss函数计算预测y值与真实y值的差的平方除以2,sgd函数对w1,w2,b值进行更新,注意sgd函数这里的for循环,里面更新params参数的方式,其中param的地址是和params一样的,所以改变param里面的值的同时params的值也会发生改变,并且直接在param上进行修改,不会新开辟内存,是目前最优的方式。

  1. lr = 0.03
  2. num_epochs = 3
  3. net = linreg
  4. loss = squared_loss
  5. for epoch in range(num_epochs): # 训练模型一共需要num_epochs个迭代周期
  6. # 在每一个迭代周期中,会使用训练数据集中所有样本一次(假设样本数能够被批量大小整除)。X
  7. # 和y分别是小批量样本的特征和标签
  8. for X, y in data_iter(batch_size, features, labels):
  9. with autograd.record(): #记录方便后面backward
  10. l = loss(net(X, w, b), y) # l是有关小批量X和y的损失
  11. l.backward() # 小批量的损失对模型参数求梯度
  12. sgd([w, b], lr, batch_size) # 使用小批量随机梯度下降迭代模型参数
  13. train_l = loss(net(features, w, b), labels)
  14. print('epoch %d, loss %f' % (epoch + 1, train_l.mean().asnumpy()))

这里设置学习速度为0.03,迭代次数为3,注意这里l.backward后,就可以用w.grad和b.grad 的方式得出l分别对w,b求导后所得值,然后根据这些值,用sgd函数进一步进行计算就可以得到更新后的w,b值,for循环data_iter得到的生成器,就是随机小批量的优化算法,大大提升了算法的速度

  1. print(true_w, w)
  2. print(true_b, b)
  3. 结果:
  4. [2, -3.4]
  5. [[ 1.9999498]
  6. [-3.3991547]]
  7. <NDArray 2x1 @cpu(0)>
  8. 4.2
  9. [4.1989775]
  10. <NDArray 1 @cpu(0)>

有任何问题,欢迎留言讨论

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/123447
推荐阅读
相关标签
  

闽ICP备14008679号