【问题标题】:Spacy's BERT model doesn't learnSpacy 的 BERT 模型不学习
【发布时间】:2020-09-08 14:36:34
【问题描述】:

我一直在尝试使用 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}

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

有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2019-09-20
      • 1970-01-01
      • 2020-09-30
      • 2018-02-25
      • 2020-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      相关资源
      最近更新 更多