PyTorch中的9种常见梯度下降算法与案例

您所在的位置:网站首页 batch梯度下降算法 PyTorch中的9种常见梯度下降算法与案例

PyTorch中的9种常见梯度下降算法与案例

2023-06-04 17:51| 来源: 网络整理| 查看: 265

@TOC

本文将介绍PyTorch中的几种常见梯度下降算法,并提供相应的Python案例。

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

批量梯度下降是最基础的梯度下降算法,通过使用全部训练数据计算损失函数的梯度来更新参数。在PyTorch中,可以通过定义损失函数和优化器来实现批量梯度下降。

例如,在简单线性回归问题中使用批量梯度下降:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数 loss_fn = torch.nn.MSELoss() # 定义优化器和超参数 optimizer = torch.optim.SGD([w, b], lr=0.01) epochs = 100 # 批量梯度下降 for epoch in range(epochs): # 前向传播 Y_pred = w * X + b # 计算损失 loss = loss_fn(Y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 1.9999034404754639, b = 0.00041007260753999686 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

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

随机梯度下降是一种在每次更新时随机选择一个样本进行梯度计算和参数更新的梯度下降算法。相比批量梯度下降,随机梯度下降具有更快的收敛速度,但更新过程较为不稳定。在PyTorch中,可以通过定义DataLoader来实现随机梯度下降。

例如,在简单线性回归问题中使用随机梯度下降:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.SGD([w, b], lr=0.01) # 定义超参数 batch_size = 1 epochs = 100 # 随机梯度下降 for epoch in range(epochs): # 创建DataLoader loader = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(X, Y), batch_size=batch_size, shuffle=True) for x_batch, y_batch in loader: # 前向传播 y_pred = w * x_batch + b # 计算损失 loss = loss_fn(y_pred, y_batch) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 2.0002050399780273, b = -0.0005163848866038325 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

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

小批量梯度下降是介于批量梯度下降和随机梯度下降之间的梯度下降算法,即每次更新时选取一定数量的样本进行梯度计算和参数更新。在PyTorch中,可以通过定义DataLoader来实现小批量梯度下降。

例如,在简单线性回归问题中使用小批量梯度下降:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.SGD([w, b], lr=0.01) # 定义超参数 batch_size = 2 epochs = 100 # 小批量梯度下降 for epoch in range(epochs): # 创建DataLoader loader = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(X, Y), batch_size=batch_size, shuffle=True) for x_batch, y_batch in loader: # 前向传播 y_pred = w * x_batch + b # 计算损失 loss = loss_fn(y_pred, y_batch) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 1.9998304843902588, b = -0.00010240276428798664 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

4. 动量梯度下降(Momentum Gradient Descent)

动量梯度下降是一种在梯度下降更新过程中加入动量项的优化算法,可以加速收敛并减少震荡。在PyTorch中,可以通过设置momentum参数实现动量梯度下降。

例如,在简单线性回归问题中使用动量梯度下降:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数和动量 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) momentum = 0.9 # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.SGD([w, b], lr=0.01, momentum=momentum) # 定义超参数 epochs = 100 # 动量梯度下降 for epoch in range(epochs): # 前向传播 y_pred = w * X + b # 计算损失 loss = loss_fn(y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 1.9999991655349731, b = -3.718109681471333e-05 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

5. AdaGrad

AdaGrad是一种自适应学习率的优化算法,在更新参数时根据历史梯度信息来动态调整每个参数的学习率。在PyTorch中,可以通过设置optim.Adagrad()来使用该优化器。

例如,在简单线性回归问题中使用AdaGrad:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.Adagrad([w, b], lr=0.1) # 定义超参数 epochs = 100 # AdaGrad for epoch in range(epochs): # 前向传播 y_pred = w * X + b # 计算损失 loss = loss_fn(y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 1.999985694885254, b = -0.0010528544095081096 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

6. RMSprop

RMSprop是一种自适应学习率的优化算法,在更新参数时根据历史梯度平方的加权平均来动态调整每个参数的学习率。在PyTorch中,可以通过设置optim.RMSprop()来使用该优化器。

例如,在简单线性回归问题中使用RMSprop:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.RMSprop([w, b], lr=0.01) # 定义超参数 epochs = 100 # RMSprop for epoch in range(epochs): # 前向传播 y_pred = w * X + b # 计算损失 loss = loss_fn(y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 2.000011920928955, b = -0.00020079404229614145 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

7. Adam

Adam是一种融合了动量梯度下降和自适应学习率的优化算法,在更新参数时既考虑历史梯度的加权平均又考虑历史梯度平方的加权平均。在PyTorch中,可以通过设置optim.Adam()来使用该优化器。

例如,在简单线性回归问题中使用Adam:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.Adam([w, b], lr=0.01) # 定义超参数 epochs = 100 # Adam for epoch in range(epochs): # 前向传播 y_pred = w * X + b # 计算损失 loss = loss_fn(y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 2.0000016689300537, b = -1.788223307551633e-05 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

8. AdamW

AdamW是一种基于Adam优化算法的变体,它引入了权重衰减(weight decay)来解决Adam可能存在的参数过度拟合问题。在PyTorch中,可以通过设置optim.AdamW()来使用该优化器。

例如,在简单线性回归问题中使用AdamW:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.AdamW([w, b], lr=0.01, weight_decay=0.1) # 定义超参数 epochs = 100 # AdamW for epoch in range(epochs): # 前向传播 y_pred = w * X + b # 计算损失 loss = loss_fn(y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 1.9564942121505737, b = 0.063056387424469 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

9. Adadelta

Adadelta是一种自适应学习率的优化算法,它与RMSprop相似,但引入了一个衰减系数来平衡历史梯度平方和目标函数变化量。在PyTorch中,可以通过设置optim.Adadelta()来使用该优化器。

例如,在简单线性回归问题中使用Adadelta:

import torch import matplotlib.pyplot as plt # 定义训练数据 X = torch.tensor([1, 2, 3, 4], dtype=torch.float32) Y = torch.tensor([2, 4, 6, 8], dtype=torch.float32) # 初始化模型参数 w = torch.tensor(0.0, requires_grad=True) b = torch.tensor(0.0, requires_grad=True) # 定义损失函数和优化器 loss_fn = torch.nn.MSELoss() optimizer = torch.optim.Adadelta([w, b], lr=0.1) # 定义超参数 epochs = 100 # Adadelta for epoch in range(epochs): # 前向传播 y_pred = w * X + b # 计算损失 loss = loss_fn(y_pred, Y) # 反向传播 loss.backward() # 更新参数 optimizer.step() # 清空梯度 optimizer.zero_grad() # 输出结果 print(f"w = {w.item()}, b = {b.item()}") # 绘制拟合直线 plt.scatter(X.numpy(), Y.numpy()) plt.plot(X.numpy(), (w * X + b).detach().numpy(), 'r') plt.show() 复制代码

输出:

w = 2.0000007152557373, b = 4.5047908031606675e-08 复制代码

绘制的拟合直线如下图所示:

在这里插入图片描述

以上是常见的优化算法,它们在不同的场景下表现出不同的效果。除此之外,PyTorch还支持其他优化算法,如Adagrad、Adamax等,并且用户也可以自定义优化器来满足特定需求。

本文由mdnice多平台发布



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3