深度学习基础:数值计算与优化(二)_基于梯度的二阶优化算法_Jacobian矩阵_Hessian矩阵_牛顿法_拟牛顿法_DFP_BFGS

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

import numpy as np
from scipy import optimize
  • 定义要求最小值的函数,这里以 f ( x , y ) = ( 1 x ) 2 + 100 ( y x 2 ) 2 为例
# 定义目标函数
def target_function(x,y):
    return (1-x)**2+100*(y-x**2)**2
  • 计算出定义函数的Jacobian矩阵和Hessian矩阵(BFGS不需要Hessian矩阵,但是其他算法需要,所有可以提前计算出来)
  • 由于 f x = 2 + 2 x 400 x ( y x 2 ) , f y = 200 y 200 x 2 ,所以Jacobian矩阵为

(1) [ 2 + 2 x 400 x ( y x 2 ) 200 y 200 x 2 ]

+ 由于 2 f x 2 = 2 ( 600 x 2 200 y + 1 ) , 2 f x y = 2 f y x = 400 x , 2 f y 2 = 200 ,所有Hessian矩阵为

(2) [ 2 ( 600 x 2 200 y + 1 ) 400 x 400 x 200 ]

  • 使用一个类来保存函数、函数的Jacobian矩阵、函数的Hessian矩阵
class TargetFunction(object):
    def __init__(self):
        self.f_points = []
        self.fjac_points = []
        self.fhess_points = []

    def f(self,p):
        '''
        给定点p(x,y),返回函数值f(x,y)
        '''
        x,y = p.tolist()
        z = target_function(x,y)
        self.f_points.append((x,y))
        return z

    def fjac(self,p):
        '''
        给定点p(x,y),返回函数在点p处的Jacobian矩阵
        '''
        x,y = p.tolist()
        self.fjac_points.append((x,y))
        dx = -2 + 2*x -400*x*(y-x**2)
        dy = 200*y -200*x**2
        return np.array([dx,dy])

    def fhess(self,p):
        '''
        给定点p(x,y),返回函数在点p处的Hessian矩阵
        '''
        x,y = p.tolist()
        self.fhess_points.append((x,y))
        hess = np.array([[2*(600*x**2-200*y+1),-400*x],
                        [-400*x,200]])
        return hess

函数原型:scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None);常用参数解释如下:

fun:取局部最小值的函数

x0:初始点

method:优化方法,包括Nelder-Mead、Powell、CG、BFGS、Newtom-CG、L-BFGS-B、TNC、COBYLA、SLSQP、dogleg、trust-ncg、

jac:计算函数fun的Jacobian矩阵

hessian:计算函数fun的Hessian矩阵

target = TargetFunction()
# 初始点
init_point = (-1,-1)
# 使用BFGS求局部极小值
res = optimize.minimize(target.f,init_point,method="BFGS",jac=target.fjac)
print(res)
      fun: 1.8499217223747175e-16
 hess_inv: array([[ 0.50825961,  1.01607777],
       [ 1.01607777,  2.03629519]])
      jac: array([  2.76270214e-07,  -1.26083165e-07])
  message: 'Optimization terminated successfully.'
     nfev: 40
      nit: 31
     njev: 40
   status: 0
  success: True
        x: array([ 1.00000001,  1.00000002])

猜你喜欢

转载自blog.csdn.net/bqw18744018044/article/details/81356557
今日推荐