Attention 직관

NLP 글 목록

한빛미디어의 <밑바닥부터 시작하는 딥러닝 2>를 요약 정리한 글이다.

Attention은 Decoder가 현재 시점의 출력을 만들 때, Encoder의 전체 hidden states 중 어떤 정보를 얼마나 참고할지 학습하는 구조이다.

원래 seq2seq에서는 Encoder의 마지막 hidden state 하나만 Decoder로 전달했다.

Attention은 이 구조를 확장해서 Decoder가 매 시점마다 Encoder의 전체 hidden states를 다시 조회할 수 있게 한다.

직관적인 흐름은 다음과 같다.

1. 잠정 벡터를 Decoder의 현재 상태 후보로 설정한다.
2. Decoder가 현재 시점의 출력을 만들기 위해 잠정 벡터와 Encoder 전체 hs 사이의 score를 계산한다.
3. score를 softmax로 정규화해 attention weight를 만든다.
4. attention weight와 Encoder 전체 hs의 가중합으로 context vector c를 만든다.
5. 잠정 벡터와 c를 함께 고려해 최종 현재 상태 h_t를 결정한다.

여기서 score를 계산한다는 것은, 현재 시점에서 입력 문장의 어떤 단어를 가장 많이 참고해야 할지 판단한다는 뜻이다.

즉 다음 단어를 생성할 때 입력의 어떤 부분이 가장 관련 있는지 유사도로 확인하는 것이다.

이 유사도를 결정하는 가중치들은 Decoder 학습 과정에서 조정된다.

1. 잠정 벡터 설정

Decoder의 잠정 상태 h~t\tilde{h}_t는 현재 시점에서 다음 단어를 만들기 전의 상태 후보라고 볼 수 있다.

이 잠정 상태는 보통 이전 hidden state와 이전 단어 임베딩을 기반으로 계산된다.

시점 t=1t=1에서는 Encoder의 최종 hidden state hs[-1]로 초기화될 수 있다.

직관적으로 말하면 잠정 상태는 다음 질문에 가깝다.

내가 지금 다음 단어를 만들 준비가 어느 정도 되어 있는가?

아직 입력 문장의 어떤 부분을 참고할지는 확정되지 않았다.

따라서 h~t\tilde{h}_t는 “현재 Decoder의 입장”을 나타내는 기준 벡터로 생각할 수 있다.

2. Score 계산과 문맥 벡터

잠정 상태 h~t\tilde{h}_t가 만들어지면, 이 벡터를 Encoder의 전체 hidden states와 비교한다.

Encoder의 전체 hidden states를 다음과 같이 두자.

hs=[h1,h2,,hT]hs = [h_1, h_2, \dots, h_T]

여기서 TT는 입력 시퀀스의 길이이다.

각 Encoder hidden state hih_i는 입력 시점 ii의 정보를 담고 있다.

Attention은 잠정 상태 h~t\tilde{h}_t와 각 hih_i 사이의 score et,ie_{t,i}를 계산한다.

dot product 방식에서는 다음과 같이 계산한다.

et,i=h~thie_{t,i} = \tilde{h}_t^\top h_i

additive 방식에서는 다음과 같이 계산할 수 있다.

et,i=vtanh(W1h~t+W2hi)e_{t,i} = v^\top \tanh(W_1 \tilde{h}_t + W_2 h_i)

여기서 W1W_1, W2W_2, vv는 학습되는 파라미터이다.

dot product 방식은 두 벡터의 방향이 얼마나 비슷한지 직접 내적으로 측정한다.

additive 방식은 두 벡터를 학습 가능한 변환에 통과시킨 뒤 유사도를 계산한다.

3. Attention Weight

score et,ie_{t,i}는 정규화되지 않은 값이다.

이 score들을 softmax에 통과시키면 attention weight ata_t를 얻는다.

at,i=exp(et,i)j=1Texp(et,j)a_{t,i} = \frac{\exp(e_{t,i})}{\sum_{j=1}^{T} \exp(e_{t,j})}

attention weight는 다음과 같은 벡터이다.

at=[at,1,at,2,,at,T]a_t = [a_{t,1}, a_{t,2}, \dots, a_{t,T}]

at,ia_{t,i}는 현재 Decoder 시점 tt에서 입력 시점 ii를 얼마나 참고할지 나타내는 값이다.

softmax를 사용하므로 모든 attention weight의 합은 1이 된다.

따라서 ata_t는 입력 문장 위치들에 대한 확률분포처럼 해석할 수 있다.

4. Context Vector

attention weight를 이용하면 context vector ctc_t를 계산할 수 있다.

ct=i=1Tat,ihic_t = \sum_{i=1}^{T} a_{t,i} h_i

context vector는 Encoder hidden states의 가중합이다.

즉 입력 문장의 모든 위치를 사용하되, 현재 시점에 중요한 위치에는 큰 가중치를 주고 덜 중요한 위치에는 작은 가중치를 준다.

직관적으로 ctc_t는 입력 문장의 중요한 정보를 요약한 벡터이다.

현재 Decoder가 다음 단어를 만들기 위해 필요한 입력 문맥이 여기에 담긴다.

5. 잠정 벡터와 문맥 벡터 결합

이제 Decoder는 잠정 상태 h~t\tilde{h}_t와 context vector ctc_t를 함께 사용한다.

결합 방식은 concat 또는 가중합 등으로 구현할 수 있다.

대표적으로 다음처럼 쓸 수 있다.

htfinal=tanh(Wc[h~t;ct])h_t^{\mathrm{final}} = \tanh(W_c [\tilde{h}_t ; c_t])

여기서 [h~t;ct][\tilde{h}_t ; c_t]는 두 벡터를 연결한 벡터이다.

WcW_c는 이 결합 벡터를 최종 hidden state로 변환하는 학습 가능한 가중치이다.

최종 hidden state htfinalh_t^{\mathrm{final}}는 이후 softmax 계층으로 전달되어 다음 단어 예측에 사용된다.

6. Attention 파라미터 학습

score 계산에 쓰이는 attention 파라미터 W1W_1, W2W_2, vv 등은 Decoder 학습 과정에서 최적화된다.

Decoder는 반복 학습을 통해 다음을 배운다.

  • 어떤 입력 단어에 어느 정도 주목해야 다음 단어를 잘 예측할 수 있는지 학습한다.
  • 그 결과 attention weight ata_t가 데이터로부터 결정된다.

즉 attention weight는 사람이 직접 지정하는 값이 아니다.

모델이 손실함수를 줄이는 방향으로 학습하면서 자동으로 만들어지는 값이다.

7. 직관적 흐름 요약

Attention의 흐름은 다음과 같이 정리할 수 있다.

  1. 잠정 상태 h~t\tilde{h}_t를 만든다.
  2. h~t\tilde{h}_t와 Encoder 전체 hidden states를 비교해 score를 계산한다.
  3. score를 softmax에 통과시켜 attention weight ata_t를 만든다.
  4. attention weight와 Encoder hidden states의 가중합으로 context vector ctc_t를 만든다.
  5. h~t\tilde{h}_tctc_t를 결합해 최종 hidden state를 만든다.
  6. 최종 hidden state를 이용해 다음 단어를 예측한다.

더 짧게 쓰면 다음과 같다.

잠정 상태
→ score 계산
→ softmax
→ attention weight
→ context vector
→ 최종 hidden state
→ softmax
→ 다음 단어 예측

Attention의 핵심은 Decoder가 매 시점마다 입력 문장 전체를 다시 바라본다는 점이다.

그리고 그중 지금 필요한 부분에 더 큰 가중치를 주어 context vector를 만든다는 점이다.