鍵.png)
使用這些基本 REST API 最佳實踐構(gòu)建出色的 API
考慮一座在 (x1, x2) 點高度是 f(x1, x2) 的山。那么,某一點的梯度方向是在該點坡度最陡的方向,而梯度的大小告訴我們坡度到底有多陡。注意,梯度也可以告訴我們不在最快變化方向的其他方向的變化速度(二維情況下,按照梯度方向傾斜的圓在平面上投影成一個橢圓)。對于一個含有 n 個變量的標量函數(shù),即函數(shù)輸入一個 n 維 的向量,輸出一個數(shù)值,梯度可以定義為:
Hesse 矩陣常被應(yīng)用于牛頓法解決的大規(guī)模優(yōu)化問題(后面會介紹),主要形式如下:
當 f(x) 為二次函數(shù)時,梯度以及 Hesse 矩陣很容易求得。二次函數(shù)可以寫成下列形式:
其中 A 是 n 階對稱矩陣,b 是 n 維列向量, c 是常數(shù)。f(x) 梯度是 Ax+b, Hesse 矩陣等于 A。
Jacobi 矩陣實際上是向量值函數(shù)的梯度矩陣,假設(shè)F:Rn→Rm 是一個從n維歐氏空間轉(zhuǎn)換到m維歐氏空間的函數(shù)。這個函數(shù)由m個實函數(shù)組成:?
。這些函數(shù)的偏導(dǎo)數(shù)(如果存在)可以組成一個m行n列的矩陣(m by n),這就是所謂的雅可比矩陣:
梯度下降法是最常用的一種優(yōu)化算法,通過迭代地沿著梯度的負方向來尋找最優(yōu)解。
在機器學(xué)習(xí)中,梯度下降法通常用于求解損失函數(shù)的最小值,通過不斷更新模型的參數(shù)來逐漸減小損失函數(shù)的值。
梯度下降法的優(yōu)點是簡單、穩(wěn)定且容易實現(xiàn),適用于大規(guī)模數(shù)據(jù)集和復(fù)雜的模型。
梯度下降是一個大類,常見的梯度下降類算法如下圖:
隨機梯度下降是在梯度下降算法效率上做了優(yōu)化,不使用全量樣本計算當前的梯度,而是使用小批量(mini-batch)樣本來估計梯度,大大提高了效率。
原因在于使用更多樣本來估計梯度的方法的收益是低于線性的,對于大多數(shù)優(yōu)化算法基于梯度下降,如果每一步中計算梯度的時間大大縮短,則它們會更快收斂。且訓(xùn)練集通常存在冗余,大量樣本都對梯度做出了非常相似的貢獻。此時基于小批量樣本估計梯度的策略也能夠計算正確的梯度,但是節(jié)省了大量時間。
SGD具有快速收斂的特點,適用于處理大規(guī)模數(shù)據(jù)集和分布式計算環(huán)境。
SGD的缺點是容易陷入局部最優(yōu)解,可結(jié)合其他優(yōu)化算法如動量法或Adam等來提高收斂效果。
import numpy as np
# 定義損失函數(shù)
def loss_function(w, X, y):
return np.sum(np.square(X.dot(w) - y)) / len(y)
# 定義梯度函數(shù)
def gradient(w, X, y):
return X.T.dot((X.dot(w) - y)) / len(y)
# 定義SGD優(yōu)化器
def sgd(X, y, learning_rate=0.01, epochs=100):
n_features = X.shape[1]
w = np.zeros(n_features)
for epoch in range(epochs):
for i in range(len(X)):
grad = gradient(w, X[i], y[i])
w -= learning_rate * grad
print("Epoch %d loss: %f" % (epoch+1, loss_function(w, X, y)))
return w
動量法通過引入一個動量項來加速梯度下降法的收斂速度。
Nesterov 動量法是對動量法的改進,在每一步迭代中考慮了未來的信息,從而更好地指導(dǎo)參數(shù)的更新方向。
動量法和Nesterov 動量法適用于非凸優(yōu)化問題,能夠跳出局部最優(yōu)解并加速收斂。
Adam是最常用的優(yōu)化算法之一,是一種自適應(yīng)學(xué)習(xí)率的優(yōu)化算法,結(jié)合了動量法和RMSprop的思想。
Adam能夠自動調(diào)整學(xué)習(xí)率,并且在不同的數(shù)據(jù)分布和模型結(jié)構(gòu)下具有良好的收斂效果。(雖然說已經(jīng)簡化了調(diào)參,但是并沒有一勞永逸地解決問題,默認的參數(shù)雖然好,但也不是放之四海而皆準。因此,在充分理解數(shù)據(jù)的基礎(chǔ)上,依然需要根據(jù)數(shù)據(jù)特性、算法特性進行充分的調(diào)參實驗。)
Adam適用于處理高維特征和稀疏數(shù)據(jù)集,非常適用于深度學(xué)習(xí)模型中的參數(shù)優(yōu)化。在使用大型模型和數(shù)據(jù)集的情況下,Adam 優(yōu)化算法在解決局部深度學(xué)習(xí)問題上是很高效的。
import torch
import torch.optim as optim
import numpy as np
# 定義損失函數(shù)和梯度函數(shù)(這里使用PyTorch的自動梯度計算)
loss_function = torch.nn.MSELoss() # 均方誤差損失函數(shù)
gradient = torch.autograd.grad # 自動梯度計算函數(shù)
# 定義Adam優(yōu)化器(這里使用了PyTorch的Adam類)
optimizer = optim.Adam([torch.Tensor([0.])], lr=0.01) # 學(xué)習(xí)率設(shè)置為0.01,初始權(quán)重為0向量(注意:PyTorch中優(yōu)化器的權(quán)重參數(shù)需要是tensor對象)
optimizer.zero_grad() # 清除歷史梯度信息(如果使用其他優(yōu)化器,可能需要手動清除梯度)
output = loss_function(torch.Tensor([1]), torch.Tensor([[1, 2], [3, 4]]), torch.Tensor([[2], [4]])) # 計算損失函數(shù)值(這里使用了PyTorch的Tensor類,模擬了線性回歸問題的數(shù)據(jù)和目標)
output.backward() # 反向傳播計算梯度(這里使用了PyTorch的backward方法)
optimizer.step() # 更新權(quán)重(這里使用了PyTorch的step方法)
AdaGrad是一種自適應(yīng)學(xué)習(xí)率的優(yōu)化算法,能夠根據(jù)參數(shù)的歷史梯度來動態(tài)調(diào)整學(xué)習(xí)率。
RMSprop則是對AdaGrad的改進,通過引入一個指數(shù)衰減的平均來平滑歷史梯度的方差。
AdaGrad和RMSprop適用于處理稀疏數(shù)據(jù)集和具有非平穩(wěn)目標函數(shù)的優(yōu)化問題。
牛頓法是一種基于目標函數(shù)的二階導(dǎo)數(shù)信息的優(yōu)化算法,通過構(gòu)建二階導(dǎo)數(shù)矩陣并對其進行求解來逼近最優(yōu)解。
擬牛頓法是牛頓法的改進,通過構(gòu)造一個對稱正定的矩陣來逼近目標函數(shù)的二階導(dǎo)數(shù)矩陣的逆矩陣,從而避免了直接計算二階導(dǎo)數(shù)矩陣的逆矩陣。
牛頓法和擬牛頓法適用于二階可導(dǎo)的目標函數(shù),具有較快的收斂速度,但在計算二階導(dǎo)數(shù)矩陣時需要較大的存儲空間。
import numpy as np
from scipy.linalg import inv
# 定義損失函數(shù)和Hessian矩陣
def loss_function(w, X, y):
return np.sum(np.square(X.dot(w) - y)) / len(y)
def hessian(w, X, y):
return X.T.dot(X) / len(y)
# 定義牛頓法優(yōu)化器
def newton(X, y, learning_rate=0.01, epochs=100):
n_features = X.shape[1]
w = np.zeros(n_features)
for epoch in range(epochs):
H = hessian(w, X, y)
w -= inv(H).dot(gradient(w, X, y))
print("Epoch %d loss: %f" % (epoch+1, loss_function(w, X, y)))
return w
共軛梯度法是介于梯度下降法和牛頓法之間的一種方法,利用共軛方向進行搜索。
共軛梯度法的優(yōu)點是在每一步迭代中不需要計算完整的梯度向量,而是通過迭代的方式逐步逼近最優(yōu)解。
該方法適用于大規(guī)模問題,尤其是稀疏矩陣和對稱正定的問題。
一種有限內(nèi)存的Broyden-Fletcher-Goldfarb-Shanno(BFGS)算法,主要用于解決大規(guī)模優(yōu)化問題。由于它只需要有限數(shù)量的計算機內(nèi)存,因此特別適合處理大規(guī)模問題。LBFGS算法的目標是最小化一個給定的函數(shù),通常用于機器學(xué)習(xí)中的參數(shù)估計。
import numpy as np
from scipy.optimize import minimize
# 目標函數(shù)
def objective_function(x):
return x**2 - 4*x + 4
# L-BFGS算法求解最小值
result = minimize(objective_function, x0=1, method='L-BFGS-B')
x_min = result.x
print(f"L-BFGS的最小值為:{objective_function(x_min)}")
一種隨機搜索算法,其靈感來源于物理退火過程。該算法通過接受或拒絕解的移動來模擬退火過程,以避免陷入局部最優(yōu)解并尋找全局最優(yōu)解。在模擬退火算法中,接受概率通常基于解的移動的優(yōu)劣和溫度的降低,允許在搜索過程中暫時接受較差的解,這有助于跳出局部最優(yōu),從而有可能找到全局最優(yōu)解。
import numpy as np
from scipy.optimize import anneal
# 目標函數(shù)
def objective_function(x):
return (x - 2)**2
# SA算法求解最小值
result = anneal(objective_function, x0=0, lower=-10, upper=10, maxiter=1000)
x_min = result.x
print(f"SA的最小值為:{objective_function(x_min)}")
一種基于自適應(yīng)聚類的模擬退火算法。通過模擬物理退火過程,利用聚類技術(shù)來組織解空間并控制解的移動。該方法適用于處理大規(guī)模、高維度的優(yōu)化問題,尤其適用于那些具有多個局部最優(yōu)解的問題。
遺傳算法是一種基于自然選擇和遺傳學(xué)機理的生物進化過程的模擬算法,適用于解決優(yōu)化問題,特別是組合優(yōu)化問題。該算法通過數(shù)學(xué)的方式,利用計算機仿真運算,將問題的求解過程轉(zhuǎn)換成類似生物進化中的染色體基因的交叉、變異等過程。在求解較為復(fù)雜的組合優(yōu)化問題時,相對一些常規(guī)的優(yōu)化算法,通常能夠較快地獲得較好的優(yōu)化結(jié)果。
PSO是一種基于種群的隨機優(yōu)化技術(shù),模擬了鳥群覓食的行為(吐槽下,智能優(yōu)化算法的領(lǐng)域真是卷麻了!!!)。粒子群算法模仿昆蟲、獸群、鳥群和魚群等的群集行為,這些群體按照一種合作的方式尋找食物,群體中的每個成員通過學(xué)習(xí)它自身的經(jīng)驗和其他成員的經(jīng)驗來不斷改變其搜索模式。PSO算法適用于處理多峰函數(shù)和離散優(yōu)化問題,具有簡單、靈活和容易實現(xiàn)的特點。
回顧下各類算法的優(yōu)缺點:
本文介紹了梯度下降類、牛頓法、模擬退火、遺傳算法和粒子群優(yōu)化等常用的機器學(xué)習(xí)優(yōu)化算法。這些算法各有特點和適用范圍,選擇合適的算法需要根據(jù)具體的問題、數(shù)據(jù)集和模型來進行權(quán)衡的。最后,結(jié)合經(jīng)驗分享一些常用梯度下降類優(yōu)化算法的選擇和使用技巧:
本文章轉(zhuǎn)載微信公眾號@Python人工智能前沿