# 导入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)  

更多推荐