免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
保姆級教程,用PyTorch和BERT進(jìn)行文本分類
userphoto

2022.06.05 湖北

關(guān)注


文本中,小猴子和大家一起學(xué)習(xí),如何利用 Hugging Face 的預(yù)訓(xùn)練 BERT 模型對新聞文章的文本(BBC 新聞分類數(shù)據(jù)集)進(jìn)行分類。
早在 2018 年,谷歌就為 NLP 應(yīng)用程序開發(fā)了一個(gè)基于 Transformer 的強(qiáng)大的機(jī)器學(xué)習(xí)模型,該模型在不同的基準(zhǔn)數(shù)據(jù)集中優(yōu)于以前的語言模型。這個(gè)模型被稱為BERT。

在這篇文章中,我們將使用來自 Hugging Face 的預(yù)訓(xùn)練 BERT 模型進(jìn)行文本分類任務(wù)。一般而言,文本分類任務(wù)中模型的主要目標(biāo)是將文本分類為預(yù)定義的標(biāo)簽或標(biāo)簽之一。

本文中,我們使用 BBC 新聞分類數(shù)據(jù)集,使用預(yù)訓(xùn)練的 BERT 模型來分類新聞文章的文本是否可以分類為體育、政治商業(yè)、娛樂科技類別。

什么是 BERT

BERT 是 Bidirectional Encoder Representations from Transformers 的首字母縮寫詞。

BERT 架構(gòu)由多個(gè)堆疊在一起的 Transformer 編碼器組成。每個(gè) Transformer 編碼器都封裝了兩個(gè)子層:一個(gè)自注意力層和一個(gè)前饋層。

有兩種不同的 BERT 模型:

  1. BERT base 模型,由 12 層 Transformer 編碼器、12 個(gè)注意力頭、768 個(gè)隱藏大小和 110M 參數(shù)組成。
  2. BERT large 模型,由 24 層 Transformer 編碼器、16 個(gè)注意力頭、1024 個(gè)隱藏大小和 340M 個(gè)參數(shù)組成。

BERT 是一個(gè)強(qiáng)大的語言模型至少有兩個(gè)原因:

  1. 它使用從 BooksCorpus (有 8 億字)和 Wikipedia(有 25 億字)中提取的未標(biāo)記數(shù)據(jù)進(jìn)行預(yù)訓(xùn)練。
  2. 顧名思義,它是通過利用編碼器堆棧的雙向特性進(jìn)行預(yù)訓(xùn)練的。這意味著 BERT 不僅從左到右,而且從右到左從單詞序列中學(xué)習(xí)信息。

論文

  • Transformer: Attention Is All You Need:https://arxiv.org/abs/1706.03762
  • BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding:https://arxiv.org/abs/1810.04805

源碼

  • Transformer Pytorch源碼:https://github.com/jadore801120/attention-is-all-you-need-pytorch
  • BERT Pytorch源碼:https://github.com/hichenway/CodeShare/tree/master/bert_pytorch_source_code
  • HuggingFace Transformers:https://github.com/huggingface/transformers

BERT 輸入

BERT 模型需要一系列 tokens (words) 作為輸入。在每個(gè)token序列中,BERT 期望輸入有兩個(gè)特殊標(biāo)記:

  • [CLS] :這是每個(gè)sequence的第一個(gè)token,代表分類token。
  • [SEP] :這是讓BERT知道哪個(gè)token屬于哪個(gè)序列的token。這一特殊表征法主要用于下一個(gè)句子預(yù)測任務(wù)或問答任務(wù)。如果我們只有一個(gè)sequence,那么這個(gè)token將被附加到序列的末尾。

為什么選它們([CLS]/[SEP])呢,因?yàn)榕c文本中已有的其它詞相比,這個(gè)無明顯語義信息的符號(hào)會(huì)更“公平”地融合文本中各個(gè)詞的語義信息,從而更好的表示整句話的語義。

