🧐 단어의 토큰화(tokenization)
🤫 NLP(Natural Language Processing)란?
컴퓨터의 언어가 아닌, 인간이 사용하는 언어를 처리하는 분야이다.
🤫 token? 그게 뭐지??
글 ⊃ 문장 ⊃ 단어로 글은 이루어져 있는데, 단어는 글의 의미있는 부분 중 가장 작은단위이다.
이때, 문법적으로 가장 작은 단위를 토큰(token)이라 하며, 전체 글을 토큰으로 나누는 것을 토큰화(tokenization)라한다.
이렇게 토큰화를 이용하면 기본적인 분석이 가능한데, 예를들어 어떤 토큰이 자주 사용되는지를 알 수 있는데, 이를 워드 카운트(word_counts)라 한다.
🧐 단어를 벡터로 변환
🤫 token을 벡터로 변환??
token을 벡터로 표현하는 방법의 하나는 one-hot encoding인데, 이에 대해 아래 코드로 살펴보자.
🧐 단어 임베딩 (embedding)
🤫 token을 벡터로 변환??
token을 벡터로 표현하는 one-hot encoding은 장점도 있지만 단점이 명확한 방법이다.
만약 단어 인덱스가 100,000개 존재한다면? → 하나의 단어를 표현하기 위해 100,001길이의 벡터가 필요하게 된다는 점!
따라서 단어 임베딩(Embedding)이라는 방법을 사용한다.
단어 임베딩은 단어 벡터의 길이를 사용자가 직접 지정할 수 있다는 장점이 있다.
즉, 인덱스 길이에 상관없이 사용자가 지정한 벡터의 길이로 모든 단어를 표현한다.
임베딩하려는 단어의 벡터를 준비하고
임베딩을 위한 행렬을 준비한다. [행: 임베딩할 단어의 개수 // 열: 임베딩 벡터의 크기]
위에서의 실습에서 벡터의 길이가 6이었지만, 아래는 해당 문장을 벡터의 길이가 3으로 지정해 임베딩하는 것을 보여주는 코드이다.
🧐 seq2seq model
기존의 딥러닝
- 기존의 딥러닝은 input과 output데이터의 차원이 고정된 벡터인 경우에만 사용
- 하지만 실제 문제들은 벡터의 길이가 사전에 알 수 없는 sequence로 표현되는 경우가 많음
🤫 seq2seq란?
입력값으로 sequence를 받고 출력값으로 다른 sequence를 출력하는 모형
입력 sequence와 출력 sequence를 맵핑하는 model으로 다음 2가지 경우가 존재
1. input sequence와 output sequence가 같은 경우 (input sequence의 길이정보가 필수적)
2. input sequence와 output sequence의 길이가 다른 경우 (targe예측을 위한 input sequence 전체가 요구됨)
🤫 seq2seq에 대한 개념적, 구조적 접근
개념적: RNN과 Auto-Encoder를 합친 형태
구조적: 2개의 RNN을 합친 형태 (특히 LSTM과 GRU를 자주 사용)
아래 예시를 통해 이해해 보자.
인코더 내부에서 1개의 step마다 한개의 LSTM모형이 존재하기에 결과적으로 여러 LSTM이 존재하고 큰 차원의 벡터를 입력받을 수 있다. 이때, 인코더는 입력시퀀스를 처리하고 은닉"상태(state)"를 return한다.
즉, encoder의 output은 버리고 오직 "상태"만 전달시키는데, 이때 인코딩 과정에서 입력데이터를 하나의 벡터로 압축하는 context vector를 진행한다.
인코딩 과정을 거친 은닉벡터를 입력받아 출력 시퀀스를 출력한다.
이때, 디코더는 target sequence의 한 시점 이전 문자가 주어지면, 바로 다음 문자를 예측하도록 학습되며 중요한 점은 디코더는 인코더의 출력벡터인 context vector를 초기 벡터로 사용한다!
즉, target sequence를 같은 sequence로 변하게 학습하지만 한시점 미래로 offset을 하는, 교사강요(teacher forcing) 학습과정을 진행한다.
ex) input sequence가 주어지면 디코더는 target값[..t]가 주어질 때, target값[t+1..]를 예측하도록 학습한다.
이를 통해 디코더는 어떤 문자를 생성할 것인지에 대한 정보를 구할 수 있다.
🤫 seq2seq. Algorithm
1. input sequence를 context 벡터로 encoding, 출력
2. size가 1의 target sequence로 시작.(target sequence는 단지 start-of-string문자)
3. 다음 문자를 예측하기 위해 decoder에 상태벡터와 1-char target sequence를 넣는다.
4. 이러한 예측법으로 다음 문자를 sampling
5. 뽑힌 문자를 target sequence에 추가
6. 이러한 과정을 <eos>가 나오거나 문자 한계치에 도달할 때까지 반복
🤫 입력시퀀스 (x1, . . . , xn)을 입력받았을 때, 출력시퀀스(y1, . . ., yn')를 출력하는 모델에 대해 살펴보자.
입력시퀀스에 대한 출력시퀀스의 조건부확률 P(y1, . . ., yn' | x1, . . . , xn)를 추정해야 하는 것이 목적이므로
아래와 같은 식을 사용해 구할 수 있다.
위 식에서 v는 입력데이터 시퀀스 데이터 x가 인코더를 거친 후 출력되는 context vector를 의미하며
P(yt | v, y1, . . . ,yt-1)는 모든 가능한 출력 후보에 softmax함수를 적용한 값이다.
🧐 Attention
🤫 seq2seq보다 좀 더 발전시켜볼까?
이름처럼 주위에 신경을 기울인다는 뜻으로 출력단어를 예측하는 매 시점 encoder에서 전체 입력문장을 참고하는 방식.
앞서 배운 seq2seq(일명 바닐라 seq2seq)는 직전 벡터에 가장 큰 영향을 받아 시간이 지나면서 정보를 잃는 한계점이 존재
반면, attention은 모든 decoding과정마다 encoder내부의 모든 hidden layer를 참고한다.
이때, encoder의 은닉상태를 동등하게 참고하지 않고 출력단어와 연관이 있는 부분을 좀 더 집중(attention)해서 참고한다.
attention의 세부단계는 총 5단계를 거치는데, 다음과 같다.
1. 내적
- decoder의 은닉상태 벡터 · encodeer의 은닉상태 벡터 = 각각의 은닉상태 벡터에 대한 attention score
2. attention의 분포 구하기
- softmax함수를 이용해 분포를 구하며 확률분포이기에 모두 합하면 1이 된다.
- 이때, 막대의 크기가 가장 큰 것이 How에 해당하는 attention score이기에 How와 연관이 크다는 것을 알 수 있다.
3. attention의 output구하기
- attention 분포 ⊙ encoder 은닉상태 = attention output. (원소곱 진행)
4. output layer의 input 구하기
- 출력층 입력 = attention output과 해당단계의 decoder 은닉상태를 이어붙인 후 w를 곱하고 b를 더해 activation 함수에 넣음
5. predict한 값 구하기
- 최종 예측값 = 4에서 구한 출력층 입력벡터에 w행렬을 곱하고 b를 더한 후 softmax를 사용