케라스 어텐션 메커니즘(Keras Attention Mechanism) (Dense)

머신러닝과 딥러닝 · 2020. 1. 8. 21:05

간단한 어텐션 메커니즘 예제를 구현

 

import tensorflow as tf
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

input_dims = 32

def build_model(input_dims):
    # Input Layer
    input_layer     = tf.keras.layers.Input(shape=(input_dims,))
    
    # Attention Layer
    attention_probs  = tf.keras.layers.Dense(input_dims, activation='softmax')(input_layer)
    attention_mul    = tf.keras.layers.multiply([input_layer, attention_probs])

    # Full Connected Layer
    fc_attention_mul = tf.keras.layers.Dense(64)(attention_mul)
    y                = tf.keras.layers.Dense(1, activation='sigmoid')(fc_attention_mul)

    return tf.keras.Model(inputs=[input_layer], outputs=y)
   
model = build_model(input_dims)
model.summary()

 

해당 모델에 들어갈 데이터를 생성하는 코드는 다음과 같다.

def get_data(n, input_dims, attention_column=1):

    train_x = np.random.standard_normal(size=(batch_size, input_dims))
    train_y = np.random.randint(low=0, high=2, size=(n, 1))
    train_x[:, attention_column] = train_y[:, 0]
    
    return (train_x, train_y)
    

train_x는 1번째(디폴트값) 데이터값이 train_y와 같다는 점을 제외하고는 랜덤값이다.

train_y는 binary(0 또는 1)이다.

실제로, 위의 모델은 target = x[attention_column]임을 학습해야함.

그러므로, 어텐션의 대부분은 attention_column에 초점이 맞춰져야한다.

 

데이터를 생성하고, train dataset으로 학습을 하면 다음과 같다.

train_x, train_y = get_data(10000, 32, 5)
test_x,  test_y  = get_data(10000, 32, 5)
 
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(train_x, train_y, epochs=20, batch_size=64, validation_split=0.5, verbose=2)

 

이제 학습된 모델의 중간층 값을 보고 싶다.

입력에 대해 중간층의 출력을 반환하는 모델을 만든다.

layer_outputs    = [layer.output for layer in model.layers]
activation_model = tf.keras.models.Model(inputs=model.input, outputs=layer_outputs)

 

이제 activation_model에 test_x 데이터를 주입하면 다음과 같다.

output_data      = activation_model.predict(test_x)

print(len(output_data))
# 5 <class 'list'>

output data의 길이는 5이고 타입은 list이다. 

아래 model.summary()의 결과를 다시 참고하면

 

output_data[0]는 input_18 출력값

output_data[1]는 dense_51의 출력값과 같다.

 

우리가 관심 있는 것은 첫번째 Dense 레이어의 출력값이다.

 

 

print(output_data[1], output_data[1].shape)

output_data[1]을 np.mean을 사용하여 column의 평균을 구한다.

attention_vector = np.mean(output_data[1], axis=0)
print(attention_vector, attention_vector.shape)

df = pd.DataFrame(attention_vector.transpose(), columns=['attention (%)'])
df.plot.bar()

5번 컬럼이 확실히 값이 높다.

 

 

https://github.com/philipperemy/keras-attention-mechanism

 

philipperemy/keras-attention-mechanism

Attention mechanism Implementation for Keras. Contribute to philipperemy/keras-attention-mechanism development by creating an account on GitHub.

github.com