具體來說,self-attention 是用文本中的其它詞來增強(qiáng)目標(biāo)詞的語義表示,但是目標(biāo)詞本身的語義還是會(huì)占主要部分的,因此,經(jīng)過BERT的12層,每次詞的 Embedding 融合了所有詞的信息,可以去更好的表示自己的語義。

[CLS]位本身沒有語義,經(jīng)過12層,得到的是attention后所有詞的加權(quán)平均,相比其他正常詞,可以更好的表征句子語義。

就像Transformer的普通編碼器一樣,BERT 將一系列單詞作為輸入,這些單詞不斷向上流動(dòng)。每一層都應(yīng)用自我注意,并將其結(jié)果通過前饋網(wǎng)絡(luò)傳遞,然后將其傳遞給下一個(gè)編碼器。

舉個(gè)簡單的例子以更清楚說明,假設(shè)我們有一個(gè)包含以下短句的文本:

第一步,需要將這個(gè)句子轉(zhuǎn)換為一系列tokens (words) ,這個(gè)過程稱為tokenization

雖然已經(jīng)對輸入句子進(jìn)行了標(biāo)記,但還需要再做一步。在將其用作 BERT 模型的輸入之前,我們需要通過添加 [CLS][SEP] 標(biāo)記來對 tokens 的 sequence 重新編碼。

其實(shí)我們只需要一行代碼(即使用BertTokenizer)就可以將輸入句子轉(zhuǎn)換為 BERT 所期望的tokens 序列。

還需要注意的是,可以輸入 BERT 模型的最大tokens大小為 512。如果sequence中的tokens小于 512,我們可以使用填充來用 [PAD] 填充未使用的tokens。如果sequence中的tokens長于 512,那么需要進(jìn)行截?cái)唷?/p>

BERT 輸出

每個(gè)位置輸出一個(gè)大小為 hidden_ size的向量(BERT Base 中為 768)。對于我們在上面看到的句子分類示例,我們只關(guān)注第一個(gè)位置的輸出(將特殊的 [CLS] token 傳遞到該位置)。

該向量現(xiàn)在可以用作我們選擇的分類器的輸入。該論文僅使用單層神經(jīng)網(wǎng)絡(luò)作為分類器就取得了很好的效果。

如果有更多標(biāo)簽,只需調(diào)整分類器網(wǎng)絡(luò)以獲得更多輸出神經(jīng)元然后通過softmax輸出多標(biāo)簽分類。

使用 BERT 進(jìn)行文本分類

本文的主題是用 BERT 對文本進(jìn)行分類。在這篇文章中,我們將使用kaggle上的BBC 新聞分類數(shù)據(jù)集。

數(shù)據(jù)集已經(jīng)是 CSV 格式,它有 2126 個(gè)不同的文本,每個(gè)文本都標(biāo)記在 5 個(gè)類別中的一個(gè)下:sport(體育),business(商業(yè)),politics(政治),tech(科技),entertainment(娛樂)。

看一下數(shù)據(jù)集的樣子:

如上表所示,數(shù)據(jù)框只有兩列,category 將作為標(biāo)簽,text 將作為 BERT 的輸入數(shù)據(jù)。

預(yù)模型下載和使用

BERT 預(yù)訓(xùn)練模型的下載有許多方式,比如從github官網(wǎng)上下載(官網(wǎng)下載的是tensorflow版本的),還可以從源碼中找到下載鏈接,然后手動(dòng)下載,最后還可以從huggingface中下載。
huggingface下載預(yù)訓(xùn)練模型的地址:https://huggingface.co/models

在搜索框搜索到你需要的模型。

來到下載頁面:

注意,這里常用的幾個(gè)預(yù)訓(xùn)練模型,bert-base-cased、bert-base-uncased及中文bert-base-chinese。其中前兩個(gè)容易混淆。bert-base-cased是區(qū)分大小寫,不需要事先lower-case;而bert-base-uncased不能區(qū)分大小寫,因?yàn)樵~表只有小寫,需要事先lower-case。

基本使用示例:

