0. 문장임베딩이란?
기존의 Word2Vec, Glove, FastText 등은 모두 단어 수준의 임베딩 모델이었다.
이러한 단어 수준의 임베딩 기법은 단어의 형태만 보고 동일한 단어로 판단하여, 자연어의 특성인 모호성(중의성 등)을 구분하기 어렵다는 한계가 있었다.
이에 문장수준의 언어 모델링 기법들이 등장하기 시작하였다.
언어 모델이란, 자연어 문장 혹은 단어에 확률을 할당하여 컴퓨터가 처리할 수 있도록 하는 모델로, 주어진 입력에 대해 가장 자연스러운 단어 시퀀스를 찾도록 해준다.
따라서 언어 모델링은 주어진 단어로부터 아직 모르는 단어들을 예측하는 작업을 뜻한다.
단어 시퀀스에 확률을 할당하게 하기 위하여 주로 사용되는 방법으로는 Masked Language Modeling 혹은 Next Token Prediction이 대표적이다.
1. Seq2Seq
`Seq2Seq` 모델이 등장하기 전 기존의 `LSTM`,'RNN`,`GRU` 같은 `DNN` 모델은 음성인식, 사물인식 등에서 꾸준히 성과를 냈었다. 그러나 모델의 입/출력 크기가 고정된다는 한계점이 존재했기 때문에, 자연어처리에서의 가변적인 길이의 입/출력을 처리하는데 한계가 있었다.
1-1. RNN
`RNN` 모델에 대해 간략하게 설명하자면, `Seq2Seq`모델이 나오기 전 입/출력을 시퀀스 단위로 처리할 수 있는 모델이었다. RNN셀을 재귀적으로 사용하기 때문에 one to many, many to one, many to many와 같은 다양한 형식의 시퀀스에 활용할 수 있었다. 그러나 반복되는 셀의 개수만큼 입/출력을 처리해야 하기 때문에 길이가 서로 달라지는 작업에서는 사용하기 힘들었다.(입출력의 길이 고정을 위해 padding을 사용하기도 했지만, 성능이 크게 향상되지는 않았다)
자세한 RNN에 대한 설명은 다음 글을 참고하면 좋을 것 같다.
링크 넣기
이에 Seq2Seq 모델이 제안되었는데, LSTM 혹은 GRU 기반의 구조를 가지고 고정된 길이의 단어 시퀀스를 입력받아 입력시퀀스에 알맞은 길이의 시퀀스를 출력해 주는 언어모델이라고 할 수 있다.
2개의 LSTM을 각각 Encoder과 Decoder로 사용하여 가변적인 길이의 입/출력을 처리하고자 하였다. 이를 통해 큰 성능향상 및 긴 문장을 처리하는데 강점을 보였다.
1-2. Seq2Seq 모델 구조
seqence to sequence는 한 문장을 다른 문장으로 변환하는 모델을 의미한다.
encoder을 이용해서 입력 문장을 context vector로 만들고(인코딩과정), encoderrk 인코딩한 context vector을 입력으로 받는 decoder이 출력 문장을 생성하는(디코딩) 방식으로 서로 다른 입/출력 시퀀스에 대응할 수 있도록 하였다.
우선 각 Encoder과 Decoder에는 위에서 말했듯이 LSTM이나 GRU 셀이 들어가게 되는데, RNN셀을 사용하지 않은 이유는 Long-term dependency를 해결하고자 하였기 때문이다. Long-term dependency란 rnn에서 히든스테이트를 계속하여 넘겨주는데, 문장이 길어질수록 처음에 넘겨받았던 내용들이 사라지는 것이다. 이를 LSTM과 GRU에서는 중요한 정보들을 남김으로써 해결하였다.
1-2-1. Encoder
우선 Encoder:인코더를 먼저 설명해 보도록 하겠다.
인코더는 입력문장을 순서대로 처리하여 고정된 크기의 context vector로 압축하는 역할을 한다.
이 context vector은 인코더의 마지막 스텝에서 출력된 hidden state를 의미하며, 입력문장의 정보를 함축하고 있는 벡터를 말한다.
1-2-2. Decoder
다음으로 Decoder:디코더는 입력문장의 정보가 압축된 context vector을 사용하여 출력 문장을 생성한다.
디코더의 LSTM셀은 인코더로부터 전달받은 콘텍스트 벡터와 문장의 시작을 뜻하는 스페셜 토큰인 <sos>토큰을 입력으로 받아서 문장의 끝을 뜻하는 <eos> 토큰이 나올 때까지 문장을 생성한다.
1-2-3. 결론
위에 그림에서는 편의를 돕기 위해 단어 자체가 들어가는 것으로 그림을 표현했는데, 모델은 단어 그 자체를 입력으로 받을 수 없기 때문에 텍스트를 벡터로 변환하여 들어가야 하고, 이를 위해 이전에 배웠던 워드임베딩을 사용하게 된다.
즉 단어가 워드임베딩을 통해 임베딩 벡터로 변환되고 모델의 입력값으로 사용되는 것이다. 이후 단어사전에서 가장 확률이 높은 단어를 골라 출력한다.
위에서 설명한 방식은 사실 모델 학습이 완료된 이후, 문장을 추론하는 과정을 설명하는 것에 가깝다.
모델을 학습하기 위해서는 디코더가 정답문장을 예측할 수 있도록 각 셀에서 어떤 단어가 정답인지를 알려줘야 한다. 특정시점의 디코딩과정에서 잘못된 단어를 출력했다면 그 단어가 다음 셀의 입력으로 들어거소 계속 이상해진다.
따라서 `Teacher forcing:교사강요`라는 기법을 사용하는데, 모델 학습 시에는 이전 셀에서 예측한 단어를 다음 셀의 입력으로 넣어주는 대신 실제 정답 단어를 다음 셀의 입력으로 넣어주는 방식을 선택한다. 즉 이전 셀에서의 오류가 다음셀에 관여하지 않도록 해주는 것이다.
1-3. Seq2Seq 한계
우선 Seq2Seq는 위에서 설명한 것과 같이 인코더와 디코더 구조를 통하여 가변적인 길이의 입/출력을 처리하는데 효과적인 모델 구조이며, 실제로 기계번역작업 등에서 성능이 우수하였으나 한계점이 존재하였다.
1. 정보손실
인코딩을 진행하여 context vector을 만드는데 이 컨텍스트 벡터의 크기가 고정되어 있다 보니, 입력으로 들어오는 단어의 수가 많아지면 성능이 떨어진다. 중요한 정보들을 담는다고 하여도 고정된 사이즈의 벡터에 많은 정보량을 함축하느데는 한계가 있기 때문이다.
2. Gradient vanishing
이는 RNN구조의 한계점으로, 이전에 말했던 long -term dependency를 LSTM이나 GRU에서 해결하려 했지만, 여전히 문장이 길어질 경우 이전 정보를 계속하여 함축하는 데는 한계가 있다.
2. Attention mechanism
위의 Seq2Seq의 한계점을 해결하고자 attention mechanism이 등장하였다.
어텐션의 기본 idea는 디코더에서 출력 단어를 매핑하는 매 시점(time step)마다 인코더에서의 전체 입력 문장을 다시 한번 참조한다는 점이다. 이 때 입력 문장을 전부 다 동일한 비율로 참고하는 것이 아니라, 해당 시점에서 예측해야할 단어와 연관이 있는 입력단어 부분을 좀 더 집중(attention)해서 보자는 것이다.
우선 어텐션 메커니즘의 전체적인 그림을 보면 다음과 같다.
예를 들어, 지금 디코더의 세 번째 lstm에서 출력을 하려고 할 때, 기존에는 이전 셀의 히든스테이트를 통해 바로 출력이 나왔는데, 어텐션 메커니즘을 적용하면 인코더의 히든state들을 참조하는 것을 볼 수 있다.
2-1. Attention score
인코더의 timestep을 각각 1,2,..,N이라고 했을 때, 각각의 히든 스테이트를 $ h_1,h_2,...,h_N$ 이라 하자, 또한 디코더의 현재 timestep t에서의 히든스테이트를 $s_t$라고 하자.
우선 디코더의 현재 시점 t에는 이전 시점 t-1의 히든스테이트와 이전 시점 t-1의 출력단어가 입력으로 들어와야 한다.
이때, 어텐션메커니즘을 적용하면 `Attention value`라는 추가적인 값이 입력으로 들어가고, 이를 $a_t$라고 정의하자.
지금까지 설명한 것을 그림으로 표현하면 아래와 같다.
이제 이 Attention value, $a_t$를 구하기 위한 과정을 진행할 것이다. 우선 `Attention score`을 계산해야 한다.
Attention score란, 현재 시점(t)의 디코더 단어를 예측하기 위해, 인코더의 모든 hidden state와 디코더의 $st_t$가 얼마나 유사한지를 나타내는 정도이다. 즉, $h_1~h_4$와 $s_t$의 유사한 정도를 점수를 매기는 것이다.
attention에도 종류가 여러 개 있는데, 이번에는 dot product attention에 대해서 설명할 것이다.
우선 $s_t$ 디코더의 현재시점 히든스테이트를 전치(transpose)하고, 인코더의 각 은닉상태와 dot product(내적)을 진행한다. 그럼 각 스칼라값이 나오게 된다. 이를 수식으로 표현하면 다음과 같다.
$$ \text{score}(s_t, h_i) = s_t^T h_i $$
이렇게 각각 계산한 attention score을 모아서 나타내기도 한다.
2-2. Attention Distribution
$$ e^t=[s_t^Th_1,...,s_t^Th_N] $$
이제 이렇게 만들어진 $e^t$에다가 softmax함수를 적용하여 각 attention score의 확률을 얻어낸다. 이를 `Attention Distribution`이라고 하며, 각각의 값을 `Attention Weight`라고 부른다.
위의 그림에서 보다시피, softmax를 거쳐서 나온 확률값의 분포를 막대그래프로 시각화해 뒀는데, 저 막대그래프의 수치가 Attention Weight인 거고, 해당 단어의 중요도를 나타낸다고 볼 수 있다. 또한 저 Attention weight들을 모아둔, Attention Distribution은 다음과 같이 나타낼 수 있다.$$ \alpha^t = softmax(e^t) $$
2-3. Attention Value
이제 최종 Attention value값을 구할 차례이다. 방법은 , 각 인코더의 hidden state와 각 attention weight를 곱하고 최종적으로 더한다. 즉 Attention value는 다음과 같이 정의된다. $$ a_t= \sum_{i=1}^{N} \alpha_i^t h_i $$
2-4. Concatenate
이제 방금 구한 attention value $a_t$와 디코더의 현재 시점 hidden state 값인 $s_t$와 concat을 해줘야 한다.
이는 $v_t$로 정의할 수 있으며, 이 $v_t$를 $\hat{y}$예측 연산의 입력으로 사용되게 된다.
이때 그냥 concat 하면 길이가 길어지고, 해당 논문에서는 신경망 연산을 한번 더 거치는 작업을 한다.
가중치행렬과 방금 이어 붙인 $v_t$를 곱하고 $tanh$ 함수를 거쳐서 새로운 벡터 $\tilde{s}_t$ 를 만들어낸다. 즉 이 $\tilde{s}_t$를 입력으로 넣는 것이다.
추후에 시간이 되면 attention에 대해서도 더 자세하게 다뤄볼 것이다.
'ML & DL > NLP' 카테고리의 다른 글
[패캠/NLP] Transformer: 트랜스포머 (0) | 2023.12.26 |
---|---|
[패캠/NLP] 문장 임베딩 ELMo (1) | 2023.12.22 |
[패캠/NLP] Word2Vec 워드 임베딩 실습 (1) | 2023.12.20 |
[패캠/NLP] 임베딩 기법(Word2Vec, FastText, GloVe) (1) | 2023.12.20 |
[패캠/NLP] 워드 임베딩 (1) | 2023.12.20 |