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

從零開始使用 Nadam 進行梯度下降優化

開發 前端
梯度下降的局限性在于,如果梯度變為平坦或大曲率,搜索的進度可能會減慢。可以將動量添加到梯度下降中,該下降合并了一些慣性以進行更新。

[[394858]]

 梯度下降是一種優化算法,遵循目標函數的負梯度以定位函數的最小值。

梯度下降的局限性在于,如果梯度變為平坦或大曲率,搜索的進度可能會減慢。可以將動量添加到梯度下降中,該下降合并了一些慣性以進行更新。可以通過合并預計的新位置而非當前位置的梯度(稱為Nesterov的加速梯度(NAG)或Nesterov動量)來進一步改善此效果。

梯度下降的另一個限制是,所有輸入變量都使用單個步長(學習率)。對梯度下降的擴展,如自適應運動估計(Adam)算法,該算法對每個輸入變量使用單獨的步長,但可能會導致步長迅速減小到非常小的值。Nesterov加速的自適應矩估計或Nadam是Adam算法的擴展,該算法結合了Nesterov動量,可以使優化算法具有更好的性能。

在本教程中,您將發現如何從頭開始使用Nadam進行梯度下降優化。完成本教程后,您將知道:

  • 梯度下降是一種優化算法,它使用目標函數的梯度來導航搜索空間。
  • 納丹(Nadam)是亞當(Adam)版本的梯度下降的擴展,其中包括了內斯特羅夫的動量。
  • 如何從頭開始實現Nadam優化算法并將其應用于目標函數并評估結果。

教程概述

本教程分為三個部分:他們是:

  • 梯度下降
  • Nadam優化算法
  • 娜達姆(Nadam)的梯度下降
    • 二維測試問題
    • Nadam的梯度下降優化
    • 可視化的Nadam優化

梯度下降

梯度下降是一種優化算法。它在技術上稱為一階優化算法,因為它明確利用了目標目標函數的一階導數。

一階導數,或簡稱為“導數”,是目標函數在特定點(例如,點)上的變化率或斜率。用于特定輸入。

如果目標函數采用多個輸入變量,則將其稱為多元函數,并且可以將輸入變量視為向量。反過來,多元目標函數的導數也可以視為向量,通常稱為梯度。

梯度:多元目標函數的一階導數。

對于特定輸入,導數或梯度指向目標函數最陡峭的上升方向。梯度下降是指一種最小化優化算法,該算法遵循目標函數的下坡梯度負值來定位函數的最小值。

梯度下降算法需要一個正在優化的目標函數和該目標函數的導數函數。目標函數f()返回給定輸入集合的分數,導數函數f'()給出給定輸入集合的目標函數的導數。梯度下降算法需要問題中的起點(x),例如輸入空間中的隨機選擇點。

假設我們正在最小化目標函數,然后計算導數并在輸入空間中采取一步,這將導致目標函數下坡運動。首先通過計算輸入空間中要移動多遠的距離來進行下坡運動,計算方法是將步長(稱為alpha或學習率)乘以梯度。然后從當前點減去該值,以確保我們逆梯度移動或向下移動目標函數。

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

在給定點的目標函數越陡峭,梯度的大小越大,反過來,在搜索空間中采取的步伐也越大。使用步長超參數來縮放步長的大小。

步長:超參數,用于控制算法每次迭代相對于梯度在搜索空間中移動多遠。

如果步長太小,則搜索空間中的移動將很小,并且搜索將花費很長時間。如果步長太大,則搜索可能會在搜索空間附近反彈并跳過最優值。

現在我們已經熟悉了梯度下降優化算法,接下來讓我們看一下Nadam算法。

Nadam優化算法

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

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

  • m = 0
  • n = 0

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

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

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

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

然后使用“ nu”超參數更新第二時刻。

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

接下來,使用Nesterov動量對第一時刻進行偏差校正。

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

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

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

最后,我們可以為該迭代計算參數的值。

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

其中alpha是步長(學習率)超參數,sqrt()是平方根函數,eps(epsilon)是一個較小的值,如1e-8,以避免除以零誤差。

回顧一下,該算法有三個超參數。他們是:

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

就是這樣。接下來,讓我們看看如何在Python中從頭開始實現該算法。

娜達姆(Nadam)的梯度下降

在本節中,我們將探索如何使用Nadam動量實現梯度下降優化算法。

二維測試問題

首先,讓我們定義一個優化函數。我們將使用一個簡單的二維函數,該函數將每個維的輸入平方,并定義有效輸入的范圍(從-1.0到1.0)。下面的Objective()函數實現了此功能

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

我們可以創建數據集的三維圖,以了解響應面的曲率。下面列出了繪制目標函數的完整示例。

  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() 

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

我們還可以創建函數的二維圖。這在以后要繪制搜索進度時會很有幫助。下面的示例創建目標函數的輪廓圖。

  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() 

