当我过去使用textcnn进行分类工作时,我有经验使用预先训练过的单词嵌入(比如Word2Vec和fasttext文本)来细化textcnn。我用这个过程:
最近我也想试试伯特。我想,“由于使用BERT预训练的嵌入到初始其他网络的嵌入层和细化应该没有什么不同,所以应该很容易!”但事实上,昨天我试了一整天,但还是做不到。
我发现,由于BERT的嵌入是一种上下文嵌入,特别是在提取单词嵌入时,每个单词的向量都会有所不同,因此似乎无法像通常那样使用该嵌入来初始化另一个网络的嵌入层。
最后,我想出了一个“finetuning”方法,如下所示:
首先,在textcnn.
通过使用这种方法,我终于可以训练,但认真思考,我认为我根本没有做一个最后的……
因为正如你所看到的,每次当我开始新的训练循环时,从BERT生成的单词嵌入总是相同的向量,所以只要将这些不变的向量输入textcnn就不会让textcnn被细化,对吗?
更新:--我想出了一种新的方法,将伯特嵌入和“训练”BERT和textcnn放在一起使用。
我代码的一部分是:
BERTmodel = AutoModel.from_pretrained('bert-
base-uncased',output_hidden_states=True).to(device)
TextCNNmodel = TextCNN(EMBD_DIM, CLASS_NUM, KERNEL_NUM,
KERNEL_SIZES).to(device)
optimizer = torch.optim.Adam(TextCNNmodel.parameters(), lr=LR)
loss_func = nn.CrossEntropyLoss() for epoch in range(EPOCH):
TextCNNmodel.train()
BERTmodel.train()
for step, (token_batch, seg_batch, y_batch) in enumerate(train_loader):
token_batch = token_batch.to(device)
y_batch = y_batch.to(device)
BERToutputs = BERTmodel(token_batch)
# I want to use the second-to-last hidden layer as the embedding, so
x_batch = BERToutputs[2][-2]
output = TextCNNmodel(x_batch)
output = output.squeeze()
loss = loss_func(output, y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()我认为,在获得嵌入时,通过启用BERTmodel.train()和删除torch.no_grad(),损失梯度也可以返回到BERTmodel。TextCNNmodel的训练过程也进行顺利。
为了以后使用这个模型,我保存了TextCNNmodel和BERTmodel的参数。
然后,为了测试BERTmodel是否真的被训练和修改,在另一个程序中,我加载了BERTModel,并输入一个句子来测试BERTModel是否真的被训练了。
然而,我发现原来的‘bert-base’模型和我的'BERTmodel‘的输出(嵌入)是相同的,这是令人失望的.
我真的不知道为什么BERTmodel部分没有改变.
发布于 2021-01-20 15:23:09
在这里,我要感谢@Jindřich,谢谢您给我一个重要的提示!
当我使用更新的版本代码时,我想我已经快到了,但是我忘记为BERTmodel设置一个优化器。
在我设置了优化器并再次执行了培训过程之后,这一次当我加载我的BERTmodel时,我发现原始‘bert-base’模型和我的' BERTmodel‘的输出(嵌入)最终是不同的,这意味着这个BERTmodel被改变了,应该被细化。
这是我的最后密码,希望它也能帮到你。
BERTmodel = AutoModel.from_pretrained('bert-
base-uncased',output_hidden_states=True).to(device)
TextCNNmodel = TextCNN(EMBD_DIM, CLASS_NUM, KERNEL_NUM,
KERNEL_SIZES).to(device)
optimizer = torch.optim.Adam(TextCNNmodel.parameters(), lr=LR)
optimizer_bert = torch.optim.Adamw(BERTmodel.parameters(), lr=2e-5, weight_decay=1e-2)
loss_func = nn.CrossEntropyLoss() for epoch in range(EPOCH):
TextCNNmodel.train()
BERTmodel.train()
for step, (token_batch, seg_batch, y_batch) in enumerate(train_loader):
token_batch = token_batch.to(device)
y_batch = y_batch.to(device)
BERToutputs = BERTmodel(token_batch)
# I want to use the second-to-last hidden layer as the embedding, so
x_batch = BERToutputs[2][-2]
output = TextCNNmodel(x_batch)
output = output.squeeze()
loss = loss_func(output, y_batch)
optimizer.zero_grad()
optimizer_bert.zero_grad()
loss.backward()
optimizer.step()
optimizer_bert.step()我将继续我的实验,看看我的BERTmodel是否真的被细化了。
https://stackoverflow.com/questions/65802782
复制相似问题