色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

PyTorch教程-16.7。自然語言推理:微調 BERT

jf_pJlTbmA9 ? 來源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:44 ? 次閱讀

在本章前面的部分中,我們為 SNLI 數據集上的自然語言推理任務(如第 16.4 節所述)設計了一個基于注意力的架構(第16.5節)。現在我們通過微調 BERT 重新審視這個任務。正如16.6 節所討論的 ,自然語言推理是一個序列級文本對分類問題,微調 BERT 只需要一個額外的基于 MLP 的架構,如圖 16.7.1所示。

poYBAGR9POGANyPIAAKGzmOF458734.svg

圖 16.7.1本節將預訓練的 BERT 提供給基于 MLP 的自然語言推理架構。

在本節中,我們將下載預訓練的小型 BERT 版本,然后對其進行微調以在 SNLI 數據集上進行自然語言推理。

import json
import multiprocessing
import os
import torch
from torch import nn
from d2l import torch as d2l

import json
import multiprocessing
import os
from mxnet import gluon, np, npx
from mxnet.gluon import nn
from d2l import mxnet as d2l

npx.set_np()

16.7.1。加載預訓練的 BERT

我們已經在第 15.9 節和第 15.10 節中解釋了如何在 WikiText-2 數據集上預訓練 BERT (請注意,原始 BERT 模型是在更大的語料庫上預訓練的)。如15.10 節所述,原始 BERT 模型有數億個參數。在下文中,我們提供了兩個版本的預訓練 BERT:“bert.base”與需要大量計算資源進行微調的原始 BERT 基礎模型差不多大,而“bert.small”是一個小版本方便演示。

d2l.DATA_HUB['bert.base'] = (d2l.DATA_URL + 'bert.base.torch.zip',
               '225d66f04cae318b841a13d32af3acc165f253ac')
d2l.DATA_HUB['bert.small'] = (d2l.DATA_URL + 'bert.small.torch.zip',
               'c72329e68a732bef0452e4b96a1c341c8910f81f')

d2l.DATA_HUB['bert.base'] = (d2l.DATA_URL + 'bert.base.zip',
               '7b3820b35da691042e5d34c0971ac3edbd80d3f4')
d2l.DATA_HUB['bert.small'] = (d2l.DATA_URL + 'bert.small.zip',
               'a4e718a47137ccd1809c9107ab4f5edd317bae2c')

預訓練的 BERT 模型都包含一個定義詞匯集的“vocab.json”文件和一個預訓練參數的“pretrained.params”文件。我們實現以下load_pretrained_model 函數來加載預訓練的 BERT 參數。

def load_pretrained_model(pretrained_model, num_hiddens, ffn_num_hiddens,
             num_heads, num_blks, dropout, max_len, devices):
  data_dir = d2l.download_extract(pretrained_model)
  # Define an empty vocabulary to load the predefined vocabulary
  vocab = d2l.Vocab()
  vocab.idx_to_token = json.load(open(os.path.join(data_dir, 'vocab.json')))
  vocab.token_to_idx = {token: idx for idx, token in enumerate(
    vocab.idx_to_token)}
  bert = d2l.BERTModel(
    len(vocab), num_hiddens, ffn_num_hiddens=ffn_num_hiddens, num_heads=4,
    num_blks=2, dropout=0.2, max_len=max_len)
  # Load pretrained BERT parameters
  bert.load_state_dict(torch.load(os.path.join(data_dir,
                         'pretrained.params')))
  return bert, vocab

def load_pretrained_model(pretrained_model, num_hiddens, ffn_num_hiddens,
             num_heads, num_blks, dropout, max_len, devices):
  data_dir = d2l.download_extract(pretrained_model)
  # Define an empty vocabulary to load the predefined vocabulary
  vocab = d2l.Vocab()
  vocab.idx_to_token = json.load(open(os.path.join(data_dir, 'vocab.json')))
  vocab.token_to_idx = {token: idx for idx, token in enumerate(
    vocab.idx_to_token)}
  bert = d2l.BERTModel(len(vocab), num_hiddens, ffn_num_hiddens, num_heads,
             num_blks, dropout, max_len)
  # Load pretrained BERT parameters
  bert.load_parameters(os.path.join(data_dir, 'pretrained.params'),
             ctx=devices)
  return bert, vocab

