언어 모델(Language Model)
주어진 단어들을 보고 다음 단어를 맞추는 모델
단어의 시퀀스를 보고 다음 단어에 확률을 할당 하는 모델에서
주변 단어를 보고 중심 단어를 예측하는 형태로 발전하게 됨.
통계적 언어 모델 (Statistical Language Model)
단점
한 번도 본 적 없는(학습 데이터에 존재하지 않는) 단어 / 문장에 대해서는 확률을 부여할 수 없다.
따라서 언어 모델이 아우르는 범위를 넓히기 위해 다양한 단어를 포함하는 데이터가 필요하다.
(양까지 충분하다면 정의하는 확률이 일반적이므로 더욱 좋다.)
신경망 언어 모델 (Neural Network Language Model : NNLM)
NNLM의 시초는 Feed-Forward 신경망 언어 모델인데, 지금의 Embedding 레이어의 아이디어인 모델
통계적 언어 모델은 희소문제 (한 번도 관측하지 못한 데이터에 대해선 0에 확률을 부여하여 예측불가한 문제)와 단어끼리의 의미적 유사성을 전혀 계산하지 못하는 문제가 있었는데,NNLM은 단어의 유사성을 학습하게 되어서 기존 학습 코퍼스에 없어 처음등장하는 단어에 대해서도이와 주변단어의 시퀀스가 유사한 다른 기존의 단어 시퀀스를 참고하여 예측이 가능하게 됨.이 개념이 Embedding layer. (원핫해서 룩업테이블해서 평균내서 softmax하던.. cBoW로 배웠던 내용)
단점
다음 단어를 위해 예측할 때, 모든 단어를 참고하는 것이 아니라 window size안의 정해진 n개의 단어만 참고하게 됨.이 한계를 극복하기 위해 RNN이 나왔음.
RNN (Recurrent)
장점
- 일정 갯수의 단어를 입력으로 받지 않고, 유동적인 크기의 입력을 '적립'하여 처리가능.
단점
- 기울기 소실 (Vanishing Gradient) 문제 : 뒤로 갈수록 앞단의 기울기가 사라짐. 밑에 그림도 남색이 사라지고 있음
- 그래서 LSTM이 나오게 됨
- 문장 generator에는 사용 가능하지만 translator에는 사용이 어려움. 언어별로 어순도, 길이도 다르기 때문.
- 한 문장 전체를 보고나서 번역하는 생성구조를 가진 seq2seq가 나오게 됨 (2014,google)
Seq2seq
각각 단어를 정해진 차원으로 임베딩하여 임베딩벡터로 인풋을 받고,
모델을 인코더, 디코더 이렇게 두 파트로 나눠서
중간에 브릿지 역할을 하는 Context vector 라는 것을 지나 다른 세계로 연결되게 함.
Context Vector
인코더 입력문장의 모든단어! 몇개가 아니라 모든단어들을 입력받아 압축한 단하나의 벡터.
디코더에서는 <sos> <eos> 토큰을 양끝단에 추가해서
디코더의 첫 입력으로 전달할 단어로 쓰고, 생성의 마지막을 알려주게 함.
Encoder
vocab_size, emb_size로 임베딩하고,
lstm_size = enc_unts으로 lstm을 돌리면
class Encoder(tf.keras.Model):
def __init__(self, vocab_size, embedding_dim, enc_units):
super(Encoder, self).__init__()
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
self.lstm = tf.keras.layers.LSTM(enc_units) # return_sequences 매개변수를 기본값 False로 전달
def call(self, x):
print("입력 Shape:", x.shape)
x = self.embedding(x)
print("Embedding Layer를 거친 Shape:", x.shape)
output = self.lstm(x)
print("LSTM Layer의 Output Shape:", output.shape)
return output
입력 Shape: (1, 3)
Embedding Layer를 거친 Shape: (1, 3, 256)
LSTM Layer의 Output Shape: (1, 512)
Decoder
Decoder는 Encoder와 구조적으로 유사하지만 결과물을 생성해야 하므로 Fully Connected 레이어가 추가되었고, 출력값을 확률로 변환해 주는 Softmax 함수도 추가.
Decoder가 매 스텝 생성하는 출력은 우리가 원하는 번역 결과에 해당하므로 LSTM 레이어의 return_sequences 변수를 True로 설정하여 State 값이 아닌 Sequence 값을 출력으로 받음.
class Decoder(tf.keras.Model):
def __init__(self, vocab_size, embedding_dim, dec_units):
super(Decoder, self).__init__()
self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
self.lstm = tf.keras.layers.LSTM(dec_units,
return_sequences=True) # return_sequences 매개변수를 True로 설정
self.fc = tf.keras.layers.Dense(vocab_size)
self.softmax = tf.keras.layers.Softmax(axis=-1)
def call(self, x, context_v): # 디코더의 입력 x와 인코더의 컨텍스트 벡터를 인자로 받는다.
print("입력 Shape:", x.shape)
x = self.embedding(x)
print("Embedding Layer를 거친 Shape:", x.shape)
context_v = tf.repeat(tf.expand_dims(context_v, axis=1),
repeats=x.shape[1], axis=1)
x = tf.concat([x, context_v], axis=-1) # 컨텍스트 벡터를 concat 해준다
print("Context Vector가 더해진 Shape:", x.shape)
x = self.lstm(x)
print("LSTM Layer의 Output Shape:", x.shape)
output = self.fc(x)
print("Decoder 최종 Output Shape:", output.shape)
return self.softmax(output)
입력 Shape: (1, 3)
Embedding Layer를 거친 Shape: (1, 3, 256)
Context Vector가 더해진 Shape: (1, 3, 768) #256 + context 512 컨캣해서
LSTM Layer의 Output Shape: (1, 3, 512)
Decoder 최종 Output Shape: (1, 3, 30000)
단점
- 컨텍스트 벡터가 고정된 길이로 정보를 압축하는 것이 손실을 발생시킨다고 주장함. 즉 문장이 길어질수록 성능이 저하된다고 함. 그래서 encoder가 state 최종값만 가져가는 것이 아니라 hidden state 까지 다 활용해서 context vector를 만들어야 한다는 Attention 메커니즘을 제안함.
'Study (Data Science) > NLP' 카테고리의 다른 글
모델 발전과정 3 - GNMT (Google's Seq2seq 8 layers w. Residual) (0) | 2023.02.28 |
---|---|
모델 발전과정 2 - Attention (Bahdanau / Luong) (0) | 2023.02.28 |
벡터화 발전과정 4 - 워드 임베딩 (Word2Vec / FastText / GloVe) (0) | 2023.02.23 |
벡터화 발전과정 3 - 임베딩 (Embbeding) / Sparse - Dense - Embedding vector (0) | 2023.02.22 |
토큰화 / 인덱싱 / 벡터화 / 임베딩 (0) | 2023.02.22 |
댓글