반응형

 

1. 토큰화

컴퓨터는 사람처럼 텍스트를 직접 이해하거나 처리할 수 없습니다.

컴퓨터는 숫자 데이터를 처리하기 때문에, 텍스트 데이터를 처리하려면 숫자 형식으로 변환해야 합니다.

이 과정에서 중요한 역할을 하는 것이 바로 임베딩(Embedding)입니다.

임베딩은 텍스트 데이터를 일정한 크기의 숫자 벡터로 변환하여 모델이 학습할 수 있도록 돕는 기술입니다.

텍스트를 임베딩으로 변환하기 위해서는 크게 세 가지 단계가 필요합니다.

  1. 토큰화(Tokenization): 텍스트를 처리하기 전에 먼저 텍스트를 작은 단위인 토큰(Token)으로 분리합니다. 이 과정에서 문장은 단어 단위나 그보다 작은 서브워드(subword) 단위로 나누어집니다. 한글의 경우 자음과 모음으로 나눌 수도 있고, 영어는 단어 단위로 나누는 경우가 많습니다. 이렇게 나눈 각 단위에는 고유의 숫자 아이디(ID)가 부여됩니다.
  2. 토큰 임베딩(Token Embedding): 토큰화된 각각의 단어는 고유의 숫자 벡터로 변환됩니다. 이러한 숫자 벡터를 임베딩이라 하며, 단어를 일정한 크기의 숫자 벡터로 표현하여 컴퓨터가 이해할 수 있는 형태로 변환하는 것입니다. 각 단어는 임베딩 층을 통과하며 이 벡터 형태로 변환됩니다.
  3. 위치 인코딩(Positional Encoding): 단어의 순서는 매우 중요합니다. 특히 자연어에서는 단어가 배치된 순서에 따라 의미가 달라질 수 있습니다. 따라서, 트랜스포머에서는 각 단어의 위치 정보를 추가적으로 인코딩하여 문맥을 이해할 수 있도록 돕습니다. 이를 위치 인코딩이라 하며, 문장 내에서 단어가 어떤 위치에 있는지에 대한 정보를 벡터에 추가합니다.

이 세 가지 과정을 통해 텍스트는 모델이 처리할 수 있는 숫자 벡터로 변환됩니다.

트랜스포머 아키텍처에서 임베딩은 매우 중요한 역할을 하며, 문맥을 이해하고 정확한 예측을 하기 위해 필수적인 단계입니다.

토큰화 예제

# 띄어쓰기 단위로 분리
input_text = "나는 최근 제주도를 다녀왔다"
input_text_list = input_text.split()
print("input_text_list: ", input_text_list)

# 토큰 -> 아이디 딕셔너리와 아이디 -> 토큰 딕셔너리 만들기
str2idx = {word:idx for idx, word in enumerate(input_text_list)}
idx2str = {idx:word for idx, word in enumerate(input_text_list)}
print("str2idx: ", str2idx)
print("idx2str: ", idx2str)

# 토큰을 토큰 아이디로 변환
input_ids = [str2idx[word] for word in input_text_list]
print("input_ids: ", input_ids)


=====출력 결과=====
input_text_list:  ['나는', '최근', '제주도를', '다녀왔다']
str2idx:  {'나는': 0, '최근': 1, '제주도를': 2, '다녀왔다': 3}
idx2str:  {0: '나는', 1: '최근', 2: '제주도를', 3: '다녀왔다'}
input_ids:  [0, 1, 2, 3]

 

2. 토큰 임베딩으로 변환하기

딥러닝 모델이 텍스트 데이터를 처리하려면, 입력된 텍스트를 수치 데이터로 변환해야 합니다. 이 과정에서 토큰 임베딩이 사용됩니다.

토큰 임베딩은 입력 텍스트에서 각 단어(토큰)의 의미를 고유한 숫자 벡터로 나타낸 것입니다.

이를 통해 토큰들 사이의 관계를 계산하거나 의미를 추출할 수 있습니다.

임베딩(Embedding)은 고차원 공간에 있는 데이터를 저차원 공간으로 변환하여, 각 토큰의 의미를 벡터로 표현하는 방식입니다.

이 벡터는 학습 가능한 구조로 모델이 의미를 학습할 수 있게 하며, 토큰 간의 관계를 추론할 수 있도록 돕습니다.

임베딩을 위한 파이토치 예시

