エイエイレトリック

なぐりがき

ngram言語モデルについてまとめる (neural language model)

4記事にわたり、複数の古典的ngram言語モデルについて試しに実装してきました。

torchtextのデータセットを使ってきたので、pytorchで簡単な言語モデルを作ってみます。

元となる論文があるわけではないですが、ネット上に多数実装が多数あるので、それらを参考にしました。

実装コードは gist を参照してください。一番下に埋め込んでます。

参考資料について軽くまとめます。

アーキテクチャ

NgramModel(
  (embedding): Embedding(28782, 100)
  (linear1): Linear(in_features=200, out_features=128, bias=True)
  (linear2): Linear(in_features=128, out_features=28782, bias=True)
)
  • 入力単語を語彙数×次元数で表現する Embedding
  • 活性化関数 Relu
  • 線形変換1 Linear
  • 線形変換2 Linear
  • 確率値として出力 log_softmax

という比較的簡単な構造。

Embedding層はいわゆるword2vecとして単語特徴量を学習する。 Mikolovの論文 (https://arxiv.org/abs/1301.3781) におけるSkipgramやCBOWとは厳密には異なる。

アーキテクチャ参考

DatasetとDataloader

上記アーキテクチャにおいて参考にしたコードたちはデータを直接コード上に書いてバッチサイズも設定していないことがある。なので実践向き (大きいデータ向き) ではない。

Dataloaderを設定して、ngramをバッチサイズごとイテレートした。

今回使っている torchtext.datasets.WikiText2 はすでにイテレーターなのでDatasetとDataloaderどっちも使う必要があるのかわからなかったが、仕組みを理解したいので使うことにした。

  • Datasetではvocabの設定をし、単語を数値に変換したngram単語列と正解単語を返す
  • Dataloaderはバッチサイズを設定し、concatしたデータを返す
    • drop_last=True でバッチサイズより小さいデータは学習に使わない

Text classification with the torchtext library — PyTorch Tutorials 1.11.0+cu102 documentation (テキスト分類タスク向け)の実装に従ったので、もしかしたら別の方法もあるかもしれない。

学習・評価

今回10epochで実験。

学習のloss

WikiText2の場合テストデータのエントロピー4.1636 、 PentTreeDatasetの場合は 4.1657 と小さくなった。 今まで実装してきたモデルでエントロピーが5を切っているモデルはなかったのでかなり良いスコアといえる。

さいごに

公式のtutorial (Welcome to PyTorch Tutorials — PyTorch Tutorials 1.11.0+cu102 documentation) で改めてpytorchを勉強したが、モデルの実装よりデータの扱いについての情報が少なくて結構困った。

日本語ngramデータは公開がされているので頻度ベースのモデルは実装できそうだ。今後試したい。

gist.github.com