from transformers import BertModel,BertTokenizer
BERT_PATH = './bert-base-cased'
tokenizer = BertTokenizer.from_pretrained(BERT_PATH)
print(tokenizer.tokenize('I have a good time, thank you.'))
bert = BertModel.from_pretrained(BERT_PATH)
print('load bert model over')
['I', 'have', 'a', 'good', 'time',
',', 'thank', 'you', '.']
load bert model over

預(yù)處理數(shù)據(jù)

現(xiàn)在我們基本熟悉了 BERT 的基本使用,接下來為其準(zhǔn)備輸入數(shù)據(jù)。一般情況下,在訓(xùn)練模型前,都需要對手上的數(shù)據(jù)進(jìn)行預(yù)處理,以滿足模型需要。

前面已經(jīng)介紹過了,模型輸入數(shù)據(jù)中,需要通過添加 [CLS][SEP] 這兩個(gè)特殊的token,將文本轉(zhuǎn)換為 BERT 所期望的格式。

首先,需要通過 pip 安裝 Transformers 庫:

%%capture
!pip install transformers

為了更容易理解得到的輸出tokenization,我們以一個(gè)簡短的文本為例。

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
example_text = 'I will watch Memento tonight'
bert_input = tokenizer(example_text,padding='max_length', 
                       max_length = 10, 
                       truncation=True,
                       return_tensors='pt')
# ------- bert_input ------
print(bert_input['input_ids'])
print(bert_input['token_type_ids'])
print(bert_input['attention_mask'])
tensor([[ 101, 146, 1209, 2824, 2508,
26173, 3568, 102, 0, 0]])
tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
tensor([[1, 1, 1, 1, 1, 1, 1, 1, 0, 0]])

下面是對上面BertTokenizer參數(shù)的解釋:

  • padding:將每個(gè)sequence填充到指定的最大長度。
  • max_length: 每個(gè)sequence的最大長度。本示例中我們使用 10,但對于本文實(shí)際數(shù)據(jù)集,我們將使用 512,這是 BERT 允許的sequence 的最大長度。
  • truncation:如果為True,則每個(gè)序列中超過最大長度的標(biāo)記將被截?cái)唷?/section>
  • return_tensors:將返回的張量類型。由于我們使用的是 Pytorch,所以我們使用pt;如果你使用 Tensorflow,那么你需要使用tf。

從上面的變量中看到的輸出bert_input,是用于稍后的 BERT 模型。但是這些輸出是什么意思?

1. 第一行是 input_ids,它是每個(gè) token 的 id 表示。實(shí)際上可以將這些輸入 id 解碼為實(shí)際的 token,如下所示:

example_text = tokenizer.decode(bert_input.input_ids[0])
print(example_text)
'[CLS] I will watch Memento tonight
[SEP] [PAD] [PAD]'

由上述結(jié)果所示,BertTokenizer負(fù)責(zé)輸入文本的所有必要轉(zhuǎn)換,為 BERT 模型的輸入做好準(zhǔn)備。它會(huì)自動(dòng)添加 [CLS][SEP][PAD] token。由于我們指定最大長度為 10,所以最后只有兩個(gè) [PAD] token。

2. 第二行是 token_type_ids,它是一個(gè) binary mask,用于標(biāo)識(shí) token 屬于哪個(gè) sequence。如果我們只有一個(gè) sequence,那么所有的 token 類型 id 都將為 0。對于文本分類任務(wù),token_type_ids是 BERT 模型的可選輸入?yún)?shù)。

3. 第三行是 attention_mask,它是一個(gè) binary mask,用于標(biāo)識(shí) token 是真實(shí) word 還是只是由填充得到。如果 token 包含 [CLS]、[SEP] 或任何真實(shí)單詞,則 mask 將為 1。如果 token 只是 [PAD] 填充,則 mask 將為 0。

注意到,我們使用了一個(gè)預(yù)訓(xùn)練BertTokenizerbert-base-cased模型。如果數(shù)據(jù)集中的文本是英文的,這個(gè)預(yù)訓(xùn)練的分詞器就可以很好地工作。

