Flair~快速構(gòu)建遷移學(xué)習(xí)的自然語言學(xué)習(xí)組件

1. 簡介

一個(gè)非常簡單的框架,用于最先進(jìn)的NLP。由Zalando Research開發(fā)。

Flair是什么:

  • 強(qiáng)大的語法 - 語義標(biāo)記器/分類器。 Flair允許應(yīng)用先進(jìn)的模型進(jìn)行命名實(shí)體識(shí)別(NER),詞性標(biāo)注(PoS),分塊和分類文本。
  • 文本嵌入庫。 Flair具有簡單的界面,允許使用和組合不同的單詞和文檔嵌入。特別是,可以嘗試提出的上下文字符串嵌入來構(gòu)建自己的NLP方法。
  • Pytorch NLP框架。 框架直接在Pytorch上構(gòu)建,使您可以輕松地訓(xùn)練自己的模型,并使用Flair嵌入和類來嘗試新方法。

其GitHub的項(xiàng)目地址位于: Flair

2. 安裝

Flair安裝需要Python 3.6
直接通過pip install flair即可

flairinstall.png

如果之前沒有安裝PyTorch,可以先按照官方的說明,通過如下方式安裝(之前PyTorch不支持Windows版本,2018年已經(jīng)支持Windows安裝并應(yīng)用了):

pip3 install https://download.pytorch.org/whl/cu90/torch-1.0.0-cp36-cp36m-win_amd64.whl
pip3 install torchvision

3. Flair的最主要特性 - 基于預(yù)訓(xùn)練模型做遷移學(xué)習(xí)

Flair的最主要特性,是基于預(yù)訓(xùn)練模型做遷移學(xué)習(xí)。

預(yù)訓(xùn)練模型的聲明,集中在:python安裝路徑\Lib\site-packages\flair\embeddings.py中:


flairembeddings.png

由模塊包含的類可以發(fā)現(xiàn)除了基礎(chǔ)的WordEmbedding之外,還有最近的新貴ELMo,甚至Bert。

值得一提的是,所有支持的預(yù)訓(xùn)練模型,都在代碼提供了下載地址,除了Bert之外,預(yù)訓(xùn)練模型都來自AllenNLP: 如:ELMo_2x_1024_128_2048cnn_1xhighway_options

Bert相關(guān)的預(yù)訓(xùn)練模型處理部分,位于:Python安裝路徑\Lib\site-packages\pytorch_pretrained_bert\modeling.py


flairbert.png

其也提供了下載地址,如:bert-base-uncased

具體的使用部分,可以參考官方文檔

4. Flair預(yù)訓(xùn)練模型的存放路徑

Flair相關(guān)的目錄存放在登錄用戶的主目錄,如:
Windows位于C:\Users\登錄用戶名\.flair
Linux對(duì)應(yīng)于~/.flair

4.1 除了Bert與Elmo之外的可直接使用模型以及Embedding的存放路徑

4.1.1 可直接使用模型(.pt擴(kuò)展名,即pytorch訓(xùn)練的模型)

  • 用法
    通過TextClassifier加載模型,如:classifier = TextClassifier.load('en-sentiment')
  • 模型種類
    目前只有兩個(gè):

en-sentiment: 情緒識(shí)別,基于imdb的英文語料訓(xùn)練
de-offensive-language:基于德語的是否有攻擊語言判斷分類

存放于~/.flair/models

4.1.2 Embedding

  • WordEmbeddings,包括:GloVe, EXTVec, Crawl, Twitter, Wiki,
  • FlairEmbeddings, 包括:
    multilingual forward (English, German, French, Italian, Dutch, Polish)
    multilingual backward (English, German, French, Italian, Dutch, Polish)
    multilingual forward fast (English, German, French, Italian, Dutch, Polish)
    multilingual backward fast (English, German, French, Italian, Dutch, Polish)
    news-english-forward
    news-english-backward
    news-english-forward-fast
    news-english-backward-backward
    mix-english-forward
    mix-english-backward
    mix-german-forward
    mix-german-backward
    common crawl Polish forward
    common crawl Polish backward
    Slovenian forward
    Slovenian backward
    Bulgarian forward
    Bulgarian backward
    Dutch forward
    Dutch backward
    Swedish forward
    Swedish backward
    French forward
    French backward
    Czech forward
    Czech backward
    Portuguese forward
    Portuguese backward
  • CharLMEmbeddings:即將被去除,與FlairEmbeddings作用一樣,已經(jīng)被其取代
    存放于~/.flair/embeddings

