Как добавить механизм внимания в keras?

Я в настоящее время использую этот код, который я получаю от одного обсуждения на github. Здесь код механизма внимания:

_input = Input(shape=[max_length], dtype='int32')

# get the embedding layer
embedded = Embedding(
        input_dim=vocab_size,
        output_dim=embedding_size,
        input_length=max_length,
        trainable=False,
        mask_zero=False
    )(_input)

activations = LSTM(units, return_sequences=True)(embedded)

# compute importance for each step
attention = Dense(1, activation='tanh')(activations)
attention = Flatten()(attention)
attention = Activation('softmax')(attention)
attention = RepeatVector(units)(attention)
attention = Permute([2, 1])(attention)


sent_representation = merge([activations, attention], mode='mul')
sent_representation = Lambda(lambda xin: K.sum(xin, axis=-2), output_shape=(units,))(sent_representation)

probabilities = Dense(3, activation='softmax')(sent_representation)

Это правильный способ сделать это? я как бы ожидал существования распределенного по времени слоя, так как механизм внимания распределяется на каждом временном шаге RNN. Мне нужно, чтобы кто-то подтвердил, что эта реализация (код) является правильной реализацией механизма внимания. Спасибо.

Ответы

Ответ 1

Если вы хотите обратить внимание на измерение времени, то эта часть вашего кода кажется мне верной:

activations = LSTM(units, return_sequences=True)(embedded)

# compute importance for each step
attention = Dense(1, activation='tanh')(activations)
attention = Flatten()(attention)
attention = Activation('softmax')(attention)
attention = RepeatVector(units)(attention)
attention = Permute([2, 1])(attention)

sent_representation = merge([activations, attention], mode='mul')

Вы разработали вектор внимания формы (batch_size, max_length):

attention = Activation('softmax')(attention)

Я никогда не видел этот код раньше, поэтому я не могу сказать, действительно ли это правильно или нет:

K.sum(xin, axis=-2)

Дальнейшее чтение (вы можете посмотреть):

Ответ 2

Механизм внимания обращает внимание на разную часть предложения:

activations = LSTM(units, return_sequences=True)(embedded)

И он определяет вклад каждого скрытого состояния этого предложения в

  1. Вычисление совокупности каждого скрытого состояния attention = Dense(1, activation='tanh')(activations)
  2. Назначение весов для разного attention = Activation('softmax')(attention) государства attention = Activation('softmax')(attention)

И, наконец, обратите внимание на разные состояния:

sent_representation = merge([activations, attention], mode='mul')

Я не совсем понимаю эту часть: sent_representation = Lambda(lambda xin: K.sum(xin, axis=-2), output_shape=(units,))(sent_representation)

Чтобы лучше понять, вы можете обратиться к этим и это, а также это одна дает хорошую реализацию, если вы можете понять больше по своему усмотрению.

Ответ 3

Недавно я работал с применением механизма внимания на плотном слое, и вот один пример реализации:

def baseline_model():
  input_dims = train_data_X.shape[1]
  inputs = Input(shape=(input_dims,))
  dense1800 = Dense(1800, activation='relu', kernel_regularizer=regularizers.l2(0.01))(inputs)
  attention_probs = Dense( 1800, activation='sigmoid', name='attention_probs')(dense1800)
  attention_mul = multiply([ dense1800, attention_probs], name='attention_mul')
  dense7 = Dense(7, kernel_regularizer=regularizers.l2(0.01), activation='softmax')(attention_mul)   
  model = Model(input=[inputs], output=dense7)
  model.compile(optimizer='adam',
                loss='categorical_crossentropy',
                metrics=['accuracy'])
  return model

print (model.summary)

model.fit( train_data_X, train_data_Y_, epochs=20, validation_split=0.2, batch_size=600, shuffle=True, verbose=1)

enter image description here