2024年10月14日 星期一

[文章轉貼] 十大優化演算法,最全總結! !

 文章轉自微信公眾號:機器學習與人工智慧AI 

文章原始連結:https://mp.weixin.qq.com/s/FTJ8b8O4LtEhzmyE-ZfnCA


今兒帶給大家的是十大優化演算法的核心公式,為大家做了一個總結。

如果剛接觸或學習過,可以作為學習或複習的材料~

牽涉到的有:

  • 梯度下降演算法
  • 隨機梯度下降演算法
  • 動量
  • AdaGrad
  • RMSProp
  • Adam
  • 牛頓法
  • 共軛梯度法
  • L-BFGS
  • 自然梯度下降法

所有內容涉及到,微積分、線性代數、機率論等。一起來看下~

1. 梯度下降演算法(Gradient Descent)

介紹:

梯度下降是一種迭代最佳化演算法,用於透過最小化目標函數(通常是損失函數)來調整模型參數。演算法的基本概念是,從初始參數開始,沿著目標函數的負梯度方向逐步移動參數,以減少目標函數的值,直到達到某個收斂條件。

原理:

假設我們有一個參數向量,目標是最小化某個可微函數。梯度下降的每次迭代通過調整參數使得目標函數減少。  

核心點:

  • 梯度: 目標函數關於參數的梯度表示函數在的方向導數,指向函數值成長最快的方向。負梯度方向則是函數值減小最快的方向。        
  • 學習率: 學習率控制每次迭代的步長。如果過大,可能會越過最優解;如果過小,收斂速度會很慢。      

核心公式:

  1. 目標函數:

假設是一個凸函數,且是可微的。  

  1. 梯度定義:

這裡,表示目標函數關於第個參數的偏導數。   

  1. 參數更新:

其中,是學習率,是第次迭代的參數。    

推導過程:

  • 從Taylor展開式出發,可以看出梯度指向目標函數上升最快的方向,因此沿著負梯度方向能夠有效降低目標函數值。
  • 對於凸函數,梯度下降可以保證收斂到全域最優點。

2. 隨機梯度下降演算法(Stochastic Gradient Descent, SGD)

介紹:

SGD是一種梯度下降的改良版。在標準的梯度下降中,梯度計算通常是基於所有樣本的。然而,對於大數據集,這種計算可能非常耗時。 SGD透過在每次迭代時僅使用一個樣本(或一個小批量樣本)來計算梯度,大大減少了計算的複雜度。

原理:

在每次迭代中,SGD從訓練集中隨機選擇一個樣本,計算該樣本的梯度,並更新參數。

核心點:

  • 隨機性: 由於梯度是基於單一樣本計算的,更新方向每次都會有所不同,因此參數更新路徑是隨機的。儘管這種隨機性可能導致震盪,但它也可以幫助模型跳出局部最佳解。
  • 更快的收斂: 在初期階段,SGD通常比標準梯度下​​降更快收斂,但在接近最佳解時可能會表現出更多的震盪。

核心公式:

  1. 目標函數:

其中是第個訓練樣本。    

  1. 隨機選擇樣本並計算其梯度:  

這表示損失函數在目前參數和样本處的梯度。    

  1. 參數更新:

推導過程:

  • 由於SGD在每次迭代中使用的樣本是隨機的,目標函數值會圍繞真實的最小值附近波動,因此需要合適的學習率或學習率衰減策略來平衡這種波動。

3. 動量(Momentum)

介紹:

動量是一種加速梯度下降的方法。它透過引入過去梯度的「動量」來減少梯度下降的震盪行為,從而加速收斂,特別是在深度學習中的高維度最佳化問題上。

原理:

動量演算法透過在每一步迭代時,結合先前迭代的梯度訊息,使得更新方向更具穩定性和慣性,從而能夠快速穿越狹長的谷底(長平面)。

