word2vec을 간단하게 구현하였으나, 몇 가지 문제점
- 말뭉치에 포함된 어휘 수가 많아지면 계산량도 커짐
해결책
- Embedding이라는 새로운 계층 도입
- 네거티브 샘플링이라는 새로운 손실 함수 도입
4.1 word2vec 개선①
앞 장 복습
CBOW 모델
- 단어 2개를 맥락으로 사용하여, 하나의 단어(타깃) 추측
- 입력 측 가중치(W_in)와의 행렬 곱으로 은닉층 계산
- 출력 측 가중치(W_out)와의 행렬 곱으로 각 단어의 점수 구함
- 소프트맥스 함수를 적용해 각 단어의 출현 확률
- 확률을 정답 레이블과 비교하여 손실 구함
두 계산에서 병목
1. 입력층의 원핫 표현과 가중치 행렬 W_in의 곱 계산 (4.1 해결)
- 입력층의 원핫 표현의 벡터 커지며, 계산에 상당한 메모리와 자원 차지
- Embedding 계층 도입
2. 은닉층과 가중치 행렬 W_out의 곱 & Softmax 계층의 계산 (4.2 해결)
- Softmax 계층의 계산량이 증가
- 네거티브 샘플링 손실 함수 도입
4.1.1 Embedding 계층
결과적으로 수행하는 일 : 행렬의 특정 행 추출
- 굳이 원핫 표현으로의 변환과 MatMul 계층의 행렬 곱 계산 필요 없음
Embedding 계층
- 가중치 매개변수로부터 '단어 ID에 해당하는 행(벡터)'을 추출하는 계층
- 단어 임베딩(분산 표현)을 저장
4.1.2 Embedding 계층 구현
특정 행을 추출하는 것은 쉬움 → W[2], W[5] 와 같이 원하는 행 명시
순전파
- forward() 메서드
- 추출하는 행의 idx를 받아 W[idx] 반환
- 가중치 W의 특정행을 추출할 뿐
= 특정 행 뉴런만을 다음 층으로 흘려보냄
역전파
- backward() 메서드
- 앞 층(출력 측 층)으로부터 전해진 기울기를 다음 층(입력 측 층)으로 그대로 흘려보냄
- 그러나, idx 원소가 중복되면 dW의 동일 행에 중복된 값 할당되어 덮어씀 → '할당'이 아닌 '더하기
MatMul 계층을 Embedding 계층으로 전환!
- 메모리 사용량을 줄이고 쓸데없는 계산도 생략
4.2 word2vec 개선②
은닉층 이후의 처리
- 네거티브 샘플링(부정적 샘플링)
- 어휘가 아무리 많아져도 계산량을 낮은 수준에서 일정하게 억제
4.2.1 은닉층 이후 계산의 문제점
은닉층 이후에서 계산이 오래 걸리는 곳
1. 은닉층의 뉴런과 가중치 행렬(W_out)의 곱
- 큰 행렬의 곱을 게산하려면 시간 오래 걸림
- 역전파 대도 같은 계산 수행하므로, 행렬 곱을 '가볍게'
2. Softmax 계층의 계산
- 어휘가 많아지면 Softmax의 계산량 증가
- Softmax를 대신할 '가벼운' 계산 필요
4.2.2 다중 분류에서 이진 분류로
네거티브 샘플링 기법
- 핵심 아이디어 '이진 분류(binary classification)'
- '다중 분류(multi-class classfication)'를 '이진 분류'로 근사하는 것
이진 분류
- 'Yes/No'로 답할 수 있는 질문
- ex) 맥락이 you, goodbye일 때, 타깃 단어는 say입니까? 와 같은 질문에 답하는 신경망을 생각
- 이 경우에 출력층에는 뉴런 하나만 준비하면 됨 → 이 뉴런이 say의 점수 출력
- 출력층의 뉴런 하나뿐
= 은닉층과 출력 측의 가중치 행렬의 내적은 'say'에 해당하는 열(단어 벡터)만을 추출 - 추출된 벡터와 은닉층 뉴런과의 내적 계산
- 이전까지 출력층에서는 모든 단어를 대상으로 계산 수행
- 여기에서는 'say'라는 단어 하나에 주목하여 그 점수만 계산
→ 시그모이드 함수를 이용해 그 점수를 확률로 변환
4.2.3 시그모이드 함수와 교차 엔트로피 오차
cf) 다중 분류
- 출력층에서 '소프트맥스 함수'
- 손실 함수로 '교차 엔트로피 오차' 사용
이진 분류
- 출력층에서 (점수를 확률로 변환시) '시그모이드 함수'
- S자 곡선 형태
- 입력 값(x)은 0~1 사이 실수로 변환 = 함수의 출력(y)을 '확률'로 해석 - 손실 함수로 '교차 엔트로피 오차' 사용
시그모이드 함수
교차 엔트로피 오차
- 시그모이드 함수를 적용해 확률 y를 얻으면, 이 확률 y로부터 손실 구함
- y : 시그모이드 함수의 출력, t : 정답 레이블(0 or 1)
- 주목 : 역전파의 (y - t)
- 정답 레이블이 1이라면, y가 1에 가까워질수록 오차 줄어듦, y가 1에서 멀어지면 오차 커짐
- 오차 크면 '크게' 학습, 오차 작으면 '작게' 학습
- 시그모이드와 교차 엔트로피 조합하면 역전파가 깔금한 값
4.2.4 다중 분류에서 이진 분류로(구현)
다중 분류
- 출력층에 어휘 수만큼의 뉴런 준비, 출력값 softmax 계층 통과
- 입력층에서 각각에 대응하는 단어 ID의 분산 표현 추출하기 위해 Embedding 계층 사용
이진 분류
- 은닉층 뉴런 h와 출력 측 가중치 W_out에서 say에 해당하는 단어 벡터와 내적 계산
- Sigmoid with Loss 계층에 입력해 최종 손실
Embedding Dot 계층을 도입하여 후반부를 더 단순화할 수 있음
4.2.5 네거티브 샘플링
다중 분류 → 이진 분류
- 그러나 긍정적인 예(정답)에 대해서만 학습했기에 부정적인 예(오답)에 대한 결과 불확실
목표
- 긍정적 예(say) : Sigmoid 계층 출력 1에 가깝게
- 부정적 예(say 이외) : Sigmoid 계층 출력 0에 가깝게 만드는 것
* 다중 분류 문제를 이진 분류로 다루려면 '정답'과 '오답' 각각에 바르게 (이진) 분류할 수 있어야 함
네거티브 샘플링
- 모든 부정적 예를 대상으로 하면 어휘 수가 늘어나서 감당할 수 없음
- 적은 수의 부정적 예를 샘플링해, 그 부정적 예에 대해서 마찬가지로 손실 구함
- 각각 데이터(긍정적 예 + 부정적 예)의 손실을 더한 값을 최종 손실로 출력
4.2.6 네거티브 샘플링의 샘플링 기법
부정적 예를 샘플링하는 방법
- 말뭉치의 통계 데이터를 기초로 샘플링
(자주 등장하는 단어는 많이 추출, 드물게 등장하는 단어는 적게 추출) - 각 단어 출현 횟수를 구해 '확률분포'로 나타내고, 거기서 단어를 샘플링
- 자주 등장하는 단어는 선택될 가능성 높음, 희소한 단어는 선택되기 어려움
- 기본 확률분포에 0.75 제곱 → 출현 확률이 낮은 단어를 버리지 않기 위해서 (낮은 빈도 확률 높여줌)
4.2.7 네거티브 샘플링 구현
- 순전파, 역전파 구현
4.3 개선판 word2vec 학습
4.3.1 CBOW 모델 구현
SimpleCBOW 클래스 개선
- Embedding 계층과 Negative Sampling Loss 계층을 적용
- 윈도우 크기 임의로 조절할 수 있도록 확장
- 초기화 메서드
- 계층 생성
- 신경망에서 사용하는 모든 매개변수와 기울기 모음
- 순전파와 역전파 처리
4.3.2 CBOW 모델 학습 코드
- 하이퍼파라미터 설정
- 데이터 읽기
- 모델 등 생성
- 학습 시작
- 데이터 저장
4.3.3 CBOW 모델 평가
- word2vec으로 얻은 단어의 분산 표현은 비슷한 단어를 가까이 모으고, 더 복잡한 패턴을 파악
- word2vec의 단어의 분산 표현을 사용하면 유추 문제를 벡터의 덧셈과 뺄셈으로 풀 수 있음
ex) ( man - woman ) 벡터와 ( king - ? ) 벡터가 가능한 가까워지는 단어를 찾음
- vec(woman) - vec(man) = vec(?) - vec(king)
vec(king) + vec(woman) - vec(man) = vec(?) 라는 벡터에 가장 가까운 단어 벡터를 구하는 일
유추 문제 몇 가지 해결을 통해 알 수 있는 점
- 현재형과 과거형 패턴 파악 : 시제 정보가 단어의 분산 표현에 인코딩 됨
- 단수형과 복수형을 올바르게 파악하고 있음
- 비교급이라는 성질이 단어의 분산 표현에 인코딩 됨
- 벡터의 덧셈과 밸셈으로 유추 문제를 풀 수 있음
→ 단어의 단순한 의미뿐 아니라 문법적인 패턴도 파악
4.4 word2vec 남은 주제
4.4.1 word2vec을 사용한 애플리케이션의 예
word2vec으로 얻은 단어의 분산 표현을 전이 학습으로 활용할 수 있음
- 전이 학습 : 한 분야에서 배운 지식을 다른 분야에도 적용하는 기법
- 큰 말뭉치로 학습을 끝난 후, 그 분산 표현을 각자의 작업에 이용
- 텍스트 분류, 문서 클러스터링, 품사 태그 달기, 감정 분석 등 자연어 처리 작업이라면 가장 먼저 단어를 벡터로 변환해야 함
- 학습을 미리 끝낸 단어의 분산 표현을 이용
단어의 분산 표현은 단어를 고정 길이 벡터로 변환해줌
- 일반적인 머신러닝 기법(신경망, SVM 등)을 적용할 수 있음
- 단어의 분산 표현은 위키백과와 같은 범용 말뭉치를 사용해 미리 학습
- 현재 직면한 문제에 관련하여 수집한 데이터를 가지고 머신러닝 시스템(SVM 등)을 학습
4.4.2 단어 벡터 평가 방법
- 단어의 분산 표현은 특정 애플리케이션에서 사용되는 것이 대부분
- 시스템의 예) 단어 분산 표현 만드는 시스템(word2vec) + 특정 문제에 대한 분류 수행 시스템(SVM)
→ 단어의 분산 표현 우수성은 실제 애플리케이션과는 분리해 평가
단어 분산 표현의 우수성을 평가하는 방법
유사성 평가
- 사람이 작성한 단어 유사도를 검증 세트를 사용해 평가
- 사람이 부여한 점수와 word2vec에 의한 코사인 유사도 점수를 비교해 상관성 살핌
유추 문제 평가
- 유추 문제를 출제하고, 그 정답률로 단어의 분산 표현의 우수성 측정
- 단어의 의미나 문법적인 문제를 제대로 이해하고 있는지 측정할 수 있음
4.5 정리
'모두' 대신 '일부'를 처리하는 것이 핵심
- Embedding 계층은 단어의 분산 표현을 담고 있으며, 순전파 시 지정한 단어 ID의 벡터를 추출한다.
- word2vec은 어휘 수의 증가에 비례하여 계산량도 증가하므로, 근사치로 계산하는 빠른 기법을 사용하면 좋다.
- 네거티브 샘플링은 부정적 예를 몇 개 샘플링하는 기법으로, 이를 이용하면 다중 분류를 이진 분류처럼 취급할 수 있다.
- word2vec으로 얻은 단어의 분산 표현에는 단어의 의미가 녹아들어 있으며, 비슷한 맥락에서 사용되는 단어는 단어 벡터 공간에서 가까이 위치한다.
- word2vec의 단어의 분산 표현을 이용하면 유추 문제를 벡터의 덧셈과 뺄셈으로 풀 수 있게 된다.
- word2vec은 전이 학습 측면에서 특히 중요하며, 그 단어의 분산 표현은 다양한 자연어 처리 작업에 이용할 수 있다.
'AI > NLP 기초' 카테고리의 다른 글
[NLP 기초] 6. 게이트가 추가된 RNN (0) | 2024.02.20 |
---|---|
[NLP 기초] 5. 순환 신경망(RNN) (0) | 2024.02.19 |
[NLP 기초] 3. word2vec (1) | 2024.02.13 |
[NLP 기초] 2. 자연어와 단어의 분산 표현 (1) | 2024.02.13 |
[NLP 기초] 1. 신경망 복습 (1) | 2024.02.13 |