CV・NLPハマりどころメモ

画像認識と自然言語処理を研究する中でうまくいかなかったことと、その対策をまとめる自分用メモが中心。

CrossRefAPIを使ってみる[CrossRefAPI]

論文からのテキストマイニングをしてみたくなったので,様々な出版社のDOI情報を取得可能なCrossRefAPIを使ってみる.

しかし,今は時間がないのでざっくりとまとめる.

インストール方法

pip install crossrefapi

クエリの指定方法

from crossref.restful import Works

works = Works()

w1 = works.query(title='deep learning')

for item in w1:
    print(item['title'])

クエリ一覧

github.com

JSONファイルを綺麗に表示する[JSON]

まずは,jqをインストール.

brew install jq

表示

cat result.json | jq .

{
  "hoge": {
    "precision": 0.9999999999990001,
    "recall": 0.9999999999990001,
    "f1_score": 0.9999999999940001
  },
  "hoge2": {
    "precision": 0.9999999999983333,
    "recall": 0.9999999999983333,
    "f1_score": 0.9999999999933333
  },
  "hoge3": {
    "precision": 0.999999999995,
    "recall": 0.999999999995,
    "f1_score": 0.99999999999
  }
}

Spyderでタブ補完でインデントされるときの対処法[Spyder][Python]

Spyderを使っていて,TABキーを押したとき,補完ではなくインデントされる場合は,

Preferences > Editor > Tab always indent のチェックを外す.

Flairでお気軽にNERを試す[Flair][NLP][NER]

CoNll2013のデータセットを使ってNERを実行するまでを雑にメモする.

Flairが入ったDockerfileをcloneしてくる.

git clone https://github.com/poteha/docker-nlp.git

Dockerfileから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 pip

pip install -U flair

CoNll2013のデータセットをダウンロードする

git clone https://github.com/synalp/NER.git

mkdir -p ~/.flair/datasets/conll_03

cp ~/NER/corpus/CoNLL-2003/eng.train ~/.flair/datasets/conll_03
cp ~/NER/corpus/CoNLL-2003/eng.testa ~/.flair/datasets/conll_03
cp ~/NER/corpus/CoNLL-2003/eng.testb ~/.flair/datasets/conll_03

ちなみに~/.flair/datasets/conll_03の中はこんな感じ

xxx@xxx:~/.flair/datasets/conll_03# ll
total 4756
drwxr-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 Corpus
from flair.datasets import ClassificationCorpus

# conll03のフォルダパスを指定
data_folder = '~/.flair/dataset/conll03'

# load corpus containing training, test and dev data
corpus: 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)

[b'<unk>', b'O', b'S-PER', b'S-ORG', b'S-LOC', b'S-MISC', b'B-ORG', b'E-ORG', b'I-ORG', b'B-LOC', b'E-LOC', b'B-PER', b'E-PER', b'B-MISC', b'E-MISC', b'I-PER', b'I-MISC', b'I-LOC', b'<START>', b'<STOP>']

embeddingのモデルを指定

今回は,StackedEmbeddingsにGloVEのword embeddingsと文字レベルのembeddingsを合わせて利用

from flair.embeddings import TokenEmbeddings, WordEmbeddings, CharacterEmbeddings, StackedEmbeddings
from typing import List

embedding_types: List[TokenEmbeddings] = [
    WordEmbeddings('glove'),
    CharacterEmbeddings(),
]
 
embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)

SequenceTaggerクラスに隠れ層のサイズやembeddings,タグの種類などを渡してインスタンス化.

from flair.models import SequenceTagger
 
tagger: 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 ModelTrainer
 
trainer: 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_SCORE
2019-06-12 08:33:03,283 ----------------------------------------------------------------------------------------------------
2019-06-12 08:33:04,025 epoch 1 - iter 0/47 - loss 55.90135956
2019-06-12 08:33:06,917 epoch 1 - iter 4/47 - loss 45.51642914
2019-06-12 08:33:08,778 epoch 1 - iter 8/47 - loss 35.78959168
2019-06-12 08:33:10,459 epoch 1 - iter 12/47 - loss 30.98981975

logsに経過やモデルが出力される.

また,学習曲線のプロットもできる

from flair.visual.training_curves import Plotter
 
plotter = Plotter()
plotter.plot_training_curves('logs/loss.tsv')

logsにpngファイルで出力

テストの際は,logsのモデルを読み込んで利用

model = SequenceTagger.load_from_file('logs/final-model.pt')
 
sentence = Sentence('I love Berlin')
model.predict(sentence)
print(sentence.to_tagged_string())

Dockerのコンテナ・イメージの保存場所を変更[Docker]

Docker のイメージやコンテナは標準設定だと /var/lib/docker に格納される.

しかし, それではメインストレージの容量が膨らんでしまったときに収集がつかなくなってしまうので, サブのストレージに格納したい.

まずはdockerを止める.

$ sudo service docker stop
$ sudo systemctl stop docker

docker.serviceファイルをコピーし, Unitファイルを編集

sudo cp /lib/systemd/system/docker.service /etc/systemd/system/

/etc/systemd/system/docker.service をvimなどで開き,以下の行を探して --data-root オプションをつける. --data-rootオプションの後にコンテナ・イメージを保存するディレクトリを指定.

ExecStart=/usr/bin/dockerd -H unix:// # 編集前
ExecStart=/usr/bin/dockerd -H unix:// --data-root /home/ubuntu/disk/docker # 編集後

Dockerを再起動

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

ここまでくれば完了.正常に動作するかを確かめる.

$ docker run hello-word

Hello worldが出たら,無事成功.

最後に指定したフォルダにdockerのファイルツリーが構築されているかを確認.

cd /home/ubuntu/disk/docker

ubuntu@ip-xxx-xx-xx-xxx:~/disk/docker$ ll
total 56
drwx--x--x 14 ubuntu ubuntu 4096 Nov 14 07:27 ./
drwx--x--x  3 ubuntu ubuntu 4096 Nov 14 07:27 ../
drwx------  2 root   root   4096 Nov 14 07:27 builder/
drwx------  4 root   root   4096 Nov 14 07:27 buildkit/
drwx------  3 root   root   4096 Nov 14 07:27 containers/
drwx------  3 root   root   4096 Nov 14 07:27 image/
drwxr-x---  3 root   root   4096 Nov 14 07:27 network/
drwx------  6 root   root   4096 Nov 14 07:27 overlay2/
drwx------  4 root   root   4096 Nov 14 07:27 plugins/
drwx------  2 root   root   4096 Nov 14 07:27 runtimes/
drwx------  2 root   root   4096 Nov 14 07:27 swarm/
drwx------  2 root   root   4096 Nov 14 07:27 tmp/
drwx------  2 root   root   4096 Nov 14 07:27 trust/
drwx------  2 root   root   4096 Nov 14 07:27 volumes/

上のようなファイルツリーが表示されれば,作業完了だ.

初期のディレクトリは混乱の元になるので削除しておこう.

sudo rm -r /var/lib/docker