Spacy的BERT模型无法学习

时间:2020-05-21 20:35:55

标签: python spacy text-classification multiclass-classification bert-language-model

我一直在尝试使用spaCy的预训练BERT模型de_trf_bertbasecased_lg来提高分类项目的准确性。我曾经使用de_core_news_sm从头开始构建模型,并且一切正常:我的准确率约为70%。但是现在我改为使用BERT预训练模型,并且我获得了0%的准确性。我不认为它的工作如此糟糕,所以我假设我的代码只是一个问题。我可能错过了一些重要的事情,但我不知道是什么。我以this article中的代码为例。

这是我的代码:

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%。我不明白自己在做什么错。

在此先感谢您的帮助!

更新

试图理解上述问题,我决定仅使用几个示例尝试该模型(就像建议使用here一样)。这是代码:

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}

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

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

GitHub上收到了我的问题的答案,好像必须指定一些优化程序参数,就像在this example中一样。