pytorch作为现在特别热的深度学习框架,很多小伙伴想入门pytorch框架,训练过程中,训练参数设置尤为重要,下文主要介绍pytorch模型保存及学习率调整。
我这里先截取一段keras训练参数,供熟练keras框架的学习者参考,便于与pytorch做比对。
logging = TensorBoard(log_dir="logs")
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, verbose=1)
checkpoint = ModelCheckpoint('logs/ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',
monitor='val_loss', save_weights_only=True, save_best_only=True, period=1)
early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=8, verbose=1)
model.fit_generator(
gen.generate(True),
steps_per_epoch=max(1, num_train//BATCH_SIZE),
validation_data=gen.generate(False),
validation_steps=max(1, num_val//BATCH_SIZE),
epochs=Freeze_Epoch,
verbose=1,
initial_epoch=Init_Epoch ,
callbacks=[logging, checkpoint, reduce_lr, early_stopping]
)
这里面有些参数的具体介绍就不细说了,市面上很多介绍,可以随自己要做的任务进行设置,去调参。
如果每隔1个epoch都保存的话,硬盘空间会不够,也显得很冗余,所以要进行恰当的模型保存设置。
隔对应epoch间隔保存,以下代码是100个epoch保存一次
if epoch % 100 == 0:
torch.save(net.state_dict(),'%d.pth' % (epoch))
只保存验证集上损失最小的时候的模型,精度最高模型保存
min_loss = 1000000#随便设置一个比较大的数
for epoch in range(epochs):
train()
val_loss = val()
if val_loss < min_loss:
min_loss = val_loss
print("save model")
torch.save(net.state_dict(),'model.pth')
1.等间隔调整
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size = 20, gamma = 0.1, last_epoch=-1)
for epoch in range(60):
scheduler.step()
train()
代码中我们使用的是SGD梯度下降优化算法,实际项目中使用Adam等算法也是可以的。其中gamma为调整倍数,20指的是调整的间隔,即0-20、21-40、41-60epoch内的学习率分别为0.001、0.0001、0.00001.
last_epoch为上一个epoch数,一般默认为-1初始值。如果需要断点续训,则将其改为续接的点的epoch。
2.按需间隔调整
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones = [30, 60], gamma = 0.1, last_epoch=-1)
for epoch in range(100):
scheduler.step()
train()
其中0-30,30-60,60-100个epoch学习率分别是0.001,0.0001,0.00001。
3.指数衰减调整
其调整方式为学习率=上一epoch的学习率*gamma^epoch
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma = 0.1, last_epoch=-1)
for epoch in range(100):
scheduler.step()
train()
4.余弦退火调整
以余弦函数的周期为周期,在每个周期的最大值时重新设置学习率,初始学习率为最大学习率,以2*T_max为周期,周期内先下降后上升。
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max = 10, eta_min=0, last_epoch=-1)
for epoch in range(100):
scheduler.step()
train()
T_max个epoch之后重新设置学习率
eta_min为最小学习率,即周期内学习率最小下降的下限,默认为0。
5.自适应调整学习率`
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, verbose=False, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08)
for epoch in range(100):
train()
val_loss = val()
scheduler.step(val_loss)
这种方式较为复杂,是当某些指标不再发生变化时使用的策略,如损失函数和精度等。
要注意的是,scheduler.step(val_loss)需要定义一个参数,即需要衡量的指标,一般选择验证集上的损失大小。
这样看起来似乎这样的学习率调整方式是最好的,但是在实际应用中可能也会存在很多问题,比如当patience太小的时候,学习率很快就会下降到最小值。这是因为就算是在合适的学习率时损失函数依然会存在一定时间的不下降的情况,不会一直下降的,所以patience的大小不应该设置的太小。
6.自定义学习率调整
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1)
for epoch in range(100):
scheduler.step()
train()
lr_lambda为函数,学习率=初始学习率*lr_lambda(last_epoch)
本来logging,early_stopping等参数设置也该介绍的,但不像学习率调整那样情况比较多,这里就先不介绍了。这些训练参数设置其实很多情况都要看大家针对不同的项目类型,依托自己丰富的项目经验进行设置,也不是很难,做的多就知道大概应该如何去设置,去调参。