提示:有謬誤請指正
摘要
本博客詳細介紹了多種常見的深度學習優化算法,包括經典的LBFGS 、Rprop 、Adagrad、RMSprop 、Adadelta 、ASGD 、Adamax、Adam、AdamW、NAdam、RAdam以及SparseAdam等,通過對這些算法的公式和參數說明進行詳細解析,博客旨在為機器學習工程師和研究人員提供清晰的理論指導,幫助讀者選擇合適的優化算法提升模型訓練效率。
父類定義Optimizer
torch.optim.Optimizer(params, defaults)
params (iterable): 一個可迭代對象,包含 :class:torch.Tensor 或 :class:dict。指定應該被優化的 Tensors。
defaults (dict): 一個字典,包含優化選項的默認值(當參數組未指定時使用)。
子類算法介紹
以下優化函數位于torch.optim包、timm.optim包內,使用句式形如:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
1、SGD (Stochastic Gradient Descent) 1951
說明:隨機梯度下降(Stochastic Gradient Descent, SGD)是最基礎的優化算法之一。它在每次迭代中隨機選擇一個或一小批樣本進行梯度計算并更新模型參數。
公式:
θ t + 1 = θ t ? η ? g t \theta_{t+1} = \theta_t - \eta \cdot g_t θt+1?=θt??η?gt?
其中:
- θ t \theta_t θt?: 在時間步 (t) 的模型參數
- θ t + 1 \theta_{t+1} θt+1?: 在時間步 (t+1) 的模型參數
- η \eta η: 學習率 (learning rate)
- g t g_t gt?: 時間步 (t) 的梯度,計算基于單個樣本的損失函數對參數的導數
函數定義:
def __init__(self, params, lr=required, momentum=0, dampening=0,weight_decay=0, nesterov=False, *, maximize=False, foreach: Optional[bool] = None):
params (iterable): 需要優化的參數,或者定義了參數組的字典。
lr (float): 學習率。
momentum (float, optional): 動量因子(默認值:0)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
dampening (float, optional): 動量的阻尼因子(默認值:0)。
nesterov (bool, optional): 是否啟用 Nesterov 動量(默認值:False)。
maximize (bool, optional): 是否基于目標函數最大化參數,而不是最小化(默認值:False)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
使用方式:
optimizer = torch.optim.SGD(params, lr=0.1, momentum=0, dampening=0, weight_decay=0, nesterov=False)
2、LBFGS (Limited-memory Broyden-Fletcher-Goldfarb-Shanno) 1980
說明:有限內存布羅伊登 - 弗萊徹 - 戈德法布 - 香農算法(Limited-memory Broyden–Fletcher–Goldfarb–Shanno, LBFGS)是一種用于求解無約束優化問題的擬牛頓法,它通過使用有限的內存來近似海森矩陣的逆,從而減少了內存需求。
公式:
θ t + 1 = θ t ? α t H t ? θ J ( θ t ) \theta_{t+1} = \theta_t - \alpha_t H_t \nabla_{\theta} J(\theta_t) θt+1?=θt??αt?Ht??θ?J(θt?)
其中:
- θ t \theta_t θt? 是當前的參數
- α t \alpha_t αt? 是步長
- H t H_t Ht?是近似的海森矩陣
- ? θ J ( θ t ) \nabla_{\theta} J(\theta_t) ?θ?J(θt?) 是當前的梯度
函數定義:
def __init__(self,params,lr=1,max_iter=20,max_eval=None,tolerance_grad=1e-7,tolerance_change=1e-9,history_size=100,line_search_fn=None):
lr (float): 學習率(默認值:1)。
max_iter (int): 每個優化步驟的最大迭代次數(默認值:20)。
max_eval (int): 每個優化步驟的最大函數評估次數(默認值:max_iter * 1.25)。
tolerance_grad (float): 關于一階最優性的終止容忍度(默認值:1e-5)。
tolerance_change (float): 關于函數值/參數變化的終止容忍度(默認值:1e-9)。
history_size (int): 更新歷史的大小(默認值:100)。
line_search_fn (str): 線搜索方法,取值為 ‘strong_wolfe’ 或 None(默認值:None)。
使用方式:
optimizer = torch.optim.LBFGS(params,lr=1,max_iter=20,max_eval=None,tolerance_grad=1e-7,tolerance_change=1e-9)
3、Rprop (Resilient Propagation) 1993
說明:彈性反向傳播算法(Resilient Backpropagation, Rprop)是一種專門為神經網絡設計的優化算法,它只考慮梯度的符號而忽略梯度的大小,從而避免了梯度大小對學習率的影響。
公式:
θ t + 1 = θ t ? η i ? sign ( ? θ J ( θ t ) ) \theta_{t+1} = \theta_t - \eta_i \cdot \text{sign}(\nabla_{\theta} J(\theta_t)) θt+1?=θt??ηi??sign(?θ?J(θt?))
其中:
- η i \eta_i ηi? 是每個參數的獨立學習率
- sign ( ? θ J ( θ t ) ) \text{sign}(\nabla_{\theta} J(\theta_t)) sign(?θ?J(θt?)) 是梯度的符號函數
函數定義:
def __init__(self, params, lr=1e-2, etas=(0.5, 1.2), step_sizes=(1e-6, 50),foreach: Optional[bool] = None):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-2)。
etas (Tuple[float, float], optional): 一對 (etaminus, etaplus),分別是乘法增長因子和減少因子(默認值:(0.5, 1.2))。
step_sizes (Tuple[float, float], optional): 最小和最大允許步長的一對值(默認值:(1e-6, 50))。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
使用方式:
optimizer = torch.optim.Rprop(params, lr=1e-2, etas=(0.5, 1.2), step_sizes=(1e-6, 50))
4、Adagrad(Adaptive Gradient Algorithm)2011
說明:自適應梯度算法(Adaptive Gradient Algorithm, Adagrad)是一種自適應學習率的優化算法,它為不同的參數分配不同的學習率,在處理稀疏數據時表現良好。
公式:
θ t + 1 = θ t ? η G t + ? ? θ J ( θ t ) \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{G_t + \epsilon}} \nabla_{\theta} J(\theta_t) θt+1?=θt??Gt?+??η??θ?J(θt?)
其中:
- G t G_t Gt? 是歷史梯度平方的累計和
- ? \epsilon ? 是避免除以零的常數
函數定義:
def __init__(self,params,lr=1e-2,lr_decay=0,weight_decay=0,initial_accumulator_value=0,eps=1e-10,foreach: Optional[bool] = None,*,maximize: bool = False):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-2)。
lr_decay (float, optional): 學習率衰減(默認值:0)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-10)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
maximize (bool, optional): 是否基于目標最大化參數,而不是最小化(默認值:False)。
使用方式:
optimizer = torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)
5、RMSprop (Root Mean Square Propagation) 2012
說明:均方根傳播算法RMSprop 是對 Adagrad 的一種改進,它通過引入衰減因子,指數移動平均的方式來調整學習率,解決了 Adagrad 在訓練后期學習率下降過快過小的問題。
公式:
θ t + 1 = θ t ? η E [ ? θ J ( θ t ) ] 2 + ? ? θ J ( θ t ) \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[\nabla_{\theta} J(\theta_t)]^2 + \epsilon}} \nabla_{\theta} J(\theta_t) θt+1?=θt??E[?θ?J(θt?)]2+??η??θ?J(θt?)
其中:
- E [ ? θ J ( θ t ) ] 2 E[\nabla_{\theta} J(\theta_t)]^2 E[?θ?J(θt?)]2 是梯度平方的移動平均
- ? \epsilon ? 是避免除以零的常數
函數定義:
def __init__(self, params, lr=1e-2, alpha=0.99, eps=1e-8, weight_decay=0, momentum=0,centered=False, foreach: Optional[bool] = None):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-2)。
momentum (float, optional): 動量因子(默認值:0)。
alpha (float, optional): 平滑常數(默認值:0.99)。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
centered (bool, optional): 如果為True,則計算中心化的RMSProp,梯度將根據其方差的估計進行歸一化。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
使用方式:
optimizer = torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
6、Adadelta 2012
說明:自適應學習率調整Adadelta 是對 Adagrad 和 RMSprop 的改進,通過使用梯度平方的指數移動平均來調整學習率,避免了 Adagrad 學習率單調遞減的問題。
公式:
θ t + 1 = θ t ? η E [ Δ θ ] t 2 + ? Δ θ t \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{E[\Delta \theta]^2_t + \epsilon}} \Delta \theta_t θt+1?=θt??E[Δθ]t2?+??η?Δθt?
其中:
- E [ Δ θ ] t 2 E[\Delta \theta]^2_t E[Δθ]t2? 是梯度的更新的平方的滑動平均
函數定義:
def __init__(self, params, lr=1.0, rho=0.9, eps=1e-6, weight_decay=0,foreach: Optional[bool] = None, *, maximize: bool = False):
params (iterable): 需要優化的參數,或者定義參數組的字典。
rho (float, optional): 用于計算平方梯度的移動平均的系數(默認值:0.9)。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-6)。
lr (float, optional): 用于縮放梯度更新的系數,在應用到參數之前(默認值:1.0)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
maximize (bool, optional): 基于目標最大化參數,而不是最小化(默認值:False)。
使用方式:
optimizer = torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-6, weight_decay=0)
7、ASGD (Averaged Stochastic Gradient Descent)2012
說明:平均隨機梯度下降(Average Stochastic Gradient Descent, ASGD)是一種對隨機梯度下降的改進算法,它通過對梯度更新的參數進行取平均,來減少參數更新的方差,提高算法的穩定性。
公式:
θ t + 1 = θ t ? η t ? θ J ( θ t ) \theta_{t+1} = \theta_t - \eta_t \nabla_{\theta} J(\theta_t) θt+1?=θt??ηt??θ?J(θt?)
同時,參數會更新為所有迭代的平均值:
θ avg = 1 t ∑ i = 1 t θ i \theta_{\text{avg}} = \frac{1}{t} \sum_{i=1}^{t} \theta_i θavg?=t1?i=1∑t?θi?
其中:
- θ t \theta_t θt?: 在時間步 (t) 的模型參數
- θ avg \theta_{\text{avg}} θavg?: 在時間步 (t) 的模型參數的平均值
- η \eta η: 學習率 (learning rate)
- ? θ J ( θ t ) \nabla_{\theta} J(\theta_t) ?θ?J(θt?): 在時間步 (t) 計算的梯度
函數定義:
def __init__(self, params, lr=1e-2, lambd=1e-4, alpha=0.75, t0=1e6, weight_decay=0,foreach: Optional[bool] = None):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-2)。
lambd (float, optional): 衰減項(默認值:1e-4)。
alpha (float, optional): 用于更新學習率的冪次(默認值:0.75)。
t0 (float, optional): 開始平均的點(默認值:1e6)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
使用方式:
optimizer = torch.optim.ASGD(params, lr=1e-2, lambd=1e-4, alpha=0.75, t0=1e6, weight_decay=0)
8、SGDP (Stochastic Gradient Descent with Momentum and Nesterov Accelerated Gradient)2015
說明:平均隨機梯度下降(Average Stochastic Gradient Descent, ASGD)是一種對隨機梯度下降的改進算法,它通過對梯度更新的參數進行取平均,來減少參數更新的方差,提高算法的穩定性。
公式:
-
計算動量:首先,計算當前的動量:
v t + 1 = μ v t + η ? θ J ( θ t ) v_{t+1} = \mu v_t + \eta \nabla_{\theta} J(\theta_t) vt+1?=μvt?+η?θ?J(θt?) -
Nesterov 加速:然后,通過提前計算在更新后的位置的梯度來進行梯度修正:
θ t + 1 = θ t ? v t + 1 \theta_{t+1} = \theta_t - v_{t+1} θt+1?=θt??vt+1?
其中
- θ t \theta_t θt? 是當前參數
- $ v_t$是動量(前一次更新的累積梯度)
- η \eta η是學習率
- μ \mu μ是動量因子
- ? θ J ( θ t ) \nabla_{\theta} J(\theta_t) ?θ?J(θt?) 是當前的梯度
函數定義:
def __init__(self, params, lr=required, momentum=0, dampening=0,weight_decay=0, nesterov=False, eps=1e-8, delta=0.1, wd_ratio=0.1):
params (iterable): 需要優化的參數,或者定義了參數組的字典。
lr (float): 學習率。
momentum (float, optional): 動量因子(默認值:0)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
dampening (float, optional): 動量的阻尼因子(默認值:0)。
nesterov (bool, optional): 是否啟用 Nesterov 動量(默認值:False)。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
delta(float, optional):調節學習率的更新或梯度的平滑度,影響參數更新時的速度(默認值:0.1)。
wd_ratio(float, optional): 控制 weight decay (權重衰減)應用到參數更新時的比例(默認值:0.1)。
使用方式:
from timm.optim.sgdp import SGDP
optimizer = SGDP(params, lr=required, momentum=0, dampening=0,weight_decay=0, nesterov=False, eps=1e-8, delta=0.1, wd_ratio=0.1)
9、Adamax 2014
說明:Adamax 是 Adam 的一個變體,使用 L∞ 范數來代替 Adam 中的二階矩估計(L2范數),在某些情況下比 Adam 更穩定。
公式:
θ t + 1 = θ t ? η m ^ t / ( v ^ t + ? ) \theta_{t+1} = \theta_t - \frac{\eta}{\hat{m}_t / (\hat{v}_t + \epsilon)} θt+1?=θt??m^t?/(v^t?+?)η?
其中:
- m ^ t \hat{m}_t m^t? 是梯度的一階矩的估計
- v ^ t \hat{v}_t v^t? 是梯度的二階矩的估計
函數定義:
def __init__(self, params, lr=2e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, foreach: Optional[bool] = None, *, maximize: bool = False):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:2e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
maximize (bool, optional): 基于目標最大化參數,而不是最小化(默認值:False)。
使用方式:
optimizer = torch.optim.Adamax(params, lr=2e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0)
10、Adam (Adaptive Moment Estimation) 2015
說明:自適應矩估計(Adaptive Moment Estimation, Adam)結合了 AdaGrad 和 RMSProp 的優點,通過計算梯度的一階矩估計(均值)和二階矩估計(方差)來為不同的參數動態調整學習率,具有較強的收斂性能
公式:
θ t + 1 = θ t ? η m ^ t v ^ t + ? \theta_{t+1} = \theta_t - \frac{\eta \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} θt+1?=θt??v^t??+?ηm^t??
其中:
- m ^ t \hat{m}_t m^t?是梯度的一階矩估計
- v ^ t \hat{v}_t v^t? 是梯度的二階矩估計
函數定義:
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, amsgrad=False, *, foreach: Optional[bool] = None,maximize: bool = False, capturable: bool = False):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.9, 0.999))。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2懲罰項)(默認值:0)。
amsgrad (boolean, optional): 是否使用AMSGrad算法變體,來源于論文《On the Convergence of Adam and Beyond》(默認值:False)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
maximize (bool, optional): 基于目標最大化參數,而不是最小化(默認值:False)。
capturable (bool, optional): 是否允許將此實例捕獲到CUDA圖中。傳入True可能會影響未圖形化的性能,因此如果不打算捕獲圖形,建議保持False(默認值:False)。
使用方式:
optimizer = torch.optim.Adam(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, amsgrad=False)
11、AdamW 2017
說明:AdamW 是 Adam 的一種變體,主要解決了 Adam 在使用正則化時存在的問題。它加入了權重衰減進行改進,來更好地處理正則化。
公式:
θ t + 1 = θ t ? η ? m ^ t v ^ t + ? ? η ? λ θ t \theta_{t+1} = \theta_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} - \eta \cdot \lambda \theta_t θt+1?=θt??η?v^t??+?m^t???η?λθt?
其中:
- λ \lambda λ是權重衰減系數
函數定義:
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=1e-2, amsgrad=False, *, maximize: bool = False,foreach: Optional[bool] = None,capturable: bool = False):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.9, 0.999))。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減系數(默認值:1e-2)。
amsgrad (boolean, optional): 是否使用AMSGrad算法變體,來源于論文《On the Convergence of Adam and Beyond》(默認值:False)。
maximize (bool, optional): 基于目標最大化參數,而不是最小化(默認值:False)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
capturable (bool, optional): 是否允許將此實例捕獲到CUDA圖中。傳入True可能會影響未圖形化的性能,因此如果不打算捕獲圖形,建議保持False(默認值:False)。
使用方式:
optimizer = torch.optim.AdamW(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=1e-2, amsgrad=False)
12、NAdam (Nesterov-accelerated Adaptive Moment Estimation) 2017
說明:NAdam 是 Adam 的一個改進版本,結合了 Nesterov 加速梯度(NAG)方法
公式:
θ t + 1 = θ t ? η ? m ^ t v ^ t + ? \theta_{t+1} = \theta_t - \frac{\eta \cdot \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} θt+1?=θt??v^t??+?η?m^t??
參數說明:
- θ t \theta_t θt?: 在時間步 (t) 的模型參數。
- η \eta η: 學習率(Learning rate),控制每次更新的步長。
- m ^ t \hat{m}_t m^t?: 第 (t) 次時間步的偏置校正后的動量估計。
Nadam 中使用了 Nesterov 加速梯度的動量估計公式:
m ^ t = β 1 ? m ^ t ? 1 + ( 1 ? β 1 ) ? ? θ J ( θ t ) \hat{m}_t = \beta_1 \cdot \hat{m}_{t-1} + (1 - \beta_1) \cdot \nabla_{\theta} J(\theta_t) m^t?=β1??m^t?1?+(1?β1?)??θ?J(θt?)
其中, β 1 \beta_1 β1? 是一階動量的衰減率(通常接近 1)。
- v ^ t \hat{v}_t v^t?: 第 (t) 次時間步的偏置校正后的平方梯度估計:
v ^ t = β 2 ? v ^ t ? 1 + ( 1 ? β 2 ) ? ( ? θ J ( θ t ) ) 2 \hat{v}_t = \beta_2 \cdot \hat{v}_{t-1} + (1 - \beta_2) \cdot (\nabla_{\theta} J(\theta_t))^2 v^t?=β2??v^t?1?+(1?β2?)?(?θ?J(θt?))2
其中 β 2 \beta_2 β2?是 二階動量的衰減率,控制歷史梯度平方的影響,通常接近 1
函數定義:
def __init__(self, params, lr=2e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, momentum_decay=4e-3, foreach: Optional[bool] = None):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:2e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.9, 0.999))。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2懲罰)(默認值:0)。
momentum_decay (float, optional): 動量衰減(默認值:4e-3)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
使用方式:
optimizer = torch.optim.NAdam(params, lr=2e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, momentum_decay=4e-3)
13、RAdam (Rectified Adam) 2018
說明:Rectified Adam(RAdam)是對 Adam 算法的改進,通過自適應學習率調整機制,解決了 Adam 在小批量訓練時的不穩定性問題。
公式:
θ t + 1 = θ t ? η ? m ^ t v ^ t + ? ? rectifier ( t ) \theta_{t+1} = \theta_t - \frac{\eta \cdot \hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} \cdot \text{rectifier}(t) θt+1?=θt??v^t??+?η?m^t???rectifier(t)
其中,rectifier(t) 是對學習率進行修正的函數。
函數定義:
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, foreach: Optional[bool] = None):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.9, 0.999))。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2懲罰)(默認值:0)。
foreach (bool, optional): 是否使用優化器的“foreach”實現(默認值:None)。
使用方式:
optimizer = torch.optim.RAdam(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0)
14、SparseAdam 2018
說明:SparseAdam 是 Adam 算法專門針對稀疏梯度進行優化的版本,通常是在 Adam 算法基礎上針對稀疏數據場景的修改和擴展。
公式:
-
計算一階矩估計(梯度的均值):
m t = β 1 m t ? 1 + ( 1 ? β 1 ) g t m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t mt?=β1?mt?1?+(1?β1?)gt? -
計算二階矩估計(梯度的平方的均值):
v t = β 2 v t ? 1 + ( 1 ? β 2 ) g t 2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 vt?=β2?vt?1?+(1?β2?)gt2? -
修正一階矩估計和二階矩估計(以抵消初始化偏差):
m ^ t = m t 1 ? β 1 t , v ^ t = v t 1 ? β 2 t \hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t} m^t?=1?β1t?mt??,v^t?=1?β2t?vt?? -
更新參數(只對非零梯度進行更新):
θ t + 1 = θ t ? η v ^ t + ? m ^ t \theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t θt+1?=θt??v^t??+?η?m^t?
其中:
- g t g_t gt? 是當前時刻的梯度。
- β 1 , β 2 \beta_1, \beta_2 β1?,β2? 是動量參數(通常設置為 0.9 和 0.999)。
- η \eta η 是學習率。
- ? \epsilon ? 是用于防止除零錯誤的小常數(通常設置為 1e-8)。
函數定義:
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8):
params (iterable): 需要優化的參數,或者定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.9, 0.999))。
eps (float, optional): 加到分母上的項,以提高數值穩定性(默認值:1e-8)。
使用方式:
optimizer = torch.optim.SparseAdam(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8)
15、Adafactor 2018
說明:Adafactor 的更新規則與 Adam 類似,但它在梯度更新時使用了低秩矩陣近似,避免了存儲整個梯度二階矩陣,從而大大減少了內存消耗。
- 梯度的平方累積:
Adafactor 使用梯度的指數衰減平均來估計梯度的方差:
v t , diag = β 1 v t ? 1 , diag + ( 1 ? β 1 ) g t 2 v_{t, \text{diag}} = \beta_1 v_{t-1, \text{diag}} + (1 - \beta_1) g_t^2 vt,diag?=β1?vt?1,diag?+(1?β1?)gt2?
v t , offdiag = β 2 v t ? 1 , offdiag + ( 1 ? β 2 ) g t g t ? 1 v_{t, \text{offdiag}} = \beta_2 v_{t-1, \text{offdiag}} + (1 - \beta_2) g_t g_{t-1} vt,offdiag?=β2?vt?1,offdiag?+(1?β2?)gt?gt?1?
其中:
- v t , diag v_{t, \text{diag}} vt,diag? 表示梯度平方的對角部分(用于每個維度的自適應學習率)。
- v t , offdiag v_{t, \text{offdiag}} vt,offdiag? 是梯度協方差的離對角部分(用于捕捉不同維度之間的相關性)。
- g t g_t gt?是當前的梯度。
- β 1 \beta_1 β1? 和 β 2 \beta_2 β2? 是衰減系數。
-
更新規則:
Adafactor 對參數更新采用以下公式:θ t + 1 = θ t ? η ? g t v t , diag + ? \theta_{t+1} = \theta_t - \eta \cdot \frac{g_t}{\sqrt{v_{t, \text{diag}}} + \epsilon} θt+1?=θt??η?vt,diag??+?gt??
其中:
- θ t \theta_t θt? 是當前的參數值。
- η \eta η 是學習率。
- v t , diag v_{t, \text{diag}} vt,diag? 是在每個維度上的累積平方梯度。
- ? \epsilon ? 是一個小常數,用于避免除零錯誤。
函數定義:
def __init__(self, params, lr=None, eps=1e-30, eps_scale=1e-3, clip_threshold=1.0,decay_rate=-0.8, betas=None, weight_decay=0.0, scale_parameter=True, warmup_init=False):
params (iterable): 要優化的參數迭代器,或者定義參數組的字典。
lr (float, optional): 外部學習率(默認值:None)。
eps (tuple[float, float]): 用于正則化常數的平方梯度和參數規模的常數(默認值:(1e-30, 1e-3))。
clip_threshold (float): 最終梯度更新的均方根閾值(默認值:1.0)。
decay_rate (float): 用于計算平方梯度的運行平均值的系數(默認值:-0.8)。
beta1 (float): 用于計算梯度運行平均值的系數(默認值:None)。
weight_decay (float, optional): 權重衰減(L2懲罰)(默認值:0)。
scale_parameter (bool): 如果為True,學習率將按參數的均方根進行縮放(默認值:True)。
warmup_init (bool): 是否使用預熱初始化來進行時間依賴的學習率計算,具體取決于是否使用了預熱初始化(默認值:False)。
使用方式:
from timm.optim.adafactor import Adafactor
optimizer = Adafactor(params, lr=None, eps=1e-30, eps_scale=1e-3, clip_threshold=1.0,decay_rate=-0.8, betas=None, weight_decay=0.0)
16、NovoGrad 2019
說明:由 NVIDIA 團隊提出,通過結合自適應梯度的方法與基于二階矩陣的優化技巧,克服了傳統的梯度下降法和一些常見優化算法在訓練過程中可能遇到的挑戰,如稀疏性和梯度消失問題。
公式:
θ t + 1 = θ t ? η g t v t + ? \theta_{t+1} = \theta_t - \eta \frac{g_t}{\sqrt{v_t} + \epsilon} θt+1?=θt??ηvt??+?gt??
其中:
- θ t \theta_t θt?:參數向量(當前迭代時的權重)
- η \eta η:學習率
- g t g_t gt?:梯度向量
- v t v_t vt?:梯度的動量(歷史信息)
- ? \epsilon ?:避免除以零的小常數
函數定義:
def __init__(self,params,lr=1e-3,betas=(0.95, 0.98),eps=1e-8,weight_decay=0,grad_averaging=False,amsgrad=False):
params (iterable): 要優化的參數的可迭代對象,或定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.95, 0.98))。
eps (float, optional): 加入分母的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2懲罰)(默認值:0)。
grad_averaging: 梯度平均。
amsgrad (boolean, optional): 是否使用AMSGrad變體,這個變體來自論文《On the Convergence of Adam and Beyond》中的算法(默認值:False)
使用方式:新版timm已舍棄該算法
from timm.optim.novograd import NovoGrad
optimizer = NovoGrad(params,lr=1e-3,betas=(0.95, 0.98),eps=1e-8,weight_decay=0)
17、NvNovoGrad 2020
說明:NvNovoGrad 采用了與 Adam 類似的思路,使用了梯度的 一階矩估計(即動量項)和 二階矩估計(即梯度的平方的指數衰減平均)。
公式:
-
一階矩估計(動量項):
m t = β 1 m t ? 1 + ( 1 ? β 1 ) g t m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t mt?=β1?mt?1?+(1?β1?)gt? -
二階矩估計(梯度平方的移動平均):
v t = β 2 v t ? 1 + ( 1 ? β 2 ) g t 2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 vt?=β2?vt?1?+(1?β2?)gt2? -
更新參數:
θ t = θ t ? 1 ? η m t v t + ? \theta_t = \theta_{t-1} - \frac{\eta m_t}{\sqrt{v_t} + \epsilon} θt?=θt?1??vt??+?ηmt??
其中
- θ t \theta_t θt? 是當前參數,
- g t g_t gt? 是當前的梯度,
- m t m_t mt? 是一階矩(梯度的動量估計),
- v t v_t vt? 是二階矩(梯度平方的動量估計),
- η \eta η 是學習率,
- β 1 \beta_1 β1? 和 β 2 \beta_2 β2?分別是一階和二階矩的衰減率,
- ? \epsilon ? 是一個小常數(用于避免除零)
函數定義:
def __init__(self, params, lr=1e-3, betas=(0.95, 0.98), eps=1e-8,weight_decay=0, grad_averaging=False, amsgrad=False):
params (iterable): 要優化的參數的可迭代對象,或定義參數組的字典。
lr (float, optional): 學習率(默認值:1e-3)。
betas (Tuple[float, float], optional): 用于計算梯度及其平方的運行平均值的系數(默認值:(0.95, 0.98))。
eps (float, optional): 加入分母的項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2懲罰)(默認值:0)。
grad_averaging: 梯度平均。
amsgrad (boolean, optional): 是否使用AMSGrad變體,這個變體來自論文《On the Convergence of Adam and Beyond》中的算法(默認值:False)。
使用方式:
from timm.optim.nvnovograd import NvNovoGrad
optimizer = NvNovoGrad(params, lr=1e-3, betas=(0.95, 0.98), eps=1e-8,weight_decay=0, grad_averaging=False, amsgrad=False)
18、AdamP 2020
說明:AdamP 與 Adam 的最大區別在于它對 權重衰減(weight decay) 的處理方式。標準的 Adam 優化算法中,權重衰減是作為一種正則化方式直接加到梯度上,而 AdamP 采用了更合適的方式,在梯度更新前對每個參數的梯度做了 正則化 處理,能夠更有效地將權重衰減融入到優化過程中。
公式:
- 動量更新:
與 Adam 一樣,AdamP 使用一階矩和二階矩的更新:
m t = β 1 m t ? 1 + ( 1 ? β 1 ) g t m_t = \beta_1 m_{t-1} + (1 - \beta_1) g_t mt?=β1?mt?1?+(1?β1?)gt?
v t = β 2 v t ? 1 + ( 1 ? β 2 ) g t 2 v_t = \beta_2 v_{t-1} + (1 - \beta_2) g_t^2 vt?=β2?vt?1?+(1?β2?)gt2?
其中:
- m t m_t mt? 是梯度的動量(與梯度的加權平均相關)。
- v t v_t vt? 是梯度的平方的加權平均(即梯度的方差估計)。
- g t g_t gt? 是當前梯度。
- β 1 \beta_1 β1? 和 β 2 \beta_2 β2? 是衰減率超參數。
- 梯度校正:
與 Adam 類似,為了消除動量的偏差,AdamP 會對 m t m_t mt?和 v t v_t vt?進行偏差校正:
m ^ t = m t 1 ? β 1 t \hat{m}_t = \frac{m_t}{1 - \beta_1^t} m^t?=1?β1t?mt??
v ^ t = v t 1 ? β 2 t \hat{v}_t = \frac{v_t}{1 - \beta_2^t} v^t?=1?β2t?vt??
- 權重衰減的處理:
AdamP 的關鍵區別在于它采用了一種不同的方式來處理權重衰減。具體來說,在每次更新時,AdamP 會通過以下方式將權重衰減與梯度結合:
θ t + 1 = θ t ? η ? m ^ t v ^ t + ? ? η ? λ ? θ t \theta_{t+1} = \theta_t - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} - \eta \cdot \lambda \cdot \theta_t θt+1?=θt??η?v^t??+?m^t???η?λ?θt?
其中:
- θ t \theta_t θt? 是當前的參數。
- η \eta η是學習率。
- λ \lambda λ 是權重衰減因子(通常為一個很小的值,如 (10^{-4}) 或 (10^{-5}))。
- ? \epsilon ? 是一個小常數,防止除零錯誤。
函數定義:
def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, delta=0.1, wd_ratio=0.1, nesterov=False):
使用方式:
from timm.optim.adamp import AdamP
optimizer = AdamP(params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8,weight_decay=0, delta=0.1, wd_ratio=0.1)
19、Adahessian 2021
說明:AdaHessian 引入了 Hessian 矩陣(即二階導數矩陣)的近似,它包含了損失函數的二階信息,能夠更精確地調整學習率和梯度更新方向。AdaHessian 結合了梯度的一階矩、二階矩和 Hessian 矩陣的信息。
公式:
-
梯度計算:
g t = ? θ L ( θ t ) g_t = \nabla_\theta L(\theta_t) gt?=?θ?L(θt?)
其中, g t g_t gt?是損失函數 L ( θ ) L(\theta) L(θ)關于模型參數 θ t \theta_t θt?的梯度。 -
Hessian 矩陣的近似:
AdaHessian 通過一種高效的方式來近似 Hessian 矩陣,避免了直接計算二階導數帶來的高計算成本。通常,AdaHessian 使用二階矩的估計來近似 Hessian。具體的近似方法可以通過使用 Kronecker-factored Approximate Curvature (K-FAC) 技術或其他矩陣分解方法來實現。 -
更新規則:
AdaHessian 使用自適應的學習率來更新參數。其更新公式如下:
θ t + 1 = θ t ? η t v t + ? ? H ^ t ? 1 g t \theta_{t+1} = \theta_t - \frac{\eta_t}{\sqrt{v_t + \epsilon}} \cdot \hat{H}_t^{-1} g_t θt+1?=θt??vt?+??ηt???H^t?1?gt?
其中:- η t \eta_t ηt? 是學習率。
- v t v_t vt? 是梯度的一階矩估計(類似于 Adam 中的一階動量)。
- H ^ t \hat{H}_t H^t? 是對 Hessian 矩陣的近似。
- ? \epsilon ?是一個小常數,防止除零錯誤。
- H ^ t ? 1 \hat{H}_t^{-1} H^t?1?是 Hessian 矩陣的逆近似。
函數定義:
def __init__(self, params, lr=0.1, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.0,hessian_power=1.0, update_each=1, n_samples=1, avg_conv_kernel=False):
params (iterable): 可迭代的參數,定義了要優化的參數或包含參數組的字典。
lr (float, optional): 學習率(默認值:0.1)。
betas ((float, float), optional): 用于計算梯度和平方海森矩陣跡的運行平均的系數(默認值:(0.9, 0.999))。
eps (float, optional): 加入分母中的小項,以提高數值穩定性(默認值:1e-8)。
weight_decay (float, optional): 權重衰減(L2 正則化)參數(默認值:0.0)。
hessian_power (float, optional): 海森矩陣跡的指數(默認值:1.0)。
update_each (int, optional): 每經過 該 步數后才計算海森矩陣跡的近似值(用于節省時間)(默認值:1)。
n_samples (int, optional): 采樣 z 的次數,用于近似海森矩陣跡(默認值:1)。
使用方式:
from timm.optim.adahessian import Adahessian
optimizer = Adahessian(params, lr=0.1, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.0,hessian_power=1.0, update_each=1, n_samples=1)