小批量梯度下降法 (Mini-Batch Gradient Descent)

小批量梯度下降法 (Mini-Batch Gradient Descent, MBGD) 是梯度下降法的一种变体。与批量梯度下降法 (Batch Gradient Descent) 和随机梯度下降法 (Stochastic Gradient Descent, SGD) 不同,小批量梯度下降法在每次迭代中使用一个小批量 (mini-batch) 样本的数据来更新参数。这样既可以减少计算开销,又能够更稳定地更新参数。

原理

小批量梯度下降法的基本思想是通过在每次迭代中使用一部分数据样本 (mini-batch) 来计算梯度,从而更新参数。这种方法在计算效率和收敛速度之间取得了平衡。相比于 SGD,它能够更稳定地更新参数,避免一些噪声引起的波动;相比于批量梯度下降法,它减少了每次迭代的计算量,加快了更新速度。

核心公式

在第 t 次迭代中,选择一个小批量 Bt样本,并计算梯度:

其中:

  • θ(t) 为第 t 次迭代的参数
  • η 为学习率
  • J(θ; Bt) 为目标函数在小批量 Bt上的梯度

目标是最小化目标函数 J(θ)J(\theta)J(θ),即:

Python 示例

我们将使用 Scikit-Learn 中的线性回归模型进行训练,并绘制多个数据分析图形。具体的图形包括:损失函数的收敛图、预测结果与实际结果的比较图、以及参数更新的轨迹图。

数据生成和分割

首先,我们生成一个带有噪声的线性回归数据集,并将其划分为训练集和测试集。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error

