接下来小编来讲一下一些优化器在线性问题中的简单使用使用,torch模块中有一个叫optim的子模块,我们可以在其中找到实现不同优化算法的类
SGD随机梯度下降
基本概念
- 定义:随机梯度下降(SGD)是一种梯度下降形式,对于每次前向传递,都会从总的数据集中随机选择一批数据,即批次大小1。
- 参数更新过程:这个参数的更新过程可以描述为随机梯度下降法,随机梯度下降(SGD)是一种简单但非常有效的方法,多用于支持向量机,逻辑回归(LR)等凸损失函数下的线性分类器的学习3。
实现步骤
- 随机抽样:从总的数据集中随机抽样一批数据1。
- 计算梯度:前向和后向运行网络,计算梯度(根据抽样的数据)1。
- 应用更新:应用梯度下降更新1。
- 重复循环:重复上述步骤,直到出现收敛情况或者循环被其他机制暂停(即迭代次数)1。
特点与优势
- 提高训练速度:随机梯度下降算法可以使用一小部分样本来计算梯度,从而大大提高了训练速度和鲁棒性3。
- 更快收敛:相比于批量梯度,这样的方法更快收敛,因此使用也比较广泛4。
import numpy as np import torch torch.set_printoptions(edgeitems=2, linewidth=75) # 设置打印格式 # 初始化参数 t_c = torch.tensor([0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0]) t_u = torch.tensor([35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4]) t_un = 0.1 * t_u # 归一化处理,防止梯度爆炸 def model(t_u, w, b): return w * t_u + b def loss_fn(t_p, t_c): squared_diffs = (t_p - t_c)**2 return squared_diffs.mean() import torch.optim as optim # 导入优化器模块 # dir(optim) ''' params = torch.tensor([1.0, 0.0], requires_grad=True) # 创建一个params张量 learning_rate = 1e-5 # 学习率 optimizer = optim.SGD([params], lr=learning_rate) # 定义了一个使用随机梯度下降(Stochastic Gradient Descent, SGD) # 算法的优化器,并设置了学习率''' params = torch.tensor([1.0, 0.0], requires_grad=True) learning_rate = 1e-2 optimizer = optim.SGD([params], lr=learning_rate) t_p = model(t_u, *params) loss = loss_fn(t_p, t_c) optimizer.zero_grad() loss.backward() optimizer.step() # 用于更新模型参数的一个关键函数 通常在每个训练迭代(epoch)中调用一次, # 以根据损失函数的梯度调整模型的权重和偏置,从而最小化损失函数。 def training_loop(n_epochs, optimizer, params, t_u, t_c): for epoch in range(1, n_epochs + 1): t_p = model(t_u, *params) loss = loss_fn(t_p, t_c) optimizer.zero_grad() loss.backward() optimizer.step() if epoch % 500 == 0: print('Epoch %d, Loss %f' % (epoch, float(loss))) return params training_loop( n_epochs = 5000, optimizer = optimizer, params = params, t_u = t_un, t_c = t_c)
运行结果如下
可以明显看出来,SGD的损失值下降还是非常快速的,收敛非常快
Adam优化器
Adam是一个更加复杂的优化器,其中学习率是自适应设置的,此外,它对参数的缩放不太敏感,我们可以不对数据进行归一化处理,甚至可以把学习率设置为1e-1
上面的代码的函数保持不变,我们只需要修改优器的选择就行
Adam 优化器(自适应矩估计优化器)
基本概念
Adam 优化器是一种自适应学习率的优化算法,结合了动量梯度下降和 RMSprop 算法的思想。它通过自适应地调整每个参数的学习率,从而在训练过程中加速收敛。1 2
使用方法
- 初始化参数:首先需要初始化 Adam 优化器的参数,包括学习率、动量因子、指数衰减率等。这些参数的选择通常需要经验和实验来确定。3
- 计算梯度:在每个训练迭代中,需要计算损失函数对各个参数的梯度。这可以通过反向传播算法来实现。3
- 更新参数:使用 Adam 优化器的更新公式来更新模型的参数。Adam 优化器的更新公式包括两个主要的步骤:计算梯度的一阶矩估计和二阶矩估计,然后将它们结合起来对参数进行更新。3
- 调整学习率:在训练过程中,可以根据需要动态调整学习率。例如,可以使用学习率衰减策略来提高模型在训练后期的稳定性和泛化能力。3
相关技巧和注意事项
- 参数调节:不同的问题可能适合不同的 Adam 优化器参数设置。可以通过尝试不同的参数组合来找到最佳的性能。3
- 正则化:在使用 Adam 优化器时,可以结合正则化技术来降低模型的过拟合风险。例如,可以使用 L1 正则化或 L2 正则化来约束模型的复杂度。3
- 批量归一化:在深度学习中,批量归一化是一种常用的技术,它可以加速训练过程并提高模型的泛化能力。可以在使用 Adam 优化器时结合批量归一化技术来进一步优化模型。3
总之,Adam 优化器是一种强大而灵活的优化算法,在机器学习和深度学习任务中广泛应用。
这里有个小问题,Adam优化器被称为自适应优化器,可是为什么还需要设置一个学习率呢,其实这两者之间并不矛盾
它根据参数的更新历史来调整每个参数的学习率。尽管Adam具有自适应的特性,但在使用时仍然需要设置一个全局的学习率(也称为初始学习率或基础学习率)。这个全局学习率对Adam的优化过程有重要影响,它控制着参数更新的总体规模。
Adam优化器会根据参数的梯度、梯度的平方以及参数的更新历史来计算每个参数的自适应学习率。然而,这个自适应学习率是在全局学习率的基础上进行调整的。如果全局学习率设置得太高,可能会导致参数更新过大,进而使模型变得不稳定;如果全局学习率设置得太低,则可能导致模型训练过慢,无法有效收敛。
因此,在使用Adam优化器时,仍然需要谨慎选择全局学习率,以确保模型能够稳定且有效地进行训练。在实际应用中,通常会通过实验来调整全局学习率,以找到最适合当前任务和学习数据的值。
# Adam优化器
params = torch.tensor([1.0, 0.0], requires_grad=True)
learning_rate = 1e-1
optimizer = optim.Adam([params], lr=learning_rate) # <1>
training_loop(
n_epochs = 5000,
optimizer = optimizer,
params = params,
t_u = t_u, # <2>
t_c = t_c
可以看到,这里传入的参数不再是归一化后的t_un,而是原始的数据t_u,可见Adam优化器确实对参数的缩放不太敏感,那我们来看看训练的效果吧
对比前面的SGD,Adam的效果也不差,所以在实际情况中还需要选择适合自己模型的优化器,选择正确的优化器可以显著提高模型的训练效果和收敛速度