核心點:

  • 慣性項: 類似於物理中的動量概念,更新的方向不僅依賴當前梯度,還依賴先前的更新方向。
  • 加速收斂: 動量能夠在梯度下降路徑較陡峭的方向上加速,同時在曲線平緩的方向上減緩震盪。

核心公式:

  1. 定義動量向量 

其中,是動量係數,通常取值為    

  1. 更新參數:

推導過程:

  • 動量項是先前所有梯度的指數加權平均,因此動量演算法能夠有效減少隨機梯度下降中的抖動行為,加速收斂。  
  • 透過引入動量,更新方向不再完全依賴當前梯度,而是考慮了過去的梯度訊息,使得更新方向更加穩定和高效。

4. AdaGrad

介紹:

AdaGrad(Adaptive Gradient Algorithm)是一種自適應學習率的最佳化演算法。它根據參數的歷史梯度資訊來調整每個參數的學習率,使得學習率在頻繁更新的參數上減小,而在更新較少的參數上保持較大。

原理:

AdaGrad 的核心思想是對不同參數自適應地調整學習率,使得每個參數都有自己的學習率,而這個學習率會隨著時間的推移而減少。

核心點:

  • 自適應學習率: 每個參數的學習率會根據其過去的梯度更新情況調整。
  • 累積梯度平方和: 學習率調整的依據是累積的梯度平方和。

核心公式:

  1. 累積梯度平方和:

其中,表示元素逐元素相乘。 

  1. 更新參數:

其中,是一個小的平滑項,防止除零。 

推導過程:

  • 隨著迭代次數增加,累積的梯度平方和也會增加,因此學習率會逐漸減少。  
  • AdaGrad 適合處理稀疏資料或在梯度變化較大的情況下表現出色。

5. RMSProp

介紹:

RMSProp 是AdaGrad 的改進版本,解決了AdaGrad 中學習率不斷減少的問題。 RMSProp 透過對歷史梯度平方的指數加權移動平均,控制累積梯度平方和的成長速度,使學習率趨於穩定。

原理:

RMSProp 透過對梯度平方進行指數加權平均,使得學習率既能適應參數的不同變化速率,也避免了AdaGrad 中學習率持續減少的問題

核心點:

  • 指數加權平均值:  RMSProp 引入了指數加權平均值對累積梯度平方和進行平滑。
  • 穩定學習率:  RMSProp 讓學習率在訓練過程中保持穩定,適應參數的變化。

核心公式:

  1. 累積梯度平方和的指數加權平均值:

其中,是指數加權平均的衰減因子,通常取值為  

  1. 更新參數:

推導過程:

  • 透過使用指數加權平均,RMSProp 保留了最近梯度的歷史信息,同時避免了累積梯度平方和無限增長的問題,使得學習率更加穩定和適應性強。

6. Adam

介紹:

Adam(Adaptive Moment Estimation)是一種結合了動量和RMSProp兩者優勢的一種自適應學習率優化演算法。 Adam 透過計算梯度的一階動量和二階動量來動態調整每個參數的學習率。

原理:

Adam 同時對梯度的一階矩(動量)和二階矩(梯度的平方)進行估計,並使用偏差修正來提高估計的準確性,從而在參數更新時能夠更精確地適應不同的梯度資訊。

核心點:

  • 一階動量(平均): 對梯度進行動量計算,類似Momentum。
  • 二階動量(變異數): 對梯度平方進行計算,類似RMSProp。
  • 偏差修正:  Adam 對動量和變異數估計進行了偏差修正,以便在初始階段提供更準確的估計。

核心公式:

  1. 一階動量估計:

其中,通常取值為  

  1. 二階動量估計:

其中,通常取值為  

  1. 偏差修正:
  1. 更新參數:

推導過程:

  • Adam 結合了動量和RMSProp 的優勢,使得最佳化過程既具有動量的加速作用,也有自適應學習率的穩定性。
  • 透過對一階和二階動量進行偏差修正,Adam 能夠在訓練初期提供更可靠的學習率估計,提升了收斂的穩定性和效率。

