ナード戦隊データマン

機械学習と自然言語処理についてのブログ

bpembをkerasのEmbeddingに凍結

BPEmbとは、事前訓練済みのSentencepieceモデルです。

github.com

今回は、BPEmbをKerasのEmbedding layerに凍結する方法を書きます。

コード

まず、以下のURLからBPEmbをダウンロードします。 https://github.com/bheinzerling/bpemb#downloads-for-each-language

wget https://nlp.h-its.org/bpemb/en/en.wiki.bpe.vs5000.d50.w2v.bin.tar.gz
wget https://nlp.h-its.org/bpemb/en/en.wiki.bpe.vs5000.model
wget https://nlp.h-its.org/bpemb/en/en.wiki.bpe.vs5000.vocab
tar -xzvf en.wiki.bpe.vs5000.d50.w2v.bin.tar.gz

次に、ダウンロードしたsentencepieceモデルを読み、Embeddingレイヤーにweightsをのせます。

import sentencepiece as spm
from gensim.models import KeyedVectors

sp = spm.SentencePieceProcessor()
sp.Load("./en.wiki.bpe.vs5000.model")


EMBEDDING_DIM = 50
max_len = 256

word2vec_file = "en.wiki.bpe.vs5000.d50.w2v.bin"
vecs = KeyedVectors.load_word2vec_format(word2vec_file, binary=True)

embedding_matrix = np.zeros((len(vecs.vocab)+1, EMBEDDING_DIM))

for vocab in vecs.vocab:
    embedding_matrix[sp.PieceToId(vocab)] = vecs[vocab]


embedding_layer = Embedding(len(vecs.vocab)+1, EMBEDDING_DIM, 
                                weights=[embedding_matrix], trainable=False, input_length=max_len)

あとは、以下のようにembedding_layerをモデルに結合するだけです。

def build_model(embedding_layer, max_features=5000, max_len=256, dropout_rate=0.5, dim=50, gru_size=100):
    model = Sequential()
    model.add(embedding_layer)
    model.add(SpatialDropout1D(dropout_rate))
    model.add(SeparableConv1D(32, kernel_size=3, padding='same', activation='relu'))
    model.add(MaxPooling1D(pool_size=2))
    model.add(SeparableConv1D(64, kernel_size=3, padding='same', activation='relu'))
    model.add(MaxPooling1D(pool_size=2))
    model.add(CuDNNGRU(gru_size))
    model.add(Dense(1, activation='sigmoid', kernel_initializer="normal"))
    model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
    return model

入力は、以下のように整形して渡します:

X_train = pad_sequences([sp.EncodeAsIds(x) for x in df["tweets"]], maxlen=maxlen) 
y_train = df["label"]
model = build_model(embedding_layer)
model.fit(X_train, y_train)  #実際は他のパラメータもちゃんと設定してください。

参考

GitHub - bheinzerling/bpemb: Pre-trained subword embeddings in 275 languages, based on Byte-Pair Encoding (BPE)