4.2 ElMo預(yù)訓(xùn)練模型的存放路徑

ELMo預(yù)訓(xùn)練的模型包括:small, medium兩種,此外還有一個(gè)葡萄牙語的模型。

存放于~/.allennlp/cache

4.3 Bert預(yù)訓(xùn)練模型的存放路徑

Bert預(yù)訓(xùn)練模型的類型:bert-base-uncased, bert-large-uncased,bert-base-cased,bert-base-multilingual,bert-base-chinese
存放于~/.pytorch_pretrained_bert
可以先根據(jù):Python安裝路徑\Lib\site-packages\pytorch_pretrained_bert\modeling.py中的PRETRAINED_MODEL_ARCHIVE_MAP所聲明的路徑:

PRETRAINED_MODEL_ARCHIVE_MAP = {
    'bert-base-uncased': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-uncased.tar.gz",
    'bert-large-uncased': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-uncased.tar.gz",
    'bert-base-cased': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-cased.tar.gz",
    'bert-large-cased': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-large-cased.tar.gz",
    'bert-base-multilingual-uncased': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-multilingual-uncased.tar.gz",
    'bert-base-multilingual-cased': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-multilingual-cased.tar.gz",
    'bert-base-chinese': "https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese.tar.gz",
}

將預(yù)訓(xùn)練模型先下載到本地,如~/.pytorch_pretrained_bert,然后再進(jìn)行使用,否則在國內(nèi)下載速度非常慢。
下載完畢后,現(xiàn)在Flair的版本居然不檢測bert模型存放地址是否已經(jīng)下載,還會(huì)從AWS S3下載,吐血。。。
出于改配置,不改代碼的原則,我們修改配置字典:PRETRAINED_MODEL_ARCHIVE_MAP的bert-base-uncased的值(默認(rèn)對(duì)應(yīng)這個(gè)模型):

 'bert-base-uncased': Path.home() / ".pytorch_pretrained_bert/bert-base-uncased.tar.gz"

然后就OK了。

5 使用訓(xùn)練好的預(yù)置分類模型

最新的Flair 0.4版本包含有兩個(gè)預(yù)先訓(xùn)練好的模型。一個(gè)基于IMDB數(shù)據(jù)集訓(xùn)練的情感分析模型和一個(gè)攻擊性語言探測模型(當(dāng)前僅支持德語)。

只需一個(gè)命令就可以下載、存儲(chǔ)并使用模型,這使得預(yù)置模型的使用過程異常簡單。例如,下面的代碼將使用情感分析模型:

當(dāng)?shù)谝淮芜\(yùn)行以下代碼時(shí),F(xiàn)lair將下載情感分析模型,默認(rèn)情況下會(huì)保存到本地用戶主目錄的.flair子目錄,下載可能需要幾分鐘。(作者太皮了,我下載到本地預(yù)估至少用了3個(gè)小時(shí)??!強(qiáng)烈建議先找到需要下載的預(yù)訓(xùn)練模型路徑,通過迅雷等工具,下載下來,并拷貝到對(duì)應(yīng)目錄,從而縮短等待時(shí)間!)

from flair.models import TextClassifier
from flair.data import Sentence
print('load en-sentiment begin')
classifier = TextClassifier.load('en-sentiment')
print('load en-sentiment end')

sentence = Sentence('Flair is pretty neat!')
print('load predict begin')
classifier.predict(sentence)
print('load predict end')

# print sentence with predicted labels
print('Sentence above is: ', sentence.labels)

上面的代碼首先載入必要的庫,然后載入情感分析模型到內(nèi)存中(必要時(shí)先下載),接下來就可以預(yù)測“Flair is pretty neat!”的情感分值了(0~1之間)。最后的命令輸入結(jié)果為:
The sentence above is: [Positive (1.0)].
就是這么簡單!現(xiàn)在你可以將上述代碼整合為一個(gè)REST API,提供類似于google云端情感分析API的功能了!

6. 遷移學(xué)習(xí)練習(xí)

使用預(yù)訓(xùn)練模型,并創(chuàng)建自己的分類模型。
要訓(xùn)練一個(gè)自定義的文本分類器,首先需要一個(gè)標(biāo)注文本集。Flair的分類數(shù)據(jù)集格式基于Facebook的FastText格式,要求在每一行的開始使用label前綴定義一個(gè)或多個(gè)標(biāo)簽。格式如下:

