Pytorch-實戰之對Himmelblau函式的優化
阿新 • • 發佈:2020-10-09
1.Himmelblau函式
Himmelblau函式:
F(x,y)=(x²+y-11)²+(x+y²-7)²
:具體優化的是,尋找一個最合適的座標(x,y)使得F(x,y)的值最小。
函式的具體影象,如下圖所示:
實現程式碼
import numpy as np from matplotlib import pyplot as plt import torch # 定義函式 def himmelblau(x_y): return (x_y[0] ** 2 + x_y[1] - 11) ** 2 + (x_y[0] + x_y[1] ** 2 - 7) ** 2 # 生成x軸資料列表 x = np.arange(-6, 6, 0.1) # 生成y軸資料列表 y = np.arange(-6, 6, 0.1) print('x,y range:', x.shape, y.shape) # 對x,y資料進行網格化, X, Y = np.meshgrid(x, y) print('X,Y maps:', X.shape, Y.shape) # 計算Z軸資料 Z = himmelblau([X, Y]) fig = plt.figure('himmelblau') ax = fig.gca(projection='3d') # 繪製3D圖形 ax.plot_surface(X, Y, Z) ax.view_init(60, -30) ax.set_xlabel('x') ax.set_ylabel('y') plt.show() if __name__ == '__main__': # [1., 0.], [-4, 0.], [4, 0.] # x_y儲存的是座標值(x,y),目的就是求解一個最優的x_y。 x_y = torch.tensor([0., 0.], requires_grad=True) # 定義優化器,優化器的目標就是x_y,學習速率learningrate是0.001 optimizer = torch.optim.Adam([x_y], lr=1e-3) for step in range(20000): # 輸入座標,得到預測值 pred = himmelblau(x_y) # 當網路參量進行反饋時,梯度是被積累的而不是被替換掉,所以把梯度資訊清零 optimizer.zero_grad() # 獲取x座標和y座標的梯度資訊 pred.backward() # 呼叫一次.step(),就會優化一次x座標 x'=x-learningrate*▽x # 呼叫一次.step(),就會優化一次y座標 y'=y-learningrate*▽y optimizer.step() if step % 2000 == 0: print ('step {}: x_y = {}, f(x) = {}' .format(step, x_y.tolist(), pred.item()))
輸出結果
x,y range: (120,) (120,) X,Y maps: (120, 120) (120, 120) step 0: x_y = [0.0009999999310821295, 0.0009999999310821295], f(x) = 170.0 step 2000: x_y = [2.3331806659698486, 1.9540694952011108], f(x) = 13.730916023254395 step 4000: x_y = [2.9820079803466797, 2.0270984172821045], f(x) = 0.014858869835734367 step 6000: x_y = [2.999983549118042, 2.0000221729278564], f(x) = 1.1074007488787174e-08 step 8000: x_y = [2.9999938011169434, 2.0000083446502686], f(x) = 1.5572823031106964e-09 step 10000: x_y = [2.999997854232788, 2.000002861022949], f(x) = 1.8189894035458565e-10 step 12000: x_y = [2.9999992847442627, 2.0000009536743164], f(x) = 1.6370904631912708e-11 step 14000: x_y = [2.999999761581421, 2.000000238418579], f(x) = 1.8189894035458565e-12 step 16000: x_y = [3.0, 2.0], f(x) = 0.0 step 18000: x_y = [3.0, 2.0], f(x) = 0.0