当前位置:   article > 正文

李宏毅《机器学习》——P3、4 回归_scalar y2017hat

scalar y2017hat

一、回归的定义和应用例子

回归:找到一个函数function,通过输入特征x,输出一个数值scalar

回归分析作为机器学习的基础分析方法,在股市走势预测、自动驾驶、用户推荐算法中有着种种运用。本节课讲述了一个用于预测Pokemon神奇宝贝进化战斗值的回归分析算法。

二、模型步骤

Step1:Model(模型假设-线性模型)


使用Linear Model:线性模型,输入为Pokemon初始的战斗力、身高等数据。参数中的w代表weight,b代表bias。

0INjc8.jpg

Step2:Goodness of Function(模型评估-损失函数)


如何判断机器找到的函数的好坏?引入概念 Loss ,Loss代表函数输出与期望结果的差距,通过另一个函数 Loss Function 来计算Loss,Loss越高说明举例期望越远,函数的可用性越差。

0IUYuD.jpg

通过Loss Function对比不同函数的的合理性,找到最合适的函数

0Ia9KO.jpg

 图中每一个点代表着一个模型对应的 w和 b,颜色越深代表模型更优

Step3:Best Function Finding(最佳模型-梯度下降)


在知道如何分辨函数的好坏之后,下一个问题就是如何对比从而找到最佳的函数。
在这里我们采用了梯度下降法:Gradient Descent

0IaqQf.jpg

在使用梯度下降法时,首先找到一个初始参数,然后以参数为自变量对Loss进行微分,得到的结果即为Loss函数在参数初始点的曲线的切线斜率,由此便可知道Loss更小的方向在哪里,以设置好的常数项:Learning Rate向Loss更小的方向移动。此时可能出现的问题是局部最小值有可能掩盖全局最小值,但在Linear Model中不用考虑此问题,因为局部最小值就是全局最小值。

1、单个模型参数w

在这里引入一个概念 学习率 

  • 步骤1:随机选取一个 w0
  • 步骤2:计算微分,也就是当前的斜率,根据斜率来判定移动的方向
    • 大于0向右移动(增加w)
    • 小于0向左移动(减少w)
  • 步骤3:根据学习率移动
  • 重复步骤2和步骤3,直到找到最低点

0IwCAH.jpg

2、两个模型参数w和b


同样的,利用在高等数学中学习过的偏导数知识,在初始参数值下分别对多个自变量求偏导数,然后向Loss小的方向移动。这里涉及到微积分下册的多元函数微分学知识,包括梯度、梯度下降等知识点请参考数学课本。

0Iw6KK.jpg

梯度下降推演最优模型的过程 

如果把 w 和 b在图形中展示:

  • 每一条线围成的圈就是等高线,代表损失函数的值,颜色约深的区域代表的损失函数越小
  • 红色的箭头代表等高线的法线方向

三、结果分析


通过梯度下降,我们就可以找到在预设的模型中Loss最小的函数,即可使用这个函数来预测Pokemon进化后的战斗力数值,那么结果如何呢?这时候我们可以通过一组Testing Data和Loss Function来测试这个函数到底效果如何:

0I0MqO.jpg

我们发现,Testing data的平均错误值比Training Data更高,有没有什么办法进一步提高函数的预测效果呢?——更强大复杂的模型:1元N次线性模型

我们可以对模型进行改进:引入参数W2和输入的二次项(Selecting another Model)

0I0vwD.jpg


再次计算平均Error后,我们发现函数的预测效果更好了,那么能否继续增加参数和输入幂次呢?我们来尝试一下:

0IBkOf.jpg

不难发现,再次增添参数后函数的预测效果反而变差了,我们可以在增添一次试试:

0IBMpn.jpg

这时候函数的预测效果已经差的离谱,这是怎么回事呢?

这是因为我们的模型出现了对训练数据的 过拟合(Overfitting)

在上面的尝试中,对Testing Data的预测效果随着参数的增加先变好后变坏,但是对Training Data 的拟合程度在逐渐增高,这是因为机器在寻找函数时过于偏向寻找符合训练数据的函数,而忽略了实际上的预测效果。

那么如何解决过拟合问题呢?

四、步骤优化(解决过拟合问题)

Step1优化:将2个input的4个线性模型合并到一个线性模型中(修改模型)

我们再次尝试重新设计Model,通过观察数据,我们发现Pokemon的战斗力和它们的种族好像有着关联,所以这次引入激活函数,让每个不同种族的宝可梦有不同的预测函数:

0IDXIe.jpg

通过这种方法得出的最佳函数如下所示,它的预测效果更好了。

0IrPqf.jpg

Step2:更多参数,更多input

在最开始我们有很多特征,图形化分析特征,将血量(HP)、重量(Weight)、高度(Height)也加入到模型中

更多特征,更多input,数据量没有明显增加,仍旧导致overfitting

Step3:加入正则化(修改损失函数)


在刚才的尝试中,我们发现在参数过多的情况下会出现过拟合,权重 w 可能会使某些特征权值过高,因此我们可以在Loss Function中引入正则化项(来降低w的权重),减轻Wi对损失函数的影响,在这种方式下寻找最佳预测函数。
当Wi越小时,函数的变化会显得越平滑,减轻参数对于Loss Function的影响会让训练数据中的noiss corrupt input造成的影响变小,从而减轻过拟合带来的危害。

