这就是我们今天要求的2D函数:
下图是使用python绘制出来的图像:
但是可以看出有4个最小值,但是还是不够直观,还是看课程里面给的比较好,蓝色是最低点位置:
课时46 优化问题实战_哔哩哔哩_bilibili
实际求的最小值:
代码示例:
python
import torch
import numpy as np
from matplotlib import pyplot as plt
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.shape:',x.shape,';y.shape:',y.shape)
X, Y = np.meshgrid(x,y) # 将X、Y进行网格化,将一维数组变为二维数组
print('X.map:',X.shape,';Y.map:',Y.shape)
Z = himmelblau([X,Y]) # 计算Z
fig = plt.figure('himmelblau') # 创建himmelblau图
ax = fig.add_subplot(projection='3d') # 获得当前极轴
ax.plot_surface(X,Y,Z) # 绘制三维平面
ax.view_init(60,-30) # 确定视图的角度
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()
# 2D函数优化
x = torch.tensor([4.,0.],requires_grad=True) # 初始化x值,requires_grad=True代表需要梯度信息
# 可以尝试改变初始化x的值,会得到不一样的结果,因此初始化值是十分重要的
optimizer = torch.optim.Adam([x],lr=1e-3) # 初始化优化器
for step in range(20000):
pred = himmelblau(x)
optimizer.zero_grad() # 当网络参量进行反馈时,梯度是被积累的而不是被替换掉,这里即每次将梯度设置为0
pred.backward() # 调出x、y的梯度信息
optimizer.step() # 根据优化信息更新优化的值x[0] x[1]
if step%2000 == 0: # 每2000个打印一组值
print('step {}:x={},f(x)={}'.format(step,x.tolist(),pred.item()))