optimtool最新版研究梯度优化

optimtool研究梯度优化

推荐下载2.9.0版本(加速函数计算)和github.com/linjing-lab/optimtool的最新版(优化Hessian计算):

python 复制代码
pip install optimtool==2.9.0

下载最新版的代码:

python 复制代码
git clone https://github.com/linjing-lab/optimtool.git
cd optimtool
pip install -e . --verbose

运行文件

python 复制代码
import sympy as sp
import optimtool.unconstrain as ou
x, y = sp.symbols('x y')
PI = sp.pi

# 说明:下面 12 个都是「梯度法难收敛」的经典测试函数:
#   病态 / 峡谷 / 平坦高原 / 海量局部极小 / 起点极度敏感
# 每个函数给出:表达式 + 推荐初始点(已用 L-BFGS-B 与 Adam 实测可收敛到全局最优)
# 以及「陷阱起点」注释(从这些点出发会卡在局部极小、跑飞或梯度消失)

# 1. Rosenbrock ------ 香蕉形狭长山谷,梯度下降锯齿震荡
f1 = (1 - x)**2 + 100*(y - x**2)**2
x0_1 = (-1.2, 1.0)          # 推荐(经典起点);全局最优 (1, 1), f=0
                            # 陷阱:(5, 5) ------ Adam 卡在 f≈2.85

# 2. Zakharov ------ 大范围平坦高原,梯度极小,一阶法爬行
f2 = x**2 + y**2 + (x/2 + y)**2 + (x/2 + y)**4
x0_2 = (1.0, -1.0)          # 推荐;全局最优 (0, 0), f=0
                            # 陷阱:(10, 10) / (20, 20) ------ Adam 停在 f≈0.36 / 49.1

# 3. Beale ------ 大片平坦区 + 极尖的谷,远端起步会被甩飞
f3 = (sp.Rational(3, 2) - x + x*y)**2 \
   + (sp.Rational(9, 4) - x + x*y**2)**2 \
   + (sp.Rational(21, 8) - x + x*y**3)**2
x0_3 = (2.5, 0.5)           # 推荐;全局最优 (3, 0.5), f=0
                            # 陷阱:(-4.5, -4.5) ------ L-BFGS 跑到 (-1337, 1), f=0.453

# 4. Rastrigin ------ 海量局部极小,只有落在原点「碗」内才收敛
f4 = 20 + x**2 - 10*sp.cos(2*PI*x) + y**2 - 10*sp.cos(2*PI*y)
x0_4 = (0.2, -0.2)          # 推荐(也可用 (0.5, 0.5)、(-0.5, 0.5));全局最优 (0, 0), f=0
                            # 陷阱:(1,1)→f=1.99,(2,2)→7.96,(3,3)→17.91(均为局部极小)

# 5. Griewank ------ 大碗 + 高频涟漪,距离原点 >2 就被涟漪困住
f5 = 1 + (x**2 + y**2)/4000 - sp.cos(x)*sp.cos(y/sp.sqrt(2))
x0_5 = (1.5, -1.5)          # 推荐(也可用 (1.2, 1.2)、(0.8, -0.8));全局最优 (0, 0), f=0
                            # 陷阱:(2, 2)→f=0.0666,(5, 5)→0.0074,(10,10)→0.0592

# 6. Easom ------ 全域近乎平坦,只有 (π, π) 处一个针孔式深坑
f6 = -sp.cos(x)*sp.cos(y)*sp.exp(-((x - PI)**2 + (y - PI)**2))
x0_6 = (2.9, 2.9)           # 推荐(也可用 (3.1, 3.1)、(3.5, 2.8));全局最优 (π, π), f=-1
                            # 陷阱:(1, 1) ------ Adam 卡在 (1.305, 1.305), f≈-8.1e-5

# 7. Levy N.13 ------ 起点极度敏感,稍偏一点就落进假极小
f7 = sp.sin(3*PI*x)**2 + (x - 1)**2*(1 + sp.sin(3*PI*y)**2) \
   + (y - 1)**2*(1 + sp.sin(2*PI*y)**2)
x0_7 = (1.0, 0.5)           # 推荐;全局最优 (1, 1), f=0
                            # 陷阱:(0, 0)、(0.5, 0.5) → 假极小 (0.6704, 1), f=0.1099

# 8. Styblinski--Tang ------ 多盆地,起点决定落进全局盆还是局部盆
f8 = (x**4 - 16*x**2 + 5*x + y**4 - 16*y**2 + 5*y)/2
x0_8 = (-2.5, -2.5)         # 推荐(也可用 (0, 0)、(-2, -2));全局最优 (-2.9035, -2.9035), f=-78.3323
                            # 陷阱:(2, 2)、(5, 5) → 局部极小 (2.7468, 2.7468), f=-50.06

