【pytorch框架学习】6.二维函数优化问题实战

本文介绍了如何使用2D函数优化器,特别是具有四个全局极小值点的函数,通过matplotlib的pyplot绘制三维图像并应用梯度下降算法进行性能测试。通过实例展示了如何在实际场景中操作,强调了初值选择对训练结果的影响。
摘要由CSDN通过智能技术生成

一,2d函数优化器

2d函数优化器说白了就是一个特殊的含有两个变量的函数,这个函数有一个特点:

他的函数图像有四个局部极小值点,而且每个极小值点的值都为0,也就是说四个局部极小值点都是全局极小值点

这样,当你设计了一个梯度下降算法时,可以把它放到这个函数中跑一下,看看最终能不能掉到极小值点里面,掉进去的效率高不高,进而来评价这个算法的优越性。

这个2d函数优化器的四个极小值点如下

二,二维函数优化的实战

该代码分为两个部分,第一个部分是利用matplotlib的子库 pyplot 绘制该二维优化函数的3d图像

第二部分就是在该函数上运行梯度下降算法,测试其性能

1.利用pyplot绘制3d函数图像
①用python的形式把函数表达出来:
def himmelblau(x):#优化器函数用python的形式表现出来
    return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2

 

②生成相应的x,y,z点

首先生成120个-6到6之间,间隔0.1的坐标值,然后利用np的meshgrid函数,但是这里的x和y只是数字,并不能代表他是坐标,因此不能被函数接受,因此还要用np的meshgrid函数来把这些数字生成相应的坐标X和Y,然后把这些坐标当作参数传递进写好的函数中,获得Z坐标

x = np.arange(-6,6,0.1)#从-6到6每个0.1生成一个数字,作为点的x坐标值
y = np.arange(-6,6,0.1)#同理作为y的坐标值
print('x,y range:',x.shape,y.shape)#由于有120个数字,所以x和y的shape都是[120]
X,Y = np.meshgrid(x,y)
#np.meshgrid(x,y)就是把x和y分别各个组成x*y个点(实际上不是x*y,是x有a个数字,y有b个数字,组成a*b个点)
#然后把这些点的x坐标和y坐标分别返回给X和Y
#比如x的shape是[120],y的shape是[120],他俩组成[120*120]个点,所以X和Y的维度就是[120,120]
print('X,Y maps:',X.shape,Y.shape)
Z = himmelblau([X,Y])

 

③把这些点传入plt的接口中,进行绘图

绘图的代码如下,各个函数的用途和用法在注释中都有写

fig = plt.figure('himmelblau')#这个窗口的标题
ax = fig.add_subplot(111,projection = '3d')#两种使用方法,第一种是直接用fig,第二种就是这种ax = fig...,第一个参数一般都写111
#第二个参数代表是3d图
ax.plot_surface(X,Y,Z)#这是生成三维图像的函数,生成二维图像用ax.plot(X,Y),当然传的参数的shape与这里的X,Y就不相同了
#因为这里是为了绘制三维图像特意准备的点,shape为[120,120],不能直接用这里的XY绘制二维图像
ax.view_init(60,-30)#定义初始化的视角,也就是点进去第一眼在什么视角看,两个参数分别代表仰角和方位角
ax.set_xlabel('x')#x坐标的标题
ax.set_ylabel('y')#y坐标的标题
plt.show()#展示

 

运行结果如下:

可以用鼠标拖动变换不同的视角来观察函数图像

可以说这套模板来画三维图像是通用的,如果想画其他函数的图像,只需要改himmelblau函数中的表达式即可

比如我想看z = x+y的图像,可以把himmelblau函数改成这样

def himmelblau(x):#优化器函数用python的形式表现出来
    return x[0]+x[1]

 

运行结果如下

2.梯度下降训练部分

常规的梯度下降训练代码,都在注释中写好了

x = torch.tensor([0.,0],requires_grad=True)#初值设置为0,0,设置成需要求梯度
optimzer = torch.optim.Adam([x],lr=1e-3)#自动进行梯度下降的迭代器,第一个参数传一个list,里面放权值,第二个参数传学习速率
for step in range(20000):#一共迭代两万步
    pred = himmelblau(x)

    #梯度下降三部曲
    optimzer.zero_grad()#清零
    pred.backward()#求导
    optimzer.step()#下降

    if step % 2000 == 0:#每隔两千步输出一下点所在的位置,看看最终有没有向全局最低点下降
        print('step {}: x = {} , f(x) = {}'
              .format(step,x.tolist(),pred.item()))

 

运行结果如下

可以看到梯度在不断下降,最终落到了[3,2]这个最低点

改变出发点,再运行一下,发现最终掉入了另外一个最低点

由此可见,初值的选择会影响训练的最终结果和运行效率,所以以后在训练模型的时候,一定要给所有的权值赋上初值

或者在训练出现瓶颈的时候,考虑是否是因为没赋初值导致的

完整的代码如下所示:

import numpy as np
from matplotlib import  pyplot as plt#生成三维图像,是matplotlib的子库
import torch

def himmelblau(x):#优化器函数用python的形式表现出来
    return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
    #return x[0]+x[1]

#下面是3D画图部分

'''
点的生成部分
'''
x = np.arange(-6,6,0.1)#从-6到6每个0.1生成一个数字,作为点的x坐标值
y = np.arange(-6,6,0.1)#同理作为y的坐标值
print('x,y range:',x.shape,y.shape)#由于有120个数字,所以x和y的shape都是[120]
X,Y = np.meshgrid(x,y)
#np.meshgrid(x,y)就是把x和y分别各个组成x*y个点(实际上不是x*y,是x有a个数字,y有b个数字,组成a*b个点)
#然后把这些点的x坐标和y坐标分别返回给X和Y
#比如x的shape是[120],y的shape是[120],他俩组成[120*120]个点,所以X和Y的维度就是[120,120]
print('X,Y maps:',X.shape,Y.shape)
Z = himmelblau([X,Y])

'''
图像绘制部分
'''
fig = plt.figure('himmelblau')#这个窗口的标题
ax = fig.add_subplot(111,projection = '3d')#两种使用方法,第一种是直接用fig,第二种就是这种ax = fig...,第一个参数一般都写111
#第二个参数代表是3d图
ax.plot_surface(X,Y,Z)#这是生成三维图像的函数,生成二维图像用ax.plot(X,Y),当然传的参数的shape与这里的X,Y就不相同了
#因为这里是为了绘制三维图像特意准备的点,shape为[120,120],不能直接用这里的XY绘制二维图像
ax.view_init(60,-30)#定义初始化的视角,也就是点进去第一眼在什么视角看,两个参数分别代表仰角和方位角
ax.set_xlabel('x')#x坐标的标题
ax.set_ylabel('y')#y坐标的标题
plt.show()

#下面是训练部分
x = torch.tensor([3.,-2],requires_grad=True)#初值设置为0,0,设置成需要求梯度
optimzer = torch.optim.Adam([x],lr=1e-3)#自动进行梯度下降的迭代器,第一个参数传一个list,里面放权值,第二个参数传学习速率
for step in range(20000):#一共迭代两万步
    pred = himmelblau(x)

    #梯度下降三部曲
    optimzer.zero_grad()#清零
    pred.backward()#求导
    optimzer.step()#下降

    if step % 2000 == 0:#每隔两千步输出一下点所在的位置,看看最终有没有向全局最低点下降
        print('step {}: x = {} , f(x) = {}'
              .format(step,x.tolist(),pred.item()))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

owooooow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值