偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

5分鐘快速掌握Adam優(yōu)化算法

開發(fā) 后端 算法
在本教程中,您將發(fā)現(xiàn)如何從頭開始使用Adam優(yōu)化算法開發(fā)梯度下降。

[[389202]]

 梯度下降是一種優(yōu)化算法,遵循目標(biāo)函數(shù)的負(fù)梯度以定位函數(shù)的最小值。

梯度下降的局限性是,所有輸入變量都使用單個(gè)步長(學(xué)習(xí)率)。像AdaGrad和RMSProp這樣的梯度下降的擴(kuò)展會(huì)更新算法,以對每個(gè)輸入變量使用單獨(dú)的步長,但可能會(huì)導(dǎo)致步長迅速減小到非常小的值。自適應(yīng)運(yùn)動(dòng)估計(jì)算法(Adam)是梯度下降的擴(kuò)展,是AdaGrad和RMSProp等技術(shù)的自然繼承者,該技術(shù)可自動(dòng)為目標(biāo)函數(shù)的每個(gè)輸入變量調(diào)整學(xué)習(xí)率,并通過使用以指數(shù)方式降低梯度的移動(dòng)平均值以更新變量。

在本教程中,您將發(fā)現(xiàn)如何從頭開始使用Adam優(yōu)化算法開發(fā)梯度下降。完成本教程后,您將知道:

  •  梯度下降是一種優(yōu)化算法,它使用目標(biāo)函數(shù)的梯度來導(dǎo)航搜索空間。
  •  可以通過使用稱為Adam的偏導(dǎo)數(shù)的遞減平均值,將梯度下降更新為對每個(gè)輸入變量使用自動(dòng)自適應(yīng)步長。
  •  如何從頭開始實(shí)施Adam優(yōu)化算法并將其應(yīng)用于目標(biāo)函數(shù)并評估結(jié)果。

教程概述

本教程分為三個(gè)部分:他們是:

  •  梯度下降
  •  Adam優(yōu)化算法
  •  Adam梯度下降

          二維測試問題

          Adam的梯度下降優(yōu)化

          Adam可視化

梯度下降

梯度下降是一種優(yōu)化算法。它在技術(shù)上稱為一階優(yōu)化算法,因?yàn)樗鞔_利用了目標(biāo)目標(biāo)函數(shù)的一階導(dǎo)數(shù)。一階導(dǎo)數(shù),或簡稱為“導(dǎo)數(shù)”,是目標(biāo)函數(shù)在特定點(diǎn)(例如,點(diǎn))上的變化率或斜率。用于特定輸入。如果目標(biāo)函數(shù)采用多個(gè)輸入變量,則將其稱為多元函數(shù),并且可以將輸入變量視為向量。反過來,多元目標(biāo)函數(shù)的導(dǎo)數(shù)也可以視為向量,通常稱為梯度。

梯度:多元目標(biāo)函數(shù)的一階導(dǎo)數(shù)。

對于特定輸入,導(dǎo)數(shù)或梯度指向目標(biāo)函數(shù)最陡峭的上升方向。

梯度下降是指一種最小化優(yōu)化算法,該算法遵循目標(biāo)函數(shù)的下坡梯度負(fù)值來定位函數(shù)的最小值。梯度下降算法需要一個(gè)正在優(yōu)化的目標(biāo)函數(shù)和該目標(biāo)函數(shù)的導(dǎo)數(shù)函數(shù)。目標(biāo)函數(shù)f()返回給定輸入集合的分?jǐn)?shù),導(dǎo)數(shù)函數(shù)f'()給出給定輸入集合的目標(biāo)函數(shù)的導(dǎo)數(shù)。梯度下降算法需要問題中的起點(diǎn)(x),例如輸入空間中的隨機(jī)選擇點(diǎn)。

假設(shè)我們正在最小化目標(biāo)函數(shù),然后計(jì)算導(dǎo)數(shù)并在輸入空間中采取一步,這將導(dǎo)致目標(biāo)函數(shù)下坡運(yùn)動(dòng)。下坡運(yùn)動(dòng)是通過首先計(jì)算輸入空間中的運(yùn)動(dòng)量來進(jìn)行的,計(jì)算方法是將步長(稱為alpha或?qū)W習(xí)率)乘以坡度。然后從當(dāng)前點(diǎn)減去該值,以確保我們逆梯度移動(dòng)或向下移動(dòng)目標(biāo)函數(shù)。

