studylog/北の雲

chainer/python/nlp

NN言語モデルの低頻度単語とメモリ問題

低火力ディープラーニングにつきまとう問題として第一にGPUのメモリ問題がある。
個人で用意できるレベルのハードではとにかく足りない。

以下言語モデル構築の話。
wikipediaの1/50コーパスをneologdで分かち書きしたときに語彙は25万ぐらい。
これを全部語彙として採用してChainerのEmbedに投げると6G~8GクラスのGPUだとメモリ不足で学習できない。

なので低頻度語として一部を切り捨てる必要がある。
仮に10万を語彙として採用し、それ以外の15万は低頻度として切り捨ててそれらを「低頻度単語(<低頻度>)」としてEmbedに専用のIDを一つ付与して学習すると、文出力の時にこうなる。

これによって<低頻度>の<低頻度>な<低頻度>を<低頻度>、<低頻度>の<低頻度>に<低頻度>をつけた。

おぉ…。
一つ一つは低頻度でも、ちりも積もればエベレストに。
普通の名詞や動詞が全く出力されず、助詞・助動詞・<低頻度>の3つばかりが出力されてしまう。

こういう場合はどうすればいいんだろうと前から思ってて、品詞を付与したりしてた。<低頻度-名詞><低頻度-動詞>のようにわける。
これでも粒度が荒すぎるので<低頻度-名詞-固有名詞>と細かくしたりあるいは後ろの接続品詞情報を付与したりしてた。

書きながら思いついたのだけどfastTextやWord2VecのWord embeddingをクラスタリングして番号振ったのを付与したらどうだろうか。
意味的にも近いし品詞もほぼ同じなので出力するときに楽そう。

品詞と違ってクラスタリングの分割数を変える事で粒度をコントロールできるし便利そう。
おわり。