前回の続き。
前回は、一応インストールが完了し、基本的な学習方法を調査したのだが、実際に試行してみるとエラーが出てきたのだった。
1. カテゴリ分類時のエラーを除去するための再ビルド
エラーとなったのは、学習対象の Universal Dependency のトレーニングセットが詳細分類が被っているために発生する以下のエラーだった。
F syntaxnet/term_frequency_map.cc:166] Check failed: category == it->second (VERB vs. AUX)POS tag cannot be mapped to multiple coarse POS tags. 'VB' is mapped to: 'VERB' and 'AUX'
これ、エラーメッセージが示しているように、トレーニングセットの分類を行っている最中に発生している。当該ソースコードは以下だ。
void TagToCategoryMap::SetCategory(const string &tag, const string &category) { const auto it = tag_to_category_.find(tag); if (it != tag_to_category_.end()) { CHECK_EQ(category, it->second) << "POS tag cannot be mapped to multiple coarse POS tags. " << "'" << tag << "' is mapped to: '" << category << "' and '" << it->second << "'"; } else { tag_to_category_[tag] = category; } }
別に詳細分類が被っても、学習には特に問題にならないんじゃないのかなあ? ともかく、この条件式を外して、問答無用でカテゴリ分類するように変更してみる。
void TagToCategoryMap::SetCategory(const string &tag, const string &category) { const auto it = tag_to_category_.find(tag); tag_to_category_[tag] = category; }
これで再度SyntaxNetのビルドを行い、学習させてみる。
$ bazel test syntaxnet/... util/utf8/... $ bazel-bin/syntaxnet/parser_trainer \ --task_context=syntaxnet/context.pbtxt \ --compute_lexicon \ --arg_prefix=brain_pos \ --graph_builder=greedy \ --training_corpus=training-corpus \ # names of training/tuning set --tuning_corpus=tuning-corpus \ --output_path=models \ # where to save new resources --batch_size=32 \ # Hyper-parameters --decay_steps=3600 \ --hidden_layer_sizes=128 \ --learning_rate=0.08 \ --momentum=0.9 \ --seed=0 \ --params=128-0.08-3600-0.9-1 # name for these parameters INFO:tensorflow:Computing lexicon... I syntaxnet/lexicon_builder.cc:124] Term maps collected over 204586 tokens from 12543 documents I syntaxnet/term_frequency_map.cc:137] Saved 18731 terms to models/brain_pos/greedy/128-0.08-3600-0.9-1/word-map. I syntaxnet/term_frequency_map.cc:137] Saved 15710 terms to models/brain_pos/greedy/128-0.08-3600-0.9-1/lcword-map. I syntaxnet/term_frequency_map.cc:137] Saved 50 terms to models/brain_pos/greedy/128-0.08-3600-0.9-1/tag-map. I syntaxnet/term_frequency_map.cc:137] Saved 17 terms to models/brain_pos/greedy/128-0.08-3600-0.9-1/category-map. I syntaxnet/term_frequency_map.cc:137] Saved 47 terms to models/brain_pos/greedy/128-0.08-3600-0.9-1/label-map. I syntaxnet/term_frequency_map.cc:101] Loaded 47 terms from models/brain_pos/greedy/128-0.08-3600-0.9-1/label-map. I syntaxnet/embedding_feature_extractor.cc:35] Features: stack(3).word stack(2).word stack(1).word stack.word input.word input(1).word input(2).word inp ut(3).word;input.digit input.hyphen;stack.suffix(length=2) input.suffix(length=2) input(1).suffix(length=2);stack.prefix(length=2) input.prefix(length=2 ) input(1).prefix(length=2) .... INFO:tensorflow:Epochs: 9, num steps: 56900, seconds elapsed: 471.62, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57000, seconds elapsed: 472.42, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57100, seconds elapsed: 473.18, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57200, seconds elapsed: 474.00, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57300, seconds elapsed: 474.78, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57400, seconds elapsed: 475.55, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57500, seconds elapsed: 476.32, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57600, seconds elapsed: 477.08, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57700, seconds elapsed: 477.82, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57800, seconds elapsed: 478.58, avg cost: 0.04, INFO:tensorflow:Epochs: 9, num steps: 57900, seconds elapsed: 479.35, avg cost: 0.04, I syntaxnet/reader_ops.cc:141] Starting epoch 10
お、何か学習したようだ。成功だ。
思うに、今回は無料のCONLLデータセットであるUniversal Dependencyを使用したから発生したエラーではないだろうか。 Googleの説明には、ほかにも有料のデータセットを使うことができるが、Universal Dependencyのみ無料で使うことができる。 有料版では、このようなエラーを発生させるデータセットは存在しなかったということかなあ?
ここで、学習パラメータとして128-0.08-3600-0.9-1
を指定している。
試しに、models/brain_pos/greedy/128-0.08-3600-0.9-1
を参照してみると、以下のようなファイルが作成されていた。
-rw-rw-r-- 1 vagrant vagrant 114377 May 18 15:37 model.meta -rw-rw-r-- 1 vagrant vagrant 110 May 18 15:37 checkpoint -rw-rw-r-- 1 vagrant vagrant 16264746 May 18 15:37 model -rw-rw-r-- 1 vagrant vagrant 114377 May 18 15:37 latest-model.meta -rw-rw-r-- 1 vagrant vagrant 16264746 May 18 15:37 latest-model -rw-rw-r-- 1 vagrant vagrant 1077 May 18 15:37 status -rw-rw-r-- 1 vagrant vagrant 104888 May 18 15:29 graph -rw-rw-r-- 1 vagrant vagrant 407 May 18 15:29 tag-to-category -rw-rw-r-- 1 vagrant vagrant 62459 May 18 15:29 prefix-table -rw-rw-r-- 1 vagrant vagrant 48771 May 18 15:29 suffix-table -rw-rw-r-- 1 vagrant vagrant 172 May 18 15:29 category-map -rw-rw-r-- 1 vagrant vagrant 547 May 18 15:29 label-map -rw-rw-r-- 1 vagrant vagrant 168481 May 18 15:29 lcword-map -rw-rw-r-- 1 vagrant vagrant 407 May 18 15:29 tag-map -rw-rw-r-- 1 vagrant vagrant 195686 May 18 15:29 word-map -rw-rw-r-- 1 vagrant vagrant 5359 May 18 15:29 context
いくつかのカテゴリ情報と、モデルなどが生成されている。ともかく、これで最初のステップである学習は上手くいったかな?
2. 学習結果をもとに分類テストを実行
次に、学習したモデルをもとに実際に単語の分類をしてみよう。これは、チュートリアルにおける以下に該当する(と思う)。
さっそく実行してみる。トレーニングセットとして、先ほど学習させたパラメータPARAMS=128-0.08-3600-0.9-1
を利用する。
これにより、syntaxnet/context.pbtxt
に記載されているen-ud-test.conlluを使って学習結果をテストするという訳だ。
input { name: 'dev-corpus' record_format: 'conll-sentence' Part { file_pattern: '/home/vagrant/work/ud-treebanks-v1.3/UD_English/en-ud-test.conllu' } }
実行してみよう。
$ for SET in training tuning dev do bazel-bin/syntaxnet/parser_eval \ --task_context=models/brain_pos/greedy/$PARAMS/context \ --hidden_layer_sizes=128 \ --input=$SET-corpus \ --output=tagged-$SET-corpus \ --arg_prefix=brain_pos \ --graph_builder=greedy \ --model_path=models/brain_pos/greedy/$PARAMS/model done I syntaxnet/term_frequency_map.cc:101] Loaded 47 terms from models/brain_pos/greedy/128-0.08-3600-0.9-1/label-map. I syntaxnet/embedding_feature_extractor.cc:35] Features: stack(3).word stack(2).word stack(1).word stack.word input.word input(1).word input(2).word inp ut(3).word;input.digit input.hyphen;stack.suffix(length=2) input.suffix(length=2) input(1).suffix(length=2);stack.prefix(length=2) input.prefix(length=2 ) input(1).prefix(length=2) I syntaxnet/embedding_feature_extractor.cc:36] Embedding names: words;other;suffix;prefix I syntaxnet/embedding_feature_extractor.cc:37] Embedding dims: 64;4;8;8 I syntaxnet/term_frequency_map.cc:101] Loaded 18731 terms from models/brain_pos/greedy/128-0.08-3600-0.9-1/word-map. I syntaxnet/term_frequency_map.cc:101] Loaded 50 terms from models/brain_pos/greedy/128-0.08-3600-0.9-1/tag-map. INFO:tensorflow:Building training network with parameters: feature_sizes: [8 2 3 3] domain_sizes: [18734 5 4195 5342] INFO:tensorflow:Created variable transition_scores:0 with shape (32, 50) and init <function _initializer at 0x7fb7d1383a28> INFO:tensorflow:Created variable step:0 with shape () and init <function OnesInitializer at 0x7fb7d1383ed8> ... INFO:tensorflow:Processed 14 documents INFO:tensorflow:Processed 17 documents INFO:tensorflow:Processed 45 documents INFO:tensorflow:Processed 16 documents INFO:tensorflow:Processed 34 documents I syntaxnet/reader_ops.cc:141] Starting epoch 2 INFO:tensorflow:Processed 2 documents INFO:tensorflow:Total processed documents: 2077 INFO:tensorflow:num correct tokens: 23093 INFO:tensorflow:total tokens: 25096 INFO:tensorflow:Seconds elapsed in evaluation: 1.77, eval metric: 92.02%
最後に分類精度が表示されている。92.02%ということかな?
先ほど参照したパラメータセットのディレクトリに、新しくファイルが作成されていた。
$ ls -lt models/brain_pos/greedy/128-0.08-3600-0.9-1/ total 40528 -rw-rw-r-- 1 vagrant vagrant 796274 May 18 15:38 tagged-dev-corpus -rw-rw-r-- 1 vagrant vagrant 798668 May 18 15:38 tagged-tuning-corpus -rw-rw-r-- 1 vagrant vagrant 6518513 May 18 15:38 tagged-training-corpus -rw-rw-r-- 1 vagrant vagrant 114377 May 18 15:37 model.meta -rw-rw-r-- 1 vagrant vagrant 110 May 18 15:37 checkpoint -rw-rw-r-- 1 vagrant vagrant 16264746 May 18 15:37 model -rw-rw-r-- 1 vagrant vagrant 114377 May 18 15:37 latest-model.meta -rw-rw-r-- 1 vagrant vagrant 16264746 May 18 15:37 latest-model -rw-rw-r-- 1 vagrant vagrant 1077 May 18 15:37 status -rw-rw-r-- 1 vagrant vagrant 104888 May 18 15:29 graph -rw-rw-r-- 1 vagrant vagrant 407 May 18 15:29 tag-to-category -rw-rw-r-- 1 vagrant vagrant 62459 May 18 15:29 prefix-table -rw-rw-r-- 1 vagrant vagrant 48771 May 18 15:29 suffix-table -rw-rw-r-- 1 vagrant vagrant 172 May 18 15:29 category-map -rw-rw-r-- 1 vagrant vagrant 547 May 18 15:29 label-map -rw-rw-r-- 1 vagrant vagrant 168481 May 18 15:29 lcword-map -rw-rw-r-- 1 vagrant vagrant 407 May 18 15:29 tag-map -rw-rw-r-- 1 vagrant vagrant 195686 May 18 15:29 word-map -rw-rw-r-- 1 vagrant vagrant 5359 May 18 15:29 context
tagged-dev-corpusがテスト結果だと思うのだが、ある程度は合っている、という印象だ。最初の一文を抜き出してみよう。以下は学習結果によるテスト。
1 What _ PRON WP _ 0 root _ _ 2 if _ ADP IN _ 4 mark _ _ 3 Google _ PROPN NNP _ 4 nsubj _ _ 4 Morphed _ VERB VBN _ 1 advcl _ _ 5 Into _ PROPN NNP _ 6 case _ _ 6 GoogleOS _ NUM CD _ 4 nmod _ _ 7 ? _ PUNCT . _ 4 punct _ _
ちなみに本来の答えはこちら。
1 What what PRON WP PronType=Int 0 root _ _ 2 if if SCONJ IN _ 4 mark _ _ 3 Google Google PROPN NNP Number=Sing 4 nsubj _ _ 4 Morphed morph VERB VBD Mood=Ind|Tense=Past|VerbForm=Fin 1 advcl _ _ 5 Into into ADP IN _ 6 case _ _ 6 GoogleOS GoogleOS PROPN NNP Number=Sing 4 nmod _ SpaceAfter=No 7 ? ? PUNCT . _ 4 punct _ _
いくつか外れているものがある。これが学習の成果、ということなのかな?