如何从头开始实现随机梯度下降和完整的训练循环

37 min read
  1. 实现随机梯度下降

随机梯度下降是优化深度学习模型的基本算法之一。在每次迭代中,它使用一个随机小批量的训练数据来更新模型参数。

下面是一个从头开始实现随机梯度下降的示例代码:

import numpy as np

def sgd(w, dw, lr):
    """
    实现随机梯度下降算法
    :param w: 权重参数
    :param dw: 权重参数的梯度
    :param lr: 学习率
    :return: 更新后的权重参数
    """
    w -= lr * dw
    return w

该代码使用了 NumPy 库来实现矩阵和向量的操作, w 是当前的权重参数,dw 是对应的梯度, lr 是学习率。该函数返回更新后的权重参数。

  1. 实现完整的训练循环

训练深度学习模型一般需要进行多次迭代,每次迭代都是使用随机梯度下降来更新模型参数,直到收敛。下面是一个从头开始实现完整的训练循环的示例代码:

def train(X, y, lr, num_epochs):
    """
    完整的训练循环
    :param X: 训练数据
    :param y: 训练标签
    :param lr: 学习率
    :param num_epochs: 迭代次数
    :return: 更新后的权重参数
    """
    # 初始化权重参数为随机值
    W = np.random.randn(X.shape[1])

    # 迭代更新权重参数
    for epoch in range(num_epochs):
        # 随机打乱训练数据
        idx = np.random.permutation(X.shape[0])
        X = X[idx]
        y = y[idx]

        # 遍历每个小批量数据
        for i in range(0, X.shape[0], batch_size):
            # 获取当前小批量数据及对应标签
            X_batch = X[i:i+batch_size]
            y_batch = y[i:i+batch_size]

            # 前向传播
            y_pred = np.dot(X_batch, W)

            # 计算损失函数并输出当前损失值
            loss = np.mean((y_pred - y_batch) ** 2)
            print("Epoch {}: loss = {}".format(epoch, loss))

            # 反向传播获取权重参数梯度
            dw = np.mean(2 * (y_pred - y_batch)[:, None] * X_batch, axis=0)

            # 使用随机梯度下降更新权重参数
            W = sgd(W, dw, lr)

    return W

该代码接受训练数据 X 和训练标签 y,以及学习率 lr 和迭代次数 num_epochs。它首先随机初始化权重参数 W,然后使用随机梯度下降来更新权重参数。每次更新时,它从训练数据中随机选取一小批量数据(大小为 batch_size),计算该小批量数据的损失函数和梯度,并使用随机梯度下降来更新权重参数。每迭代一次,输出当前迭代次数和损失函数。

注意,这是一个非常简单的示例,实际中可能需要进行更多的优化和改进。例如,可以添加正则化、动量等方法来提高模型性能;同时,还需要对模型的超参数(如学习率)进行调整,以获得更好的训练效果。