成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

從零開始使用 Nadam 進(jìn)行梯度下降優(yōu)化

開發(fā) 前端
梯度下降的局限性在于,如果梯度變?yōu)槠教够虼笄剩阉鞯倪M(jìn)度可能會(huì)減慢。可以將動(dòng)量添加到梯度下降中,該下降合并了一些慣性以進(jìn)行更新。

[[394858]]

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

梯度下降的局限性在于,如果梯度變?yōu)槠教够虼笄剩阉鞯倪M(jìn)度可能會(huì)減慢。可以將動(dòng)量添加到梯度下降中,該下降合并了一些慣性以進(jìn)行更新。可以通過合并預(yù)計(jì)的新位置而非當(dāng)前位置的梯度(稱為Nesterov的加速梯度(NAG)或Nesterov動(dòng)量)來進(jìn)一步改善此效果。

梯度下降的另一個(gè)限制是,所有輸入變量都使用單個(gè)步長(zhǎng)(學(xué)習(xí)率)。對(duì)梯度下降的擴(kuò)展,如自適應(yīng)運(yùn)動(dòng)估計(jì)(Adam)算法,該算法對(duì)每個(gè)輸入變量使用單獨(dú)的步長(zhǎng),但可能會(huì)導(dǎo)致步長(zhǎng)迅速減小到非常小的值。Nesterov加速的自適應(yīng)矩估計(jì)或Nadam是Adam算法的擴(kuò)展,該算法結(jié)合了Nesterov動(dòng)量,可以使優(yōu)化算法具有更好的性能。

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

  • 梯度下降是一種優(yōu)化算法,它使用目標(biāo)函數(shù)的梯度來導(dǎo)航搜索空間。
  • 納丹(Nadam)是亞當(dāng)(Adam)版本的梯度下降的擴(kuò)展,其中包括了內(nèi)斯特羅夫的動(dòng)量。
  • 如何從頭開始實(shí)現(xiàn)Nadam優(yōu)化算法并將其應(yīng)用于目標(biāo)函數(shù)并評(píng)估結(jié)果。

教程概述

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

  • 梯度下降
  • Nadam優(yōu)化算法
  • 娜達(dá)姆(Nadam)的梯度下降
    • 二維測(cè)試問題
    • Nadam的梯度下降優(yōu)化
    • 可視化的Nadam優(yōu)化

梯度下降

梯度下降是一種優(yōu)化算法。它在技術(shù)上稱為一階優(yōu)化算法,因?yàn)樗鞔_利用了目標(biāo)目標(biāo)函數(shù)的一階導(dǎo)數(shù)。

一階導(dǎo)數(shù),或簡(jiǎn)稱為“導(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ù)。

對(duì)于特定輸入,導(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)。首先通過計(jì)算輸入空間中要移動(dòng)多遠(yuǎn)的距離來進(jìn)行下坡運(yùn)動(dòng),計(jì)算方法是將步長(zhǎng)(稱為alpha或?qū)W習(xí)率)乘以梯度。然后從當(dāng)前點(diǎn)減去該值,以確保我們逆梯度移動(dòng)或向下移動(dòng)目標(biāo)函數(shù)。

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

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

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

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

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

Nadam優(yōu)化算法

Nesterov加速的自適應(yīng)動(dòng)量估計(jì)或Nadam算法是對(duì)自適應(yīng)運(yùn)動(dòng)估計(jì)(Adam)優(yōu)化算法的擴(kuò)展,添加了Nesterov的加速梯度(NAG)或Nesterov動(dòng)量,這是一種改進(jìn)的動(dòng)量。更廣泛地講,Nadam算法是對(duì)梯度下降優(yōu)化算法的擴(kuò)展。Timothy Dozat在2016年的論文“將Nesterov動(dòng)量整合到Adam中”中描述了該算法。盡管論文的一個(gè)版本是在2015年以同名斯坦福項(xiàng)目報(bào)告的形式編寫的。動(dòng)量將梯度的指數(shù)衰減移動(dòng)平均值(第一矩)添加到梯度下降算法中。這具有消除嘈雜的目標(biāo)函數(shù)和提高收斂性的影響。Adam是梯度下降的擴(kuò)展,它增加了梯度的第一和第二矩,并針對(duì)正在優(yōu)化的每個(gè)參數(shù)自動(dòng)調(diào)整學(xué)習(xí)率。NAG是動(dòng)量的擴(kuò)展,其中動(dòng)量的更新是使用對(duì)參數(shù)的預(yù)計(jì)更新量而不是實(shí)際當(dāng)前變量值的梯度來執(zhí)行的。在某些情況下,這樣做的效果是在找到最佳位置時(shí)減慢了搜索速度,而不是過沖。

