NLP(四十三)模型调参技巧之Warmup and Decay

本文介绍了深度学习中WarmupandDecay学习率调整策略,详细阐述了其原理和作用,并展示了在keras_bert库中如何使用AdamWarmup优化器实现这一策略。通过实例对比,说明了WarmupandDecay在序列标注任务中的效果提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  Warmup and Decay是深度学习中模型调参的常用trick。本文将简单介绍Warmup and Decay以及如何在keras_bert中使用它们。

什么是warmup and decay?

  Warmup and Decay是模型训练过程中,一种学习率(learning rate)的调整策略。
  Warmup是在ResNet论文中提到的一种学习率预热的方法,它在训练开始的时候先选择使用一个较小的学习率,训练了一些epoches或者steps(比如4个epoches,10000steps),再修改为预先设置的学习来进行训练。
  同理,Decay是学习率衰减方法,它指定在训练到一定epoches或者steps后,按照线性或者余弦函数等方式,将学习率降低至指定值。一般,使用Warmup and Decay,学习率会遵循从小到大,再减小的规律。
  由于刚开始训练时,模型的权重(weights)是随机初始化的,此时若选择一个较大的学习率,可能带来模型的不稳定(振荡),选择Warmup预热学习率的方式,可以使得开始训练的几个epoches或者一些steps内学习率较小,在预热的小学习率下,模型可以慢慢趋于稳定,等模型相对稳定后再选择预先设置的学习率进行训练,使得模型收敛速度变得更快,模型效果更佳。而当模型训到一定阶段后(比如10个epoch),模型的分布就已经比较固定了,或者说能学到的新东西就比较少了。如果还沿用较大的学习率,就会破坏这种稳定性,用我们通常的话说,就是已经接近损失函数的局部最优值点了,为了靠近这个局部最优值点,我们就要慢慢来。

如何在keras_bert中使用Warmup and Decay?

  在keras_bert中,提供了优化器AdamWarmup类,其参数定义如下:

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_stepslearning_ratemin_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((1024, 100))

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实战

  笔者在文章NLP(三十四)使用keras-bert实现序列标注任务中,在使用keras-bert训练 序列标注模型时,学习率调整策略使用了ReduceLROnPlateau,代码如下:

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

在三个数据集上的评估结果如下:

  • 人民日报命名实体识别数据集:micro avg F1=0.9182
  • 时间识别数据集:micro avg F1=0.8587
  • CLUENER细粒度实体识别数据集:micro avg F1=0.7603

  我们将学习率调整策略修改为Warmup and Decay(模型其他参数不变,数据集不变),代码如下:

# 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,在三个数据集上的评估结果如下:

  • 人民日报命名实体识别数据集
学习率调整预测1预测2预测3avg
Warmup0.92760.92170.92520.9248
  • 时间识别数据集
学习率调整预测1预测2预测3avg
Warmup0.89260.89340.88200.8893
  • CLUENER细粒度实体识别数据集
学习率调整预测1预测2预测3avg
Warmup0.76120.76290.76070.7616

可以看到,使用了Warmup and Decay,模型在不同的数据集上均有不同程度的效果提升。
  本项目已经开源,代码地址为:https://github.com/percent4/keras_bert_sequence_labeling
  本文到此结束,感谢大家的阅读~
  2021年3月27日于上海浦东~

### Transformer 架构在自然语言处理 NLP 中的应用 #### 1. 序列到序列任务 Transformer 模型通过自注意力机制(self-attention mechanism),可以并行化处理输入数据,从而提高了计算效率。这种特性使得 Transformer 成为了机器翻译、文本摘要等序列到序列任务的理想选择[^1]。 ```python import torch.nn as nn from transformers import BertTokenizer, BertModel class Seq2Seq(nn.Module): def __init__(self, encoder, decoder): super(Seq2Seq, self).__init__() self.encoder = encoder self.decoder = decoder def forward(self, src, trg): enc_output = self.encoder(src) output = self.decoder(trg, enc_output) return output ``` #### 2. 文本分类 对于情感分析、垃圾邮件检测等文本分类任务,Transformer 可以捕捉上下文信息,提高分类准确性。BERT (Bidirectional Encoder Representations from Transformers) 是一种预训练的语言表示模型,在多个下游任务上表现出色[^2]。 ```python from sklearn.model_selection import train_test_split from transformers import Trainer, TrainingArguments tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') model = BertModel.from_pretrained('bert-base-uncased') train_texts, test_texts, train_labels, test_labels = train_test_split(texts, labels) training_args = TrainingArguments( output_dir='./results', num_train_epochs=3, per_device_train_batch_size=8, per_device_eval_batch_size=8, warmup_steps=500, weight_decay=0.01, logging_dir='./logs', ) trainer = Trainer( model=model, args=training_args, train_dataset=train_texts, eval_dataset=test_texts ) ``` #### 3. 命名实体识别 命名实体识别(NER)是提取文档中特定类型的实体的任务。由于 Transformer 能够理解词语之间的关系,因此非常适合用于此场景。Hugging Face 的 `transformers` 库提供了方便易用的接口来加载预训练模型并微调它们以适应具体应用场景。 ```python from transformers import pipeline nlp = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english") example_text = "Apple is looking at buying U.K. startup for $1 billion" entities = nlp(example_text) print(entities) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值