에이블스쿨 교육과정에서 시간 부족으로 인해 Attention에 대해 배우지 못했다. 또한, Attention 이후 transformer까지 배워보는 시간을 가져야 할 것 같아 보충 TIL을 작성하게 되었다.
딥 러닝을 이용한 자연어 처리 입문 교재를 참고하였다.
💡 내적은 두 행렬간의 유사도를 구하기 위해 사용할 수 있다!
[1 1 1] · [1 1 1] = 3
[1 1 1] · [1 -1 1] = 1
[1 1 1] · [-1 -1 -1] = -3
두 행렬이 유사할 수록 내적은 큰 값을 갖고, 두 행렬이 다를 수록 작은 값을 갖는다.
# 1. 세션 클리어
tf.keras.backend.clear_session()
# 2. 레이어 연결
# Encoder
enc_I = Input(shape=(kor_pad.shape[1],))
# Input을 이미 선언하여 shape를 지정해 주었으므로 input_length를 넣어줄 필요가 없음
enc_E = Embedding(kor_vocab_size, 128)(enc_I)
enc_S_full, enc_S = GRU(512, return_sequences=True, return_state=True)(enc_E)
# Decoder
# eos를 제외한 Input이 들어어오므로 -1
dec_I = Input(shape=(eng_pad.shape[1]-1, ))
dec_E = Embedding(eng_vocab_size, 128)(dec_I)
# 인코더의 마지막 시점 히든스테이트를 Input으로 받음
dec_H = GRU(512, return_sequences=True)(dec_E, initial_state=enc_S)
# Attention
key = enc_S_full # 인코더의 모든 히든스테이트
value = enc_S_full # 인코더의 모든 히든스테이트
query = dec_H # 디코더 각 시점의 히든스테이트
# 1. 어텐션 스코어(Attention Score) 구하기
score = tf.matmul(query, key, transpose_b=True)
# 2. 소프트맥스(softmax) 함수를 통해 어텐션 분포(Attention Distribution)를 구하기
# 마지막 축으로 소프트맥스 연산
att_dist = tf.nn.softmax(score, axis = -1)
# 3. 각 인코더의 어텐션 가중치와 은닉 상태를 가중합하여 어텐션 값(Attention Value)구하기
att_value = tf.matmul(att_dist, value)
# 4. 어텐션 값과 디코더의 t 시점의 은닉 상태를 연결(Concatenate)
dec_H = Concatenate()([dec_H, att_value])
# Fuclly Connected Layer
dec_H = Dense(512, activation='tanh')(dec_H)
# 아웃풋 레이어
dec_O = Dense(eng_vocab_size, activation='softmax')(dec_H)
model = tf.keras.models.Model([enc_I, dec_I], dec_O)
# 컴파일
model.compile(loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'],
optimizer='adam')
model.summary()
Model: "model"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 95)] 0 []
input_2 (InputLayer) [(None, 103)] 0 []
embedding (Embedding) (None, 95, 128) 1003776 ['input_1[0][0]']
embedding_1 (Embedding) (None, 103, 128) 394112 ['input_2[0][0]']
gru (GRU) [(None, 95, 512), 986112 ['embedding[0][0]']
(None, 512)]
gru_1 (GRU) (None, 103, 512) 986112 ['embedding_1[0][0]',
'gru[0][1]']
tf.linalg.matmul (TFOpLambda) (None, 103, 95) 0 ['gru_1[0][0]',
'gru[0][0]']
tf.nn.softmax (TFOpLambda) (None, 103, 95) 0 ['tf.linalg.matmul[0][0]']
tf.linalg.matmul_1 (TFOpLambda (None, 103, 512) 0 ['tf.nn.softmax[0][0]',
) 'gru[0][0]']
concatenate (Concatenate) (None, 103, 1024) 0 ['gru_1[0][0]',
'tf.linalg.matmul_1[0][0]']
dense (Dense) (None, 103, 512) 524800 ['concatenate[0][0]']
dense_1 (Dense) (None, 103, 3079) 1579527 ['dense[0][0]']
==================================================================================================
Total params: 5,474,439
Trainable params: 5,474,439
Non-trainable params: 0
__________________________________________________________________________________________________
att_value = tf.keras.layers.Attention()([query, key])