x(t)= x(t-1)–step* f'(x(t-1))

在給定點(diǎn)的目標(biāo)函數(shù)越陡峭,梯度的幅度越大,反過來,在搜索空間中采取的步伐也越大。使用步長超參數(shù)來縮放步長的大小。

步長(alpha):超參數(shù),控制算法每次迭代時(shí)相對于梯度在搜索空間中移動(dòng)多遠(yuǎn)。

如果步長太小,則搜索空間中的移動(dòng)將很小,并且搜索將花費(fèi)很長時(shí)間。如果步長太大,則搜索可能會(huì)在搜索空間附近反彈并跳過最優(yōu)值。

現(xiàn)在我們已經(jīng)熟悉了梯度下降優(yōu)化算法,下面讓我們看一下Adam算法。

Adam優(yōu)化算法

自適應(yīng)運(yùn)動(dòng)估計(jì)算法(簡稱“Adam”)是梯度下降優(yōu)化算法的擴(kuò)展。Diederik Kingma和Jimmy Lei Ba在2014年發(fā)表的題為“Adam:隨機(jī)優(yōu)化方法”的論文中描述了該算法。Adam旨在加速優(yōu)化過程,例如減少達(dá)到最佳狀態(tài)所需的功能評估次數(shù),或提高優(yōu)化算法的功能,例如產(chǎn)生更好的最終結(jié)果。這是通過為每個(gè)要優(yōu)化的輸入?yún)?shù)計(jì)算步長來實(shí)現(xiàn)的。重要的是,每個(gè)步長都將根據(jù)每個(gè)變量遇到的梯度(偏導(dǎo)數(shù))自動(dòng)調(diào)整搜索過程的吞吐量。

讓我們逐步介紹該算法的每個(gè)元素。首先,對于作為搜索一部分而被優(yōu)化的每個(gè)參數(shù),我們必須維持一個(gè)矩矢量和指數(shù)加權(quán)無窮大范數(shù),分別稱為m和v(真是希臘字母nu)。在搜索開始時(shí)將它們初始化為0.0。

m = 0 

v = 0

該算法在從t=1開始的時(shí)間t內(nèi)迭代執(zhí)行,并且每次迭代都涉及計(jì)算一組新的參數(shù)值x,例如。從x(t-1)到x(t)。如果我們專注于更新一個(gè)參數(shù),這可能很容易理解該算法,該算法概括為通過矢量運(yùn)算來更新所有參數(shù)。首先,計(jì)算當(dāng)前時(shí)間步長的梯度(偏導(dǎo)數(shù))。

g(t)= f'(x(t-1))

接下來,使用梯度和超參數(shù)beta1更新第一時(shí)刻。

m(t)= beta1 * m(t-1)+(1 – beta1)* g(t)

然后,使用平方梯度和超參數(shù)beta2更新第二時(shí)刻。

v(t)= beta2 * v(t-1)+(1 – beta2)* g(t)^ 2

由于第一和第二力矩是用零值初始化的,所以它們是有偏的。接下來,對第一力矩和第二力矩進(jìn)行偏差校正,并以第一力矩為起點(diǎn):

mhat(t)= m(t)/(1 – beta1(t))

然后第二個(gè)時(shí)刻:

vhat(t)= v(t)/(1 – beta2(t))

注意,beta1(t)和beta2(t)指的是beta1和beta2超參數(shù),它們在算法的迭代過程中按時(shí)間表衰減??梢允褂渺o態(tài)衰減時(shí)間表,盡管該論文建議以下內(nèi)容:

beta1(t)= beta1 ^ t

beta2(t)= beta2 ^ t

最后,我們可以為該迭代計(jì)算參數(shù)的值。

x(t)= x(t-1)– alpha * mhat(t)/(sqrt(vhat(t))+ eps)

其中alpha是步長超參數(shù),eps是一個(gè)較小的值(epsilon),例如1e-8,可確保我們不會(huì)遇到被零除的誤差,而sqrt()是平方根函數(shù)。

注意,可以使用對本文中列出的更新規(guī)則進(jìn)行更有效的重新排序:

