24/8/13算法笔记 复习_BGD,MGD,SGD

MGD

import numpy as np
import matplotlib.pyplot as plt

#随机生成线性回归函数
X = np.random.rand(100,1)
w,b = np.random.randint(1,10,size = 2)

#增加噪声,更像真实数据
#numpy广播机制
y = w*X+b+np.random.randn(100,1)
plt.scatter(X,y)

#将b作为偏置项,截距,对应系数理解为1
X =np.concatenate([X,np.full(shape = (100,1),fill_value = 1)],axis = 1)

#大批量梯度下降
epoches = 10000#循环次数

eta = 0.01 #学习率
t0 = 5
t1 = 1000
def learning_rate_shedule(t): #优化学习率变化,t梯度下降的次数,逆时衰减,随着梯度下降次数增加学习率,变小
    return t0/(t1 + t)

theta = np.random.randn(2,1)#要求解的系数

#梯度下降的次数
t = 0
for i in range(epoches):
    #批量梯度下降
    g = X.T.dot(X.dot(theta)-y)#根据公式计算梯度
    eta = learning_rate_shedule(t)#随着梯度下降增加,学习率下降
    theta = theta - eta*g
print('真实斜率是,截距是:',w,b)
print('BGD求解的斜率,截距是:',theta)#因为增加了噪声,所以有差距

#随机梯度下降
X = np.random.rand(100,1)
w,b = np.random.randint(1,10,size = 2)  #随机系数和偏置项

y = w*X + b +np.random.randn(100,1)
plt.scatter(X,y)

X = np.concatenate([X,np.full_like(X,fill_value = 1)],axis = 1) #like参数决定了新数组的形状和数据类型,并且新数组中的所有元素都被填充为fill_value指定的值,这里是1。

epoches = 100#循环次数

t0 = 5
t1 = 1000

def learning_rate_shedule(t):
    return t0/(t1 + t)
theta = np.random.randn(2,2)

count = 0
for t in range(epoches):
    index = np.arange(100)    #np.arange 是 NumPy 中的一个函数,用于生成一个给定范围内的值的数组
    np.random.shuffle(index)#洗牌,打乱
    
    X = X[index]
    y = y[index]
    for i in range(100):#随机抽样
        X_i = X[i]
        y_i = y[i]
        #根据这个样本,逆行计算梯度
        #单个样本依然是矩阵
        g = X_i.T.dot(X_i - theta*y_i)
        eta = learning_rate_shedule(t+count)#动态学习率
        count += 1
        theta -= eta*g
print('真实的斜率,截距是',w,b)
print('SGD求解的斜率,截距是',theta)
        

#小批量梯度下降
X = np.random.rand(100,1)
w,b = np.random.randint(1,10,size=2)

y = w*X+b+np.random.randn(100,1)
X = np.c_[X,np.ones((100,1))] #,np.c_ 是一个 NumPy 函数,用于沿着列的方向(水平方向)连接两个数组。这与 np.concatenate 函数类似,但 np.c_ 是一个更快捷的方式,特别是当你需要连接两个数组为一个新的二维数组时。

t0,t1=5,500
def learning_rate_shedule(t):
    return t0/(t1+t)

epoches = 100
n=100
#处理大量数据时,会将数据分成多个批次(batch),以便逐步训练模型。这种处理方式称为批量处理(batch processing)
batch_size = 16 #每个批次包含的样本数量
num_batches =int(n/batch_size)#是数据集可以被分成的批次总数。这里使用了 int() 函数来确保 num_batches 是一个整数。如果 n 不能被 batch_size 整除,int() 函数会向下取整,即只计算完全填满的批次数量。

#初始化w0,wn标准正态分布创建
o = np.random.randn(2,1)

#多次for循环实现梯度下降,最终结果收敛
for epoch in range(epoches):
    #在双层for循环之间,每个轮次开始分批次迭代之前打乱数据索引顺序
    index = np.arange(n)
    np.random.shuffle(index)#打乱
    X = X[index]
    y = y[index]
    for i in range(num_batches):
        #切片
        X_batch = X[i*batch_size:(i+1)*batch_size]
        y_batch = y[i*batch_size:(i+1)*batch_size]
        
        g = X_batch.T.dot(X_batch.dot(o) - y_batch)
        
        learning_rate = learning_rate_shedule(epoch *n+i)#更新学习率
        o = o-learning_rate*g
        
print('真实斜率和截距',w,b)
print('梯度下降计算斜率和截距',o)

np.c_ 是一个 NumPy 函数,用于沿着列的方向(水平方向)连接两个数组。这与 np.concatenate 函数类似,但 np.c_ 是一个更快捷的方式,特别是当你需要连接两个数组为一个新的二维数组时。

为什么使用切片?

  1. 小批量处理:在小批量梯度下降中,整个数据集被分成多个小批量。这样做的原因是:

    • 内存效率:小批量可以减少内存的使用,使得算法能够处理大于内存容量的数据集。
    • 计算效率:现代计算硬件(如GPU)通常针对小批量数据优化,可以更快地进行并行计算。
    • 稳定性:小批量可以减少训练过程中的噪声,有时可以提供更稳定的收敛性能。

 o = o-learning_rate*g:

  1. o 初始化为一个包含两个元素的数组,这里 o 被用作参数向量,其中第一个元素是权重 w 的估计值,第二个元素是偏置 b 的估计值。

  2. o = o - learning_rate * g 这行代码是梯度下降更新规则:

    • g 是梯度向量,计算当前参数 o 下的预测值与实际值 y_batch 之差的平方和的梯度。
    • learning_rate 是学习率,用于控制每一步更新的步长。
    • o 根据负梯度方向进行更新,以减少预测误差。
  3. 学习率调度函数 learning_rate_shedule 根据当前的迭代次数调整学习率,这是一种常见的技术,用于在训练初期使用较大的学习率,随着迭代的进行逐渐减小学习率,以保证收敛的稳定性。

  4. 每次迭代中,通过双层循环(外层迭代轮次 epoch,内层迭代批次 i),整个数据集被分成多个小批量进行处理。在每个批次中,计算梯度并更新参数 o

  5. 最终,o 包含了通过梯度下降算法学习到的权重和偏置的估计值。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值