Keras - перевод из последовательного в функциональный API - PullRequest
0 голосов
/ 10 октября 2018

Я следовал учебному руководству Towards Data Science о моделях word2vec и skip-грамм, но наткнулся на проблему, которую не могу решить, несмотря на то, что много ее искал и пытался найти несколько неудачных решений.

https://towardsdatascience.com/understanding-feature-engineering-part-4-deep-learning-methods-for-text-data-96c44370bbfa

Шаг, на котором показано, как построить архитектуру модели скип-граммы, кажется устаревшим из-за использования слоя Merge из keras.layers.

То, что я пытался сделать, былоперевести его фрагмент кода, который реализован в Sequential API-интерфейсе Keras, в Functional API, чтобы решить проблему устаревания слоя Merge, заменив его слоем keras.layers.Dot.Однако я все еще застрял на этом этапе объединения двух моделей (слова и контекста) в конечную модель, архитектура которой должна быть такой:

Skip-gram model summary and architecture

Вот код, который использовал автор:

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: Слой dot_5 был вызван со входом, который не является символическим тензором.Полученный тип:.Полный ввод: [,].Все входные данные для слоя должны быть тензорами.

Я абсолютный новичок в функциональном API Keras, буду благодарен, если вы сможете дать мне несколько советов в этой ситуации о том, как я могу ввестиконтекст и слово модели в точечный слой для достижения архитектуры в изображении.

1 Ответ

0 голосов
/ 10 октября 2018

Вы передаете 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 в качестве входных данных Model.Поэтому:

model_output = layers.Dense(1, kernel_initializer='glorot_uniform',
                            activation='sigmoid')(dot_output)

model = Model([word_input, context_input], model_output)
...