深度学习之详解常见梯度算法(概念、公式、原理、算法实现过程)

目录

前言

一、如何实现梯度下降?

二、梯度计算

三、常见的梯度公式及梯度算法

常见的梯度公式:

1.标量对向量的梯度:

2. 标量对矩阵的梯度:

3. 向量对标量的梯度:

常见梯度算法:

四、常见梯度算法实现 

1、批量梯度下降算法实现函数

2、随机梯度下降算法实现函数

 3、小批量梯度下降算法实现函数

 4、Adam优化算法实现函数

5、简单应用案列demo

五、总结 


博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦!

🍅文末三连哦🍅

👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

前言

梯度下降(Gradient Descent)是一种优化算法,用于寻找最小化损失函数(或成本函数)的参数值。在机器学习和深度学习的背景下,损失函数衡量了模型预测值与真实值之间的差异,而梯度下降则是用于更新模型的参数(例如权重和偏置),以最小化这个差异。

梯度下降的工作原理是,通过计算损失函数关于模型参数的梯度,然后沿着梯度的反方向(即最陡峭的下降方向)更新参数。这样,每次迭代都会使损失函数值减小(至少在局部上是这样的),从而逐渐接近损失函数的最小值。

具体来说,梯度下降算法的步骤通常如下:

  1. 初始化参数:随机初始化模型的参数(例如权重和偏置)。

  2. 计算梯度:使用当前参数计算损失函数关于这些参数的梯度。梯度是一个向量,指示了损失函数在每个参数上的局部变化率。

  3. 更新参数:将每个参数沿着梯度的反方向移动一小步,步长由学习率控制。学习率是一个超参数,决定了参数更新的幅度。

  4. 重复迭代:重复步骤2和3,直到满足某个停止条件(例如达到最大迭代次数、损失函数值足够小或梯度足够小)。

常见的梯度下降算法:

  • 批量梯度下降(Batch Gradient Descent):在每次迭代中使用整个数据集来计算梯度并更新参数。这种方法计算量大,但通常能保证收敛到全局最小值(对于凸损失函数)。

  • 随机梯度下降(Stochastic Gradient Descent, SGD):在每次迭代中只使用一个样本来计算梯度并更新参数。这种方法计算量小,收敛速度快,但可能会引入噪声,导致在最小值附近震荡。

  • 小批量梯度下降(Mini-batch Gradient Descent):在每次迭代中使用一小批样本来计算梯度并更新参数。这种方法是批量梯度下降和随机梯度下降的折中,结合了它们的优点。

梯度下降是机器学习和深度学习中最常用的优化算法之一,但它也有其局限性。例如,对于非凸损失函数,梯度下降可能只能找到局部最小值而不是全局最小值。此外,学习率的选择对算法的性能至关重要,过大或过小的学习率都可能导致算法表现不佳。因此,在实践中,常常使用更先进的优化算法,如动量(Momentum)、Adam、RMSprop等,它们是对梯度下降算法的改进和扩展。

一、如何实现梯度下降?

深度学习中的自动求梯度,主要依赖于反向传播(Backpropagation)算法和计算图(Computational Graph)的概念。下面,我们将简要解释这两个概念如何共同作用以实现自动求梯度:

  1. 计算图
    深度学习模型中的计算可以看作是一系列的操作(如加法、乘法、激活函数等)的组合。这些操作可以表示为计算图中的节点,而节点之间的连接则代表数据依赖关系。每个节点都有一个或多个输入(来自其他节点的输出)和一个输出。

  2. 前向传播
    在前向传播过程中,数据从输入层流向输出层,经过计算图中的每个节点,并产生相应的输出。这些输出将作为后续节点的输入,直到最终得到模型的预测结果。

  3. 损失函数
    为了评估模型的预测结果与真实结果之间的差距,我们使用损失函数。损失函数是一个量化这种差距的指标,其目标是在训练过程中最小化。

  4. 反向传播
    反向传播是自动求梯度的关键步骤。它开始于损失函数节点,并沿着计算图反向传播。在反向传播过程中,我们计算每个节点的梯度,即损失函数对该节点输入的偏导数。这些梯度表示了如何调整节点的输入以最小化损失函数。

  5. 梯度下降
    有了每个参数的梯度后,我们就可以使用梯度下降(或其变种,如Adam、RMSprop等)来更新模型的参数。通过反复进行前向传播、计算损失、反向传播和参数更新,模型逐渐学会从输入数据中提取有用的特征,并产生准确的预测。