# 9. Michalewicz ------ 极窄的谷,谷外梯度几乎为零(原地不动)
f9 = -(sp.sin(x)*sp.sin(x**2/PI)**20 + sp.sin(y)*sp.sin(2*y**2/PI)**20)
x0_9 = (2.2, 1.5)          # 推荐(也可用 (2.3, 1.6)、(2.6, 1.4)、(1.8, 1.2))
                            # 全局最优 (2.2029, 1.5708), f=-1.8013
                            # 陷阱:(0.5, 0.5) ------ 梯度≈0,直接原地卡死 f≈0

# 10. Drop-Wave ------ 同心波纹,只有极靠近原点才收敛(原点梯度奇异)
f10 = -(1 + sp.cos(12*sp.sqrt(x**2 + y**2)))/(sp.Rational(1, 2)*(x**2 + y**2) + 2)
x0_10 = (0.1, -0.1)         # 推荐(也可用 (0.05, 0.05));全局最优 (0, 0), f=-1
                            # 陷阱:(0,0) 梯度 0/0 → NaN;(0.2,0.2)→-0.786;(0.5,0.5)→-0.9362

# 11. Schwefel(限定 x, y > 0)------ 次优盆地极具欺骗性,离 420.97 太远就回不来
f11 = 418.9829*2 - (x*sp.sin(sp.sqrt(x)) + y*sp.sin(sp.sqrt(y)))
x0_11 = (420.0, 420.0)      # 推荐(也可用 (450, 450)、(480, 480)、(350, 420))
                            # 全局最优 (420.9687, 420.9687), f≈0
                            # 陷阱:(300, 300)、(200, 200) → 卡在 (203.81, 203.81), f=434.3

# 附:Himmelblau ------ 不难点在收敛,而在「起点决定落到 4 个极小点中的哪一个」
f12 = (x**2 + y - 11)**2 + (x + y**2 - 7)**2
x0_12 = (1.0, 0.5)          # → (3, 2)
                            # (-2, -2) → (-3.7793, -3.2832);(-1.2, 1) → (-2.8051, 3.1313)
                            # (3.5, -1.5) → (3.5844, -1.8481);四处 f 均为 0

FUNCS = {
    "Rosenbrock":      (f1,  x0_1),
    "Zakharov":        (f2,  x0_2),
    "Beale":           (f3,  x0_3),
    "Rastrigin":       (f4,  x0_4),
    "Griewank":        (f5,  x0_5),
    "Easom":           (f6,  x0_6),
    "Levy N.13":       (f7,  x0_7),
    "Styblinski-Tang": (f8,  x0_8),
    "Michalewicz":     (f9, x0_9),
    "Drop-Wave":       (f10, x0_10),
    "Schwefel":        (f11, x0_11),
    "Himmelblau":      (f12, x0_12),
}

if __name__ == "__main__":
    for name, (expr, x0) in FUNCS.items():
        print(f"{name:16s} x0 = {x0}")
        print(f"    f = {expr}")
        opt = ou.gradient_descent.barzilar_borwein(expr, (x, y), x0, verbose=True, epsilon=1e-4)
        print(opt, '\n')

可视化

从上到下依次是不同函数的可视化:

相关推荐
Flynt1 小时前
日涨4000星的OSINT工具,我拿Linus的用户名和一个随机字符串实测了一遍
python·安全
曲径海盗3 小时前
【Python 学习第 53 天】列表基础
python·学习笔记·编程入门
Dumbness4 小时前
群里 @ 机器人发"查订单",指令一条都没命中:微信群机器人在路由前漏掉的几步归一化
python·微信
用户1614840955454 小时前
用 M4 Pro 跑羽毛球视频 AI 分析(二):TrackNet MPS 加速 3.2 倍、卡尔曼滤波补漏与自动回合剪辑
python
用户4019925568614 小时前
基于对话树回溯的社媒评论流买方意图识别与噪音过滤实践
python
用户0332126663675 小时前
使用 Python 加密或解密 PDF 文档
python
小七-七牛开发者5 小时前
让 Go 走得更远:用 LLGo 打通 Go 与 C/C++/Python 生态
python·编程·编译器·llvm·llgo
CyrusYiVPP6 小时前
实测 Ollama 本地部署:我用 Python 搓了个离线问答机器人,Qwen4 27B 一到换个模型名就能用
人工智能·python
2601_967980117 小时前
Python中flatten( )函数及函数用法详解
python·numpy·数组操作·flatten函数·列表处理
xbzb7 小时前
自定义 yum 软件源:Linux 上 createrepo,Windows 上纯 Python 也能造
linux·运维·windows·python·yum·createrepo