更多实时更新的个人学习笔记分享,请关注:
知乎:https://www.zhihu.com/people/yuquanle/columns
微信订阅号:AI小白入门
ID: StudyForAI

<center> </center>

Flair工具使用教程之如何训练自己的模型


训练序列标记模型

  • 下面是使用简单的GloVe嵌入对CoNLL-03数据训练的小型NER模型的示例代码。 要运行此代码,首先需要获取CoNLL-03英语数据集(或者,使用NLPTaskDataFetcher.load_corpus(NLPTask.WNUT)代替具有免费可用数据的任务)。
  • 作者提供复现他论文效果的代码:zalandoresearch/flair
  • 在此示例中,我们将数据下采样到原始数据的10%:
from flair.data import TaggedCorpus
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
from flair.embeddings import TokenEmbeddings, WordEmbeddings, StackedEmbeddings
from typing import List

# 1. get the corpus
corpus: TaggedCorpus = NLPTaskDataFetcher.load_corpus(NLPTask.CONLL_03).downsample(0.1)
print(corpus)

# 2. what tag do we want to predict?
tag_type = 'ner'

# 3. make the tag dictionary from the corpus
tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
print(tag_dictionary.idx2item)

# 4. initialize embeddings
embedding_types: List[TokenEmbeddings] = [

    WordEmbeddings('glove'),

    # comment in this line to use character embeddings
    # CharacterEmbeddings(),

    # comment in these lines to use flair embeddings
    # FlairEmbeddings('news-forward'),
    # FlairEmbeddings('news-backward'),
]

embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)

# 5. initialize sequence tagger
from flair.models import SequenceTagger

tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                        embeddings=embeddings,
                                        tag_dictionary=tag_dictionary,
                                        tag_type=tag_type,
                                        use_crf=True)

# 6. initialize trainer
from flair.trainers import ModelTrainer

trainer: ModelTrainer = ModelTrainer(tagger, corpus)

# 7. start training
trainer.train('resources/taggers/example-ner',
              learning_rate=0.1,
              mini_batch_size=32,
              max_epochs=150)

# 8. plot training curves (optional)
from flair.visual.training_curves import Plotter
plotter = Plotter()
plotter.plot_training_curves('resources/taggers/example-ner/loss.tsv')
plotter.plot_weights('resources/taggers/example-ner/weights.txt')

训练文本分类模型

  • 下面是使用简单的GloVe嵌入和Flair嵌入的组合,在AGNews语料库上训练文本分类器的示例代码。
  • 您需要先下载AGNews才能运行此代码。 AGNews语料库下载地址AG’s corpus of news articles:
  • 在此示例中,我们将数据下采样到原始数据的10%。
from flair.data import TaggedCorpus
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
from flair.embeddings import WordEmbeddings, FlairEmbeddings, DocumentLSTMEmbeddings
from flair.models import TextClassifier
from flair.trainers import ModelTrainer


# 1. get the corpus
corpus: TaggedCorpus = NLPTaskDataFetcher.load_corpus(NLPTask.AG_NEWS, 'path/to/data/folder').downsample(0.1)

# 2. create the label dictionary
label_dict = corpus.make_label_dictionary()

# 3. make a list of word embeddings
word_embeddings = [WordEmbeddings('glove'),

                   # comment in flair embeddings for state-of-the-art results 
                   # FlairEmbeddings('news-forward'),
                   # FlairEmbeddings('news-backward'),
                   ]

# 4. init document embedding by passing list of word embeddings
document_embeddings: DocumentLSTMEmbeddings = DocumentLSTMEmbeddings(word_embeddings,
                                                                     hidden_size=512,
                                                                     reproject_words=True,
                                                                     reproject_words_dimension=256,
                                                                     )

# 5. create the text classifier
classifier = TextClassifier(document_embeddings, label_dictionary=label_dict, multi_label=False)

# 6. initialize the text classifier trainer
trainer = ModelTrainer(classifier, corpus)

# 7. start the training
trainer.train('resources/taggers/ag_news',
              learning_rate=0.1,
              mini_batch_size=32,
              anneal_factor=0.5,
              patience=5,
              max_epochs=150)

# 8. plot training curves (optional)
from flair.visual.training_curves import Plotter
plotter = Plotter()
plotter.plot_training_curves('resources/taggers/ag_news/loss.tsv')
plotter.plot_weights('resources/taggers/ag_news/weights.txt')

训练模型后,您可以加载它来预测新句子的类别。 只需调用模型的预测(predict)方法即可。

classifier = TextClassifier.load_from_file('resources/taggers/ag_news/final-model.pt')

# create example sentence
sentence = Sentence('France is the current world cup winner.')

# predict tags and print
classifier.predict(sentence)

print(sentence.labels)

多数据集训练

  • 现在,让我们训练一个可以用英语和德语标记PoS标签文本的模型。 为此,我们加载英语和德语UD语料库并创建MultiCorpus对象。 我们还使用新的多语言Flair嵌入来完成此任务。
  • 请注意,这里我们使用MICRO_ACCURACY评估指标而不是默认的MICRO_F1_SCORE。
  • 所有其余的都和以前一样,例如:
from typing import List
from flair.data import MultiCorpus
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
from flair.embeddings import FlairEmbeddings, TokenEmbeddings, StackedEmbeddings
from flair.training_utils import EvaluationMetric


