伴随着这篇文章的代码可以在订阅后收到
*表示需要
电子邮件地址*
在过去的几年里,NLP的进展突飞猛进。在研究方面。 机器学习和**深度学习**为新技术和可能性铺平了道路。其中许多技术已经成为主流 ,如ELMo、PyText、BERT等。这些技术为我们提供了许多功能,如预测文本、检测文本中的实体,以及可能是最重要的--理解文本的上下文。
业界紧随其后,在新的研究技术基础上开发了各种框架和工具。今天,在谈到不同的NLP框架时,我们有几种选择。在这篇文章中,我介绍了其中一个框架--Flair。它的易用性和提供的可能性给我留下了深刻印象,以及你如何在短短几分钟内取得最先进的结果。因此,让我们深入了解它。
这套电子书捆绑在一起,是专门为初学者制作的。从Python基础知识到机器学习算法在生产中的部署,一切都在一个地方。今天就成为机器学习的超级英雄吧!
在这篇文章中,你会发现。
1.什么是Flair?
Flair 是一个惊人的NLP框架,建立在 PyTorch深度学习框架之上。它是由柏林洪堡大学和Zalando研究公司建立和外包的。从本质上讲,它提供了三大系列的功能。首先,它暴露了最先进的自然语言处理(NLP)模型,所以你可以很容易地使用它们进行迁移学习。
其次,它提供了各种嵌入,所以你可以把Flair作为一个嵌入库。最后,它暴露了各种数据集,允许你训练自己的模型,所以你可以把它作为一个深度学习框架来使用。Flair是一个多语言库,所以如果你从事多语言工作,特别是需要从事德语工作时,它是非常好的。
1.1 Flair SOTA NLP模型
正如我们已经提到的,Flair的第一个大功能是暴露了各种SOTA NLP模型,所以你可以通过迁移学习来使用它们。一些可以开箱即用的模型是。
**1.名字-实体识别(NER)。**检测文本中代表人物、地点或名字的词。
**2.语音部分标记(PoS)。**根据给定文本中的 "语音部分 "标记所有的词。
3.3. 文本分类。根据定义的标准对文本进行分类。
这些模型真的很好,如果不是SOTA,那么它们就非常接近SOTA。看看Flair提供的模型与当前SOTA模型在NER方面的结果。
1.2 作为嵌入库的Flair
我们将在下面的章节中更详细地探讨这个话题,然而,重要的是要认识到,Flair提供了各种单词和文档 嵌入技术,如BERT嵌入、ELMo等。特别有趣的是,它提供了自己的嵌入技术--Flair Embeddings或Contextual String Embeddings。
这是一种新颖的单词嵌入,是基于字符的。这些嵌入是 在没有任何明确的单词概念的情况下进行训练的,因此从根本上将单词建模为字符序列。此外,它们 是由其周围的文本所决定的,这意味着同一个词将根据其上下文的使用而有不同的嵌入。
请在本文中了解更多关于语境字符串嵌入的信息。
在本文中,我们提出了一种新型的语境化字符级单词嵌入,我们假设它结合了上述嵌入的最佳属性;即:(1)在大型无标签语料库上进行预训练的能力;(2)在语境中捕捉单词的意义,因此根据其用法对多义词产生不同的嵌入;以及(3)将单词和语境基本建模为字符序列,以更好地处理罕见和拼错的单词,以及建模子词结构,如前缀和尾缀。
阿兰-阿克比克
柏林洪堡大学机器学习系教授
2.安装与前提条件
在安装Flair之前,请确保你已经安装了Python 3.6或更高版本,以及PyTorch 1.5或更高版本。一旦你安装了这些,只需运行以下命令。
pip install flair
3.Flair基础知识
一般来说,有几种重要的Flair数据类型。让我们从最简单的类型开始,然后从这里开始。
3.1 句子类
在Flair库的核心部分,你可以找到句子类。
from flair.data import Sentence
这个数据类型用于本库中的大多数操作。正如你可能意识到的,它代表一个句子。每个句子都使用标记化,所以每个句子都被自动分割成标记。默认的标记化是由segtok库在引擎盖下完成的。
# Automatic tokenization using the segtok library.
sentence = Sentence('I love Rubik\'s Code blog!')
print(sentence)
Sentence: "I love Rubik 's Code blog !" [− Tokens: 7]
你可以通过使用索引或使用get_token方法来访问句子的每个标记*。*
print(sentence[1])
print(sentence.get_token(2))
Token: 2 love
Token: 2 love
当然,你也可以选择不使用标记化,而仅仅通过单词来分割句子,也就是仅仅通过空格来分割。
sentence = Sentence('I love Rubik\'s Code blog!', use_tokenizer=False)
print(sentence) # Note that text is still split on whitespaces, so 5 tokens are returned here
Sentence: "I love Rubik's Code blog!" [− Tokens: 5]
如果你需要一些其他的标记化,例如日语,你也可以这样做。
from flair.tokenization import JapaneseTokenizer
japaneze_tokenizer = JapaneseTokenizer("janome")
sentence = Sentence('愛は法です。意志の下での愛。', use_tokenizer=japaneze_tokenizer)
print(sentence)
Sentence: "愛 は 法 です 。 意志 の 下 で の 愛 。" [− Tokens: 12]
3.2 SequenceTagger和TextClassifier类
为了加载所有这些整洁的SOTA模型,你可以使用两个类。SequenceTagger和TextClassifier。 SequenceTagger 用于NER和POS操作,而TextClassifeier正如其名称所示,用于文本分类。我们将在下面的章节中看到这些类是如何用于这些操作的,但这两个类中最重要的方法是加载 方法。
from flair.models import SequenceTagger
from flair.models import TextClassifier
tagger = SequenceTagger.load('ner')
classifier = TextClassifier.load('en-sentiment')
4.Flair嵌入法
正如我们提到的,Flair通过其flair.embeddings模块提供了各种嵌入类型。你可以使用简单的GLoVe嵌入,新颖的Flair 嵌入,或者将它们叠加起来。下面是你需要首先导入的内容。
from flair.data import Sentence
from flair.embeddings import WordEmbeddings
from flair.embeddings import FlairEmbeddings
from flair.embeddings import StackedEmbeddings
sentence = Sentence('I love Rubik\'s Code blog!')
在上面的片段中,我们还初始化了句子 "我爱Rubik's Code博客!"。为了加载各种嵌入,我们使用WordEmbeddings类。例如,如果我们想加载GLoVe嵌入并将其应用于先前初始化的句子,我们所要做的就是。
glove_embedding = WordEmbeddings('glove')
glove_embedding.embed(sentence)
可以通过使用句子中一个标记的嵌入属性来访问结果。
print(sentence[1])
print(sentence[1].embedding)
Token: 2 love
tensor([ 2.5975e-01, 5.5833e-01, 5.7986e-01, -2.1361e-01, 1.3084e-01,
9.4385e-01, -4.2817e-01, -3.7420e-01, -9.4499e-02, -4.3344e-01,
-2.0937e-01, 3.4702e-01, 8.2516e-02, 7.9735e-01, 1.6606e-01,
-2.6878e-01, 5.8830e-01, 6.7397e-01, -4.9965e-01, 1.4764e+00,
5.5261e-01, 2.5295e-02, -1.6068e-01, -1.3878e-01, 4.8686e-01,
1.1420e+00, 5.6195e-02, -7.3306e-01, 8.6932e-01, -3.5892e-01,
-5.1877e-01, 9.0402e-01, 4.9249e-01, -1.4915e-01, 4.8493e-02,
2.6096e-01, 1.1352e-01, 4.1275e-01, 5.3803e-01, -4.4950e-01,
8.5733e-02, 9.1184e-02, 5.0177e-03, -3.4645e-01, -1.1058e-01,
-2.2235e-01, -6.5290e-01, -5.1838e-02, 5.3791e-01, -8.1040e-01,
-1.8253e-01, 2.4194e-01, 5.4855e-01, 8.7731e-01, 2.2165e-01,
-2.7124e+00, 4.9405e-01, 4.4703e-01, 5.5882e-01, 2.6076e-01,
2.3760e-01, 1.0668e+00, -5.6971e-01, -6.4960e-01, 3.3511e-01,
3.4609e-01, 1.1033e+00, 8.5261e-02, 2.4847e-02, -4.5453e-01,
7.7012e-02, 2.1321e-01, 1.0444e-01, 6.7157e-02, -3.4261e-01,
8.5534e-01, 1.3361e-01, -4.3296e-01, -5.6726e-01, -2.1348e-01,
-3.3277e-01, 3.4351e-01, 3.2164e-01, 4.4527e-01, -1.3208e+00,
-1.3270e-01, -7.0820e-01, -4.8472e-01, -6.9396e-01, -2.6080e-01,
-4.7099e-01, -5.7492e-02, 9.3587e-02, 4.0006e-01, -4.3419e-01,
-2.7364e-01, -7.7017e-01, -8.4028e-01, -1.5620e-03, 6.2223e-01])
如果我们想使用新颖的Flair Embeddings,我们可以使用同名的类。这个类还提供了各种选项,如向前和向后嵌入。
flair_embedding = FlairEmbeddings('news-forward')
flair_embedding.embed(sentence)
print(sentence[1])
print(sentence[1].embedding)
Token: 2 love
tensor([ 0.2598, 0.5583, 0.5799, ..., -0.0039, -0.0130, 0.0047])
最酷的是,如果你想这样使用这些嵌入,你可以把这两个嵌入堆在一起。
stacked_embeddings = StackedEmbeddings([
glove_embedding,
flair_embedding
])
stacked_embeddings.embed(sentence)
5.命名实体识别(NER)与Flair
好了,让我们最后看看如何使用我们谈了这么多的Flair最先进的NLP模型。我们从命名实体识别或NER开始。以下是维基百科对NER的定义。
命名实体识别 (NER)(也称为 (命名的) 实体识别、 实体分块和 实体提取)是 信息提取的一个子任务 ,旨在将 非结构化文本 中提到的 命名实体 定位并分类 到预先定义的类别中,如人名、组织、地点、 医疗代码、时间表达、数量、货币价值、百分比等。
维基百科
从本质上讲,它是一个检测非结构化文本中代表组织、个人、城市等名称的词语的过程。这是一种常用的、非常强大的NLP技术。 我们已经知道,我们可以使用SequenceTagger类来做这件事。非常酷的一点是,Flair是多语言的。
这在我目前正在进行的项目中非常重要,所以我很高兴它对其他语言的支持。然而,让我们从英语开始,看看我们如何在其他语言中做到这一点。
5.1 英语中的命名实体识别(NER)
首先,我们导入所有必要的模块并初始化Sentence。
from flair.data import Sentence
from flair.models import SequenceTagger
sentence = Sentence('Rubiks Code is located in Berlin!')
然后我们使用SequenceTagger加载英语NER模型*。*
en_ner = SequenceTagger.load('ner')
第一次运行前面的函数时,NER模型将从HuggingFace下载。然后该模型被加载到en_ner变量中。之后,我们可以在定义的文本上运行该模型,看看它的表现如何。
en_ner.predict(sentence)
print(sentence.to_tagged_string())
Rubiks <B-ORG> Code <E-ORG> is located in Berlin <S-LOC> !
注意,我们使用to_tagged_string方法从被标记的句子中检索必要的信息。该模型成功地将Rubik's Code识别并标记为一个组织,将柏林标记为一个地点。同样的信息也可以像这样从句子中提取出来。
print(sentence)
print('NER tags:')
# iterate over entities and print
for entity in sentence.get_spans('ner'):
print(entity)
Sentence: "Rubiks Code is located in Berlin !" [− Tokens: 7 − Token-Labels: "Rubiks <B-ORG> Code <E-ORG> is located in Berlin <S-LOC> !"]
The following NER tags are found:
Span [1,2]: "Rubiks Code" [− Labels: ORG (0.5957)]
Span [6]: "Berlin" [− Labels: LOC (0.9998)]
在这里,我们还可以看到概率,即模型识别以前实体的信心。这真是令人惊讶。这段代码是如此的干净和容易使用。更棒的是,我们也可以在其他语言中做同样的事情。
5.2 德语和法语的命名实体识别(NER)
德文NER的代码几乎是一样的。
sentence = Sentence('Rubiks Code befindet sich in Berlin!')
# Loading German NER model
de_ner = SequenceTagger.load('de-ner')
de_ner.predict(sentence)
print(sentence)
print('NER tags:')
# iterate over entities and print
for entity in sentence.get_spans('ner'):
print(entity)
Sentence: "Rubiks Code befindet sich in Berlin !" [− Tokens: 7 − Token-Labels: "Rubiks <S-PER> Code befindet sich in Berlin <S-LOC> !"]
NER tags:
Span [1]: "Rubiks" [− Labels: PER (0.9822)]
Span [6]: "Berlin" [− Labels: LOC (0.9986)]
有趣的是,德语模型没有将Rubik's Code 识别为一个组织,但它将Rubik识别为一个人。
我们可以在法语中做同样的事情。
fr_ner = SequenceTagger.load('fr-ner')
sentence = Sentence('Rubiks Code est à Berlin !')
fr_ner.predict(sentence)
print(sentence)
print('NER tags:')
# iterate over entities and print
for entity in sentence.get_spans('ner'):
print(entity)
Sentence: "Rubiks Code est à Berlin !" [− Tokens: 6 − Token-Labels: "Rubiks <B-ORG> Code <E-ORG> est à Berlin <S-LOC> !"]
NER tags:
Span [1,2]: "Rubiks Code" [− Labels: ORG (0.5733)]
Span [5]: "Berlin" [− Labels: LOC (0.873)]
6.用Flair进行文本分类
Flair提供了许多文本分类的方法。在本章中,我们将学习如何用它实现简单的情感分析。为了这个目的,我们需要使用TextClassifier 类。与NER类似,我们可以在多种语言中做到这一点。
在过去的几年中,情感分析成为监测和理解客户反馈的基本工具之一。这种方式对信息和回应所携带的潜在情感基调的检测是完全 ,这意味着企业可以更好更快地了解客户的需求,提供更好的产品和服务。
简而言之,情感分析是最常见的文本分类工具。它是分析文本片段以确定情绪的过程,无论它们是积极的、消极的还是中立的。了解你的品牌、产品或服务的社会情绪,同时监测在线对话是现代企业的基本工具之一,而情绪分析是实现这一目标的第一步。
6.1 简单的英语情感分析
让我们从导入所有必要的模块和初始化开始,显然是正面的句子。
from flair.data import Sentence
from flair.models import TextClassifier
sentence = Sentence('I love Rubik\'s Code blog!')
现在,让我们加载模型。
classifier = TextClassifier.load('en-sentiment')
和前面的例子一样,模型将在第一次运行时被下载。下面是我们如何使用该模型。
classifier.predict(sentence)
print('Sentiment: ', sentence.labels)
Sentiment: [POSITIVE (0.9826)]
我们可以看到,该模型将前面的句子归类为 "正 ",而且信心相当高。这真的很好,让我们看看它是否对否定句子也有效。
sentence = Sentence('I don\'t like pineapple!')
classifier.predict(sentence)
print('Sentiment: ', sentence.labels)
Sentiment: [NEGATIVE (0.9988)]
6.2 检测德语中的冒犯性语言
这并不是唯一可以用Flair进行分类的类型。例如,我们可以检测德语中的攻击性语言。
sentence = Sentence('Ich liebe dich!')
classifier = TextClassifier.load('de-offensive-language')
classifier.predict(sentence)
print('Offensive: ', sentence.labels)
Offensive: [OTHER (1.0)]
7.Flair数据集
Flair库提供了许多数据集,为此,它使用了语料库类和对象。该对象由训练句子列表--训练数据集、设计 句子列表 --验证数据集和测试 句子列表--测试数据集构成。使用这个对象,你可以直接从Flair加载数据集,或者加载你自己的数据集(后面会有更多介绍)。下面是你如何加载英语语料库。
corpus = flair.datasets.UD_ENGLISH()
print(f'Train size: {len(corpus.train)}')
print(f'Test size: {len(corpus.test)}')
print(f'Dev size: {len(corpus.dev)}')
Train size: 12543
Test size: 2077
Dev size: 2001
之后,你可以很容易地通过索引访问这个语料库的句子。
print(corpus.test[9])
Sentence: "I 'm staying away from the stock ." [− Tokens: 8 − Token-Labels: "I <I/PRON/PRP/nsubj/Nom/Sing/1/Prs> 'm <be/AUX/VBP/aux/Ind/Pres/Fin> staying <stay/VERB/VBG/root/Pres/Part> away <away/ADV/RB/advmod> from <from/ADP/IN/case> the <the/DET/DT/det/Def/Art> stock <stock/NOUN/NN/obl/Sing> . <./PUNCT/./punct>"]
德语语料库也是可用的。
corpus = flair.datasets.UD_GERMAN()
print(f'Train size: {len(corpus.train)}')
print(f'Test size: {len(corpus.test)}')
print(f'Dev size: {len(corpus.dev)}')
print(corpus.test[9])
Sentence: "Absolut empfehlenswert ist auch der Service ." [− Tokens: 7 − Token-Labels: "Absolut <absolut/ADV/ADJD/advmod> empfehlenswert <empfehlenswert/ADJ/ADJD/root> ist <sein/AUX/VAFIN/cop/Ind/Sing/3/Pres/Fin> auch <auch/ADV/ADV/advmod> der <der/DET/ART/det/Nom/Def/Masc/Sing/Art> Service <Service/NOUN/NN/nsubj/Nom/Masc/Sing> . <./PUNCT/$./punct>"]
8.训练一个模型
最后,让我们探讨一下如何使用Flair来训练一个模型。从技术上讲,你可以将Flair作为一个标准的深度学习框架。在这里,我们训练一个模型,可以对**垃圾短信数据集** 的信息进行分类**。** 垃圾邮件检测是互联网上最早使用的机器学习任务之一。这项任务属于NLP和文本分类工作,听起来与Flair框架完美匹配。它在文献中被大量使用,对初学者来说是很好的。首先,让我们导入所有必要的模块。
import pandas as pd
from pathlib import Path
from flair.data import Sentence
from flair.embeddings import WordEmbeddings, FlairEmbeddings, DocumentRNNEmbeddings
from flair.models import TextClassifier
from flair.trainers import ModelTrainer
from flair.data import Corpus
from flair.datasets import ClassificationCorpus
我们使用在前几章中已经探讨过的各种模块。句子、文本分类器和嵌入类我们已经学会如何使用。我们在这里更明确地使用Corpus对象。此外,我们还使用了ClassificationCorpus 来从*.csv*中加载数据。ModelTrainer类是用来训练模型的,正如其名称所暗示的那样。
8.1 加载和准备数据
好的,让我们从数据集中加载和预处理数据。
data = pd.read_csv(".\\data\\spam.csv", encoding='latin-1')
data.sample(frac=1).drop_duplicates()
data = data[['v1', 'v2']].rename(columns={"v1":"label", "v2":"text"})
data['label'] = '__label__' + data['label'].astype(str)
好的,现在我们需要将这些数据从Pandas数据框架转移到语料库对象。为此,我们需要把它分成训练、验证 和测试子集。同时,为此我们利用ClassificationCorpus类。
border_1 = int(len(data)*0.8)
border_2 = int(len(data)*0.9)
data.iloc[0:border_1].to_csv('.\\data\\train.csv', sep='\t', index = False, header = False)
data.iloc[border_1:border_2].to_csv('.\\data\\test.csv', sep='\t', index = False, header = False)
data.iloc[border_2:].to_csv('.\\data\\dev.csv', sep='\t', index = False, header = False)
corpus: Corpus = ClassificationCorpus(Path('.\\data\\'), test_file='test.csv', dev_file='dev.csv', train_file='train.csv', label_type='topic')
最后,我们需要从这些数据中建立单词和文档的嵌入。我们使用GLoVe和Flair嵌入来进行单词嵌入,使用DocumentRNNEmbeddings 进行文档嵌入。
word_embeddings = [WordEmbeddings('glove'), FlairEmbeddings('news-forward-fast'), FlairEmbeddings('news-backward-fast')]
document_embeddings = DocumentRNNEmbeddings(word_embeddings, hidden_size=512, reproject_words=True, reproject_words_dimension=256)
8.2 训练一个模型
我们把所有这些放在一起,训练一个模型。
classifier = TextClassifier(document_embeddings, label_dictionary=corpus.make_label_dictionary(label_type='topic'), multi_label=False, label_type='topic')
trainer = ModelTrainer(classifier, corpus)
trainer.train('.\\model', max_epochs=5)
首先,我们创建一个TextClassifier类的对象。我们传递嵌入、标签和标签类型。然后我们使用之前创建的分类器对象和语料库对象创建一个ModelTrainer对象。最后,我们运行训练方法 。
输出将位于模型 文件夹中。在那里存储着每个周期的信息、权重值和模型本身。这个过程的输出看起来像这样。
2021-09-10 16:59:35,414 Computing label dictionary. Progress:
100%|██████████| 4457/4457 [00:03<00:00, 1340.41it/s]
2021-09-10 17:00:02,226 Corpus contains the labels: topic (#4457)
2021-09-10 17:00:02,229 Created (for label 'topic') Dictionary with 2 tags: ham, spam
2021-09-10 17:00:02,237 ----------------------------------------------------------------------------------------------------
2021-09-10 17:00:02,239 Model: "TextClassifier(
(loss_function): CrossEntropyLoss()
(document_embeddings): DocumentRNNEmbeddings(
(embeddings): StackedEmbeddings(
(list_embedding_0): WordEmbeddings('glove')
(list_embedding_1): FlairEmbeddings(
(lm): LanguageModel(
(drop): Dropout(p=0.25, inplace=False)
(encoder): Embedding(275, 100)
(rnn): LSTM(100, 1024)
(decoder): Linear(in_features=1024, out_features=275, bias=True)
)
)
(list_embedding_2): FlairEmbeddings(
(lm): LanguageModel(
(drop): Dropout(p=0.25, inplace=False)
(encoder): Embedding(275, 100)
(rnn): LSTM(100, 1024)
(decoder): Linear(in_features=1024, out_features=275, bias=True)
)
)
)
show more (open the raw output data in a text editor) ...
2021-09-10 17:00:02,262 ----------------------------------------------------------------------------------------------------
2021-09-10 17:00:02,264 Device: cpu
2021-09-10 17:00:02,265 ----------------------------------------------------------------------------------------------------
2021-09-10 17:00:02,267 Embeddings storage mode: cpu
2021-09-10 17:00:02,271 ----------------------------------------------------------------------------------------------------
2021-09-10 17:01:08,981 epoch 1 - iter 14/140 - loss 0.01010582 - samples/sec: 9.13 - lr: 0.100000
2021-09-10 17:02:08,546 epoch 1 - iter 28/140 - loss 0.00864684 - samples/sec: 7.54 - lr: 0.100000
2021-09-10 17:03:05,738 epoch 1 - iter 42/140 - loss 0.00766546 - samples/sec: 7.88 - lr: 0.100000
2021-09-10 17:04:15,945 epoch 1 - iter 56/140 - loss 0.00688913 - samples/sec: 6.87 - lr: 0.100000
2021-09-10 17:05:24,812 epoch 1 - iter 70/140 - loss 0.00605645 - samples/sec: 6.51 - lr: 0.100000
2021-09-10 17:06:28,052 epoch 1 - iter 84/140 - loss 0.00563861 - samples/sec: 7.09 - lr: 0.100000
2021-09-10 17:07:27,420 epoch 1 - iter 98/140 - loss 0.00548316 - samples/sec: 7.82 - lr: 0.100000
2021-09-10 17:08:16,254 epoch 1 - iter 112/140 - loss 0.00507662 - samples/sec: 9.18 - lr: 0.100000
2021-09-10 17:08:59,090 epoch 1 - iter 126/140 - loss 0.00479925 - samples/sec: 10.47 - lr: 0.100000
2021-09-10 17:09:47,542 epoch 1 - iter 140/140 - loss 0.00471874 - samples/sec: 9.25 - lr: 0.100000
2021-09-10 17:09:51,488 ----------------------------------------------------------------------------------------------------
2021-09-10 17:09:51,489 EPOCH 1 done: loss 0.0047 - lr 0.1000000
2021-09-10 17:11:09,362 DEV : loss 0.00234626024030149 - f1-score (micro avg) 0.9785
2021-09-10 17:11:09,708 BAD EPOCHS (no improvement): 0
2021-09-10 17:11:09,710 saving best model
2021-09-10 17:11:14,686 ----------------------------------------------------------------------------------------------------
2021-09-10 17:12:19,000 epoch 2 - iter 14/140 - loss 0.00292956 - samples/sec: 9.45 - lr: 0.100000
2021-09-10 17:13:38,299 epoch 2 - iter 28/140 - loss 0.00347677 - samples/sec: 5.66 - lr: 0.100000
2021-09-10 17:14:33,241 epoch 2 - iter 42/140 - loss 0.00307422 - samples/sec: 8.19 - lr: 0.100000
2021-09-10 17:15:45,948 epoch 2 - iter 56/140 - loss 0.00310895 - samples/sec: 6.62 - lr: 0.100000
2021-09-10 17:16:36,750 epoch 2 - iter 70/140 - loss 0.00291028 - samples/sec: 8.83 - lr: 0.100000
2021-09-10 17:17:32,092 epoch 2 - iter 84/140 - loss 0.00280403 - samples/sec: 8.11 - lr: 0.100000
2021-09-10 17:18:36,880 epoch 2 - iter 98/140 - loss 0.00281082 - samples/sec: 6.98 - lr: 0.100000
2021-09-10 17:19:37,738 epoch 2 - iter 112/140 - loss 0.00272288 - samples/sec: 7.79 - lr: 0.100000
2021-09-10 17:20:29,745 epoch 2 - iter 126/140 - loss 0.00259132 - samples/sec: 8.63 - lr: 0.100000
show more (open the raw output data in a text editor) ...
macro avg 0.9732 0.9226 0.9459 557
weighted avg 0.9765 0.9767 0.9760 557
samples avg 0.9767 0.9767 0.9767 557
2021-09-10 17:53:27,039 ----------------------------------------------------------------------------------------------------
{'test_score': 0.9766606822262118,
'dev_score_history': [0.978494623655914,
0.982078853046595,
0.985663082437276,
0.9838709677419355,
0.985663082437276],
'train_loss_history': [0.004718736432190163,
0.0025660763221981146,
0.0022709675352163288,
0.0019738855226341923,
0.0018342424205162503],
'dev_loss_history': [tensor(0.0023),
tensor(0.0019),
tensor(0.0023),
tensor(0.0016),
tensor(0.0014)]}
结论
在这篇文章中,我们探索了Flair的许多可能性--一个强大的NLP框架。我们有机会学习它的基础知识,并学习如何将其用于各种NLP任务,如NER和情感分析。
这套电子书是专门为初学者设计的。从Python基础知识到机器学习算法在生产中的部署,一切都在一个地方。今天就成为机器学习的超级英雄吧!
Nikola M. Zivkovic
尼古拉-M-日夫科维奇是 这几本书的作者 。 机器学习终极指南 和 程序员的深度学习.他热爱知识分享,是一位经验丰富的演讲者。你可以看到他在 聚会、会议上发言 ,也可以在诺维萨德大学担任客座讲师。