__label__<class_1> <text>
__label__<class_2> <text>

在這篇文章中我們將使用Kaggle的SMS垃圾信息檢測數(shù)據(jù)集來用Flair構(gòu)建一個(gè)垃圾/非垃圾分類器。這個(gè)數(shù)據(jù)集很適合我們的學(xué)習(xí)任務(wù),因?yàn)樗苄?,只?572行數(shù)據(jù),可以在單個(gè)CPU上只花幾分鐘就完成模型的訓(xùn)練。

6.1 預(yù)處理 - 構(gòu)建數(shù)據(jù)集

首先下載Kaggle上的數(shù)據(jù)集,得到spam.csv;然后再數(shù)據(jù)集目錄下,運(yùn)行我們的處理腳本,得到訓(xùn)練集、開發(fā)集和測試集:

import pandas as pd
# The frac keyword argument specifies the fraction of rows to return in the random sample, 
# so frac=1 means return all rows (in random order).
data = pd.read_csv("./csv/spam.csv", encoding='latin-1').sample(frac=1).drop_duplicates()

data = data[['v1', 'v2']].rename(columns={"v1":"label", "v2":"text"})
 
data['label'] = '__label__' + data['label'].astype(str)

data.iloc[0:int(len(data)*0.8)].to_csv('./csv/spamtrain.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.8):int(len(data)*0.9)].to_csv('./csv/spamtest.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.9):].to_csv('./csv/spamdev.csv', sep='\t', index = False, header = False)

上面的腳本會(huì)進(jìn)行剔重和隨機(jī)亂序處理,并按照80/10/10的比例進(jìn)行數(shù)據(jù)集的分割。

腳本成功執(zhí)行后,就會(huì)得到FastText格式的三個(gè)數(shù)據(jù)文件:train.csv、dev.csv和test.csv。

如果需要支持多標(biāo)簽分類,標(biāo)簽之間用空格分隔。

最簡單的方式就是通過label標(biāo)簽1 label標(biāo)簽2實(shí)現(xiàn),如下面所示實(shí)現(xiàn)了三標(biāo)簽分類:

__label__add __label__close __label__merge

6.2 訓(xùn)練自定義文本分類模型

這里使用了WordEmbeddings: GloVe作為預(yù)訓(xùn)練模型,不過DocumentLSTMEmbeddings類,是支持Emedding列表的,所以按照如下代碼去定義包含Bert預(yù)訓(xùn)練模型的embedding列表,然后實(shí)例化DocumentLSTMEmbeddings也是可以的:

# BertEmbeddings模型使用base uncase預(yù)訓(xùn)練模型
word_embeddings = [BertEmbeddings(), 
  FlairEmbeddings('news-forward-fast'), 
  FlairEmbeddings('news-backward-fast')]

document_embeddings = DocumentLSTMEmbeddings(word_embeddings,   
  hidden_size=512,
  reproject_words=True,
  reproject_words_dimension=256,
  bidirectional=True)

通過GloVe作為預(yù)訓(xùn)練模型進(jìn)行遷移學(xué)習(xí)的源碼:

from flair.data_fetcher import NLPTaskDataFetcher
from flair.embeddings import WordEmbeddings, FlairEmbeddings, DocumentLSTMEmbeddings
from flair.models import TextClassifier
from flair.trainers import ModelTrainer
from pathlib import Path
import os

if not os.path.exists('./nlpmodel/flair/spam/best-model.pt'):
    corpus = NLPTaskDataFetcher.load_classification_corpus(Path('./csv'), 
                                                           test_file='spamtrain.csv', 
                                                           dev_file='spamdev.csv', 
                                                           train_file='spamtest.csv')

    word_embeddings = [WordEmbeddings('glove'), 
                       FlairEmbeddings('news-forward-fast'), 
                       FlairEmbeddings('news-backward-fast')]

    document_embeddings = DocumentLSTMEmbeddings(word_embeddings, 
                                                 hidden_size=512, 
                                                 reproject_words=True, 
                                                 reproject_words_dimension=256)

    classifier = TextClassifier(document_embeddings, 
                                label_dictionary=corpus.make_label_dictionary(), 
                                multi_label=False)

    trainer = ModelTrainer(classifier, corpus)

    trainer.train('./nlpmodel/flair/spam', max_epochs=20)
