밑바닥부터 시작하는 딥러닝 2 4장 word2vec 속도 개선
·915 words·5 mins
📝 상세 정리 # 기존의 CBOW모델은 말뭉치에 포함된 어휘 수가 많아지면 계산량도 커진다는 단점이 있었다. 이를 Embedding 계층과 네거티브샘플링이라는 새로운 손힐함수를 이용하여 개선할 것이다. 4.1 word2vec 개선 1 # 기존의 CBOW모델에서 어휘가 100만개가 된다고 가정해보자. 그렇다면 입력층은 $W_{in} = 1000000 * 100, W_{out} = 100 * 1000000$의 행렬이 된다. 심지어 원핫 벡터라 상당히 sparse한데.. 이를 Embedding 계층 도입으로 해결해보자. $W_{in}$은 Embedding으로, $W_{out}$은 네거티브 샘플링으로 해결할 것이다. 4.1.1 Embedding 계층 다시한번 어휘 수가 100만개인 상황을 상상해보자. 단어의 원핫벡터는 100만차원.. 그런데, 이 연산이 무엇을 의미하는걸까? 이는 그저 행렬의 특정 행을 추출하는 것뿐이다! 다시말해, 원핫표현으로의 변환가 행렬 곱연산은 사실 큰 필요가 없다. 가중치 매개변수로부터 단어 ID에 해당하는 행을 추출하기만 하면 된다. 해당 계층을 만들어보자. 이를 Embedding 계층이라고 하고, 단어 임베딩이라는 용어에서 유래했다. Embedding 계층에 단어의 분산 표현을 저장할 것이다. 4.1.2 Embedding 계층 구현 행렬에서 특정 행을 추출하는것은 꽤나 쉽다. $W$가 2차원 numpy 배열이라면, W[2]처럼 원하는 행을 명시하면 끝 입력층 단어가 일때도 쉽게 된다. 따라서 구현에서도 W[idx]로 인덱싱만 진행하면 된다. 역전파에서도 똑같이 전해진 기울기를 idx번째 행에 전달하면 된다. 그런데 여기서 문제가 발생한다. idx의 원소가 중복된다면? 예를 들어 입력층에서 넣은 단어인덱스 배열이 [0, 2, 0, 4]라면? 이 문제를 해결하기 위해 구현 시 dW의 층을 0으로 초기화하고 각 인덱스에 대해 더해주자. 4.2 word2vec 개선 2 # 여기서는 은닉층 이후의 처리, 즉 행렬곱과 Softmax계층의 계산 파트의 병목을 해소할 것 네거티브 샘플링을 이용할 것이다. 4.2.1 은닉층 이후 계산의 문제점 언제나 그랬듯 어휘가 100만개, 은닉층 뉴런이 100개라고 생각해보자. $W_{out} = 100 * 1000000$ 의 행렬 연산을 해서 100만 길이의 출력층을 만들고 이에 softmax 함수를 적용해서 확률을 얻어내야 한다. 4.2.2 다중 분류에서 이진 분류로 이 기법의 핵심 아이디어는 다중 분류(multi-class classification)을 이중 분류(binary classification)으로 근사하는데 있다. 100만개의 단어 중 옳은 단어 하나를 고르는 문제를, 맥락이 주어졌을 때 타깃 단어는 say 입니까? 라는 이진 분류, 즉 결정 문제로 바꿀 수 있다. 그렇다면 출력층에는 뉴런을 하나만 준비하면 된다! 따라서 연산은 $W_{out}[idx] = 100 * 1$ 로 바뀌게 되고, 길이 1의 출력층만 sigmoid를 적용하면 되게 되었다. 4.2.3 시그모이드 함수와 교차 엔트로피 오차 이진 분류 문제를 신경망으로 풀 때에는 점수에 시그모이드 함수를 적용해 확률로 변환하고 손실을 구할 때에는 손실 함수로 교차 엔트로피 오차를 사용한다. 시그모이드 함수는 앞에서 배운것과 같이 다음과 같고, $y = \frac{1}{1+e^{-x}}$ 교차 엔트로피 오차는 다음과 같다. $L = -(t\log y + (1-t)\log (1-y))$ $y$는 시그모이드 함수의 출력, $t$는 정답 레이블 $t = 1$일 때 Yes, $t = 0$일때 No 따라서 $t = 1$일때 $-\log y$가, $t = 0$일 때 $-\log (1-y)$가 출력된다 이때 역전파 계산 결과, Chain Rule로 계산을 완료하면 전달되는 오차(기울기)가 $y-t$가 된다. $t = 0$일때는 $y$가 크면 크게 학습하고, $y$가 작으면 작게 학습한다는 의미도 된다! 4.2.4 다중 분류에서 이진 분류로 ![[Pasted image 20260127170240.png]] 위의 모든 최적화를 거친 그림은 위와 같다. 여기서 출력층의 Embedding 계층과 내적 연산을 합쳐서 Embedding dot 계층으로 표현하면 조금 더 간단하게도 그릴 수 있다. Embedding dot 계층은 $h, idx$를 입력받아서 점수를 반환한다. 내적은 $\text{Score} = \sum\limits_{i=1}^d{h_i \cdot w_i} = h \cdot w_{target}$ 이라고 생각할 수 있고, 곱의 결과로 나온 벡터가 실제 정답과 얼마나 유사한지에 대한 값이라고 생각할 수 있다. 4.2.5 네거티브 샘플링 위는 정답의 예만 신경썼고, 오답의 예를 신경쓰지 않았다. 이를 어떻게 학습시키면 좋을까? 모든 오답에 대해서 이진 분류를 학습시키면 어떨까? 그렇다면 다시 어휘의 수에 연산량이 비례하게 된다…. 따라서 근사적인 해법으로, 부정적인 예를 조금만 선택하자! 이를 네거티브 샘플링이라고 한다. 4.2.6 네거티브 샘플링의 샘플링 기법 샘플링을 단순히 무작위로 할 것인가? 더 좋은 방법이 있다. 말뭉치의 통계 데이터를 기초로 샘플링하자! 자주 등장하는 단어를 많이 추출하고, 드물게 등장하는 단어를 적게 추출하자. 단어의 출현 횟수를 확률분포로 나타내고, 그 확률분포대로 단어를 샘플링하면 된다. 그런데, word2vec의 네거티브 샘플링에서는 각 확률분포에 0.75승을 하라고 권장한다. 이는 출현확률이 낮은 단어를 버리지 않게하기 위함으로, 낮은 출현율의 단어의 확률을 조금 끌어올릴 수 있다. 4.2.7 네거티브 샘플링 구현 앞과 크게 다르지 않다. 4.3 개선판 word2vec 학습 # PTB 데이터셋으로 학습해보자. 4.3.1 CBOW 모델 구현 4.3.2 CBOW 모델 학습 코드 4.3.3 CBOW 모델 평가 4.4 word2vec 남은 주제 # 4.4.1 word2vec을 사용한 애플리케이션의 예 전이 학습 한 분야에서 배운 지식을 다른 분야에 적용하는 기법 자연어 문제를 풀 때, 처음부터 학습하는 것이 아니라 위키백과나 구글 뉴스등의 큰 말뭉치로 학습을 끝낸 후, 우리가 원하는 작업에 돌입하자. 문장을 고정크기 벡터로 변환할 때에는 단어 벡터들의 합을 이용하자. 4.4.2 단어 벡터 평가 방법 우리가 얻어낸 분산 표현이 좋은지는 어떻게 평가할 수 있을까? 단어의 유사성 사람이 작성한 단어 유사도를 검증 세트로 사용해 평가하는 것 유추 문제를 이용한 평가 “king : queen = man : ?” 과 같은 문제를 출제해서 정답률로 측정 4.5 정리 # CBOW모델은 말뭉치의 어휘 수 증가에 비례해 계산량이 증가하는 문제가 있었다. 이를 Embedding계층 구현, 네거티브 샘플링 두가지 방법을 도입해서 해결하였다. 핵심은 어휘 모두를 처리하는 것이 아니라 일부 단어만을 대상으로 하는 것이다. ❔질문 사항 # yes / no 결정문제로 만들면 no가 나오면 yes가 나올때까지 돌리는건가? 근데 그러면 똑같이 시간복잡도가 $O(N)$인거 아닌가? 아하, 위는 학습에서나 나오는 이야기고, 결국 나중에 디코딩할때는 = 단어를 찾을 때는 어떤 벡터의 결과값으로 가장 가까운 단어를 찾아가는건가? 그건 어떻게 이루어지지? 벡터공간에서 가장 가까운 점 찾기가 쉽나? -> 근사 최근접 이웃 (Approximate Nearest Neighbor, ANN) 알고리즘을 이용한다. [[260127_TIL_Approximate Nearest Nighbor 알고리즘]] 🔗 참고 자료 # https://word2vec.kr/search/