himmelblau函数:
该函数用于检测优化器的效果。可以通过求解这个函数,来看一下我们设计的优化器,或者我们设计的梯度下降法则,能否很好的找到这个解,我们的解是已知的。可以对比两个的差距。
已知最小值:
f(3.0,2.0)=0
f(-2.805118,3.131312)=0
f(-3.779310,-3.283186)=0
f(3.584428,-1.848126)=0
都是全局最小值。
import torch
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
def himmelblau(x):
return (x[0]**2+x[1]-11)**2+(x[0]+x[1]**2-7)**2
# 可视化代码,打印出函数图像
#生成x和y轴数据列表
x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print('x,y range:',x.shape,y.shape)
#对x和y数据进行网格化
X,Y = np.meshgrid(x,y)
print('X,Y maps:',X.shape,Y.shape)
Z = himmelblau([X,Y])
fig=plt.figure('himmelblau')
ax =fig.add_subplot(projection='3d')
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x')
ax.set_xlabel('y')
plt.show()
#x可初始化为[1.,0.],[-4,0.],[4,0.]
x=torch.tensor([0.,0.],requires_grad=True)
optimizer = torch.optim.Adam([x],lr=1e-3)
for step in range(20000):
pred = himmelblau(x)
optimizer.zero_grad()
pred.backward()
optimizer.step()
if step % 2000 == 0:
print('step {}: x={},f(x)={}'.format(step,x.tolist(),pred.item()))
变换x的初始值,可以得到其他三个极小值。
optimizer = torch.optim.Adam([x],lr=1e-3)
优化器的目标是x,这一步会自动完成:
x‘=x-0.001▽x
y‘=y-0.001▽y
只要执行一次optimizer.step(),就会更新一次以上两个的过程。
optimizer.zero_grad()将梯度信息清零。
pred.backward()生成x和y的梯度信息▽x和▽y。
不停循环循环,直到找到合适的x和y。
修改x为:x=torch.tensor([-4,0.],requires_grad=True)