【机器学习】案例2.2——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. 设置SGD的超参数 =====================
n_epochs = 10000 # 训练轮数(epoch):每轮会“随机遍历”一次所有样本
m = 100 # 样本总数量
learning_rate = 0.001 # 学习率:控制参数更新的步长(SGD通常会用动态学习率,这里是固定值)
# ===================== 3. 初始化模型参数 =====================
# 初始化参数theta:包含2个值(w0:截距,w1:X的系数),用标准正态分布随机生成初始值
theta = np.random.randn(2, 1)
# ===================== 4. 随机梯度下降(SGD)核心迭代 =====================
# 外层循环:遍历每一轮训练(每轮会“随机过一遍”所有样本)
for epoch in range(n_epochs):
# 内层循环:遍历每个样本(但SGD是“随机选一个样本”更新,而非按顺序)
for _ in range(m):
# 随机选一个样本的索引:从0到m-1(共100个样本)中随机选一个整数
random_index = np.random.randint(m)
# 取出该随机索引对应的“单个样本”的特征(xi,形状是(1,2))
xi = X_b[random_index:random_index+1]
# 取出该随机索引对应的“单个样本”的标签(yi,形状是(1,1))
yi = y[random_index:random_index+1]
# 计算“单个样本”对应的损失函数梯度(SGD用单样本算梯度,而非批量,因此梯度有噪声)
gradients = xi.T.dot(xi.dot(theta) - yi)
# 用单样本的梯度更新参数theta:向梯度反方向移动(最小化损失)
theta = theta - learning_rate * gradients
# 打印最终学习到的参数theta
# 理想情况下会接近真实值[4,3](但SGD梯度噪声大,结果波动会比批量梯度下降更明显)
print(theta)
更多推荐
所有评论(0)