Как построить модель внимания с помощью кераса?

Я пытаюсь понять модель внимания, а также построить ее самостоятельно. После многих поисков я наткнулся на этот веб-сайт, на котором присутствовали Модель закодирована в керасе и тоже выглядит просто. Но когда я попытался построить ту же модель на своей машине, она выдала ошибку с несколькими аргументами. Ошибка возникла из-за несоответствия аргумента, передаваемого в классе Attention. В классе внимания веб-сайта он запрашивает один аргумент, но инициирует объект внимания с двумя аргументами.

import tensorflow as tf

max_len = 200
rnn_cell_size = 128
vocab_size=250

class Attention(tf.keras.Model):
    def __init__(self, units):
        super(Attention, self).__init__()
        self.W1 = tf.keras.layers.Dense(units)
        self.W2 = tf.keras.layers.Dense(units)
        self.V = tf.keras.layers.Dense(1)
    def call(self, features, hidden):
        hidden_with_time_axis = tf.expand_dims(hidden, 1)
        score = tf.nn.tanh(self.W1(features) + self.W2(hidden_with_time_axis))
        attention_weights = tf.nn.softmax(self.V(score), axis=1)
        context_vector = attention_weights * features
        context_vector = tf.reduce_sum(context_vector, axis=1)
        return context_vector, attention_weights

sequence_input = tf.keras.layers.Input(shape=(max_len,), dtype='int32')

embedded_sequences = tf.keras.layers.Embedding(vocab_size, 128, input_length=max_len)(sequence_input)

lstm = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM
                                     (rnn_cell_size,
                                      dropout=0.3,
                                      return_sequences=True,
                                      return_state=True,
                                      recurrent_activation='relu',
                                      recurrent_initializer='glorot_uniform'), name="bi_lstm_0")(embedded_sequences)

lstm, forward_h, forward_c, backward_h, backward_c = tf.keras.layers.Bidirectional \
    (tf.keras.layers.LSTM
     (rnn_cell_size,
      dropout=0.2,
      return_sequences=True,
      return_state=True,
      recurrent_activation='relu',
      recurrent_initializer='glorot_uniform'))(lstm)

state_h = tf.keras.layers.Concatenate()([forward_h, backward_h])
state_c = tf.keras.layers.Concatenate()([forward_c, backward_c])

#  PROBLEM IN THIS LINE
context_vector, attention_weights = Attention(lstm, state_h)

output = keras.layers.Dense(1, activation='sigmoid')(context_vector)

model = keras.Model(inputs=sequence_input, outputs=output)

# summarize layers
print(model.summary())

Как заставить эту модель работать?


person Eka    schedule 09.07.2019    source источник
comment
вот простой способ привлечь внимание: stackoverflow.com/questions/62948332/   -  person Marco Cerliani    schedule 17.07.2020


Ответы (3)


Проблема с тем, как вы инициализируете attention layer и передаете параметры. Вы должны указать количество attention layer единиц в этом месте и изменить способ передачи параметров :

context_vector, attention_weights = Attention(32)(lstm, state_h)

Результат:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 200)          0                                            
__________________________________________________________________________________________________
embedding (Embedding)           (None, 200, 128)     32000       input_1[0][0]                    
__________________________________________________________________________________________________
bi_lstm_0 (Bidirectional)       [(None, 200, 256), ( 263168      embedding[0][0]                  
__________________________________________________________________________________________________
bidirectional (Bidirectional)   [(None, 200, 256), ( 394240      bi_lstm_0[0][0]                  
                                                                 bi_lstm_0[0][1]                  
                                                                 bi_lstm_0[0][2]                  
                                                                 bi_lstm_0[0][3]                  
                                                                 bi_lstm_0[0][4]                  
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 256)          0           bidirectional[0][1]              
                                                                 bidirectional[0][3]              
__________________________________________________________________________________________________
attention (Attention)           [(None, 256), (None, 16481       bidirectional[0][0]              
                                                                 concatenate[0][0]                
__________________________________________________________________________________________________
dense_3 (Dense)                 (None, 1)            257         attention[0][0]                  
==================================================================================================
Total params: 706,146
Trainable params: 706,146
Non-trainable params: 0
__________________________________________________________________________________________________
None
person giser_yugang    schedule 09.07.2019

Уровни внимания теперь являются частью Keras API Tensorflow (2.1). Но он выводит тензор того же размера, что и тензор вашего запроса.

Вот как использовать внимание в стиле Луонг:

query_attention = tf.keras.layers.Attention()([query, value])

И внимание в стиле Бахданау:

query_attention = tf.keras.layers.AdditiveAttention()([query, value])

Адаптированная версия:

attention_weights = tf.keras.layers.Attention()([lstm, state_h])

Дополнительную информацию можно найти на исходном веб-сайте: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Attention https://www.tensorflow.org/api_docs/python/tf/keras/layers/AdditiveAttention

person Redzhep Mehmedov Redzhebov    schedule 29.02.2020
comment
Не могли бы вы уточнить запрос и значение в соответствии с этим конкретным вопросом OP? OP хочет передать lstm и state_h на уровень внимания. - person Arman Malekzadeh; 29.06.2020
comment
А какими должны быть query и value? Любой пример? - person Yahya; 18.04.2021
comment
@Yahya, они должны быть тензорами TensorFlow в формате данных временной последовательности [пакет, время, функция]. Я надеюсь, что это то, о чем вы просили. - person Redzhep Mehmedov Redzhebov; 18.04.2021

Чтобы ответить на конкретный запрос Армана - эти библиотеки используют семантику запросов, значений и ключей после 2018 года. Чтобы отобразить семантику обратно в статью Бахданау или Луонга, вы можете рассматривать «запрос» как последнее скрытое состояние декодера. «Значения» будут набором выходов кодировщика - все скрытые состояния кодировщика. «Запрос» учитывает все «значения».

Какую бы версию кода или библиотеки вы ни использовали, всегда помните, что «запрос» будет расширен по оси времени, чтобы подготовить его к последующему добавлению. Это значение (которое расширяется) всегда будет последним скрытым состоянием RNN. Другим значением всегда будут значения, которые необходимо учитывать - все скрытые состояния на стороне кодировщика. Эту простую проверку кода можно выполнить, чтобы определить, какие «запрос» и «значения» отображаются независимо от библиотеки или кода, которые вы используете.

Вы можете обратиться к https://towardsdatascience.com/create-your-own-custom-attention-layer-understand-all-flavours-2201b5e8be9e, чтобы написать свой собственный уровень внимания менее чем в 6 строках кода.

person Allohvk    schedule 19.11.2020