zoukankan      html  css  js  c++  java
  • 机器学习中常见优化方法汇总

    http://www.scipy-lectures.org/advanced/mathematical_optimization/index.html#a-review-of-the-different-optimizers

    机器学习中数学优化专门用于解决寻找一个函数的最小值的问题。这里的函数被称为cost function或者objective function,或者energy:损失函数或者目标函数。

    更进一步,在机器学习优化中,我们并不依赖于被优化的函数的数学解析表达式,我们通过使用$scipy.optimize$从而实现类似黑盒优化。

    了解你的优化问题本身

    并不是所有的优化问题都是一样的,如果你能对你待优化的问题本身有一个深刻的理解,这样可以选择正确的优化方法。

    1.其中非常重要的一点就是要考察问题本身的维数。问题本身数据的维数(标量变量的个数)决定了优化问题的规模。

    2.convex和non-convex优化

    凸函数的特征:

    • $f$总是在其切线之上
    • 或者说,对于两个点$A,B$,如果$A<C<B$,则$f(C)$总是在线段$f(A),f(B)$之间

    凸函数优化相对非常简单。

     3.函数光滑与否(是否处处可导)

    4. loss函数以及gradient函数是否存在噪声

    如果gradient没有解析式,那么我们都须通过计算式计算,这必然导致误差。

    5. 是否有限制条件

    比如,下图中就要求优化只能在$x_1,x_2 in (-1,1)$间优化

    常见的优化方法

    Brent’s method 

    理论依据是中值定理,对于一个连续函数,$f$,如果两个端点a,b的函数值$f(a)f(b)<0$,则$(a,b)$之间必然存在一个驻点(导数为0),我们可以不断迭代最终求得驻点;

    from scipy import optimize
    def f(x):
        return -np.exp(-(x - 0.7)**2)
    result = optimize.minimize_scalar(f)
    result.success # check if solver was successful
    
    x_min = result.x

    gradient based methods

    简单梯度下降法

    原理如教科书的描述,根据梯度下降的方向去做数值变更和迭代,最终求得驻点。

    存在的问题是:参数调整时可能反复跨过驻点从而形成震荡,虽然减少参数调整的布幅可以减轻这个问题,但是无法彻底解决。

    共轭梯度下降

    共轭算法在简单梯度下降基础上增加一个摩擦项(friction term),每个step依赖于梯度最近的两个值,这样可以有效解决反复震荡问题。

    def f(x):   # The rosenbrock function
        return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2
    optimize.minimize(f, [2, -1], method="CG")    

    梯度优化方法需要loss函数的雅可比(梯度)值,虽然即使你不传入导数(雅可比矩阵是针对y值为向量的情况下的梯度向量),算法也能够通过数值计算方法算出来,但是如果有解析表达式,我们传入这个值会大大提升收敛效率.

    def jacobian(x):
        return np.array((-2*.5*(1 - x[0]) - 4*x[0]*(x[1] - x[0]**2), 2*(x[1] - x[0]**2)))
    optimize.minimize(f, [2, 1], method="CG", jac=jacobian)    

    注意:通过传入解析表达式后,只需要28次就能收敛,而之前需要108次迭代才能收敛。

    牛顿梯度法(Newton and quasi-newton methods)

    def f(x):   # The rosenbrock function
        return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2
    def jacobian(x):
        return np.array((-2*.5*(1 - x[0]) - 4*x[0]*(x[1] - x[0]**2), 2*(x[1] - x[0]**2)))
    optimize.minimize(f, [2,-1], method="Newton-CG", jac=jacobian)    

    BFGS

    BFGS在牛顿法基础上细调了Hessian矩阵的估算方法

    L-BFGS

    L-BFGS位于BFGS和共轭梯度法之间。对于非常高维(大于250个)的loss函数,Hessian矩阵的计算是非常耗时的,L-BFGS keeps a low-rank version.

    非梯度优化方法

    Powell算法

    Nelder-Mead

    带约束条件的函数优化

    盒子边界

    def f(x):
       return np.sqrt((x[0] - 3)**2 + (x[1] - 2)**2)
    optimize.minimize(f, np.array([0, 0]), bounds=((-1.5, 1.5), (-1.5, 1.5))) 

     通用约束:拉格朗日乘数法化约束为对偶无约束的优化问题

    def f(x):
        return np.sqrt((x[0] - 3)**2 + (x[1] - 2)**2)
    
    def constraint(x):
        return np.atleast_1d(1.5 - np.sum(np.abs(x)))
    
    x0 = np.array([0, 0])
    optimize.minimize(f, x0, constraints={"fun": constraint, "type": "ineq"}) 
  • 相关阅读:
    [Ljava.lang.String; cannot be cast to java.lang.String 报错的原因
    ajaxfileupload多文件上传
    如何设置 html 中 select 标签不可编辑、只读
    docker
    nvm use 指定版本后无效 win7
    win7禁用Adnimistrator账号登录
    win10安装tomcat9
    webstorm命令行无法使用node-gyp进行编译
    tomcat7.0安装笔记
    win10 java1.7安装笔记
  • 原文地址:https://www.cnblogs.com/kidsitcn/p/9535306.html
Copyright © 2011-2022 走看看