做購物網(wǎng)站適合的服務器快速開發(fā)平臺
梯度下降的基本概念
梯度下降(Gradient Descent)是一種用于優(yōu)化機器學習模型參數(shù)的算法,其目的是最小化損失函數(shù),從而提高模型的預測精度。梯度下降的核心思想是通過迭代地調(diào)整參數(shù),沿著損失函數(shù)下降的方向前進,最終找到最優(yōu)解。
生活中的背景例子:尋找山谷的最低點
想象你站在一個山谷中,眼睛被蒙住,只能用腳感受地面的坡度來找到山谷的最低點(即損失函數(shù)的最小值)。你每一步都想朝著坡度下降最快的方向走,直到你感覺不到坡度,也就是你到了最低點。這就好比在優(yōu)化一個模型時,通過不斷調(diào)整參數(shù),使得模型的預測誤差(損失函數(shù))越來越小,最終找到最佳參數(shù)組合。
梯度下降的具體方法及其優(yōu)化
1. 批量梯度下降(Batch Gradient Descent)
生活中的例子:
你決定每次移動之前,都要先測量整個山谷的坡度,然后再決定移動的方向和步幅。雖然每一步的方向和步幅都很準確,但每次都要花很多時間來測量整個山谷的坡度。
公式:
θ : = θ ? η ? ? θ J ( θ ) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta) θ:=θ?η??θ?J(θ)
其中:
- θ \theta θ是模型參數(shù)
- η \eta η是學習率
- ? θ J ( θ ) \nabla_{\theta} J(\theta) ?θ?J(θ)是損失函數(shù) J ( θ ) J(\theta) J(θ)關(guān)于 θ \theta θ的梯度
API:
TensorFlow:
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
PyTorch:
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
批量梯度下降過程圖像python代碼
import numpy as np
import matplotlib.pyplot as plt# 損失函數(shù): y = x^2
def loss(x):return x ** 2# 損失函數(shù)的梯度: dy/dx = 2x
def gradient(x):return 2 * x# 批量梯度下降
def batch_gradient_descent(start, learning_rate, iterations):x = startpath = [x]for i in range(iterations):grad = gradient(x)x = x - learning_rate * gradpath.append(x)return path# 參數(shù)
start = 10
learning_rate = 0.1
iterations = 20# 運行梯度下降
path = batch_gradient_descent(start, learning_rate, iterations)# 繪制圖像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Batch Gradient Descent Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Batch Gradient Descent')
plt.show()
- 從圖像可知,批量梯度下降每次使用整個訓練集計算梯度并更新參數(shù),適用于小規(guī)模數(shù)據(jù)集,收斂穩(wěn)定,但計算開銷大。
2. 隨機梯度下降(Stochastic Gradient Descent, SGD)
生活中的例子:
你決定每一步都只根據(jù)當前所在位置的坡度來移動。雖然這樣可以快速決定下一步怎么走,但由于只考慮當前點,可能會導致路徑不穩(wěn)定,有時候會走過頭。
公式:
θ : = θ ? η ? ? θ J ( θ ; x ( i ) , y ( i ) ) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta; x^{(i)}, y^{(i)}) θ:=θ?η??θ?J(θ;x(i),y(i))
其中 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i))是當前樣本的數(shù)據(jù)
API:
TensorFlow 和 PyTorch 中的API與批量梯度下降相同,具體行為取決于數(shù)據(jù)的加載方式。例如在訓練時可以一批數(shù)據(jù)包含一個樣本。
隨機梯度下降過程圖像python代碼
import numpy as np
import matplotlib.pyplot as plt# 損失函數(shù): y = x^2
def loss(x):return x ** 2# 損失函數(shù)的梯度: dy/dx = 2x
def gradient(x):return 2 * x# 隨機梯度下降
def stochastic_gradient_descent(start, learning_rate, iterations):x = startpath = [x]for i in range(iterations):grad = gradient(x)x = x - learning_rate * grad * np.random.uniform(0.5, 1.5) # 模擬隨機樣本的影響path.append(x)return path# 參數(shù)
start = 10
learning_rate = 0.1
iterations = 20# 運行梯度下降
path = stochastic_gradient_descent(start, learning_rate, iterations)# 繪制圖像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='SGD Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Stochastic Gradient Descent')
plt.show()
- 隨機梯度下降每次使用一個樣本計算梯度并更新參數(shù),計算效率高,適用于大規(guī)模數(shù)據(jù)集,但收斂不穩(wěn)定,容易出現(xiàn)抖動。
3. 小批量梯度下降(Mini-Batch Gradient Descent)
生活中的例子:
你決定每次移動之前,只測量周圍一小部分區(qū)域的坡度,然后根據(jù)這小部分區(qū)域的平均坡度來決定方向和步幅。這樣既不需要花太多時間測量整個山谷,也不會因為只看一個點而導致路徑不穩(wěn)定。
公式:
θ : = θ ? η ? ? θ J ( θ ; B ) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta; \mathcal{B}) θ:=θ?η??θ?J(θ;B)
其中 B \mathcal{B} B是當前小批量的數(shù)據(jù)
API:
TensorFlow 和 PyTorch 中的API與批量梯度下降相同,但在數(shù)據(jù)加載時使用小批量。
小批量梯度下降過程圖像python代碼
import numpy as np
import matplotlib.pyplot as plt# 損失函數(shù): y = x^2
def loss(x):return x ** 2# 損失函數(shù)的梯度: dy/dx = 2x
def gradient(x):return 2 * x# 小批量梯度下降
def mini_batch_gradient_descent(start, learning_rate, iterations, batch_size=5):x = startpath = [x]for i in range(iterations):grad = gradient(x)x = x - learning_rate * grad * np.random.uniform(0.8, 1.2) # 模擬小批量樣本的影響path.append(x)return path# 參數(shù)
start = 10
learning_rate = 0.1
iterations = 20# 運行梯度下降
path = mini_batch_gradient_descent(start, learning_rate, iterations)# 繪制圖像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Mini-Batch Gradient Descent Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Mini-Batch Gradient Descent')
plt.show()
- 小批量梯度下降每次使用一個小批量樣本計算梯度并更新參數(shù),平衡了計算效率和穩(wěn)定性。
4. 動量法(Momentum)
生活中的例子:
你在移動時,不僅考慮當前的坡度,還考慮之前幾步的移動方向,就像帶著慣性一樣。如果前幾步一直往一個方向走,那么你會傾向于繼續(xù)往這個方向走,減少來回震蕩。
公式:
v : = β v + ( 1 ? β ) ? θ J ( θ ) v := \beta v + (1 - \beta) \nabla_{\theta} J(\theta) v:=βv+(1?β)?θ?J(θ)
θ : = θ ? η v \theta := \theta - \eta v θ:=θ?ηv
其中:
- v v v是動量項
- β \beta β是動量系數(shù)(通常接近1,如0.9)
API:
TensorFlow:
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
PyTorch:
optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
動量法圖像python代碼
import numpy as np
import matplotlib.pyplot as plt# 損失函數(shù): y = x^2
def loss(x):return x ** 2# 損失函數(shù)的梯度: dy/dx = 2x
def gradient(x):return 2 * x# 動量法
def momentum_gradient_descent(start, learning_rate, iterations, beta=0.9):x = startv = 0path = [x]for i in range(iterations):grad = gradient(x)v = beta * v + (1 - beta) * gradx = x - learning_rate * vpath.append(x)return path# 參數(shù)
start = 10
learning_rate = 0.1
iterations = 20# 運行梯度下降
path = momentum_gradient_descent(start, learning_rate, iterations)# 繪制圖像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Momentum Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Momentum Gradient Descent')
plt.show()
- 動量法通過引入動量項加速收斂并減少震蕩,適用于深度神經(jīng)網(wǎng)絡訓練。
5. RMSProp
生活中的例子:
你在移動時,會根據(jù)最近一段時間內(nèi)每一步的坡度情況,動態(tài)調(diào)整步幅。比如,當坡度變化劇烈時,你會邁小步,當坡度變化平緩時,你會邁大步。
公式:
s : = β s + ( 1 ? β ) ( ? θ J ( θ ) ) 2 s := \beta s + (1 - \beta) (\nabla_{\theta} J(\theta))^2 s:=βs+(1?β)(?θ?J(θ))2
θ : = θ ? η s + ? ? θ J ( θ ) \theta := \theta - \frac{\eta}{\sqrt{s + \epsilon}} \nabla_{\theta} J(\theta) θ:=θ?s+??η??θ?J(θ)
其中:
- s s s是梯度平方的加權(quán)平均值
- ? \epsilon ?是一個小常數(shù),防止除零錯誤
API:
TensorFlow:
optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001)
PyTorch:
optimizer = torch.optim.RMSprop(model.parameters(), lr=0.001)
RMSProp圖像python代碼
import numpy as np
import matplotlib.pyplot as plt# 損失函數(shù): y = x^2
def loss(x):return x ** 2# 損失函數(shù)的梯度: dy/dx = 2x
def gradient(x):return 2 * x# RMSProp
def rmsprop_gradient_descent(start, learning_rate, iterations, beta=0.9, epsilon=1e-8):x = starts = 0path = [x]for i in range(iterations):grad = gradient(x)s = beta * s + (1 - beta) * grad**2x = x - learning_rate * grad / (np.sqrt(s) + epsilon)path.append(x)return path# 參數(shù)
start = 10
learning_rate = 0.1
iterations = 20# 運行梯度下降
path = rmsprop_gradient_descent(start, learning_rate, iterations)# 繪制圖像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='RMSProp Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('RMSProp Gradient Descent')
plt.show()
- RMSProp動態(tài)調(diào)整學習率,通過對梯度平方的加權(quán)平均值進行調(diào)整,適用于處理非平穩(wěn)目標。
6. Adam(Adaptive Moment Estimation)
生活中的例子:
你在移動時,結(jié)合動量法和RMSProp的優(yōu)點,不僅考慮之前的移動方向(動量),還根據(jù)最近一段時間內(nèi)的坡度變化情況(調(diào)整步幅),從而使移動更加平穩(wěn)和高效。
公式:
m : = β 1 m + ( 1 ? β 1 ) ? θ J ( θ ) m := \beta_1 m + (1 - \beta_1) \nabla_{\theta} J(\theta) m:=β1?m+(1?β1?)?θ?J(θ)
v : = β 2 v + ( 1 ? β 2 ) ( ? θ J ( θ ) ) 2 v := \beta_2 v + (1 - \beta_2) (\nabla_{\theta} J(\theta))^2 v:=β2?v+(1?β2?)(?θ?J(θ))2
m ^ : = m 1 ? β 1 t \hat{m} := \frac{m}{1 - \beta_1^t} m^:=1?β1t?m?
v ^ : = v 1 ? β 2 t \hat{v} := \frac{v}{1 - \beta_2^t} v^:=1?β2t?v?
θ : = θ ? η m ^ v ^ + ? \theta := \theta - \eta \frac{\hat{m}}{\sqrt{\hat{v}} + \epsilon} θ:=θ?ηv^?+?m^?
其中:
- m m m和 v v v分別是梯度的一階和二階動量
- β 1 \beta_1 β1?和 β 2 \beta_2 β2?是動量系數(shù)(通常分別取0.9和0.999)
- m ^ \hat{m} m^和 v ^ \hat{v} v^是偏差校正后的動量項
- t t t是時間步
API:
TensorFlow:
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
PyTorch:
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
Adam圖像python代碼
import numpy as np
import matplotlib.pyplot as plt# 損失函數(shù): y = x^2
def loss(x):return x ** 2# 損失函數(shù)的梯度: dy/dx = 2x
def gradient(x):return 2 * x# Adam
def adam_gradient_descent(start, learning_rate, iterations, beta1=0.9, beta2=0.999, epsilon=1e-8):x = startm = 0v = 0path = [x]for t in range(1, iterations + 1):grad = gradient(x)m = beta1 * m + (1 - beta1) * gradv = beta2 * v + (1 - beta2) * grad**2m_hat = m / (1 - beta1**t)v_hat = v / (1 - beta2**t)x = x - learning_rate * m_hat / (np.sqrt(v_hat) + epsilon)path.append(x)return path# 參數(shù)
start = 10
learning_rate = 0.1
iterations = 20# 運行梯度下降
path = adam_gradient_descent(start, learning_rate, iterations)# 繪制圖像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Adam Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Adam Gradient Descent')
plt.show()
- Adam結(jié)合動量法和RMSProp的優(yōu)點,自適應調(diào)整學習率,適用于各種優(yōu)化問題。
綜合應用示例
假設我們在使用TensorFlow和PyTorch訓練一個簡單的神經(jīng)網(wǎng)絡,以下是如何應用這些優(yōu)化方法的示例代碼。
TensorFlow 示例:
import tensorflow as tf# 定義模型
model = tf.keras.Sequential([tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),tf.keras.layers.Dense(10, activation='softmax')
])# 編譯模型并選擇優(yōu)化器
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])# 準備數(shù)據(jù)
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0# 訓練模型
model.fit(x_train, y_train, epochs=10, batch_size=32)
PyTorch 示例:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader# 定義模型
class SimpleNN(nn.Module):def __init__(self):super(SimpleNN, self).__init__()self.fc1 = nn.Linear(784, 128)self.fc2 = nn.Linear(128, 10)def forward(self, x):x = torch.relu(self.fc1(x))x = self.fc2(x)return xmodel = SimpleNN()# 選擇優(yōu)化器
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()# 準備數(shù)據(jù)
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)# 訓練模型
for epoch in range(10):for batch in train_loader:x_train, y_train = batchx_train = x_train.view(x_train.size(0), -1) # Flatten the imagesoptimizer.zero_grad()outputs = model(x_train)loss = criterion(outputs, y_train)loss.backward()optimizer.step()
綜合對比
優(yōu)化方法 | 優(yōu)點 | 缺點 | 可能出現(xiàn)的問題 | 適用場景 |
---|---|---|---|---|
批量梯度下降(Batch GD) | 收斂穩(wěn)定,適用于小規(guī)模數(shù)據(jù)集 | 每次迭代計算開銷大,速度慢 | 難以處理大規(guī)模數(shù)據(jù),容易陷入局部最優(yōu) | 小規(guī)模數(shù)據(jù)集,適合精確收斂 |
隨機梯度下降(SGD) | 計算效率高,適用于大規(guī)模數(shù)據(jù)集 | 路徑不穩(wěn)定,波動較大 | 收斂路徑抖動大,不穩(wěn)定 | 大規(guī)模數(shù)據(jù)集,在線學習,快速迭代 |
小批量梯度下降(Mini-Batch GD) | 平衡了計算效率和收斂穩(wěn)定性 | 需要選擇合適的小批量大小,計算量仍然較大 | 小批量大小選擇不當可能影響收斂效果 | 大規(guī)模數(shù)據(jù)集,適合批量計算 |
動量法(Momentum) | 加速收斂,減少震蕩 | 需要調(diào)整動量系數(shù),增加了參數(shù)選擇的復雜性 | 動量系數(shù)選擇不當可能導致過沖 | 深度神經(jīng)網(wǎng)絡訓練,加速收斂 |
RMSProp | 動態(tài)調(diào)整學習率,適應非平穩(wěn)目標 | 需要調(diào)整參數(shù)β和ε,參數(shù)選擇復雜 | 參數(shù)選擇不當可能影響收斂效果 | 非平穩(wěn)目標,復雜優(yōu)化問題 |
Adam | 結(jié)合動量法和RMSProp優(yōu)點,自適應調(diào)整學習率,收斂快 | 需要調(diào)整多個參數(shù),計算復雜性高 | 參數(shù)選擇不當可能影響收斂效果 | 各種優(yōu)化問題,特別是深度學習模型訓練 |