[英]How to train a neural network model with bert embeddings instead of static embeddings like glove/fasttext?
我正在尋找一些能夠用動態生成的bert嵌入來訓練傳統神經網絡模型(BERT上下文嵌入,為不同的上下文生成相同單詞的嵌入)。
在正常的神經網絡模型中,我們將使用手套或快速文本嵌入來初始化模型,如
import torch.nn as nn
embed = nn.Embedding(vocab_size, vector_size)
embed.weight.data.copy_(some_variable_containing_vectors)
我沒有像這樣復制靜態向量並將其用於訓練,而是希望將每個輸入傳遞給BERT模型並為動態的單詞生成嵌入,並將它們提供給模型進行訓練。
那么我是否應該改變模型中的前向函數來合並這些嵌入?
任何幫助,將不勝感激!
如果你使用的是Pytorch。 你可以使用https://github.com/huggingface/pytorch-pretrained-BERT這是Pytorch最流行的BERT實現(它也是一個pip包!)。 在這里,我將概述如何正確使用它。
對於這個特殊問題,有兩種方法 - 你顯然不能使用Embedding
層:
你可以編寫一個循環來為這樣的字符串生成BERT令牌(假設 - 因為BERT消耗了大量的GPU內存):
(注意:為了更合適你還應該添加注意面具 - 這是1和0的LongTensor屏蔽句子長度)
import torch
from pytorch_pretrained_bert import BertTokenizer, BertModel
batch_size = 32
X_train, y_train = samples_from_file('train.csv') # Put your own data loading function here
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
X_train = [tokenizer.tokenize('[CLS] ' + sent + ' [SEP]') for sent in X_train] # Appending [CLS] and [SEP] tokens - this probably can be done in a cleaner way
bert_model = BertModel.from_pretrained('bert-base-uncased')
bert_model = bert_model.cuda()
X_train_tokens = [tokenizer.convert_tokens_to_ids(sent) for sent in X_train]
results = torch.zeros((len(X_test_tokens), bert_model.config.hidden_size)).long()
with torch.no_grad():
for stidx in range(0, len(X_test_tokens), batch_size):
X = X_test_tokens[stidx:stidx + batch_size]
X = torch.LongTensor(X).cuda()
_, pooled_output = bert_model(X)
results[stidx:stidx + batch_size,:] = pooled_output.cpu()
之后,您將獲得包含計算嵌入的results
張量,您可以將其用作模型的輸入。
這個完整的(更合適)提供代碼, 在這里
該方法的優點是不必在每個時期重新計算這些嵌入。
使用此方法,例如,對於分類,您的模型應僅包含Linear(bert_model.config.hidden_size, num_labels)
圖層,模型的輸入應為上述代碼中的results
張量
BertForSequenceClassification
)。 實現從BertPretrainedModel
繼承的自定義類並使用repo中的各種Bert類也應該很容易。 例如,您可以使用:
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', labels=num_labels) # Where num_labels is the number of labels you need to classify.
之后,您可以繼續進行預處理,直到生成令牌ID。 然后你可以訓練整個模型(但學習率很低,例如對於batch_size
= 32,亞當3e-5)
有了這個,你可以微調BERT的嵌入本身,或者使用諸如凍結BERT幾個時代的技術來訓練分類器,然后解凍微調等等。但它的計算成本也更高。
回購中還提供了一個例子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.