December 10, 2017
この記事は自然言語処理 Advent Calendar 2017の11日目の記事になります。
AAAI 2016で発表されたCharacter-Aware Neural Language Modelsという論文を読んだので紹介します。
そもそも言語モデル(language model)とは、ある単語の系列が与えられたときに、次に来る単語を予測することをモデリングしているものです。例えばある単語の系列
が与えられたときに、単語が出現する確率は
と表されます。言語モデルは、この確率について頻出する単語の系列が与えられたときに高くなるように学習します。
言語モデルの評価には、パープレキシティ(perplexity)が使われることが多いです。
100%単語の出現を予測することができればとなり、 パープレキシティは1.0になります。逆に予測ができなければできないほどパープレキシティは1よりも大きくなります。モデルとデータの量にもよりますが、数十から百強程度が適正範囲かもしれません。
入力が文字レベルだけの言語モデル作ったよ。出力は相変わらず単語レベルだよ。文字レベルの入力をCNNしてHighwayして出てきた出力をLSTMなRNN-LM(Recurrent neural network language model)に食わせるよ。英語のPenn Treebankにおいては、既存モデルよりパラメータ数60%少ないけど同等の性能だったよ。
入力は文字埋め込み(character embeddings)の系列を文書の長さ分だけ用意したテンソル(i.e. shape=(文書の長さ, 単語の長さ, 文字埋め込みの次元数))。各単語ごとにTemporal Conv(i.e. One-dimensional Conv)とTemporal Max-poolingを行い(i.e. shape=(文書の長さ, フィルタ枚数))、Highwayし、最後にLSTMに流し込む(i.e. output shape=(文書の長さ, 単語の語彙サイズ))。
(当時の)state-of-the-artと同等の結果だったよ。訴求点としては、SOTAよりも60%もパラメータ減らしたのに性能が同等だったことを言っている。
各クエリについて、学習された単語埋め込み(word embeddings)のコサイン類似度ランキングを作成したのが以下の表。モデルごとに比較している。特筆すべきは、入力が単語レベルの通常のモデル(LSTM-Word)では、語彙データに存在しない(Out-of-Vocabulary)未知語について扱うことができないが、文字レベルの今回のモデルは未知語についても単語埋め込みに落とし込むことができる。現に、未知語であるlooooook(SNSとかには出てきそう?)についてlook、looks、looked、looking等とコサイン類似度が大きかった。面白い。
続いては、文字レベルのn-gramの単語埋め込みを主成分分析で2次元に落とし込んで可視化したのが以下の図。 赤が接頭辞、青が接尾辞、オレンジがハイフン繋ぎの、灰色がその他となっている。 これを書いている途中でだんだん単語埋め込みという言葉がここでは適切ではない気がしてきた。
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Highway
from keras.layers import Input
from keras.layers import Embedding
from keras.layers import TimeDistributed
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Reshape
from keras.layers import Concatenate
from keras.layers import LSTM
from keras.layers import BatchNormalization
from keras.models import Model
def build_lstm_char_cnn(batch_size = 20,
word_length = 10,
sentence_length = 100,
word_vocab_size = 10000,
char_vocab_size = 100,
char_embedding_dim = 128,
lstm_size = 650,
dropout_ratio = 0.5):
filsters = [50, 100, 150, 200, 200, 200, 200]
filster_sizes = [1, 2, 3, 4, 5, 6, 7]
x = Input(batch_shape=(batch_size, sentence_length, word_length))
char_embeddings = TimeDistributed(Embedding(char_vocab_size, char_embedding_dim))(x)
output = []
for f, f_size in zip(filsters, filster_sizes):
h = Conv2D(f, (1, f_size), activation='tanh')(char_embeddings)
h = MaxPooling2D(pool_size=(1, word_length-f_size+1))(h)
h = Reshape((sentence_length, f))(h)
output.append(h)
h = Concatenate()(output)
h = BatchNormalization()(h)
h = TimeDistributed(Highway(activation='relu'))(h)
h = TimeDistributed(Highway(activation='relu'))(h)
h = LSTM(lstm_size, activation='tanh', recurrent_activation='sigmoid', return_sequences=True)(h)
h = LSTM(lstm_size, activation='tanh', recurrent_activation='sigmoid', return_sequences=True)(h)
h = Dropout(dropout_ratio)(h)
output = TimeDistributed(Dense(word_vocab_size, activation='softmax'))(h)
return Model(x, output)
パープレキシティの推移は後日載せますが、とりあえず学習した結果得られたword(char sequence) embeddingsについて各クエリに最も近い5語を表示してみました。論文の実験結果に近づいた!
----------------
searching for most similar 5 words to "while" ...
['where', 'whenever', 'chile', 'wheels', 'when']
----------------
searching for most similar 5 words to "his" ...
['its', 'this', 'hhs', 'eric', 'the']
----------------
searching for most similar 5 words to "you" ...
['boy', 'nobody', 'do', 'we', 'dog']
----------------
searching for most similar 5 words to "richard" ...
['gerard', 'bernard', 'leonard', 'sanford', 'maynard']
----------------
searching for most similar 5 words to "trading" ...
['engaging', 'heading', 'riding', 'reading', 'sliding']
----------------
input word does not appear in vocabulary data
calculating word embedding of "computer-aided" ... done!
searching for most similar 5 words to "computer-aided" ...
['computer-guided', 'computerized', 'competitive', 'prosecuted', 'high-priced']
----------------
input word does not appear in vocabulary data
calculating word embedding of "misinformed" ... done!
searching for most similar 5 words to "misinformed" ...
['informed', 'performed', 'confirmed', 'emphasized', 'speculated']
----------------
input word does not appear in vocabulary data
calculating word embedding of "looooook" ... done!
searching for most similar 5 words to "looooook" ...
['look', 'outlook', 'cook', 'book', 'took']
----------------