word2vec
통계 기반 기법의 문제점
- 말뭉치 어휘의 수는 100만개 이상
- 통계 기반 기법에서는 '100만개x100만개' 거대한 행렬 생성 -> SVD 적용 현실적 어려움
- 통계 기반 기법은 단 1회의 처리만에 단어의 분산 표현을 얻음
- 한편, 추런 기반 기법에서는, 예컨대 신경망을 이용하는 경우는 미니배치로 학습하는 것이 일반적
추론 기반 기법
- 주변 단어(맥락)이 주어졌을 때 "?"에 무슨 단어가 들어가는지를 추측하는 작업
- 모델(신경망)은 맥락 정보를 입력 받아 각 단어의 출현 확률을 출력
- 학습 결과로 단어의 분산 표현을 얻음
신경망에서의 단어 처리
- 단어를 '고정 길이의 벡터'로 변환하여 뉴런의 수 '고정' (원핫 벡터)
- 먼저 총 어휘 수만큼의 원소를 갖는 벡터 준비
- 인덱스가 단어ID와 같은 원소를 1로, 나머지는 모두 0으로 설정
- 완전연결계층에 의한 변환을 단순화 한 그림
단순한 word2vec
wordvec에서 제안하는 CBOW
- 맥락으로부터 타깃을 추측하는 용도의 신경망
- 입력은 '맥락'
- 입력층 수 = 맥락에 포함시킬 단어 수
- 출력층 뉴런의 수 = 어휘의 수
- 두 입력층에서 은닉층으로의 변환은 똑같은 완전연결계층이 처리(은닉층에서 출력층으로 변환도 마찬가지)
- 은닉층의 뉴련은 입력층이 여려 개이면 전체를 '평균'
- 출력층 이후 소프트맥스 함수를 적용해 대응 단어의 출현 확률 나타냄
- W(in)의 각 행에는 해당 단어의 분산 표현이 담겨 있다고 볼 수 있음
- 따라서 학습을 진행할수록 맥락에서 출현하는 단어를 잘 추측하는 방향으로 이 분산표현들이 갱신
은닉층의 뉴런 수를 입력층의 뉴런 수보다 적게하는 이유
- 은닉층에 단어 예측에 필요한 정보를 '간결하게' 담게 됨
- 결과적으로 밀집벡터 표현을 얻을 수 있음
- W(in)과 W(out)에 단어의 출현 패턴을 파악한 벡터가 학습됨
- 해당 모델은 다중 클래스 분류를 수행하는 신경망
- 따라서 해당 신경망을 학습하려면 소프트맥스와 교차 엔트로피 오차만 이용
- wordvec에서 사용되는 신경망에는 두 가지 가중치
- 입력 측 완전연결계층의 가중치(Win)와 출력 측 완전연결계층의 가중치(Wout)
- W(in)과 W(out)은 각 단어의 분산 표현에 해당한다고 볼 수 있음
- 다만, W(out)은 분산 표현이 열 방향으로 저장
- word2vec에서는 '입력 측의 가중치(Win)만 이용한다'가 가장 대중적인 선택
CBOW 모델과 확률
- 맥락으로 wt-1과 wt+1이 주어졌을 때 타킷이 wt가 될 확률
손실함수(교차 엔트로피 오차)
- yk : k번째에 해당하는 사건이 일어날 확률
- tk : 정답 레이블(wt에 해당하는 원소만 1이고 나머지는 0)
- 음의 로그 가능도(단순히 확률에 log 취한 다음 마이너스)
- CBOW 모델의 학습이 수행하는 일은 아래 손실 함수의 값을 가능한 작게 막드는 것
- T : 전체 말뭉치에서 샘플 데이터 수
skip-gram 모델
- skip-gram은 CBOW에서 다루는 맥락과 타킷을 역전시킨 모델
- 중앙의 단어(타킷)으로부터 주변의 여러 단어(맥락) 추측
- skip-gram 모델의 입력층은 하나
- 출력층은 맥락의 수만큼 존재
- wt가 주여졌을 때 wt-1과 wt+1이 동시에 일어날 확률
- 조건부 독립 가정하여 교차 엔트로피 오차에 적용
- 말 뭉치 전체로 확장
CBOW vs skip-gram
- 단어 분산 표현의 정밀도 면에서 skip-gram 모델의 결과가 더 좋은 경우가 많음(더 어려운 문제에 도전)
- 반면, 학습 속도 면에서는 CBOW 모델이 더 빠름 (skip-gram은 손실을 맥락 수만큼 구해야 해서 계산비용이 큼)
통계 기반 vs 추론 기반
추가할 새 단어가 생길 경우
- 통계 기반 기법에서는 동시발생 행렬을 다시 만들고 SVD를 수행하는 등 처음부터 다시 작업 수행
- 추론 기반 기법은 지금까지 학습한 가중치를 초깃값으로 사용해 다시 학습
=> 추론 기반은 학습한 경험을 해치지 않으면서 단어의 분산 표현을 효율적으로 갱신 가능
단어의 분산 표현의 정밀도 측면
- 통계 기반 기법에서는 주로 단어의 유사성이 인코딩
- 한편, word2vec에서는 단어의 유사성은 물론, 한층 복잡한 단어 사이의 패턴까지 파악되어 인코딩
- ex) king-man+woman = queen
=> 그러나 실제로 단어의 유사성을 정량 평가해본 결과, 의외로 추론 기반과 통계 기반 기법의 우열을 가릴 수 X
추론 기반 기법과 통계 기반 기법은 서로 관련
- skip-gram과 네커티브 샘플링을 이용한 모델은 말뭉치 전체의 동시발생 행렬에 특수한 행렬 분해를 적용한 것과 같음
- 나아가 word2vec 이후 추론 기반 기법과 통계 기반 기법을 융합한 GIoVe 기법 등장
- 말뭉치 전체의 통계 정보를 손실 함수에 도입해 미니배치 학습
word2vec 속도 개선
- 입력층과 출력층에는 각 100만 개의 뉴런이 존재
- 수많은 뉴런 때문에 중간 계산에 많은 시간 소요
문제1) 입력층의 원핫 표현
- 어휘가 100만 개라면 그 원핫 표현 하나만 해도 원소 수가 100만 개인 벡터
- 상당한 메모리 차지
- 게다가 가중치 행렬 W(in)을 곱해야 하는데, 이것만으로 계산 자원을 상당히 사용
- Embedding 계층을 도입하여 해결
문제2) 은닉층 이후의 계산
- 우선 은닉층과 가중치 행렬 W(out)의 곱만 해도 계산량 상당
- Softmax 계층에서도 다루는 어휘가 많아짐에 따라 계산량 증가
- 네커티브 샘플링이라는 새로운 손실 함수 도입해 해결
Embedding 계층
- 사실상 결과적으로 수행하는 일은 단지 행렬의 특정 행을 추출하는 것 뿐
- 따라서 원핫 표현으로의 변환과 MatMul 계층의 행렬 곱 계산은 사실 필요가 없는 것
- Embedding 계층의 순전파는 가중치 W의 특정 행을 추출할 뿐
- 단순히 가중치의 특정 행 뉴런만을 다음 층으로 흘려보냄
- 역전파에서는 앞 층으로부터 전해진 기울기를 다음 층으로 그대로 흘려주면 됨
- 다만, 앞 층으로부터 전해진 기울기를 가중치 기울기 dW의 특정 행에 설정
그런데 역전파 구현에 사실 문제가 하나 존재
- idx의 원소가 중복될 때 발생
- ex) idx = [0,2,0,4]
- 중복 문제를 해결하려면 '할당'이 아닌 '더하기'를 해야함
네거티브 샘플링
- 핵심 아이디어는 다중분류를 '이진 분류'로 근사하는 것
- "Yes/No"로 답할 수 있는 질문
- 예컨대 "맥락이 'you'와 'goodbye'일 때, 타킷이 'say'입니까"
- 이렇게 하면 출력층에는 뉴런을 하나만 준비하면 됨(Wout에서 "say"에 해당하는 단어 벡터만 추출)
- 이진 분류 문제를 신경망으로 풀려면 점수에 시그모이드 함수 적용해 확률로 변환
- 손실을 구할 때는 '교차 엔트로피 오차' 사용
- y: 시그모이드 함수 출력
- t: 정답 레이블(0 or 1)
- 주목할 점은 역전파의 y-t 값
- 정답 레이블이 1이라면, y가 1에 가까워질수록 오차가 줄어든다는 뜻
- 오차가 앞 계층으로 흘러가므로, 오차가 크면 '크게' 학습하고, 오차가 작으면 '작게' 학습
- 이진 분류를 수행하는 word2vec(CBOW 모델)의 전체 그림
- 은닉층 뉴련 h와 출력 측의 가중치 W(out)에서 단어 "say"에 해당하는 단어 벡터와 내적
- 다중 분류 문제를 이진 분류로 다루려면 '정답(긍정적 예)'과 '오답(부정적 예)' 각각에 대해 바르게 분류할 수 있어야 함
- 따라서 부정적 예를 대상으로도 이진 분류를 학습시켜야 함
- 하지만 모든 부정적 예를 대상으로 하는 방법은 어휘 수가 늘어나면 감당할 수 없음
- 그래서 적은 수의 부정적 예를 샘플링해 사용(=네커티브 샘플링)
- 최종손실 = 긍정적 예를 타킷으로 한 경우의 손실 + 샘플링된 부정적 예를 타킷으로 한 경우의 손실
네커티브 샘플링의 샘플링 기법
- 말뭉치에서 자주 등장하는 단어를 많이 추출하고 드물게 등장하는 단어를 적게 추출
- 먼저 말뭉치에서 각 단어의 출현 횟수를 바탕으로 '확률 분포'를 구한 다음, 그 확률분포에 따라서 샘플링
단어의 분산 표현 중요성
- 자연어 처리 분야에서 단어의 분산 표현이 중요한 이유는 '전이 학습'에 있음
- 전이 학습은 한 분야에서 배운 지식을 다른 분야에도 적용하는 기법
- 텍스트 분류, 문서 클러스터링, 감정 분석 등 자연어 처리 작업이라면 가장 먼저 단어를 벡터로 변환작업이 필요함
- 이때 학습을 미리 끝낸 단어의 분산 표현 이용
- 단어의 분산 표현은 단어를 고정길이 벡터로 변환해준다는 장점
- 문장도 단어의 분산 표현을 사용하면 고정 길이 벡터로 변환할 수 있음
- 가장 간단한 방법은 문장의 각 단어의 분산 표현을 합하는 것(bag-of-words)
- 또한, 순환 신경망(RNN)을 사용하면 한층 세련된 방법으로 문장을 고정 길이 벡터로 변환 가능
- 단어나 문장을 고정 길이 벡터로 변환하면 일반적인 머신러닝 기법을 적용할 수 있음
단어 벡터 평가 방법
- 단어의 '유사성'이나 '유추 문제'를 활용한 평가
- 사람이 부여한 유사도 점수와 word2vec에 의한 코사인 유사도 점수를 비교해 그 상관성을 봄
- "king:queen = man:?"와 같은 유추 문제를 출제하고, 그 정답률로 단어의 분산 표현의 우수성 측정
'Study > DL' 카테고리의 다른 글
[밑시딥2] Chapter 7. RNN을 사용한 문장 생성 (0) | 2024.02.02 |
---|---|
[밑시딥2] Chapter 5~6. 순환신경망(RNN)& 게이트가 추가된 RNN (0) | 2024.01.25 |
[모두를 위한 딥러닝 시즌2] lab 10-5. Advanced CNN(VGG) (0) | 2024.01.21 |
[밑시딥2] Chapter 2. 자연어와 단어의 분산 표현 (0) | 2024.01.20 |
[파이썬 딥러닝 파이토치] PART 4. 컴퓨터 비전 (0) | 2024.01.19 |