雑記: transformers の examples/token-classification を実行するだけ

以下の transformers リポジトリの固有表現抽出タスクの例(WNUT’17 データの方)を実行するだけです。
https://github.com/huggingface/transformers/tree/master/examples/token-classification
但し、使用する学習済みモデルを bert-large-cased にすると手元のマシンでは DefaultCPUAllocator: can't allocate memory になったので、さしあたり以下では bert-base-cased に変更しています。

手順
transformers リポジトリを clone して examples/token-classification ディレクトリに移動する

git clone https://github.com/huggingface/transformers.git
cd transformers/examples/token-classification/

WNUT’17 データを取得する

mkdir -p data_wnut_17
curl -L 'https://github.com/leondz/emerging_entities_17/raw/master/wnut17train.conll'  | tr '\t' ' ' > data_wnut_17/train.txt.tmp
curl -L 'https://github.com/leondz/emerging_entities_17/raw/master/emerging.dev.conll' | tr '\t' ' ' > data_wnut_17/dev.txt.tmp
curl -L 'https://raw.githubusercontent.com/leondz/emerging_entities_17/master/emerging.test.annotated' | tr '\t' ' ' > data_wnut_17/test.txt.tmp

ls data_wnut_17/  # (train|dev|test).txt.tmp が取得できていることを確認

プレ処理として128トークンを超える文章は分割する

export MAX_LENGTH=128
export BERT_MODEL=bert-base-cased  # トークン数を数えるのでトークナイザの指定が必要
python scripts/preprocess.py data_wnut_17/train.txt.tmp $BERT_MODEL $MAX_LENGTH > data_wnut_17/train.txt
python scripts/preprocess.py data_wnut_17/dev.txt.tmp $BERT_MODEL $MAX_LENGTH > data_wnut_17/dev.txt
python scripts/preprocess.py data_wnut_17/test.txt.tmp $BERT_MODEL $MAX_LENGTH > data_wnut_17/test.txt

ls data_wnut_17/  # プレ処理済みの (train|dev|test).txt が生成されていることを確認

ラベルを収集する

cat data_wnut_17/train.txt data_wnut_17/dev.txt data_wnut_17/test.txt | cut -d " " -f 2 | grep -v "^$"| sort | uniq > data_wnut_17/labels.txt

vi data_wnut_17/labels.txt  # 6固有表現×(B+I)+O=13ラベルのリストが生成されていることを確認

設定ファイルを用意する

vi wnut_17.json  # 以下をコピペするだけ
{
    "data_dir": "./data_wnut_17",
    "labels": "./data_wnut_17/labels.txt",
    "model_name_or_path": "bert-base-cased",
    "output_dir": "wnut-17-model-1",
    "max_seq_length": 128,
    "num_train_epochs": 3,
    "per_device_train_batch_size": 32,
    "save_steps": 425,
    "seed": 1,
    "do_train": true,
    "do_eval": true,
    "do_predict": true,
    "fp16": false
}

モデルを学習する

python run_ner.py wnut_17.json
# 学習が走る

vi wnut-17-model-1/test_predictions.txt  # テストデータへの予測結果が出力されていることを確認

補足
WNUT’17 について
固有表現抽出タスクでも、レアなエンティティを含むタスクとのことです。
WNUT’17 Emerging and Rare Entities task | noisy-text.github.io
ラベリングされている固有表現は6種類あります。
Person人名(架空の人名でも可)。
Location地名(架空の地名でも可)。
Corporation会社名(場所や商品を指している場合は Location, Product へ)。
Product商品名(架空の商品名でも可)。
Creative work創作物(映画、本、歌など)の名前。
Groupグループ名(スポーツチーム、バンドなど)。会社名は Corporation へ。
train.txt.tmp の一番最初の文章をみると、以下のように地名がラベリングされています。
@paulwalk It's the view from where I'm living for two weeks. Empire State Building = ESB. Pretty bad storm here last evening.
設定ファイルについて
以下のファイルの引数が指定できます。
transformers/training_args.py at master · huggingface/transformers · GitHub
モデルについて
学習済みの bert-base-cased を利用した BertForTokenClassification モデルで各トークンを分類しています。
https://github.com/huggingface/transformers/blob/master/src/transformers/modeling_bert.py#L1447-L1530
  入力文章(トークンIDの列)
  →[BERT]
  → 768 次元の特徴ベクトルの列(※ bert-large-cased なら 1024 次元)
  →[ドロップアウト
  →[全結合]
  → 13次元の出力ベクトルの列(※ 活性化前)
損失は正解ラベルとの torch.nn.CrossEntropyLoss によります。
学習について
AdamW で学習します。
https://github.com/huggingface/transformers/blob/master/src/transformers/trainer.py#L583
https://github.com/huggingface/transformers/blob/master/src/transformers/trainer.py#L412
https://github.com/huggingface/transformers/blob/master/src/transformers/optimization.py#L219