alpha(t)= alpha * sqrt(1 – beta2(t))/(1 – beta1(t)) x(t)= x(t-1)– alpha(t)* m(t)/(sqrt(v(t))+ eps)

回顧一下,該算法有三個(gè)超參數(shù),它們是:

  •  alpha:初始步長(學(xué)習(xí)率),典型值為0.001。
  •  beta1:第一個(gè)動(dòng)量的衰減因子,典型值為0.9。
  •  beta2:無窮大范數(shù)的衰減因子,典型值為0.999。

接下來,讓我們看看如何在Python中從頭開始實(shí)現(xiàn)該算法。

Adam梯度下降

在本節(jié)中,我們將探討如何使用Adam實(shí)現(xiàn)梯度下降優(yōu)化算法。

二維測試問題

首先,讓我們定義一個(gè)優(yōu)化函數(shù)。我們將使用一個(gè)簡單的二維函數(shù),該函數(shù)將每個(gè)維的輸入平方,并定義有效輸入的范圍(從-1.0到1.0)。

下面的Objective()函數(shù)實(shí)現(xiàn)了此功能 

  1. # objective function  
  2. def objective(x, y):  
  3.  return x**2.0 + y**2.0 

我們可以創(chuàng)建數(shù)據(jù)集的三維圖,以了解響應(yīng)面的曲率。下面列出了繪制目標(biāo)函數(shù)的完整示例。 

  1. # 3d plot of the test function  
  2. from numpy import arange  
  3. from numpy import meshgrid  
  4. from matplotlib import pyplot   
  5. # objective function  
  6. def objective(x, y):  
  7.  return x**2.0 + y**2.0   
  8. # define range for input  
  9. r_min, r_max = -1.0, 1.0  
  10. # sample input range uniformly at 0.1 increments  
  11. xaxis = arange(r_min, r_max, 0.1)  
  12. yaxis = arange(r_min, r_max, 0.1)  
  13. # create a mesh from the axis  
  14. x, y = meshgrid(xaxis, yaxis)  
  15. # compute targets 
  16. results = objective(x, y)  
  17. # create a surface plot with the jet color scheme  
  18. figure = pyplot.figure()  
  19. axis = figure.gca(projection='3d' 
  20. axis.plot_surface(x, y, results, cmap='jet'
  21. # show the plot  
  22. pyplot.show() 

運(yùn)行示例將創(chuàng)建目標(biāo)函數(shù)的三維表面圖。我們可以看到全局最小值為f(0,0)= 0的熟悉的碗形狀。

我們還可以創(chuàng)建函數(shù)的二維圖。這在以后要繪制搜索進(jìn)度時(shí)會(huì)很有幫助。下面的示例創(chuàng)建目標(biāo)函數(shù)的輪廓圖。 

  1. # contour plot of the test function  
  2. from numpy import asarray  
  3. from numpy import arange  
  4. from numpy import meshgrid  
  5. from matplotlib import pyplot   
  6. # objective function  
  7. def objective(x, y):  
  8.  return x**2.0 + y**2.0   
  9. # define range for input  
  10. bounds = asarray([[-1.0, 1.0], [-1.0, 1.0]])  
  11. # sample input range uniformly at 0.1 increments  
  12. xaxis = arange(bounds[0,0], bounds[0,1], 0.1)  
  13. yaxis = arange(bounds[1,0], bounds[1,1], 0.1)  
  14. # create a mesh from the axis  
  15. x, y = meshgrid(xaxis, yaxis)  
  16. # compute targets  
  17. results = objective(x, y)  
  18. # create a filled contour plot with 50 levels and jet color scheme  
  19. pyplot.contourf(x, y, results, levels=50cmap='jet' 
  20. # show the plot  
  21. pyplot.show() 

運(yùn)行示例將創(chuàng)建目標(biāo)函數(shù)的二維輪廓圖。我們可以看到碗的形狀被壓縮為以顏色漸變顯示的輪廓。我們將使用該圖來繪制在搜索過程中探索的特定點(diǎn)。

現(xiàn)在我們有了一個(gè)測試目標(biāo)函數(shù),讓我們看一下如何實(shí)現(xiàn)Adam優(yōu)化算法。

Adam梯度下降優(yōu)化

我們可以將帶有Adam的梯度下降應(yīng)用于測試問題。首先,我們需要一個(gè)函數(shù)來計(jì)算此函數(shù)的導(dǎo)數(shù)。

f(x)= x ^ 2

f'(x)= x * 2

x ^ 2的導(dǎo)數(shù)在每個(gè)維度上均為x * 2。 derived()函數(shù)在下面實(shí)現(xiàn)了這一點(diǎn)。 

  1. # derivative of objective function  
  2. def derivative(x, y):  
  3.  return asarray([x * 2.0, y * 2.0]) 

接下來,我們可以實(shí)現(xiàn)梯度下降優(yōu)化。首先,我們可以選擇問題范圍內(nèi)的隨機(jī)點(diǎn)作為搜索的起點(diǎn)。假定我們有一個(gè)數(shù)組,該數(shù)組定義搜索范圍,每個(gè)維度一行,并且第一列定義最小值,第二列定義維度的最大值。 

  1. # generate an initial point  
  2. x = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])  
  3. score = objective(x[0], x[1]) 

接下來,我們需要將第一時(shí)刻和第二時(shí)刻初始化為零。 

  1. # initialize first and second moments  
  2. m = [0.0 for _ in range(bounds.shape[0])]  
  3. v = [0.0 for _ in range(bounds.shape[0])] 

然后,我們運(yùn)行由“ n_iter”超參數(shù)定義的算法的固定迭代次數(shù)。 

  1. ...  
  2. # run iterations of gradient descent  
  3. for t in range(n_iter):  
  4.  ... 

第一步是使用導(dǎo)數(shù)()函數(shù)計(jì)算當(dāng)前解決方案的梯度。 

  1. # calculate gradient  
  2. gradient = derivative(solution[0], solution[1]) 

第一步是計(jì)算當(dāng)前參數(shù)集的導(dǎo)數(shù)。 

  1. # calculate gradient g(t)  
  2. g = derivative(x[0], x[1]) 

接下來,我們需要執(zhí)行Adam更新計(jì)算。為了提高可讀性,我們將使用命令式編程樣式一次執(zhí)行一個(gè)變量的這些計(jì)算。

在實(shí)踐中,我建議使用NumPy向量運(yùn)算以提高效率。 

  1. ...  
  2. # build a solution one variable at a time  
  3. for i in range(x.shape[0]):  
  4.  ... 

首先,我們需要計(jì)算力矩。 

  1. # m(t) = beta1 * m(t-1) + (1 - beta1) * g(t)  
  2. m[i] = beta1 * m[i] + (1.0 - beta1) * g[i] 

然后是第二個(gè)時(shí)刻。 

  1. # v(t) = beta2 * v(t-1) + (1 - beta2) * g(t)^2  
  2. v[i] = beta2 * v[i] + (1.0 - beta2) * g[i]**2 

然后對第一和第二時(shí)刻進(jìn)行偏差校正。 

  1. # mhat(t) = m(t) / (1 - beta1(t))  
  2. mmhat = m[i] / (1.0 - beta1**(t+1)) 
  3. # vhat(t) = v(t) / (1 - beta2(t))  
  4. vvhat = v[i] / (1.0 - beta2**(t+1)) 

然后最后是更新的變量值。 

  1. # x(t) = x(t-1) - alpha * mhat(t) / (sqrt(vhat(t)) + eps)  
  2. x[i] = x[i] - alpha * mhat / (sqrt(vhat) + eps) 

然后,針對要優(yōu)化的每個(gè)參數(shù)重復(fù)此操作。在迭代結(jié)束時(shí),我們可以評估新的參數(shù)值并報(bào)告搜索的性能。 

  1. # evaluate candidate point  
  2. score = objective(x[0], x[1])  
  3. # report progress  
  4. print('>%d f(%s) = %.5f' % (t, x, score)) 

我們可以將所有這些結(jié)合到一個(gè)名為adam()的函數(shù)中,該函數(shù)采用目標(biāo)函數(shù)和派生函數(shù)的名稱以及算法超參數(shù),并返回在搜索及其評估結(jié)束時(shí)找到的最佳解決方案。

下面列出了完整的功能。 

  1. # gradient descent algorithm with adam  
  2. def adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2, eps=1e-8):  
  3.  # generate an initial point  
  4.  x = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])  
  5.  score = objective(x[0], x[1])  
  6.  # initialize first and second moments  
  7.  m = [0.0 for _ in range(bounds.shape[0])]  
  8.  v = [0.0 for _ in range(bounds.shape[0])]  
  9.  # run the gradient descent updates  
  10.  for t in range(n_iter):  
  11.   # calculate gradient g(t)  
  12.   g = derivative(x[0], x[1])  
  13.   # build a solution one variable at a time  
  14.   for i in range(x.shape[0]):  
  15.    # m(t) = beta1 * m(t-1) + (1 - beta1) * g(t)  
  16.    m[i] = beta1 * m[i] + (1.0 - beta1) * g[i]  
  17.    # v(t) = beta2 * v(t-1) + (1 - beta2) * g(t)^2  
  18.    v[i] = beta2 * v[i] + (1.0 - beta2) * g[i]**2  
  19.    # mhat(t) = m(t) / (1 - beta1(t))  
  20.    mmhat = m[i] / (1.0 - beta1**(t+1))  
  21.    # vhat(t) = v(t) / (1 - beta2(t))  
  22.    vvhat = v[i] / (1.0 - beta2**(t+1))  
  23.    # x(t) = x(t-1) - alpha * mhat(t) / (sqrt(vhat(t)) + eps)  
  24.    x[i] = x[i] - alpha * mhat / (sqrt(vhat) + eps)  
  25.   # evaluate candidate point  
  26.   score = objective(x[0], x[1])  
  27.   # report progress  
  28.   print('>%d f(%s) = %.5f' % (t, x, score))  
  29.  return [x, score] 

