梯度下降
梯度下降(Gradient Descent)又称最速下降(steepest descent),是求解无约束最优化问题的一种常用方法,梯度下降法是一种迭代算法,每一步都需要求解目标函数的梯度向量。
假设f(x)f(x)f(x)是RnR^nRn上具有一阶连续偏倒数的函数,要求解以下无约束最优化问题:
minx∈Rnf(x)
\min_{x \in R^n} f(x)
x∈Rnminf(x)
令x∗x^*x∗表示要求解的目标函数f(x)f(x)f(x)的极小点,即,目标函数f(x)f(x)f(x)在x∗x^*x∗处能够取得极小值。
梯度下降法是一种迭代算法。首先选取适当的初始值x(0)x^{(0)}x(0),通过不断迭代来更新xxx的值,进行目标函数的极小化,直到收敛。由于负梯度方向是使函数值下降最快的方向,在迭代的每一步,以负梯度方向更新xxx的值,从而达到减少函数值的目的。
由于f(x)f(x)f(x)具有一阶连续偏导数,若第kkk次迭代值为x(k)x^{(k)}x(k),则可将f(x)f(x)f(x)在x(k)x^{(k)}x(k)附近进行一阶泰勒展开:
f(x)=f(x(k))+gkT(x−x(k))
f(x)=f(x^{(k)})+g_k^T(x-x^{(k)})
f(x)=f(x(k))+gkT(x−x(k))
上式中的gk=g(x(k))=∇f(x(k))g_k=g(x^{(k)})=\nabla f(x^{(k)})gk=g(x(k))=∇f(x(k))为f(x)f(x)f(x)在点x(k)x^{(k)}x(k)处的梯度。
第k+1k+1k+1次的迭代值x(k+1)x^{(k+1)}x(k+1)可有以下方式获得:
x(k+1)←x(k)+λkpk
x^{(k+1)} \leftarrow x^{(k)} + \lambda_k p_k
x(k+1)←x(k)+λkpk
上式中,pkp_kpk 是搜索方向,取负梯度方向pk=−∇f(x(k))p_k = -\nabla f(x^{(k)})pk=−∇f(x(k)),λk\lambda_kλk是步长,由一维搜索确定,即λk\lambda_kλk使得
f(x(k)+λkpk)=minλ≥0f(x(k)+λpk)
f(x^{(k)} + \lambda_k p_k) = \min_{\lambda \geq 0} f(x^{(k)} + \lambda p_k)
f(x(k)+λkpk)=λ≥0minf(x(k)+λpk)
梯度下降法具体步骤
梯度下降法具体步骤如下:
输入:目标函数f(x)f(x)f(x),梯度函数g(x)=∇f(x)g(x) = \nabla f(x)g(x)=∇f(x),计算精度ϵ\epsilonϵ;
输出:f(x)f(x)f(x)的极小值点x∗x^*x∗。
(1) 取初始值x(0)∈Rnx^{(0)} \in R^nx(0)∈Rn,令k=0k=0k=0。
(2) 计算f(x(k))f(x^{(k)})f(x(k))。
(3) 计算梯度gk=g(x(k))g_k=g(x^{(k)})gk=g(x(k)),当∣∣gk<ϵ∣∣||g_k < \epsilon||∣∣gk<ϵ∣∣时,停止迭代,并令x∗=x(k)x^* = x^{(k)}x∗=x(k);否则,令pk=−g(x(k))p_k = -g(x^{(k)})pk=−g(x(k)),求λk\lambda_kλk,使
f(x(k)+λkpk)=minλ≥0f(x(k)+λpk)
f(x^{(k)} + \lambda_k p_k) = \min_{\lambda \geq 0} f(x^{(k)} + \lambda p_k)
f(x(k)+λkpk)=λ≥0minf(x(k)+λpk)
(4) 令x(k+1)=x(k)+λkpkx^{(k+1)} = x^{(k)} + \lambda_k p_kx(k+1)=x(k)+λkpk,计算f(x(k))f(x^{(k)})f(x(k)),当∣∣f(x(k+1))−f(x(k))∣∣<ϵ||f(x^{(k+1)})- f(x^{(k)})|| < \epsilon∣∣f(x(k+1))−f(x(k))∣∣<ϵ或∣∣x(k+1)−x(k)∣∣<ϵ||x^{(k+1)}-x^{(k)}||<\epsilon∣∣x(k+1)−x(k)∣∣<ϵ时,停止迭代,并令x∗=x(k+1)x^* = x^{(k+1)}x∗=x(k+1);
(5) 否则,令k=k+1k = k+1k=k+1,转至步骤(3)。
当目标函数是凸函数时,梯度下降法的解是全局最优解。一般情况下,其解不保证是全局最优解。梯度下降法的收敛速度也未必是最快的。
示例1-求解一元函数极小值
一元函数 f(x)f(x)f(x) 为:
f(x)=(x+1)(x−1)(x+2)(x−2) f(x)=(x+1)(x-1)(x+2)(x-2) f(x)=(x+1)(x−1)(x+2)(x−2)
对 f(x)f(x)f(x) 求导可得:
f′(x)=4x3−10x f'(x)=4x^3-10x f′(x)=4x3−10x
def f(x):
"""
原函数
"""
return (x+1)*(x-1)*(x+2)*(x-2)
def df(x):
"""
导函数
"""
return 4*x**3-10*x
lr = 0.001
x = -3
for i in range(1000):
x -= lr*df(x) # 迭代
if i%100==0:
print("epoch:{},x:{}".format(i,x))
print("epoch:{},x:{}".format(i,x))
输出如下:
epoch:0,x:-2.922
epoch:100,x:-1.6594568957100684
epoch:200,x:-1.5908783935416804
epoch:300,x:-1.5824199959582812
epoch:400,x:-1.5813085551214408
epoch:500,x:-1.5811613357358625
epoch:600,x:-1.5811418147173184
epoch:700,x:-1.5811392259039174
epoch:800,x:-1.5811388825776078
epoch:900,x:-1.5811388370458432
epoch:999,x:-1.581138831026283
示例2-求解二元函数极小值
求解二元函数f(x,y)f ( x , y )f(x,y)的极小值:
f(x,y)=x3−y3+3x2+3y2−9x f ( x , y ) = x ^ { 3 } - y ^ { 3 } + 3 x ^ { 2 } + 3 y ^ { 2 } - 9 x f(x,y)=x3−y3+3x2+3y2−9x
对xxx求偏导数:
∂f∂x=3x2+6x−9 \frac{\partial f}{\partial x}=3x^2+6x-9 ∂x∂f=3x2+6x−9
对yyy求偏导数:
∂f∂y=−3y2+6y \frac{\partial f}{\partial y}=-3y^2+6y ∂y∂f=−3y2+6y
def f(x,y):
"""
参数:
x -- x 的值
y -- y 的值
返回:
v -- 当取 x, y 时,该多元函数的值
"""
v = x**3-y**3+3*x**2+3*y**2-9*x
return v
def dx(x, y):
"""
x的偏导数
参数:
x -- x 的值
y -- y 的值
返回:
v -- 当取 x, y 时,该多元函数关于 x 的偏导的值
"""
v = 3*x**2+6*x-9
return v
def dy(x, y):
"""
y的偏导数
参数:
x -- x 的值
y -- y 的值
返回:
v -- 当取 x, y 时,该多元函数关于 y 的偏导的值
"""
v = -3*y**2+6*y
return v
def df(x,y):
"""
f(x,y)的导数
"""
return dx(x, y),dy(x, y)
def gradient_descent(x, y, f, dx, dy, lr, max_iter):
"""
梯度下降法求解二元函数极小值点的计算函数
参数:
x -- 初始变量 x 的值
y -- 初始变量 y 的值
f -- 该数学函数所定义的 Python 函数
dx -- 函数 f 关于 x 的偏导数,Python 函数
dy -- 函数 f 关于 y 的偏导数,Python 函数
lr -- 学习率,即参数更新速度
max_iter -- 最大迭代次数
返回:
x -- 极小值点对应的 x 的值
y -- 极小值点对应的 y 的值
v -- 极小值点的值
"""
for i in range(max_iter):
x -= lr*dx(x,y)
y -= lr*dy(x,y)
v = f(x,y)
return x, y, v
import numpy as np
np.random.seed(10) # 设置随机数种子
# 初始点和学习率
x = np.random.randn(1)
y = np.random.randn(1)
lr = 0.1
max_iter = 1000
gradient_descent(x, y, f, dx, dy, lr, max_iter)
输出如下:
(array([1.]), array([0.]), array([-5.]))
参考:
[1] 李航. 统计学习方法.

969

被折叠的 条评论
为什么被折叠?



