Pytorch对Himmelblau函数的优化详解

Himmelblau函数如下:

有四个全局最小解,且值都为0,这个函数常用来检验优化算法的表现如何:

可视化函数图像:

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 = np.arange(-6, 6, 0.1)
y = np.arange(-6, 6, 0.1)
X, Y = np.meshgrid(x, y)
Z = himmelblau([X, Y])
fig = plt.figure("himmeblau")
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()

结果:

使用随机梯度下降优化:

import torch

 def himmelblau(x):
 return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2

# 初始设置为0,0.
x = torch.tensor([0., 0.], requires_grad=True)
# 优化目标是找到使himmelblau函数值最小的坐标x[0],x[1],
# 也就是x, y
# 这里是定义Adam优化器,指明优化目标是x,学习率是1e-3
optimizer = torch.optim.Adam([x], lr=1e-3)

for step in range(20000):
 # 每次计算出当前的函数值
 pred = himmelblau(x)
 # 当网络参量进行反馈时,梯度是被积累的而不是被替换掉,这里即每次将梯度设置为0
 optimizer.zero_grad()
 # 生成当前所在点函数值相关的梯度信息,这里即优化目标的梯度信息
 pred.backward()
 # 使用梯度信息更新优化目标的值,即更新x[0]和x[1]
 optimizer.step()
 # 每2000次输出一下当前情况
 if step % 2000 == 0:
 print("step={},x={},f(x)={}".format(step, x.tolist(), pred.item()))

输出结果:

step=0,x=[0.0009999999310821295, 0.0009999999310821295],f(x)=170.0
step=2000,x=[2.3331806659698486, 1.9540692567825317],f(x)=13.730920791625977
step=4000,x=[2.9820079803466797, 2.0270984172821045],f(x)=0.014858869835734367
step=6000,x=[2.999983549118042, 2.0000221729278564],f(x)=1.1074007488787174e-08
step=8000,x=[2.9999938011169434, 2.0000083446502686],f(x)=1.5572823031106964e-09
step=10000,x=[2.999997854232788, 2.000002861022949],f(x)=1.8189894035458565e-10
step=12000,x=[2.9999992847442627, 2.0000009536743164],f(x)=1.6370904631912708e-11
step=14000,x=[2.999999761581421, 2.000000238418579],f(x)=1.8189894035458565e-12
step=16000,x=[3.0, 2.0],f(x)=0.0
step=18000,x=[3.0, 2.0],f(x)=0.0

从上面结果看,找到了一组最优解[3.0, 2.0],此时极小值为0.0。如果修改Tensor变量x的初始化值,可能会找到其它的极小值,也就是说初始化值对于找到最优解很关键。

补充拓展:pytorch 搭建自己的神经网络和各种优化器

还是直接看代码吧!

import torch
import torchvision
import torchvision.transforms as transform
import torch.utils.data as Data
import matplotlib.pyplot as plt
from torch.utils.data import Dataset,DataLoader
import pandas as pd
import numpy as np
from torch.autograd import Variable

# data set
train=pd.read_csv('Thirdtest.csv')
#cut 0 col as label
train_label=train.iloc[:,[0]] #只读取一列
#train_label=train.iloc[:,0:3]
#cut 1~16 col as data
train_data=train.iloc[:,1:]
#change to np
train_label_np=train_label.values
train_data_np=train_data.values

#change to tensor
train_label_ts=torch.from_numpy(train_label_np)
train_data_ts=torch.from_numpy(train_data_np)

train_label_ts=train_label_ts.type(torch.LongTensor)
train_data_ts=train_data_ts.type(torch.FloatTensor)

print(train_label_ts.shape)
print(type(train_label_ts))

train_dataset=Data.TensorDataset(train_data_ts,train_label_ts)
train_loader=DataLoader(dataset=train_dataset,batch_size=64,shuffle=True)

#make a network

import torch.nn.functional as F   # 激励函数都在这

class Net(torch.nn.Module):   # 继承 torch 的 Module
  def __init__(self ):
    super(Net, self).__init__()   # 继承 __init__ 功能
    self.hidden1 = torch.nn.Linear(16, 30)# 隐藏层线性输出
    self.out = torch.nn.Linear(30, 3)    # 输出层线性输出

  def forward(self, x):
    # 正向传播输入值, 神经网络分析出输出值
    x = F.relu(self.hidden1(x))   # 激励函数(隐藏层的线性值)
    x = self.out(x)         # 输出值, 但是这个不是预测值, 预测值还需要再另外计算
    return x

