NLP 관련해서 정리를 해보려고 한다.
우리는 단어들을 숫자의 조합으로 표현하려고 한다.
one-hot encoding도 하나의 방법이지만
그 수의 집합이 단어들의 유사도 까지 내포하고 있으면 얼마나 좋을까?
(great은 good와 비슷한 벡터를 나타낼 수 있게)
word-embedding 방식중 skip-gram이라는 방식에 대해서 알아보자.
다음과 같이 하나의 Context를 정하고 그 주변 단어(target)과의 관계를 학습해서 워드임베딩을 추출하는 과정을 Skip gram이라고 한다.
훈련 데이터셋에서 각 문장을 분석하여 단어 단위로 나눔
각 중심 단어에 대해 설정된 '컨텍스트 윈도우 크기'에 따라 그 주변 단어들이 타겟 단어로 선택됨. 예를 들어, 컨텍스트 윈도우 크기가 2라면, 중심 단어의 앞뒤로 두 단어씩이 타겟 단어로 선택된다.
그리고 네트워크를 학습시키는데, "영화를" 이 one hot enocding vector 로 [0,0,0,1,0...] 로 나타날 때 가중치 w의 3번째 행이 "영화를"에 해당하는 워드임베딩이 된다. ( 행 뽑기)
Loss는 위와 같이 softmax를 통과한 값과 target사이의 Cross-Entropy를 통해서 구한다.
CBOW는 반대로 주변 단어들을 통해 특정 단어를 예측하는 방식이다.
NN 를 학습시키고 Weight행렬의 인덱스 값을 각 단어의 Word embedding으로 결정한다.
학습방식은 동일하다. 다만 입력층이 여러개면 전체를 평균 하면된다. ( 첫 네트워크를 통과하고 4로 나누는 것을 주의하자)
따로따로 학습하는 거 아니다~~ 한번에 다같이 한다.
가정해 보자: 단어의 수가 100만 개에 이른다. 이 경우 전체 네트워크를 학습하는 것은 매우 비효율적이다. 그래서 one-hot embedding 대신에, 각 단어에 해당하는 인덱스만 전달하고, 이 인덱스에 해당하는 가중치만을 추출하여 학습을 진행한다.
예를 들어, 필요한 가중치를 W[[number,number2,number3,number4]]와 같이 간단히 합산하여 사용한다.
이러면 dramatic하게 메모리도 줄이고 연산량을 줄일 수 있다.
Skip-gram 의 경우를 예시로 들어보자. Skip-gram은 기본적으로 중심 단어로 주변 단어를 추론하는 알고리즘이다.
중심 단어와 주변 단어의 내적값을 이 모델의 예측값으로 하고, 레이블과의 오차로부터 역전파하여 중심 단어와 주변 단어의 임베딩 벡터값을 업데이트 한다. (다 더해서 한번에 함)
부정적 예시들은 확률 분포를 바탕으로 샘플링 한다.
여기서 P는 단어가 발생할 확률을 의미하고 0.75라고 적혀있는 차수부분이 작을수록 p가 낮을 단어의 확률을 높일 수 있다고 한다. ( 잘 안나오는 애들한테 관심을 주는거임)
RNN의 기본 아키텍쳐는 위와 같다
RNN은 가변적인 Data에 Robust하며 네트워크의 weight를 공유하는 특징이 있다.
=> backprop시 t번째 layer의 weight가 바뀔 시 다른 layer들의 네트워크도 바뀐다.
또 tanh를 activation으로 사용함 --> 뒤로 갈수록 앞의 정보를 잃는다. back porp할 때 뒤의 부분은 gradient Vanishing에 의해 업데이트에 영향을 주지못함. (오래된 정보는 넣으나 마나)
이러한 문제를 해결하기 위해서 나온게 LSTM이다!!
BPTT (Back prop)
위의 식은 RNN에서 backprop이 어떻게 이루어지는지 보여준다.
시점 1의 Gradient, 즉 먼쪽 Gradient가 점점 작아져서 뒷 부분 Loss에 대한 weight 업데이트에 큰 기여를 못하고 있다.
=> 멀리 있는 입력은 잊혀진다.
LSTM은 장기기억을 보존하기 위한 Cell state라는 부분이 있다.
여기서 hidden-state는 short-term Memory라고 봐도 될 것 같다
이 모델 아키텍쳐를 이해하기위해선 총 4개의 Gate 에 대한 이해가 필요하다!
이름 그대로 얼마나 까먹을지 결정하는 gate이다. ft는 cell state와 곱해지는 값으로 ft값이 1에 가까울수록 많은 정보를 보존하고 0에 가까울수록 과거의 정보를 잃게 된다.
이 Gate는 현재 정보를 기억하기 위한 게이트! (기존의 Rnn 연산 block과 일치하는 것을 볼 수 있음)
Cell state 값에 얼마나 더할지를 정하는 역할
과거의 정보는 얼마나 갖고 갈지~ 현재의 정보는 얼마나 갖고 갈지~ 정하는 과정. Cell state를 업데이트 한다.
현재의 셀 상태에 대한 정보 중 어떤 부분이 다음 히든 상태로 전달될 것인지를 결정한다.
위의 나타난 weight들은 다 공유되며 전부 학습시켜야하는 값들이다 :)
의문점: Cell state는 왜 존재하는가 어차피 -1~1곱해주는 거 말고 ouput에 기여하지 못하는데.
따로 네트워크에 넣어서 학습시키는 것도 아니고..
Cell-state 크다=LSTM 네트워크가 해당 정보를 중요하게 평가한다.
이게 왜 장기기억을 의미하지..?내가 생각한 답
Cell state => 각 시퀀스 별 정보의 합이라고 봐도 무방함.
뒤로 가더라도 앞의 정보가 반드시 사라지진 않음
1번정보는 살아 있고 2번정보는 죽어있고 이렇게 선택적인 학습이 가능함 gate덕분에.
그리고 이 정보가 결국 결과에 영향을 주므로 앞의 정보를 잊는 문제(장기 의존성 문제)는 해결했다고 봐도 됨.
하지만 여전히 앞부분의 w는 기울기 소실로 인해 많이 영향을 받지 못한다. (업데이트 안됨)
장기 의존성 문제를 해결함으로써 모델은 초기 정보를 효과적으로 보존할 수 있음. 그러나, 이 정보를 보존한다 하더라도 네트워크의 후반부가 초기 부분을 직접적으로 영향을 주거나 업데이트할 수는 없다는 점을 명심해야 한다.
초기 정보가 단지 영향을 주는 것을 넘어서, 신경망 모델의 모든 계층에서 지속적으로 업데이트가 일어날 수 있게 해주어야함.
LSTM과 같은 일반적인 RNN 구조들은 고정된 길이의 입력을 받아 고정된 길이의 출력을 생성하는 데 최적화되어 있지만 세계의 많은 문제들은 입력과 출력의 길이가 서로 다르다! ( Vamos! -->Lets go!)
그래서 등장한게 Encoder-decoder model 인 Seq2Seq!!
다음 포스트에 알아보자.