# 生成回归数据集
X, y = make_regression(n_samples=1000, n_features=1, noise=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 打印前5条数据和对应的目标值
print("前5条训练数据:")
print(X_train[:5])
print("前5个训练目标值:")
print(y_train[:5])
小批量梯度下降法回归模型初始化

使用 SGDRegressor 初始化随机梯度下降回归模型,设定最大迭代次数、禁用容忍度检查、启用 warm_start,每次迭代使用上次的解,设定常数学习率和初始学习率。

# 初始化小批量梯度下降回归模型
sgd = SGDRegressor(max_iter=1, tol=None, warm_start=True, learning_rate='constant', eta0=0.01, random_state=42)
训练模型

进行多次迭代(epochs),在每个 epoch 进行一次模型训练,记录训练误差和测试误差,以及每次迭代后的系数值。

# 记录训练过程中的信息
n_epochs = 50
batch_size = 32
train_errors, test_errors = [], []
coef_updates = []

# 训练模型
for epoch in range(n_epochs):
    for i in range(0, X_train.shape[0], batch_size):
        X_batch = X_train[i:i+batch_size]
        y_batch = y_train[i:i+batch_size]
        sgd.fit(X_batch, y_batch)
    
    y_train_predict = sgd.predict(X_train)
    y_test_predict = sgd.predict(X_test)
    train_errors.append(mean_squared_error(y_train, y_train_predict))
    test_errors.append(mean_squared_error(y_test, y_test_predict))
    coef_updates.append(sgd.coef_.copy())
绘制图形
  1. 损失函数的收敛图:展示训练误差和测试误差随迭代次数的变化。
# 绘制损失函数的收敛图
plt.figure(figsize=(10, 6))
plt.plot(train_errors, label='训练误差')
plt.plot(test_errors, label='测试误差')
plt.xlabel('迭代次数')
plt.ylabel('均方误差')
plt.title('训练和测试误差随迭代次数的变化')
plt.legend()
plt.grid()
plt.show()
  1. 预测结果与实际结果的比较图:展示测试集上的实际值和预测值的散点图。
# 绘制预测结果与实际结果的比较图
plt.figure(figsize=(10, 6))
plt.scatter(X_test, y_test, color='blue', label='实际值')
plt.scatter(X_test, y_test_predict, color='red', label='预测值')
plt.xlabel('输入特征')
plt.ylabel('目标值')
plt.title('实际值与预测值的比较')
plt.legend()
plt.grid()
plt.show()
  1. 参数更新的轨迹图:展示模型系数在每个 epoch 的更新情况。
# 绘制参数更新的轨迹图
coef_updates = np.array(coef_updates)
plt.figure(figsize=(10, 6))
plt.plot(coef_updates, marker='o')
plt.xlabel('迭代次数')
plt.ylabel('系数值')
plt.title('系数更新轨迹')
plt.grid()
plt.show()

案例描述

我们将构建一个案例,使用小批量梯度下降(MBGD)算法对一个带有噪声的线性回归数据集进行训练和预测。具体步骤如下:

  1. 生成数据:使用 make_regression 生成一个包含 1000 个样本和 1 个特征的回归数据集,并添加噪声。
  2. 数据分割:将数据集划分为训练集和测试集。
  3. 初始化模型:使用 SGDRegressor 初始化小批量梯度下降回归模型。
  4. 模型训练:通过多次迭代(epochs),在每个 epoch 中使用训练数据训练模型,并记录训练误差和测试误差,以及每次迭代后的模型系数。
  5. 结果可视化:绘制损失函数的收敛图、预测结果与实际结果的比较图,以及参数更新的轨迹图。
代码实现

以下是实现上述案例的详细代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error

# 生成回归数据集
X, y = make_regression(n_samples=1000, n_features=1, noise=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化小批量梯度下降回归模型
sgd = SGDRegressor(max_iter=1, tol=None, warm_start=True, learning_rate='constant', eta0=0.01, random_state=42)

# 记录训练过程中的信息
n_epochs = 50
batch_size = 32
train_errors, test_errors = [], []
coef_updates = []

# 训练模型
for epoch in range(n_epochs):
    for i in range(0, X_train.shape[0], batch_size):
        X_batch = X_train[i:i+batch_size]
        y_batch = y_train[i:i+batch_size]
        sgd.fit(X_batch, y_batch)
    
    y_train_predict = sgd.predict(X_train)
    y_test_predict = sgd.predict(X_test)
    train_errors.append(mean_squared_error(y_train, y_train_predict))
    test_errors.append(mean_squared_error(y_test, y_test_predict))
    coef_updates.append(sgd.coef_.copy())

# 绘制损失函数的收敛图
plt.figure(figsize=(10, 6))
plt.plot(train_errors, label='训练误差')
plt.plot(test_errors, label='测试误差')
plt.xlabel('迭代次数')
plt.ylabel('均方误差')
plt.title('训练和测试误差随迭代次数的变化')
plt.legend()
plt.grid()
plt.show()

# 绘制预测结果与实际结果的比较图
plt.figure(figsize=(10, 6))
plt.scatter(X_test, y_test, color='blue', label='实际值')
plt.scatter(X_test, y_test_predict, color='red', label='预测值')
plt.xlabel('输入特征')
plt.ylabel('目标值')
plt.title('实际值与预测值的比较')
plt.legend()
plt.grid()
plt.show()

# 绘制参数更新的轨迹图
coef_updates = np.array(coef_updates)
plt.figure(figsize=(10, 6))
plt.plot(coef_updates, marker='o')
plt.xlabel('迭代次数')
plt.ylabel('系数值')
plt.title('系数更新轨迹')
plt.grid()
plt.show()
详细步骤解释
  1. 生成数据
    • 使用 make_regression 生成一个线性回归数据集,包含 1000 个样本,每个样本有 1 个特征,并添加噪声以模拟真实数据中的误差。
    • 使用 train_test_split 将数据集划分为训练集(80%)和测试集(20%)。
  1. 初始化模型
    • 使用 SGDRegressor 初始化小批量梯度下降回归模型,设置 max_iter=1warm_start=True 以确保每次迭代都使用上次的解。
    • 设置常数学习率(learning_rate='constant')和初始学习率(eta0=0.01)。
  1. 模型训练
    • 进行 50 次迭代(epochs),在每次迭代中使用训练数据训练模型。
    • 每次迭代中使用小批量数据进行训练,并记录训练误差和测试误差,以及模型系数。
  1. 结果可视化
    • 损失函数的收敛图:展示训练误差和测试误差随迭代次数的变化,以评估模型的收敛情况。

    • 预测结果与实际结果的比较图:展示测试集上的实际值和预测值的散点图,以评估模型的预测效果。

    • 参数更新的轨迹图:展示模型系数在每个 epoch 的更新情况,以了解参数的收敛过程。

结论

在这个案例中,我们生成了一个带有噪声的线性回归数据集,并使用小批量梯度下降(MBGD)进行模型训练。通过分析损失函数的收敛图、预测结果与实际结果的比较图,以及参数更新的轨迹图,我们可以清楚地了解模型的训练过程和效果。小批量梯度下降法由于在每次迭代中使用了一部分数据样本,使得参数更新更加频繁,有助于更快地逼近目标函数的最小值,同时避免了过多的噪声干扰。

案例:房价预测

案例描述

假设你是一位房地产分析师,希望根据房屋的面积和房间数量来预测房价。你可以使用机器学习中的小批量梯度下降法(Mini-Batch Gradient Descent, MBGD)来进行回归分析,以构建一个房价预测模型。

场景细节
  • 目标:根据房屋面积和房间数量预测房价。
  • 数据集:我们将生成一个模拟的数据集,包括1000个样本,每个样本包含房屋的面积、房间数量和房价。数据集带有一定的噪声,以模拟真实数据中的误差。
  • 步骤
    1. 生成数据集。
    2. 划分数据集为训练集和测试集。
    3. 初始化小批量梯度下降法回归模型。
    4. 训练模型并记录训练误差和测试误差。
    5. 可视化结果,包括损失函数的收敛图、预测结果与实际结果的比较图、以及参数更新的轨迹图。
代码实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error

# 生成模拟房价数据
np.random.seed(42)
n_samples = 1000
X_area = np.random.rand(n_samples, 1) * 1000  # 面积在0到1000平米之间
X_rooms = np.random.randint(1, 10, size=(n_samples, 1))  # 房间数在1到10之间
X = np.hstack([X_area, X_rooms])
y = 50 + 0.5 * X_area + 10 * X_rooms + np.random.randn(n_samples, 1) * 50  # 房价公式,带有噪声

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化小批量梯度下降回归模型
sgd = SGDRegressor(max_iter=1, tol=None, warm_start=True, learning_rate='constant', eta0=0.01, random_state=42)

# 记录训练过程中的信息
n_epochs = 50
batch_size = 32
train_errors, test_errors = [], []
coef_updates = []

# 训练模型
for epoch in range(n_epochs):
    for i in range(0, X_train.shape[0], batch_size):
        X_batch = X_train[i:i+batch_size]
        y_batch = y_train[i:i+batch_size]
        sgd.fit(X_batch, y_batch.ravel())
    
    y_train_predict = sgd.predict(X_train)
    y_test_predict = sgd.predict(X_test)
    train_errors.append(mean_squared_error(y_train, y_train_predict))
    test_errors.append(mean_squared_error(y_test, y_test_predict))
    coef_updates.append(sgd.coef_.copy())

# 绘制损失函数的收敛图
plt.figure(figsize=(10, 6))
plt.plot(train_errors, label='训练误差')
plt.plot(test_errors, label='测试误差')
plt.xlabel('迭代次数')
plt.ylabel('均方误差')
plt.title('训练和测试误差随迭代次数的变化')
plt.legend()
plt.grid()
plt.show()

# 绘制预测结果与实际结果的比较图
plt.figure(figsize=(10, 6))
plt.scatter(X_test[:, 0], y_test, color='blue', label='实际值')
plt.scatter(X_test[:, 0], y_test_predict, color='red', label='预测值')
plt.xlabel('面积')
plt.ylabel('房价')
plt.title('实际值与预测值的比较')
plt.legend()
plt.grid()
plt.show()

# 绘制参数更新的轨迹图
coef_updates = np.array(coef_updates)
plt.figure(figsize=(10, 6))
for i in range(coef_updates.shape[1]):
    plt.plot(coef_updates[:, i], marker='o', label=f'系数 {i}')
plt.xlabel('迭代次数')
plt.ylabel('系数值')
plt.title('系数更新轨迹')
plt.legend()
plt.grid()
plt.show()
详细步骤解释
  1. 生成数据
    • 使用 numpy 生成一个包含房屋面积(0-1000平米)和房间数量(1-10个房间)的模拟数据集。
    • 使用房价公式生成目标值,公式中包括常数项、面积和房间数量的系数,以及一定的随机噪声。
  1. 划分数据集
    • 使用 train_test_split 将数据集划分为训练集(80%)和测试集(20%)。
  1. 初始化模型
    • 使用 SGDRegressor 初始化小批量梯度下降回归模型,设置 max_iter=1warm_start=True 以确保每次迭代都使用上次的解。
    • 设置常数学习率(learning_rate='constant')和初始学习率(eta0=0.01)。
  1. 模型训练
    • 进行 50 次迭代(epochs),在每次迭代中使用小批量数据进行训练。
    • 记录每次迭代的训练误差和测试误差,以及模型系数。
  1. 结果可视化
    • 损失函数的收敛图:展示训练误差和测试误差随迭代次数的变化。

    • 预测结果与实际结果的比较图:展示测试集上的实际值和预测值的散点图。

    • 参数更新的轨迹图:展示模型系数在每个 epoch 的更新情况。

结论

通过以上步骤,我们构建了一个小批量梯度下降法的回归模型,用于预测房价。通过分析损失函数的收敛图、预测结果与实际结果的比较图,以及参数更新的轨迹图,我们可以清楚地了解模型的训练过程和效果。小批量梯度下降法能够更快地逼近目标函数的最小值,并且通过频繁的参数更新,有助于避免陷入局部最优解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值