最優化 牛頓優化演算法

2021-08-03 00:14:55 字數 4493 閱讀 5715

本人總結的常用優化演算法pdf版本,主要講解原理:

主要包括梯度下降,共軛梯度法;牛頓法,擬牛頓法;信賴域方法,罰函式法。

# -*- coding: utf-8 -*-

"""author: uniquez_

file: 牛頓法, 基於dfp的擬牛頓法

date: 2017-06-24

remark: 原方程為(x1)**2 + 2*(x2)**2

"""import numpy as np

import matplotlib.pyplot as plt

class newton_method:

""" 使用的方向和牛頓方向有關的優化演算法: 牛頓法 & 基於dfp的擬牛頓法 """

def __init__(self, x0, gradient_threshold, method, h=none):

""" 1. 初始化

x0: 初始迭代點

x: 當前迭代點

gradient_threshold: 演算法終止的梯度閾值

h: 由梯度生成的矩陣, 取代牛頓法計算方向中的hessian矩陣;

method: "newton" & "quasi_newton_dfp" & "quasi_newton_bfgs"

"""self.x = x0

self.gradient_threshold = gradient_threshold

self.method = method

self.h = h

def compute_original_fun(self, point):

""" 2. 計算點point的函式值

point: 乙個點, 但不一定是當前的迭代點

"""value = point[0,0]**2 + 2*point[1,0]**2

return value

def compute_gradient(self):

""" 3. 計算當前迭代點的梯度值

value:當前迭代點的梯度值, 乙個矩陣

"""value = np.mat([[0],[0]], np.float)

value[0,0] = 2*(self.x[0])

value[1,0] = 2*(self.x[1])

return value

def compute_hessian(self):

""" 4. 計算當前迭代點的hessian matrix """

value = np.mat([[2, 0], [0, 4]], np.float)

return value

def is_termination(self):

""" 5. 檢驗演算法是否應該終止 """

if np.linalg.norm(self.compute_gradient()) < self.gradient_threshold:

return true

else:

return false

def correct_algorithm(self, s, y):

""" 6. 校正迭代矩陣: bfgs, dfp

s: 迭代點位移

y: 梯度差

h: 由梯度生成的矩陣, 取代牛頓法計算方向中的hessian矩陣

"""if self.method == "quasi_newton_dfp":

if s.t * y > 0:

self.h = self.h - (self.h*y*y.t*self.h)/(y.t*self.h*y) + (s*s.t)/(s.t*y)

elif self.method == "quasi_newton_bfgs":

if y.t*s > 0:

self.h = self.h - (self.h*s*s.t*self.h)/(s.t*self.h*s) + (y*y.t)/(y.t*s)

else:

raise(exception("no method founded."))

def compute_direction(self):

""" 7. 計算搜尋方向

h: 由梯度生成的矩陣, 取代牛頓法計算方向中的hessian矩陣

"""if self.method == "newton":

value = -np.linalg.inv(self.compute_hessian()) * self.compute_gradient()

elif self.method in ["quasi_newton_dfp", "quasi_newton_bfgs"]:

value = -self.h * self.compute_gradient()

else:

raise(exception("no method founded."))

return value

def compute_step(self, alpha = 1, row = 1/4):

""" 8. 計算步長

x: 當前迭代點, 乙個行向量

alpha: 初始步長, 返回步長, 步長迭代過程中每次縮短1/2, 最多迭代20次, alpha變為初始alpha的百萬分之一

row: 確定步長簡單搜尋法的乙個引數

"""gradient = self.compute_gradient()

direction = - gradient

max_iter = 20

for i in range(max_iter):

if self.compute_original_fun(self.x + alpha*direction) <= self.compute_original_fun(self.x) + alpha*row*gradient.t*direction:

break

alpha = 1/3 * alpha

if alpha < 0.1:

alpha = 0.1

if i == max_iter - 1:

print("no valid step founded.")

return alpha

def compute_next_point(self, alpha, direction):

""" 9. 計算下乙個迭代點 """

self.x = self.x + alpha * direction

def draw_result(self, point):

""" 10. 畫出迭代點的變化過程 """

plt.figure()

plt.plot(range(len(point)), point, "y")

plt.title("min value's change")

return plt

def main(self, iter_point, max_iter=1000):

""" main

method: 梯度優化演算法方面的方法: gradient(梯度下降) & cg(共軛梯度法)

max_iter: 最大迭代次數

x_last: 上乙個迭代點

g_last: 上乙個迭代點的梯度

x: 最優解

"""for i in range(max_iter):

# 演算法是否終止

if self.is_termination():

break

# 計算方向direction

direction = self.compute_direction()

# 計算步長alpha

alpha = self.compute_step()

# 計算下乙個迭代點x

x_last = self.x.copy()

g_last = self.compute_gradient().copy()

self.compute_next_point(alpha, direction)

# 校正迭代矩陣

最優化演算法 牛頓法

牛頓搜尋演算法,參考edwin 最優化導論 7.5章節,演算法採用go語言實現。filename newton search.go author fredric date 2017.09.01 note 牛頓搜尋演算法 history package search import fmt math 根...

最優化演算法 牛頓法

牛頓搜尋演算法,參考edwin 最優化導論 7.5章節,演算法採用go語言實現。filename newton search.go author fredric date 2017.09.01 note 牛頓搜尋演算法 history package search import fmt math 根...

最優化演算法3 擬牛頓法1

計算量大,每次都需要計算hesse矩陣,對於自變數維數較高的優化函式,計算量是相當大的 hesse矩陣可能存在不正定的問題,此時求得的迭代方向可能不是下降方向 為了解決上述問題,需要求hesse矩陣近似矩陣 b 將函式在 x 處二階展開 f x f x g t x x frac x x tg x x...