# net=Net()
# optimizer = torch.optim.SGD(net.parameters(), lr=0.0001,momentum=0.001)
# loss_func = torch.nn.CrossEntropyLoss() # the target label is NOT an one-hotted

# loss_list=[]
# for epoch in range(500):
#   for step ,(b_x,b_y) in enumerate (train_loader):
#     b_x,b_y=Variable(b_x),Variable(b_y)
#     b_y=b_y.squeeze(1)
#     output=net(b_x)
#     loss=loss_func(output,b_y)
#     optimizer.zero_grad()
#     loss.backward()
#     optimizer.step()
#     if epoch%1==0:
#       loss_list.append(float(loss))
#     print( "Epoch: ", epoch, "Step ", step, "loss: ", float(loss))

# 为每个优化器创建一个 net
net_SGD     = Net()
net_Momentum  = Net()
net_RMSprop   = Net()
net_Adam    = Net()
nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]

#定义优化器
LR=0.0001
opt_SGD     = torch.optim.SGD(net_SGD.parameters(), lr=LR,momentum=0.001)
opt_Momentum  = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
opt_RMSprop   = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
opt_Adam    = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam]

loss_func = torch.nn.CrossEntropyLoss()
losses_his = [[], [], [], []]

for net, opt, l_his in zip(nets, optimizers, losses_his):
  for epoch in range(500):
    for step, (b_x, b_y) in enumerate(train_loader):
      b_x, b_y = Variable(b_x), Variable(b_y)
      b_y = b_y.squeeze(1)# 数据必须得是一维非one-hot向量
    # 对每个优化器, 优化属于他的神经网络

      output = net(b_x)       # get output for every net
      loss = loss_func(output, b_y) # compute loss for every net
      opt.zero_grad()        # clear gradients for next train
      loss.backward()        # backpropagation, compute gradients
      opt.step()           # apply gradients
      if epoch%1==0:
        l_his.append(loss.data.numpy())   # loss recoder
        print("optimizers: ",opt,"Epoch: ",epoch,"Step ",step,"loss: ",float(loss))

labels = ['SGD', 'Momentum', 'RMSprop', 'Adam']
for i, l_his in enumerate(losses_his):
  plt.plot(l_his, label=labels[i])
plt.legend(loc='best')
plt.xlabel('Steps')
plt.ylabel('Loss')
plt.xlim((0,1000))
plt.ylim((0,4))
plt.show()

#
# for epoch in range(5):
#   for step ,(b_x,b_y) in enumerate (train_loader):
#     b_x,b_y=Variable(b_x),Variable(b_y)
#     b_y=b_y.squeeze(1)
#     output=net(b_x)
#     loss=loss_func(output,b_y)
#     loss.backward()
#     optimizer.zero_grad()
#     optimizer.step()
#     print(loss)

