FlairでNERを試す[Flair][NLP][NER]
CoNll2013のデータセットを使ってNERを実行するまでを雑にメモする.
Flairが入ったDockerfileをcloneしてくる.
git clone https://github.com/poteha/docker-nlp.gitDockerfileからFlairのImageを作成
docker build -t nlp-gpu -f ./Dockerfile.gpu .作成したImageからcontainerを立てる
docker run -it --runtime=nvidia nlp-gpu:latest bashコンテナに入って,Flairのアップデートを行う
pip install -U pippip install -U flairCoNll2013のデータセットをダウンロードする
git clone https://github.com/synalp/NER.gitmkdir -p ~/.flair/datasets/conll_03cp ~/NER/corpus/CoNLL-2003/eng.* ~/.flair/datasets/conll_03ちなみに~/.flair/datasets/conll_03の中はこんな感じ
xxx@xxx:~/.flair/datasets/conll_03# lltotal 4756drwxr-xr-x 2 root root 4096 Jun 12 08:12 ./drwxr-xr-x 4 root root 4096 Jun 12 08:33 ../-rw-r--r-- 1 root root 827012 Jun 12 08:11 eng.testa-rw-r--r-- 1 root root 748096 Jun 12 08:11 eng.testb-rw-r--r-- 1 root root 3281528 Jun 12 08:11 eng.trainここからFlairを用いたNERのモデルの学習を始める
まずコーパスの準備
from flair.data import Corpusfrom flair.datasets import ClassificationCorpus# conll03のフォルダパスを指定data_folder = '~/.flair/dataset/conll03'# load corpus containing training, test and dev datacorpus: Corpus = ClassificationCorpus(data_folder,test_file='eng.testa',dev_file='eng.testb',train_file='eng.train')フルでデータを使うと学習に時間がかかるので,コーパスから1割だけデータを取り出す
downcorpus = corpus.downsample(0.1)print(downcorpus)TaggedCorpus: 1499 train + 347 dev + 369 test sentencesタグを取り出してモデルが何を予測するかを事前に確認する.
tag_type = 'ner'tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)print(tag_dictionary.idx2item)embeddingのモデルを指定
今回は,GloVeとCharacterEmbeddingsをstackさせて利用.
from flair.embeddings import TokenEmbeddings, WordEmbeddings, CharacterEmbeddings, StackedEmbeddingsfrom typing import Listembedding_types: List = [WordEmbeddings('glove'),CharacterEmbeddings(),]embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)SequenceTaggerクラスに隠れ層のサイズやembeddings,タグの種類などを渡す.
from flair.models import SequenceTaggertagger: SequenceTagger = SequenceTagger(hidden_size=256,embeddings=embeddings,tag_dictionary=tag_dictionary,tag_type=tag_type,use_crf=True)ModelTrainerクラスにtaggerとcorpusを渡す.
from flair.trainers import ModelTrainertrainer: ModelTrainer = ModelTrainer(tagger, corpus)学習を開始
trainer.train('logs/',learning_rate=0.1,mini_batch_size=32,max_epochs=10)2019-06-12 08:33:03,132 ----------------------------------------------------------------------------------------------------2019-06-12 08:33:03,132 Evaluation method: MICRO_F1_SCORE2019-06-12 08:33:03,283 ----------------------------------------------------------------------------------------------------2019-06-12 08:33:04,025 epoch 1 - iter 0/47 - loss 55.901359562019-06-12 08:33:06,917 epoch 1 - iter 4/47 - loss 45.516429142019-06-12 08:33:08,778 epoch 1 - iter 8/47 - loss 35.789591682019-06-12 08:33:10,459 epoch 1 - iter 12/47 - loss 30.98981975logsに経過やモデルが出力される.
学習曲線のプロットもできる
from flair.visual.training_curves import Plotterplotter = Plotter()plotter.plot_training_curves('logs/loss.tsv')今回学習したモデルを用いて検出を実施する場合は,フォルダ「logs」の中にあるモデルを読み込んで利用
model = SequenceTagger.load_from_file('logs/final-model.pt')sentence = Sentence('I love Berlin')model.predict(sentence)print(sentence.to_tagged_string())