官方文档中的优化器的举例
for input, target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
每行代码的含义
-
optimizer.zero_grad()
- 清除上一次计算的梯度,确保当前的梯度计算是基于本次数据的。
-
output = model(input)
- 将输入
input
传入模型,得到预测输出output
。
- 将输入
-
loss = loss_fn(output, target)
- 计算预测结果
output
与实际标签target
之间的损失,用损失函数loss_fn
来衡量。
- 计算预测结果
-
loss.backward()
- 进行反向传播,计算损失对模型参数的梯度,存储在各参数的
grad
属性中。
- 进行反向传播,计算损失对模型参数的梯度,存储在各参数的
-
optimizer.step()
- 根据计算的梯度,使用优化器更新模型参数。
在实际开发中的应用
在深度学习模型训练中,优化器用于更新模型参数,使得损失(误差)逐步减小。例如,在图像分类任务中,模型会不断更新参数,使得预测结果更接近真实标签,提高分类准确率。
在示例中,CIFAR-10 是一个包含 10 类图片的常用数据集,每张图片都带有一个标签(target),用来表示图片的类别(如飞机、汽车、鸟等)。其中:
-
input
:是图片数据,表示模型的输入,即dataloader
中imgs
的部分。 -
target
:是标签数据,表示每张图片所属的真实类别,用于训练时的对比,帮助模型进行分类学习。
为什么要将 grad
设为 0?
grad
是模型参数的梯度(偏导数),表示损失函数相对于各个参数的变化率。
每次反向传播时,梯度会累积(因为 PyTorch 的默认行为是累加梯度)。如果不清除旧的梯度,每次计算的新梯度会与之前的叠加,导致更新的方向不准确。通过 optimizer.zero_grad()
将梯度清零,可以确保每次更新只考虑当前批次的数据计算得到的梯度,从而使训练过程更加稳定。
result_loss.backward()
和 optim.step()
的作用
-
result_loss.backward()
:计算损失result_loss
对模型参数的梯度,并将梯度存储在每个参数的grad
属性中。 -
optim.step()
:根据梯度信息,优化器调整模型参数,使得损失逐步减小。
这两行代码的作用是完成反向传播和参数更新,是训练模型的核心步骤。
代码的功能、 loss
的作用,及 loss
增大的原因
视频中代码的功能是对模型进行训练,并计算并输出每个 epoch 的累积损失。loss
表示模型输出和目标标签之间的差距,越小表示模型表现越好。
target
在代码中的作用
在训练过程中,模型会对 input
做出预测,生成一个输出(预测的类别)。我们用 target
来计算预测结果和真实标签之间的损失(误差),这个损失会作为训练信号传回去,指导模型如何调整参数,使得模型的预测更接近真实标签。
优化器的作用
优化器的作用是根据损失值loss来调整模型的参数,使得预测结果逐步接近真实标签。具体来说,优化器根据 反向传播 得到的每个参数的 梯度 来更新参数。更新的方式通常遵循以下公式:
新参数=旧参数−学习率×梯度
每次迭代时:
- 计算损失(loss):通过模型的预测结果和真实标签计算损失。
- 计算梯度(backward):通过反向传播得到损失对各参数的梯度。
- 参数更新(optimizer.step()):优化器根据这些梯度和设定的学习率,更新每个参数的值。
loss
增大的原因
在代码运行中,我发现 loss
越来越大,这可能有以下原因:
-
学习率过大:如果学习率设置过大,参数更新的步伐太大,可能会导致模型“跳过”最优解,导致
loss
持续增加。可以尝试将学习率调小。 -
数据或标签问题:检查数据和标签是否正确匹配,如果标签错误,也会导致
loss
不收敛。 - 初始化问题:如果模型参数初始化不合理,可能导致不稳定的训练。
可以通过调整学习率、检查数据等手段来排查和解决 loss
增大的问题。
将lr调节为0.001后,loss的确越来越小了