如果有來自不同語言的數(shù)據(jù)集,可能需要使用bert-base-multilingual-cased。具體來說,如果你的數(shù)據(jù)集是德語、荷蘭語、中文、日語或芬蘭語,則可能需要使用專門針對這些語言進(jìn)行預(yù)訓(xùn)練的分詞器??梢栽诖颂幉榭聪鄳?yīng)的預(yù)訓(xùn)練標(biāo)記器的名稱[1]。特別地,如果數(shù)據(jù)集中的文本是中文的,需要使用bert-base-chinese 模型,以及其相應(yīng)的BertTokenizer等。

數(shù)據(jù)集類

現(xiàn)在我們知道從BertTokenizer中獲得什么樣的輸出,接下來為新聞數(shù)據(jù)集構(gòu)建一個(gè)Dataset類,該類將作為一個(gè)類來將新聞數(shù)據(jù)轉(zhuǎn)換成模型需要的數(shù)據(jù)格式。

上下滑動(dòng)查看更多源碼
import torch
import numpy as np
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-cased')
labels = {'business':0,
          'entertainment':1,
          'sport':2,
          'tech':3,
          'politics':4
          }

class Dataset(torch.utils.data.Dataset):
    def __init__(self, df):
        self.labels = [labels[label] for label in df['category']]
        self.texts = [tokenizer(text, 
                                padding='max_length', 
                                max_length = 512, 
                                truncation=True,
                                return_tensors='pt') 
                      for text in df['text']]

    def classes(self):
        return self.labels

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

    def get_batch_labels(self, idx):
        # Fetch a batch of labels
        return np.array(self.labels[idx])

    def get_batch_texts(self, idx):
        # Fetch a batch of inputs
        return self.texts[idx]

    def __getitem__(self, idx):
        batch_texts = self.get_batch_texts(idx)
        batch_y = self.get_batch_labels(idx)
        return batch_texts, batch_y

在上面實(shí)現(xiàn)的代碼中,我們定義了一個(gè)名為 labels的變量,它是一個(gè)字典,將DataFrame中的 category 映射到 labels的 id 表示。注意,上面的__init__函數(shù)中,還調(diào)用了BertTokenizer將輸入文本轉(zhuǎn)換為 BERT 期望的向量格式。

定義Dataset類后,將數(shù)據(jù)框拆分為訓(xùn)練集、驗(yàn)證集和測試集,比例為 80:10:10。

np.random.seed(112)
df_train, df_val, df_test = np.split(df.sample(frac=1, random_state=42), 
                                     [int(.8*len(df)), int(.9*len(df))])

print(len(df_train),len(df_val), len(df_test))
1780 222 223

構(gòu)建模型

至此,我們已經(jīng)成功構(gòu)建了一個(gè) Dataset 類來生成模型輸入數(shù)據(jù)?,F(xiàn)在使用具有 12 層 Transformer 編碼器的預(yù)訓(xùn)練 BERT 基礎(chǔ)模型構(gòu)建實(shí)際模型。

如果數(shù)據(jù)集中的文本是中文的,需要使用bert-base-chinese 模型。

from torch import nn
from transformers import BertModel

class BertClassifier(nn.Module):
    def __init__(self, dropout=0.5):
        super(BertClassifier, self).__init__()
        self.bert = BertModel.from_pretrained('bert-base-cased')
        self.dropout = nn.Dropout(dropout)
        self.linear = nn.Linear(768, 5)
        self.relu = nn.ReLU()

    def forward(self, input_id, mask):
        _, pooled_output = self.bert(input_ids= input_id, attention_mask=mask,return_dict=False)
        dropout_output = self.dropout(pooled_output)
        linear_output = self.linear(dropout_output)
        final_layer = self.relu(linear_output)
        return final_layer

