有没有一种方法可以优化SpaCy培训?

时间:2020-09-04 20:08:58

标签: python performance machine-learning spacy

我目前正在训练用于多标签文本分类的SpaCy模型。有6个标签:愤怒,预期,厌恶,恐惧,喜悦,悲伤,惊讶和信任。数据集超过200k。但是,每个时期需要4个小时。我想知道是否有一种方法可以优化训练并更快地进行训练,也许我在这里跳过了一些可以改善模型的事情。


TRAINING_DATA

TRAIN_DATA = list(zip(train_texts, [{"cats": cats} for cats in final_train_cats]))

[...
  {'cats': {'anger': 1,
    'anticipation': 0,
    'disgust': 0,
    'fear': 0,
    'joy': 0,
    'sadness': 0,
    'surprise': 0,
    'trust': 0}}),
 ('mausoleum',
  {'cats': {'anger': 1,
    'anticipation': 0,
    'disgust': 0,
    'fear': 0,
    'joy': 0,
    'sadness': 0,
    'surprise': 0,
    'trust': 0}}),
 ...]

培训

nlp = spacy.load("en_core_web_sm")
category = nlp.create_pipe("textcat", config={"exclusive_classes": True})
nlp.add_pipe(category)

# add label to text classifier
category.add_label("trust")
category.add_label("fear")
category.add_label("disgust")
category.add_label("surprise")
category.add_label("anticipation")
category.add_label("anger")
category.add_label("joy")

optimizer = nlp.begin_training()
losses = {}

for i in range(100):
    random.shuffle(TRAIN_DATA)

    print('...')
    for batch in minibatch(TRAIN_DATA, size=8):
        texts = [nlp(text) for text, entities in batch]
        annotations = [{"cats": entities} for text, entities in batch]
        nlp.update(texts, annotations, sgd=optimizer, losses=losses)
    print(i, losses)

...
0 {'parser': 0.0, 'tagger': 27.018985521040854, 'textcat': 0.0, 'ner': 0.0}
...
1 {'parser': 0.0, 'tagger': 27.01898552104131, 'textcat': 0.0, 'ner': 0.0}
...

1 个答案:

答案 0 :(得分:0)

“ 20万条记录的数据集每个周期要花费4个小时”并不能告诉我们很多东西:

  1. 确保您没有耗尽内存(对吗?)它占用了多少RAM?
  2. 由于GIL,您可能正在运行单线程。参见例如this讨论如何关闭GIL以运行训练多核。您有几个核心?
  • texts = [nlp(text) ...]放入内部循环for batch in minibatch(TRAIN_DATA, size=8):似乎很麻烦,因为即使在处理输入文本时C语言库字符串调用只需要它,代码也将始终保持GIL, parser阶段,不用于培训。
  • 重构代码,以便首先在所有输入上运行nlp()管道,然后保存一些中间表示(数组或其他内容)。将代码与训练循环分开,以便训练可以是多线程的。
  1. 我无法评论您选择的minibatch()参数,但是8个参数似乎很小,这些参数似乎对性能至关重要,因此请尝试对其进行调整(/ grid-search一些值)。
  2. 最后,一旦您首先检查了上述所有内容,便找到了速度最快的单核/多核设备,并具有足够的RAM。