以上这篇Pytorch对Himmelblau函数的优化详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 详解PyTorch批训练及优化器比较

    一.PyTorch批训练 1. 概述 PyTorch提供了一种将数据包装起来进行批训练的工具--DataLoader.使用的时候,只需要将我们的数据首先转换为torch的tensor形式,再转换成torch可以识别的Dataset格式,然后将Dataset放入DataLoader中就可以啦. import torch import torch.utils.data as Data torch.manual_seed(1) # 设定随机数种子 BATCH_SIZE = 5 x = torch.li

  • 浅谈Pytorch torch.optim优化器个性化的使用

    一.简化前馈网络LeNet import torch as t class LeNet(t.nn.Module): def __init__(self): super(LeNet, self).__init__() self.features = t.nn.Sequential( t.nn.Conv2d(3, 6, 5), t.nn.ReLU(), t.nn.MaxPool2d(2, 2), t.nn.Conv2d(6, 16, 5), t.nn.ReLU(), t.nn.MaxPool2d(2

  • Pytorch对Himmelblau函数的优化详解

    Himmelblau函数如下: 有四个全局最小解,且值都为0,这个函数常用来检验优化算法的表现如何: 可视化函数图像: 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 = np.ar

  • PyTorch中topk函数的用法详解

    听名字就知道这个函数是用来求tensor中某个dim的前k大或者前k小的值以及对应的index. 用法 torch.topk(input, k, dim=None, largest=True, sorted=True, out=None) -> (Tensor, LongTensor) input:一个tensor数据 k:指明是得到前k个数据以及其index dim: 指定在哪个维度上排序, 默认是最后一个维度 largest:如果为True,按照大到小排序: 如果为False,按照小到大排序

  • pytorch之Resize()函数具体使用详解

    Resize函数用于对PIL图像的预处理,它的包在: from torchvision.transforms import Compose, CenterCrop, ToTensor, Resize 使用如: def input_transform(crop_size, upscale_factor): return Compose([ CenterCrop(crop_size), Resize(crop_size // upscale_factor), ToTensor(), ]) 而Resi

  • pytorch中permute()函数用法实例详解

    目录 前言 三维情况 变化一:不改变任何参数 变化二:1与2交换 变化三:0与1交换 变化四:0与2交换 变化五:0与1交换,1与2交换 变化六:0与1交换,0与2交换 总结 前言 本文只讨论二维三维中的permute用法 最近的Attention学习中的一个permute函数让我不理解 这个光说太抽象 我就结合代码与图片解释一下 首先创建一个三维数组小实例 import torch x = torch.linspace(1, 30, steps=30).view(3,2,5) # 设置一个三维

  • Pytorch mask_select 函数的用法详解

    非常简单的函数,但是官网的介绍令人(令我)迷惑,所以稍加解释. mask_select会将满足mask(掩码.遮罩等等,随便翻译)的指示,将满足条件的点选出来. 根据掩码张量mask中的二元值,取输入张量中的指定项( mask为一个 ByteTensor),将取值返回到一个新的1D张量, 张量 mask须跟input张量有相同数量的元素数目,但形状或维度不需要相同 x = torch.randn(3, 4) x 1.2045 2.4084 0.4001 1.1372 0.5596 1.5677

  • Pytorch 的损失函数Loss function使用详解

    1.损失函数 损失函数,又叫目标函数,是编译一个神经网络模型必须的两个要素之一.另一个必不可少的要素是优化器. 损失函数是指用于计算标签值和预测值之间差异的函数,在机器学习过程中,有多种损失函数可供选择,典型的有距离向量,绝对值向量等. 损失Loss必须是标量,因为向量无法比较大小(向量本身需要通过范数等标量来比较). 损失函数一般分为4种,平方损失函数,对数损失函数,HingeLoss 0-1 损失函数,绝对值损失函数. 我们先定义两个二维数组,然后用不同的损失函数计算其损失值. import

  • PyTorch里面的torch.nn.Parameter()详解

    在看过很多博客的时候发现了一个用法self.v = torch.nn.Parameter(torch.FloatTensor(hidden_size)),首先可以把这个函数理解为类型转换函数,将一个不可训练的类型Tensor转换成可以训练的类型parameter并将这个parameter绑定到这个module里面(net.parameter()中就有这个绑定的parameter,所以在参数优化的时候可以进行优化的),所以经过类型转换这个self.v变成了模型的一部分,成为了模型中根据训练可以改动

  • PyTorch实现卷积神经网络的搭建详解

    目录 PyTorch中实现卷积的重要基础函数 1.nn.Conv2d: 2.nn.MaxPool2d(kernel_size=2) 3.nn.ReLU() 4.x.view() 全部代码 PyTorch中实现卷积的重要基础函数 1.nn.Conv2d: nn.Conv2d在pytorch中用于实现卷积. nn.Conv2d( in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1, ) 1.in_channels为输

  • 基于C++ bitset常用函数及运算符(详解)

    C++ bitset--高端压位卡常题必备STL ------------------------------------------------------------ 以下内容翻译自cplusplus.com,极大地锻炼了我的英语能力. bitset存储二进制数位. bitset就像一个bool类型的数组一样,但是有空间优化--bitset中的一个元素一般只占1 bit,相当于一个char元素所占空间的八分之一. bitset中的每个元素都能单独被访问,例如对于一个叫做foo的bitset,

  • 基于Python中单例模式的几种实现方式及优化详解

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. 比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息.如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪

随机推荐