Python中随机梯度下降法

随机梯度下降法

批量梯度下降使用全部的训练样本来计算梯度,并更新模型参数,因此它的每一次迭代计算量较大,但对于凸优化问题,可以保证每次迭代都朝着全局最优解的方向前进,收敛速度较快,最终收敛到的结果也比较稳定。

随机梯度下降则每次迭代仅使用一个样本来计算梯度,并更新模型参数,因此每次迭代的计算量较小,但收敛速度较慢,最终收敛结果也不够稳定,可能会陷入局部最优解。

在实际应用中,批量梯度下降通常用于训练数据量较小、维度较高的情况,而随机梯度下降通常用于训练数据量较大、维度较低的情况。同时也可以采用一种介于两者之间的小批量梯度下降(Mini-Batch Gradient Descent),即每次迭代使用一定数量的随机样本来计算梯度,并更新模型参数,这种方法在训练大规模数据集时也比较实用。
我们用一个函数举例子:
在这里插入图片描述
这里需要求它的梯度:
在这里插入图片描述

随机梯度下降法的代码实现:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
np.random.seed(42)  # 设置随机种子,保证每次运行结果相同
x = np.random.randn(100, 3)
y = x.dot(np.array([4, 5, 6])) + np.random.randn(100) * 0.1
def loss_function(w, x, y):
    return 0.5 * np.mean((np.dot(x, w) - y) ** 2)

def gradient_function(w, x, y):
    return np.dot(x.T, np.dot(x, w) - y) / len(y)
def SGD(x, y, w_init, alpha, max_iter):
    w = w_init
    for i in range(max_iter):
        rand_idx = np.random.randint(len(y))
        x_i = x[rand_idx, :].reshape(1, -1)
        y_i = y[rand_idx]
        grad_i = gradient_function(w, x_i, y_i)
        w = w - alpha * grad_i
    return w
fig = plt.figure()
ax = Axes3D(fig)
W0 = np.arange(0, 10, 0.1)
W1 = np.arange(0, 10, 0.1)
W0, W1 = np.meshgrid(W0, W1)
W2 = np.array([SGD(x, y, np.array([w0, w1, 0]), 0.01, 1000)[2] for w0, w1 in zip(np.ravel(W0), np.ravel(W1))])
W2 = W2.reshape(W0.shape)
ax.plot_surface(W0, W1, W2, cmap='coolwarm')
ax.set_xlabel('w0')
ax.set_ylabel('w1')
ax.set_zlabel('loss')
plt.show()



在这里插入图片描述
这个图像表示了随机梯度下降算法在二元线性回归问题中对于不同初始权重( x x x y y y)的收敛情况。横轴和纵轴分别表示 x x x y y y的值,而竖轴表示算法收敛的迭代次数。不同颜色的曲面表示不同的收敛路径。可以看到,算法在不同的初始权重下都能收敛到大致相同的最优权重,这也验证了随机梯度下降算法的鲁棒性和适用性。此外,可以看到不同初始权重下的收敛速度和路径都不同,这也说明了随机梯度下降算法的随机性。
可以更换max_iter的值,以下是迭代10000此的结果:
在这里插入图片描述
迭代100000的结果:
在这里插入图片描述

在这段代码中的数学含义代表如下:

w_init:表示模型参数的初始值。这里是一个一维数组,包含三个元素,分别对应截距、x1系数和x2系数。

x:表示输入特征矩阵,每行包含两个特征x1和x2。

y:表示输出标签,是一个一维数组。

alpha:表示学习率,是一个超参数,决定了每一次迭代参数的更新幅度。

max_iter:表示最大迭代次数,也是一个超参数。

rand_idx = np.random.randint(len(y)):在每一次迭代中,随机选择一个样本。

x_i = x[rand_idx, :].reshape(1, -1):根据随机选择的样本索引,选取相应的特征向量,并将其变为一个1行2列的矩阵。

y_i = y[rand_idx]:根据随机选择的样本索引,选取相应的输出标签。

grad_i = gradient_function(w, x_i, y_i):计算该样本的梯度。

w = w - alpha * grad_i:更新模型参数。

return w:返回最终权重。

x = np.insert(x, 0, 1, axis=1):将截距添加到输入特征矩阵x的第一列。

np.dot(x, w):计算模型的预测值。

np.dot(x, w) - y:计算模型预测值与真实标签的误差。

np.dot(x.T, np.dot(x, w) - y):计算误差的梯度。

len(y):计算样本的数量。

return np.dot(x.T, np.dot(x, w) - y) / len(y):返回梯度。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python实现函数的随机梯度下降可以通过以下步骤进行: 1. 定义损失函数:首先,需要定义一个损失函数,用于衡量模型预测结果与实际结果之间的差异。常见的损失函数包括均方误差(Mean Squared Error)和交叉熵(Cross Entropy)等。 2. 初始化参数:随机梯度下降需要初始化模型参数,例如权重和偏置。可以使用随机数或者固定初始值进行初始化。 3. 迭代更新参数:在每一次迭代,从训练数据集随机选择一个样本,并计算该样本对应的梯度。然后,根据学习率和梯度的方向更新模型参数。这个过程会不断重复,直到达到预定的迭代次数或者满足停止条件。 4. 重复迭代:重复步骤3,直到达到预定的迭代次数或者满足停止条件。通常情况下,可以设置一个最大迭代次数或者当损失函数的变化小于某个阈值时停止迭代。 下面是一个简单的Python代码示例,演示了如何实现函数的随机梯度下降: ```python import random # 定义损失函数 def loss_function(x, y, w, b): return (w * x + b - y) ** 2 # 初始化参数 w = random.random() b = random.random() learning_rate = 0.01 max_iterations = 1000 # 随机梯度下降 for i in range(max_iterations): # 随机选择一个样本 index = random.randint(0, len(data) - 1) x = data[index][0] y = data[index][1] # 计算梯度 gradient_w = 2 * (w * x + b - y) * x gradient_b = 2 * (w * x + b - y) # 更新参数 w -= learning_rate * gradient_w b -= learning_rate * gradient_b # 输出最终的参数值 print("最终的参数值:w =", w, "b =", b) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值