納丹(Nadam)是對(duì)亞當(dāng)(Adam)的擴(kuò)展,它使用NAG動(dòng)量代替經(jīng)典動(dòng)量。讓我們逐步介紹該算法的每個(gè)元素。Nadam使用衰減步長(zhǎng)(alpha)和一階矩(mu)超參數(shù)來改善性能。為了簡(jiǎn)單起見,我們暫時(shí)將忽略此方面,并采用恒定值。首先,對(duì)于搜索中要優(yōu)化的每個(gè)參數(shù),我們必須保持梯度的第一矩和第二矩,分別稱為m和n。在搜索開始時(shí)將它們初始化為0.0。

  • m = 0
  • n = 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í)間步長(zhǎng)的梯度(偏導(dǎo)數(shù))。

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

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

  1. m(t)=mu* m(t-1)+(1 –mu)* g(t) 

然后使用“ nu”超參數(shù)更新第二時(shí)刻。

  1. n(t)= nu * n(t-1)+(1 – nu)* g(t)^ 2 

接下來,使用Nesterov動(dòng)量對(duì)第一時(shí)刻進(jìn)行偏差校正。

  1. mhat =(mu * m(t)/(1 – mu))+((1 – mu)* g(t)/(1 – mu)) 

然后對(duì)第二個(gè)時(shí)刻進(jìn)行偏差校正。注意:偏差校正是Adam的一個(gè)方面,它與在搜索開始時(shí)將第一時(shí)刻和第二時(shí)刻初始化為零這一事實(shí)相反。

  1. nhat = nu * n(t)/(1 – nu) 

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

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

其中alpha是步長(zhǎng)(學(xué)習(xí)率)超參數(shù),sqrt()是平方根函數(shù),eps(epsilon)是一個(gè)較小的值,如1e-8,以避免除以零誤差。

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

  1. alpha:初始步長(zhǎng)(學(xué)習(xí)率),典型值為0.002。 
  2. mu:第一時(shí)刻的衰減因子(Adam中的beta1),典型值為0.975。 
  3. nu:第二時(shí)刻的衰減因子(Adam中的beta2),典型值為0.999。 

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

娜達(dá)姆(Nadam)的梯度下降

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

二維測(cè)試問題

