[17/08/07 00:38 更新]
今作ったchar_lstm_train_jp.pl
とchar_lstm_gen_jp.pl
を、文字レベルの学習から単語レベルの学習に変更する。そのために、Text::MeCab
を使うので、インストールのページを参考に、インストールしておくこと。
word_lstm_jp_train.pl
)
char_lstm_jp_train.pl
をword_lstm_jp_train.pl
にコピーしておく。GetOptions
の中のprefix
のデフォルトを変更。
'prefix=s' => \(my $prefix = 'word_lstm_jp' ),
後半のpackage main;
が始まるまでは変更なし。Text::MeCab
を読み込む。
use Text::MeCab;
データを読み込んだあとに、ちょっとした工夫をしている。改行を単語のひとつに数えるために、別の文字列に変換している。後で戻すことを忘れないこと。
$fdata =~ s/\n/ :: /g;
そのあとは、mecabを利用して単語に分けて%vocabulary
と$fdata
を作る。
my @wds = ();
my $mc = Text::MeCab->new();
my $nx = $mc->parse($fdata);
while ($nx) {
my $wd = decode_utf8($nx->surface);
push @wds, $wd if $wd;
$nx = $nx->next;
}
my %vocabulary; my $i = 0;
$fdata = pdl(map{ exists $vocabulary{$_} ? $vocabulary{$_} : ($vocabulary{$_} = $i++) } @wds);
変更点はこれだけ。
Epoch数25で実行してみると、こんな感じ。
Epoch[0] Train-Perplexity=76.289168
Epoch[0] Time cost=11.779
Epoch[1] Train-Perplexity=9.079578
Epoch[1] Time cost=11.905
Epoch[2] Train-Perplexity=2.950353
Epoch[2] Time cost=11.736
Epoch[3] Train-Perplexity=1.856245
Epoch[3] Time cost=11.962
Epoch[4] Train-Perplexity=1.535606
Epoch[4] Time cost=12.036
Epoch[5] Train-Perplexity=1.396455
Epoch[5] Time cost=12.439
Epoch[6] Train-Perplexity=1.318441
Epoch[6] Time cost=12.289
Epoch[7] Train-Perplexity=1.268591
Epoch[7] Time cost=12.545
Epoch[8] Train-Perplexity=1.233796
Epoch[8] Time cost=12.583
Epoch[9] Train-Perplexity=1.207820
Epoch[9] Time cost=12.458
Epoch[10] Train-Perplexity=1.187615
Epoch[10] Time cost=12.449
Epoch[11] Train-Perplexity=1.171490
Epoch[11] Time cost=13.016
Epoch[12] Train-Perplexity=1.158333
Epoch[12] Time cost=13.069
Epoch[13] Train-Perplexity=1.147435
Epoch[13] Time cost=13.049
Epoch[14] Train-Perplexity=1.138458
Epoch[14] Time cost=12.956
Epoch[15] Train-Perplexity=1.131047
Epoch[15] Time cost=13.190
Update[1002]: Changed learning rate to 9.90000e-04
Epoch[16] Train-Perplexity=1.124606
Epoch[16] Time cost=13.073
Epoch[17] Train-Perplexity=1.118849
Epoch[17] Time cost=13.466
Epoch[18] Train-Perplexity=1.113460
Epoch[18] Time cost=12.984
Epoch[19] Train-Perplexity=1.108719
Epoch[19] Time cost=14.556
Epoch[20] Train-Perplexity=1.104825
Epoch[20] Time cost=13.404
Epoch[21] Train-Perplexity=1.101403
Epoch[21] Time cost=13.549
Epoch[22] Train-Perplexity=1.097612
Epoch[22] Time cost=13.182
Epoch[23] Train-Perplexity=1.094173
Epoch[23] Time cost=13.348
Epoch[24] Train-Perplexity=1.090882
Epoch[24] Time cost=13.315
Saved checkpoint to "word_lstm_jp-0025.params"
word_lstm_jp_gen.pl
)
char_lstm_jp_gen.pl
を改造。
まず、GetOptions
の中で、prefix
のデフォルトをword_lstm_jp_train.pl
に合わせておく。
'prefix=s' => \(my $prefix = 'word_lstm_jp' ),
sub sample
の出力部分は、一旦変数に収めて、改行文字の変換を元に戻して、表示。
my $nxt = $reverse_vocab{$next_char};
$nxt =~ s/::/\n/;
print encode_utf8($nxt);
実行結果はこんな感じ。
思ったときが、一番間違いやすい。
うまくいかないと思ったときは、既に間違っている」
%%
「マーフィの法則を熟知したるものは、マーフィの法則に縛られる」
%%
「議論がすれ違ったときには、まず、言葉の定義が共通であるかどうか確かめよ」
KGKによる議論の第一法則
%%
「感情的な発言は、議論を後退させる事はあっても、議論を進ませる事はない」
KGKによる議論の第二法則
%%
「問題を解決するためには、その問題に対して何等かの判断を下さなければならない。そして、正しい判断は、正しい情報と正しい分析の上に初めてなり立つ」
KGKによる知的問題解決の一般法則その1
%%
「同じ結果を生むのなら、楽な解決法を選ぶべきである。
同じ労力なら、美しい解決法を選ぶべきである」
KGKに
……、文章生成というより、文章再生? 入力データが小さすぎるか?
単語に分けるだけより、品詞を反映した方がいいんじゃないかと思って、「[品詞]単語」で学習させてみたのだが、考えてみれば、あまり意味がなかった。この方法が意味を持つには、同じ単語が別の品詞に分類されることが多くなければならない。
まあ、作ってみたんで、lc_word_lstm_jp_train.pl
とlc_word_lstm_jp_gen.pl
の名で置いている。
[「日本語の文字レベル学習と文章生成」に戻る] [「PerlとMXNetで文章生成」に戻る] [「あえてのPerl」に戻る]