概要
BERTの本家には文章の尤度を測るサンプルがなかった。
尤度を測れるまでの作業メモ
- 本家 GitHub google-research/bert
- 言語モデル拡張 GitHub xu-song/bert-as-language-model
- 日本語モデル BERT with SentencePiece を日本語 Wikipedia で学習してモデルを公開しました
- 日本語モデルコード GitHub yoheikikuta/bert-japanese
謝辞
google-researchチーム、xu-songさん、yoheikikutaさんに感謝いたします。
フォークしたソース
GitHub KTaskn/bert-as-language-model
手順
- 言語モデル拡張をgit cloneする
- 日本語モデルコードからtokenization_sentencepiece.pyをダウンロードする
- クローンしたディレクトリにmodelsディレクトリを作成する
- 日本語モデルから "内容" => "google drive"から日本語モデルをダウンロードしmodelsディレクトリに保存する
- run_lm_predict.pyのコードを修正する
- 日本語モデルのconfig.iniを参考にからbert_config.jsonを作成する
bash.
$ git clone https://github.com/xu-song/bert-as-language-model.git
$ mkdir models
$ wget --no-check-certificate https://raw.githubusercontent.com/yoheikikuta/bert-japanese/master/src/tokenization_sentencepiece.py
# modelsにモデルをダウンロード
# bert_configを作成する
$ export BERT_BASE_DIR=models
$ export INPUT_FILE=data/lm/test.ja.tsv
$ python run_lm_predict.py \
--input_file=$INPUT_FILE \
--vocab_file=$BERT_BASE_DIR/wiki-ja.vocab \
--bert_config_file=$BERT_BASE_DIR/bert_config.json \
--init_checkpoint=$BERT_BASE_DIR/model.ckpt-1400000 \
--max_seq_length=128 \
--output_dir=/tmp/lm_output/ \
--jp_tokenizer=True
run_lm_predict.py
# 21行目〜
import os
import json
import modeling
import tokenization
# 追加
import tokenization_sentencepiece as tokenization_jp
import numpy as np
import tensorflow as tf
# ~~
# 93行目〜
flags.DEFINE_integer(
"num_tpu_cores", 8,
"Only used if `use_tpu` is True. Total number of TPU cores to use.")
# 追加
flags.DEFINE_bool("jp_tokenizer", False, "Use JP Tokenizer")
class InputExample(object):
def __init__(self, unique_id, text):
self.unique_id = unique_id
self.text = text
# 310行目〜
# 変更
if FLAGS.jp_tokenizer:
tokenizer = tokenization_jp.FullTokenizer(
model_file="./models/jp_model/wiki-ja.model",
vocab_file="./models/jp_model/wiki-ja.vocab",
do_lower_case=True)
else:
tokenizer = tokenization.FullTokenizer(
vocab_file=FLAGS.vocab_file, do_lower_case=FLAGS.do_lower_case)
bert_config.json
{
"attention_probs_dropout_prob" : 0.1,
"hidden_act" : "gelu",
"hidden_dropout_prob" : 0.1,
"hidden_size" : 768,
"initializer_range" : 0.02,
"intermediate_size" : 3072,
"max_position_embeddings" : 512,
"num_attention_heads" : 12,
"num_hidden_layers" : 12,
"type_vocab_size" : 2,
"vocab_size" : 32000
}
実行結果
data/lm/test.ja.tsv
私は本を読む
私は日本を読む
本の国土は広い
日本の国土は広い
/tmp/lm_output/test_results.json
[
{
"tokens": [
{
"token": "▁",
"prob": 0.9849837422370911
},
{
"token": "私は",
"prob": 0.01772877760231495
},
{
"token": "本",
"prob": 0.38430821895599365
},
{
"token": "を読む",
"prob": 0.14501915872097015
}
],
"ppl": 5.6616988500880625
},
{
"tokens": [
{
"token": "▁",
"prob": 0.9833461046218872
},
{
"token": "私は",
"prob": 0.019558683037757874
},
{
"token": "日本",
"prob": 0.00026242720196023583
},
{
"token": "を読む",
"prob": 0.0007271786453202367
}
],
"ppl": 128.47718205285057
},
{
"tokens": [
{
"token": "▁",
"prob": 0.011469533666968346
},
{
"token": "本の",
"prob": 2.954236833829782e-06
},
{
"token": "国土",
"prob": 5.874089401913807e-05
},
{
"token": "は",
"prob": 0.514896810054779
},
{
"token": "広い",
"prob": 3.2568786991760135e-05
}
],
"ppl": 1973.8280517535734
},
{
"tokens": [
{
"token": "▁日本の",
"prob": 0.001967047341167927
},
{
"token": "国土",
"prob": 0.07699552178382874
},
{
"token": "は",
"prob": 0.11561550199985504
},
{
"token": "広い",
"prob": 2.0818872144445777e-05
}
],
"ppl": 228.85563777870746
}
]
summary.
* 私は本を読む => 5.6616988500880625
* 私は日本を読む => 128.47718205285057
* 本の国土は広い => 1973.8280517535734
* 日本の国土は広い => 228.85563777870746
うまくいったかな?
以上