티스토리 뷰
Minibatch
모델에 넣기 위한 코퍼스의 최종 모양을 만들어줘야 할텐데, 그 tensor의 모양은 다음과 같다.

tensor를 보면, 몇 가지 문제점이 보인다.
- vocab이 sparse해지기 때문에 메모리의 낭비가 생긴다. 따라서 vocab을 one-hot vector가 아닌 index로 처리하는게 좋다.
- 문장의 길이가 다 다르기 때문에 극단적인 예로 어떤 문장은 두 단어로, 어떤 문장은 100단어로 구성되어있다면 오른쪽의 padding 토큰의 차이가 극명해지고, 계산 낭비가 이뤄진다.
2번의 문제를 해결하기 위해서는 length를 sorting하는 방법이 있다. 그리고 미니배치의 순서를 shuffling하면 된다.
실습 with TorchText
먼저 터미널을 통해서 tsv파일을 shuffle해줘야 하는데, 맥의 경우 gshuf 명령어를 사용한다. 명령어가 먹히지 않는다면 coreutils를 설치해준다.
# brew install coreutils
gshuf < review.sorted.uniq.refined.tok.tsv > review.sorted.uniq.refined.tok.shuf.tsv

약 30만 줄의 원본 문서를 27:3으로 train, test로 분리한다.
head -n 272680 ./review.sorted.uniq.refined.tok.shuf.tsv > review.sorted.uniq.refined.tok.shuf.train.tsv
tail -n 30000 ./review.sorted.uniq.refined.tok.shuf.tsv > review.sorted.uniq.refined.tok.shuf.test.tsv
TorchText를 통해서 데이터를 로딩해보자.
현재 torchtext의 모듈들은 legacy코드가 되어서 다음처럼 코드를 바꿔주어야 한다.
from torchtext.legacy import data
데이터를 로드하고, train/valid와 vocab, label을 확인해보자.
loaders = DataLoader(
train_fn='./review.sorted.uniq.refined.tok.shuf.train.tsv',
batch_size=256,
valid_ratio=.2,
device=-1,
max_vocab=999999,
min_freq=5,
)
print("|train|=%d" % len(loaders.train_loader.dataset))
print("|valid|=%d" % len(loaders.valid_loader.dataset))
print("|vocab|=%d" % len(loaders.text.vocab))
print("|label|=%d" % len(loaders.label.vocab))
# >> |train|=217998
# >> |valid|=54500
# >> |vocab|=17788
# >> |label|=2
train 약 27만 개를 알아서 8:2로 분할, train, valid로 나누어준다. label은 당연히 positive, negative 2개이다.
tensor shape을 살펴보자.
data = next(iter(loaders.train_loader))
print(data.text.shape)
print(data.label.shape)
# >> torch.Size([256, 30])
# >> torch.Size([256])
배치사이즈 256에 30단어의 미니배치가 만들어졌다.
vocab의 예시를 출력해보자.
print(loaders.text.vocab.itos[7777])
print(loaders.text.vocab.stoi['세라믹'])
# >> 세라믹
# >> 7777
vocab의 7777번째 단어는 세라믹이고, 세라믹은 7777번째 단어이다.
가장 빈번하게 나온 상위 30개의 단어를 출력해보자.
for i in range(30):
word = loaders.text.vocab.itos[i]
print('%5d: %s\t%d' % (i, word, loaders.text.vocab.freqs[word]))
# >> 0: <unk> 0
# >> 1: <pad> 0
# >> 2: . 261513
# >> 3: 고 149958
# >> 4: 이 143263
# >> 5: 하 123330
# >> 6: 도 101991
# >> 7: 네요 99382
# >> 8: 좋 96413
# >> 9: 에 92638
# >> 10: 는 86014
# >> 11: 가 70096
# >> 12: 은 65965
# >> 13: 는데 56838
# >> 14: 아요 54207
# >> 15: 게 54111
# >> 16: 잘 52760
# >> 17: 어요 50107
# >> 18: 배송 47572
# >> 19: 있 45092
# >> 20: 했 42339
# >> 21: 습니다 42169
# >> 22: 안 38552
# >> 23: 을 37697
# >> 24: 한 35808
# >> 25: ~ 34010
# >> 26: 구매 31619
# >> 27: 같 30130
# >> 28: 너무 29579
# >> 29: 거 29319
데이터의 예시를 보자.
print(data.text[-1])
# >> tensor([2514, 524, 6574, 11, 549, 8, 46, 94, 25, 900, 82, 74,
# 5, 60, 4085, 1205, 239, 3, 156, 17, 129, 594, 900, 23,
# 22, 5, 182, 153, 152, 1])
x = data.text[-1]
line = []
for x_i in x:
line += [loaders.text.vocab.itos[x_i]]
print(' '.join(line))
# >> 27 개월 딸내미 가 너무너무 좋 아 해요 ~ 딜 좀 많이 하 면 왕창 쟁여 놓 고 싶 어요 ㅋㅋ 그런데 딜 을 안 하 네 용 ㅠㅠ <pad>
이런식으로 모든 리뷰의 text classification을 하기 위한 정제와 벡터화를 완료하였다.
'Study > NLP' 카테고리의 다른 글
NLP with DeepLearning (7) - Word Embedding(Word2Vec) (0) | 2021.11.30 |
---|---|
NLP with DeepLearning (6) - Word Embedding(prev) (0) | 2021.11.25 |
NLP with DeepLearning (4) - Subword Segmentation (0) | 2021.11.23 |
NLP with DeepLearning (3) - Tokenization (0) | 2021.11.20 |
NLP with DeepLearning (2) - Corpus 정제 (0) | 2021.11.18 |
- Total
- Today
- Yesterday
- productresearch
- MLOps
- 스타트업
- ML
- torch
- DDUX
- productowner
- Tennis
- deeplearning
- dl
- PM
- 인공지능
- 쿠버네티스
- 전처리
- 도커
- 파이프라인
- Kubernetes
- mlpipeline
- 머신러닝
- productmanager
- nlp
- Oreilly
- 딥러닝
- 자연어처리
- PO
- Bert
- 머신러닝파이프라인
- container
- docker
- pmpo
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |