Моя цель - использовать Transformer для предсказания последовательности, как и seq2seq.Но когда я декодирую последовательность, она всегда отвечает мне одними и теми же результатами, независимо от того, во что я вхожу.
Традиционно, кодировщик Transformer включает в себя модуль самообслуживания и модуль прямой связи, а декодер - самообслуживаниемодуль, модуль взаимного внимания и модуль обратной связи.И со следующими настройками:
Настройка 1: маскировка использования самоконтроля кодировщика: False;
маскировка использования самоконтроля декодера: True;
использование взаимного внимания декодерамаскирование: False.
Настройка 2: маскировка с использованием собственного внимания кодера: False;
маскировка с использованием собственного внимания декодера: True;
маскировка с использованием взаимного внимания декодера:Верно
Когда я использую настройку 1, модель всегда отвечает мне одинаковыми результатами, независимо от того, во что я вхожу.На самом деле, настройка 2 - это неправильная настройка, просто для проверки результатов.Интересно, что когда я использую параметр 2, он возвращает разные ответы для разных входных данных.Я не могу сказать, почему.
У меня довольно много кодов, поэтому я вставляю здесь только код ключа.
Часть модели:
def __get_encoder(self, input_layer):
next_step_input, self.embedding_matrix = self.embedding_layer(input_layer)
next_step_input = self.coordinate_embedding_layer(next_step_input, step=0)
for i in range(self.args.transformer_depth):
next_step_input = (
TransformerEncoderBlock(
name='transformer_encoder' + str(i), num_heads=self.args.num_heads,
residual_dropout=self.transformer_dropout,
attention_dropout=self.transformer_dropout,
activation='relu',
use_masking=False, # Allow bi-directional attention
vanilla_wiring=True) # use vanilla Transformer instead of Universal Transformer
(next_step_input))
return next_step_input
def __get_decoder(self, input_layer, encoder_output):
next_step_input, _ = self.embedding_layer(input_layer)
next_step_input = self.coordinate_embedding_layer(next_step_input, step=0)
for i in range(self.args.transformer_depth):
next_step_input = (
TransformerDecoderBlock(
name='transformer_decoder' + str(i), num_heads=self.args.num_heads,
residual_dropout=self.transformer_dropout,
attention_dropout=self.transformer_dropout,
activation='relu',
self_attention_use_masking=True, # Forbid bi-directional attention
mutual_attention_use_masking=False,
vanilla_wiring=True) # use vanilla Transformer instead of Universal Transformer
([encoder_output, next_step_input]))
return next_step_input
def get_model(self):
inp_query = Input(name='query_input',
shape=(None, ),
dtype='int32'
)
inp_answer = Input(name='answer_input',
shape=(None, ),
dtype='int32',
)
encoder_output = self.__get_encoder(inp_query)
decoder_output = self.__get_decoder(inp_answer, encoder_output)
# build model part
word_predictions = self.output_softmax_layer(
self.output_layer([decoder_output, self.embedding_matrix]))
model = Model(
inputs=[inp_query, inp_answer],
outputs=[word_predictions]
)
return model
Внимание Часть ключа:
attention_heads = K.reshape(
K.batch_dot(
self.apply_dropout_if_needed(
K.softmax(
# mask the attention for the prediction process
self.mask_attention_if_needed(
# core scaled dot product
K.batch_dot( # (batch_size * num_heads, tar_seq_len, src_seq_len)
K.reshape(q, (-1, q_shape[-2], q_shape[-1])), # q_shape: (batch_size*num_heads, q_seq_len, d_model//heads)
K.reshape(k_transposed, # k_transposed: (batch_size*num_heads, d_model//heads, k_seq_len)
(-1, k_t_shape[-2], k_t_shape[-1])))
/ sqrt_d)),
training=training),
K.reshape(v, (-1, v_shape[-2], v_shape[-1]))), # shape: (batch_size * num_heads, v_seq_len, d_model//heads)
(-1, self.num_heads, q_shape[-2], q_shape[-1]))
def mask_attention_if_needed(self, dot_product):
if not self.use_masking:
return dot_product
print('in %s masking...' % self.name)
last_dims = K.shape(dot_product)
q_len, k_len = last_dims[-2], last_dims[-1]
row = K.expand_dims(K.arange(0, q_len), axis=-1)
col = K.expand_dims(K.arange(0, k_len), axis=0)
low_triangle_ones = K.expand_dims(K.cast(col <= row, K.floatx()), axis=0)
inverse_low_triangle = K.ones_like(low_triangle_ones) - low_triangle_ones
close_to_negative_inf = K.constant(-1e9, dtype=K.floatx())
part1 = low_triangle_ones * dot_product
part2 = close_to_negative_inf * inverse_low_triangle
result = (part1 + part2)
return result
Часть декодера
results = [[ds.start_id] for _ in range(cur_batch_size)]
for t in range(1, tar_length):
preds = model.predict([src_input, np.asarray(results)])
for batch_i in range(len(preds)):
last_token_id = np.argmax(preds[batch_i][-1])
results[batch_i].append(last_token_id)
Я ожидаю, что результаты будут отличаться в зависимости от разных входных данных, но я получаю одно и то же.Я проверил почти каждую строку кода, но не могу понять проблему.Кто-нибудь может дать некоторые подсказки о том, как проверить или подтвердить код?Большое спасибо!