從上面的代碼可以看出,BERT 模型輸出了兩個(gè)變量:

  • 在上面的代碼中命名的第一個(gè)變量_包含sequence中所有 token 的 Embedding 向量層。
  • 命名的第二個(gè)變量pooled_output包含 [CLS] token 的 Embedding 向量。對于文本分類任務(wù),使用這個(gè) Embedding 作為分類器的輸入就足夠了。

然后將pooled_output變量傳遞到具有 ReLU 激活函數(shù)的線性層。在線性層中輸出一個(gè)維度大小為 5 的向量,每個(gè)向量對應(yīng)于標(biāo)簽類別(運(yùn)動(dòng)、商業(yè)、政治、 娛樂和科技)。

訓(xùn)練模型

接下來是訓(xùn)練模型。使用標(biāo)準(zhǔn)的 PyTorch 訓(xùn)練循環(huán)來訓(xùn)練模型。

上下滑動(dòng)查看更多源碼

from torch.optim import Adam
from tqdm import tqdm

def train(model, train_data, val_data, learning_rate, epochs):
  # 通過Dataset類獲取訓(xùn)練和驗(yàn)證集
    train, val = Dataset(train_data), Dataset(val_data)
    # DataLoader根據(jù)batch_size獲取數(shù)據(jù),訓(xùn)練時(shí)選擇打亂樣本
    train_dataloader = torch.utils.data.DataLoader(train, batch_size=2, shuffle=True)
    val_dataloader = torch.utils.data.DataLoader(val, batch_size=2)
  # 判斷是否使用GPU
    use_cuda = torch.cuda.is_available()
    device = torch.device('cuda' if use_cuda else 'cpu')
    # 定義損失函數(shù)和優(yōu)化器
    criterion = nn.CrossEntropyLoss()
    optimizer = Adam(model.parameters(), lr=learning_rate)

    if use_cuda:
            model = model.cuda()
            criterion = criterion.cuda()
    # 開始進(jìn)入訓(xùn)練循環(huán)
    for epoch_num in range(epochs):
      # 定義兩個(gè)變量,用于存儲(chǔ)訓(xùn)練集的準(zhǔn)確率和損失
            total_acc_train = 0
            total_loss_train = 0
      # 進(jìn)度條函數(shù)tqdm
            for train_input, train_label in tqdm(train_dataloader):

                train_label = train_label.to(device)
                mask = train_input['attention_mask'].to(device)
                input_id = train_input['input_ids'].squeeze(1).to(device)
        # 通過模型得到輸出
                output = model(input_id, mask)
                # 計(jì)算損失
                batch_loss = criterion(output, train_label)
                total_loss_train += batch_loss.item()
                # 計(jì)算精度
                acc = (output.argmax(dim=1) == train_label).sum().item()
                total_acc_train += acc
        # 模型更新
                model.zero_grad()
                batch_loss.backward()
                optimizer.step()
            # ------ 驗(yàn)證模型 -----------
            # 定義兩個(gè)變量,用于存儲(chǔ)驗(yàn)證集的準(zhǔn)確率和損失
            total_acc_val = 0
            total_loss_val = 0
      # 不需要計(jì)算梯度
            with torch.no_grad():
                # 循環(huán)獲取數(shù)據(jù)集,并用訓(xùn)練好的模型進(jìn)行驗(yàn)證
                for val_input, val_label in val_dataloader:
          # 如果有GPU,則使用GPU,接下來的操作同訓(xùn)練
                    val_label = val_label.to(device)
                    mask = val_input['attention_mask'].to(device)
                    input_id = val_input['input_ids'].squeeze(1).to(device)
  
                    output = model(input_id, mask)

                    batch_loss = criterion(output, val_label)
                    total_loss_val += batch_loss.item()
                    
                    acc = (output.argmax(dim=1) == val_label).sum().item()
                    total_acc_val += acc
            
            print(
                f'''Epochs: {epoch_num + 1} 
              | Train Loss: {total_loss_train / len(train_data): .3f} 
              | Train Accuracy: {total_acc_train / len(train_data): .3f} 
              | Val Loss: {total_loss_val / len(val_data): .3f} 
              | Val Accuracy: {total_acc_val / len(val_data): .3f}''')           

