Класс Keras MultiHeadAttention() не возвращает ожидаемые значения

#keras #tf.keras

Вопрос:

Я хотел бы сопоставить результаты self_attention() функции на странице 339 книги Чолле «Глубокое обучение с помощью Python«, второе издание, с результатами MultiHeadAttention() примера, приведенного чуть ниже на той же странице.

Я написал пример с теми же данными, и у меня разные результаты. Может кто-нибудь объяснить, почему? Я вставил self_attention() функцию для ясности.

 import numpy as np
from scipy.special import softmax
from tensorflow.keras.layers import MultiHeadAttention


def self_attention(input_sequence):
    output = np.zeros(shape=input_sequence.shape)
    # The output will consist of contextual embeddinsgs of the same shape
    for i, pivot_vector in enumerate(input_sequence):
        scores = np.zeros(shape=(len(input_sequence),))
        for j, vector in enumerate(input_sequence):
            scores[j] = np.dot(pivot_vector, vector.T)  # Q K^T
        scores /= np.sqrt(input_sequence.shape[1])  # sqrt(d_k)
        scores = softmax(scores)  # softmax(Q K^T / sqrt(d_k))
        print(i, scores)
        new_pivot_representation = np.zeros(shape=pivot_vector.shape)
        for j, vector in enumerate(input_sequence):
            new_pivot_representation  = vector * scores[j]
        output[i] = new_pivot_representation
    return output


test_input_sequence = np.array([[[1.0, 0.0, 0.0, 1.0],
                                 [0.0, 1.0, 0.0, 0.0],
                                 [0.0, 1.0, 1.0, 1.0]]])

test_input_sequence.shape
# (1, 3, 4)

self_attention(test_input_sequence[0])
"""
returns
[[0.50648039 0.49351961 0.30719589 0.81367628]
 [0.23269654 0.76730346 0.38365173 0.61634827]
 [0.21194156 0.78805844 0.57611688 0.78805844]]

the attention scores being:
[0.50648039 0.18632372 0.30719589]
[0.23269654 0.38365173 0.38365173]
[0.21194156 0.21194156 0.57611688]
"""
att_layer = MultiHeadAttention(num_heads=1,
                               key_dim=4,
                               use_bias=False,
                               attention_axes=(1,))

att_layer(test_input_sequence,
          test_input_sequence,
          test_input_sequence,
          return_attention_scores=True)

"""
returns
array([[[-0.46123487,  0.36683324, -0.47130704, -0.00722525],
        [-0.49571565,  0.37488416, -0.52883905, -0.02713571],
        [-0.4566634 ,  0.38055322, -0.45884743, -0.00156384]]],
      dtype=float32)

and the attention scores
array([[[[0.31446996, 0.36904442, 0.3164856 ],
         [0.34567958, 0.2852166 , 0.36910382],
         [0.2934979 , 0.3996053 , 0.30689687]]]], dtype=float32)>)
"""
 

Ответ №1:

Я нашел ответ. Это связано с тремя плотными слоями перед запросом, ключом и значением и одним после модуля внимания (этот последний плотный слой отсутствует на рис. 11.8 в книге). Чтобы воспроизвести результаты self_attention() , нам просто нужно иметь сквозные плотные слои:

 i_4 = np.identity(4)
w_pt_4 = [i_4.reshape(4, 1, 4) for _ in range(3)]   [i_4.reshape(1, 4, 4)]
att_layer.set_weights(w_pt_4)