Pytorch對(duì)Himmelblau函數(shù)的優(yōu)化詳解
Himmelblau函數(shù)如下:

有四個(gè)全局最小解,且值都為0,這個(gè)函數(shù)常用來(lái)檢驗(yàn)優(yōu)化算法的表現(xiàn)如何:

可視化函數(shù)圖像:
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()
結(jié)果:

使用隨機(jī)梯度下降優(yōu)化:
import torch
def himmelblau(x):
return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
# 初始設(shè)置為0,0.
x = torch.tensor([0., 0.], requires_grad=True)
# 優(yōu)化目標(biāo)是找到使himmelblau函數(shù)值最小的坐標(biāo)x[0],x[1],
# 也就是x, y
# 這里是定義Adam優(yōu)化器,指明優(yōu)化目標(biāo)是x,學(xué)習(xí)率是1e-3
optimizer = torch.optim.Adam([x], lr=1e-3)
for step in range(20000):
# 每次計(jì)算出當(dāng)前的函數(shù)值
pred = himmelblau(x)
# 當(dāng)網(wǎng)絡(luò)參量進(jìn)行反饋時(shí),梯度是被積累的而不是被替換掉,這里即每次將梯度設(shè)置為0
optimizer.zero_grad()
# 生成當(dāng)前所在點(diǎn)函數(shù)值相關(guān)的梯度信息,這里即優(yōu)化目標(biāo)的梯度信息
pred.backward()
# 使用梯度信息更新優(yōu)化目標(biāo)的值,即更新x[0]和x[1]
optimizer.step()
# 每2000次輸出一下當(dāng)前情況
if step % 2000 == 0:
print("step={},x={},f(x)={}".format(step, x.tolist(), pred.item()))
輸出結(jié)果:
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
從上面結(jié)果看,找到了一組最優(yōu)解[3.0, 2.0],此時(shí)極小值為0.0。如果修改Tensor變量x的初始化值,可能會(huì)找到其它的極小值,也就是說(shuō)初始化值對(duì)于找到最優(yōu)解很關(guān)鍵。
補(bǔ)充拓展:pytorch 搭建自己的神經(jīng)網(wǎng)絡(luò)和各種優(yōu)化器
還是直接看代碼吧!
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 # 激勵(lì)函數(shù)都在這
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):
# 正向傳播輸入值, 神經(jīng)網(wǎng)絡(luò)分析出輸出值
x = F.relu(self.hidden1(x)) # 激勵(lì)函數(shù)(隱藏層的線性值)
x = self.out(x) # 輸出值, 但是這個(gè)不是預(yù)測(cè)值, 預(yù)測(cè)值還需要再另外計(jì)算
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))
# 為每個(gè)優(yōu)化器創(chuàng)建一個(gè) net
net_SGD = Net()
net_Momentum = Net()
net_RMSprop = Net()
net_Adam = Net()
nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]
#定義優(yōu)化器
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)# 數(shù)據(jù)必須得是一維非one-hot向量
# 對(duì)每個(gè)優(yōu)化器, 優(yōu)化屬于他的神經(jīng)網(wǎng)絡(luò)
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對(duì)Himmelblau函數(shù)的優(yōu)化詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)的排列組合、破解密碼算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)的排列組合、破解密碼算法,結(jié)合實(shí)例形式分析了Python排列組合、密碼破解相關(guān)數(shù)學(xué)運(yùn)算操作技巧,需要的朋友可以參考下2019-04-04
python 采用paramiko 遠(yuǎn)程執(zhí)行命令及報(bào)錯(cuò)解決
這篇文章主要介紹了python 采用paramiko 遠(yuǎn)程執(zhí)行命令及報(bào)錯(cuò)解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
python實(shí)現(xiàn)超市管理系統(tǒng)(后臺(tái)管理)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)超市管理系統(tǒng),增加后臺(tái)管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10
Python實(shí)現(xiàn)矩陣轉(zhuǎn)置的幾種方法詳解
這篇文章主要介紹了Python實(shí)現(xiàn)矩陣轉(zhuǎn)置的幾種方法詳解,zip() 函數(shù)用于將可迭代的對(duì)象作為參數(shù),將對(duì)象中對(duì)應(yīng)的元素打包成一個(gè)個(gè)元組,然后返回由這些元組組成的對(duì)象,這樣做的好處是節(jié)約了不少的內(nèi)存,需要的朋友可以參考下2023-08-08
selenium設(shè)置瀏覽器為headless無(wú)頭模式(Chrome和Firefox)
這篇文章主要介紹了selenium設(shè)置瀏覽器為headless無(wú)頭模式(Chrome和Firefox),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Python查找數(shù)組中數(shù)值和下標(biāo)相等的元素示例【二分查找】
這篇文章主要介紹了Python查找數(shù)組中數(shù)值和下標(biāo)相等的元素,結(jié)合實(shí)例形式分析了Python基于二分查找針對(duì)數(shù)組查找相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-02-02
python自動(dòng)發(fā)郵件總結(jié)及實(shí)例說(shuō)明【推薦】
python發(fā)郵件需要掌握兩個(gè)模塊的用法,smtplib和email,這倆模塊是python自帶的,只需import即可使用。這篇文章主要介紹了python自動(dòng)發(fā)郵件總結(jié)及實(shí)例說(shuō)明 ,需要的朋友可以參考下2019-05-05
詳細(xì)聊一聊為什么Python沒有main函數(shù)
相信很多初學(xué)python的人看代碼的時(shí)候都會(huì)先找一下main()方法,從main往下看,但事實(shí)上python中是沒有你理解中的“main()”方法的,下面這篇文章主要給大家介紹了關(guān)于為什么Python沒有main函數(shù)的相關(guān)資料,需要的朋友可以參考下2023-03-03

