[INTRO]
NIPS에서 Google이 소개했던 Transformer는 NLP 학계에서 정말 큰 주목을 받음
CNN 과 RNN 이 주를 이뤘던 연구들에서 벗어나 아예 새로운 모델을 제안했기 때문
[핵심]
multi-head self-attention을 이용해 sequential computation 을 줄여 더 많은 부분을 병렬처리가 가능하게 만들면서 동시에 더 많은 단어들 간 dependency를 모델링 한다는 것
[읽기 위해 필요한 지식]
attention
[원 논문]
Attention is All You Need
[코드 구현, 설명]
transfomer 코드 하나하나 파헤치기: 이 포스트를 다 읽고 보자
👀, 🤷♀️ , 📜
이 아이콘들을 누르시면 코드, 개념 부가 설명을 보실 수 있습니다:)
목차
도입 배경, 이유
[intro_RNN의 단점]
어텐션을 갖춘 seq2seq의 구성에는 반드시 RNN이 등장했음.
RNN은 병렬 처리 불가
[RNN]
이전 시각에 계산한 결과를 이용하여 순서대로 계산
따라서 RNN의 계산을 시간 방향으로 병렬 계산하기란 (기본적으로는) 불가능
- 딥러닝 학습이 GPU를 사용한 병렬 계산 환경에서 이뤄진다는 점을 생각하면 큰 단점임
- 현재 RNN을 없애는 연구(혹은 병렬 계산할 수 있는 RNN 연구) 활발.
- 그 중 유명한 것이 「Attention is all you need」라는 논문 에서 제안한 기법인 트랜스포머 Transformer 모델
📜 RNN Seq2Seq 모델/네트워크 대비 Transformer의 이점 보기
1️⃣ Transformer는 반복을 Attention으로 대체하고 입력 시퀀스 내에서 각 기호의 위치를 인코딩하여 병렬화를 실현합니다. 따라서 트레이닝 시간이 단축됩니다.
2️⃣ Transformer는 입력/출력 시퀀스의 두 기호를 상수 O(1) 연산 수에 연결하여 순차 연산의 수를 줄입니다. Transformer는 입력 또는 출력 문장에서의 거리에 관계없이 종속성을 모델링할 수 있게 해 주는 Attention 메커니즘을 사용하여 이를 실현합니다.
지금은 이해가 안돼도 괜찮다 아래의 포스트를 모두 보고 와서 다시 이해해보자.
📜 Attention 요약
Transformer 모델의 핵심은 “Attention” 메커니즘입니다.
쉽게 설명해 딥러닝의 Attention은 인간이 시각적인 장면을 볼 수 있는 방식을 모방한 것이라고 볼 수 있습니다. 우리는 일반적으로 시야에 들어오는 모든 것을 살피지 않으며 그보다는 장면의 맥락에 따라 중요한 특징에 집중합니다. 마찬가지로, 언어에서도 다시 맥락에 따라 다른 단어에 적용될 때 특정한 중요 단어에 더 집중합니다.
Attention 메커니즘은 입력 시퀀스를 살펴보고 각 단계에서 시퀀스의 어떤 부분이 중요한지 결정합니다. 딥러닝의 Attention은 중요도 가중치의 벡터로 해석될 수 있습니다. 아래 예에서 “ball”은 “tennis”와 “playing” 모두에서 강한 Attention이 있지만 “tennis”와 “dog”은 연관성이 약합니다.
Transformer 모델 개요
Google Cloud는 이제 그들의 Cloud TPU를 쓸 때 Transfomer 모델을 기준으로 쓸 것을 추천.
이 모델은 ‘RNN이 아닌’ 어텐션을 사용해 처리
트랜스포머는 어텐션으로 구성,
- 그중 셀프어텐션 Self-Attention 이라는 기술을 이용
[모델의 전체 개요]
기계 번역의 경우를 생각해본다면, 모델은 어떤 한 언어로 된 하나의 문장을 입력으로 받아 다른 언어로 된 번역을 출력으로 내놓음
[encoding 과 decoding 확대]
- encoding: encoder 을 쌓아 올려 만든 것
- decoding: encoding 부분과 동일한 개수만큼의 decoder 을 쌓은 것
encoder 들은 모두 정확히 똑같은 구조를 가지고 있음 (그러나 그들 간에 같은 weight을 공유하진 않습니다)
[encoder 확대]
인코더에 들어온 입력은,
1) self-attention
을 지남추후설명
- encoder가 하나의 특정한 단어를 encode 하기 위해서 입력 내의 모든 다른 단어들과의 관계를 살펴봄
2) 위의 출력은 feed-forward
신경망으로 들어감.
- 똑같은 feed-forward 신경망이 각 위치의 단어마다 독립적으로 적용돼 출력을 만듦
[decoder확대]
encoder에 있는 두 layer 모두를 가지고 있음
+)
1.5) encoder-decoder attention
추가 : 그 두 층 사이에 seq2seq 모델의attention 과 비슷한 이것이 끼워져있음
- decoder가 입력 문장 중에서 각 타임 스텝에서 가장 관련 있는 부분에 집중할 수 있도록 해줌
encoder
입력으로 들어와서 출력이 될 때까지,
이 부분들 사이를 지나가며 변환될 벡터/텐서들을 기준으로 모델 분석.
[1단계]
입력 단어들을 embedding 알고리즘를 이용해 벡터로 바꿈(링크 삽입)
- 각 단어들은 크기 512의 벡터 하나로 embed
- 이 벡터 리스트의 사이즈는 hyperparameter으로 우리가 마음대로 정할 수 있음
- 주로 가장 긴 문장의 길이
- 변환된 벡터들 박스로 표현
이 embedding은 가장 밑단의 encoder 에서만 일어남
모든 encoder 들은 크기 512의 벡터의 리스트를 입력으로 받음
이 벡터는,
- 가장 밑단의 encoder의 경우: word embedding이 된 것
- 다른 encoder들: 바로 전의 encoder의 출력
[2단계]
입력 문장의 단어들을 embedding 한 후에,
각 단어에 해당하는 벡터들은 encoder 내의 두 개의 sub-layer( Self-attention
, feed-forward
)으로 들어가게 됨
[Transformer 모델의 주요 성질 파악 가능]
각 위치에 있는 각 단어가 각각의 path를 통해 encoder에서 흘러감
Self-attention
층: 이 위치에 따른 path들 사이에 다 dependency 존재(단어간의 관계 봄)feed-forward
층: 이런dependency가 없음- feed-forward layer 내의 이 다양한 path 들은 병렬처리 가능
위의 각 layer에서 무슨 일이 일어나는지를 자세히 보자
단계 구체화
1) encoder는 입력으로 벡터들의 리스트를 받음
2) 이 리스트를 먼저 self-attention layer에 통과시킴
3) 그다음으로 feed-forward 신경망에 통과시킴
4) 그 결과물을 그다음 encoder에게 전달
각 위치의 단어들은 각각 다른 self-encoding 과정을 거침
그다음으로는 모두에게 같은 과정인 feed-forward 신경망을 거침
sub-layer1: Self-Attention
하나의 시계열 데이터를 대상으로 한 어텐션으로,
하나의 시계열 데이터 내에서 각 원소가 다른 원소들과 어떻게 관련되는지를 살펴보자는 취지(다른 단어와의 관계를 본다는게 핵심이다 기억하자)
⛔ [PROBLEM]
다음 문장을 우리가 번역하고 싶은 문장:
“그 동물은 길을 건너지 않았다 왜냐하면 그것은 너무 피곤했기 때문이다”
이 문장에서 “그것” 이 가리키는 것?
- 길
- 동물
사람에게는 이것이 너무나도 간단한 질문이지만 신경망 모델에게는 그렇게 간단하지만은 않은 문제임.
⭕ [SOLUTION]
모델이 “그것은”이라는 단어를 처리할 때, 모델은 self-attention
을 이용하여 “그것”과 “동물”을 연결 가능
self-attention
: 현재 처리 중인 단어에 다른 연관 있는 단어들의 맥락을 불어 넣어주는 method
모델이 입력 문장 내의 각 단어를 처리해 나감에 따라,
self-attention은 입력 문장 내의 다른 위치에 있는 단어들을 보고 거기서 힌트를 받아 현재 타겟 위치의 단어를 더 잘 encoding 할 수 있음
(SOLVE)
가장 윗단에 있는 encoder에서 “그것”이라는 단어를 encoding 할 때,
- attention 메커니즘은 입력의 여러 단어들 중에서 “그 동물”이라는 단어에 집중
- 이 단어(“그 동물”)의 의미 중 일부를 “그것”이라는 단어를 encoding 할 때 이용
self-attention 원리
그럼 이 self-attention을 이해하기 쉽게 먼저 벡터로 쪼개서 설명하겠다.
📜 벡터 계산으로 먼저 이해하기
여러 가지 벡터들을 통해서 어떻게 self-attention 을 계산할 수 있을까?
- 행렬을 이용해서 이것이 실제로 어떻게 구현되어 있는지 확인해보자
실제로는 벡터단위로 계산을 안하고 행렬 단위로 계산을 하지만 이해를 위해 백터계산을 설명한 후 행렬 계산을 보여주겠다.
그럼 계산을 쉽게 보여주기위해,
고양이는 너무 귀엽다 ➡ 고양이는 귀엽다
로 예문을 바꾸겠다
[1단계]
encoder에 입력된 벡터들(각 단어의 embedding 벡터입니다)에서 부터 각 3개의 벡터를 만들어냄
우리는 각 단어에 대해서
- Query 벡터
- Key 벡터
- Value 벡터를 생성.
이 벡터들은 입력 벡터에 대해서 세 개의 학습 가능한 행렬들을 각각 곱함으로써 만들어 짐
주의)
기존의 벡터 사이즈 < 이 새로운 벡터 사이즈
multi-head attention의 계산 복잡도를 일정하게 만들고자 내린 구조적인 선택
[2 단계]
점수를 계산
아래 예시의 첫 번째 단어인 고양이는
에 대해서 self-attention 을 계산한다고 하면,
우리는 이 단어와 입력 문장 속의 다른 모든 단어들에 대해서 각각 점수를 계산해야 함
- 점수: 현재 위치의 이 단어를 encode 할 때 다른 단어들에 대해서 얼마나 집중을 해야 할지를 결정
- 점수 계산: 현재 단어의
query vector
와 점수를 매기려 하는 다른 위치에 있는 단어의key vector
의 내적(얼마나 관련도가 높니?) - 다시 말해, 우리가 위치에 있는 단어에 대해서 self-attention 을 계산한다 했을 때,
- 첫 번째 점수는 q1과 k1의 내적.
- 두 번째 점수는 q1과 k2의 내적.
- 점수 계산: 현재 단어의
[3 단계]
1) \((이 점수들)/{√key 벡터의 사이즈(key 벡터의 사이즈의 제곱근)}\) = 더 안정적인 gradient
2) 이 값(더 안정적인 gradient)을 softmax
계산을 통과시켜 모든 점수들을 양수로 만들고 그 합을 1으로 만들어 줌
- softmax 점수: 현재 위치의 단어의 encoding에 있어서 얼마나 각 단어들의 표현이 들어갈 것인지를 결정함
- 당연하게 현재 위치의 단어가 가장 높은 점수, 가장 많은 부분차지
- 가끔은 현재 단어에 관련이 있는 다른 단어에 대한 정보가 들어가는 것이 도움이 됨
[4단계]
\((입력의 각 단어들의 value 벡터)* (softmax 점수)\)
- 우리가 집중을 하고 싶은 관련이 있는 단어들은 그래도 남겨두고,
- 관련이 없는 단어들은 0.001 과 같은 작은 숫자 (점수)를 곱해 없애버리기 위함.
[5 단계]
이 점수로 곱해진 weighted value 벡터들을 다 더함.
이 단계의 출력이 바로 현재 위치에 대한 self-attention layer의 출력
- 이 결과로 나온 벡터를
feed-forward
신경망으로 보냄
물론 이 결과인 z는 feed-foeward계층으로 넘길 수 있다.
하지만 이렇게 하나하나 처리를하면 오래걸리므로 벡터가 아닌 행열로 처리하는 것이 대부분이다(아래에서 백터로 계산하는 법을 보자)
📜 행렬계산으로 변환 자세히 보기
실제 구현에서는 빠른 속도를 위해 이 모든 과정들이 위의 방법과 같이 벡터가 아닌 행렬의 형태로 진행한다
그럼 위의 처리를 묶어서 하는 행렬 계산을 보자
[1단계]
입력 문장에 대해서 Query, Key, Value 행렬들을 계산
- 이를 위해 입력 벡터들(embedding 벡터들)을 하나의 행렬 X로 쌓아 올리고,
- 그것을 우리가 학습할 weight 행렬들인 WQ, WK, WV 로 곱함.
행렬 X의 각 행: 입력 문장의 각 단어에 해당
- 여기서 다시 한번 embedding 벡터들(크기4)와 query/key/value 벡터들(크기 3) 간의 크기 차이확인 가능
[2단계]
현재 행렬을 이용하고 있으므로 앞의 self-attention 계산 단계 2~5 단계
를 하나의 식으로 압축 가능
📜 multi-headed attention 자세히 보기
위의 self-attention layer
에 “multi-headed” attention
이라는 메커니즘을 더해 더욱더 이를 개선했다
이것은 두 가지 방법으로 attention layer의 성능을 향상시킨다
The Beast With Many Heads / “multi-headed” attention: 여러개의 encoder
- 1️⃣ 성능 향상 방법 1
- 모델이 다른 위치에 집중하는 능력을 확장시킴
z1 이 모든 다른 단어들의 encoding 을 조금씩 포함했지만,
사실 이것은 실제 자기 자신에게만 높은 점수를 줘 자신만을 포함해도 됐을 것임- 이것은 “그 동물은 길을 건너지 않았다 왜냐하면 그것은 너무 피곤했기 때문이다” 과 같은 문장을 번역할 때,
- “그것”이 무엇을 가리키는지에 대해 알아낼 때 유용
- 2️⃣ 성능 향상 방법 2
attention layer
가 여러 개의 “representation 공간”을 가지게 해줌
multi-headed attention을 이용함으로써 우리는 여러 개의 query/key/value weight 행렬들을 가지게 됨- 밑의 그림은 5개의 attention heads을 가지므로 각 encoder/decoder마다 이런 5개의 세트를 가지게 되는 것
- 이 각각의 query/key/value set는 랜덤으로 초기화되어 학습됨
- 학습이 된 후 각각의 세트: 입력 벡터들에 곱해져 벡터들을 각 목적에 맞게 투영시키게 됨
- 이러한 세트가 여러개 있다는 것은 각 벡터들을 각각 다른 representation 공간으로 나타낸 다는 것을 의미
1) 각 head에 대한 Q/K/V 행렬 생성
multi-headed attention
을 이용하기 위해서,
- 각 head를 위해서 각각의 다른 query/key/value weight 행렬들을 모델에 가짐.
- 이전에 설명한 것과 같이 우리는 입력 벡터들의 모음인 행렬 X를 WQ/WK/WV 행렬들로 곱해 각 head에 대한 Q/K/V 행렬들을 생성
즉, 같은 문장에 가중치들을 한번씩만 주는게 아닌 여러개를 줘서 이를 다 더한다는 것.
2) 서로 다른 Z 행렬
self-attention
계산 과정을 5개의 다른 weight 행렬들에 대해 5번 거치게 되면, 우리는 5개의 서로 다른 Z 행렬을 가지게 됨
- 위의 그림에서 encoder이 5개 이므로 그 결과인 z도 5개
(problem)
이 5개의 행렬을 바로 feed-forward layer
으로 보낼 수 없음
feed-forward layer
은 한 위치에 대해 오직 한 개의 행렬만을 input으로 받을 수 있음.- 그러므로 우리는 이 5개의 행렬을 하나의 행렬로 합치는 방법 필요
(solve)
1) 모두 이어 붙여서 하나의 행렬로 만들어버리고,
2) 그 다음 하나의 또 다른 weight 행렬인 W0을 곱함
총 정리
📜 예제 적용 자세히 보기
“그것” 이란 단어를 encode 할 때 여러 개의 attention 이 각각 어디에 집중하는지 확인
- 주황색 attention head: “그 동물”에 가장 집중
- 초록색 attention head: “피곤”이라는 단어에 집중
모델: 이 두 개의 attention head를 이용하여 “동물”과 “피곤” 두 단어 모두에 대한 representation 을 “그것”의 representation에 포함시킬 수 있음
sub-layer2: feed-forward
대표적인 feed-forward가 word2vec
흐름이 단방향인 신경망이다.
RNN이전에 사용했던 것으로 RNN이후엔 잘 쓰지 않았지만 RNN을 사용하지 않는 transformer에선 이 피드포워드를 쓴다
더 알아보러 가기
Positional Encoding
Positional Encoding 을 이용해 시퀀스의 순서 나타내기
[problem]
우리가 이때까지 설명해온 Transformer 모델의 문제는,
이 모델이 입력 문장에서 단어들의 순서에 대해서 고려하고 있지 않는 것이다.
[solve]
각각의 입력 embedding에 positional encoding이라고 불리는 하나의 벡터를 추가.
- 이 벡터들은 모델이 학습하는 특정한 패턴을 따름
- 패턴: 모델이 각 단어의 위치와 시퀀스 내의 다른 단어 간의 위치 차이에 대한 정보를 알 수 있게 해줌
- 이 값들을 단어들의 embedding에 추가하는 것이 query/key/value 벡터들로 나중에 투영되었을 때 단어들 간의 거리를 늘릴 수 있음
[의문점]
위치를 알려주는 벡터를 010101(sin,cos) 이렇게 넣어주고 이를 embeding과 더해준다(embeding이 그럼 손상되지 않을까?➡ 그럴 수 있다! 그런데 명확한 설명이 없어 이에 대한 많은 연구가 논의중이다 ex BERT같은 경우는 이 부분을 학습 가능하게 하였다.)
위치 별로 특정한 패턴을 따르는 positional encoding 벡터들을 추가
➡ 모델에게 단어의 순서에 대한 정보를 주기 위해
The Residuals
- error(오차): 모집단에서 회귀식을 얻었다면, 그 회귀식을 통해 얻은 예측값과 실제 관측값의 차이
- Residual(잔차): 표본집단에서 회귀식을 얻었다면, 그 회귀식을 통해 얻은 예측값과 실제 관측값의 차이
각 encoder 내의 sub-layer 가 residual connection으로 연결되어 있으며,
그 후에는 layer-normalization 과정을 거침
이 add & nomerlize
계층은 입력값과 attention 후 변환값을 합쳐주는 역할을 한다
전체 코드
Decoder
Encoding before Decoding
1) encoder가 먼저 입력 시퀀스를 처리하기 시작.
2) 그다음 가장 윗단의 encoder의 출력은 attention 벡터들인 K와 V로 변형됨.
3) 이 벡터들은 이제 각 decoder의 “encoder-decoder attention” layer에서 decoder 가 입력 시퀀스에서 적절한 장소에 집중할 수 있도록 도와줌
Decoding
위의 encoding 단계가 끝나면 이제 decoding 단계가 시작됨
decoding 단계의 각 스텝은 출력 시퀀스의 한 element를 출력합니다 (현재 기계 번역의 경우에는 영어 번역 단어).
- 출력을 완료했다는 special 기호인 ‘
'를 출력할 때까지 반복 - 각 스텝마다의 출력된 단어는,
- 1) 다음 스텝의 가장 밑단의 decoder에 들어가고
- 2) encoder와 마찬가지로 여러 개의 decoder를 거쳐 올라감.
- 3) encoder의 입력에 했던 것과 동일하게 embed를 한 후
- 4) positional encoding을 추가하여 decoder에게 각 단어의 위치 정보를 더해줌
sub-layer1: Masked self-attention layer
encoder와는 조금 다르게 작동
Masked: 현재 해석하는 단어의 뒤의 단어는 안보기 때문에(마스킹 해버린다)
output sequence 내에서 현재 위치의 이전 위치들에 대해서만 attend 할 수 있음
[구현]
self-attention 계산 과정에서 softmax를 취하기 전에,
현재 스텝 이후의 위치들에 대해서 masking (즉 그에 대해서 \(-inf\)로 치환하는 것)을 해줌으로써 가능해짐
📜 encoder: self-attention VS decoder: Masked self-attention
즉 ‘키가 매우 큰 남자가 엄청나게 맛있는 케이크를 먹는다’라는 예문에서 ‘남자’에 대해여 어텐션 처리를 할 때,
- encoder: ‘키가 매우 큰 남자가 엄청나게 맛있는 케이크를 먹는다’ 라는 모든 단어를 고려한다.
- decoder: ‘키가 매우 큰 남자’라는 남자와 남자 앞의 벡터만 고려한다
sub-layer2: Encoder-Decoder Attention layer
multi-head self-attention 과 한 가지를 제외하고는 똑같은 방법으로 작동,
[한가지 차이점]
- Query 행렬들: 그 밑의 layer에서 가져옴
- Key 와 Value 행렬들: encoder의 출력에서 가져온다 는 점
즉, 인코더의 정보 중 어느 단어에 attend 할 지를 정하는 것이다.
After layer
여러 개의 decoder를 거치고 난 후에는 소수로 이루어진 벡터 하나가 남음.
이 하나의 벡터를 단어로 바꾸는 역할을 함
Linear layer
fully-connected 신경망
decoder가 마지막으로 출력한 벡터를 그보다 훨씬 더 큰 사이즈의 벡터인 \(logits 벡터\)로 투영시킴
[ex] 모델의 “output vocabulary”
- training 데이터에서 총 10,000개의 영어 단어를 학습하였다고 가정
- 그렇다면 이 경우에 logits vector의 크기는 10,000이 될 것
- 벡터의 각 셀은 그에 대응하는 각 단어에 대한 점수.
- 이렇게 되면 우리는 Linear layer의 결과로서 나오는 출력에 대해서 해석 가능
softmax layer
이 점수들을 확률로 변환해주는 역할
셀들의 변환된 확률 값들은 모두 양수 값을 가지며 다 더하게 되면 1
가장 높은 확률 값을 가지는 셀에 해당하는 단어가 해당 스텝의 최종 결과물로서 출력
decoder에서 나온 출력은 Linear layer 와 softmax layer를 통과하여 최종 출력 단어로 변환됨
학습과정 review
학습 과정 동안, 학습이 되지 않은 모델은 정확히 같은 forward pass 과정을 거침.
그러나 우리는 이것을 label된 학습 데이터 셋에 대해 학습시키는 중이므로,
우리는 모델의 결과를 실제 label 된 정답과 비교가능
output vocabulary 생성
output vocabulary 가 6개의 단어만 ((“look”, “am”, “i”, “hi”, “cat”, and “<eos>” (‘end of sentence’의 줄임말)))
포함하고 있다고 가정
- 모델의 output vocabulary는 학습 시작 전인 preprocessing 단계에서 완성됨
one-hot encoding
output vocabulary를 정의한 후에는, one-hot encoding으로 표현 가능
one-hot encoding
: 이 vocabulary의 크기만 한 벡터를 이용하여 각 단어를 표현 가능
ex) 단어 “am” 을 다음과 같은 벡터로 나타낼 수 있음
Loss Function
이것은 학습 과정에서 최적화함으로써 인해 모델을 정확하게 학습시킬 수 있게 해주는 값
ex)
모델을 학습하는 상황에서 가장 첫 번째 단계라고 가정
학습을 위해 “안녕”이라는 한국어를 “hi”로 번역하는 간단한 예시를 생각하면,
- 우리가 원하는 모델의 출력: “hi”라는 단어를 가리키는 확률 벡터
- 하지만, 우리의 모델은 아직 학습이 되지 않았기 때문에, 아직 모델의 출력이 그렇게 나올 확률은 매우 작음
[1단계]
학습이 시작될 때 모델 임의의 값 출력
- 이 모델의 parameter(weight): 들은 랜덤으로 값을 부여하기 때문에, 그저 각 cell (word)에 대해서 임의의 값을 출력
[2단계]
이 출력된 임의의 값을 가지는 벡터와 데이터 내의 실제 출력값을 비교하여,
그 차이와 backpropagation 알고리즘을 이용해 현재 모델의 weight들을 조절해 원하는 출력값에 더 가까운 출력이 나오도록 만듦
두 확률 벡터를 어떻게 비교 방법
\((하나의 벡터)-(다른 하나의 벡터)\)
자세한 정보) cross-entropy 와 Kullback–Leibler divergence
[주의 점]
우리가 고려하고 있는 예제가 지나치게 단순화된 경우임
조금 더 현실적인 예제에서는 한 단어보다는 긴 문장을 이용할 것임
ex)
입력 한국어 문장 “나는 고양이다”의 바라는 출력은 “i am cat”
즉, 우리가 바라는 모델이 출력할 확률 분포는
- 각 단어에 대한 확률 분포는 output vocabulary 크기를 가지는 벡터로 나타냄(우리의 간단한 예제에서는 6이지만 실제 실험에서는 3,000 혹은 10,000과 같은 숫자일 것)
- decoder가 첫 번째로 출력하는 확률 분포
- “i”라는 단어와 연관이 있는 cell에 가장 높은 확률을 줘야 함
- 두 번째로 출력하는 확률 분포
- “am”라는 단어와 연관이 있는 cell에 가장 높은 확률을 줘야 함
- 이와 동일하게 마지막 ‘
‘를 나타내는 다섯 번째 출력까지 이 과정은 반복 (‘ ’ 또한 그에 해당하는 cell을 벡터에서 가짐). (이상적인 output) ![image](https://user-images.githubusercontent.com/76824611/117944220-fdf9f980-b347-11eb-8da3-4496a6d380a4.png)
(큰 모델 실현 시 나오는 실제 output_결과 좋은 편)