我們對模型進(jìn)行了 5 個(gè) epoch 的訓(xùn)練,我們使用 Adam 作為優(yōu)化器,而學(xué)習(xí)率設(shè)置為1e-6。因?yàn)楸景咐惺翘幚矶囝惙诸悊栴},則使用分類交叉熵作為我們的損失函數(shù)。

建議使用 GPU 來訓(xùn)練模型,因?yàn)?BERT 基礎(chǔ)模型包含 1.1 億個(gè)參數(shù)。

EPOCHS = 5
model = BertClassifier()
LR = 1e-6
train(model, df_train, df_val, LR, EPOCHS)

顯然,由于訓(xùn)練過程的隨機(jī)性,每次可能不會(huì)得到與上面截圖類似的損失和準(zhǔn)確率值。如果在 5 個(gè) epoch 之后沒有得到好的結(jié)果,可以嘗試將 epoch 增加到 10 個(gè),或者調(diào)整學(xué)習(xí)率。

在測試數(shù)據(jù)上評估模型

現(xiàn)在我們已經(jīng)訓(xùn)練了模型,我們可以使用測試數(shù)據(jù)來評估模型在未見數(shù)據(jù)上的性能。下面是評估模型在測試集上的性能的函數(shù)。

def evaluate(model, test_data):

    test = Dataset(test_data)
    test_dataloader = torch.utils.data.DataLoader(test, batch_size=2)
    use_cuda = torch.cuda.is_available()
    device = torch.device('cuda' if use_cuda else 'cpu')
    if use_cuda:
        model = model.cuda()

    total_acc_test = 0
    with torch.no_grad():
        for test_input, test_label in test_dataloader:
              test_label = test_label.to(device)
              mask = test_input['attention_mask'].to(device)
              input_id = test_input['input_ids'].squeeze(1).to(device)
              output = model(input_id, mask)
              acc = (output.argmax(dim=1) == test_label).sum().item()
              total_acc_test += acc   
    print(f'Test Accuracy: {total_acc_test / len(test_data): .3f}')
    
evaluate(model, df_test)

運(yùn)行上面的代碼后,我從測試數(shù)據(jù)中得到了 0.994 的準(zhǔn)確率。由于訓(xùn)練過程中的隨機(jī)性,將獲得的準(zhǔn)確度可能會(huì)與我的結(jié)果略有不同。

討論兩個(gè)問題

這里有個(gè)問題:使用BERT預(yù)訓(xùn)練模型為什么最多只能輸入512個(gè)詞,最多只能兩個(gè)句子合成一句?

這是Google BERT預(yù)訓(xùn)練模型初始設(shè)置的原因,前者對應(yīng)Position Embeddings,后者對應(yīng)Segment Embeddings

在BERT中,Token,Position,Segment Embeddings 都是通過學(xué)習(xí)來得到的,pytorch代碼中它們是這樣的

self.word_embeddings = Embedding(config.vocab_size, config.hidden_size)
self.position_embeddings = Embedding(config.max_position_embeddings, config.hidden_size)
self.token_type_embeddings = Embedding(config.type_vocab_size, config.hidden_size)

而在BERT config中

'max_position_embeddings': 512
'type_vocab_size': 2

因此,在直接使用 Google 的 BERT 預(yù)訓(xùn)練模型時(shí),輸入最多512個(gè)詞(還要除掉[CLS]和[SEP]),最多兩個(gè)句子合成一句。這之外的詞和句子會(huì)沒有對應(yīng)的 Embedding 。

當(dāng)然,如果有足夠的硬件資源自己重新訓(xùn)練 BERT,可以更改 BERT config,設(shè)置更大 max_position_embeddingstype_vocab_size 值去滿足自己的需求。

此外還有人問 BERT的三個(gè)Embedding直接相加會(huì)對語義有影響嗎?

這是一個(gè)非常有意思的問題,蘇劍林老師也給出了回答,真的很妙?。?/p>

