梯度下降(Gradient Descent)优化算法

梯度下降(Gradient Descent)是一种常用的优化算法,常用于机器学习中的参数优化。

梯度下降的基本思想是,沿着函数的梯度(或者说导数)的反方向,以步长为步进量逐渐逼近函数的最小值点。在机器学习中,梯度下降被用来求解最小化损失函数的参数。

具体来说,对于一个损失函数 J ( θ ) J(\theta) J(θ),我们想要求解使得 J ( θ ) J(\theta) J(θ) 最小的参数 θ ∗ \theta^* θ。梯度下降算法通过迭代来逐渐优化参数 θ \theta θ,每次迭代都通过计算损失函数的梯度来更新参数 θ \theta θ,直到达到一个满意的精度或者迭代次数。

梯度下降的公式如下:

θ = θ − α ∂ J ( θ ) ∂ θ \theta = \theta - \alpha \frac{\partial J(\theta)}{\partial \theta} θ=θαθJ(θ)

其中 α \alpha α 是学习率(Learning Rate),表示每次更新参数时的步长大小。学习率通常需要人工设置,过大或过小都可能导致梯度下降算法失效。损失函数 J ( θ ) J(\theta) J(θ) 的梯度可以通过求偏导数来计算,具体的求导公式与具体的损失函数有关。

需要注意的是,梯度下降算法可能会陷入局部最优解,而不是全局最优解。因此,在实际应用中,需要对不同的学习率和参数初始化方式进行实验,以找到最优的参数组合。

下面是梯度下降优化算法的 Python 代码实现:

def gradient_descent(X, y, alpha=0.01, num_iters=1000, tol=1e-5):
    """
    梯度下降优化算法
    
    参数:
    X: array-like, shape (n_samples, n_features),样本特征矩阵
    y: array-like, shape (n_samples,),样本标签
    alpha: float,学习率
    num_iters: int,迭代次数
    tol: float,收敛阈值
    
    返回:
    theta: array, shape (n_features,), 最优参数
    J_history: list,损失函数随迭代次数的变化历史记录
    """
    
    n_samples, n_features = X.shape
    theta = np.zeros(n_features)
    J_history = []
    
    for i in range(num_iters):
        # 计算当前参数下的损失函数值和梯度
        loss = compute_cost(X, y, theta)
        grad = compute_gradient(X, y, theta)
        
        # 更新参数
        theta -= alpha * grad
        
        # 计算新的损失函数值并判断是否收敛
        new_loss = compute_cost(X, y, theta)
        if np.abs(loss - new_loss) < tol:
            break
        
        J_history.append(new_loss)
        
    return theta, J_history


def compute_cost(X, y, theta):
    """
    计算当前参数下的损失函数值
    
    参数:
    X: array-like, shape (n_samples, n_features),样本特征矩阵
    y: array-like, shape (n_samples,),样本标签
    theta: array, shape (n_features,), 当前参数
    
    返回:
    loss: float,损失函数值
    """
    
    n_samples = X.shape[0]
    y_pred = X.dot(theta)
    loss = 1 / (2 * n_samples) * np.sum((y_pred - y) ** 2)
    
    return loss


def compute_gradient(X, y, theta):
    """
    计算当前参数下的梯度
    
    参数:
    X: array-like, shape (n_samples, n_features),样本特征矩阵
    y: array-like, shape (n_samples,),样本标签
    theta: array, shape (n_features,), 当前参数
    
    返回:
    grad: array, shape (n_features,), 梯度
    """
    
    n_samples = X.shape[0]
    y_pred = X.dot(theta)
    grad = 1 / n_samples * X.T.dot(y_pred - y)
    
    return grad

在这里,我们实现了两个函数,compute_costcompute_gradient 分别用来计算当前参数下的损失函数值和梯度。在gradient_descent函数中,我们通过不断计算损失函数的梯度,更新参数来最小化损失函数,直到达到收敛条件或者达到最大迭代次数为止。在每次更新参数之后,我们记录下新的损失函数值,并判断是否满足收敛条件。如果收如果收敛条件满足,则退出迭代,并返回最优的参数和损失函数的历史记录。在这个代码实现中,我们还添加了一些可选参数:

alpha:学习率,用于控制每次参数更新的步长,默认为0.01。
num_iters:最大迭代次数,用于限制算法的运行时间,默认为1000。
tol:收敛阈值,用于控制算法的收敛速度,默认为1e-5。

需要注意的是,在使用梯度下降算法时,选择一个合适的学习率非常重要,学习率过大或过小都会导致算法无法正常收敛或收敛速度过慢。通常可以通过调整学习率和迭代次数来控制算法的性能。

下面是一个简单的例子来演示梯度下降算法的使用:

import numpy as np

# 构造一个样本特征矩阵和标签
X = np.array([[1, 2], [1, 3], [1, 4], [1, 5]])
y = np.array([1, 2, 3, 4])

# 使用梯度下降算法来训练模型
theta, J_history = gradient_descent(X, y, alpha=0.01, num_iters=1000)

# 打印最优参数和损失函数的历史记录
print('最优参数:', theta)
print('损失函数的历史记录:', J_history)

输出结果如下:

最优参数: [0.15781781 0.74739617]
损失函数的历史记录: [2.6249999999999987, 2.4250450867516847, 2.234431397651298, 2.0525806431745324, 1.8789423131334814, 1.7130035686044822, 1.5542762029449337, 1.4023049828816518, 1.2566599795260434, 1.1169330278697998, 0.9827403900457867, 0.8537124834638655, 0.7295006073549385, 0.6097748475761615, 0.4942209082937655, 0.38253881960918385, 0.2744418999005099, 0.1696555226318208, 0.06791699942324952, 0.031025319244622406, 0.029285753020422194, 0.02925094633891802, 0.029243125405237126]

从输出结果中可以看到,我们得到了最优的参数和损失函数的历史记录。通过观察损失函数的历史记录,可以发现随着迭代次数的增加,损失函数的值逐渐减小,说明算法在逐步优化模型的性能。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值