一、簡介
Gradient Descent,又稱梯度下降法,是一種用於機器學習的優化演算法。通俗地說,就是在參數空間中找到使損失函數最小化的參數值。
梯度下降演算法的核心思想是沿著損失函數梯度方向的相反方向搜索最小值點,每次迭代根據當前位置的梯度值和學習率,更新參數的值,以此來不斷逼進最優解。
二、原理與應用
梯度信息描述了函數在某個點的變化方向,它是求導數值在多維空間中的推廣。梯度下降演算法的核心思想是,從當前的參數點出發,每次移動一個步長,採用負梯度方向的方向,每次迭代能夠得到一個新的解,並使目標函數值向著更小的方向逼近。
梯度下降演算法是一種迭代方法,需要設置學習率,過大或過小都會影響演算法的速度和穩定性。學習率過大可能會導致演算法不收斂,學習率過小則會導致演算法收斂過慢。一般通過交叉驗證法和實驗比較得出一個合適的學習率。
梯度下降演算法廣泛應用於神經網路、線性回歸、邏輯回歸等機器學習和深度學習領域。
三、演算法優化
1. 隨機梯度下降
梯度下降演算法每次迭代需要用到全部樣本的數據,運算量隨樣本數增加而增加,效率較低。隨機梯度下降演算法將全局搜索轉化為隨機搜索,每次只使用一個樣本來更新參數,通過隨機選取樣本的方式避免了樣本的依賴性,可以加速模型的訓練。
隨機梯度下降演算法雖然收斂速度比梯度下降演算法要快,但由於只使用一個樣本而不是全部樣本,可能會造成雜訊的影響,導致結果不穩定。
2. 批量梯度下降
批量梯度下降演算法是指每次使用一個固定大小的批量樣本來更新參數,這個批量的大小稱為batch size。批量梯度下降演算法可以在保證更新的穩定性前提下,加速模型的訓練。
批量梯度下降演算法相比隨機梯度下降演算法,雖然迭代過程中需要運算的樣本數目變多,但由於多個樣本堆疊起來形成的樣本都是隨機的,樣本的偏差因此降低,對於非凸函數求解尤為重要。
四、代碼示例
1. 梯度下降
import numpy as np def gradient_descent(x, y, alpha, num_iters): m = len(y) theta = np.zeros((2,1)) J_history = np.zeros((num_iters,1)) for i in range(num_iters): h = np.dot(x, theta) loss = h - y gradient = np.dot(x.transpose(),loss)/m theta = theta - alpha * gradient J_history[i] = compute_cost(x, y, theta) return theta,J_history def compute_cost(X, y, theta): m = len(y) J = 0 J = np.sum((np.dot(X,theta)-y)**2)/(2*m) return J X = np.array([[1,1],[1,2],[1,3]]) y = np.array([[1],[2],[3]]) theta, J_history = gradient_descent(X, y, 0.1, 1000)
2. 隨機梯度下降
import numpy as np def gradient_descent(x, y, alpha, num_iters): m = len(y) theta = np.zeros((2,1)) J_history = np.zeros((num_iters,1)) for i in range(num_iters): index = np.random.randint(m) h = np.dot(x[index,:], theta) loss = h - y[index,:] gradient = x[index,:].transpose() * loss theta = theta - alpha * gradient J_history[i] = compute_cost(x, y, theta) return theta, J_history def compute_cost(X, y, theta): m = len(y) J = 0 J = np.sum((np.dot(X,theta)-y)**2)/(2*m) return J X = np.array([[1,1],[1,2],[1,3]]) y = np.array([[1],[2],[3]]) theta, J_history = gradient_descent(X, y, 0.1, 1000)
3. 批量梯度下降
import numpy as np def gradient_descent(x, y, alpha, num_iters,batch_size): m = len(y) theta = np.zeros((2,1)) J_history = np.zeros((num_iters,1)) for i in range(num_iters): index = np.random.choice(m,batch_size,replace=False) h = np.dot(x[index,:], theta) loss = h - y[index,:] gradient = np.dot(x[index,:].transpose(), loss)/batch_size theta = theta - alpha * gradient J_history[i] = compute_cost(x, y, theta) return theta,J_history def compute_cost(X, y, theta): m = len(y) J = 0 J = np.sum((np.dot(X,theta)-y)**2)/(2*m) return J X = np.array([[1,1],[1,2],[1,3]]) y = np.array([[1],[2],[3]]) theta, J_history = gradient_descent(X, y, 0.1, 1000,2)
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/288681.html