Embedding 的數(shù)學(xué)本質(zhì),就是以 one hot 為輸入的單層全連接。也就是說,世界上本沒什么 Embedding,有的只是one hot。

在這里想用一個(gè)例子再嘗試解釋一下:

假設(shè) token Embedding 矩陣維度是 [4,768];position Embedding 矩陣維度是 [3,768];segment Embedding 矩陣維度是 [2,768]。

對于一個(gè)字,假設(shè)它的 token one-hot 是[1,0,0,0];它的 position one-hot 是[1,0,0];它的 segment one-hot 是[1,0]。

那這個(gè)字最后的 word Embedding,就是上面三種 Embedding 的加和。

如此得到的 word Embedding,和concat后的特征:[1,0,0,0,1,0,0,1,0],再過維度為 [4+3+2,768] = [9, 768] 的全連接層,得到的向量其實(shí)就是一樣的。

再換一個(gè)角度理解:

直接將三個(gè)one-hot 特征 concat 起來得到的 [1,0,0,0,1,0,0,1,0] 不再是one-hot了,但可以把它映射到三個(gè)one-hot 組成的特征空間,空間維度是 432=24 ,那在新的特征空間,這個(gè)字的one-hot就是[1,0,0,0,0...] (23個(gè)0)。

此時(shí),Embedding 矩陣維度就是 [24,768],最后得到的 word Embedding 依然是和上面的等效,但是三個(gè)小 Embedding 矩陣的大小會(huì)遠(yuǎn)小于新特征空間對應(yīng)的 Embedding 矩陣大小。

當(dāng)然,在相同初始化方法前提下,兩種方式得到的 word Embedding 可能方差會(huì)有差別,但是,BERT還有Layer Norm,會(huì)把 Embedding 結(jié)果統(tǒng)一到相同的分布。

BERT的三個(gè)Embedding相加,本質(zhì)可以看作一個(gè)特征的融合,強(qiáng)大如 BERT 應(yīng)該可以學(xué)到融合后特征的語義信息的

這就是 BERT 期望的所有輸入。

然后,BERT 模型將在每個(gè)token中輸出一個(gè)大小為 768 的 Embedding 向量。我們可以將這些向量用作不同類型 NLP 任務(wù)的輸入,無論是文本分類、本文生成、命名實(shí)體識(shí)別 (NER) 還是問答。

對于文本分類任務(wù),我們將注意力集中在特殊 [CLS] token 的 embedding 向量輸出上。這意味著我們將使用具有 [CLS] token 的大小為 768 的 embedding 向量作為分類器的輸入,然后它將輸出一個(gè)大小為分類任務(wù)中類別個(gè)數(shù)的向量。

寫在最后

現(xiàn)在我們?nèi)鐚W(xué)會(huì)了何利用 Hugging Face 的預(yù)訓(xùn)練 BERT 模型進(jìn)行文本分類任務(wù)的步驟。我希望在你開始使用 BERT是,這篇文章能幫到你。我們不僅可以使用來自 BERT 的embedding向量來執(zhí)行句子或文本分類任務(wù),還可以執(zhí)行更高級的 NLP 應(yīng)用,例如問答、文本生成或命名實(shí)體識(shí)別 (NER)任務(wù)。

參考資料

[1]

預(yù)訓(xùn)練標(biāo)記器的名稱: https://huggingface.co/transformers/pretrained_models.html

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ACL 2021|美團(tuán)提出基于對比學(xué)習(xí)的文本表示模型,效果提升8%
論文解讀:Bert原理深入淺出
圖解BERT模型:從零開始構(gòu)建BERT
內(nèi)存用量1/20,速度加快80倍,騰訊QQ提出全新BERT蒸餾框架,未來將開源
BEIT:基于圖像重建進(jìn)行預(yù)訓(xùn)練!微軟提出BEIT,Top-1準(zhǔn)確率達(dá)86.3%!代碼已開源!
基于HybridDL模型的文本相似度檢測方法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服