gpt4 book ai didi

python - 如何使用 bert 嵌入而不是 glove/fasttext 等静态嵌入来训练神经网络模型?

转载 作者:太空宇宙 更新时间:2023-11-03 13:26:06 24 4
gpt4 key购买 nike

我正在寻找一些提示来训练具有动态生成的 bert 嵌入的传统神经网络模型(BERT 上下文化嵌入,当出现在不同的上下文中时,它会为同一个词生成不同的嵌入)。

在普通的神经网络模型中,我们会用 glove 或 fasttext 嵌入来初始化模型,比如,

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 层:

  1. 您可以将生成 BERT 嵌入整合到数据预处理管道中。您将需要使用 BERT 自己的分词器和 word-to-ids 字典。 repo 协议(protocol)的 README有预处理的例子。

您可以编写一个循环来为这样的字符串生成 BERT token (假设 - 因为 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 张量,您可以将其用作模型的输入。

提供了完整的(和更合适的)代码 here

这种方法的优点是不必在每个时期都重新计算这些嵌入。

使用这种方法,例如,对于分类,您的模型应该只包含一个Linear(bert_model.config.hidden_​​size, num_labels) 层,模型的输入应该是结果 上面代码中的张量

  1. 第二种方法,可以说是更简洁的方法:如果您查看 repo ,您会发现有各种任务的包装器(例如 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.

之后您可以继续进行预处理,直到生成 token ID。然后你可以训练整个模型(但学习率较低,例如 Adam 3e-5 for batch_size = 32)

有了它,您可以微调 BERT 的嵌入本身,或使用诸如将 BERT 卡住几个时期以仅训练分类器,然后解冻以进行微调等技术。但它的计算成本也更高。

repo 中也提供了一个例子

关于python - 如何使用 bert 嵌入而不是 glove/fasttext 等静态嵌入来训练神经网络模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55369821/

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