自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ML之梯度下降算法 機器學習初學者的梯度下降算法

人工智能 機器學習 算法
梯度下降算法就是一個被廣泛使用的優(yōu)化算法, 它可以用于尋找最小化成本函數(shù)的參數(shù)值. 用中學數(shù)學的語言來描述梯度下降, 是這樣的: 當函數(shù) _ 取得最小值時, 求所對應的自變量 的過程_ 此處, 就是機器要學習的參數(shù), 就是用于參數(shù)估計的成本函數(shù), 是關于 的函數(shù). 因此, 基本上具備中學數(shù)學知識的, 都能理解梯度下降算法.

[[197951]]

基本概念

本節(jié)嘗試獨立于機器學習算法, 單純地來講梯度下降算法 [Gradient Descent, GD], 以使梯度下降更具一般性。

開始之前, 先放 2 個基本概念, 帶著這 2 個認識, 在幾乎不具備機器學習知識的前提下, 應該也能很好地讀懂本節(jié)內容:

  • 機器學習的主要任務之一, 就是通過訓練, 習得一組最優(yōu)的參數(shù). 常以成本函數(shù) [Cost Function] 作為參數(shù)估計的函數(shù), 因此, 機器學習的任務就轉變?yōu)榱俗钚』杀竞瘮?shù).
  • 優(yōu)化是機器學習算法非常重要的組成部分, 幾乎每個機器學習算法都有一個優(yōu)化算法.

梯度下降算法就是一個被廣泛使用的優(yōu)化算法, 它可以用于尋找最小化成本函數(shù)的參數(shù)值. 用中學數(shù)學的語言來描述梯度下降, 是這樣的: 當函數(shù) _ 取得最小值時, 求所對應的自變量 的過程_ 此處, 就是機器要學習的參數(shù), 就是用于參數(shù)估計的成本函數(shù), 是關于 的函數(shù). 因此, 基本上具備中學數(shù)學知識的, 都能理解梯度下降算法.

梯度下降的基本步驟是:

  1. 對成本函數(shù)進行微分, 得到其在給定點的梯度. 梯度的正負指示了成本函數(shù)值的上升或下降:
  2. 選擇使成本函數(shù)值減小的方向, 即梯度負方向, 乘以以學習率 計算得參數(shù)的更新量, 并更新參數(shù):
  3. 重復以上步驟, 直到取得最小的成本

以上就是梯度下降算法最基礎也是最核心的概念, 很簡單吧.

下面講講梯度下降算法的幾個變種, 包括: 批量梯度下降 [Batch Gradient Descent, BGD], 隨機梯度下降 [Stochastic Gradient Descent, SGD], 小批量梯度下降 [Mini-Batch Gradient Descent, MBGD]

算法簡介

BGD

BGD 是梯度下降算法最原始的形式, 其特點是每次更新參數(shù) 時, 都使用整個訓練集的數(shù)據(jù).

BGD 的具體實現(xiàn)是這樣的:

  • 設假設函數(shù)為:
    • 所謂假設函數(shù), 就是用于將輸入映射為輸出的工具, 其返回值也稱為估計值
  • 設成本函數(shù)為:
    • 注意, 才是函數(shù)自變量, 是模型輸入, 是輸入對應的真實值
    • 該成本函數(shù)中, 真正有效的部分是 , 前面的 是為后續(xù)計算方便添加的
  • 對成本函數(shù)求導, 需要對每一個參數(shù) 分別求偏導, 得到它們各自的梯度:
    • 機器學習模型通常不止一個參數(shù). 成本函數(shù)作為參數(shù)估計的工具, 要估計每個參數(shù)的最優(yōu)值, 因此需要對每一個參數(shù)分別求偏導數(shù)
  • 每個參數(shù)都按梯度負方向進行更新:

因此, BGD 的偽代碼形式可以簡單地寫成:

  1. repeat { 
  2.  
  3.      
  4.  
  5.     (for every j = 0, 1, .. n) 
  6.  
  7.  

上式中的求和部分 就體現(xiàn)了每一次迭代, 都以整個訓練集為對象進行梯度計算.

BGD 得到的是全局最優(yōu)解, 因為它總是以整個訓練集來計算梯度, 這是 BGD 的優(yōu)點. 但也因此帶來了巨大的計算量, 計算迭代速度很很慢.

SGD

SGD 每次以一個樣本, 而不是整個數(shù)據(jù)集來計算梯度. 因此, SGD 從成本函數(shù)開始, 就不必再求和了, 針對單個樣例的成本函數(shù)可以寫成: (此處的 同樣是為了后續(xù)計算方便設置的)

于是, SGD 的參數(shù)更新規(guī)則就可以寫成:

SGD 的偽代碼形式如下:

  1. repeat { 
  2.  
  3.     for i = 1, .., m { 
  4.  
  5.          
  6.  
  7.         (for every j = 0, 1, .. n) 
  8.  
  9.     } 
  10.  
  11.  

SGD 的關鍵點在于以隨機順序選取樣本. 因為 SGD 存在局部最優(yōu)困境, 若每次都以相同的順序選取樣本, 其有很大的可能會在相同的地方陷入局部困境, 或者收斂減緩. 因此, 欲使 SGD 發(fā)揮更好的效果, 應充分利用隨機化 [Randomise] 帶來的優(yōu)勢: 可以在每次迭代之前 (偽代碼中最外圍循環(huán)), 對訓練集進行隨機排列.

因為每次只取一個樣本來進行梯度下降, SGD 的訓練速度很快, 但會引入噪聲, 使準確度下降. 這意味著并不是每次迭代都向著全局最優(yōu)而去, 即并不是每次迭代都能使成本函數(shù)值降低. 不過換個思路的話, 噪聲在一定程度上以使算法避免了局部最優(yōu).

SGD 的另一個好處是, 可以使用在線學習 [online learning]. 也就是說, 在模型訓練好之后, 只要有新的數(shù)據(jù)到來, 模型都可以利用新的數(shù)據(jù)進行再學習, 更新參數(shù),以適應新的變化.

MBGD

MBGD 是為解決 BGD 與 SGD 各自缺點而發(fā)明的折中算法, 或者說它利用了 BGD 和 SGD 各自優(yōu)點. 其基本思想是: 每次更新參數(shù)時, 使用 n 個樣本, 既不是全部, 也不是 1. (SGD 可以看成是 n=1 的 MBGD 的一個特例)

此處就不再給出 MBGD 的成本函數(shù)或其求導公式或參數(shù)更新規(guī)則公式了, 基本同 BGD, 見上.

MBGD 的偽代碼如下:

  1. say b=10, m=1000, 
  2. repeat { 
  3.     for i = 1, 11, 21, .., 991 { 
  4.          
  5.         (for every j = 0, 1, .. n) 
  6.     } 
  7.  

總結一下以上 3 個梯度下降算法的優(yōu)缺點:

梯度下降算法 優(yōu)點 缺點
BGD 全局最優(yōu)解 計算量大, 迭代速度慢, 訓練速度慢
SGD 1.訓練速度快
2. 支持在線學習
準確度下降, 有噪聲, 非全局最優(yōu)解
MBGD 1. 訓練速度較快, 取決于小批量的數(shù)目
2. 支持在線學習
準確度不如 BGD, 仍然有噪聲, 非全局最優(yōu)解

Tips

下面將介紹一些梯度下降算法的使用技巧:

  • 挑選合適的學習率 . 最好的選擇方法就是監(jiān)測目標函數(shù)值 (本文中就是成本函數(shù)值) 隨時間的學習曲線.
  • 繪制成本-時間的曲線, 觀察成本隨迭代的變化情況, 即梯度的變化情況. 若成本沒有隨著迭代而下降, 說明學習率過大了 (發(fā)散了).
  • 學習率通常是一個很小的實值, 比如 0.1, 0.001, 0.0001. 學習率如果過大, 成本函數(shù)可能無法收斂, 一直處于發(fā)散狀態(tài).
  • 學習算法之前, 進行特征縮放能夠改善梯度下降. (親測! 原來使用較大學習率, 成本函數(shù)無法收斂; 使用特征縮放之后, 收斂了)
  • 使用 MBGD 時, 在學習過程中, 可以逐漸增大小批量的大小, 更好地綜合發(fā)揮 BGD 與 SGD 的優(yōu)勢.

進階

以下內容有點深奧, 筆者對一些概念也不甚熟悉, 僅僅是做個記錄

我注意到 Keras 實現(xiàn)的 SGD 提供了 3 個關鍵字參數(shù): decay, momentum, nestrov:

  1. decay – 衰減的意思, 表示每一次迭代, 學習率 的衰減量.
  2. momentum – 動量的意思, 旨在加速學習, 稍后介紹.
  3. nesterov – 算法名, 表示是否使用 Nesterov 動量算法.

使用 BGD 達到極小值時, 整個成本函數(shù)的真實梯度會變得很小, 最終減小為 0, 因此 BGD 可以使用固定的學習率; 然而, SGD 中梯度估計引入的噪聲源不會在極小點處消失, 因此有必要隨著時間的推移逐漸降低學習率, 以保證 SGD 收斂.

實踐中, 一般讓學習率線性衰減, 直到第 次迭代:

其中, 表示第 k 次迭代, 表示第 次迭代, .

上式中, 需要設置的量包括: 初始學習率 , 最終學習率 以及 終止迭代次數(shù) . 通常取幾百的大小, 則設為 的 . 因此, 剩下的主要問題就是選擇一個合適的 : 取值太大, 學習曲線會劇烈抖動, 成本會明顯增加; 取值太小, 學習過程會變得很緩慢.

上面提到, 在梯度下降中引入動量的概念, 是為了加速學習, 特別是對于處理高曲率 (曲率: 曲線偏離直線的程度), 小但一致的梯度, 或者帶噪聲的梯度, 有明顯的加速效果. 因為動量算法積累了之前梯度指數(shù)級衰減的移動平均 (移動平均: 分析時間序列數(shù)據(jù)的有效工具), 能夠繼續(xù)沿該方向移動, 從而使成本持續(xù)減小.

從形式上看, 動量算法引入了 充當速度的角色, 代表參數(shù)在參數(shù)空間移動的方向和速率. 被設為負梯度的指數(shù)衰減平均, 其更新規(guī)則如下:

從上式可以得出的一個結論是: 相對于 , 越大, 之前梯度對現(xiàn)在方向的影響就越大.

在引入動量的概念之前, 的更新步長只是梯度范數(shù)乘以學習率, 引入動量之后則取決于梯度序列的大小和排列. 當許多連續(xù)的梯度指向相同時, 步長最大

Nesterov 動量算法是標準動量算法的變種, 其更新規(guī)則如下:

Nesterov 動量算法與標準動量算法的區(qū)別在于梯度的計算, 其梯度計算是在施加了當前速度之后, 可以解釋為向標準動量方法中添加了一個校正因子.

題外話

研究優(yōu)化算法的收斂率時, 一般會衡量額外誤差: , 即當前成本超出最低可能成本的量. SGD 應用于凸問題 (研究定義于凸集中的凸函數(shù)最小化的問題)時, k 步迭代的額外誤差量級是 , 在強凸情況下是 . 除非假定額外條件, 否則不能進一步改進.

Cramer-Rao 界限指出, 泛化誤差的下降速度不會快于 . Bottou and Bousquet 因此認為機器學習任務, 不值得探尋收斂快于 的優(yōu)化算法, 因為:

更快的收斂可能對應過擬合

樣例代碼

以下是 BGD, SGD, MBGD 的 Python 代碼實現(xiàn), 暫時不包括進階部分提到的高級內容.

  1. import numpy as np 
  2. import pylab 
  3. from sklearn.datasets.samples_generator import make_regression 
  4.  
  5.  
  6. def bgd(alpha, x, y, numIterations): 
  7.     """Copied from Internet""" 
  8.     m = x.shape[0]  # number of samples 
  9.     theta = np.ones(2) 
  10.     J_list = [] 
  11.  
  12.     x_transpose = x.transpose() 
  13.     for iter in range(0, numIterations): 
  14.         hypothesis = np.dot(x, theta) 
  15.         loss = y - hypothesis 
  16.         J = np.sum(loss ** 2) / (2 * m)  # cost 
  17.         J_list.append(J) 
  18.         print("iter %s | J: %.3f" % (iter, J)) 
  19.  
  20.         gradient = np.dot(x_transpose, loss) / m 
  21.         theta += alpha * gradient  # update 
  22.  
  23.     pylab.plot(range(numIterations), J_list, "k-"
  24.     return theta 
  25.  
  26.  
  27. def sgd(alpha, x, y, num_iter): 
  28.     """Writtern by kissg""" 
  29.     m = x.shape[0]  # number of samples 
  30.     theta = np.ones(2) 
  31.     J_list = [] 
  32.  
  33.     # 隨機化序列 
  34.     idx = np.random.permutation(y.shape[0]) 
  35.     x, y = x[idx], y[idx] 
  36.  
  37.     for j in range(num_iter): 
  38.  
  39.         for i in idx: 
  40.             single_hypothesis = np.dot(x[i], theta) 
  41.             single_loss = y[i] - single_hypothesis 
  42.             gradient = np.dot(x[i].transpose(), single_loss) 
  43.             theta += alpha * gradient  # update 
  44.  
  45.         hypothesis = np.dot(x, theta) 
  46.         loss = y - hypothesis 
  47.         J = np.sum(loss ** 2) / (2 * m)  # cost 
  48.         J_list.append(J) 
  49.         print("iter %s | J: %.3f" % (j, J)) 
  50.  
  51.     pylab.plot(range(num_iter), J_list, "r-"
  52.     return theta 
  53.  
  54.  
  55. def mbgd(alpha, x, y, num_iter, minibatches): 
  56.     """Writtern by kissg""" 
  57.     m = x.shape[0]  # number of samples 
  58.     theta = np.ones(2) 
  59.     J_list = [] 
  60.  
  61.     for j in range(num_iter): 
  62.  
  63.         idx = np.random.permutation(y.shape[0]) 
  64.         x, y = x[idx], y[idx] 
  65.         mini = np.array_split(range(y.shape[0]), minibatches) 
  66.  
  67.         for i in mini: 
  68.             mb_hypothesis = np.dot(x[i], theta) 
  69.             mb_loss = y[i] - mb_hypothesis 
  70.             gradient = np.dot(x[i].transpose(), mb_loss) / minibatches 
  71.             theta += alpha * gradient  # update 
  72.  
  73.         hypothesis = np.dot(x, theta) 
  74.         loss = y - hypothesis 
  75.         J = np.sum(loss ** 2) / (2 * m)  # cost 
  76.         J_list.append(J) 
  77.         print("iter %s | J: %.3f" % (j, J)) 
  78.  
  79.     pylab.plot(range(num_iter), J_list, "y-"
  80.     return theta 
  81.  
  82.  
  83. if __name__ == '__main__'
  84.  
  85.     x, y = make_regression(n_samples=100, n_features=1, n_informative=1, 
  86.                            random_state=0, noise=35) 
  87.     m, n = np.shape(x) 
  88.     x = np.c_[np.ones(m), x]  # insert column, bias 
  89.     alpha = 0.01  # learning rate 
  90.  
  91.     pylab.plot(x[:, 1], y, 'o'
  92.  
  93.     print("\n#***BGD***#\n"
  94.     theta_bgd = bgd(alpha, x, y, 800) 
  95.     for i in range(x.shape[1]): 
  96.         y_bgd_predict = theta_bgd * x 
  97.     pylab.plot(x, y_bgd_predict, 'k--'
  98.  
  99.     print("\n#***SGD***#\n"
  100.     theta_sgd = sgd(alpha, x, y, 10) 
  101.     for i in range(x.shape[1]): 
  102.         y_sgd_predict = theta_sgd * x 
  103.     pylab.plot(x, y_sgd_predict, 'r--'
  104.  
  105.     print("\n#***MBGD***#\n"
  106.     theta_mbgd = mbgd(alpha, x, y, 50, 10) 
  107.     for i in range(x.shape[1]): 
  108.         y_mbgd_predict = theta_mbgd * x 
  109.     pylab.plot(x, y_mbgd_predict, 'y--'
  110.  
  111.     pylab.show() 
  112.     print("Done!" 

執(zhí)行以上代碼, 得到 3 類梯度下降算法的函數(shù)圖像如下圖所示.

 

  • 黑色是 BGD 的圖像, 是一條光滑的曲線, 因為 BGD 每一次迭代求得的都是全局最優(yōu)解;
  • 紅色是 SGD 的圖像, 可見抖動很劇烈, 有不少局部最優(yōu)解;
  • 黃色是 MBGD 的圖像, 相對 SGD 的成本-時間曲線平滑許多, 但仔細看, 仍然有抖動.
責任編輯:龐桂玉 來源: 36大數(shù)據(jù)
相關推薦

2017-03-22 12:25:29

機器學習梯度下降法

2016-11-28 09:24:08

Python內存技巧

2014-06-19 14:14:35

機器學習

2017-05-25 11:14:21

機器學習算法神經(jīng)網(wǎng)絡

2017-05-25 13:37:46

機器學習算法神經(jīng)網(wǎng)絡

2022-06-08 19:10:27

MarcusLeCun算法

2021-01-21 12:13:23

算法梯度下降網(wǎng)絡

2017-05-08 08:39:12

梯度算法Octave機器學習

2019-03-28 07:31:03

2017-04-05 08:39:20

機器學習模型梯度下降法

2018-07-20 14:58:16

深度學習梯度下降損失函數(shù)

2018-11-21 09:22:54

策略梯度算法機器學習強化學習

2024-12-25 08:00:00

機器學習ML管道人工智能

2017-10-30 14:56:04

機器學習算法非監(jiān)督學習

2021-10-26 16:10:50

神經(jīng)網(wǎng)絡AI算法

2018-11-20 15:23:30

深度學習梯度神經(jīng)網(wǎng)絡

2017-03-13 09:48:04

神經(jīng)網(wǎng)絡算法函數(shù)

2023-05-17 11:33:45

梯度下降機器學習

2022-01-21 09:05:34

機器學習工具安全

2017-08-24 10:54:29

Andrew NG深度學習操作
點贊
收藏

51CTO技術棧公眾號