運行示例將創建目標函數的二維輪廓圖。我們可以看到碗的形狀被壓縮為以顏色漸變顯示的輪廓。我們將使用該圖來繪制在搜索過程中探索的特定點。

現在我們有了一個測試目標函數,讓我們看一下如何實現Nadam優化算法。

Nadam的梯度下降優化

我們可以將Nadam的梯度下降應用于測試問題。首先,我們需要一個函數來計算此函數的導數。

x ^ 2的導數在每個維度上均為x * 2。

  1. f(x)= x ^ 2 
  2. f'(x)= x * 2 

derived()函數在下面實現了這一點。

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

接下來,我們可以使用Nadam實現梯度下降優化。首先,我們可以選擇問題范圍內的隨機點作為搜索的起點。假定我們有一個數組,該數組定義搜索范圍,每個維度一行,并且第一列定義最小值,第二列定義維度的最大值。

  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])] 

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

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

第一步是計算當前參數集的導數。

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

接下來,我們需要執行Nadam更新計算。為了提高可讀性,我們將使用命令式編程樣式來一次執行一個變量的這些計算。在實踐中,我建議使用NumPy向量運算以提高效率。

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

首先,我們需要計算力矩矢量。

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

然后是第二個矩向量。

  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 

然后是經過偏差校正的內斯特羅夫動量。

  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)) 

偏差校正的第二時刻。

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

最后更新參數。

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

然后,針對要優化的每個參數重復此操作。在迭代結束時,我們可以評估新的參數值并報告搜索的性能。

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

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

  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] 

然后,我們可以定義函數和超參數的界限,并調用函數執行優化。在這種情況下,我們將運行該算法進行50次迭代,初始alpha為0.02,μ為0.8,nu為0.999,這是經過一點點反復試驗后發現的。

  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) 

運行結束時,我們將報告找到的最佳解決方案。

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

綜合所有這些,下面列出了適用于我們的測試問題的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)) 

運行示例將優化算法和Nadam應用于我們的測試問題,并報告算法每次迭代的搜索性能。

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

在這種情況下,我們可以看到在大約44次搜索迭代后找到了接近最佳的解決方案,輸入值接近0.0和0.0,評估為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優化

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

  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 

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

  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) 

然后,我們可以像以前一樣創建目標函數的輪廓圖。

  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'

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

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

綜上所述,下面列出了對測試問題執行Nadam優化并將結果繪制在輪廓圖上的完整示例。

  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() 

運行示例將像以前一樣執行搜索,但是在這種情況下,將創建目標函數的輪廓圖。

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

 

責任編輯:武曉燕 來源: Python中文社區
相關推薦

2018-05-09 20:08:09

人工智能深度學習Python

2017-06-29 11:05:46

TensorFlow深度學習

2024-11-13 15:18:51

JITWatch開發

2015-11-17 16:11:07

Code Review

2019-01-18 12:39:45

云計算PaaS公有云

2018-04-18 07:01:59

Docker容器虛擬機

2024-12-06 17:02:26

2020-07-02 15:32:23

Kubernetes容器架構

2022-01-24 07:35:39

XLL網絡攻擊惡意軟件

2010-05-26 17:35:08

配置Xcode SVN

2018-09-14 17:16:22

云計算軟件計算機網絡

2024-05-15 14:29:45

2013-09-22 10:15:01

Spring DataJPA

2019-09-30 10:51:11

Markdown標記語言

2017-10-05 16:51:28

LSTM神經網絡貨幣兌換匯率

2018-03-14 11:15:06

2023-12-27 08:47:41

PrometheusLinux架構

2015-10-15 14:16:24

2024-04-10 07:48:41

搜索引擎場景

2011-04-06 15:55:50

開發webOS程序webOS
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人激情视频免费在线观看 | 伊人狠狠操 | 九九在线视频 | 国产一区二区三区久久久久久久久 | 97国产在线观看 | 免费观看a级毛片在线播放 黄网站免费入口 | 欧美精品一二三区 | 色视频www在线播放国产人成 | 精品视频在线播放 | 日本欧美国产 | 国产精品国产精品国产专区不卡 | 精品免费国产一区二区三区 | 紧缚调教一区二区三区视频 | aaa精品| 日韩三区| 亚洲午夜小视频 | 午夜精品一区二区三区在线观看 | 精品在线看 | 国产日屁| 欧美日韩成人在线 | 色999视频 | 成人国产精品 | 亚洲精品在线播放 | 亚洲成人精品 | 成人在线免费网站 | 黄色国产大片 | 亚洲精品美女 | 婷婷久久精品一区二区 | 91精品久久久久久久久久入口 | 成年人在线观看视频 | 久久综合一区 | 黄色一级毛片 | 亚洲第一视频网站 | 91亚洲精品国偷拍自产在线观看 | 91视视频在线观看入口直接观看 | 九色在线| 成人欧美日韩一区二区三区 | 欧美精品一区二区在线观看 | 91精品一区二区三区久久久久久 | 日韩av免费在线电影 | 国产精品欧美一区二区三区不卡 |