Spacy的BERT模型无法学习



我一直在尝试使用spaCy的预训练BERT模型de_trf_bertbasecased_lg来提高我的分类项目的准确性。我曾经使用de_core_news_sm从头开始构建模型,一切正常:我的准确率约为 70%。但是现在我正在使用BERT预训练模型,并且我得到了0%的准确率。我不相信它工作得那么糟糕,所以我假设我的代码只是有问题。我可能错过了一些重要的东西,但我无法弄清楚是什么。我以本文中的代码为例。

这是我的代码:

import spacy
from spacy.util import minibatch
from random import shuffle
spacy.require_gpu()
nlp = spacy.load('de_trf_bertbasecased_lg')
data = get_data()  # get_data() function returns a list with train data (I'll explain later how it looks)
textcat = nlp.create_pipe("trf_textcat", config={"exclusive_classes": False})
for category in categories:  # categories - a list of 21 different categories used for classification
textcat.add_label(category)
nlp.add_pipe(textcat)
num = 0  # number used for counting batches
optimizer = nlp.resume_training()
for i in range(2):
shuffle(data)
losses = {}
for batch in minibatch(data):
texts, cats = zip(*batch)
nlp.update(texts, cats, sgd=optimizer, losses=losses)
num += 1
if num % 10000 == 0:  # test model's performance every 10000 batches
acc = test(nlp)  # function test() will be explained later
print(f'Accuracy: {acc}')
nlp.to_disk('model/')

函数get_data()打开不同类别的文件,创建一个像(text, {'cats' : {'category1': 0, 'category2':1, ...}})这样的元组,将所有这些元组收集到一个数组中,然后将其返回到主函数。

函数test(nlp)打开包含测试数据的文件,预测文件中每一行的类别并检查预测是否正确。

同样,de_core_news_sm一切都很好,所以我很确定get_data()test(nlp)的功能工作正常。上面的代码看起来像示例,但准确性仍然为 0%。我不明白我做错了什么。

提前感谢任何帮助!

更新

为了理解上述问题,我决定只用几个例子来尝试这个模型(就像这里建议的那样(。这是代码:

import spacy
from spacy.util import minibatch
import random
import torch
train_data = [
("It is realy cool", {"cats": {"POSITIVE": 1.0, "NEGATIVE": 0.0}}),
("I hate it", {"cats": {"POSITIVE": 0.0, "NEGATIVE": 1.0}})
]
is_using_gpu = spacy.prefer_gpu()
if is_using_gpu:
torch.set_default_tensor_type("torch.cuda.FloatTensor")
nlp = spacy.load("en_trf_bertbaseuncased_lg")
textcat = nlp.create_pipe("trf_textcat", config={"exclusive_classes": True})
for label in ("POSITIVE", "NEGATIVE"):
textcat.add_label(label)
nlp.add_pipe(textcat)
optimizer = nlp.resume_training()
for i in range(10):
random.shuffle(train_data)
losses = {}
for batch in minibatch(train_data):
texts, cats = zip(*batch)
nlp.update(texts, cats, sgd=optimizer, losses=losses)
print(i, losses)
print()
test_data = [
"It is really cool",
"I hate it",
"Great!",
"I do not think this is cool"
]
for line in test_data:
print(line)
print(nlp(line).cats)

输出是:

0 {'trf_textcat': 0.125}
1 {'trf_textcat': 0.12423406541347504}
2 {'trf_textcat': 0.12188033014535904}
3 {'trf_textcat': 0.12363225221633911}
4 {'trf_textcat': 0.11996611207723618}
5 {'trf_textcat': 0.14696261286735535}
6 {'trf_textcat': 0.12320466339588165}
7 {'trf_textcat': 0.12096124142408371}
8 {'trf_textcat': 0.15916231274604797}
9 {'trf_textcat': 0.1238454058766365}
It is really cool
{'POSITIVE': 0.47827497124671936, 'NEGATIVE': 0.5217249989509583}
I hate it
{'POSITIVE': 0.47827598452568054, 'NEGATIVE': 0.5217240452766418}
Great!
{'POSITIVE': 0.4782750606536865, 'NEGATIVE': 0.5217249393463135}
I do not think this is cool
{'POSITIVE': 0.478275328874588, 'NEGATIVE': 0.5217246413230896}

不仅模型表现不佳,损失也没有变小,所有测试句子的分数几乎相同。最重要的是:它甚至没有正确回答这些问题,这恰好在火车数据中。所以我的问题是:模型甚至学习吗?我做错了什么?

有什么想法吗?

在 GitHub 上收到了我问题的答案,看起来必须指定一些优化器参数,就像本例中一样。

相关内容

  • 没有找到相关文章

最新更新