為了便于在大多數機器上進行演示,我們將在本節中加載和微調預訓練 BERT 的小型版本(“bert.small”)。在練習中,我們將展示如何微調更大的“bert.base”以顯著提高測試準確性。

devices = d2l.try_all_gpus()
bert, vocab = load_pretrained_model(
  'bert.small', num_hiddens=256, ffn_num_hiddens=512, num_heads=4,
  num_blks=2, dropout=0.1, max_len=512, devices=devices)

Downloading ../data/bert.small.torch.zip from http://d2l-data.s3-accelerate.amazonaws.com/bert.small.torch.zip...

devices = d2l.try_all_gpus()
bert, vocab = load_pretrained_model(
  'bert.small', num_hiddens=256, ffn_num_hiddens=512, num_heads=4,
  num_blks=2, dropout=0.1, max_len=512, devices=devices)

Downloading ../data/bert.small.zip from http://d2l-data.s3-accelerate.amazonaws.com/bert.small.zip...

16.7.2。微調 BERT 的數據集

對于 SNLI 數據集上的下游任務自然語言推理,我們定義了一個自定義的數據集類SNLIBERTDataset。在每個示例中,前提和假設形成一對文本序列,并被打包到一個 BERT 輸入序列中,如圖 16.6.2所示。回想第 15.8.4 節 ,段 ID 用于區分 BERT 輸入序列中的前提和假設。對于 BERT 輸入序列 ( max_len) 的預定義最大長度,輸入文本對中較長者的最后一個標記會不斷被刪除,直到max_len滿足為止。為了加速生成用于微調 BERT 的 SNLI 數據集,我們使用 4 個工作進程并行生成訓練或測試示例。

class SNLIBERTDataset(torch.utils.data.Dataset):
  def __init__(self, dataset, max_len, vocab=None):
    all_premise_hypothesis_tokens = [[
      p_tokens, h_tokens] for p_tokens, h_tokens in zip(
      *[d2l.tokenize([s.lower() for s in sentences])
       for sentences in dataset[:2]])]

    self.labels = torch.tensor(dataset[2])
    self.vocab = vocab
    self.max_len = max_len
    (self.all_token_ids, self.all_segments,
     self.valid_lens) = self._preprocess(all_premise_hypothesis_tokens)
    print('read ' + str(len(self.all_token_ids)) + ' examples')

  def _preprocess(self, all_premise_hypothesis_tokens):
    pool = multiprocessing.Pool(4) # Use 4 worker processes
    out = pool.map(self._mp_worker, all_premise_hypothesis_tokens)
    all_token_ids = [
      token_ids for token_ids, segments, valid_len in out]
    all_segments = [segments for token_ids, segments, valid_len in out]
    valid_lens = [valid_len for token_ids, segments, valid_len in out]
    return (torch.tensor(all_token_ids, dtype=torch.long),
        torch.tensor(all_segments, dtype=torch.long),
        torch.tensor(valid_lens))

  def _mp_worker(self, premise_hypothesis_tokens):
    p_tokens, h_tokens = premise_hypothesis_tokens
    self._truncate_pair_of_tokens(p_tokens, h_tokens)
    tokens, segments = d2l.get_tokens_and_segments(p_tokens, h_tokens)
    token_ids = self.vocab[tokens] + [self.vocab['']] 
               * (self.max_len - len(tokens))
    segments = segments + [0] * (self.max_len - len(segments))
    valid_len = len(tokens)
    return token_ids, segments, valid_len

  def _truncate_pair_of_tokens(self, p_tokens, h_tokens):
    # Reserve slots for '', '', and '' tokens for the BERT
    # input
    while len(p_tokens) + len(h_tokens) > self.max_len - 3:
      if len(p_tokens) > len(h_tokens):
        p_tokens.pop()
      else:
        h_tokens.pop()

  def __getitem__(self, idx):
    return (self.all_token_ids[idx], self.all_segments[idx],
        self.valid_lens[idx]), self.labels[idx]

  def __len__(self):
    return len(self.all_token_ids)