具体来说,反向传播利用链式法则来计算梯度。链式法则允许我们将复杂的复合函数的导数分解为更简单的子函数的导数的乘积。这样,我们可以从输出层开始,逐层计算梯度,直到达到输入层。

二、梯度计算

梯度下降的核心思想是通过迭代地调整模型参数的值,使得损失函数逐渐减小。具体来说,它的步骤如下:

  1. 初始化参数:选择一个初始的模型参数向量。
  2. 计算梯度:计算损失函数对参数的梯度(或者称为导数),表示损失函数在当前参数值处的变化率。
  3. 更新参数:沿着梯度的反方向,以一定的步长(学习率)更新参数的值,使得损失函数逐渐减小。
  4. 迭代:重复步骤2和步骤3,直到满足终止条件(如达到最大迭代次数、损失函数收敛等)。

公式:

假设损失函数为$J(\theta)$$\theta$是待优化的模型参数向量。梯度下降的更新规则如下:

\theta = \theta - \alpha \cdot \nabla J(\theta)

其中,$\alpha$是学习率,用来控制参数更新的步长;$\nabla J(\theta)$是损失函数$J(\theta)$对参数$\theta$的梯度。

实现过程:

下面是梯度下降的实现过程的伪代码:

1. 初始化参数 theta
2. 设置学习率 alpha,最大迭代次数 num_iters,终止条件 threshold
3. 初始化损失函数值列表 J_history
4. for iter in range(num_iters):
5.     计算损失函数值 J
6.     计算损失函数对参数的梯度 gradient
7.     更新参数 theta:theta = theta - alpha * gradient
8.     将损失函数值 J 加入 J_history
9.     if 损失函数变化小于 threshold:
10.        结束迭代
11. 返回优化后的参数 theta 和损失函数值列表 J_history

三、常见的梯度公式及梯度算法

常见的梯度公式:

1.标量对向量的梯度:

假设有一个标量函数 $f(\mathbf{x})$$\mathbf{x}$是一个向量,梯度的公式为:

\nabla f(\mathbf{x}) = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, ..., \frac{\partial f}{\partial x_n} \right)

其中,$\frac{\partial f}{\partial x_i}$表示函数 $f$$\mathbf{x}$的第 $i$个元素 $x_i$的偏导数。

2. 标量对矩阵的梯度:

假设有一个标量函数 $f(\mathbf{X})$$\mathbf{X}$是一个矩阵,梯度的公式为:

\nabla f(\mathbf{X}) = \begin{pmatrix} \frac{\partial f}{\partial X_{11}} & \frac{\partial f}{\partial X_{12}} & \cdots & \frac{\partial f}{\partial X_{1m}} \\ \frac{\partial f}{\partial X_{21}} & \frac{\partial f}{\partial X_{22}} & \cdots & \frac{\partial f}{\partial X_{2m}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial f}{\partial X_{n1}} & \frac{\partial f}{\partial X_{n2}} & \cdots & \frac{\partial f}{\partial X_{nm}} \end{pmatrix}

其中,$X_{ij}$表示矩阵 $\mathbf{X}$中的元素。

3. 向量对标量的梯度:

假设有一个向量函数$\mathbf{f}(x)$$x$是一个标量,梯度的公式为:

\nabla \mathbf{f}(x) = \left( \frac{\partial f_1}{\partial x}, \frac{\partial f_2}{\partial x}, ..., \frac{\partial f_n}{\partial x} \right)

其中$\frac{\partial f_i}{\partial x}$表示函数$\mathbf{f}$ 的第$i$个分量对$x$ 的偏导数。

