Существует элегантный способ сделать то, что вам нужно.
Проблема с вашим решением состоит в том, что:
- размер ввода велик:
(batch_size, MAX_SEQUENCE_LENGTH, dim)
и может не подходитьв памяти. - Вы не сможете обучать и обновлять векторы слов согласно своей задаче
Вместо этого вы можете просто сойти с рук: (batch_size, MAX_SEQUENCE_LENGTH)
.Слой встраивания keras позволяет передать индекс слова и получить вектор.Итак, 42 -> Embedding Layer -> [3, 5.2, ..., 33]
.
Для удобства модель w2v от gensim имеет функцию get_keras_embedding
, которая создает необходимый вам слой встраивания для вас с обученными весами.
gensim_model = # train it or load it
embedding_layer = gensim_model.wv.get_keras_embedding(train_embeddings=True)
embedding_layer.mask_zero = True # No need for a masking layer
model = Sequential()
model.add(embedding_layer) # your embedding layer
model.add(Bidirectional(
LSTM(num_lstm, dropout=0.5, recurrent_dropout=0.4, return_sequences=True))
)
Но вы должны убедиться, что индекс дляСлово в данных совпадает с индексом для модели word2vec.
word2index = {}
for index, word in enumerate(model.wv.index2word):
word2index[word] = index
Используйте приведенный выше словарь word2index
, чтобы преобразовать ваши входные данные в тот же индекс, что и в модели gensim.
Например, ваши данные могут быть:
X_train = [["hello", "there"], ["General", "Kenobi"]]
new_X_train = []
for sent in X_train:
temp_sent = []
for word in sent:
temp_sent.append(word2index[word])
# Add the padding for each sentence. Here I am padding with 0
temp_sent += [0] * (MAX_SEQUENCE_LENGTH - len(temp_sent))
new_X_train.append(temp_sent)
X_train = numpy.as_array(new_X_train)
Теперь вы можете использовать X_train
, и это будет выглядеть так: [[23, 34, 0, 0], [21, 63, 0, 0]]
Слой встраивания автоматически сопоставит индекс с этим вектором и обучит его, еслиНужен.
Я думаю, что это лучший способ сделать это, но я выясню, как gensim хочет, чтобы это было сделано, и обновлю этот пост, если необходимо.