본문 바로가기

딥러닝/[밑바닥부터 시작하는 딥러닝]딥러닝

추론 기반 기법과 신경망

통계 기반 기법과 추론 기반 기법
단어의 의미는 주변 단어와의 관계에 따라 형성된다는 분포 가설은 자연어 처리 분야에서 매우 중요한 개념 중 하나입니다.
통계 기반 기법과 추론 기반 기법은 이 분포 가설을 이용하여 단어를 벡터로 표현하는 방법 중 두 가지입니다.
통계 기반 기법은 주변 단어의 출현 빈도를 집계하여 단어를 벡터로 변환하고,
추론 기반 기법은 주변 단어가 주어졌을 때 중심 단어가 출현할 확률을 예측하여 단어를 벡터로 변환합니다.

 

1.통계 기반 기법의 문제점

 

통계 기반 기법은 주변 단어의 빈도를 기초로 단어를 표현한다.

단어의 동시발생 행렬을 만들고 그 행렬에 SVD를 적용하여 밀집벡터(단어의 분산 표현)을 얻었습니다.

 

통계 기반 기법
통계 기반 기법은 단어의 동시발생 행렬을 만들어서 해당 행렬을 분해하여 밀집 벡터를 얻는 방식입니다.
동시발생 행렬에서는 각 단어들이 함께 등장한 빈도수를 세어서 단어 간의 관련성을 파악합니다.
이를 통해 단어들 간의 유사성을 계산하고, SVD와 같은 특이값 분해를 이용하여 밀집 벡터를 얻습니다.
이렇게 얻어진 밀집 벡터는 단어 간의 의미적 관계를 나타내며, 단어의 분산 표현이라고도 합니다.

 

SVD(Singular Value Decomposition)
SVD는 Singular Value Decomposition의 약어로, 행렬을 세 개의 행렬 곱으로 분해하는 기법입니다.
특히, 정방행렬이 아닌 행렬의 경우에도 적용이 가능하며, 다양한 분야에서 활용됩니다.
SVD는 행렬을 저차원의 밀집벡터로 분해하는 것이 가능하다는 점에서, 자연어처리 분야에서 단어 임베딩에 많이 활용됩니다.
SVD를 n x n 행렬에 적용하는 비용은 O(n^3)이며, 대규모 행렬의 경우 계산 비용이 매우 높아질 수 있습니다.
이러한 문제를 해결하기 위해, SVD의 변형 알고리즘들이 제안되었고, 이들 중에서도 truncated SVD, randomized SVD 등이 널리 사용됩니다.

 

통계 기반 학습 VS 추론 기반 기법
통계 기반 학습은 대체로 학습 데이터를 한꺼번에 처리하는 배치 학습(batch learning) 방식을 사용합니다.
이 방식에서는 전체 학습 데이터를 한 번에 모두 처리하고 그 결과를 바탕으로 가중치를 갱신합니다.
이에 비해 추론 기반 기법은 학습 데이터의 일부를 사용하여 순차적으로 학습하는 미니배치(mini-batch) 학습 방식을 사용합니다.
이 방식에서는 전체 학습 데이터를 작은 묶음으로 나누어 순차적으로 처리하며, 각 미니배치의 결과를 바탕으로 가중치를 갱신합니다.

 

데이터를 작게 나눠 학습하기에 계산량이 큰 작업일때에도 신경망을 학습할 수 있습니다.

병렬 계산도 가능해져서 학습 속도를 높일 수도 있습니다.

추론 기반 기법
추론 기반 기법은 학습 데이터를 작게 나누어서(minibatch) 학습하는 방식을 취하므로 계산량이 큰 작업일 경우에도 학습이 가능합니다.
또한, 이 방식은 병렬 계산이 가능하므로 학습 속도를 높일 수도 있습니다.
하지만, 일부 데이터만 사용하여 학습을 진행하므로 정확도가 조금 낮을 수 있습니다.

 

2.추론 기반 기법 개요

추론 기반 기법
추론 기반 기법은 맥락 정보를 입력받아서 해당 단어의 출현 확률을 출력하는 모델을 학습합니다.
이 모델의 핵심은 단어의 분산 표현을 얻는 것입니다.
맥락 정보를 이용해 단어의 의미를 추론하고, 이를 통해 단어를 벡터로 나타냅니다.
이러한 단어 벡터를 임베딩이라고 하며, 이를 이용해 다양한 자연어 처리 작업을 수행할 수 있습니다.

 

3.신경망에서의 단어 처리

 

신경망에서의 단어 처리를 위해서는 단어를 '고정 길이의 벡터'로 변환해야 합니다.

 

단어 임베딩
신경망에서 단어를 처리하기 위해서는 단어를 벡터로 변환하는 작업이 필요합니다. 이를 흔히 '단어 임베딩'이라고 합니다.
단어 임베딩은 단어를 고정 길이의 실수 벡터로 변환하는 작업입니다.
이러한 작업은 단어의 의미를 보존하면서도 계산이 가능하도록 해줍니다.
이렇게 변환된 단어 벡터는 신경망의 입력층으로 들어가게 되며, 신경망은 이 벡터를 기반으로 학습됩니다.

 

대표적인 방법이 단어를 원핫one-hot 표현(원핫 벡터)로 변환하는 것입니다.

원핫 표현
원핫 표현은 각 단어를 모두 다른 벡터로 나타내는 방법 중 하나로, 각 단어마다 유일한 인덱스를 할당하고 해당 인덱스에만 1을 표시하고 나머지는 0으로 표시하는 벡터입니다.
이 방법으로 표현하면 단어간의 유사도를 표현할 수 없지만, 각 단어를 독립적인 개체로 취급하여 처리하는 것이 가능합니다.

 

