Я следовал руководству "На пути к науке о науке" о моделях word2vec и skip-gram, но я наткнулся на проблему, которую я не могу решить, несмотря на многому и многому и несколько неудачных решений.
Шаг, показывающий, как создать архитектуру модели skip-gram, кажется устаревшим из-за использования слоя Merge из keras.layers.
То, что я пытался сделать, это перевести его фрагмент кода, который реализован в Sequential API Keras, в функциональный API, чтобы решить проблему сглаживания слоя Merge, заменив его слоем keras.layers.Dot. Тем не менее, я все еще придерживаюсь этого шага по объединению двух моделей (слова и контекста) в конечную модель, архитектура которой должна быть такой:
Вот код, который использовал автор:
from keras.layers import Merge
from keras.layers.core import Dense, Reshape
from keras.layers.embeddings import Embedding
from keras.models import Sequential
# build skip-gram architecture
word_model = Sequential()
word_model.add(Embedding(vocab_size, embed_size,
embeddings_initializer="glorot_uniform",
input_length=1))
word_model.add(Reshape((embed_size, )))
context_model = Sequential()
context_model.add(Embedding(vocab_size, embed_size,
embeddings_initializer="glorot_uniform",
input_length=1))
context_model.add(Reshape((embed_size,)))
model = Sequential()
model.add(Merge([word_model, context_model], mode="dot"))
model.add(Dense(1, kernel_initializer="glorot_uniform", activation="sigmoid"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
И вот моя попытка перевести реализацию последовательного кода в функциональную:
from keras import models
from keras import layers
from keras import Input, Model
word_input = Input(shape=(1,))
word_x = layers.Embedding(vocab_size, embed_size, embeddings_initializer='glorot_uniform')(word_input)
word_reshape = layers.Reshape((embed_size,))(word_x)
word_model = Model(word_input, word_reshape)
context_input = Input(shape=(1,))
context_x = layers.Embedding(vocab_size, embed_size, embeddings_initializer='glorot_uniform')(context_input)
context_reshape = layers.Reshape((embed_size,))(context_x)
context_model = Model(context_input, context_reshape)
model_input = layers.dot([word_model, context_model], axes=1, normalize=False)
model_output = layers.Dense(1, kernel_initializer='glorot_uniform', activation='sigmoid')
model = Model(model_input, model_output)
Однако при выполнении возвращается следующая ошибка:
ValueError: Layer dot_5 вызывается с входом, который не является символическим тензором. Полученный тип:. Полный ввод: [,]. Все входы слоя должны быть тензорами.
Я новичок в функциональном API Keras, я буду признателен, если вы можете дать мне некоторое руководство в этой ситуации о том, как я могу ввести контекстные и текстовые модели в точечный уровень для достижения архитектуры на изображении.
Вы передаете экземпляры Model
на уровень, однако, поскольку ошибка предполагает, что вам необходимо передать тензоры Keras (т.е. выходы слоев или моделей) на слои в Keras. У вас есть два варианта. Один из них - использовать атрибут .output
экземпляра Model
следующим образом:
dot_output = layers.dot([word_model.output, context_model.output], axes=1, normalize=False)
или, что то же самое, вы можете напрямую использовать выходные тензоры:
dot_output = layers.dot([word_reshape, context_reshape], axes=1, normalize=False)
Кроме того, вам необходимо применить слой Dense
который следует за dot_output
и передать экземпляры Input
layer в качестве входных данных Model
. Следовательно:
model_output = layers.Dense(1, kernel_initializer='glorot_uniform',
activation='sigmoid')(dot_output)
model = Model([word_input, context_input], model_output)