汎用言語モデルBERTをつかってNERを動かしてみる

9月 8, 2020

本記事は,2018秋にバズった汎用言語モデルBERTをとりあえずつかってみたときのレポートである.

このBERTというモデルをpre-trainingに用いると,様々なNLPタスクで高精度がでるようだ.詳細に関しては以下のリンクを参照.

[1810.04805] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

早速手順に入る.

今回はdockerにBERT-NER専用のコンテナを構築するところから始める.

まず,BERT-NER専用のコンテナを以下のコマンドで作成.

今回は,nvidia-docker2でコンテナをつくった.

$ docker run -it --runtime=nvidia --name "bert" nvidia/cuda:8.0-cudnn5-devel-ubuntu16.04 /bin/bash

コンテナに入り, 標準搭載されていないパッケージを入れる.

# apt update
# apt install git
# apt install unzip

Anacondaに必要なパッケージをインストール

# apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev libpng-dev

pyenvのインストール

# cd ~
# mkdir git
# cd git
# git clone git://github.com/yyuu/pyenv.git ~/.pyenv
# git clone https://github.com/yyuu/pyenv-pip-rehash.git ~/.pyenv/plugins/pyenv-pip-rehash
# echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
# echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
# echo 'eval "$(pyenv init -)"' >> ~/.bashrc
# source ~/.bashrc

Anaconda(Python3系)のバージョンを確認

root@xxxx:~/git# pyenv install -l | grep anaconda3
anaconda3-4.1.1
anaconda3-4.2.0
anaconda3-4.3.0
anaconda3-4.3.1
anaconda3-4.4.0
anaconda3-5.0.0
anaconda3-5.0.1
anaconda3-5.1.0
anaconda3-5.2.0
anaconda3-5.3.0

最新のanaconda3-5.3.0をインストールし, デフォルトとして設定.

# pyenv install anaconda3-5.3.0
# pyenv global anaconda3-5.3.0
# echo 'export PATH="$PYENV_ROOT/versions/anaconda3-5.3.0/bin:$PATH"' >> ~/.bashrc
# source ~/.bashrc

Pythonの環境を確認

# python --version
Python 3.7.0 (default, Jun 28 2018, 13:15:42)
[GCC 7.2.0]

TensorflowをインストールするためにPython3.6の環境を構築

conda create -n tf_p36 python=3.6 anaconda
source activate tf_p36
echo 'source activate tf_p36' >> ~/.bashrc
source ~/.bashrc

Tensorflowをpipでインストール

pip install tensorflow-gpu

GoogleのBERTをクローンしてくる

git clone https://github.com/google-research/bert

学習済みのBERTモデルをダウンロードしてくる

wget https://storage.googleapis.com/bert_models/2018_10_18/uncased_L-12_H-768_A-12.zip
unzip uncased_L-12_H-768_A-12.zip

BERTをpre-trainingにつかってNERするためのコードを落としてくる

git clone https://github.com/kyzhouhzau/BERT-NER

GoogleのBERTを以下のように配置する

BERT-NER
|____ bert # GoogleのBERTリポジトリ
|____ BERT_NER.py # kyzhouhzau氏のスクリプトを配置
|____ output/result_dir # mkdir -p output/result_dirで新たに作成
|____ NERdata # NER用のデータ(CoNLL-2003)

最後に以下のコマンドで実行

各種パラメータは私の環境下で指定したものなので,皆さんがつかうときには適宜書き換えてください.

python BERT_NER.py --task_name="NER" --do_train=True --do_eval=True --do_predict=True --data_dir=NERdata --vocab_file=/root/share/disk2/20190214_BERT/uncased_L-12_H-768_A-12/vocab.txt --bert_config_file=/root/share/disk2/20190214_BERT/uncased_L-12_H-768_A-12/bert_config.json --init_checkpoint=/root/share/disk2/20190214_BERT/uncased_L-12_H-768_A-12/bert_model.ckpt.index --max_seq_length=128 --train_batch_size=16 --learning_rate=2e-5 --num_train_epochs=3.0 --output_dir=./output/result_dir/

ちなみに筆者の環境(CPU:16コア, GPUメモリ:122GiB)で--train_batch_size=32に設定するとOOM(Out of Memory) Errorがでたので, --train_batch_size=16に変更した

実行後, BERT-NER/output/result_dir の下にあるeval_results.txtを確認すると精度が確認できる

以下は筆者の結果


epoch=3のときの結果

eval_f = 0.5213871

eval_precision = 0.6434281

eval_recall = 0.45150447

global_step = 1307

loss = 106.11042


epoch=30のときの結果

eval_f = 0.6811273

eval_precision = 0.72659624

eval_recall = 0.6476951

global_step = 13074

loss = 109.76331


あれ?なんでこんなに精度が低いのだろうか?

検証が必要だ.

NER,NLP

Posted by vastee