# 1. get the corpora - English and German UD
corpus: MultiCorpus = NLPTaskDataFetcher.load_corpora([NLPTask.UD_ENGLISH, NLPTask.UD_GERMAN]).downsample(0.1)

# 2. what tag do we want to predict?
tag_type = 'upos'

# 3. make the tag dictionary from the corpus
tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
print(tag_dictionary.idx2item)

# 4. initialize embeddings
embedding_types: List[TokenEmbeddings] = [

    # we use multilingual Flair embeddings in this task
    FlairEmbeddings('multi-forward'),
    FlairEmbeddings('multi-backward'),
]

embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)

# 5. initialize sequence tagger
from flair.models import SequenceTagger

tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                        embeddings=embeddings,
                                        tag_dictionary=tag_dictionary,
                                        tag_type=tag_type,
                                        use_crf=True)

# 6. initialize trainer
from flair.trainers import ModelTrainer

trainer: ModelTrainer = ModelTrainer(tagger, corpus)

# 7. start training
trainer.train('resources/taggers/example-universal-pos',
              learning_rate=0.1,
              mini_batch_size=32,
              max_epochs=150,
              evaluation_metric=EvaluationMetric.MICRO_ACCURACY)

绘制训练曲线和权重

  • Flair包括一个辅助方法,用于绘制神经网络中的训练曲线和权重。 ModelTrainer自动在结果文件夹中生成loss.tsv和weights.txt文件。
  • 训练之后,简单地将绘图仪指向这些文件。
  • 这会在结果文件夹中生成PNG图。
from flair.visual.training_curves import Plotter
plotter = Plotter()
plotter.plot_training_curves('loss.tsv')
plotter.plot_weights('weights.txt')

恢复训练

  • 如果要在某个时刻停止训练并稍后恢复训练,则应将参数检查点设置为True进行训练。 这将在每个epoch后保存模型和训练参数。 因此,您可以在以后任何时候加载模型和trainer,并在您离开的地方继续训练。
  • 下面的示例代码显示了如何训练,停止和继续训练SequenceTagger。 TextClassifier也可以这样做。
from flair.data import TaggedCorpus
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
from flair.embeddings import TokenEmbeddings, WordEmbeddings, StackedEmbeddings
from typing import List

# 1. get the corpus
corpus: TaggedCorpus = NLPTaskDataFetcher.load_corpus(NLPTask.CONLL_03).downsample(0.1)

# 2. what tag do we want to predict?
tag_type = 'ner'

# 3. make the tag dictionary from the corpus
tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)

# 4. initialize embeddings
embedding_types: List[TokenEmbeddings] = [
    WordEmbeddings('glove')
]

embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)

# 5. initialize sequence tagger
from flair.models import SequenceTagger

tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                        embeddings=embeddings,
                                        tag_dictionary=tag_dictionary,
                                        tag_type=tag_type,
                                        use_crf=True)

# 6. initialize trainer
from flair.trainers import ModelTrainer
from flair.training_utils import EvaluationMetric

trainer: ModelTrainer = ModelTrainer(tagger, corpus)

# 7. start training
trainer.train('resources/taggers/example-ner',
              EvaluationMetric.MICRO_F1_SCORE,
              learning_rate=0.1,
              mini_batch_size=32,
              max_epochs=150,
              checkpoint=True)

# 8. stop training at any point

# 9. continue trainer at later point
from pathlib import Path

trainer = ModelTrainer.load_from_checkpoint(Path('resources/taggers/example-ner/checkpoint.pt'), 'SequenceTagger', corpus)
trainer.train('resources/taggers/example-ner',
              EvaluationMetric.MICRO_F1_SCORE,
              learning_rate=0.1,
              mini_batch_size=32,
              max_epochs=150,
              checkpoint=True)

可扩展性:大数据集训练

使用FlairEmbeddings(你应该)时要考虑的主要事情是,为大型训练数据集生成它们的成本有些高。根据您的设置,您可以设置选项以优化培训时间。有三个问题要问:

1.你有GPU吗?

CharLMEmbeddings使用Pytorch RNN生成,因此针对GPU进行了优化。如果您有一个,您可以设置大型小批量大小以使用批处理。如果没有,您可能想要使用较小的语言模型。对于英语,我们打包嵌入式的“快速”变体,可加载如下:FlairEmbeddings(‘news-forward-fast’)。

2.整个数据集的嵌入是否适合内存?

在最佳情况下,数据集的所有嵌入都适合您的常规内存,这极大地提高了训练速度。如果不是这种情况,则必须在相应的培训师(即ModelTrainer)中设置标志embeddings_in_memory = False以避免内存问题。使用该标志,嵌入是(a)在每个纪元重新计算或(b)从磁盘检索,如果您选择实现磁盘。

3.你有快速硬盘吗?

如果您有快速硬盘驱动器,请考虑将嵌入物实现到磁盘。您可以通过以下方式实现我的实例化FlairEmbedding:FlairEmbeddings(‘news-forward-fast’,use_cache = True)。如果嵌入不适合内存,这可能会有所帮助。此外,如果您没有GPU并且想要对同一数据集进行重复实验,这会有所帮助,因为嵌入只需要计算一次,然后始终从磁盘中检索。