Недавно я наткнулся на предупреждение в Tensorflow, которое вызвало у меня недоумение, и на его исправление потребовалось некоторое время. Поскольку я не нашел решения в Интернете, я хотел поделиться.
Я создаю архитектуру преобразователя (кодер-декодер). Но результаты моих тренировок действительно плохие. Трансформатор всегда дает один и тот же ответ независимо от входных данных, хотя точность обучения выглядит очень хорошей (выше 0,95). Вдобавок ко всему я получаю следующее предупреждение:
WARNING:tensorflow:Gradients do not exist for variables ['embedding/embeddings:0'] when minimizing the loss. If you're using 'model.compile()', did you forget to provide a 'loss' argument?
И кодер, и декодер имеют
keras.Embedding
keras_nlp.PositionEmbedding
слой.Вот код кодировщика:
encoder_inputs = Input(shape=(encoder_inputs_size,), name = "encoder_inputs")
token_embeddings = Embedding(input_dim=vocabulary_size, output_dim=embedding_dim) (encoder_inputs)
position_embeddings = PositionEmbedding(sequence_length=encoder_inputs_size)(token_embeddings)
encoder_outputs = TransformerEncoder(intermediate_dim=intermediate_dim, num_heads=num_heads)(inputs=position_embeddings)
encoder = Model(encoder_inputs, encoder_outputs, name = "encoder")
Существует keras_nlp.TokenAndPositionEmbedding
, который объединяет два встраивания в один слой и при его использовании проблема исчезает. Но поскольку я хочу использовать другие формы внедрения, например встраивание патчей для обработки изображений, я не могу использовать этот комбинированный слой.
Решение заключается в том, что в отличие от обычных слоев keras, которые просто передают информацию при их соединении, встраивание токенов и позиционное встраивание необходимо складывать вручную, поэтому следующий код решает проблему:
encoder_inputs = Input(shape=(encoder_inputs_size,), name = "encoder_inputs")
token_embeddings = Embedding(input_dim=vocabulary_size, output_dim=embedding_dim)(encoder_inputs)
position_embeddings = PositionEmbedding(sequence_length=encoder_inputs_size)(token_embeddings)
# this line adds up the embeddings and fixes the problem
embeddings = token_embeddings + position_embeddings
encoder_outputs = TransformerEncoder(intermediate_dim=intermediate_dim, num_heads=num_heads)(inputs=position_embeddings)
encoder = Model(encoder_inputs, encoder_outputs, name = "encoder")