파이토치(PyTorch)에서 토큰 임베딩을 구현하는 방법은 비교적 간단합니다. 예를 들어, 파이토치의 nn.Embedding 클래스를 사용하면 토큰을 숫자 벡터로 변환할 수 있습니다. 코드는 다음과 같이 작성됩니다.

import torch
nn = torch.nn

# 토큰을 ID로 변환한 리스트
input_ids = [0, 1, 2, 3, 4]

# nn.Embedding 클래스 사용
embedding_dim = 16
embed_layer = nn.Embedding(5, embedding_dim)

# 임베딩된 벡터 출력
input_embeddings = embed_layer(torch.tensor(input_ids)).unsqueeze(0)
print(input_embeddings.shape)


=====출력 결과=====
torch.Size([1, 5, 16])

 

이 코드에서는 임베딩 차원을 16으로 설정했으며, 5개의 토큰을 임베딩 벡터로 변환했습니다. 결과적으로, 각 토큰은 16차원의 벡터로 표현됩니다.


토큰 임베딩의 역할

토큰 임베딩은 딥러닝 모델에서 중요한 역할을 수행합니다.

단순히 단어를 벡터로 변환하는 것이 아니라, 단어의 의미와 문맥을 학습할 수 있는 기회를 제공합니다.

예를 들어, "여행", "음식", "게임"과 같은 카테고리에 맞추어 텍스트를 분류할 때, 임베딩된 벡터가 각 단어의 의미를 잘 반영하여 학습을 돕습니다.

이와 같은 과정은 NLP(자연어 처리) 작업에서 필수적이며, 딥러닝 모델이 더 나은 성능을 발휘할 수 있도록 지원합니다.

 

3. 위치 인코딩

RNN과 트랜스포머의 가장 큰 차이점 중 하나는 입력된 데이터의 처리 방식입니다.

RNN은 입력을 순차적으로 처리하며, 단어의 순서 정보를 자연스럽게 유지할 수 있습니다.

그러나 트랜스포머는 병렬 처리 방식을 채택하여 모든 입력 데이터를 동시에 처리하기 때문에 단어의 순서 정보를 별도로 관리할 필요가 있습니다. 이때 중요한 역할을 하는 것이 바로 위치 인코딩(Position Encoding)입니다.

위치 인코딩은 입력된 각 단어의 위치 정보를 벡터에 추가하여 모델이 문장 내에서 단어의 순서를 인식할 수 있게 도와줍니다.

이를 통해 트랜스포머는 문맥을 더욱 정확하게 이해할 수 있으며, 자연어 처리 작업에서 탁월한 성능을 발휘할 수 있습니다.

절대적 위치 인코딩과 상대적 위치 인코딩

위치 인코딩에는 절대적 위치 인코딩(Absolute Position Encoding)과 상대적 위치 인코딩(Relative Position Encoding)의 두 가지 방식이 있습니다. 절대적 위치 인코딩은 각 단어의 고유한 위치를 절대적인 수치로 인코딩합니다. 예를 들어, 문장 내에서 첫 번째 단어, 두 번째 단어 등 각 단어의 고정된 위치 정보를 추가하는 방식입니다.

반면, 상대적 위치 인코딩은 단어들 간의 상대적인 위치를 인코딩합니다. 이는 문장의 길이가 달라지거나, 문장 구조가 변화해도 단어들 간의 상대적인 위치 관계는 유지될 수 있도록 돕습니다. 최근에는 상대적 위치 인코딩이 더 자주 사용되며, 트랜스포머 모델이 문장 구조에 더욱 유연하게 대응할 수 있게 만듭니다.

 

절대적 위치 인코딩 예제

embedding_dim = 16
max_position = 12

# 토큰 임베딩 층 생성
embed_layer = nn.Embedding(len(str2idx), embedding_dim)

# 위치 인코딩 층 생성
position_embed_layer = nn.Embedding(max_position, embedding_dim)

position_ids = torch.arange(len(input_ids), dtype=torch.long).unsqueeze(0)
position_encodings = position_embed_layer(position_ids)
token_embeddings = embed_layer(torch.tensor(input_ids)) # (5, 16)
token_embeddings = token_embeddings.unsqueeze(0) # (1, 5, 16)

# 토큰 임베딩과 위치 인코딩을 더해 최종 입력 임베딩 생성
input_embeddings = token_embeddings + position_encodings
input_embeddings.shape


=====출력 결과=====
torch.Size([1, 5, 16])
반응형

+ Recent posts