class SNLIBERTDataset(gluon.data.Dataset):
  def __init__(self, dataset, max_len, vocab=None):
    all_premise_hypothesis_tokens = [[
      p_tokens, h_tokens] for p_tokens, h_tokens in zip(
      *[d2l.tokenize([s.lower() for s in sentences])
       for sentences in dataset[:2]])]

    self.labels = np.array(dataset[2])
    self.vocab = vocab
    self.max_len = max_len
    (self.all_token_ids, self.all_segments,
     self.valid_lens) = self._preprocess(all_premise_hypothesis_tokens)
    print('read ' + str(len(self.all_token_ids)) + ' examples')

  def _preprocess(self, all_premise_hypothesis_tokens):
    pool = multiprocessing.Pool(4) # Use 4 worker processes
    out = pool.map(self._mp_worker, all_premise_hypothesis_tokens)
    all_token_ids = [
      token_ids for token_ids, segments, valid_len in out]
    all_segments = [segments for token_ids, segments, valid_len in out]
    valid_lens = [valid_len for token_ids, segments, valid_len in out]
    return (np.array(all_token_ids, dtype='int32'),
        np.array(all_segments, dtype='int32'),
        np.array(valid_lens))

  def _mp_worker(self, premise_hypothesis_tokens):
    p_tokens, h_tokens = premise_hypothesis_tokens
    self._truncate_pair_of_tokens(p_tokens, h_tokens)
    tokens, segments = d2l.get_tokens_and_segments(p_tokens, h_tokens)
    token_ids = self.vocab[tokens] + [self.vocab['']] 
               * (self.max_len - len(tokens))
    segments = segments + [0] * (self.max_len - len(segments))
    valid_len = len(tokens)
    return token_ids, segments, valid_len

  def _truncate_pair_of_tokens(self, p_tokens, h_tokens):
    # Reserve slots for '', '', and '' tokens for the BERT
    # input
    while len(p_tokens) + len(h_tokens) > self.max_len - 3:
      if len(p_tokens) > len(h_tokens):
        p_tokens.pop()
      else:
        h_tokens.pop()

  def __getitem__(self, idx):
    return (self.all_token_ids[idx], self.all_segments[idx],
        self.valid_lens[idx]), self.labels[idx]

  def __len__(self):
    return len(self.all_token_ids)

下載 SNLI 數據集后,我們通過實例化SNLIBERTDataset類來生成訓練和測試示例。此類示例將在自然語言推理的訓練和測試期間以小批量讀取。

