Pytorch对Himmelblau函数的优化详解
Himmelblau函数如下:
有四个全局最小解,且值都为0,这个函数常用来检验优化算法的表现如何:
可视化函数图像:
importnumpyasnp frommatplotlibimportpyplotasplt frommpl_toolkits.mplot3dimportAxes3D defhimmelblau(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()
结果:
使用随机梯度下降优化:
importtorch defhimmelblau(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) forstepinrange(20000): #每次计算出当前的函数值 pred=himmelblau(x) #当网络参量进行反馈时,梯度是被积累的而不是被替换掉,这里即每次将梯度设置为0 optimizer.zero_grad() #生成当前所在点函数值相关的梯度信息,这里即优化目标的梯度信息 pred.backward() #使用梯度信息更新优化目标的值,即更新x[0]和x[1] optimizer.step() #每2000次输出一下当前情况 ifstep%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搭建自己的神经网络和各种优化器
还是直接看代码吧!
importtorch importtorchvision importtorchvision.transformsastransform importtorch.utils.dataasData importmatplotlib.pyplotasplt fromtorch.utils.dataimportDataset,DataLoader importpandasaspd importnumpyasnp fromtorch.autogradimportVariable #dataset train=pd.read_csv('Thirdtest.csv') #cut0colaslabel train_label=train.iloc[:,[0]]#只读取一列 #train_label=train.iloc[:,0:3] #cut1~16colasdata train_data=train.iloc[:,1:] #changetonp train_label_np=train_label.values train_data_np=train_data.values #changetotensor 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) #makeanetwork importtorch.nn.functionalasF#激励函数都在这 classNet(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)#输出层线性输出 defforward(self,x): #正向传播输入值,神经网络分析出输出值 x=F.relu(self.hidden1(x))#激励函数(隐藏层的线性值) x=self.out(x)#输出值,但是这个不是预测值,预测值还需要再另外计算 returnx #net=Net() #optimizer=torch.optim.SGD(net.parameters(),lr=0.0001,momentum=0.001) #loss_func=torch.nn.CrossEntropyLoss()#thetargetlabelisNOTanone-hotted #loss_list=[] #forepochinrange(500): #forstep,(b_x,b_y)inenumerate(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() #ifepoch%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=[[],[],[],[]] fornet,opt,l_hisinzip(nets,optimizers,losses_his): forepochinrange(500): forstep,(b_x,b_y)inenumerate(train_loader): b_x,b_y=Variable(b_x),Variable(b_y) b_y=b_y.squeeze(1)#数据必须得是一维非one-hot向量 #对每个优化器,优化属于他的神经网络 output=net(b_x)#getoutputforeverynet loss=loss_func(output,b_y)#computelossforeverynet opt.zero_grad()#cleargradientsfornexttrain loss.backward()#backpropagation,computegradients opt.step()#applygradients ifepoch%1==0: l_his.append(loss.data.numpy())#lossrecoder print("optimizers:",opt,"Epoch:",epoch,"Step",step,"loss:",float(loss)) labels=['SGD','Momentum','RMSprop','Adam'] fori,l_hisinenumerate(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() # #forepochinrange(5): #forstep,(b_x,b_y)inenumerate(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函数的优化详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。