汎用言語モデルBERTをつかってNERを動かしてみる
本記事は,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 unzipAnacondaに必要なパッケージをインストール
# apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev libpng-devpyenvのインストール
# 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 ~/.bashrcAnaconda(Python3系)のバージョンを確認
root@xxxx:~/git# pyenv install -l | grep anaconda3anaconda3-4.1.1anaconda3-4.2.0anaconda3-4.3.0anaconda3-4.3.1anaconda3-4.4.0anaconda3-5.0.0anaconda3-5.0.1anaconda3-5.1.0anaconda3-5.2.0anaconda3-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 ~/.bashrcPythonの環境を確認
# python --versionPython 3.7.0 (default, Jun 28 2018, 13:15:42)TensorflowをインストールするためにPython3.6の環境を構築
conda create -n tf_p36 python=3.6 anacondasource activate tf_p36echo 'source activate tf_p36' >> ~/.bashrcsource ~/.bashrcTensorflowをpipでインストール
pip install tensorflow-gpuGoogleの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.zipunzip uncased_L-12_H-768_A-12.zipBERTをpre-trainingにつかってNERするためのコードを落としてくる
git clone https://github.com/kyzhouhzau/BERT-NERGoogleの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
あれ?なんでこんなに精度が低いのだろうか?
検証が必要だ.