注意:為了提高可讀性,我們有意使用列表和命令式編碼樣式,而不是矢量化操作。隨意將實(shí)現(xiàn)改編為帶有NumPy數(shù)組的矢量化實(shí)現(xiàn),以實(shí)現(xiàn)更好的性能。

然后,我們可以定義我們的超參數(shù)并調(diào)用adam()函數(shù)來優(yōu)化我們的測試目標(biāo)函數(shù)。

在這種情況下,我們將使用算法的60次迭代,初始步長為0.02,beta1和beta2值分別為0.8和0.999。經(jīng)過一些反復(fù)試驗(yàn)后,發(fā)現(xiàn)了這些超參數(shù)值。 

  1. # seed the pseudo random number generator  
  2. seed(1)  
  3. # define range for input  
  4. bounds = asarray([[-1.0, 1.0], [-1.0, 1.0]])  
  5. # define the total iterations  
  6. n_iter = 60 
  7. # steps size  
  8. alpha = 0.02  
  9. # factor for average gradient  
  10. beta1 = 0.8  
  11. # factor for average squared gradient  
  12. beta2 = 0.999  
  13. # perform the gradient descent search with adam  
  14. best, score = adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2)  
  15. print('Done!')  
  16. print('f(%s) = %f' % (best, score)) 

