himmelblau函数优化
概述
himmelblau函数是数学家们构造出来的一个特殊的函数,可以用来测试深度学习算法是否能够收敛到局部最小值。这个函数的表达式是:
f
(
x
,
y
)
=
(
x
2
+
y
−
11
)
2
+
(
x
+
y
2
−
7
)
2
f(x,y)=(x^2+y-11)^2+(x+y^2-7)^2
f(x,y)=(x2+y−11)2+(x+y2−7)2
这个函数最小值为0,有四个最小值点,分别是:
f
(
3.0
,
2.0
)
=
0
f
(
−
2.805118
,
3.131312
)
=
0
f
(
−
3.779310
,
−
3.283186
)
=
0
f
(
3.584428
,
−
1.848126
)
=
0
f(3.0,2.0)=0\\f(-2.805118,3.131312)=0\\f(-3.779310,-3.283186)=0\\f(3.584428,-1.848126)=0
f(3.0,2.0)=0f(−2.805118,3.131312)=0f(−3.779310,−3.283186)=0f(3.584428,−1.848126)=0
求解过程
添加头文件
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as plt
import torch
绘制himmelblau函数的图像
# 书写himmelblau函数
def himmelblau(x):
return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
# 绘制himmelblau函数的三维图像
# 通过x,y两个张量调用meshgrid方法生成一个网格
x = np.arange(-6, 6, 0.1)
y = np.arange(-6, 6, 0.1)
X, Y = np.meshgrid(x, y)
# 网格上每一个点x,y带入himmelblau求出z
Z = himmelblau([X, Y])
# 作图
fig = plt.figure('himmelblau')
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z)
ax.view_init(60, -30)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()
得到如下图像,可以清楚的看到himmelblau函数的曲面有四个最小值点
梯度下降
# 梯度下降法求局部最小值
# 初始坐标
x = torch.tensor([0., 4.], requires_grad=True)
# 构造优化器
optimizer = torch.optim.Adam([x], lr=1e-3)
# 进行20000轮下降
for step in range(20000):
# 要找到himmelblau的最小值,损失函数就是himmelblau的函数值
pred = himmelblau(x)
# 清空各参数的梯度
optimizer.zero_grad()
# 反向传播重新计算各参数的梯度
pred.backward()
# 优化器更新参数x'=x-lr*梯度
optimizer.step()
if step % 2000 == 0:
print('step {}:x={},f(x)={}'.format(step, x.tolist(), pred.item()))
当初始化为(0,0)时,陷入了(3,2)这个局部最小值
当初始化为(0,4)时,陷入了(-2.80,3.13)这个局部最小值
由此可见初始化位置的不同将会影响最终收敛到哪个局部最小值