基于pyTorch应用的2D函数优化实例
内容来自:
https://www.bilibili.com/video/BV1Rv411y7oE?p=36
首先选定一个简单的2D函数
用3D曲线表达如图所示
通过图像容易观察到有四个最小值解,该解可以直接通过高斯扰动直接解出来:
下面通过求解该函数验证一下设置的优化是否成功:
首先将该函数实现出来
def himmelblau(x):
return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print('x,y range:',x.shape,y.shape)
X,Y = np.meshgrid(x,y)
print('X,Y maps:',X.shape,Y.shape)
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()
下面使用随机梯度方法进行求解
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()
# x' = x - lr * delta
# y' = y - lr * delta
optimizer.step()
if step % 2000 ==0:
print(f"step {step}: x = {x.tolist()} f(x) = {pred.item()}")
根据运行结果可以观察到找到的一个最小点是(3,2)与高斯扰动的解一致
然后更改一下初始化寻求验证其它解
x = torch.tensor([-6.,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()
# x' = x - lr * delta
# y' = y - lr * delta
optimizer.step()
if step % 2000 ==0:
print(f"step {step}: x = {x.tolist()} f(x) = {pred.item()}")
该点为(-3.77,-3.28)亦与高斯扰动的解一致