gpt4 book ai didi

nlp - BERT 微调的优化器和调度器

转载 作者:行者123 更新时间:2023-12-03 18:31:29 27 4
gpt4 key购买 nike

我正在尝试使用 BERT 微调模型(使用 transformers 库),但我对优化器和调度器有点不确定。

首先,我明白我应该使用 transformers.AdamW而不是 Pytorch 的版本。此外,我们应该使用论文中建议的预热调度程序,因此调度程序是使用 get_linear_scheduler_with_warmup 创建的。函数来自 transformers包裹。

我的主要问题是:

  • get_linear_scheduler_with_warmup应该在热身时调用。可以在 10 个 epoch 中使用 2 进行热身吗?
  • 我应该什么时候调用scheduler.step() ?如果我在 train 之后做,第一个 epoch 的学习率为零。我应该为每批调用它吗?

  • 我做错了什么吗?

    from transformers import AdamW
    from transformers.optimization import get_linear_scheduler_with_warmup

    N_EPOCHS = 10

    model = BertGRUModel(finetune_bert=True,...)
    num_training_steps = N_EPOCHS+1
    num_warmup_steps = 2
    warmup_proportion = float(num_warmup_steps) / float(num_training_steps) # 0.1

    optimizer = AdamW(model.parameters())
    criterion = nn.BCEWithLogitsLoss(pos_weight=torch.Tensor([class_weights[1]]))


    scheduler = get_linear_schedule_with_warmup(
    optimizer, num_warmup_steps=num_warmup_steps,
    num_training_steps=num_training_steps
    )

    for epoch in range(N_EPOCHS):
    scheduler.step() #If I do after train, LR = 0 for the first epoch
    print(optimizer.param_groups[0]["lr"])

    train(...) # here we call optimizer.step()
    evaluate(...)

    我的模型和训练例程(与 this notebook 非常相似)

    class BERTGRUSentiment(nn.Module):
    def __init__(self,
    bert,
    hidden_dim,
    output_dim,
    n_layers=1,
    bidirectional=False,
    finetune_bert=False,
    dropout=0.2):

    super().__init__()

    self.bert = bert

    embedding_dim = bert.config.to_dict()['hidden_size']

    self.finetune_bert = finetune_bert

    self.rnn = nn.GRU(embedding_dim,
    hidden_dim,
    num_layers = n_layers,
    bidirectional = bidirectional,
    batch_first = True,
    dropout = 0 if n_layers < 2 else dropout)

    self.out = nn.Linear(hidden_dim * 2 if bidirectional else hidden_dim, output_dim)
    self.dropout = nn.Dropout(dropout)

    def forward(self, text):
    #text = [batch size, sent len]

    if not self.finetune_bert:
    with torch.no_grad():
    embedded = self.bert(text)[0]
    else:
    embedded = self.bert(text)[0]
    #embedded = [batch size, sent len, emb dim]
    _, hidden = self.rnn(embedded)

    #hidden = [n layers * n directions, batch size, emb dim]

    if self.rnn.bidirectional:
    hidden = self.dropout(torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim = 1))
    else:
    hidden = self.dropout(hidden[-1,:,:])

    #hidden = [batch size, hid dim]

    output = self.out(hidden)

    #output = [batch size, out dim]

    return output


    import torch
    from sklearn.metrics import accuracy_score, f1_score


    def train(model, iterator, optimizer, criterion, max_grad_norm=None):
    """
    Trains the model for one full epoch
    """
    epoch_loss = 0
    epoch_acc = 0

    model.train()

    for i, batch in enumerate(iterator):
    optimizer.zero_grad()
    text, lens = batch.text

    predictions = model(text)

    target = batch.target

    loss = criterion(predictions.squeeze(1), target)

    prob_predictions = torch.sigmoid(predictions)

    preds = torch.round(prob_predictions).detach().cpu()
    acc = accuracy_score(preds, target.cpu())

    loss.backward()
    # Gradient clipping
    if max_grad_norm:
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)

    optimizer.step()

    epoch_loss += loss.item()
    epoch_acc += acc.item()

    return epoch_loss / len(iterator), epoch_acc / len(iterator)


    最佳答案

    Here您可以使用 get_linear_scheduler_with_warmup 看到学习率变化的可视化。 .

    引用 this评论:预热步骤是一个用于降低学习率的参数,以减少模型偏离学习对突然的新数据集暴露的影响。

    默认情况下,预热步骤数为 0。

    然后你迈出更大的步伐,因为你可能不在最小值附近。但是当你接近最小值时,你会采取更小的步骤来收敛到它。

    另请注意,训练步数为 number of batches * number of epochs ,但不仅仅是number of epochs .所以,基本上num_training_steps = N_EPOCHS+1不正确,除非您的 batch_size等于训练集的大小。

    您调用scheduler.step()每批,就在 optimizer.step() 之后, 更新学习率。

    关于nlp - BERT 微调的优化器和调度器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60120043/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com