綜合所有這些,下面列出了使用Adam進(jìn)行梯度下降優(yōu)化的完整示例。 

  1. # gradient descent optimization with adam for a two-dimensional test function  
  2. from math import sqrt  
  3. from numpy import asarray  
  4. from numpy.random import rand  
  5. from numpy.random import seed   
  6. # objective function  
  7. def objective(x, y):  
  8.  return x**2.0 + y**2.0  
  9. # derivative of objective function  
  10. def derivative(x, y):  
  11.  return asarray([x * 2.0, y * 2.0])  
  12. # gradient descent algorithm with adam  
  13. def adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2, eps=1e-8):  
  14.  # generate an initial point  
  15.  x = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])  
  16.  score = objective(x[0], x[1])  
  17.  # initialize first and second moments  
  18.  m = [0.0 for _ in range(bounds.shape[0])]  
  19.  v = [0.0 for _ in range(bounds.shape[0])]  
  20.  # run the gradient descent updates  
  21.  for t in range(n_iter):  
  22.   # calculate gradient g(t)  
  23.   g = derivative(x[0], x[1])  
  24.   # build a solution one variable at a time  
  25.   for i in range(x.shape[0]):  
  26.    # m(t) = beta1 * m(t-1) + (1 - beta1) * g(t)  
  27.    m[i] = beta1 * m[i] + (1.0 - beta1) * g[i]  
  28.    # v(t) = beta2 * v(t-1) + (1 - beta2) * g(t)^2  
  29.    v[i] = beta2 * v[i] + (1.0 - beta2) * g[i]**2  
  30.    # mhat(t) = m(t) / (1 - beta1(t))  
  31.    mmhat = m[i] / (1.0 - beta1**(t+1))  
  32.    # vhat(t) = v(t) / (1 - beta2(t))  
  33.    vvhat = v[i] / (1.0 - beta2**(t+1))  
  34.    # x(t) = x(t-1) - alpha * mhat(t) / (sqrt(vhat(t)) + eps)  
  35.    x[i] = x[i] - alpha * mhat / (sqrt(vhat) + eps)  
  36.   # evaluate candidate point  
  37.   score = objective(x[0], x[1])  
  38.   # report progress  
  39.   print('>%d f(%s) = %.5f' % (t, x, score)) 
  40.  return [x, score]  
  41. # seed the pseudo random number generator  
  42. seed(1)  
  43. # define range for input  
  44. bounds = asarray([[-1.0, 1.0], [-1.0, 1.0]])  
  45. # define the total iterations  
  46. n_iter = 60  
  47. # steps size  
  48. alpha = 0.02  
  49. # factor for average gradient  
  50. beta1 = 0.8  
  51. # factor for average squared gradient  
  52. beta2 = 0.999  
  53. # perform the gradient descent search with adam  
  54. best, score = adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2)  
  55. print('Done!')  
  56. print('f(%s) = %f' % (best, score)) 

