前言:
当我们训练神经网络时,我们需要调整模型的参数,使得损失函数的值逐渐减小,从而优化模型。但是模型的参数我们一般是无法看见的,所以我们必须学会对参数的更新,下面,我将介绍两种参数更新的方法
下面以梯度下降法为例进行展示:
在PyTorch中,模型的参数是通过torch.nn.Parameter类来表示的,并存储在模型的parameters()方法返回的迭代器中。
for param in models.parameters():param.data -= param.grad.data * lr
- 我们遍历模型models中的每个参数,通过
param.data
来访问参数的值,即参数的张量。在训练过程中,通过反向传播计算得到每个参数的梯度,这些梯度存储在param.grad.data
中。梯度表示损失函数关于参数的变化率,通过更新参数,我们期望能够朝着损失函数下降的方向调整参数值。- 学习率
lr
是梯度下降法的超参数,它决定了每次更新参数的步幅。在梯度下降中,我们通过梯度与学习率的乘积来更新参数的值。这个操作使得参数朝着损失函数下降最快的方向更新,从而优化模型。
torch.optim是PyTorch中用于实现优化算法的模块。它提供了多种常用的优化器,可以用于自动调整模型参数以最小化损失函数,从而实现神经网络的训练。
优化器的作用是根据模型的梯度信息来更新模型的参数,以最小化损失函数。在神经网络的训练过程中,优化器会不断地调整参数值,使得模型的预测结果与真实标签更接近,从而提高模型的性能。
torch.optim模块提供了许多优化器,常见的包括:
- SGD(Stochastic Gradient Descent,随机梯度下降):每次迭代使用单个样本计算梯度,更新模型参数。是最经典的优化算法之一。
- Adam(Adaptive Moment Estimation,自适应矩估计):结合了动量法和RMSprop方法,并进行了参数的偏差校正。在深度学习中广泛使用,通常能够快速收敛。
- RMSprop(Root Mean Square Propagation,均方根传播):调整学习率来适应不同的参数。
- Adagrad(Adaptive Gradient Algorithm,自适应梯度算法):对每个参数使用不同的学习率,以适应不同参数的更新频率。
- Adadelta:是对Adagrad的扩展,使用了更稳定的学习率。
- AdamW:是对Adam优化器的改进版本,添加了权重衰减。
使用torch.optim优化器的基本流程是:
- 定义神经网络模型。
- 定义损失函数。
- 创建优化器对象,将模型的参数传递给优化器。
- 在每个训练迭代中,执行以下步骤:
a. 前向传播计算预测值。
b. 计算损失函数。
c. 将优化器的梯度清零。
d. 反向传播计算梯度。
e. 使用优化器来更新模型参数。
import torch
from torch.optim import SGD# ... 定义模型和其他训练相关的代码 ...# 定义优化器
optimizer = SGD(models.parameters(), lr=lr) #传入参数(参数和梯度),超参数(学习率)
# 迭代进行训练
for epoch in range(epoch_n):y_pred = models(x) # 前向传播,计算预测值loss = loss_fn(y_pred, y) # 计算均方误差损失if epoch % 1000 == 0:print("epoch:{}, loss:{:.4f}".format(epoch, loss.item()))optimizer.zero_grad() # 将模型参数的梯度清零,避免梯度累积loss.backward() # 反向传播,计算梯度optimizer.step() # 使用优化器来自动更新模型参数
完整演示
import torch
import torch.nn as nn
import torch.optim as optim# 定义神经网络模型
class SimpleModel(nn.Module):def __init__(self):super(SimpleModel, self).__init__()self.fc = nn.Linear(2, 1)def forward(self, x):return self.fc(x)# 定义训练数据和目标数据
x_train = torch.tensor([[1.0, 2.0], [2.0, 3.0], [3.0, 4.0]], dtype=torch.float32)
y_train = torch.tensor([[3.0], [5.0], [7.0]], dtype=torch.float32)# 创建神经网络模型和损失函数
model = SimpleModel()
loss_fn = nn.MSELoss()# 创建优化器对象,将模型参数传递给优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)# 定义训练轮数
epochs = 1000# 训练过程
for epoch in range(epochs):# 前向传播y_pred = model(x_train)# 计算损失函数loss = loss_fn(y_pred, y_train)# 将优化器的梯度缓存清零optimizer.zero_grad()# 反向传播loss.backward()# 使用优化器来更新模型参数optimizer.step()if epoch % 100 == 0:print(f"Epoch {epoch}, Loss: {loss.item()}")# 在训练完成后,可以使用训练好的模型来进行预测
x_new = torch.tensor([[4.0, 5.0], [5.0, 6.0]], dtype=torch.float32)
with torch.no_grad():y_pred_new = model(x_new)print("Predictions for new data:")print(y_pred_new)