자연어 처리의 첫걸음, PyTorch와 TorchText로 데이터 마스터하기
안녕하세요! 개발하는 머리입니다. 최근 딥러닝을 활용한 자연어 처리(NLP) 기술이 정말 빠르게 발전하고 있죠. 챗GPT 같은 거대 언어 모델도 결국은 아주 기초적인 텍스트 데이터를 정제하고 학습하는 것에서부터 시작되었습니다. 하지만 막상 NLP 공부를 시작하려고 하면 텍스트 데이터를 어떻게 불러오고, 어떻게 컴퓨터가 이해할 수 있는 숫자로 바꿔야 하는지 막막할 때가 많습니다.
그래서 이번 포스팅에서는 PyTorch와 TorchText 라이브러리를 사용해서 NLP 데이터셋을 효율적으로 다루는 방법을 준비했습니다. 가장 대표적인 데이터셋인 IMDB를 활용해 데이터 로딩부터 전처리, 그리고 간단한 감성 분석 모델을 함께 만들어보겠습니다.

📌 핵심 요약 3줄
- torchtext.datasets를 사용하면 IMDB, AG_NEWS 등 대표적인 NLP 데이터셋을 몇 줄의 코드만으로 간편하게 다운로드하고 로드할 수 있습니다.
- 텍스트 데이터를 딥러닝 모델에 입력하기 위해서는 토큰화(Tokenization)와 수치화(Vocabulary 빌딩) 과정을 반드시 거쳐야 합니다.
- 전처리가 완료된 데이터는 DataLoader와 Dataset 객체를 통해 배치(Batch) 단위로 묶여 모델 학습에 활용됩니다.
1. 주요 NLP 데이터셋 개요
자연어 처리 모델을 학습할 때 자주 사용하는 대표적인 오픈소스 데이터셋들을 먼저 정리해 보겠습니다. 각 데이터셋은 해결하려는 문제의 유형에 따라 다르게 선택되어 사용됩니다.
| 데이터셋 이름 | 주요 용도 | 데이터 구성 특징 | 추천 학습 모델 |
| IMDB | 감성 분석 (Sentiment Analysis) | 25,000개의 영화 리뷰 텍스트 (긍정/부정 이진 분류) | RNN, LSTM, BERT 등 |
| AG_NEWS | 뉴스 기사 카테고리 분류 | 세계, 스포츠, 비즈니스, 과학/기술 (4개 클래스) | TextCNN, 변형 RNN 등 |
| SST-2 | Stanford Sentiment Treebank | 세밀한 감성 분석 및 문장 구조 분석 데이터 | Transformer 기반 모델 |
PyTorch에서는 torchtext.datasets 모듈을 통해 위 데이터셋들을 복잡한 다운로드 과정 없이 함수 호출 한 번으로 편리하게 불러올 수 있습니다.
2. PyTorch를 활용한 NLP 데이터셋 로딩
2.1 데이터셋 다운로드 및 로딩
가장 먼저 IMDB 영화 리뷰 데이터셋을 불러오는 방법입니다. 라이브러리를 불러온 뒤, 훈련(train) 데이터와 테스트(test) 데이터를 나누어 받습니다.
import torch
from torchtext.datasets import IMDB
# 데이터 로드 (train, test 분할)
train_iter, test_iter = IMDB(split=("train", "test"))
# 데이터 구조 확인을 위해 리스트로 변환 후 첫 번째 샘플 확인
train_list = list(train_iter)
label, text = train_list[0]
print(f"Label: {label}")
print(f"Text: {text[:100]}...") # 가독성을 위해 텍스트는 100자까지만 출력
코드를 실행하면 IMDB 데이터가 자동으로 로컬 환경에 다운로드됩니다. 텍스트와 함께 긍정(pos) 또는 부정(neg)을 나타내는 라벨이 매칭되어 있는 것을 볼 수 있습니다.
2.2 데이터 전처리 (토큰화 및 단어 사전 생성)
컴퓨터는 문자열 자체를 이해하지 못하므로, 문장을 단어 단위로 쪼개는 토큰화(Tokenization)와 각 단어에 고유한 숫자를 부여하는 단어 사전(Vocabulary) 구축이 필요합니다.
from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
# 1. 영어 기본 토크나이저 설정
tokenizer = get_tokenizer("basic_english")
# 2. 토큰을 생성하는 제너레이터 함수 정의
def yield_tokens(data_list):
for _, text in data_list:
yield tokenizer(text)
# 3. 단어 사전(Vocabulary) 생성 (알 수 없는 단어는 <unk>로 처리)
vocab = build_vocab_from_iterator(yield_tokens(train_list), specials=["<unk>"])
vocab.set_default_index(vocab["<unk>"])
# 4. 텍스트를 정수 인덱스 리스트로 변환하는 파이프라인 생성
text_pipeline = lambda x: vocab(tokenizer(x))
# 전처리 테스트
example_text = "This is a great movie!"
print("전처리 결과:", text_pipeline(example_text))
위 코드를 실행하면 "This is a great movie!"라는 문장이 [12, 10, 14, 92, 23, 5]와 같이 모델이 이해할 수 있는 정수 배열로 변환됩니다.
3. NLP 데이터셋 활용 예제: 간단한 감성 분석 모델 구현
이제 전처리된 데이터를 가지고 간단한 LSTM 기반의 감성 분석 모델을 만들어보겠습니다. 문장의 길이를 맞춰주는 패딩(Padding) 처리를 포함하여 실무 친화적인 코드로 작성했습니다.
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torch.nn.utils.rnn import pad_sequence
# 데이터 파이프라인 적용 함수
def collate_batch(batch):
label_list, text_list = [], []
for _label, _text in batch:
# 라벨 변경: 'pos' -> 1, 'neg' -> 0
label_list.append(1 if _label == 'pos' else 0)
# 텍스트를 텐서로 변환하여 추가
processed_text = torch.tensor(text_pipeline(_text), dtype=torch.int64)
text_list.append(processed_text)
label_list = torch.tensor(label_list, dtype=torch.float32)
# 문장 길이가 다르므로 패딩(0)을 채워 정렬 (batch_first=True)
text_list = pad_sequence(text_list, batch_first=True, padding_value=0)
return text_list, label_list
# 데이터로더 생성
train_loader = DataLoader(train_list, batch_size=32, shuffle=True, collate_fn=collate_batch)
# 감성 분석 LSTM 모델 정의
class SentimentRNN(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim, output_dim):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
self.rnn = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, text):
embedded = self.embedding(text)
_, (hidden, _) = self.rnn(embedded)
# LSTM의 마지막 은닉 상태(hidden state)를 사용해 예측
return self.fc(hidden[-1])
# 모델 학습 설정
model = SentimentRNN(len(vocab), 100, 128, 1)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.BCEWithLogitsLoss()
# 학습 루프
def train(model, data_loader, optimizer, criterion, epochs=3):
model.train()
for epoch in range(epochs):
total_loss = 0
for text, label in data_loader:
optimizer.zero_grad()
output = model(text).squeeze(1) # 차원 맞추기
loss = criterion(output, label)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss / len(data_loader):.4f}")
# 학습 시작
train(model, train_loader, optimizer, criterion)
🛠️ 개발을 위한 팁 (Tips)
- 사전 훈련된 임베딩(Word Embedding) 사용하기: 처음부터 임베딩 레이어를 학습시키는 것보다 FastText나 GloVe 같은 검증된 사전 학습 임베딩 가중치를 nn.Embedding.from_pretrained()로 로드해서 사용하면 모델의 초기 성능을 크게 올릴 수 있습니다.
- GPU 가속 필수 활용: 텍스트 데이터의 길이가 길어지면 RNN 연산 속도가 급격히 느려집니다. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') 코드를 추가하고 모델과 텐서를 반드시 .to(device)로 넘겨서 학습시키세요.
⚠️ 흔히 하는 실수 (Common Mistakes)
- Iterator 일회성 소모 실수: TorchText의 데이터셋 객체들은 제너레이터(Iterator) 형태로 동작합니다. 즉, for 루프를 한 번 돌거나 build_vocab_from_iterator에 집어넣으면 안의 데이터가 소모되어 텅 비게 됩니다. 안전하게 사용하려면 본문 코드처럼 list(train_iter) 형태로 리스트화해두고 재사용하는 것이 좋습니다.
- 패딩(Padding) 처리 누락: 미니 배치 내부의 문장 길이가 서로 다르면 텐서로 묶이지 않아 에러가 발생합니다. 반드시 DataLoader의 collate_fn을 활용하여 최장 문장 길이에 맞춰 pad_sequence 처리를 해주어야 합니다.
4. 결론
이번 포스팅에서는 PyTorch와 TorchText의 기초적인 활용법부터 시작해서 텍스트 전처리 알고리즘을 구축하고, 실제 감성 분석 모델에 데이터를 주입하는 전체적인 흐름을 알아봤습니다.
정형 데이터와 달리 자연어 데이터는 토큰화, 패딩 작업 등 거쳐야 할 전처리 단계가 많아서 까다롭지만, 구조를 한 번만 제대로 이해해 두면 다른 고급 모델(Transformer, BERT 등)에도 고스란히 적용할 수 있습니다. 오늘 다룬 내용을 바탕으로 더 깊이 있는 NLP 프로젝트에 도전해 보세요! 궁금한 점은 언제든 댓글로 남겨주세요.
'Python for AI, Embedded > Deep Learning: PyTorch & AI Modeling' 카테고리의 다른 글
| RNN을 넘어선 혁신, 트랜스포머(Transformer) 모델 구조와 핵심 개념 완벽 정리 (0) | 2026.05.19 |
|---|---|
| PyTorch로 시작하는 자연어 처리: IMDb 리뷰 감정 분석 및 텍스트 분류 완벽 가이드 (0) | 2026.05.18 |
| PyTorch RNN, LSTM, GRU 개념 완벽 정리: 구조부터 차이점까지 한눈에 보기 (0) | 2026.05.16 |
| PyTorch 이미지 분류 완벽 가이드: MNIST부터 CIFAR-10까지 한 번에 끝내기 (0) | 2026.05.15 |
| PyTorch로 시작하는 CNN 이미지 분류: 기초부터 실전 예제까지 (0) | 2026.05.14 |