常见梯度算法:

  1. 批量梯度下降(Batch Gradient Descent)

    批量梯度下降是最基本的梯度下降算法之一,它在每一次迭代中使用整个训练数据集来计算梯度,并更新模型参数。虽然计算梯度的效率较低,但是可以得到全局最优解。批量梯度下降的缺点是可能陷入局部最优解,同时对内存要求较高。

  2. 随机梯度下降(Stochastic Gradient Descent)

    随机梯度下降是批量梯度下降的一种改进方法,它在每一次迭代中随机选择一个样本来计算梯度,并更新模型参数。虽然计算梯度的效率较高,但是由于参数更新的方向波动较大,因此收敛过程不稳定。随机梯度下降通常用于大规模数据集和在线学习。

  3. 小批量梯度下降(Mini-batch Gradient Descent)

    小批量梯度下降是批量梯度下降和随机梯度下降的结合,每次迭代使用一个小批量的样本来计算梯度,并更新模型参数。这种方法在计算效率和收敛稳定性之间取得了平衡,是实际应用中最常用的梯度下降算法之一。

  4. Adam优化算法

    Adam(Adaptive Moment Estimation)是一种自适应学习率的优化算法,结合了动量梯度下降和自适应学习率的优点。它通过计算梯度的一阶矩估计和二阶矩估计来自适应地调整学习率,从而在不同维度上具有不同的学习率。Adam算法在实践中表现良好,被广泛应用于深度学习中。

  5. RMSProp优化算法

    RMSProp(Root Mean Square Propagation)是一种自适应学习率的优化算法,它在Adam算法之前提出,通过计算梯度的平方的移动平均来调整学习率,从而加速收敛过程。RMSProp算法通常用于优化神经网络的训练。

  6. Adagrad优化算法

    Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,它通过将学习率分别应用于每个参数的梯度的平方来调整学习率,从而使得稀疏梯度的参数得到更大的更新,稠密梯度的参数得到较小的更新。Adagrad算法通常用于处理稀疏数据集和非凸优化问题。

四、常见梯度算法实现 

1、批量梯度下降算法实现函数

def batch_gradient_descent(X, y, theta, alpha, num_iters):
    """
    批量梯度下降算法实现函数
    
    参数:
    X:特征矩阵,每一行代表一个训练样本的特征,每一列代表一个特征
    y:目标值,向量,每个元素对应一个训练样本的目标值
    theta:模型参数,向量,初始值
    alpha:学习率,控制参数更新步长
    num_iters:迭代次数,控制优化的迭代次数
    
    返回:
    theta:优化后的模型参数
    J_history:损失函数值的历史记录
    """
    m = len(y)
    J_history = []  # 记录损失函数值的历史记录
    
    for iter in range(num_iters):
        # 计算损失函数值
        h = np.dot(X, theta)
        loss = h - y
        J = np.sum(loss ** 2) / (2 * m)
        J_history.append(J)
        
        # 计算梯度
        gradient = np.dot(X.T, loss) / m
        
        # 更新参数
        theta = theta - alpha * gradient
    
    return theta, J_history

2、随机梯度下降算法实现函数

def stochastic_gradient_descent(X, y, theta, alpha, num_iters):
    """
    随机梯度下降算法实现函数
    
    参数:
    X:特征矩阵,每一行代表一个训练样本的特征,每一列代表一个特征
    y:目标值,向量,每个元素对应一个训练样本的目标值
    theta:模型参数,向量,初始值
    alpha:学习率,控制参数更新步长
    num_iters:迭代次数,控制优化的迭代次数
    
    返回:
    theta:优化后的模型参数
    J_history:损失函数值的历史记录
    """
    m = len(y)
    J_history = []  # 记录损失函数值的历史记录
    
    for iter in range(num_iters):
        for i in range(m):
            # 随机选择一个样本
            random_index = np.random.randint(m)
            X_i = X[random_index:random_index+1]
            y_i = y[random_index:random_index+1]
            
            # 计算损失函数值
            h = np.dot(X_i, theta)
            loss = h - y_i
            J = np.sum(loss ** 2) / 2
            J_history.append(J)
            
            # 计算梯度
            gradient = np.dot(X_i.T, loss)
            
            # 更新参数
            theta = theta - alpha * gradient
    
    return theta, J_history

 3、小批量梯度下降算法实现函数

