【机器学习】案例2.3——numpy实现小批量梯度下降
·
# 导入numpy库,用于高效数值计算(矩阵操作、随机数生成等)
import numpy as np
# ===================== 1. 构造模拟数据集 =====================
# 生成特征矩阵X:100个样本,每个样本1个特征,取值为[0,2)的均匀随机数(2*rand放大取值范围)
X = 2 * np.random.rand(100, 1)
# 构造标签y:模拟真实线性关系 y = 4(截距) + 3*X(特征系数) + 噪声
# np.random.randn(100,1):添加标准正态分布的噪声,让数据更贴近真实场景
y = 4 + 3 * X + np.random.randn(100, 1)
# 给特征矩阵拼接偏置项(对应模型的截距w0):每一行前加1,形状变为(100,2),方便计算w0*1 + w1*X
X_b = np.c_[np.ones((100, 1)), X]
# ===================== 2. 设置小批量梯度下降的超参数 =====================
learning_rate = 0.001 # 学习率:控制参数更新的步长
n_epochs = 10000 # 训练轮数(epoch):每轮会处理多批样本
m = 100 # 总样本数量
batch_size = 10 # 小批量的样本数:每批用10个样本计算梯度(核心参数,介于BGD的“全样本”和SGD的“1样本”之间)
num_batches = int(m / batch_size) # 每轮的批次数:总样本数 ÷ 每批样本数,这里是100÷10=10批
# ===================== 3. 初始化模型参数 =====================
# 初始化参数theta:包含2个值(w0:截距,w1:X的系数),用标准正态分布随机生成初始值
theta = np.random.randn(2, 1)
# ===================== 4. 小批量梯度下降核心迭代过程 =====================
# 外层循环:遍历每一轮训练(每轮会处理num_batches批样本)
for epoch in range(n_epochs):
# 内层循环:遍历每一批样本(每轮处理10批,每批10个样本)
for _ in range(num_batches):
# 随机选当前批次的“起始索引”:从0到m-1(共100个样本)中随机选一个整数
random_index = np.random.randint(m)
# 取出当前批次的特征:从random_index开始,取batch_size个样本(形状为(10,2))
x_batch = X_b[random_index: random_index + batch_size]
# 取出当前批次的标签:对应上述10个样本的真实值(形状为(10,1))
y_batch = y[random_index: random_index + batch_size]
# 计算“当前批次样本”对应的损失函数梯度
# 小批量梯度是“批量梯度(全样本)”和“随机梯度(1样本)”的折中:既减少噪声,又提升计算效率
gradients = x_batch.T.dot(x_batch.dot(theta) - y_batch)
# 用当前批次的梯度更新参数theta:向梯度反方向移动(最小化损失函数)
theta = theta - learning_rate * gradients
# 打印最终学习到的参数theta
# 理想情况下会接近真实值[4,3](小批量梯度的噪声比SGD小,收敛稳定性比SGD好)
print(theta)
更多推荐
所有评论(0)