7. 牛頓法(Newton's Method)

介紹:

牛頓法是一種基於二階導數(Hessian矩陣)來尋找函數極值的最佳化演算法。與梯度下降不同,牛頓法不僅考慮了目標函數的梯度,還考慮了目標函數的曲率信息,以更快地收斂到極值點。

原理:

牛頓法透過在每次迭代中利用Hessian矩陣調整步長,使得參數更新更接近目標函數的極值點。這個演算法的核心是利用泰勒展開來逼近目標函數,並根據二階導數資訊調整步長。

核心點:

  • Hessian矩陣: 描述目標函數的二階導數訊息,反映了函數的曲率。
  • 精確步長調整: 透過Hessian矩陣對梯度進行縮放,可以得到更精確的步長,進而加速收斂。

核心公式:

  1. 泰勒展開(保留二階項):

其中,是Hessian 矩陣,即目標函數的二階導數。 

  1. 參數更新(設梯度為0求解):

解得:

因此,參數更新為:

推導過程:

  • 牛頓法利用Hessian矩陣的逆矩陣來調整步長,使得每次更新可以更精確地逼近目標函數的極值。
  • 在Hessian矩陣可逆且計算開銷允許的情況下,牛頓法可以大幅加快收斂速度。然而,對於高維問題,Hessian矩陣的計算和求逆開銷較大,因此不常直接使用。

8. 共軛梯度法(Conjugate Gradient Method)

介紹:

共軛梯度法是一種適用於大型線性系統和無約束最佳化問題的迭代方法。它是一種不需要儲存完整Hessian矩陣的二階最佳化演算法,非常適合解決大規模問題。

原理:

共軛梯度法結合了梯度下降和二階方法的優點,透過在共軛方向上進行最佳化,逐步逼近目標函數的最優解。

核心點:

  • 共軛方向: 在每次迭代中,搜尋的方向是共軛的,確保每次更新都盡可能靠近最佳解。
  • 避免計算Hessian矩陣: 透過共軛方向的性質,避免了直接計算Hessian矩陣,適用於大規模最佳化問題。

核心公式:

  1. 初始方向選擇:
  1. 參數更新:

其中,是步長,可以透過線搜尋確定。 

  1. 梯度更新:
  1. 共軛方向更新:

其中,可以透過以下公式計算: 

推導過程:

  • 透過在共軛方向上進行最佳化,共軛梯度法可以有效地逼近最優解,而不需要儲存和計算完整的Hessian矩陣。
  • 共軛梯度法特別適用於大規模最佳化問題,如大型稀疏矩陣的求解。

9. L-BFGS(Limited-memory Broyden-Fletcher-Goldfarb-Shanno)

介紹:

L-BFGS 是BFGS 演算法的變體,是一種適用於大規模問題的最佳化演算法。它透過限制記憶體使用量,只保存和更新一部分歷史訊息,從而在較少記憶體開銷下逼近二階資訊。

原理:

L-BFGS 透過利用最近的梯度和參數更新資訊來建立目標函數的局部二階近似,從而在每次迭代時有效地更新參數。

核心點:

  • 有限記憶體: 僅保存最近的梯度和參數更新歷史,以減少記憶體使用。
  • 近似二階資訊: 透過更新資訊的有限記憶來建構Hessian 矩陣的近似,使得最佳化過程更有效率。

核心公式:

  1. 初始Hessian 矩陣近似(單位矩陣)。 
  2. 保存最近的個梯度差和參數差     
  1. 更新步驟:

反向計算:

正向計算:

最終更新:

推導過程:

  • L-BFGS 的核心在於透過有限的記憶近似Hessian 矩陣,從而在每次迭代中獲得比一階方法更有效的更新方向。
  • L-BFGS 廣泛應用於大規模機器學習問題和非線性最佳化問題。

10. 自然梯度下降法(Natural Gradient Descent)

介紹:

自然梯度下降法是一種改進的梯度下降方法,它在計算更新方向時考慮了參數空間的幾何性質,使得在參數更新時更自然,能夠提高最佳化效率。

原理:

自然梯度下降透過Fisher 資訊矩陣對梯度進行縮放,使得更新步長在參數空間中更加自然,避免了傳統梯度下降中可能的「曲率失真」。

核心點:

  • Fisher 資訊矩陣: 表示參數空間的幾何結構,用於對梯度進行縮放。
  • 自然步長: 考慮參數空間的結構,更新步長更適應最佳化目標的曲率。

核心公式:

  1. Fisher 資訊矩陣:

其中,是模型的機率分佈函數。 

  1. 自然梯度:
  1. 參數更新:

推導過程:

  • 自然梯度下降法透過考慮參數空間的幾何結構,使得梯度更新更符合目標函數的自然曲率,從而提高最佳化的收斂效率。
  • 這種方法特別適用於機率模型的最佳化,如變分推斷和資訊幾何。

代表案例

咱們在這裡使用隨機梯度下降(SGD)演算法進行機器學習建模。我們使用Iris資料集,該資料集用於分類任務。    

1. 資料集概述

資料集:  Iris 資料集

任務: 使用邏輯迴歸模型進行分類,最佳化演算法選擇隨機梯度下降(SGD)。

2. 資料預處理

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import numpy as np

# 加载数据
iris = load_iris()
X = iris.data
y = iris.target

# 仅选择前两类数据和前两个特征进行可视化
X = X[y != 2]
y = y[y != 2]

# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 标准化特征
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

3. 實現隨機梯度下降邏輯迴歸

from sklearn.linear_model import SGDClassifier
from sklearn.metrics import accuracy_score, log_loss
import matplotlib.pyplot as plt

# 初始化随机梯度下降逻辑回归模型
model = SGDClassifier(loss='log', max_iter=1, warm_start=True, random_state=42)

# 训练和记录损失
train_losses = []
for epoch in range(100):  # 训练100轮
    model.fit(X_train, y_train)
    y_train_pred = model.predict_proba(X_train)
    loss = log_loss(y_train, y_train_pred)
    train_losses.append(loss)

# 测试模型
y_test_pred = model.predict_proba(X_test)
test_loss = log_loss(y_test, y_test_pred)
accuracy = accuracy_score(y_test, model.predict(X_test))

print(f'Test Accuracy: {accuracy:.4f}')
print(f'Test Log Loss: {test_loss:.4f}')

4. 繪製損失變化曲線

plt.figure(figsize=(125))
plt.plot(range(1101), train_losses, label='Training Loss')
plt.title('Loss During Training with SGD')
plt.xlabel('Epochs')
plt.ylabel('Log Loss')
plt.legend()
plt.show()




5. 繪製決策邊界

為了視覺化決策邊界,我們將繪製訓練集上的決策邊界。由於Iris 資料集的維度較高,這裡我們只選擇兩個特徵來展示。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# 准备网格数据
x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 1
y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
                     np.arange(y_min, y_max, 0.01))

# 绘制决策边界
Z = model.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.figure(figsize=(106))
plt.contourf(xx, yy, Z, alpha=0.8, cmap=ListedColormap(['#FFAAAA''#AAAAFF']))
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, edgecolor='k', marker='o', cmap=ListedColormap(['#FF0000''#0000FF']))
plt.title('Decision Boundary with SGD')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()





  1. 資料預處理:載入Iris 資料集並進行標準化處理。選擇前兩類資料(簡化為二分類問題),以便進行視覺化。

  2. 隨機梯度下降模型:使用來實現隨機梯度下降的邏輯迴歸。訓練模型,並記錄每回合的損失。 SGDClassifier 

  3. 損失變化曲線:繪製訓練過程中損失的變化曲線,以顯示隨機梯度下降演算法的動態行為。

  4. 決策邊界:繪製決策邊界來展示模型如何將特徵空間劃分為不同類別區域。

沒有留言:

張貼留言