梯度下降基础
一 概述
机器学习三大步骤:
- model (define a set of function)
- goodness of function
- pick the "best" function
step1:model
在这里我们建立一个model
这个Model称之为Linear model:
不同的b、w,得到的 f 不尽相同
而我们要找到最能满足要求的一个 f 。
step2 goodness of function
training data:
当我们将准备好的training data(已知10个宝可梦的进化情况),建立一个二维坐标轴。
通过上图可以看出,好像有一个函数能够拟合这些坐标点,而这正是我们想要的,为了选出最契合的 f ,我们要建立一个Loss function L ,也就是函数的函数。
如果我们将 f 的 w 和 b 作为两轴,则在下图中每一点都确定了一个 function f ,而颜色代表output的大小,也就代表该function f 参数的好坏。易理解,smallest点做对应的函数 f 就是我们想要的。
step3 best function
接下来就是选出使Loss function值最小的f。该怎么计算出来呢?可以用线性代数的方法来计算出最佳的w和b。但我们也可以用Gradient Descent方法求出最佳的w和b。
当我们在L(w)的二维平面中时,我们必须要找到函数的最低点。
首先随机选取一个点w0,计算微分也就是斜率,如果为正,则减小w,如果为负,则增大w。
而这有另一个问题,每次要增加或减少多少w值呢,有两个因素影响。第一,即微分值,如果微分值很大或很小,表示此处非常陡峭,那么证明距离最低点还有很远的距离,所以移动的距离就很大。第二个因素是我们事先自己定义的常数项 η 值,即步长(Learning Rate)。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727094546747-1521804574.png)
不断重复,经过多次的参数更新后,能达到一个最低点。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727094801978-563618623.png)
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727094922026-295072649.png)
说到这里大家可能会担心,会不会产生下图左半部分的哪种情况,即不同的起始位置,找到的最低点是不一样的,其实,在我们案例的Linear regression中,是不会出现这种情况的。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727095050290-769319426.png)
通过上图就会发现,并不是所有的点都能拟合函数,这就会造成很大的预测不准的情况,通过Loss Function也能看出,最优解的值依然很大,在测试数据的表现也不好,所以自然就要想办法做得更好。怎么做得更好呢?这个时候我们可以考虑更换Model。
引入平方
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727095835162-1506774345.png)
引入立方
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727095920270-913815212.png)
引入四次方
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100006421-1105165665.png)
引入五次方
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100103925-503545557.png)
观察以上模型的表现,可以看到随着模型次数的增加,在Training Data上的表现越来越好(前提是Gradient Descent可以找到参数的最优值)。为什么呢?因为复杂的模型包含了简单的模型。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100251026-1858225779.png)
而在Testing Data上的表现却不一样,甚至在五次方程时,大大超出了我们的预估,那么这种现象就叫做overfitting。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100338360-1758199398.png)
所以,function不是越复杂越好,所以我们要选择一个最合适的,由上图可以看出,在三次方程中表现最好。
你是不是以为这样就结束了?答案是否定的。
当我们收集了更多的数据后,将其绘制成图像:
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100519055-1016817430.png)
可以看出来,肯定有什么别的因素影响着进化后的CP值。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100615134-1734633828.png)
可以看到,进化后的CP值受物种影响很大。知道了这点后,我们自然要重新设计Model。
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100713209-174223680.png)
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100744684-1612862927.png)
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100821183-162903715.png)
结果如下:
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727100945523-216167962.png)
当然还可能有别的特征影响了进化的CP值,比如:
我们还是从重新设置Model,并经过计算得到:
出现了Overfitting的现象,如何改进呢?
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727101323815-2146851165.png)
![](https://images2018.cnblogs.com/blog/1414369/201807/1414369-20180727101423005-1040684084.png)
二 实例
假设有如下数据:
x_data = [338.,333.,328.,207.,226.,25.,179.,60.,208.,606]
y_data = [640.,633.,619.,393.,428.,27.,193.,66.,226.,1591]
其中,y_data = w * x_data + b
,w
和b
都是参数,让我们用梯度下降(Gradient Descent)的方法将w
和b
的值找出来。当然,还有许多其他的方法,但我们假装不知道这件事,用Gradient Descent的方法将其找出来。
代码如下:
import numpy as np
import matplotlib.pyplot as plt
x_data = [338.,333.,328.,207.,226.,25.,179.,60.,208.,606]
y_data = [640.,633.,619.,393.,428.,27.,193.,66.,226.,1591]
#ydata=b+w*xdata
x = np.arange(-200,-100,1)# bias
y = np.arange(-5,5,0.1)# weight
z = np.zeros((len(x),len(y)))
X,Y = np.meshgrid(x,y)
for i in range(len(x)):
for j in range(len(y)):
b = x[j]
w = y[j]
z[j][i]=0
for n in range(len(x_data)):
z[j][i] = z[j][i] + (y_data[n] - b - w * x_data[n]) ** 2
z[j][i] = z[j][i] / len(x_data)
#ydata = b + w * xdata
b = -120 #initial b
w = -4 #initial w
lr = 0.0000001 #learning rata
iteration = 100000
#store initial values for plotting
b_history = [b]
w_history = [w]
#iterations
for i in range(iteration):
b_grad = 0.0
w_grad = 0.0
for n in range(len(x_data)):
b_grad = b_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * 1.0
w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]
#updata parameters
b = b - lr * b_grad
w = w - lr * w_grad
#store parameters for plotting
b_history.append(b)
w_history.append(w)
# plot the figure
plt.contourf(x,y,z,50,alpha=0.5,cmap=plt.get_cmap('jet'))
plt.plot([-188.4],[2.67],'x',ms=12,markeredgewidth=3,color='orange')
plt.plot(b_history,w_history,'o-',ms=3,lw=1.5,color='black')
plt.xlim(-200,-100)
plt.ylim(-5,5)
plt.xlabel(r'$b$',fontsize = 16)
plt.ylabel(r'$w$',fontsize = 16)
plt.show()
运行结果如下:
其中,橙色的x
代表最优解,图中的黑色块代表了100000次的迭代过程,可以看出此时离最优解还差得远。这显然是Learning Rate不够大,我们不妨把它调大点,比如说lr = 0.000001
,也就是增大了10倍,得到结果如下:
离最优解稍微近了一点,不过有一个剧烈震荡的现象。我们不妨再把Learning Rate调大,比如说lr=0.00001
,得到结果如下:
糟糕,Learning Rate此时太大了。此时我们该怎么办?如果两个参数都没办法解决,更不用谈更多参数的情况了,只好用大招!——我们要给b
和w
客制化的Learning Rate。
#ydata = b + w * xdata
b = -120 #initial b
w = -4 #initial w
lr = 1 #learning rata
iteration = 100000
#store initial values for plotting
b_history = [b]
w_history = [w]
lr_b = 0.0
lr_w = 0.0
#iterations
for i in range(iteration):
b_grad = 0.0
w_grad = 0.0
for n in range(len(x_data)):
b_grad = b_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * 1.0
w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]
lr_b = lr_b + b_grad ** 2
lr_w = lr_w + w_grad ** 2
#updata parameters
b = b - lr / np.sqrt(lr_b) * b_grad
w = w - lr / np.sqrt(lr_w) * w_grad
#store parameters for plotting
b_history.append(b)
w_history.append(w)
# plot the figure
plt.contourf(x,y,z,50,alpha=0.5,cmap=plt.get_cmap('jet'))
plt.plot([-188.4],[2.67],'x',ms=12,markeredgewidth=3,color='orange')
plt.plot(b_history,w_history,'o-',ms=3,lw=1.5,color='black')
plt.xlim(-200,-100)
plt.ylim(-5,5)
plt.xlabel(r'$b$',fontsize = 16)
plt.ylabel(r'$w$',fontsize = 16)
plt.show()
运行结果如下:
可以看到,在100000次的迭代内,找到了最优解。
参考:
https://www.jianshu.com/p/5ac76589ee7b
https://www.jianshu.com/p/8463d08f4379