學習率策略之 burn-in


darknet的cfg文件中有一個配置參數: burn_in

burn_in=1000

這個參數在caffe中是沒有的,一旦設置了這個參數,當update_num小於burn_in時,不是使用配置的學習速率更新策略,而是按照下面的公式更新

lr = base_lr * power(batch_num/burn_in,pwr)

其背后的假設是:全局最優點就在網絡初始位置附近,所以訓練開始后的burn_in次更新,學習速率從小到大變化。update次數超過burn_in后,采用配置的學習速率更新策略從大到小變化,顯然finetune時可以嘗試。
————————————————
版權聲明:本文為CSDN博主「z0n1l2」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/z0n1l2/article/details/82959455

darknet-yolov3 burn_in learning_rate policy


 

darknet-yolov3中的learning_rate是一個超參數,調參時可通過調節該參數使模型收斂到一個較好的狀態。

在cfg配置中的呈現如下圖:

我這里隨便設了一個值。

接下來說一下burn_in和policy.

這兩者在代碼中的呈現如下所示:

float get_current_rate(network *net)
{
    size_t batch_num = get_current_batch(net);
    int i;
    float rate;
    if (batch_num < net->burn_in)  //當batch_num小於burn_in時,返回如下learning_rate
      return net->learning_rate * pow((float)batch_num / net->burn_in, net->power);   
    switch (net->policy) {//當大於burn_in時,按如下方式,原配值中給的是STEPS
        case CONSTANT:
            return net->learning_rate;
        case STEP:
            return net->learning_rate * pow(net->scale, batch_num/net->step);
        case STEPS:
            rate = net->learning_rate;     for(i = 0; i < net->num_steps; ++i){
                if(net->steps[i] > batch_num) return rate;
                rate *= net->scales[i];
            }
            return rate;
        case EXP:
            return net->learning_rate * pow(net->gamma, batch_num);
        case POLY:
            return net->learning_rate * pow(1 - (float)batch_num / net->max_batches, net->power);
        case RANDOM:
            return net->learning_rate * pow(rand_uniform(0,1), net->power);
        case SIG:
            return net->learning_rate * (1./(1.+exp(net->gamma*(batch_num - net->step))));
        default:
            fprintf(stderr, "Policy is weird!\n");
            return net->learning_rate;
    }
}

這里我做了一些調整。

調整依據是:發現自己設置的學習率和burn_in結束時的學習率總是有很大差異,造成loss變化出現停滯,或者劇烈抖動。

調整辦法:讓steps的起始學習率=burn_in結束時的學習率。

實現如下:

float last_rate;
float get_current_rate(network *net)
{
    size_t batch_num = get_current_batch(net);
    int i;
    float rate;
    if (batch_num < net->burn_in)
    {
      /******************************************************/
      last_rate = net->learning_rate * pow((float)batch_num / net->burn_in, net->power);
      /*****************************************************/
      return net->learning_rate * pow((float)batch_num / net->burn_in, net->power);
    }
    switch (net->policy) {
        case CONSTANT:
            return net->learning_rate;
        case STEP:
            return net->learning_rate * pow(net->scale, batch_num/net->step);
        case STEPS:
            //rate = net->learning_rate;
           rate = last_rate;
            for(i = 0; i < net->num_steps; ++i){
                if(net->steps[i] > batch_num) return rate;
                rate *= net->scales[i];
            }
            return rate;
        case EXP:
            return net->learning_rate * pow(net->gamma, batch_num);
        case POLY:
            return net->learning_rate * pow(1 - (float)batch_num / net->max_batches, net->power);
        case RANDOM:
            return net->learning_rate * pow(rand_uniform(0,1), net->power);
        case SIG:
            return net->learning_rate * (1./(1.+exp(net->gamma*(batch_num - net->step))));
        default:
            fprintf(stderr, "Policy is weird!\n");
            return net->learning_rate;
    }
}

原文地址:https://www.codeprj.com/blog/b9a0f01.html


YOLOv3官方版本的學習率配置信息在模型配置文件 *.cfg file 中:

learning_rate: 標准學習率
burn_in: 學習率從 0 上升到 learning_rate 的 batch 數目
max_batches: 需要進行訓練的 batch 數目
policy: 學習率調度的策略
steps: 在何處進行學習率衰減
scales: 學習率進行衰減的倍數


這個YOLO關於學習率調度的的代碼設置在 train.py 中,設置標准學習率和最終的學習率分別為參數hyp['lr0'] 和 hyp['lrf'],其中最終的學習率 final LR = hyp['lr0'] * (10 ** hyp['lrf'])。例如,標准學習率 hyp['lr0']  = 0.001, hyp['lrf'] = -2,因此 final LR = 0.00001.下面這張圖顯示了Pytorch中的兩個常用的學習率調度方法。其中YOLO原版采用的是  MultiStepLR scheduler。我們可以根據自己需要對學習率進行調整。

 

 

 

YOLO會對前面1000個batch進行學習率warm up:

# SGD burn-in
if epoch == 0 and i <= n_burnin:
lr = hyp['lr0'] * (i / n_burnin) ** 4
for x in optimizer.param_groups:
x['lr'] = lr

 

 


不過代碼里默認是注釋掉了,如果使用的話需要打開以下

 
————————————————
版權聲明:本文為CSDN博主「松菇」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/songwsx/article/details/102656935

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM