pytorch:2D函数优化举例

我们以函数f(x)=\left ( x^{2}+y-11 \right )^{2}+\left ( x+y^{2} -7\right )^{2}为例,这个函数专用于检测优化器的效果。

理论上得到的图像和极小值结果为

 我们将这一部分用代码实现

import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as plt
import torch



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) # meshgrid()将x,y的范围传进去后,生成两个图片,每张图片的点和他相同位置的点拼在一起,就形成一个坐标(x,y)
# 如果每个图片都有120个点,那这个map就是120*120的
print('X,Y maps:',X.shape,Y.shape)
Z=himmelblau([X,Y]) # 得到Z的坐标

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()


# [1,0],[-4,0],[4,0]
x=torch.tensor([0.,0.],requires_grad=True)  # 梯度信息设置为True,初始化的值设为0和0
optimizer=torch.optim.Adam([x],lr=1e-3)  # 使用了一个优化器,优化器的目标是x,学习率是1e-3。当接收到梯度信息后,自动的完成x=x-0.001*x的梯度,y同理
for step in range(20000):
    pred=himmelblau(x)  # x送进来,得到一个预测值。

    optimizer.zero_grad()  # 梯度信息清零
    pred.backward()  # 生成x,y的梯度信息
    optimizer.step()  # 生成上述优化器部分得到的x,y
# 一直循环,直到得到最好的x,y
    if step % 2000==0:
        print('step{}:x={},f(x)={}'
              .format(step,x.tolist(),pred.item()))

此时初始值设置为(0,0)

运行结果

先汇出函数的图像

 然后继续运行,得到优化的结果。

x,y range: (120,) (120,)
X,Y maps: (120, 120) (120, 120)
step0:x=[0.0009999999310821295, 0.0009999999310821295],f(x)=170.0
step2000:x=[2.3331806659698486, 1.9540694952011108],f(x)=13.730916023254395
step4000:x=[2.9820079803466797, 2.0270984172821045],f(x)=0.014858869835734367
step6000:x=[2.999983549118042, 2.0000221729278564],f(x)=1.1074007488787174e-08
step8000:x=[2.9999938011169434, 2.0000083446502686],f(x)=1.5572823031106964e-09
step10000:x=[2.999997854232788, 2.000002861022949],f(x)=1.8189894035458565e-10
step12000:x=[2.9999992847442627, 2.0000009536743164],f(x)=1.6370904631912708e-11
step14000:x=[2.999999761581421, 2.000000238418579],f(x)=1.8189894035458565e-12
step16000:x=[3.0, 2.0],f(x)=0.0
step18000:x=[3.0, 2.0],f(x)=0.0

可以看出x,y从0,0开始,此时f(x)为170然后不断优化,当x=3.0,y=2.0时,f(x)得到极小值0

我们可以改变初始值,比如x=-4,y=0

代码改变部分为

x=torch.tensor([-4.,0.],requires_grad=True)  # 梯度信息设置为True,初始化的值设为0和0

输出结果为

step0:x=[-3.999000072479248, -0.0009999999310821295],f(x)=146.0
step2000:x=[-3.526559829711914, -2.5002429485321045],f(x)=19.4503231048584
step4000:x=[-3.777446746826172, -3.2777843475341797],f(x)=0.0012130826944485307
step6000:x=[-3.7793045043945312, -3.283174753189087],f(x)=5.636138666886836e-09
step8000:x=[-3.779308319091797, -3.28318190574646],f(x)=7.248672773130238e-10
step10000:x=[-3.7793095111846924, -3.28318452835083],f(x)=8.822098607197404e-11
step12000:x=[-3.7793102264404297, -3.2831854820251465],f(x)=8.185452315956354e-12
step14000:x=[-3.7793102264404297, -3.2831859588623047],f(x)=0.0
step16000:x=[-3.7793102264404297, -3.2831859588623047],f(x)=0.0
step18000:x=[-3.7793102264404297, -3.2831859588623047],f(x)=0.0

可以看出此时x=-3.77,y=-3.28

也可以将初始值改为其他值,进行操作。

经过两次初始值改变,我们可以看到与上文图片中的理论值相差无几。说明优化器结果还是很好的

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值