0IrDoD.jpg

在Loss function中增添新项之后,我们可以观察函数预测效果的变化如下所示:

  • w 越小,表示 function较平滑的, function输出值与输入值相差不大
  • 在很多应用场景中,并不是 w 越小模型越平滑越好,但是经验值告诉我们,w越小大部分情况下都是好的。
  • b 的值接近于0 ,对曲线平滑是没有影响

五、总结

0IyCE8.jpg

六、回归演示

现在假设有10个x_data和y_data,x和y之间的关系是y_data=b+w*x_data。b,w都是参数,是需要学习出来的。现在我们来练习用梯度下降找到b和w。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from pylab import mpl
  4. # matplotlib没有中文字体,动态解决
  5. plt.rcParams['font.sans-serif'] = ['Simhei'] # 显示中文
  6. mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
  1. x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]
  2. y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]
  3. x_d = np.asarray(x_data)
  4. y_d = np.asarray(y_data)
  1. x = np.arange(-200, -100, 1)
  2. y = np.arange(-5, 5, 0.1)
  3. Z = np.zeros((len(x), len(y)))
  4. X, Y = np.meshgrid(x, y)
  1. # loss
  2. for i in range(len(x)):
  3. for j in range(len(y)):
  4. b = x[i]
  5. w = y[j]
  6. Z[j][i] = 0 # meshgrid吐出结果:y为行,x为列
  7. for n in range(len(x_data)):
  8. Z[j][i] += (y_data[n] - b - w * x_data[n]) ** 2
  9. Z[j][i] /= len(x_data)

先给b和w一个初始值,计算出b和w的偏微分

  1. # linear regression
  2. #b = -120
  3. #w = -4
  4. b=-2
  5. w=0.01
  6. lr = 0.000005
  7. iteration = 1400000
  8. b_history = [b]
  9. w_history = [w]
  10. loss_history = []
  11. import time
  12. start = time.time()
  13. for i in range(iteration):
  14. m = float(len(x_d))
  15. y_hat = w * x_d +b
  16. loss = np.dot(y_d - y_hat, y_d - y_hat) / m
  17. grad_b = -2.0 * np.sum(y_d - y_hat) / m
  18. grad_w = -2.0 * np.dot(y_d - y_hat, x_d) / m
  19. # update param
  20. b -= lr * grad_b
  21. w -= lr * grad_w
  22. b_history.append(b)
  23. w_history.append(w)
  24. loss_history.append(loss)
  25. if i % 10000 == 0:
  26. print("Step %i, w: %0.4f, b: %.4f, Loss: %.4f" % (i, w, b, loss))
  27. end = time.time()
  28. print("大约需要时间:",end-start)
  1. # plot the figure
  2. plt.contourf(x, y, Z, 50, alpha=0.5, cmap=plt.get_cmap('jet')) # 填充等高线
  3. plt.plot([-188.4], [2.67], 'x', ms=12, mew=3, color="orange")
  4. plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
  5. plt.xlim(-200, -100)
  6. plt.ylim(-5, 5)
  7. plt.xlabel(r'$b$')
  8. plt.ylabel(r'$w$')
  9. plt.title("线性回归")
  10. plt.show()

输出结果如图

横坐标是b,纵坐标是w,标记×位最优解,显然,在图中我们并没有运行得到最优解,最优解十分的遥远。那么我们就调大learning rate,lr = 0.000001(调大10倍),得到结果如下图。

我们再调大learning rate,lr = 0.00001(调大10倍),得到结果如下图。

结果发现learning rate太大了,结果很不好。

所以我们给b和w特制化两种learning rate

  1. # linear regression
  2. b = -120
  3. w = -4
  4. lr = 1
  5. iteration = 100000
  6. b_history = [b]
  7. w_history = [w]
  8. lr_b=0
  9. lr_w=0
  10. import time
  11. start = time.time()
  12. for i in range(iteration):
  13. b_grad=0.0
  14. w_grad=0.0
  15. for n in range(len(x_data)):
  16. b_grad=b_grad-2.0*(y_data[n]-n-w*x_data[n])*1.0
  17. w_grad= w_grad-2.0*(y_data[n]-n-w*x_data[n])*x_data[n]
  18. lr_b=lr_b+b_grad**2
  19. lr_w=lr_w+w_grad**2
  20. # update param
  21. b -= lr/np.sqrt(lr_b) * b_grad
  22. w -= lr /np.sqrt(lr_w) * w_grad
  23. b_history.append(b)
  24. w_history.append(w)
  1. # plot the figure
  2. plt.contourf(x, y, Z, 50, alpha=0.5, cmap=plt.get_cmap('jet')) # 填充等高线
  3. plt.plot([-188.4], [2.67], 'x', ms=12, mew=3, color="orange")
  4. plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
  5. plt.xlim(-200, -100)
  6. plt.ylim(-5, 5)
  7. plt.xlabel(r'$b$')
  8. plt.ylabel(r'$w$')
  9. plt.title("线性回归")
  10. plt.show()

有了新的特制化两种learning rate就可以在10w次迭代之内到达最优点了。

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

闽ICP备14008679号