sgd学习率选择问题
关于使用SGD时如何选择初始的学习率(这里SGD是指带动量的SGD,momentum=0.9):
训练一个epoch,把学习率从一个较小的值(10-8)上升到一个较大的值(10),画出学习率(取log)和经过平滑后的loss的曲线,根据曲线来选择合适的初始学习率。
从上图可以看出学习率和loss之间的关系,最曲线的最低点的学习率已经有了使loss上升的趋势,曲线的最低点不选。最低点左边的点都是可供选择的点,但是选择太小的学习率会导致收敛的速度过慢,所以根据上图我们可以选择0.01(10-2)为初始的学习率。
关于学习率的调整策略,在使用SGD时不建议使用指数型连续下降的调节方法,建议使用阶梯式调节学习率的方法。每隔一定数量的epoch学习率调节为之前的0.1倍(根据自己实际任务调节每个阶段迭代epoch的数量)。
如果不想使用上述方法,这里提供几个经验值供选择,fine-tune模型初始学习率可设置为0.01,从头开始训练模型学习率可设置为0.1(仅供参考)。
供参考的寻找初始学习率的pytorch代码(根据自己的任务进行修改):
def find_lr(init_value = 1e-8, final_value=10., beta = 0.98): num = len(train_loader)-1 mult = (final_value / init_value) ** (1/num) lr = init_value optimizer.param_groups[0]['lr'] = lr avg_loss = 0. best_loss = 0. batch_num = 0 losses = [] log_lrs = [] for data in train_loader: batch_num += 1 #As before, get the loss for this mini-batch of inputs/outputs inputs,labels = data inputs, labels = Variable(inputs), Variable(labels) optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) #Compute the smoothed loss avg_loss = beta * avg_loss + (1-beta) *loss.data[0] smoothed_loss = avg_loss / (1 - beta**batch_num) #Stop if the loss is exploding if batch_num > 1 and smoothed_loss > 4 * best_loss: return log_lrs, losses #Record the best loss if smoothed_loss < best_loss or batch_num==1: best_loss = smoothed_loss #Store the values losses.append(smoothed_loss) log_lrs.append(math.log10(lr)) #Do the SGD step loss.backward() optimizer.step() #Update the lr for the next step lr *= mult optimizer.param_groups[0]['lr'] = lr return log_lrs, losses
参考论文《Cyclical Learning Rates for Training Neural Networks》
和博客https://sgugger.github.io/how-do-you-find-a-good-learning-rate.html
C/C++基本语法学习
STL
C++ primer