1. 学习率衰减
这是之前在实习的时候进行的图像处理课题提供的思路。
学习率衰减策略可以实现两个目的:在训练初期较高的学习率使得网络模型更快的梯度下降,训练后期较小的学习率使得算法更容易收敛到最优值。
1.1 自定义指数衰减算法
D e c a y e d L e a r n i n g R a t e = L e a r n i n g R a t e ∗ D e c a y R a t e G l o b a l S t e p / D a c a y S t e p s DecayedLearningRate = LearningRate*DecayRate^{GlobalStep/DacaySteps} DecayedLearningRate=LearningRate∗DecayRateGlobalStep/DacaySteps
其中,
LearningRate是设定的初始学习率;
DecayRate是衰减比率,一般略小于1.0;
DacaySteps是衰减学习率的间隔次数;
GlobalStep是当前的迭代次数;
另外在算法中引入了warm up 机制。
Warm up 预热:
在初始warm_up_step训练中保持一个较大的学习率,以便模型尽快适应数据,当模型趋于稳定之后在按照设定的学习率进行训练:
当step<warm_up_step时,lr = 0.1lr + (lr-0.1lr)(step/warm_up_step) ,
当step>warm_up_step时,lr = decayed_learning_rate 。
def self_adjust_learning_rate(optimizer, train_sum):
optimizer.step()
warm_up_step = int(EPOCHS * warm_up)
if train_sum < warm_up_step:
lr = 0.1 * LR + (LR - 0.1 * LR) / warm_up_step * train_sum
else:
lr = LR * (decay_rate ** ((train_sum - warm_up_step) // decay_steps))
for param_group in optimizer.param_groups:
param_group["lr"] = lr
return lr
lr = self_adjust_learning_rate(optimizer, epoch) # 自定义学习率衰减算法
使用学习率衰减算法后:
BATCH_SIZE = 64 # 定义超参数,每次处理64张图片
DEVICE = torch.device(“cuda” if torch.cuda.is_available() else “cpu”) # 检测电脑上是否有GPU,如果有就使用GPU,如果没有就使用cpu
EPOCHS = 300 # 将数据集训练100轮
LR = 0.001 # 学习率
TRAIN_DIVISION = 3 # 训练集划分占比
warm_up = 5
decay_rate = 0.95
decay_steps = 20
这个结果0.9789是在IITD数据集上得到的,大于之前得到的最好结果 0.951316。
1.2 指数衰减函数
torch.optim.lr_scheduler中提供等间隔调整(Step)、多间隔调整(MultiStep)、指数衰减(Exponential)、余弦退火(CosineAnnealing)、自适应调整(ReduceLROnPlateau)、自定义调整(LambdaLR)等函数实现学习率的调整,参考这篇:Pytorch:学习率衰减及其用法
为了比较,选用了指数衰减函数:
def scheduler_adjust_learning_rate(optimizer, scheduler, train_sum):
warm_up_step = int(EPOCHS * warm_up)
if train_sum < warm_up_step:
optimizer.step()
lr = 0.1 * LR + (LR - 0.1 * LR) / warm_up_step * train_sum
for param_group in optimizer.param_groups:
param_group["lr"] = lr
else:
scheduler.step()
lr = scheduler.get_lr()[0]
return lr
scheduler = lr_scheduler.ExponentialLR(optimizer, gamma=decay_rate)
lr = scheduler_adjust_learning_rate(optimizer, scheduler, epoch) # 学习率衰减
但结果并不理想,也可能是我使用的方式不正确。
2打乱数据集
在划分数据集时随机划分,并改变比例:
for i, path in enumerate(PATH):
data_index = os.listdir(path)
data_size = len(data_index)
train_size = int(data_size * TRAIN_DIVISION)
train_index = random.sample(data_index, train_size)
test_index = list(set(data_index) - set(train_index))
TRAIN_DIVISION | RR |
---|---|
0.7 | 0.9565217391304348 |
0.8 | 0.9616122840690979 |
0.9 | 0.9846743295019157 |
似乎训练集占比在0.9的时候识别率最高,但考虑到IITD只有2601幅图片用于训练和测试,有可能是因为用于测试的图片较少,所以识别率相对较高。所以或许可以考虑使用数据增强扩充可供训练的数据。
3.完善代码和流程
将训练结果和相关信息输出到日志中保存,以便再次使用数据和进行对比。
保存每次训练的最优模型,在训练结束后加载模型测试随机选出的掌纹图片,记录测试单张图片的时间。