文章目录
一、梯度下降法的原理介绍
(一)梯度下降法
梯度下降(gradient descent)主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。所以,它是一种常用的求解无约束最优化问题的方法,在最优化、统计学以及机器学习等领域有着广泛的应用。
(二)梯度下降的相关概念及描述
- 下山过程描述
场景描述:一个人需要从山的某处开始下山,尽快到达山底。
下山过程重要的信息:方向和距离
为了尽快的到达山底,需要选择最陡峭的方向下山。而且,在下山的过程中,下山方向也并不是一层不变的,每过一段距离,就需要重新选择方向。
说明:该图引用此链接https://arrow.blog.csdn.net/article/details/86583789
- 梯度下降的过程内容描述
梯度下降的过程跟下山过程很相似。两者结合来看,山就等同于我们需要优化的函数表达式,山的最低点就等同于我们求解的最优值,而每次下山的距离就是梯度下降中的学习率,寻找方向利用的信息就是样本数据,某处就是优化函数设置的初始值。
求解最优解的过程,就是利用初始值不断迭代求解得到的。 - 梯度的概念
①认识微分
单变量的微分
例: d x 2 d x = 2 x {\frac{d{x^2}}{d{x}}}=2x dxdx2=2x
多变量的微分
例: ∂ x 2 y 2 ∂ x = 2 x y 2 {\frac{\partial {x^2y^2}}{\partial x}}=2x{y^2} ∂x∂x2y2=2xy2
②梯度
在数学上,梯度是多变量微分的一般化
例:
f ( x , y , z ) = 0.55 − ( 5 x + 2 y − 12 z ) {f(x,y,z)=0.55−(5x+2y−12z )} f(x,y,z)=0.55−(5x+2y−12z)
梯度
g r a d f ( x , y , z ) = ▽ f ( x , y , z ) = ( ∂ f ( x , y , z ) ∂ x , ∂ f ( x , y , z ) ∂ y , ∂ f ( x , y , z ) ∂ z ) = ( − 5 , − 2 , 12 ) {gradf(x,y,z)=▽f(x,y,z)=(\frac{\partial f(x,y,z)}{\partial x},\frac{\partial f(x,y,z)}{\partial y},\frac{\partial f(x,y,z)}{\partial z})}=(-5,-2,12) gradf(x,y,z)=▽f(x,y,z)=(∂x∂f(x,y,z),∂y∂f(x,y,z),∂z∂f(x,y,z))=(−5,−2,12)
由此,看来梯度是一个向量,向量包括大小和方向,所以梯度的方向就指出了函数在给定点的上升最快的方向,而梯度的反方向就是函数在给定点下降最快的方向。
4.梯度下降的数学解释
数学公式:
Θ 1 = Θ 0 + α ▽ J ( Θ ) → e v a l u a t e d a t Θ 0 {{\color{Red} \Theta^1} ={\color{Blue} \Theta^0}+ {\color{Green} \alpha} {\color{Purple} \triangledown J(\Theta)} → e v a l u a t e d a t Θ^0} Θ1=Θ0+α▽J(Θ)→evaluatedatΘ0
公式意义:J表示关于Θ的一个函数,初始位置为 Θ 0 {Θ^0} Θ0点,要从 Θ 0 {Θ^0} Θ0走到J的最小值点(山底)。我们先确定前进的方向(梯度的反向),然后走一段距离的α(步长/学习率),走完这个段步长,就到达了 Θ 1 {Θ^1} Θ1。补充:
α(步长/学习率)取值不能太大也不能太小,太小的话,可能导致迟迟走不到最低点,太大的话,会导致错过最低点。
(三)梯度下降算法原理
- 批量梯度下降法(Batch Gradient Descent, BGD)
批量梯度下降法在计算优化函数的梯度时利用全部样本数据,n表示总的样本数
梯度计算公式:
迭代公式:
- 小批量梯度下降法(Mini-batch Gradient Descent, MBGD)
随机梯度下降法在计算优化函数的梯度时利用随机选择的一个样本数据
梯度计算公式:
迭代公式:
- 随机梯度下降法(Stochastic Gradient Descent, SGD)
小批量梯度下降法在计算优化函数的梯度时利用随机选择的一部分样本数据,k表示选取样本的数目
梯度计算公式:
迭代公式为:
三种方式的比较
BGD(批量 | SGD(随机) | MBGD(小批量) | |
---|---|---|---|
优点 | 非凸函数可保证收敛至全局最优解 | 计算速度快 | 计算速度快,收敛稳定 |
缺点 | 计算速度缓慢,不允许新样本中途进入 | 计算结果不易收敛,可能会陷入局部最优解中 | —— |
二、梯度下降法的一般求解步骤
- 给定待优化连续可微函数 J ( Θ ) {J\left ( \Theta \right)} J(Θ)、学习率 α {\alpha} α以及一组初始值 Θ 0 = ( θ 01 , θ 02 , ⋯ , θ 0 l , ) {\Theta_{0}=\left ( \theta_{01}, \theta_{02}, \cdots, \theta_{0l}, \right )} Θ0=(θ01,θ02,⋯,θ0l,)
- 计算待优化函数梯度: ▽ J ( Θ 0 ) {\triangledown J\left ( \Theta _{0} \right )} ▽J(Θ0)
- 更新迭代公式: Θ 0 + 1 = Θ 0 − α ▽ J ( Θ 0 ) {\Theta^{0+1}=\Theta _{0}-\alpha \triangledown J\left ( \Theta _{0} \right )} Θ0+1=Θ0−α▽J(Θ0)
- 计算 Θ 0 + 1 {\Theta^{0+1}} Θ0+1处函数梯度 ▽ J ( Θ 0 + 1 ) {\triangledown J\left ( \Theta _{0+1} \right)} ▽J(Θ0+1)
- 计算梯度向量的模来判断算法是否收敛: ∥ ▽ J ( Θ ) ∥ ⩽ ε {\left\| \triangledown J\left ( \Theta \right ) \right \|\leqslant \varepsilon} ∥▽J(Θ)∥⩽ε
- 若收敛,算法停止,否则根据迭代公式继续迭代直至收敛
三、梯度下降法手工求解极值
(一)题目描述
(二)计算过程
- 设置初始点及学习率
初始点: x 0 = ( x 1 ( 0 ) , x 2 ( 0 ) ) ⊤ = ( 3 , 2 ) ⊤ {x^0=\left ( x_{1}^{\left ( 0 \right )},x_{2}^{\left ( 0 \right )} \right )^{\top }=\left ( 3,2 \right )^{\top }} x0=(x1(0),x2(0))⊤=(3,2)⊤
学习率: λ {\lambda} λ说明:
初始点和学习率是自己随意设置的,这里学习率就不预设值,当然也可以预先设置学习率的值,只不过取值不是很好确定,取值取得不是很好,可能要迭代很多次 - 计算初始点的梯度
梯度计算
▽ f ( x ) = ( 2 3 x 1 , x 2 ) {\triangledown f(x)=(\frac {2}{3}x_{1},x_{2})} ▽f(x)=(32x1,x2)
初始点的梯度(将 x 0 {x^0} x0的值代入上面的梯度计算)
▽ f ( x 0 ) = ( 2 , 2 ) {\triangledown f(x^0)=(2,2)} ▽f(x0)=(2,2) - 更新迭代公式
f ( x 1 ) = f ( x 0 − λ ▽ f ( x 0 ) ) = 10 3 λ 2 − 8 λ + 5 {f(x^1)=f(x^0-\lambda \triangledown f(x^0))=\frac{10}{3}\lambda^2-8\lambda+5} f(x1)=f(x0−λ▽f(x0))=310λ2−8λ+5
λ 0 = 6 5 {\lambda^{0}=\frac{6}{5}} λ0=56为函数极小点
更新后的迭代公式 x 1 = x 0 − λ 0 ▽ f ( x 0 ) = ( 3 5 , − 2 5 ) {x^{1}=x^{0}-\lambda ^{0}\triangledown f(x^0) =\left ( \frac{3}{5},-\frac{2}{5} \right )} x1=x0−λ0▽f(x0)=(53,−52)
重复上面过程可以得到 x 2 = ( 3 5 2 , 2 5 2 ) {x^{2}=\left ( \frac{3}{5^{2}},\frac{2}{5^{2}} \right )} x2=(523,522)
通过总结可以得到 x k = ( 3 5 k , ( − 1 ) k 2 5 k ) {x^{k}=\left ( \frac{3}{5^{k}},(-1)^{k} \frac{2}{5^{k}} \right )} xk=(5k3,(−1)k5k2)
不断的迭代,直到 x k = ( 0 , 0 ) {x^{k}=(0,0)} xk=(0,0)为止
四、Excel中利用梯度下降求解近似根
求解 z = 2 ( x − 1 ) 2 + y 2 { z=2(x-1)^2+y^2} z=2(x−1)2+y2 的近似根
- 设置表格的一些基本内容
- 设置(x,y)的初始值为(2,1)
- 其他表格输入相应的计算公式
∂ z ∂ x = 4 ∗ ( x − 1 ) {\frac{\partial z}{\partial x}=4*(x-1)} ∂x∂z=4∗(x−1)
∂ z ∂ y = 2 y {\frac{\partial z}{\partial y}=2y} ∂y∂z=2y
Δ x = η ∂ z ∂ x {\Delta x=\eta \frac{\partial z}{\partial x}} Δx=η∂x∂z
Δ y = η ∂ z ∂ y {\Delta y=\eta \frac{\partial z}{\partial y}} Δy=η∂y∂z
其他位置的按照公式输入相应的内容,然后安装从左向右的顺序,向下拉取多格 - 多次迭代结果
当学习率取0.1的时候,迭代2000多次仍旧没有出现函数值为0的情况,所以更改学习率为0.15
结果
由此,可得到其近似值为(1,0)
五、线性回归问题求解
(一)最小二乘法
-
代码
定义数据及设置相关数值from sklearn import linear_model #可以调用sklearn中的linear_model模块进行线性回归 import seaborn as sns # 定义数据集的大小 即20个数据点 m = 20 # x的坐标以及对应的矩阵 X0 = ones((m, 1)) # 生成一个m行1列的向量,其值全是1 X1 = arange(1, m+1).reshape(m, 1) # 生成一个m行1列的向量,也就是x1,从1到m X = hstack((X0, X1)) # 按照列堆叠形成数组,其实就是样本数据 # 对应的y坐标 Y = np.array([ 3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12, 11, 13, 13, 16, 17, 18, 17, 19, 21 ]).reshape(m, 1)
进行线性回归
#进行线性回归的求解 model = linear_model.LinearRegression() model.fit(X1,Y) print("斜率=",model.coef_[0]) print("截距为=",model.intercept_)
线性结果绘制# 根据数据画出对应的图像 def plot(X, Y, theta): ax = plt.subplot(111) # 将画布分为1行1列,取第一个 ax.scatter(X, Y, s=30, c="blue", marker="s") plt.xlabel("X") plt.ylabel("Y") x = arange(0, 21, 0.2) # x的范围 y = model.intercept_+ model.coef_[0]*x ax.plot(x, y) plt.show() plot(X1, Y, model.coef_[0])
(二)梯度下降
-
代价函数
-
代码
定义数据及设置相关数值from numpy import * # 定义数据集的大小 即20个数据点 m = 20 # x的坐标以及对应的矩阵 X0 = ones((m, 1)) # 生成一个m行1列的向量,其值全是1 X1 = arange(1, m+1).reshape(m, 1) # 生成一个m行1列的向量,也就是x1,从1到m X = hstack((X0, X1)) # 按照列堆叠形成数组,其实就是样本数据 # 对应的y坐标 Y = np.array([ 3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12, 11, 13, 13, 16, 17, 18, 17, 19, 21 ]).reshape(m, 1) # 学习率 alpha = 0.01 import matplotlib.pyplot as plt #绘制出数据集 plt.scatter(X1,Y,color='red') plt.show()
代价函数定义及代价函数的梯度函数# 定义代价函数 #损失函数(loss function)或代价函数(cost function)是将随机事件或其有关随机变量的取值映射为非负实数以表示该随机事件的“风险”或“损失”的函数 def cost_function(theta, X, Y): diff = dot(X, theta) - Y # dot() 数组需要像矩阵那样相乘,就需要用到dot() return (1/(2*m)) * dot(diff.transpose(), diff) # 定义代价函数对应的梯度函数 def gradient_function(theta, X, Y): diff = dot(X, theta) - Y return (1/m) * dot(X.transpose(), diff)
梯度下降迭代
# 梯度下降迭代 def gradient_descent(X, Y, alpha): #将[1,1]变为2行1列的形式 theta = array([1, 1]).reshape(2, 1) #得到代价函数的初始梯度 gradient = gradient_function(theta, X, Y) #不断迭代的过程 while not all(abs(gradient) <= 1e-5): #更新迭代公式 theta = theta - alpha * gradient #更新迭代所用的梯度 gradient = gradient_function(theta, X, Y) return theta #梯度下降最终的结果 optimal = gradient_descent(X, Y, alpha) print('optimal:', optimal) print('cost function:', cost_function(optimal, X, Y)[0][0])
线性结果绘制# 根据数据画出对应的图像 def plot(X, Y, theta): ax = plt.subplot(111) # 将画布分为1行1列,取第一个 ax.scatter(X, Y, s=30, c="red", marker="s") plt.xlabel("X") plt.ylabel("Y") x = arange(0, 21, 0.2) # x的范围 y = theta[0] + theta[1]*x ax.plot(x, y) plt.show() plot(X1, Y, optimal)
(三)两种方法的对比
最小二乘法
梯度下降法
两个最终得到的结果相差极其小,小到差距可以被忽略。从代码量来说,最小二乘法是直接调用sklearn中linear_model.LinearR egression()
来进行求解的,相对于梯度下降的方法来说,会更加快计算出结果。通过这个方法,还是比较好理解梯度下降的整个原理过程的实现。
六、参考链接
深入浅出–梯度下降法及其实现
梯度下降算法原理讲解——机器学习
机器学习算法:梯度下降法——原理篇
人工智能与机器学习——梯度下降法求函数极值
详解:如何用Python实现机器学习算法(1)