運(yùn)行示例將Adam優(yōu)化算法應(yīng)用于我們的測試問題,并報(bào)告算法每次迭代的搜索性能。

注意:由于算法或評估程序的隨機(jī)性,或者數(shù)值精度的差異,您的結(jié)果可能會(huì)有所不同。考慮運(yùn)行該示例幾次并比較平均結(jié)果。

在這種情況下,我們可以看到在搜索53次迭代后找到了接近最佳的解決方案,輸入值接近0.0和0.0,評估為0.0。 

  1. >50 f([-0.00056912 -0.00321961]) = 0.00001  
  2. >51 f([-0.00052452 -0.00286514]) = 0.00001  
  3. >52 f([-0.00043908 -0.00251304]) = 0.00001  
  4. >53 f([-0.0003283  -0.00217044]) = 0.00000  
  5. >54 f([-0.00020731 -0.00184302]) = 0.00000  
  6. >55 f([-8.95352320e-05 -1.53514076e-03]) = 0.00000  
  7. >56 f([ 1.43050285e-05 -1.25002847e-03]) = 0.00000  
  8. >57 f([ 9.67123406e-05 -9.89850279e-04]) = 0.00000  
  9. >58 f([ 0.00015359 -0.00075587]) = 0.00000  
  10. >59 f([ 0.00018407 -0.00054858]) = 0.00000  
  11. Done!  
  12. f([ 0.00018407 -0.00054858]) = 0.000000 

Adam可視化

我們可以在域的輪廓圖上繪制Adam搜索的進(jìn)度。這可以為算法迭代過程中的搜索進(jìn)度提供直觀的認(rèn)識(shí)。我們必須更新adam()函數(shù)以維護(hù)在搜索過程中找到的所有解決方案的列表,然后在搜索結(jié)束時(shí)返回此列表。下面列出了具有這些更改的功能的更新版本。 

  1. # gradient descent algorithm with adam  
  2. def adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2, eps=1e-8):  
  3.  solutions = list()  
  4.  # generate an initial point  
  5.  x = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])  
  6.  score = objective(x[0], x[1])  
  7.  # initialize first and second moments  
  8.  m = [0.0 for _ in range(bounds.shape[0])]  
  9.  v = [0.0 for _ in range(bounds.shape[0])]  
  10.  # run the gradient descent updates  
  11.  for t in range(n_iter):  
  12.   # calculate gradient g(t)  
  13.   g = derivative(x[0], x[1])  
  14.   # build a solution one variable at a time  
  15.   for i in range(bounds.shape[0]):  
  16.    # m(t) = beta1 * m(t-1) + (1 - beta1) * g(t)  
  17.    m[i] = beta1 * m[i] + (1.0 - beta1) * g[i]  
  18.    # v(t) = beta2 * v(t-1) + (1 - beta2) * g(t)^2  
  19.    v[i] = beta2 * v[i] + (1.0 - beta2) * g[i]**2  
  20.    # mhat(t) = m(t) / (1 - beta1(t))  
  21.    mmhat = m[i] / (1.0 - beta1**(t+1))  
  22.    # vhat(t) = v(t) / (1 - beta2(t))  
  23.    vvhat = v[i] / (1.0 - beta2**(t+1))  
  24.    # x(t) = x(t-1) - alpha * mhat(t) / (sqrt(vhat(t)) + ep)  
  25.    x[i] = x[i] - alpha * mhat / (sqrt(vhat) + eps)  
  26.   # evaluate candidate point  
  27.   score = objective(x[0], x[1])  
  28.   # keep track of solutions  
  29.   solutions.append(x.copy())  
  30.   # report progress  
  31.   print('>%d f(%s) = %.5f' % (t, x, score))  
  32.  return solutions 