단어는 텍스트, 단어 ID, 원핫 표현 형태로 나타낼 수 있습니다.

  • 텍스트: 단어를 문자열 형태로 표현한 것입니다.
  • 단어 ID: 단어마다 고유한 ID를 부여하여 숫자로 표현한 것입니다. 
  • 원핫 표현: 단어를 벡터로 표현한 것으로, 해당하는 단어의 위치만 1이고 나머지는 모두 0인 벡터입니다.

 

단어를 고정 길이 벡터로 변환하면 신경망의 입력층은 뉴런의 수를 '고정'할 수 있습니다.

이렇게 함으로써 신경망의 입력층의 크기를 일정하게 유지할 수 있어서, 모델 구현이나 모델의 성능을 개선하는 데 도움이 됩니다.

 

단어를 벡터로 나타낼 수 있고, 신경망을 구성하는 '계층'들은 벡터를 처리할 수 있습니다.

단어를 벡터로 나타낼 수 있는 이유는 단어의 의미를 벡터화하기 위해서입니다.
벡터화된 단어는 신경망을 구성하는 다양한 계층들에서 입력값으로 사용될 수 있습니다

 

편향을 이용하지 않는 완전연결계층은 '행렬 곱' 계산입니다.

편향(bias)을 이용하지 않는 완전연결계층(fully connected layer)
편향(bias)을 이용하지 않는 완전연결계층(fully connected layer)은 입력과 가중치 행렬의 곱을 통해 출력을 계산합니다.
입력 벡터와 가중치 행렬은 모두 2차원 배열 형태이며, 이를 곱한 결과는 다시 2차원 배열 형태의 출력 벡터가 됩니다.
이때, 편향을 이용하지 않는 것이므로 편향의 크기는 입력의 크기와 같습니다.

 

 

 

NumPy를 사용하여 단어 벡터와 가중치 행렬을 곱해 은닉층 벡터를 계산하는 예시입니다.
c는 입력 단어를 one-hot encoding한 벡터로서, 해당 단어의 인덱스에만 1의 값을 가지고 나머지는 0입니다.
w는 가중치 행렬로서, 입력 단어의 크기와 은닉층의 크기를 결정합니다. 
h는 입력 단어 벡터 c와 가중치 행렬 w를 곱한 결과입니다.
이 값은 은닉층 벡터로서, 입력 단어와 가중치 행렬 사이의 관계를 나타냅니다.

 

 

편향을 이용하지 않는 완전연결계층을 나타냅니다.
입력값과 가중치 사이의 행렬 곱을 계산하며, 입력값의 형상이 (N, D), 가중치의 형상이 (D, H)일 때 출력값의 형상은 (N, H)가 됩니다.
def __init__(self,W):
self.params = [W]
self.grads = [np.zeros_like(W)]
self.x = None
이 코드는 완전 연결층의 초기화를 담당하는 코드입니다.
  • W: 가중치 매개변수
  • grads: W의 그래디언트 리스트
  • x: 순전파 시의 입력 값
np.zeros_like()
np.zeros_like는 인자로 받은 배열과 같은 크기의 0으로 이루어진 배열을 반환하는 NumPy 함수입니다.

 

def forward(self,x):
W, = self.params
out = np.matmul(x,W)
self.x = x return out
forward 메서드는 입력 벡터와 가중치 행렬의 행렬 곱을 계산하여 출력을 반환합니다.
  • x: 입력 데이터
  • W, : 가중치 행렬
  • out: 출력 데이터
  • self.x: 역전파 때 사용하기 위해 입력 데이터를 인스턴스 변수에 저장합니다.
W, = self.params
W, = self.params는 리스트 self.params에서 첫번째 원소를 W로 언패킹하는 것입니다.
리스트에서 값을 언패킹하면서 변수를 할당하는 것을 리스트 언패킹(unpacking)이라고 합니다.
리스트의 길이가 1일 경우에만 가능합니다.
self.params가 2개 이상의 원소를 가지고 있다면, 원소 개수만큼 변수를 지정해줘야 합니다.
self
self는 파이썬에서 인스턴스 메소드에서 자신을 가리키는 키워드입니다.
클래스 내에서 self를 이용하여 인스턴스 변수에 접근하거나, 다른 메소드를 호출하거나, 클래스 변수에 접근할 수 있습니다.

 

def backward(self,dout):
W, = self.params
dx = np.matmul(dout, W.T)
dw = np.matmul(self.x.T,dout)
self.grads[0][...] = dw return dx
이 코드는 MatMul 클래스의 backward 메서드입니다.
backward 메서드는 출력에 대한 손실의 기울기(dout)를 입력으로 받아, 입력과 가중치 행렬에 대한 손실의 기울기를 계산하고 반환합니다.
이 때, 입력 벡터와 가중치 행렬의 기울기를 self.grads 리스트에 저장하고, 이를 이용하여 가중치 갱신을 수행할 수 있습니다.

 

 

 

  1. numpy 모듈과 sys 모듈을 가져옵니다.
  2. sys.path.append('..') 코드를 이용해 부모 디렉토리의 모듈을 가져올 수 있도록 설정합니다.
  3. numpy 배열 c를 생성합니다.
  4. 가중치 행렬 W를 생성합니다.
  5. MatMul 클래스의 인스턴스 layer를 생성합니다.
  6. 입력 벡터 c를 layer에 입력하여 출력 벡터 h를 얻습니다.
  7. h를 출력합니다.

 

 

 

 

'딥러닝 > [밑바닥부터 시작하는 딥러닝]딥러닝' 카테고리의 다른 글

단순한 word2vec  (0) 2023.03.17