# Reduce `batch_size` if there is an out of memory error. In the original BERT
# model, `max_len` = 512
batch_size, max_len, num_workers = 512, 128, d2l.get_dataloader_workers()
data_dir = d2l.download_extract('SNLI')
train_set = SNLIBERTDataset(d2l.read_snli(data_dir, True), max_len, vocab)
test_set = SNLIBERTDataset(d2l.read_snli(data_dir, False), max_len, vocab)
train_iter = torch.utils.data.DataLoader(train_set, batch_size, shuffle=True,
                  num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(test_set, batch_size,
                 num_workers=num_workers)

read 549367 examples
read 9824 examples

# Reduce `batch_size` if there is an out of memory error. In the original BERT
# model, `max_len` = 512
batch_size, max_len, num_workers = 512, 128, d2l.get_dataloader_workers()
data_dir = d2l.download_extract('SNLI')
train_set = SNLIBERTDataset(d2l.read_snli(data_dir, True), max_len, vocab)
test_set = SNLIBERTDataset(d2l.read_snli(data_dir, False), max_len, vocab)
train_iter = gluon.data.DataLoader(train_set, batch_size, shuffle=True,
                  num_workers=num_workers)
test_iter = gluon.data.DataLoader(test_set, batch_size,
                 num_workers=num_workers)

read 549367 examples
read 9824 examples

16.7.3。微調 BERT

如圖16.6.2所示,為自然語言推理微調 BERT 只需要一個額外的 MLP,該 MLP 由兩個完全連接的層組成(參見下一類中的self.hidden和)。該 MLP 將特殊“”標記的 BERT 表示形式(對前提和假設的信息進行編碼)轉換為自然語言推理的三個輸出:蘊含、矛盾和中性。self.outputBERTClassifier

class BERTClassifier(nn.Module):
  def __init__(self, bert):
    super(BERTClassifier, self).__init__()
    self.encoder = bert.encoder
    self.hidden = bert.hidden
    self.output = nn.LazyLinear(3)

  def forward(self, inputs):
    tokens_X, segments_X, valid_lens_x = inputs
    encoded_X = self.encoder(tokens_X, segments_X, valid_lens_x)
    return self.output(self.hidden(encoded_X[:, 0, :]))

class BERTClassifier(nn.Block):
  def __init__(self, bert):
    super(BERTClassifier, self).__init__()
    self.encoder = bert.encoder
    self.hidden = bert.hidden
    self.output = nn.Dense(3)

  def forward(self, inputs):
    tokens_X, segments_X, valid_lens_x = inputs
    encoded_X = self.encoder(tokens_X, segments_X, valid_lens_x)
    return self.output(self.hidden(encoded_X[:, 0, :]))

接下來,預訓練的 BERT 模型bert被輸入到 下游應用程序的BERTClassifier實例中。net在 BERT 微調的常見實現中,只會net.output從頭學習附加 MLP ( ) 輸出層的參數。net.encoder預訓練的 BERT 編碼器 ( ) 和附加 MLP 的隱藏層 ( )的所有參數都net.hidden將被微調。

net = BERTClassifier(bert)

net = BERTClassifier(bert)
net.output.initialize(ctx=devices)

回想一下15.8 節中類MaskLM和 NextSentencePred類在它們使用的 MLP 中都有參數。這些參數是預訓練 BERT 模型中參數bert的一部分,因此也是net. 然而,這些參數僅用于計算預訓練期間的掩碼語言建模損失和下一句預測損失。MaskLM這兩個損失函數與微調下游應用程序無關,因此在微調 BERT 時,在和中使用的 MLP 的參數NextSentencePred不會更新(失效)。

為了允許具有陳舊梯度的參數,在的函數 ignore_stale_grad=True中設置了標志 。我們使用此函數使用SNLI 的訓練集 ( ) 和測試集 ( )來訓練和評估模型。由于計算資源有限,訓練和測試的準確性可以進一步提高:我們將其討論留在練習中。stepd2l.train_batch_ch13nettrain_itertest_iter

lr, num_epochs = 1e-4, 5
trainer = torch.optim.Adam(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss(reduction='none')
net(next(iter(train_iter))[0])
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices)

loss 0.519, train acc 0.791, test acc 0.782
9226.8 examples/sec on [device(type='cuda', index=0), device(type='cuda', index=1)]

pYYBAGR9POSAGNU7AAECAEIwxyI914.svg

lr, num_epochs = 1e-4, 5
trainer = gluon.Trainer(net.collect_params(), 'adam', {'learning_rate': lr})
loss = gluon.loss.SoftmaxCrossEntropyLoss()
d2l.train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs, devices,
        d2l.split_batch_multi_inputs)

loss 0.477, train acc 0.810, test acc 0.785
4626.9 examples/sec on [gpu(0), gpu(1)]

pYYBAGR9POaAD1LSAAECF6LTtKs956.svg

16.7.4。概括

我們可以為下游應用微調預訓練的 BERT 模型,例如 SNLI 數據集上的自然語言推理。

