Transformers 從pytorch-pretrained-bert遷移

這是從pytorch-pretrained-bert遷移到transformers時應注意的事項的快速摘要。

模型始終輸出tuple

從pytorch-pretrained-bert遷移到transformers時,主要的突破性變化是模型forward方法始終根據模型和配置參數輸出帶有各種元素的tuple。

每個模型的元組的確切內容在模型的文檔字符串和文檔(https://huggingface.co/transformers/)中進行了詳細說明。

在幾乎每種情況下,你都可以通過將輸出的第一個元素用作先前在pytorch-pretrained-bert中使用的輸出來正常工作。

這是BertForSequenceClassification分類模型的pytorch-pretrained-bert到transformers的轉換示例:

<code># 讓我們加載模型
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')

# 如果你以前在pytorch-pretrained-bert中使用此行:
loss = model(input_ids, labels=labels)

# 現在只需在transformers中使用以下代碼即可從輸出元組中提取loss:
outputs = model(input_ids, labels=labels)
loss = outputs[0]

# 在transformers你也可以訪問logits:
loss, logits = outputs[:2]

# 將模型配置為輸出注意力權重的話,可以輸出注意力權重值(其他輸出,也請參閱文檔字符串和文檔)
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', output_attentions=True)
outputs = model(input_ids, labels=labels)
loss, logits, attentions = outputs/<code>

序列化

from_pretrained()方法的重大變化:

  1. 現在,在使用from_pretrained()方法實例化時,默認情況下將模型設置為評估模式。要訓​​練它們,不要忘記將它們重新設置為訓練模式(model.train())以激活dropout模塊。
  2. 提供給from_pretrained()方法的附加*inputs和** kwargs參數通常直接傳遞給基礎模型的類
    init __()方法。現在,它們可用於首先更新模型配置屬性,這可以突破先前的BertForSequenceClassification示例構建的派生模型類。更確切地說,提供給from_pretrained()的位置參數* inputs被直接轉發給model的`init ()方法,而與配置類屬性匹配的關鍵字參數** kwargs:(i)匹配配置類屬性用於更新所述屬性(ii)與任何配置類屬性都不匹配的屬性被轉發到model的init __()`方法。

同樣,雖然沒有什麼大的變化,但是序列化方法已經標準化,如果以前使用過任何其他序列化方法,則可能應該切換到新方法save_pretrained(save_directory)。

這是一個例子:

<code>###讓我們加載模型和令牌生成器

model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

### 對我們的模型和令牌生成器做一些事情
# 例如: 將新標記添加到模型的詞彙表和嵌入中
tokenizer.add_tokens(['[SPECIAL_TOKEN_1]', '[SPECIAL_TOKEN_2]'])
model.resize_token_embeddings(len(tokenizer))
# 訓練模型
train(model)

### 現在讓我們將模型和tokenizer保存到目錄中
model.save_pretrained('./my_saved_model_directory/')
tokenizer.save_pretrained('./my_saved_model_directory/')

### 重新加載模型和tokenizer
model = BertForSequenceClassification.from_pretrained('./my_saved_model_directory/')
tokenizer = BertTokenizer.from_pretrained('./my_saved_model_directory/')/<code>

優化程序:BertAdam和OpenAIAdam現在是AdamW,日程表是標準的PyTorch日程表

以前包括的兩個優化器,BertAdam和OpenAIAdam,已由單個的AdamW優化器代替,但有一些區別:

  • 僅實現權重衰減校正,
  • schedules現在是外部的(請參閱下文),
  • 梯度裁剪現在也是外部的(請參閱下文)。

新的優化器AdamW與PyTorchAdam優化器API匹配,可讓你使用標準的PyTorch或apex方法進行schedule和裁剪。

現在,這些schedules已成為標準的PyTorch學習率調度程序,現在不再是優化程序的一部分。

以下是轉換示例:

<code># 參數:
lr = 1e-3
max_grad_norm = 1.0
num_training_steps = 1000
num_warmup_steps = 100
warmup_proportion = float(num_warmup_steps) / float(num_training_steps)  # 0.1

### 以前,BertAdam優化器是這樣實例化的:
optimizer = BertAdam(model.parameters(), lr=lr, schedule='warmup_linear', warmup=warmup_proportion, t_total=num_training_steps)
### 並像這樣使用:
for batch in train_data:
    loss = model(batch)
    loss.backward()
    optimizer.step()

### 在“Transformer”中,優化器和schedules按如下方式拆分和實例化:
optimizer = AdamW(model.parameters(), lr=lr, correct_bias=False)  # 要重現BertAdam特定的行為,請設置correct_bias = False
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=num_warmup_steps, num_training_steps=num_training_steps)  # PyTorch調度程序用法如下:

for batch in train_data:
    model.train()
    loss = model(batch)
    loss.backward()
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)  # 梯度裁剪不再在AdamW中了(因此你可以毫無問題地使用放大器)
    optimizer.step()
    scheduler.step()
    optimizer.zero_grad()/<code>


分享到:


相關文章: