1. NLP(四十三)模型調(diào)參技巧之Warmup and Decay

        共 6545字,需瀏覽 14分鐘

         ·

        2021-03-27 17:55

        ??Warmup and Decay是深度學習中模型調(diào)參的常用trick。本文將簡單介紹Warmup and Decay以及如何在keras_bert中使用它們。

        什么是warmup and decay?

        ??Warmup and Decay是模型訓練過程中,一種學習率(learning rate)的調(diào)整策略。
        ??Warmup是在ResNet論文中提到的一種學習率預熱的方法,它在訓練開始的時候先選擇使用一個較小的學習率,訓練了一些epoches或者steps(比如4個epoches,10000steps),再修改為預先設(shè)置的學習來進行訓練。
        ??同理,Decay是學習率衰減方法,它指定在訓練到一定epoches或者steps后,按照線性或者余弦函數(shù)等方式,將學習率降低至指定值。一般,使用Warmup and Decay,學習率會遵循從小到大,再減小的規(guī)律。
        ??由于剛開始訓練時,模型的權(quán)重(weights)是隨機初始化的,此時若選擇一個較大的學習率,可能帶來模型的不穩(wěn)定(振蕩),選擇Warmup預熱學習率的方式,可以使得開始訓練的幾個epoches或者一些steps內(nèi)學習率較小,在預熱的小學習率下,模型可以慢慢趨于穩(wěn)定,等模型相對穩(wěn)定后再選擇預先設(shè)置的學習率進行訓練,使得模型收斂速度變得更快,模型效果更佳。而當模型訓到一定階段后(比如10個epoch),模型的分布就已經(jīng)比較固定了,或者說能學到的新東西就比較少了。如果還沿用較大的學習率,就會破壞這種穩(wěn)定性,用我們通常的話說,就是已經(jīng)接近損失函數(shù)的局部最優(yōu)值點了,為了靠近這個局部最優(yōu)值點,我們就要慢慢來。

        如何在keras_bert中使用Warmup and Decay?

        ??在keras_bert中,提供了優(yōu)化器AdamWarmup類,其參數(shù)定義如下:

        class AdamWarmup(keras.optimizers.Optimizer):
            """Adam optimizer with warmup.

            Default parameters follow those provided in the original paper.

            # Arguments
                decay_steps: Learning rate will decay linearly to zero in decay steps.
                warmup_steps: Learning rate will increase linearly to lr in first warmup steps.
                learning_rate: float >= 0. Learning rate.
                beta_1: float, 0 < beta < 1. Generally close to 1.
                beta_2: float, 0 < beta < 1. Generally close to 1.
                epsilon: float >= 0. Fuzz factor. If `None`, defaults to `K.epsilon()`.
                weight_decay: float >= 0. Weight decay.
                weight_decay_pattern: A list of strings. The substring of weight names to be decayed.
                                      All weights will be decayed if it is None.
                amsgrad: boolean. Whether to apply the AMSGrad variant of this
                    algorithm from the paper "On the Convergence of Adam and
                    Beyond".
            """


            def __init__(self, decay_steps, warmup_steps, min_lr=0.0,
                         learning_rate=0.001, beta_1=0.9, beta_2=0.999,
                         epsilon=None, weight_decay=0., weight_decay_pattern=None,
                         amsgrad=False, **kwargs)
        :

        在這個類中,我們需要指定decay_stepswarmup_steps,learning_rate,min_lr,其含義為模型在訓練warmup_steps后,將學習率逐漸增加至learning_rate,在訓練decay_steps后,將學習率逐漸線性地降低至min_lr
        ??以下為Warmup預熱學習率以及學習率預熱完成后衰減(sin or exp decay)的曲線圖:

        學習率Warmup and Decay示意圖

        ??在keras_bert的官方文檔中,給出了使用Warmup and Decay的代碼例子,如下:
        import numpy as np
        from keras_bert import AdamWarmup, calc_train_steps

        train_x = np.random.standard_normal((1024100))

        total_steps, warmup_steps = calc_train_steps(
            num_example=train_x.shape[0],
            batch_size=32,
            epochs=10,
            warmup_proportion=0.1,
        )

        optimizer = AdamWarmup(total_steps, warmup_steps, lr=1e-3, min_lr=1e-5)

        Warmup and Decay實戰(zhàn)

        ??筆者在文章NLP(三十四)使用keras-bert實現(xiàn)序列標注任務(wù)中,在使用keras-bert訓練 序列標注模型時,學習率調(diào)整策略使用了ReduceLROnPlateau,代碼如下:

        reduce_lr = ReduceLROnPlateau(monitor='val_loss', min_delta=0.0004, patience=2, factor=0.1, min_lr=1e-6,
                                          mode='auto',
                                          verbose=1)

        在三個數(shù)據(jù)集上的評估結(jié)果如下:

        • 人民日報命名實體識別數(shù)據(jù)集:micro avg F1=0.9182

        • 時間識別數(shù)據(jù)集:micro avg F1=0.8587

        • CLUENER細粒度實體識別數(shù)據(jù)集:micro avg F1=0.7603

        ??我們將學習率調(diào)整策略修改為Warmup and Decay(模型其他參數(shù)不變,數(shù)據(jù)集不變),代碼如下:

        # add warmup
            total_steps, warmup_steps = calc_train_steps(
                num_example=len(input_train),
                batch_size=BATCH_SIZE,
                epochs=EPOCH,
                warmup_proportion=0.2,
            )
            optimizer = AdamWarmup(total_steps, warmup_steps, lr=1e-4, min_lr=1e-7)
            model = BertBilstmCRF(max_seq_length=MAX_SEQ_LEN, lstm_dim=64).create_model()
            model.compile(
                optimizer=optimizer,
                loss=crf_loss,
                metrics=[crf_accuracy]
            )

        使用該trick,在三個數(shù)據(jù)集上的評估結(jié)果如下:

        • 人民日報命名實體識別數(shù)據(jù)集

        學習率調(diào)整預測1預測2預測3avg
        Warmup0.92760.92170.92520.9248
        • 時間識別數(shù)據(jù)集

        學習率調(diào)整預測1預測2預測3avg
        Warmup0.89260.89340.88200.8893
        • CLUENER細粒度實體識別數(shù)據(jù)集

        學習率調(diào)整預測1預測2預測3avg
        Warmup0.76120.76290.76070.7616

        可以看到,使用了Warmup and Decay,模型在不同的數(shù)據(jù)集上均有不同程度的效果提升。
        ??本項目已經(jīng)開源,代碼地址為:https://github.com/percent4/keras_bert_sequence_labeling 。
        ??本文到此結(jié)束,感謝大家的閱讀~
        ??2021年3月27日于上海浦東~


        瀏覽 250
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 男同桌上课硬了让我口 | 幺公吃我奶水边摸边做 | 一级 a一级 a 免费观看免免黄 | 成人做爱全过程免费的视频 | b想要叉叉网站在线看 |