워드 임베딩은 벡터, 실제 문장은 행렬
Attention 적용 절치
Input 1: [1, 0, 1, 0]
Input 2: [0, 2, 0, 2]
Input 3: [1, 1, 1, 1]
w_key = [
[0, 0, 1],
[1, 1, 0],
[0, 1, 0],
[1, 1, 0]
]
w_query = [
[1, 0, 1],
[1, 0, 0],
[0, 0, 1],
[0, 1, 1]
]
w_value = [
[0, 2, 0],
[0, 3, 0],
[1, 0, 3],
[1, 1, 0]
]
w_key = torch.tensor(w_key, dtype=torch.float32)
w_query = torch.tensor(w_query, dtype=torch.float32)
w_value = torch.tensor(w_value, dtype=torch.float32)
각 문장의 쿼리, 키 , value는 행렬곱을 통해 한번에 구할 수 있다.
keys = x @ w_key
querys = x @ w_query
values = x @ w_value
print(keys)
# tensor([[0., 1., 1.],
# [4., 4., 0.],
# [2., 3., 1.]])
print(querys)
# tensor([[1., 0., 2.],
# [2., 2., 2.],
# [2., 1., 3.]])
print(values)
# tensor([[1., 2., 3.],
# [2., 8., 0.],
# [2., 6., 3.]])
기본적으로 현재의 단어가 Query이고 어떤 단어와 다른 단어의 상관을 구할 때 Query를 Key에 곱해준다
이를 Attenstion Score라고 한다
Attention Score 는 한 Sequence(문장) 내에서 특정 단어와 나머지 모든 단어와의 관련성의 정도를 나타낸다.
attn_scores = querys @ keys.T
# tensor([[ 2., 4., 4.], # attention scores from Query 1
# [ 4., 16., 12.], # attention scores from Query 2
# [ 4., 12., 10.]]) # attention scores from Query 3
attenstion score에 다음와 같은 방식으로 softmax를 적용해 준다. -> 확률값 산출
softmax(Score/sqrt(dimention of key))
이는 키벡터의 차원이 늘어날 수록 dot product 계산시 값이 증대되는 문제를 보완하기 위해 score를 sqrt(dimention of key) 로 나눠줌
from torch.nn.functional import softmax
attn_scores_softmax = softmax(attn_scores, dim=-1)
# tensor([[6.3379e-02, 4.6831e-01, 4.6831e-01],
# [6.0337e-06, 9.8201e-01, 1.7986e-02],
# [2.9539e-04, 8.8054e-01, 1.1917e-01]])
# For readability, approximate the above as follows
attn_scores_softmax = [
[0.0, 0.5, 0.5],
[0.0, 1.0, 0.0],
[0.0, 0.9, 0.1]
]
attn_scores_softmax = torch.tensor(attn_scores_softmax)
weighted_values = values[:,None] * attn_scores_softmax.T[:,:,None]
# tensor([[[0.0000, 0.0000, 0.0000],
# [0.0000, 0.0000, 0.0000],
# [0.0000, 0.0000, 0.0000]],
#
# [[1.0000, 4.0000, 0.0000],
# [2.0000, 8.0000, 0.0000],
# [1.8000, 7.2000, 0.0000]],
#
# [[1.0000, 3.0000, 1.5000],
# [0.0000, 0.0000, 0.0000],
# [0.2000, 0.6000, 0.3000]]])
7 . Weighted Value 합산
밸류(v) 각 단어의 벡터를 곱해준 후 모두 더한다
outputs = weighted_values.sum(dim=0)
# tensor([[2.0000, 7.0000, 1.5000], # Output 1
# [2.0000, 8.0000, 0.0000], # Output 2
# [2.0000, 7.8000, 0.3000]]) # Output 3
모든 self attention 연산은 행렬곱으로 한번에 처리할 수 있다
transformer는 1에서 7까지의 연산을 수행하는 encoder layer를 6개 붙인 형태이다
encoder layer 입력벡터와 출력벡터의 크기는 동일하다
self attention 구조
+ Dimention
+ Bias
self attetion layer에 들어갈 수 잇는 input
+ Embedding module
+ Positional encoding
+ Truncating
+ Masking
다른 self attention modul
+ Multihead attention
+ Layer stacking
: 병렬처리되는 attention을 Multi Head Attention이라고 한다.
구체적으로는 attention layer가 여러개의 representation space를 가지게 해주는 것.
여러개의 attention layer를 병렬처리해서 얻는 이점은 문장에서 단어의 의미가 모호해서 한개의 attention으로 모호한 단어의 정보를 충분히
encoding하기 가 어려운데 multi head attenion을 사용해서 다른 관점에 단어정보를 수집해서 이를 보완할 수 있다. ->
multi head attention의 결과값은 모두 이어 붙여저서 또 다른 행렬과 곱해져 최초 워드임베딩과 동일한
크기를 갖는 벡터로 나온다.
multi head attentionn layer에서 나온 최초의 워드임베딩과 동일한 크기를 가지는 벡터로 나온다.
: 위치정보를 포함하고 있는 임베딩
목적: 원래문장 - 번역 문장 관계 파악
a. query : 디코더
b. Key, value : 인코더
c. 인코더 블록의 단어 정보와 디코더 블록의 단어 정보를 연결