然后,我們可以像以前一樣執(zhí)行搜索,這一次將檢索解決方案列表,而不是最佳的最終解決方案。 

  1. # seed the pseudo random number generator  
  2. seed(1)  
  3. # define range for input  
  4. bounds = asarray([[-1.0, 1.0], [-1.0, 1.0]])  
  5. # define the total iterations  
  6. n_iter = 60  
  7. # steps size  
  8. alpha = 0.02  
  9. # factor for average gradient  
  10. beta1 = 0.8  
  11. # factor for average squared gradient  
  12. beta2 = 0.999  
  13. # perform the gradient descent search with adam  
  14. solutions = adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2) 

然后,我們可以像以前一樣創(chuàng)建目標(biāo)函數(shù)的輪廓圖。 

  1. # sample input range uniformly at 0.1 increments  
  2. xaxis = arange(bounds[0,0], bounds[0,1], 0.1)  
  3. yaxis = arange(bounds[1,0], bounds[1,1], 0.1)  
  4. # create a mesh from the axis  
  5. x, y = meshgrid(xaxis, yaxis)  
  6. # compute targets  
  7. results = objective(x, y)  
  8. # create a filled contour plot with 50 levels and jet color scheme  
  9. pyplot.contourf(x, y, results, levels=50cmap='jet'

最后,我們可以將在搜索過程中找到的每個(gè)解決方案繪制成一條由一條線連接的白點(diǎn)。 

  1. # plot the sample as black circles  
  2. solutions = asarray(solutions)  
  3. pyplot.plot(solutions[:, 0], solutions[:, 1], '.-', color='w'

綜上所述,下面列出了對測試問題執(zhí)行Adam優(yōu)化并將結(jié)果繪制在輪廓圖上的完整示例。 

  1. # example of plotting the adam search on a contour plot of the test function  
  2. from math import sqrt  
  3. from numpy import asarray  
  4. from numpy import arange  
  5. from numpy.random import rand  
  6. from numpy.random import seed  
  7. from numpy import meshgrid  
  8. from matplotlib import pyplot  
  9. from mpl_toolkits.mplot3d import Axes3D  
  10. # objective function  
  11. def objective(x, y):  
  12.  return x**2.0 + y**2.0  
  13. # derivative of objective function  
  14. def derivative(x, y):  
  15.  return asarray([x * 2.0, y * 2.0])  
  16. # gradient descent algorithm with adam  
  17. def adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2, eps=1e-8):  
  18.  solutions = list()  
  19.  # generate an initial point  
  20.  x = bounds[:, 0] + rand(len(bounds)) * (bounds[:, 1] - bounds[:, 0])  
  21.  score = objective(x[0], x[1])  
  22.  # initialize first and second moments  
  23.  m = [0.0 for _ in range(bounds.shape[0])]  
  24.  v = [0.0 for _ in range(bounds.shape[0])]  
  25.  # run the gradient descent updates  
  26.  for t in range(n_iter):  
  27.   # calculate gradient g(t)  
  28.   g = derivative(x[0], x[1])  
  29.   # build a solution one variable at a time  
  30.   for i in range(bounds.shape[0]):  
  31.    # m(t) = beta1 * m(t-1) + (1 - beta1) * g(t)  
  32.    m[i] = beta1 * m[i] + (1.0 - beta1) * g[i]  
  33.    # v(t) = beta2 * v(t-1) + (1 - beta2) * g(t)^2  
  34.    v[i] = beta2 * v[i] + (1.0 - beta2) * g[i]**2  
  35.    # mhat(t) = m(t) / (1 - beta1(t))  
  36.    mmhat = m[i] / (1.0 - beta1**(t+1))  
  37.    # vhat(t) = v(t) / (1 - beta2(t))  
  38.    vvhat = v[i] / (1.0 - beta2**(t+1))  
  39.    # x(t) = x(t-1) - alpha * mhat(t) / (sqrt(vhat(t)) + ep)  
  40.    x[i] = x[i] - alpha * mhat / (sqrt(vhat) + eps)  
  41.   # evaluate candidate point  
  42.   score = objective(x[0], x[1])  
  43.   # keep track of solutions  
  44.   solutions.append(x.copy())  
  45.   # report progress  
  46.   print('>%d f(%s) = %.5f' % (t, x, score))  
  47.  return solutions 
  48. # seed the pseudo random number generator  
  49. seed(1)  
  50. # define range for input  
  51. bounds = asarray([[-1.0, 1.0], [-1.0, 1.0]])  
  52. # define the total iterations  
  53. n_iter = 60  
  54. # steps size  
  55. alpha = 0.02  
  56. # factor for average gradient  
  57. beta1 = 0.8 
  58. # factor for average squared gradient  
  59. beta2 = 0.999  
  60. # perform the gradient descent search with adam  
  61. solutions = adam(objective, derivative, bounds, n_iter, alpha, beta1, beta2)  
  62. # sample input range uniformly at 0.1 increments  
  63. xaxis = arange(bounds[0,0], bounds[0,1], 0.1)  
  64. yaxis = arange(bounds[1,0], bounds[1,1], 0.1)  
  65. # create a mesh from the axis  
  66. x, y = meshgrid(xaxis, yaxis)  
  67. # compute targets  
  68. results = objective(x, y)  
  69. # create a filled contour plot with 50 levels and jet color scheme  
  70. pyplot.contourf(x, y, results, levels=50cmap='jet' 
  71. # plot the sample as black circles  
  72. solutions = asarray(solutions)  
  73. pyplot.plot(solutions[:, 0], solutions[:, 1], '.-', color='w' 
  74. # show the plot  
  75. pyplot.show() 

運(yùn)行示例將像以前一樣執(zhí)行搜索,但是在這種情況下,將創(chuàng)建目標(biāo)函數(shù)的輪廓圖。

在這種情況下,我們可以看到在搜索過程中找到的每個(gè)解決方案都顯示一個(gè)白點(diǎn),從最優(yōu)點(diǎn)開始,逐漸靠近圖中心的最優(yōu)點(diǎn)。

 

 

責(zé)任編輯:龐桂玉 來源: Python中文社區(qū) (ID:python-china)
相關(guān)推薦

2020-12-07 11:23:32

Scrapy爬蟲Python

2021-01-29 11:25:57

Python爬山算法函數(shù)優(yōu)化

2020-12-17 10:00:16

Python協(xié)程線程

2021-03-12 09:45:00

Python關(guān)聯(lián)規(guī)則算法

2021-01-11 09:33:37

Maven數(shù)目項(xiàng)目

2021-04-27 10:16:51

優(yōu)化機(jī)器學(xué)習(xí)人工智能

2017-01-10 09:07:53

tcpdumpGET請求

2020-10-14 11:31:41

Docker

2020-10-27 10:43:24

Redis字符串數(shù)據(jù)庫

2019-05-08 14:02:52

MySQL索引查詢優(yōu)化數(shù)據(jù)庫

2023-03-27 09:40:01

GoWebAssembl集成

2021-01-27 18:15:01

Docker底層宿主機(jī)

2021-06-07 09:51:22

原型模式序列化

2009-11-17 14:50:50

Oracle調(diào)優(yōu)

2021-10-20 06:58:10

工具低代碼無代碼

2020-11-24 11:50:52

Python文件代碼

2021-04-19 23:29:44

MakefilemacOSLinux

2020-12-01 12:44:44

PythonHook鉤子函數(shù)

2018-01-30 05:04:06

2021-01-06 05:23:15

ServiceMesh網(wǎng)絡(luò)阿帕網(wǎng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號