首先,讓我們定義一個(gè)優(yōu)化函數(shù)。我們將使用一個(gè)簡(jiǎn)單的二維函數(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.   
  6. # objective function 
  7. def objective(x, y): 
  8.  return x**2.0 + y**2.0 
  9.   
  10. # define range for input 
  11. r_min, r_max = -1.0, 1.0 
  12. # sample input range uniformly at 0.1 increments 
  13. xaxis = arange(r_min, r_max, 0.1) 
  14. yaxis = arange(r_min, r_max, 0.1) 
  15. create a mesh from the axis 
  16. x, y = meshgrid(xaxis, yaxis) 
  17. # compute targets 
  18. results = objective(x, y) 
  19. create a surface plot with the jet color scheme 
  20. figure = pyplot.figure() 
  21. axis = figure.gca(projection='3d'
  22. axis.plot_surface(x, y, results, cmap='jet'
  23. # show the plot 
  24. 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.   
  7. # objective function 
  8. def objective(x, y): 
  9.  return x**2.0 + y**2.0 
  10.   
  11. # define range for input 
  12. bounds = asarray([[-1.0, 1.0], [-1.0, 1.0]]) 
  13. # sample input range uniformly at 0.1 increments 
  14. xaxis = arange(bounds[0,0], bounds[0,1], 0.1) 
  15. yaxis = arange(bounds[1,0], bounds[1,1], 0.1) 
  16. create a mesh from the axis 
  17. x, y = meshgrid(xaxis, yaxis) 
  18. # compute targets 
  19. results = objective(x, y) 
  20. create a filled contour plot with 50 levels and jet color scheme 
  21. pyplot.contourf(x, y, results, levels=50, cmap='jet'
  22. # show the plot 
  23. pyplot.show() 

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

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

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

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

x ^ 2的導(dǎo)數(shù)在每個(gè)維度上均為x * 2。

  1. f(x)= x ^ 2 
  2. f'(x)= 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]) 

接下來,我們可以使用Nadam實(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]) 

接下來,我們需要初始化力矩矢量。

  1. # initialize decaying moving averages 
  2. m = [0.0 for _ in range(bounds.shape[0])] 
  3. n = [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.  ... 

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

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

接下來,我們需要執(zhí)行Nadam更新計(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) = mu * m(t-1) + (1 - mu) * g(t) 
  2. m[i] = mu * m[i] + (1.0 - mu) * g[i] 

然后是第二個(gè)矩向量。

  1. # nhat = nu * n(t) / (1 - nu) 
  2. nhat = nu * n[i] / (1.0 - nu) 
  3. # n(t) = nu * n(t-1) + (1 - nu) * g(t)^2 
  4. n[i] = nu * n[i] + (1.0 - nu) * g[i]**2 

然后是經(jīng)過偏差校正的內(nèi)斯特羅夫動(dòng)量。

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

偏差校正的第二時(shí)刻。

  1. # nhat = nu * n(t) / (1 - nu) 
  2. nhat = nu * n[i] / (1.0 - nu) 

最后更新參數(shù)。

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

然后,針對(duì)要優(yōu)化的每個(gè)參數(shù)重復(fù)此操作。在迭代結(jié)束時(shí),我們可以評(píng)估新的參數(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è)名為nadam()的函數(shù)中,該函數(shù)采用目標(biāo)函數(shù)和派生函數(shù)的名稱以及算法超參數(shù),并返回在搜索及其評(píng)估結(jié)束時(shí)找到的最佳解決方案。

  1. # gradient descent algorithm with nadam 
  2. def nadam(objective, derivative, bounds, n_iter, alpha, mu, nu, 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 decaying moving averages 
  7.  m = [0.0 for _ in range(bounds.shape[0])] 
  8.  n = [0.0 for _ in range(bounds.shape[0])] 
  9.  # run the gradient descent 
  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(bounds.shape[0]): 
  15.    # m(t) = mu * m(t-1) + (1 - mu) * g(t) 
  16.    m[i] = mu * m[i] + (1.0 - mu) * g[i] 
  17.    # n(t) = nu * n(t-1) + (1 - nu) * g(t)^2 
  18.    n[i] = nu * n[i] + (1.0 - nu) * g[i]**2 
  19.    # mhat = (mu * m(t) / (1 - mu)) + ((1 - mu) * g(t) / (1 - mu)) 
  20.    mhat = (mu * m[i] / (1.0 - mu)) + ((1 - mu) * g[i] / (1.0 - mu)) 
  21.    # nhat = nu * n(t) / (1 - nu) 
  22.    nhat = nu * n[i] / (1.0 - nu) 
  23.    # x(t) = x(t-1) - alpha / (sqrt(nhat) + eps) * mhat 
  24.    x[i] = x[i] - alpha / (sqrt(nhat) + eps) * mhat 
  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ù)和超參數(shù)的界限,并調(diào)用函數(shù)執(zhí)行優(yōu)化。在這種情況下,我們將運(yùn)行該算法進(jìn)行50次迭代,初始alpha為0.02,μ為0.8,nu為0.999,這是經(jīng)過一點(diǎn)點(diǎn)反復(fù)試驗(yàn)后發(fā)現(xiàn)的。

  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 = 50 
  7. # steps size 
  8. alpha = 0.02 
  9. # factor for average gradient 
  10. mu = 0.8 
  11. # factor for average squared gradient 
  12. nu = 0.999 
  13. # perform the gradient descent search with nadam 
  14. best, score = nadam(objective, derivative, bounds, n_iter, alpha, mu, nu) 

運(yùn)行結(jié)束時(shí),我們將報(bào)告找到的最佳解決方案。

  1. # summarize the result 
  2. print('Done!'
  3. print('f(%s) = %f' % (best, score)) 

綜合所有這些,下面列出了適用于我們的測(cè)試問題的Nadam梯度下降的完整示例。

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

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

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

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

  1. >40 f([ 5.07445337e-05 -3.32910019e-03]) = 0.00001 
  2. >41 f([-1.84325171e-05 -3.00939427e-03]) = 0.00001 
  3. >42 f([-6.78814472e-05 -2.69839367e-03]) = 0.00001 
  4. >43 f([-9.88339249e-05 -2.40042096e-03]) = 0.00001 
  5. >44 f([-0.00011368 -0.00211861]) = 0.00000 
  6. >45 f([-0.00011547 -0.00185511]) = 0.00000 
  7. >46 f([-0.0001075 -0.00161122]) = 0.00000 
  8. >47 f([-9.29922627e-05 -1.38760991e-03]) = 0.00000 
  9. >48 f([-7.48258406e-05 -1.18436586e-03]) = 0.00000 
  10. >49 f([-5.54299505e-05 -1.00116899e-03]) = 0.00000 
  11. Done! 
  12. f([-5.54299505e-05 -1.00116899e-03]) = 0.000001 

可視化的Nadam優(yōu)化

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

  1. # gradient descent algorithm with nadam 
  2. def nadam(objective, derivative, bounds, n_iter, alpha, mu, nu, 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 decaying moving averages 
  8.  m = [0.0 for _ in range(bounds.shape[0])] 
  9.  n = [0.0 for _ in range(bounds.shape[0])] 
  10.  # run the gradient descent 
  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) = mu * m(t-1) + (1 - mu) * g(t) 
  17.    m[i] = mu * m[i] + (1.0 - mu) * g[i] 
  18.    # n(t) = nu * n(t-1) + (1 - nu) * g(t)^2 
  19.    n[i] = nu * n[i] + (1.0 - nu) * g[i]**2 
  20.    # mhat = (mu * m(t) / (1 - mu)) + ((1 - mu) * g(t) / (1 - mu)) 
  21.    mhat = (mu * m[i] / (1.0 - mu)) + ((1 - mu) * g[i] / (1.0 - mu)) 
  22.    # nhat = nu * n(t) / (1 - nu) 
  23.    nhat = nu * n[i] / (1.0 - nu) 
  24.    # x(t) = x(t-1) - alpha / (sqrt(nhat) + eps) * mhat 
  25.    x[i] = x[i] - alpha / (sqrt(nhat) + eps) * mhat 
  26.   # evaluate candidate point 
  27.   score = objective(x[0], x[1]) 
  28.   # store solution 
  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 = 50 
  7. # steps size 
  8. alpha = 0.02 
  9. # factor for average gradient 
  10. mu = 0.8 
  11. # factor for average squared gradient 
  12. nu = 0.999 
  13. # perform the gradient descent search with nadam 
  14. solutions = nadam(objective, derivative, bounds, n_iter, alpha, mu, nu) 

然后,我們可以像以前一樣創(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=50, cmap='jet'

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

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

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

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

2018-05-09 20:08:09

人工智能深度學(xué)習(xí)Python

2017-06-29 11:05:46

TensorFlow深度學(xué)習(xí)

2024-11-13 15:18:51

JITWatch開發(fā)

2015-11-17 16:11:07

Code Review

2019-01-18 12:39:45

云計(jì)算PaaS公有云

2018-04-18 07:01:59

Docker容器虛擬機(jī)

2024-12-06 17:02:26

2020-07-02 15:32:23

Kubernetes容器架構(gòu)

2022-01-24 07:35:39

XLL網(wǎng)絡(luò)攻擊惡意軟件

2010-05-26 17:35:08

配置Xcode SVN

2018-09-14 17:16:22

云計(jì)算軟件計(jì)算機(jī)網(wǎng)絡(luò)

2013-09-22 10:15:01

Spring DataJPA

2019-09-30 10:51:11

Markdown標(biāo)記語言

2024-05-15 14:29:45

2018-03-14 11:15:06

2017-10-05 16:51:28

LSTM神經(jīng)網(wǎng)絡(luò)貨幣兌換匯率

2023-12-27 08:47:41

PrometheusLinux架構(gòu)

2017-08-25 14:29:43

機(jī)器學(xué)習(xí)Java

2011-04-06 15:55:50

開發(fā)webOS程序webOS

2015-10-15 14:16:24

點(diǎn)贊
收藏

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

主站蜘蛛池模板: 成人在线观看免费 | 色本道| 中文字幕 亚洲一区 | 91精品国产一区二区三区蜜臀 | 蜜桃精品噜噜噜成人av | 国产一区二区激情视频 | 午夜码电影| 国产高清精品在线 | 亚洲国产激情 | 中文字幕日韩一区 | 久久综合伊人一区二区三 | 国产精品永久免费视频 | 五月婷婷导航 | 国产三区在线观看视频 | 另类视频区 | 成人在线视频网 | 亚洲精品自拍视频 | 免费特级黄毛片 | 成人在线免费av | 黄色一级电影免费观看 | 91看片| 亚洲精品电影 | 精品国产一区二区三区日日嗨 | 天天躁日日躁狠狠躁2018小说 | 一区二区在线不卡 | 国产伦精品一区二区三区照片91 | 91玖玖 | 国产精品久久久久久久模特 | 国产视频一二三区 | 毛片毛片毛片毛片毛片 | 国产综合av | 国产日韩欧美精品一区二区 | 久久久久久亚洲 | 国产成人综合在线 | 1区2区3区视频 | 国产高清亚洲 | 美国一级毛片a | 在线观看欧美一区 | 狠狠操电影 | av国产精品| 国产玖玖 |