LoginSignup
59
49

More than 3 years have passed since last update.

Kerasで可変長系列をEmbeddingしてLSTMに入力するときはmask_zero=Trueにする

Last updated at Posted at 2018-06-21

KerasのLSTMに文章を入力して何らかの評価値を出力する場合、よく次のような流れで処理すると思います。

  1. 文章を形態素解析器で単語に分割
  2. 単語系列の系列長を揃える
  3. 単語ベクトルでEmbedding
  4. LSTMに入力
  5. 評価値を出力

「系列長を揃える」というのは、具体的には長すぎる系列を切断したり短すぎる系列をゼロパディングしたりします。

さて、これで問題なく学習できるかと思いきや、学習後にどんな文章を入力しても同じ評価値しか出力しないという状況に陥ってしまいました。

実はこのままだとゼロパディングした部分を0の系列として扱うため、うまく学習できなくなるケースがあるようです。
Embeddingレイヤーmask_zero=Trueにすると、ゼロパディングした部分を無視(?)してくれるようです。

  • mask_zero: 真理値.入力の0をパディングのための特別値として扱うかどうか. これは入力の系列長が可変長となりうる変数を入力にもつRecurrentレイヤーに対して有効です. この引数がTrueのとき,以降のレイヤーは全てこのマスクをサポートする必要があり, そうしなければ,例外が起きます. mask_zeroがTrueのとき,index 0は語彙の中で使えません(input_dim は語彙数+1と等しくなるべきです).

プログラムは次のようになります。

# 文章を形態素解析器で単語に分割
import MeCab
tagger = MeCab.Tagger('-Owakati')
texts = [tagger.parse(x).rstrip() for x in texts]

# 単語をインデックスに変換
from keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer()
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)

# 単語系列の系列長を揃える
from keras.preprocessing.sequence import pad_sequences
maxlen = 8000
X = pad_sequences(sequences, maxlen=maxlen)
print(X.shape) # (2000, 8000)

# embedding_matrixを作成
embedding_matrix = np.zeros((max(tokenizer.word_index.values())+1, word2vec.vector_size))
for word, i in tokenizer.word_index.items():
    if word in wv:
        embedding_matrix[i] = word2vec.wv[word]

# Embedding&LSTM
main_input = Input(shape=(x.shape[1],), name='main_input')
embedding1 = Embedding(
        input_dim=embedding_matrix.shape[0], 
        output_dim=embedding_matrix.shape[1], 
        weights=[embedding_matrix], 
        trainable=False, 
        mask_zero=True, 
        name='embedding1')(main_input)
lstm1 = LSTM(32, name='lstm1')(embedding1)
main_output = Dense(8, name='main_output')(lstm1)
model = Model(inputs=main_input, outputs=main_output)
model.compile(loss='mse', optimizer='adam')

無題.png

embedding_matrixはインデックスをキーとする単語ベクトルの辞書です。
mask_zeroの説明に「index 0は語彙の中で使えません」とあるので、1から開始するようにします。

このようにすると、文章ごとに異なる評価値を出力するようになりました。

59
49
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
49