文章目录
一、概念与算法原理
1.1 梯度
- 从几何意义上讲,梯度就是函数变化增加最快的地方.
- 在微积分里面,对多元函数的参数求 ∂ \partial ∂ 偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。如函数 f ( x , y ) f(x,y) f(x,y),其梯度向量为 ( ∂ f ∂ x , ∂ f ∂ y ) T (\frac{∂f}{∂x}, \frac{∂f}{∂y})^T (∂x∂f,∂y∂f)T,简称 g r a d f ( x , y ) grad f(x,y) gradf(x,y) 或者 ▽ f ( x , y ) ▽f(x,y) ▽f(x,y) 。如果是3个参数的向量梯度,就是 ( ∂ f ∂ x , ∂ f ∂ y , ∂ f ∂ z , ) T (\frac{∂f}{∂x}, \frac{∂f}{∂y},\frac{∂f}{∂z},)^T (∂x∂f,∂y∂f,∂z∂f,)T ,以此类推。
1.2 梯度下降
1.2.1 梯度下降相关概念
-
步长(Learning rate):步长决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度。
-
特征(feature):指的是样本中输入部分,比如2个样本、1个特征的数据集 { ( x ( 0 ) , y ( 0 ) ) , ( x ( 1 ) , y ( 1 ) ) } \{(x^{(0)},y^{(0)}),(x^{(1)},y^{(1)})\} {(x(0),y(0)),(x(1),y(1))},则第一个样本特征为 x ( 0 ) x^{(0)} x(0) ,第一个样本输出为 y ( 0 ) y^{(0)} y(0)。
-
假设函数(hypothesis function):在监督学习中,为了拟合输入样本,而使用的假设函数,记为 h θ ( x ) h_{\theta}(x) hθ(x) 。比如对于1个特征的n个样本 ( x ( i ) , y ( i ) ) ( i = 1 , 2 , . . . , n ) (x^{(i)},y^{(i)})(i=1,2,...,n) (x(i),y(i))(i=1,2,...,n),其假设函数可写成:
h θ ( x ) = θ 0 + θ 1 x h_{\theta}(x) = \theta_{0}+\theta_{1}x hθ(x)=θ0+θ1x -
损失函数(loss function):为了评估模型拟合的好坏,通常用损失函数来度量拟合的程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。在线性回归中,损失函数通常为样本输出和假设函数的差取平方。比如对于1个特征的n个样本 ( x ( i ) , y ( i ) ) ( i = 1 , 2 , . . . , n ) (x^{(i)},y^{(i)})(i=1,2,...,n) (x(i),y(i))(i=1,2,...,n),其线性回归的损失函数为:
J ( θ 0 , θ 1 ) = ∑ i = 0 n ( h θ ( x ) ( i ) − y ( i ) ) 2 = ∑ i = 0 n [ ( θ 0 ( i ) + θ 1 ( i ) x 1 ( i ) ) − y ( i ) ] 2 \begin{aligned} J(\theta_{0},\theta_{1}) & = \sum_{i=0}^{n}(h_{\theta}(x)^{(i)} - y^{(i)})^{2} \\ & = \sum_{i=0}^{n}[(\theta_{0}^{(i)}+\theta_{1}^{(i)}x_{1}^{(i)}) - y^{(i)}]^{2} \end{aligned} J(θ0,θ1)=i=0∑n(hθ(x)(i)−y(i))2=i=0∑n[(θ0(i)+θ1(i)x1(i))−y(i)]2 -
梯度下降不一定能够找到全局的最优解,有可能是一个局部最优解。当然,如果损失函数是凸函数,梯度下降法得到的解就一定是全局最优解。
1.2.2 梯度下降的详细算法
(1)代数描述
-
1.先决条件: 确认优化模型的假设函数和损失函数。
比如对于m个特征的线性回归,假设函数表示为 h θ ( x 1 , x 2 , . . . , x m ) = θ 0 + θ 1 x 1 + . . . + θ m x m h_{\theta}(x_{1},x_{2},...,x_{m}) = \theta_{0}+\theta_{1}x_{1}+...+\theta_{m}x_{m} hθ(x1,x2,...,xm)=θ0+θ1x1+...+θmxm,其中 θ i ( i = 0 , 1 , . . . , m ) \theta_{i}(i=0,1,...,m) θi(i=0,1,...,m) 为模型参数, x i ( i = 1 , 2 , . . . , m ) x_{i}(i=1,2,...,m) xi(i=1,2,...,m)为每个样本的m个特征值。为了表示可以简化,可以设 x 0 = 1 x_{0}=1 x0=1,假设函数则可以简化为
h θ ( x 0 , x 1 , . . . , x m ) = ∑ i = 0 m θ i x i h_{\theta}(x_{0},x_{1},...,x_{m}) = \sum_{i=0}^{m} \theta_{i}x_{i} hθ(x0,x1,...,xm)=i=0∑mθixi
对应于上面的假设函数,损失函数为:
J ( θ 0 , θ 1 , . . . , θ m ) = 1 2 n ∑ i = 1 n [ h θ ( x 0 ( i ) , x 1 ( i ) , . . . , x m ( i ) ) − y ( i ) ] 2 \begin{aligned} J(\theta_{0},\theta_{1},...,\theta_{m}) = \frac{1}{2n} \sum_{i=1}^{n} [h_{\theta}(x_{0}^{(i)},x_{1}^{(i)},...,x_{m}^{(i)})-y^{(i)}]^{2} \end{aligned} J(θ0,θ1,...,θm)=2n1i=1∑n[hθ(x0(i),x1(i),...,xm(i))−y(i)]2
其中, n n n 是样本量, m m m 是特征数,加 1 2 n \frac{1}{2n} 2n1是为了更好地理解,也方便求偏导后抵消2次幂。 -
2.算法相关参数初始化:参数 θ \theta θ,步长 α \alpha α,终止距离(即梯度下降的距离) ε \varepsilon ε
-
3.算法过程:
1)确认梯度函数。
2)用步长乘以损失函数的梯度,得到当前位置下降的距离。如参数 θ i ( i = 0 , 1 , . . . , m ) \theta_{i}(i=0,1,...,m) θi(i=0,1,...,m) 的梯度为 ∂ J ( θ ) ∂ θ i \frac{\partial J(\theta)}{\partial \theta_{i}} ∂θi∂J(θ),梯度下降的距离为 α ∂ J ( θ ) ∂ θ i \alpha \frac{\partial J(\theta)}{\partial \theta_{i}} α∂θi∂J(θ),即
d = α 1 n ∑ i = 1 n [ h θ ( x 0 ( i ) , x 1 ( i ) , . . . , x m ( i ) ) − y ( i ) ] x ( i ) d = \alpha \frac{1}{n} \sum_{i=1}^{n} [h_{\theta}(x_{0}^{(i)},x_{1}^{(i)},...,x_{m}^{(i)})-y^{(i)}]x^{(i)} d=αn1i=1∑n[hθ(x0(i),x1(i),...,xm(i))−y(i)]x(i)
3)确定是否所有的 θ i ( i = 0 , 1 , . . . , m ) \theta_{i}(i=0,1,...,m) θi(i=0,1,...,m)梯度下降的距离都小于 ε \varepsilon ε,如果小于 ε \varepsilon ε 则算法终止,否则进入步骤4.
4)更新所有的 θ i ( i = 0 , 1 , . . . , m ) \theta_{i}(i=0,1,...,m) θi(i=0,1,...,m),更新完毕后继续转入步骤1。
θ i : = θ i − d = θ i − α 1 n ∑ i = 1 n [ h θ ( x 0 ( i ) , x 1 ( i ) , . . . , x m ( i ) ) − y ( i ) ] x ( i ) \begin{aligned} \theta_{i} & := \theta_{i} - d \\ & =\theta_{i} - \alpha \frac{1}{n} \sum_{i=1}^{n} [h_{\theta}(x_{0}^{(i)},x_{1}^{(i)},...,x_{m}^{(i)})-y^{(i)}]x^{(i)} \end{aligned} θi:=θi−d=θi−αn1i=1∑n[hθ(x0(i),x1(i),...,xm(i))−y(i)]x(i)
(2)矩阵描述
- 这一部分是梯度下降法的矩阵公式,不再讲解。
- 如果需要熟悉矩阵求导建议参考张贤达的《矩阵分析与应用》一书。
目 标 函 数 : h θ ( X ) = X θ 损 失 函 数 : J ( θ ) = 1 2 ( X θ − Y ) T ( X θ − Y ) 损 失 函 数 偏 导 : ∂ ∂ θ J ( θ ) = X T ( X θ − Y ) 梯 度 下 降 距 离 : α X T ( X θ − Y ) 参 数 更 新 : θ : = θ − α X T ( X θ − Y ) \begin{aligned} &目标函数:h_{\theta}(X) = X \theta \\ &损失函数:J(\theta) = \frac{1}{2}(X \theta-Y)^{T}(X \theta-Y) \\ &损失函数偏导:\frac{\partial}{\partial \theta} J(\theta) = X^{T} ( X\theta-Y) \\ &梯度下降距离:\alpha X^{T} ( X\theta-Y) \\ &参数更新:\theta := \theta - \alpha X^{T} ( X\theta-Y) \end{aligned} 目标函数:hθ(X)=Xθ损失函数:J(θ)=21(Xθ−Y)T(Xθ−Y)损失函数偏导:∂θ∂J(θ)=XT(Xθ−Y)梯度下降距离:αXT(Xθ−Y)参数更新:θ:=θ−αXT(Xθ−Y)
二、案例实战
- 设原函数 h θ ( x ) = θ 0 + θ 1 x h_{\theta}(x) = \theta_{0}+\theta_{1}x hθ(x)=θ0+θ1x,我们使用以下五个数据点来拟合该函数。(正确解: h = 1 + 2 x h= 1+2x h=1+2x)
n | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
x | 1 | 2 | 3 | 4 | 5 |
y | 3 | 5 | 7 | 9 | 11 |
2.1 手撸(代数形式)
1)定义梯度公式,该案例有五个样本,两个
θ
\theta
θ,所以损失函数的梯度有:
∇
θ
0
=
1
5
∑
i
=
1
5
[
(
θ
0
(
i
)
+
θ
1
(
i
)
x
(
i
)
)
−
y
(
i
)
]
x
0
(
i
)
∇
θ
1
=
1
5
∑
i
=
1
5
[
(
θ
0
(
i
)
+
θ
1
(
i
)
x
(
i
)
)
−
y
(
i
)
]
x
0
(
i
)
\nabla_{\theta_{0}} = \frac{1}{5} \sum_{i=1}^{5} [(\theta_{0}^{(i)}+\theta_{1}^{(i)}x^{(i)})-y^{(i)}]x_{0}^{(i)} \\ \nabla_{\theta_{1}} = \frac{1}{5} \sum_{i=1}^{5} [(\theta_{0}^{(i)}+\theta_{1}^{(i)}x^{(i)})-y^{(i)}]x_{0}^{(i)}
∇θ0=51i=1∑5[(θ0(i)+θ1(i)x(i))−y(i)]x0(i)∇θ1=51i=1∑5[(θ0(i)+θ1(i)x(i))−y(i)]x0(i)
其中,
x
0
(
i
)
=
1
x_{0}^{(i)}=1
x0(i)=1.(不明白这里可以查看上文)
2)定义梯度下降的距离公式,该案例有五个样本,两个
θ
\theta
θ,所以梯度下降的距离有:
d
0
=
α
∇
θ
0
d
1
=
α
∇
θ
1
d0 = \alpha \nabla_{\theta0} \\ d1 = \alpha \nabla_{\theta1}
d0=α∇θ0d1=α∇θ1
其中,
x
0
(
i
)
=
1
x_{0}^{(i)}=1
x0(i)=1.(不明白这里可以查看上文)
3)定义
θ
\theta
θ 更新公式 :
θ
0
:
=
θ
0
−
d
0
θ
1
:
=
θ
1
−
d
1
\theta_{0} := \theta_{0} - d0 \\ \theta_{1} := \theta_{1} - d1
θ0:=θ0−d0θ1:=θ1−d1
4)初始化相关参数
α
=
0.01
θ
0
=
0
,
θ
1
=
0
ε
=
0.001
\begin{aligned} & \alpha = 0.01 \\ & \theta_{0} = 0, \theta_{1} = 0 \\ & \varepsilon = 0.001 \end{aligned}
α=0.01θ0=0,θ1=0ε=0.001
5)算法过程:把
1
n
\frac{1}{n}
n1去掉不计算,且注意
x
0
i
=
1
x_{0}^{i}=1
x0i=1
迭代第0次,计算出:
两个
θ
\theta
θ损失函数梯度为
∇
θ
0
=
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
3
]
∗
1
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
5
]
∗
1
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
7
]
∗
1
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
9
]
∗
1
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
11
]
∗
1
=
−
0.2
∗
(
3
+
5
+
7
+
9
+
11
)
=
−
7
\begin{aligned} \nabla_{\theta_{0}} & = \frac{1}{5} * [(0*1+0*2) - 3]*1 \\ & + \frac{1}{5} * [(0*1+0*2) - 5]*1 \\ & + \frac{1}{5} * [(0*1+0*2) - 7]*1 \\ & + \frac{1}{5} * [(0*1+0*2) - 9]*1 \\ & + \frac{1}{5} * [(0*1+0*2) - 11]*1 \\ & = -0.2*(3+5+7+9+11) \\ & = -7 \end{aligned}
∇θ0=51∗[(0∗1+0∗2)−3]∗1+51∗[(0∗1+0∗2)−5]∗1+51∗[(0∗1+0∗2)−7]∗1+51∗[(0∗1+0∗2)−9]∗1+51∗[(0∗1+0∗2)−11]∗1=−0.2∗(3+5+7+9+11)=−7
∇
θ
1
=
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
3
]
∗
1
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
5
]
∗
2
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
7
]
∗
3
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
9
]
∗
4
+
1
5
∗
[
(
0
∗
1
+
0
∗
2
)
−
11
]
∗
5
=
0.2
∗
(
3
+
10
+
21
+
46
+
55
)
=
25
\begin{aligned} \nabla_{\theta_{1}} & = \frac{1}{5} * [(0*1+0*2) - 3]*1 \\ & + \frac{1}{5} * [(0*1+0*2) - 5]*2 \\ & + \frac{1}{5} * [(0*1+0*2) - 7]*3 \\ & + \frac{1}{5} * [(0*1+0*2) - 9]*4 \\ & + \frac{1}{5} * [(0*1+0*2) - 11]*5 \\ & = 0.2*(3+10+21+46+55) \\ & = 25 \end{aligned}
∇θ1=51∗[(0∗1+0∗2)−3]∗1+51∗[(0∗1+0∗2)−5]∗2+51∗[(0∗1+0∗2)−7]∗3+51∗[(0∗1+0∗2)−9]∗4+51∗[(0∗1+0∗2)−11]∗5=0.2∗(3+10+21+46+55)=25
两个
θ
\theta
θ损失函数梯度下降距离为
d
0
=
0.01
∗
∇
θ
0
=
0.01
∗
(
−
7
)
=
−
0.07
d
1
=
0.01
∗
∇
θ
1
=
0.01
∗
(
−
27
)
=
−
0.25
\begin{aligned} d0 & = 0.01*\nabla_{\theta_{0}} =0.01*(-7) = -0.07 \\ d1 & = 0.01*\nabla_{\theta_{1}} =0.01*(-27) = -0.25 \end{aligned}
d0d1=0.01∗∇θ0=0.01∗(−7)=−0.07=0.01∗∇θ1=0.01∗(−27)=−0.25
终止迭代判断:两个
θ
\theta
θ梯度下降的距离都大于设定的阈值
ε
\varepsilon
ε,继续迭代。
∣
d
0
∣
=
0.07
>
ε
=
0.001
&
∣
d
2
∣
=
0.25
>
ε
=
0.001
\begin{aligned} |d0| = 0.07 & > \varepsilon =0.001\\ & \& \\ |d2| = 0.25 & > \varepsilon =0.001\\ \end{aligned}
∣d0∣=0.07∣d2∣=0.25>ε=0.001&>ε=0.001
迭代第1次,计算出:
更新两个
θ
\theta
θ
θ
0
:
=
θ
0
−
d
0
=
0
+
0.07
=
0.07
θ
1
:
=
θ
1
−
d
1
=
0
+
0.25
=
0.25
\theta_{0} := \theta_{0} - d0 =0+0.07 = 0.07 \\ \theta_{1} := \theta_{1} - d1 = 0+0.25=0.25
θ0:=θ0−d0=0+0.07=0.07θ1:=θ1−d1=0+0.25=0.25
两个
θ
\theta
θ损失函数梯度为
∇
θ
0
=
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
3
]
∗
1
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
5
]
∗
1
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
7
]
∗
1
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
9
]
∗
1
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
11
]
∗
1
=
−
0.2
∗
(
2.423
+
4.43
+
6.43
+
8.43
+
10.43
)
=
−
6.4286
\begin{aligned} \nabla_{\theta_{0}} & = \frac{1}{5} * [(0.07*1+0.25*2) - 3]*1 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 5]*1 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 7]*1 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 9]*1 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 11]*1 \\ & = -0.2*(2.423+4.43+6.43+8.43+10.43) \\ & = -6.4286 \end{aligned}
∇θ0=51∗[(0.07∗1+0.25∗2)−3]∗1+51∗[(0.07∗1+0.25∗2)−5]∗1+51∗[(0.07∗1+0.25∗2)−7]∗1+51∗[(0.07∗1+0.25∗2)−9]∗1+51∗[(0.07∗1+0.25∗2)−11]∗1=−0.2∗(2.423+4.43+6.43+8.43+10.43)=−6.4286
∇
θ
0
=
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
3
]
∗
1
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
5
]
∗
2
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
7
]
∗
3
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
9
]
∗
4
+
1
5
∗
[
(
0.07
∗
1
+
0.25
∗
2
)
−
11
]
∗
5
=
−
0.2
∗
(
2.423
+
8.86
+
19.29
+
33.72
+
52.15
)
=
−
23.289
\begin{aligned} \nabla_{\theta_{0}} & = \frac{1}{5} * [(0.07*1+0.25*2) - 3]*1 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 5]*2 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 7]*3 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 9]*4 \\ & + \frac{1}{5} * [(0.07*1+0.25*2) - 11]*5 \\ & = -0.2*(2.423+8.86+19.29+33.72+52.15) \\ & = -23.289 \end{aligned}
∇θ0=51∗[(0.07∗1+0.25∗2)−3]∗1+51∗[(0.07∗1+0.25∗2)−5]∗2+51∗[(0.07∗1+0.25∗2)−7]∗3+51∗[(0.07∗1+0.25∗2)−9]∗4+51∗[(0.07∗1+0.25∗2)−11]∗5=−0.2∗(2.423+8.86+19.29+33.72+52.15)=−23.289
两个
θ
\theta
θ损失函数梯度下降距离为
d
0
=
0.01
∗
∇
θ
0
=
0.01
∗
(
−
6.4286
)
=
−
0.064286
d
1
=
0.01
∗
∇
θ
1
=
0.01
∗
(
−
23.289
)
=
−
0.23289
\begin{aligned} d0 & = 0.01*\nabla_{\theta_{0}} =0.01*(-6.4286) = -0.064286 \\ d1 & = 0.01*\nabla_{\theta_{1}} =0.01*(-23.289) = -0.23289 \end{aligned}
d0d1=0.01∗∇θ0=0.01∗(−6.4286)=−0.064286=0.01∗∇θ1=0.01∗(−23.289)=−0.23289
终止迭代判断:两个
θ
\theta
θ梯度下降的距离都大于设定的阈值
ε
\varepsilon
ε,继续迭代。
∣
d
0
∣
=
0.064286
>
ε
=
0.001
&
∣
d
2
∣
=
0.23289
>
ε
=
0.001
\begin{aligned} |d0| = 0.064286 & > \varepsilon =0.001\\ & \& \\ |d2| = 0.23289 & > \varepsilon =0.001\\ \end{aligned}
∣d0∣=0.064286∣d2∣=0.23289>ε=0.001&>ε=0.001
迭代第2次,计算出:
更新两个
θ
\theta
θ
θ
0
:
=
θ
0
−
d
0
=
0.07
+
0.064286
=
0.134286
θ
1
:
=
θ
1
−
d
1
=
0.25
+
0.23289
=
0.48289
\theta_{0} := \theta_{0} - d0 =0.07+0.064286 = 0.134286 \\ \theta_{1} := \theta_{1} - d1 = 0.25+0.23289 = 0.48289
θ0:=θ0−d0=0.07+0.064286=0.134286θ1:=θ1−d1=0.25+0.23289=0.48289
......暂且撸到这里
😄
2.2 python 实现
2.2.1 代数形式
import numpy as np
def GetH_Y(x,y,Theta):
'''
功能:获取损失函数梯度表达式的部分:h-y
传入:X --> 特征,如单特征2个样本为 [[1, 1], [1, 2]],其中x0==1
Y --> 对应的样本输出
Theta --> 模型参数
返回:
表达式部分:h-y
'''
m = len(x) # m个特征,包含x0==1这个特征
res = "+".join(['Theta[{}]*x[{}]'.format(i,i) for i in range(m)])
return eval('({}) - y'.format(res))
def GetDistanceAndTheta(X,Y,Alpha,Theta):
'''
功能:获取梯度下降的距离和迭代更新后的theta
传入:X --> 特征,如单特征2个样本为 [[1, 1], [1, 2]],其中x0==1
Y --> 对应的样本输出
Theta --> 模型参数
Alpha --> 步长
返回:
distance --> 梯度下降的距离
Theta --> 更新后的theta
'''
m = len(X[0]) # m个特征,包含x0==1这个特征
n = len(X) # n个样本
distance = [] # 梯度下降距离
for i in range(m):
nabla = 1/n * np.sum([GetH_Y(x,y,Theta)*x[i] for x,y in zip(X,Y)]) # theta对应的损失函数梯度
distance.append(nabla*Alpha) # 梯度下降距离
print(" theta: ",Theta) # 打印目前的theta
print("distance: ",distance) # 打印梯度下降距离
print("---------")
Theta = list(map(lambda x: x[0]-x[1], zip(Theta, distance))) # 更新 theta
return distance,Theta
def GradientDescent(X,Y,Theta,Alpha,Epsilon,Freq):
'''
功能:使用梯度下降法计算线性函数的参数近似值(代数法)
传入:X --> 特征,如单特征2个样本为 [[1, 1], [1, 2]],其中x0==1
Y --> 对应的样本输出
Theta --> 模型参数
Alpha --> 步长
Freq --> 迭代次数
Epsilon --> 终止迭代的阈值
返回:
'''
print("迭代第%s次"%Freq)
distance,Theta = GetDistanceAndTheta(X,Y,Alpha,Theta) # 开始迭代
AbsDistance = list(map(lambda x:abs(x),distance)) # 取梯度下降距离的绝对值
# 判断任何一个theta的梯度下降距离是否大于给定的阈值,如果为True,则继续迭代,否则终止迭代.
while (np.array(AbsDistance) > Epsilon).any():
Freq += 1 # 迭代次数加 1
print("迭代第%s次"%Freq) # 打印迭代次数
distance,Theta = GetDistanceAndTheta(X,Y,Alpha,Theta) # 继续迭代
AbsDistance = list(map(lambda x:abs(x),distance)) # 取梯度下降距离的绝对值
print("迭代终止!")
if __name__ == "__main__":
x = [[1,1], [1,2], [1,3], [1,4], [1,5]] # 其中x0==1
y = [3, 5, 7, 9, 11]
freq = 0 # 迭代次数初始化为0
theta = [0,0] # 参数初始化
alpha = 0.01 # 步长
epsilon = 0.0001 # 迭代终止条件的阈值
GradientDescent(x,y,theta,alpha,epsilon,freq)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
........................................................................
........................................................................
不难看出,前几次迭代的结果与上文手撸版一致(结果可能存在小数点差异);最终的
θ
\theta
θ值也很接近最优解
θ
0
=
1
,
θ
1
=
2
\theta_{0}=1,\theta_{1}=2
θ0=1,θ1=2。
上文计算
θ
\theta
θ的损失函数梯度时加了
1
n
\frac{1}{n}
n1,其实加和不加对对结果影响不大。比如将程序中的代码去掉
1
n
\frac{1}{n}
n1
改为
运行结果
最终迭代了419次(加
1
n
\frac{1}{n}
n1迭代了1151次),只是迭代次数减少了(针对本案例而言),但结果是相差不大的。
2.2.2 矩阵形式
import numpy as np
def GetDistanceAndTheta(X,Y,Alpha,Theta):
'''
功能:获取梯度下降的距离和迭代更新后的theta
传入:X --> 特征,如单特征2个样本为 [[1, 1], [1, 2]],其中x0==1
Y --> 对应的样本输出
Theta --> 模型参数
Alpha --> 步长
返回:
D --> 梯度下降的距离
Theta --> 更新后的theta
'''
D = np.dot(Alpha*np.array(X).T,np.dot(X,Theta)-Y)
print(" Theta: ",Theta) # 打印目前的theta
print("Distance: ",D) # 打印梯度下降距离
print("---------")
Theta -= D # 更新 theta
return D,Theta
def GradientDescent(X,Y,Theta,Alpha,Epsilon,Freq):
'''
功能:使用梯度下降法计算线性函数的参数近似值(代数法)
传入:X --> 特征,如单特征2个样本为 [[1, 1], [1, 2]],其中x0==1
Y --> 对应的样本输出
Theta --> 模型参数
Alpha --> 步长
Freq --> 迭代次数
Epsilon --> 终止迭代的阈值
返回:
'''
print("迭代第%s次"%Freq)
D,Theta = GetDistanceAndTheta(X,Y,Alpha,Theta) # 迭代第0次
AbsD = list(map(lambda x:abs(x),D)) # 取梯度下降距离的绝对值
# 判断任何一个theta的梯度下降距离是否大于给定的阈值,如果为True,则继续迭代,否则终止迭代.
while (np.array(AbsD) > Epsilon).any():
Freq += 1 # 迭代次数加 1
print("迭代第%s次"%Freq) # 打印迭代次数
D,Theta = GetDistanceAndTheta(X,Y,Alpha,Theta) # 继续迭代
AbsD = list(map(lambda x:abs(x),D)) # 取梯度下降距离的绝对值
AbsD = list(map(lambda x:abs(x),D)) # 取梯度下降距离的绝对值
print("迭代终止!")
if __name__ == "__main__":
x = [[1,1], [1,2], [1,3], [1,4], [1,5]] # 其中x0==1
y = [3, 5, 7, 9, 11]
freq = 0 # 迭代次数初始化为0
theta = [0,0] # 参数初始化
alpha = 0.01 # 步长
epsilon = 0.0001 # 迭代终止条件的阈值
GradientDescent(x,y,theta,alpha,epsilon,freq)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
........................................................................
........................................................................
- 该结果与代数形式下不加 1 n \frac{1}{n} n1 的结果一致。
- 矩阵形式的写法代码较为简洁、运行速度较快.