本人總結的常用優化演算法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...