else:
    print('model: {0} existed!'.format('./nlpmodel/flair/spam/best-model.pt'))

第一次運(yùn)行上面這個(gè)腳本時(shí),F(xiàn)lair會(huì)自動(dòng)下載所需要的嵌入模型,這可能需要一段時(shí)間(如果預(yù)先下載,并放入上述提到的Embedding的存放路徑,就可以直接訓(xùn)練模型),然后接下來的整個(gè)訓(xùn)練過程還需要大約5分鐘。

腳本首先載入需要的庫和數(shù)據(jù)集,得到一個(gè)corpus對(duì)象。

接下來,我們創(chuàng)建一個(gè)嵌入列表,包含兩個(gè)Flair上下文字符串嵌入和一個(gè)GloVe單詞嵌入,這個(gè)列表接下來將作為我們文檔嵌入對(duì)象的輸入。

具體訓(xùn)練的截圖如下:


flairtrain.png

堆疊和文本嵌入是Flair中最有趣的感念之一,它們提供了將不同的嵌入整合在一起的手段,你可以同時(shí)使用單詞嵌入(例如GloVe、word2vector、ELMo,Bert)和Flair的上下文字符串嵌入。

在上面的示例中我們使用一個(gè)基于LSTM的方法來生成文檔嵌入,關(guān)于該方法的詳細(xì)描述可以參考這里。
下面進(jìn)行簡單的垃圾信息預(yù)測,簡直是驚天地泣鬼神的簡易:

classifier = TextClassifier.load_from_file('./nlpmodel/flair/spam/best-model.pt')
textlist= ["Hi. Yes mum, I will...", 
           "Want 2 get laid tonight? Want real Dogging locations sent direct 2 ur mob? Join the UK's largest Dogging Network bt Txting GRAVEL to 69888! Nt. ec2a. 31p.msg@150p"
          ]
for text in textlist:
    sentence = Sentence(text)
    classifier.predict(sentence)
    print('Text: {0} is belong to: {1}'.format(text, sentence.labels))

輸入大致如下:

Text: Hi. Yes mum, I will... is belong to: [ham (1.0)]
Text: Want 2 get laid tonight? Want real Dogging locations sent direct 2 ur mob? Join the UK's largest Dogging Network bt Txting GRAVEL to 69888! Nt. ec2a. 31p.msg@150p is belong to: [spam (1.0)]

值得一提的是,經(jīng)過加載預(yù)處理的GloVe單詞嵌入生成的模型非常大,即使是Spam這種只有幾千句,492K的訓(xùn)練集,生成的模型,也有200多M,至少比嵌入的預(yù)訓(xùn)練模型要大一丟丟。(通過Bert Base預(yù)訓(xùn)練模型進(jìn)行遷移學(xué)習(xí),訓(xùn)練得到的模型將近500M)


flairmodel.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 摘要:圖解,2018年自然語言處理領(lǐng)域最成功的方向! 2018年是自然語言處理的轉(zhuǎn)折點(diǎn),能捕捉潛在意義和關(guān)系的方式...
    城市中迷途小書童閱讀 2,142評(píng)論 0 18
  • Flair是一個(gè)基于PyTorch構(gòu)建的NLP開發(fā)包,它在解決命名實(shí)體識(shí)別(NER)、語句標(biāo)注(POS)、文本分類...
    編程狂魔閱讀 1,936評(píng)論 0 1
  • MJ老師的超級(jí)數(shù)字力已經(jīng)學(xué)完了“現(xiàn)金能力”、“經(jīng)營能力”這兩個(gè)模塊,現(xiàn)在開始學(xué)習(xí)“盈利能力”這個(gè)模塊。 1、盈利能...
    依盈閱讀 290評(píng)論 0 0
  • 之前老是忘了線程和進(jìn)程的關(guān)系,今天特地查了下,發(fā)現(xiàn)阮一峰博客里對(duì)這個(gè)問題的解釋很精妙,用工廠車間比喻進(jìn)程,用工人比...
    汨羅在北方閱讀 295評(píng)論 0 0
  • App在StrictMode(嚴(yán)格)模式下運(yùn)行模式下報(bào)的異常 定位異常方法 具體異常位置 Android官網(wǎng)對(duì)這個(gè)...
    WilsonMing閱讀 2,874評(píng)論 1 1

友情鏈接更多精彩內(nèi)容