浅谈梯度下降

梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。在机器学习中,基于基本的梯度下降法发展了两种梯度下降方法,分别为随机梯度下降法和批量梯度下降法。

梯度下降法

梯度下降法是使用迭代的方法求解曲线的近似函数。

梯度下降主要的步骤为:

  1. 猜想近似函数 $h(x)$

  2. 计算出损失函数 $J(θ)= \frac{1}{2}*( h(x) - y )^2$,其中 $y$ 为 $θ$ 对应的实际值。

  3. 迭代求解。

猜想近似函数

梯度下降的第一步就是猜想近似函数,猜想出来后才能根据这个函数进行函数求解。一般是根据实际值在图像中所形成的图形进行猜想。

计算损失函数

实际值和近似函数计算出来的值会有一些差异,梯度下降就是尽量减少这个差异。因此我们需要计算损失函数,使得损失函数尽可能的接近0.

前两步是准备工作。

迭代求解

在我们计算出损失函数后,我们需要对其函数系数值进行修正。梯度下降是按照函数在某一点的导数进行修正,当迭代的次数足够多时,系数值趋于稳定时,我们就可以认为近似的求出来了曲线的近似函数。

单变量线性回归问题

房屋价格与面积(数据在下面表格中)

序号 面积 价格
1 150 6450
2 200 7450
3 250 8450
4 300 9450
5 350 11450
6 400 15450
7 600 18450

使用梯度下降求解线性回归(求 $θ_0 , θ_1$ ):

$$
h_{θ(x)}=θ_0+θ_1*x
$$

首先我们要写出损失函数:
$$
J(θ)=\frac{1}{2m}\sum_{i=1}^{m}{(h_θ(x^{(i)})-y^{(i)})^2}
$$
其中 $x^{(i)} ,y^{(i)}$ 分别表示房屋面积和价格的值。$\frac{1}{2}$ 方便函数化简,不影响最终结果。$\frac{1}{m}$ 中 $m$ 表示数据集中元素个数,本题 $m=7$ .

然后我们求解导函数:

$$
\nabla J_{θ0} =\frac{1}{m}\sum_{i=1}^{m}{(h_{θ_1}(x^{(i)})-y^{(i)})}*θ_1
$$

$$
\nabla {J_{θ1}}= \frac{1}{m} \sum_{i=1}^{m}{(h_{θ_1}(x^{(i)})-y^{(i)})}*θ_1
$$

上面两式是对 $θ_1,θ_2$ 求偏导所得到的函数。然后我们根据两个函数的函数值进行迭代求解即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from math import *

#设置数据集
m=7
alpha=0.000000001#步长,即每次迭代距离
area=[150,200,250,300,350,400,600]
price=[6450,7450,8450,9450,11450,15450,18450]

#初始值,可在合理范围内任意选,迭代次数足够多后对结果没有太大影响,建议选在数据集中的值
Theta0=150
Theta1=6450

#求Theta0的偏导,即斜率
def get_theta0(Theta0,Theta1):
ans=0
for i in range(0,m):
ans=ans+(Theta0+Theta1*area[i]-price[i])
return ans/m

#求Theta1的偏导,即斜率
def get_Theta1(Theta0,Theta1):
ans=0
for i in range(0,m):
ans=ans+(Theta0+Theta1*area[i]-price[i])*area[i]
return ans/m;

#nxt_Theta0,nxt_Theta1分别表示当前的Theta0,Theta1下一步的位置
#alpha * get_theta() 步长*斜率=函数值变化的多少
nxt_Theta0 = Theta0 - alpha * get_theta0(Theta0,Theta1)
nxt_Theta1 = Theta1 - alpha * get_Theta1(Theta0,Theta1)

#如果当前位置到下一个位置函数值差距小于给定值,则退出迭代
while fabs(Theta1-nxt_Theta1)>=0.000000001 :
Theta0 = nxt_Theta0
Theta1 = nxt_Theta1
a = Theta0 - alpha * get_theta0(nxt_Theta0,nxt_Theta1)
b = Theta1 - alpha * get_Theta1(nxt_Theta0,nxt_Theta1)
nxt_Theta0 = a
nxt_Theta1 = b
print(Theta0,Theta1)

运行结果为:

1
133.20781607232527 33.07613925785978

接下来画图验证结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from numpy import *
from matplotlib import pyplot
from matplotlib.pyplot import *

area=[150,200,250,300,350,400,600]
price=[6450,7450,8450,9450,11450,15450,18450]

scatter(area,price) #画出点阵图

x=arange(100,700,100) #设置范围和步长
y=133.20781607232527 + 33.07613925785978 * x

plot(x,y)
xlabel('area')
ylabel('price')
show()

图像为:

结果与实际情况与和很好,可认为求出近似函数。

感谢您的支持
-------------本文结束感谢您的阅读-------------