机器学习小插曲:几种常见的优化方法,梯度下降、牛顿法、拟牛顿以及共轭梯度法

1.梯度下降法:

梯度下降法是最早最简单,也是最为常用的最优化方法。梯度下降法实现简单,当目标函数是凸函数时,梯度下降法的解是全局解。一般情况下,其解不保证是全局最优解,梯度下降法的速度也未必是最快的。梯度下降法是寻找当前点下降最快的方向。

梯度下降就是希望寻找我们的最优解,也就是希望f(x^{t+1})<f(x^t),然后根据我们的泰勒公式展开:

f(x+\bigtriangleup x)\simeq f(x)+\bigtriangleup x^T\bigtriangledown f(x),欲满足f(x+\bigtriangleup x)< f(x),那么可以选择:

                                                                  \bigtriangleup x = -\gamma \bigtriangledown f(x)

利用最简单的线性方程来解释:

令输入为x,实际输出为h(x),真实值为y。

假设有两个参数,那么:

然后引入我们的损失函数:

然后为了寻找减少我们损失函数使得h(x)与y更加的接近,就不得不改变h当中的参数,对\theta进行求导:

然后按照公式\bigtriangleup x = -\gamma \bigtriangledown f(x)来更新\theta

主要过程就这么简单,举个简单的小例子来进行实现:

假设y,x之间存在如下关系(实际上电脑不知道):

y = 2x_1+x_2+3

实际上就是求解:

y = ax_1+bx_2+c

代码如下:

import numpy as np
import matplotlib.pyplot as plt
#y=2 * (x1) + (x2) + 3 
rate = 0.001
x_train = np.array([[1, 2],[2, 1],[2, 3],[3, 5],[1, 3],[4, 2],[7, 3],[4, 5],[11, 3],[8, 7]])
y_train = np.array([7, 8, 10, 14, 8, 13, 20, 16, 28, 26])
x_test  = np.array([[1, 4],[2, 2],[2, 5],[5, 3],[1, 5],[4, 1]])

a = np.random.normal()
b = np.random.normal()
c = np.random.normal()

def h(x):
    return a*x[0]+b*x[1]+c

for i in range(10000):
    sum_a=0
    sum_b=0
    sum_c=0
    for x, y in zip(x_train, y_train):
        sum_a = sum_a + rate*(y-h(x))*x[0]
        sum_b = sum_b + rate*(y-h(x))*x[1]
        sum_c = sum_c + rate*(y-h(x))
    a = a + sum_a
    b = b + sum_b
    c = c + sum_c

梯度下降法又分常用的两种:

批量梯度下降---最小化所有训练样本的损失函数,使得最终求解的是全局的最优解,即求解的参数是使得风险函数最小,但是对于大规模样本问题效率低下。

随机梯度下降---最小化每条样本的损失函数,虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近,适用于大规模训练样本情况。

2.牛顿法:

当f(x)二阶连续可微时,将泰勒公式展开成更为精确的二阶,就形成了牛顿法,因为牛顿法的“目光”更为长远,可以理解为如果需要下降两次,梯度下降就是每一次都寻找最快下降点,而牛顿会综合两次寻找最快点,牛顿法的迭代次数远小于梯度下降,但由于涉及到海森矩阵(第i行第j列上的元素为(\bigtriangledown ^2f(x))_{ij} = \frac{\partial ^2f(x)}{\partial x_i \partial x_j} )

牛顿法的具体实现过程如下:

具体的迭代关系如下:

多数情况下\theta都是矩阵,就用如下的计算公式:

然后接受一个具体的实例来解释公式的应用:

利用函数:f(x) = 100(x_2 - x_1^2)^2 + (1 - x_1)^2

一阶导为:\triangledown f(x) = (-400(x_2 - x_1^2)x_1 - 2(1-x_1),200(x_2 - x_1^2))^T

然后根据上面提到的海森公式,计算海森矩阵:

H(x) = \begin{bmatrix} -400(x_2 - 3x_1^2)+2&-400x_1 \\ -400x_1& 200 \end{bmatrix}

然后利用python实现这个过程:

#梯度的公式
def tidu(x):
    return np.array([-400*x[0]*(x[1]-x[0]**2)-2*(1-x[0]),200*(x[1]-x[0]**2)])

#海森矩阵的公式
def hessian(x):
    return np.array([[-400*(x[1]-3*x[0]**2)+2,-400*x[0]],[-400*x[0],200]])

#牛顿法
def newton(x):
    print("初始点为 : ",x)
    res=[]
    res.append(x)
    i = 1
    imax = 1000
    delta = 1
    #迭代的条件是小于imax,或者是更新的距离小于一个很小的数值
    while i<imax and delta>10**(-5):
        p = -np.dot(np.linalg.inv(hessian(x)),tidu(x))#求逆相乘
        x_new = x + p
        res.append(x_new)
        delta = sum((x-x_new)**2)   # 更新的距离
        print("初始点为 : ",x_new)
        i=i+1
        x=x_new  # 更新x
    return np.array(res)

3.拟牛顿法:

拟牛顿法的本质思想是改善牛顿法每次需要求解复杂的Hessian矩阵的逆矩阵的缺陷,它使用正定矩阵来近似Hessian矩阵的逆,从而简化了运算的复杂度

4.共轭梯度法:

共轭梯度法是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算海森矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值