将下面这段代码进行完善并加入当每隔50个epoch最佳准确率不改变时候更新学习率的部分import torchimport torchvisionmodels as modelsfrom torchutils import datafrom torch import nnfrom torch import optimimport numpy as npimport argparsefrom dat
下面是完善并加入学习率更新部分的代码:
from torch.optim.lr_scheduler import ReduceLROnPlateau
# 设置ReduceLROnPlateau学习率调度器
scheduler = ReduceLROnPlateau(optimizer, mode='max', factor=0.5, patience=10, verbose=True)
best_accuracy = 0.0 # 保存最佳模型的准确率
best_epoch = 0
no_improve_count = 0 # 记录连续没有提升的epoch次数
for epoch in range(args.epochs):
model.train()
# 遍历训练集数据
for imgs, labels in my_datalodaer:
steps += 1
labels = torch.tensor(labels, dtype=torch.long)
imgs, labels = imgs.to(DEVICE), labels.to(DEVICE)
optimizer.zero_grad() # 梯度归零
outputs = model(imgs)
loss = loss_fn(outputs, labels)
loss.backward() # 反向传播计算梯度
optimizer.step() # 梯度优化
running_loss += loss.item()
if steps % count == 0:
test_loss = 0
accuracy = 0
model.eval()
with torch.no_grad():
# 遍历测试集数据
for imgs, labels in test_dl:
labels = torch.tensor(labels, dtype=torch.long)
imgs, labels = imgs.to(DEVICE), labels.to(DEVICE)
outputs = model(imgs)
loss = loss_fn(outputs, labels)
test_loss += loss.item()
ps = torch.exp(outputs)
top_p, top_class = ps.topk(1, dim=1)
equals = top_class == labels.view(*top_class.shape)
accuracy += torch.mean(equals.type(torch.FloatTensor)).item()
train_losses.append(running_loss / len(train_dl))
test_losses.append(test_loss / len(test_dl))
if steps % (int(50)) == 0:
print(
f"Epoch {epoch + 1}/{args.epochs}.. "
f"Train loss: {running_loss / count:.3f}.. "
f"Test loss: {test_loss / len(test_dl):.3f}.. "
f"Test accuracy: {accuracy / len(test_dl):.3f}")
running_loss = 0
model.train()
if accuracy > best_accuracy:
best_accuracy = accuracy
best_epoch = epoch
torch.save(model, "Direction_model.pth")
no_improve_count = 0
else:
no_improve_count += 1
if no_improve_count >= 50:
# 更新学习率
scheduler.step(best_accuracy)
if optimizer.param_groups[0]['lr'] < 1e-6:
# 学习率过小,停止训练
print("Learning rate too small, training stopped.")
break
no_improve_count = 0
print("Training completed.")
在上述代码中,首先引入了ReduceLROnPlateau学习率调度器,它会在每隔一定的epoch中检查模型的准确率是否有提升,如果没有提升,则会将学习率降低一定的倍数(通过factor参数指定)。在代码中使用mode='max'表示要寻找准确率的最大值,patience参数表示连续多少个epoch没有提升时才进行学习率更新。当学习率更新后,会重置no_improve_count计数器为0。
在代码中添加了best_epoch变量来记录最佳准确率对应的epoch,以便在保存最佳模型时使用。
最后,在每个epoch结束后,增加了判断no_improve_count是否达到50的条件,如果达到,则调用scheduler.step(best_accuracy)来更新学习率,并重置no_improve_count为0。如果学习率小于1e-6,则认为学习率过小,停止训练
原文地址: https://www.cveoy.top/t/topic/hL5G 著作权归作者所有。请勿转载和采集!