在微調期間,BERT 模型成為下游應用模型的一部分。僅與預訓練損失相關的參數在微調期間不會更新。

16.7.5。練習

如果您的計算資源允許,微調一個更大的預訓練 BERT 模型,該模型與原始 BERT 基礎模型差不多大。將函數中的參數設置load_pretrained_model為:將“bert.small”替換為“bert.base”,將 、 、 和 的值分別增加到 num_hiddens=256768、3072、12ffn_num_hiddens=512和num_heads=412 num_blks=2。通過增加微調周期(并可能調整其他超參數),您能否獲得高于 0.86 的測試精度?

如何根據長度比截斷一對序列?比較這對截斷方法和類中使用的方法 SNLIBERTDataset。他們的優缺點是什么?

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 自然語言
    +關注

    關注

    1

    文章

    291

    瀏覽量

    13578
  • pytorch
    +關注

    關注

    2

    文章

    809

    瀏覽量

    13712
收藏 0人收藏

    評論

    相關推薦
    熱點推薦

    如何開始使用PyTorch進行自然語言處理

    隨著人工智能和深度學習程序在未來幾年的蓬勃發展,自然語言處理(NLP)將日益普及,而且必要性也與日俱增。PyTorch 自然語言處理是實現這些程序的不錯選擇。
    的頭像 發表于 07-07 10:01 ?2717次閱讀

    python自然語言

    最近,python自然語言是越來越火了,那么什么是自然語言自然語言(Natural Language )廣納了眾多技術,對自然或人類語言
    發表于 05-02 13:50

    自然語言處理的語言模型

    自然語言處理——53 語言模型(數據平滑)
    發表于 04-16 11:11

    什么是自然語言處理

    什么是自然語言處理?自然語言處理任務有哪些?自然語言處理的方法是什么?
    發表于 09-08 06:51

    自然語言處理怎么最快入門_自然語言處理知識了解

    自然語言處理就是實現人機間自然語言通信,實現自然語言理解和自然語言生成是十分困難的,造成困難的根本原因是自然語言文本和對話的各個層次上廣泛存
    發表于 12-28 17:10 ?5382次閱讀

    自然語言入門之ESIM

    ESIM是ACL2017的一篇論文,在當時成為各個NLP比賽的殺器,直到現在仍是入門自然語言推理值得一讀的文章。 本文根據ESIM原文以及pytorch代碼實現對ESIM模型進行總結
    的頭像 發表于 02-22 11:34 ?1231次閱讀
    <b class='flag-5'>自然語言</b>入門之ESIM

    PyTorch教程16.4之自然語言推理和數據集

    電子發燒友網站提供《PyTorch教程16.4之自然語言推理和數據集.pdf》資料免費下載
    發表于 06-05 10:57 ?0次下載
    <b class='flag-5'>PyTorch</b>教程16.4之<b class='flag-5'>自然語言</b><b class='flag-5'>推理</b>和數據集

    PyTorch教程16.5之自然語言推理:使用注意力

    電子發燒友網站提供《PyTorch教程16.5之自然語言推理:使用注意力.pdf》資料免費下載
    發表于 06-05 10:49 ?0次下載
    <b class='flag-5'>PyTorch</b>教程16.5之<b class='flag-5'>自然語言</b><b class='flag-5'>推理</b>:使用注意力

    PyTorch教程16.6之針對序列級和令牌級應用程序微調BERT

    電子發燒友網站提供《PyTorch教程16.6之針對序列級和令牌級應用程序微調BERT.pdf》資料免費下載
    發表于 06-05 10:51 ?0次下載
    <b class='flag-5'>PyTorch</b>教程16.6之針對序列級和令牌級應用程序<b class='flag-5'>微調</b><b class='flag-5'>BERT</b>

    PyTorch教程16.7自然語言推理微調BERT

    電子發燒友網站提供《PyTorch教程16.7自然語言推理微調BERT.pdf》資料免費下載
    發表于 06-05 10:52 ?0次下載
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>16.7</b>之<b class='flag-5'>自然語言</b><b class='flag-5'>推理</b>:<b class='flag-5'>微調</b><b class='flag-5'>BERT</b>

    PyTorch教程-16.4。自然語言推理和數據集

    16.4。自然語言推理和數據集? Colab [火炬]在 Colab 中打開筆記本 Colab [mxnet] Open the notebook in Colab Colab [jax
    的頭像 發表于 06-05 15:44 ?703次閱讀

    PyTorch教程-16.5。自然語言推理:使用注意力

    16.5。自然語言推理:使用注意力? Colab [火炬]在 Colab 中打開筆記本 Colab [mxnet] Open the notebook in Colab Colab
    的頭像 發表于 06-05 15:44 ?725次閱讀
    <b class='flag-5'>PyTorch</b>教程-16.5。<b class='flag-5'>自然語言</b><b class='flag-5'>推理</b>:使用注意力

    PyTorch教程-16.6. 針對序列級和令牌級應用程序微調 BERT

    和 MLPs。當存在空間或時間限制時,這些模型很有用,但是,為每個自然語言處理任務制作一個特定模型實際上是不可行的。在 15.8 節中,我們介紹了一種預訓練模型 BERT,它需要對各種自然語言處理任務進行
    的頭像 發表于 06-05 15:44 ?588次閱讀
    <b class='flag-5'>PyTorch</b>教程-16.6. 針對序列級和令牌級應用程序<b class='flag-5'>微調</b> <b class='flag-5'>BERT</b>

    自然語言處理的概念和應用 自然語言處理屬于人工智能嗎

      自然語言處理(Natural Language Processing)是一種人工智能技術,它是研究自然語言與計算機之間的交互和通信的一門學科。自然語言處理旨在研究機器如何理解人類語言
    發表于 08-23 17:31 ?1988次閱讀

    ChatGPT是一個好的因果推理器嗎?

    因果推理能力對于許多自然語言處理(NLP)應用至關重要。最近的因果推理系統主要基于經過微調的預訓練語言模型(PLMs),如
    的頭像 發表于 01-03 09:55 ?1083次閱讀
    ChatGPT是一個好的因果<b class='flag-5'>推理</b>器嗎?
    主站蜘蛛池模板: 无码AV动漫精品一区二区免费 | 人妻免费久久久久久久了 | 爽a中文字幕一区 | 超熟女专门志 | 99国产电影| 国产成人精品免费视频大全可播放的 | 两个人在线观看的视频720 | 美女乱草鲍高清照片 | 久久成人亚洲 | 小护士大pp | jizzjizz丝袜 | 国产专区青青草原亚洲 | 天天狠狠弄夜夜狠狠躁·太爽了 | 99久久精品费精品蜜臀AV | 国产99视频精品一区 | 亚洲2017天堂色无码 | 久久久GOGO无码啪啪艺术 | 国产成人综合95精品视频免费 | 俄罗斯搜索引擎Yandex推广入口 | 女子叉开腿让男子桶免费软件 | 亚洲国产AV精品一区二区蜜芽 | 韩国成人理伦片免费播放 | JAVASCRIPTJAVA水多多 | 日韩中文字幕亚洲无线码 | 国产精品1区在线播放 | 久久99国产亚洲高清观着 | 校园男男高h小黄文 | 久久视频在线视频观看天天看视频 | 日本工口生肉全彩大全 | DASD-700美谷朱里 | 久久91精品久久久久久水蜜桃 | 九色91精品国产网站 | 狠狠色色综合网站 | 性派对xxxhd| AV亚洲精品少妇毛片无码 | 九九99亚洲精品久久久久 | 妈妈的朋友6未删减版完整在线 | 俄罗斯乌克兰战争原因 | 2020久久精品永久免费 | 午夜人妻理论片天堂影院 | 国产精品国产三级国产an |

    電子發燒友

    中國電子工程師最喜歡的網站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品