def mini_batch_gradient_descent(X, y, theta, alpha, num_iters, batch_size):
    """
    小批量梯度下降算法实现函数
    
    参数:
    X:特征矩阵,每一行代表一个训练样本的特征,每一列代表一个特征
    y:目标值,向量,每个元素对应一个训练样本的目标值
    theta:模型参数,向量,初始值
    alpha:学习率,控制参数更新步长
    num_iters:迭代次数,控制优化的迭代次数
    batch_size:小批量大小,控制每次迭代使用的样本数量
    
    返回:
    theta:优化后的模型参数
    J_history:损失函数值的历史记录
    """
    m = len(y)
    J_history = []  # 记录损失函数值的历史记录
    
    for iter in range(num_iters):
        for i in range(0, m, batch_size):
            # 选择一个小批量样本
            X_batch = X[i:i+batch_size]
            y_batch = y[i:i+batch_size]
            
            # 计算损失函数值
            h = np.dot(X_batch, theta)
            loss = h - y_batch
            J

 4、Adam优化算法实现函数

def adam(X, y, theta, alpha, beta1, beta2, epsilon, num_iters):
    """
    Adam优化算法实现函数
    
    参数:
    X:特征矩阵,每一行代表一个训练样本的特征,每一列代表一个特征
    y:目标值,向量,每个元素对应一个训练样本的目标值
    theta:模型参数,向量,初始值
    alpha:学习率,控制参数更新步长
    beta1:动量参数,控制历史梯度的影响程度
    beta2:动量参数,控制历史梯度平方的影响程度
    epsilon:数值稳定性参数,防止除零错误
    num_iters:迭代次数,控制优化的迭代次数
    
    返回:
    theta:优化后的模型参数
    J_history:损失函数值的历史记录
    """
    m = len(y)
    J_history = []  # 记录损失函数值的历史记录
    mt = np.zeros_like(theta)  # 一阶矩估计
    vt = np.zeros_like(theta)  # 二阶矩估计
    t = 0  # 迭代次数
    
    for iter in range(num_iters):
        t += 1
        # 计算梯度
        h = np.dot(X, theta)
        loss = h - y
        gradient = np.dot(X.T, loss) / m
        
        # 更新一阶矩估计
        mt = beta1 * mt + (1 - beta1) * gradient
        
        # 更新二阶矩估计
        vt = beta2 * vt + (1 - beta2) * (gradient ** 2)
        
        # 纠正偏差
        mt_hat = mt / (1 - beta1 ** t)
        vt_hat = vt / (1 - beta2 ** t)
        
        # 更新参数
        theta = theta - alpha * mt_hat / (np.sqrt(vt_hat) + epsilon)
        
        # 计算损失函数值
        J = np.sum((np.dot(X, theta) - y) ** 2) / (2 * m)
        J_history.append(J)
    
    return theta, J_history

5、简单应用案列demo

基于线性回归神经网络模型,并使用批量梯度下降算法进行训练。最后,使用matplotlib库将损失函数值随迭代次数的变化可视化输出。

import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
np.random.seed(0)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)

# 在特征矩阵 X 中添加偏置列
X_b = np.c_[np.ones((100, 1)), X]

# 定义激活函数(这里使用恒等函数)
def identity_activation(z):
    return z

# 定义损失函数(均方误差)
def mse_loss(y_true, y_pred):
    return np.mean((y_true - y_pred) ** 2)

# 定义批量梯度下降算法
def batch_gradient_descent(X, y, theta, alpha, num_iters):
    m = len(y)
    J_history = []  # 记录损失函数值的历史记录
    
    for iter in range(num_iters):
        # 计算模型预测值
        y_pred = identity_activation(np.dot(X, theta))
        
        # 计算损失函数值
        J = mse_loss(y, y_pred)
        J_history.append(J)
        
        # 计算梯度
        gradient = np.dot(X.T, (y_pred - y)) / m
        
        # 更新参数
        theta = theta - alpha * gradient
    
    return theta, J_history

# 初始化模型参数
theta = np.random.randn(2, 1)

# 设置超参数
alpha = 0.01  # 学习率
num_iters = 1000  # 迭代次数

# 调用批量梯度下降算法训练模型
theta_bgd, J_history_bgd = batch_gradient_descent(X_b, y, theta, alpha, num_iters)

# 输出优化后的模型参数
print("优化后的模型参数 theta:", theta_bgd)

# 可视化损失函数值的变化
plt.plot(range(num_iters), J_history_bgd)
plt.xlabel('Iterations')
plt.ylabel('Cost Function (MSE)')
plt.title('Batch Gradient Descent')
plt.show()

执行结果:

 

 

五、总结 

通过今天的学习,我们对梯度下降算法及其在神经网络训练中的应用有了更深入的理解,也了解了一些常见的梯度优化算法的原理和特点。总之,我们深入探讨了梯度下降法,这是一种常用的优化算法。它的核心思想是根据目标函数的梯度方向,逐步向最陡峭的下降方向移动,以最小化目标函数。我们学习了批量梯度下降法、随机梯度下降法和小批量梯度下降法三种形式,并了解了它们各自的优缺点和应用场景。

最后,创作不易!非常感谢大家的关注、点赞、收藏、评论啦!谢谢四连哦!好人好运连连,学习进步!工作顺利哦! 

  • 58
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 32
    评论
深度学习之卷积神经网络(CNN)详解与代码实现(一) 卷积神经网络(CNN)是深度学习领域中应用广泛的一种神经网络,它通过卷积、池化等操作,能够有效地处理图像、语音、文本等数据类型。本文将从卷积神经网络的基本原理、结构、训练方法等方面进行详细介绍,并通过代码实现,加深读者对卷积神经网络的理解。 一、卷积神经网络的基本原理 卷积神经网络(CNN)的基本原理是通过卷积操作对输入数据进行特征提取,然后通过全连接层对特征进行分类或回归。卷积操作是CNN的核心,它可以有效地减少网络中的参数数量,提高模型的泛化能力。 卷积操作是指将一个卷积核(kernel)与输入数据进行卷积运算,得到一个特征图(feature map)。卷积核是一个小的矩阵,可以通过学习得到,它的作用是对输入数据进行特征提取。卷积操作可以提取出输入数据中的局部特征,不同的卷积核可以提取出不同的特征,从而实现对输入数据的特征提取。 二、卷积神经网络的结构 卷积神经网络的结构包括卷积层、池化层、全连接层等。其中卷积层和池化层是CNN的核心,全连接层用于分类或回归。 1. 卷积层 卷积层是CNN中最重要的层之一,它的作用是对输入数据进行特征提取。卷积层的参数包括卷积核的大小、深度、步长等,其中卷积核的大小和深度是最重要的参数。 卷积层的输入是一个四维张量,分别表示样本数量、图像高度、图像宽度、图像通道数。卷积核是一个三维张量,分别表示卷积核的高度、宽度、深度。 卷积操作可以通过矩阵乘法实现,也可以通过FFT等方法实现,但是前者的方法在卷积核较小时速度较慢,后者在卷积核较大时速度较慢。 2. 池化层 池化层是CNN中另一个重要的层,它的作用是对卷积层的输出进行降维和特征提取。池化操作可以通过最大池化、平均池化等方法实现。最大池化是指在一个池化区域内选取最大的值作为池化结果,平均池化是指在一个池化区域内取平均值作为池化结果。 池化操作可以有效地减少数据的大小,提高模型的泛化能力。但是需要注意的是,过度的池化会导致信息的丢失,从而影响模型的性能。 3. 全连接层 全连接层是CNN中的最后一层,它的作用是将卷积层和池化层的输出进行分类或回归。全连接层是一个标准的神经网络,其中每个神经元都与前一层的所有神经元相连。 全连接层的输出可以通过softmax函数进行分类,也可以通过线性函数进行回归。 三、卷积神经网络的训练方法 卷积神经网络的训练方法与其他神经网络类似,主要包括前向传播和反向传播两个过程。前向传播是指将输入数据通过卷积层、池化层、全连接层等一系列操作,得到最终的输出结果。反向传播是指将输出结果与真实标签进行比较,然后通过梯度下降等方法,不断调整网络参数,使得输出结果更加接近真实标签。 在训练过程中,需要注意的是,卷积神经网络通常需要较长的训练时间和大量的训练数据,以便得到更好的性能。此外,还需要注意选择适当的优化算法、学习率、正则化等参数,以避免过拟合和欠拟合等问题。 四、代码实现 下面是一个简单的卷积神经网络的代码实现,用于对手写数字进行分类。 ```python import tensorflow as tf # 加载数据 mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() # 数据预处理 x_train, x_test = x_train / 255.0, x_test / 255.0 # 定义模型 model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)), tf.keras.layers.MaxPooling2

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序小勇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值