์ฑ์จ ๊ตญ์ ๋ถ๋ฅ ๋ฐ์ดํฐ์
๋ค์ด๋ก๋
ย
ย
์ด๋ฒ ์ฅ์์๋ RNN์ ์ด์ฉํ ์ฑ์จ ๊ตญ์ ๋ถ๋ฅ ์์ ๋ฅผ ์งํํ๋ฉฐ RNN์ ๊ธฐ๋ณธ ์ฑ์ง๊ณผ ์์ ๊ณต๋ถํ ์๋ง RNN ๋ชจ๋ธ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด๊ฒ ์ต๋๋ค.
ย
ํ์ดํ ์น์ ๋ฏธ๋๋ฐฐ์น ํ์ดํ๋ผ์ธ
ํ์ดํ ์น์์๋ NLP ์ฒ๋ฆฌ๋ฅผ ์ํด ์ฃผ์ด์ง ํ
์คํธ๋ฅผ ์ผ๋ จ์ ๊ณผ์ ์ ๊ฑฐ์ณ ๋ฏธ๋๋ฐฐ์น(mini-batch)ํํ๋ก ๋ณํํ์ฌ ๋ชจ๋ธ์ ์
๋ ฅ์ผ๋ก ์ ๋ฌํฉ๋๋ค. ์ด ๊ณผ์ ์๋ ํ
์คํธ์ ํ ํฐํ, ๋ฒกํฐํ, ๋ฏธ๋๋ฐฐ์น๋ก ๋ชจ์ผ๋ ๊ณผ์ ์ ๋ชจ๋ ํฌํจํฉ๋๋ค. ์ฆ, ๋ฏธ๋๋ฐฐ์น ํ์ดํ๋ผ์ธ์ด๋ ๋ชจ๋ธ์๊ฒ ์ฌ์ฉ์ ์ ์ ๋ฐ์ดํฐ์
์ ์
๋ ฅํ๊ธฐ ์ํ ์ ์ฒ๋ฆฌ ๊ณผ์ ์ด๋ผ๊ณ ๋ณผ ์ ์์ต๋๋ค. ์ฌ์ฉ์ ์ ์ ๋ฐ์ดํฐ์
์ ํ์ดํ๋ผ์ธ์ ์ ์ฉํ๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- Dataset ์๋ก์ด ๋ฐ์ดํฐ์ ์ ์ ๋ฐ ์์ฑ
- Vocabulary ๋ฐ์ดํฐ์ ์ ํ ํฐ์ ์ ์๋ก ๋งคํํ๊ธฐ
- Vectorizer Vocabulary๋ฅผ ์ฐธ๊ณ ํด ๋ฐ์ดํฐ์ ์ ํ ํฐ์ ์ ์๋ก ๋ณํํ์ฌ ๋ฒกํฐํํ๊ธฐ
- DataLoader Vectorizer๊ฐ ๋ณํํ ๋ฒกํฐ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์ ๋ฏธ๋๋ฐฐ์น๋ก ๋ง๋ค๊ธฐ
ย
๊ฐ๊ฐ์ ๋ชจ๋์ ๋ํ ์ค๋ช
๊ณผ ์ฝ๋๋ฅผ ์์๋๋ก ์๋์ ์์ฑํด๋์์ต๋๋ค. ์์ค์ฝ๋์ ๊ฒฝ์ฐ, ํ ๊ธ๋ฒํผ์ ๋๋ฅด๋ฉด ํ์ธํ ์ ์์ต๋๋ค.
ย
1. Dataset
ํ์ดํ ์น์์๋ ์๋ก์ด ๋ฐ์ดํฐ์
์ ์ฌ์ฉํ๊ธฐ ์ํด
Dataset
ํด๋์ค๋ฅผ ์์ํ๊ณ __init()__
, __getitem__()
, __len__()
3๊ฐ์ ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค. ์๋ก์ด ๋ฐ์ดํฐ์
์ธ SurnameDataset
ํด๋์ค์ ํ์ํ ๊ฐ๋ค์ __init__()
ํจ์๋ฅผ ํตํด ์ ์ธํ๊ณ , ํ์ํ ๋งค์๋๋ฅผ ๊ตฌํํด๋ด
์๋ค.ย
๋ฐ์ดํฐ์
์์ค์ฝ๋
from argparse import Namespace import os import json import numpy as np import pandas as pd import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.data import Dataset, DataLoader import tqdm class SurnameDataset(Dataset): def __init__(self, surname_df, vectorizer): """ ๋งค๊ฐ๋ณ์: surname_df (pandas.DataFrame): ๋ฐ์ดํฐ์ vectorizer (SurnameVectorizer): ๋ฐ์ดํฐ์ ์์ ๋ง๋ Vectorizer ๊ฐ์ฒด """ self.surname_df = surname_df self._vectorizer = vectorizer self._max_seq_length = max(map(len, self.surname_df.surname)) + 2 self.train_df = self.surname_df[self.surname_df.split=='train'] self.train_size = len(self.train_df) self.val_df = self.surname_df[self.surname_df.split=='val'] self.validation_size = len(self.val_df) self.test_df = self.surname_df[self.surname_df.split=='test'] self.test_size = len(self.test_df) self._lookup_dict = {'train': (self.train_df, self.train_size), 'val': (self.val_df, self.validation_size), 'test': (self.test_df, self.test_size)} self.set_split('train') # ํด๋์ค ๊ฐ์ค์น class_counts = self.train_df.nationality.value_counts().to_dict() def sort_key(item): return self._vectorizer.nationality_vocab.lookup_token(item[0]) sorted_counts = sorted(class_counts.items(), key=sort_key) frequencies = [count for _, count in sorted_counts] self.class_weights = 1.0 / torch.tensor(frequencies, dtype=torch.float32) @classmethod def load_dataset_and_make_vectorizer(cls, surname_csv): """๋ฐ์ดํฐ์ ์ ๋ก๋ํ๊ณ ์๋ก์ด Vectorizer ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค ๋งค๊ฐ๋ณ์: surname_csv (str): ๋ฐ์ดํฐ์ ์ ์์น ๋ฐํ๊ฐ: SurnameDataset์ ๊ฐ์ฒด """ surname_df = pd.read_csv(surname_csv) train_surname_df = surname_df[surname_df.split=='train'] return cls(surname_df, SurnameVectorizer.from_dataframe(train_surname_df)) @classmethod def load_dataset_and_load_vectorizer(cls, surname_csv, vectorizer_filepath): """ ๋ฐ์ดํฐ์ ๊ณผ ์๋ก์ด Vectorizer ๊ฐ์ฒด๋ฅผ ๋ก๋ํฉ๋๋ค. ์บ์๋ Vectorizer ๊ฐ์ฒด๋ฅผ ์ฌ์ฌ์ฉํ ๋ ์ฌ์ฉํฉ๋๋ค. ๋งค๊ฐ๋ณ์: surname_csv (str): ๋ฐ์ดํฐ์ ์ ์์น vectorizer_filepath (str): Vectorizer ๊ฐ์ฒด์ ์ ์ฅ ์์น ๋ฐํ๊ฐ: SurnameDataset์ ์ธ์คํด์ค """ surname_df = pd.read_csv(surname_csv) vectorizer = cls.load_vectorizer_only(vectorizer_filepath) return cls(surname_df, vectorizer) @staticmethod def load_vectorizer_only(vectorizer_filepath): """ํ์ผ์์ Vectorizer ๊ฐ์ฒด๋ฅผ ๋ก๋ํ๋ ์ ์ ๋ฉ์๋ ๋งค๊ฐ๋ณ์: vectorizer_filepath (str): ์ง๋ ฌํ๋ Vectorizer ๊ฐ์ฒด์ ์์น ๋ฐํ๊ฐ: SurnameVectorizer์ ์ธ์คํด์ค """ with open(vectorizer_filepath) as fp: return SurnameVectorizer.from_serializable(json.load(fp)) def save_vectorizer(self, vectorizer_filepath): """Vectorizer ๊ฐ์ฒด๋ฅผ json ํํ๋ก ๋์คํฌ์ ์ ์ฅํฉ๋๋ค ๋งค๊ฐ๋ณ์: vectorizer_filepath (str): Vectorizer ๊ฐ์ฒด์ ์ ์ฅ ์์น """ with open(vectorizer_filepath, "w") as fp: json.dump(self._vectorizer.to_serializable(), fp) def get_vectorizer(self): """ ๋ฒกํฐ ๋ณํ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค """ return self._vectorizer def set_split(self, split="train"): self._target_split = split self._target_df, self._target_size = self._lookup_dict[split] def __len__(self): return self._target_size def __getitem__(self, index): """ํ์ดํ ์น ๋ฐ์ดํฐ์ ์ ์ฃผ์ ์ง์ ๋ฉ์๋ ๋งค๊ฐ๋ณ์: index (int): ๋ฐ์ดํฐ ํฌ์ธํธ ์ธ๋ฑ์ค ๋ฐํ๊ฐ: ๋ค์ ๊ฐ์ ๋ด๊ณ ์๋ ๋์ ๋๋ฆฌ: ํน์ฑ (x_data) ๋ ์ด๋ธ (y_target) ํน์ฑ ๊ธธ์ด (x_length) """ row = self._target_df.iloc[index] surname_vector, vec_length = \ self._vectorizer.vectorize(row.surname, self._max_seq_length) nationality_index = \ self._vectorizer.nationality_vocab.lookup_token(row.nationality) return {'x_data': surname_vector, 'y_target': nationality_index, 'x_length': vec_length} def get_num_batches(self, batch_size): """๋ฐฐ์น ํฌ๊ธฐ๊ฐ ์ฃผ์ด์ง๋ฉด ๋ฐ์ดํฐ์ ์ผ๋ก ๋ง๋ค ์ ์๋ ๋ฐฐ์น ๊ฐ์๋ฅผ ๋ฐํํฉ๋๋ค ๋งค๊ฐ๋ณ์: batch_size (int) ๋ฐํ๊ฐ: ๋ฐฐ์น ๊ฐ์ """ return len(self) // batch_size def generate_batches(dataset, batch_size, shuffle=True, drop_last=True, device="cpu"): """ ํ์ดํ ์น DataLoader๋ฅผ ๊ฐ์ธ๊ณ ์๋ ์ ๋๋ ์ดํฐ ํจ์. ๊ฑฑ ํ ์๋ฅผ ์ง์ ๋ ์ฅ์น๋ก ์ด๋ํฉ๋๋ค. """ dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last) for data_dict in dataloader: out_data_dict = {} for name, tensor in data_dict.items(): out_data_dict[name] = data_dict[name].to(device) yield out_data_dict
ย
2. Vocabulary
Vocabulary๋ ๋ฐ์ดํฐ์
์ ๊ฐ ๋ฌธ์ ํ ํฐ๋ค์ด ๊ณ ์ ํ ์ ์๊ฐ์ ๋งคํ๋๋๋ก ํ๋ ์์
์
๋๋ค. ๋์
๋๋ฆฌ ์๋ฃํ์ ์ด์ฉํด Vocabulary๋ฅผ ๊ด๋ฆฌํ๋๋ฐ, ํ๋์ ๋์
๋๋ฆฌ๋ ๋ฌธ์๋ฅผ ์ ์ ์ธ๋ฑ์ค์ ๋งคํํ๊ณ ๋๋จธ์ง ๋์
๋๋ฆฌ๋ ์ ์ ์ธ๋ฑ์ค๋ฅผ ๋ฌธ์์ ๋งคํํฉ๋๋ค.
ย
๋ณธ ์์ ์์๋ Vocabulary๋ฅผ ์์ํ๋ SequenceVocabulary๋ฅผ ๋ง๋ญ๋๋ค. ํ์ต ๊ณผ์ ์์ ํ ๋ฒ๋ ๋ณธ ์ ์๋ ๋จ์ด๊ฐ ํ
์คํธ ๊ณผ์ ์์ ์
๋ ฅ๋ ๊ฒฝ์ฐ์๋ Vocabulary์์ ๋์๋๋ ์ ์๊ฐ์ ์ฐพ์ ์ ์์ต๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ์ ๋ํด์๋ ์ปค๋ฒํ๊ธฐ ์ํด SequenceVocabulary์์๋ UNK(unknown)๊ณผ ๊ฐ์ ๋ค์ํ ํน์ ํ ํฐ์ ํ์ฉํฉ๋๋ค.
unk_token
: ํ์ต ๊ณผ์ ์์ ๋ณด์ง ๋ชปํด ์ดํ ์ฌ์ ์ ์๋ ๋จ์ด๊ฐ ์ ๋ ฅ์ผ๋ก ๋ค์ด์จ ๊ฒฝ์ฐ UNK ํ ํฐ์ผ๋ก ์ฒ๋ฆฌ
mask_token
: ๊ฐ๋ณ ๊ธธ์ด์ ์ ๋ ฅ์ ์ฒ๋ฆฌํ ๋ MASK ํ ํฐ์ ์ฌ์ฉ
begin_seq_token
: ๋ฌธ์ฅ ์์์ BEGIN ํ ํฐ์ ๋ถ์ฌ ๋ชจ๋ธ์ด ๋ฌธ์ฅ ๊ฒฝ๊ณ๋ฅผ ์ธ์ํ๋๋ก ํจ
end_seq_token
: ๋ฌธ์ฅ ์์์ END ํ ํฐ์ ๋ถ์ฌ ๋ชจ๋ธ์ด ๋ฌธ์ฅ ๊ฒฝ๊ณ๋ฅผ ์ธ์ํ๋๋ก ํจ
ย
Vocabulary ์์ค์ฝ๋
class Vocabulary(object): """๋งคํ์ ์ํด ํ ์คํธ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ดํ ์ฌ์ ์ ๋ง๋๋ ํด๋์ค """ def __init__(self, token_to_idx=None): """ ๋งค๊ฐ๋ณ์: token_to_idx (dict): ๊ธฐ์กด ํ ํฐ-์ธ๋ฑ์ค ๋งคํ ๋์ ๋๋ฆฌ """ if token_to_idx is None: token_to_idx = {} self._token_to_idx = token_to_idx self._idx_to_token = {idx: token for token, idx in self._token_to_idx.items()} def to_serializable(self): """ ์ง๋ ฌํํ ์ ์๋ ๋์ ๋๋ฆฌ๋ฅผ ๋ฐํํฉ๋๋ค """ return {'token_to_idx': self._token_to_idx} @classmethod def from_serializable(cls, contents): """ ์ง๋ ฌํ๋ ๋์ ๋๋ฆฌ์์ Vocabulary ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค """ return cls(**contents) def add_token(self, token): """ ํ ํฐ์ ๊ธฐ๋ฐ์ผ๋ก ๋งคํ ๋์ ๋๋ฆฌ๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค ๋งค๊ฐ๋ณ์: token (str): Vocabulary์ ์ถ๊ฐํ ํ ํฐ ๋ฐํ๊ฐ: index (int): ํ ํฐ์ ์์ํ๋ ์ ์ """ if token in self._token_to_idx: index = self._token_to_idx[token] else: index = len(self._token_to_idx) self._token_to_idx[token] = index self._idx_to_token[index] = token return index def add_many(self, tokens): """ํ ํฐ ๋ฆฌ์คํธ๋ฅผ Vocabulary์ ์ถ๊ฐํฉ๋๋ค. ๋งค๊ฐ๋ณ์: tokens (list): ๋ฌธ์์ด ํ ํฐ ๋ฆฌ์คํธ ๋ฐํ๊ฐ: indices (list): ํ ํฐ ๋ฆฌ์คํธ์ ์์๋๋ ์ธ๋ฑ์ค ๋ฆฌ์คํธ """ return [self.add_token(token) for token in tokens] def lookup_token(self, token): """ํ ํฐ์ ๋์ํ๋ ์ธ๋ฑ์ค๋ฅผ ์ถ์ถํฉ๋๋ค. ๋งค๊ฐ๋ณ์: token (str): ์ฐพ์ ํ ํฐ ๋ฐํ๊ฐ: index (int): ํ ํฐ์ ํด๋นํ๋ ์ธ๋ฑ์ค """ return self._token_to_idx[token] def lookup_index(self, index): """ ์ธ๋ฑ์ค์ ํด๋นํ๋ ํ ํฐ์ ๋ฐํํฉ๋๋ค. ๋งค๊ฐ๋ณ์: index (int): ์ฐพ์ ์ธ๋ฑ์ค ๋ฐํ๊ฐ: token (str): ์ธํ ์ค์ ํด๋นํ๋ ํ ํฐ ์๋ฌ: KeyError: ์ธ๋ฑ์ค๊ฐ Vocabulary์ ์์ ๋ ๋ฐ์ํฉ๋๋ค. """ if index not in self._idx_to_token: raise KeyError("the index (%d) is not in the Vocabulary" % index) return self._idx_to_token[index] def __str__(self): return "<Vocabulary(size=%d)>" % len(self) def __len__(self): return len(self._token_to_idx) class SequenceVocabulary(Vocabulary): def __init__(self, token_to_idx=None, unk_token="<UNK>", mask_token="<MASK>", begin_seq_token="<BEGIN>", end_seq_token="<END>"): super(SequenceVocabulary, self).__init__(token_to_idx) self._mask_token = mask_token self._unk_token = unk_token self._begin_seq_token = begin_seq_token self._end_seq_token = end_seq_token self.mask_index = self.add_token(self._mask_token) self.unk_index = self.add_token(self._unk_token) self.begin_seq_index = self.add_token(self._begin_seq_token) self.end_seq_index = self.add_token(self._end_seq_token) def to_serializable(self): contents = super(SequenceVocabulary, self).to_serializable() contents.update({'unk_token': self._unk_token, 'mask_token': self._mask_token, 'begin_seq_token': self._begin_seq_token, 'end_seq_token': self._end_seq_token}) return contents def lookup_token(self, token): """ ํ ํฐ์ ๋์ํ๋ ์ธ๋ฑ์ค๋ฅผ ์ถ์ถํฉ๋๋ค. ํ ํฐ์ด ์์ผ๋ฉด UNK ์ธ๋ฑ์ค๋ฅผ ๋ฐํํฉ๋๋ค. ๋งค๊ฐ๋ณ์: token (str): ์ฐพ์ ํ ํฐ ๋ฐํ๊ฐ: index (int): ํ ํฐ์ ํด๋นํ๋ ์ธ๋ฑ์ค ๋ ธํธ: UNK ํ ํฐ์ ์ฌ์ฉํ๋ ค๋ฉด (Vocabulary์ ์ถ๊ฐํ๊ธฐ ์ํด) `unk_index`๊ฐ 0๋ณด๋ค ์ปค์ผ ํฉ๋๋ค. """ if self.unk_index >= 0: return self._token_to_idx.get(token, self.unk_index) else: return self._token_to_idx[token]
ย
3. Vectorizer
Vectorizer๋ ์์ ์ ์ํ SequenceVocabulary ๊ฐ์ฒด๋ฅผ ํ์ฉํฉ๋๋ค. Vectorizer๋ Vocabulary์์ ๋จ์ด์ ๋ํ ์ ์ ์ธ๋ฑ์ค๋ฅผ ๋ฐ์์ ๋ฒกํฐํ๋ฅผ ์งํํฉ๋๋ค. ๋ฒกํฐํ๋ ๋ฌธ์ฅ ๋จ์(๋๋ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ํ์ค ๊ธธ์ด ๋จ์)๋ก ์งํ๋ฉ๋๋ค. ๋ฒกํฐํ์ ๊ฒฐ๊ณผ๋ก ๋์จ ๋ฒกํฐ์ ๊ธธ์ด๋ ํญ์ ๊ฐ์์ผํ๋ฏ๋ก, ๋น ์๋ฆฌ์ 0์ ์ฑ์๋ฃ๋ ํจ๋ฉ ๋ฑ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํฉ๋๋ค. ์๋์์ ๋ฒกํฐํ ๊ณผ์ ์ ์์๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
[์์] ์๋ฌธ : I Love Deep Daiv -> ์ ์ ๋งคํ : 1 5 7 6 -> ํ ํฐ ๋ถ์ฌ : 8 1 5 7 6 9 (BEGIN, END ํ ํฐ์ 8, 9 ๋ผ๊ณ ํ์) -> ๋ฒกํฐ ํจ๋ฉ : 8 1 5 7 6 9 0 0 (ํ ๋ฒ์ ์ฒ๋ฆฌํ๋ ๊ธธ์ด๊ฐ 8์ผ ๋, ๋จ์ ์๋ฆฌ 0์ผ๋ก ์ฑ์ฐ๊ธฐ)
ย
Vectorizer์์ Vocabulary ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์, Vocabulary๊ฐ ๊ฐ์ง ์ ์๋ ๋จ์ด์ ๊ฐ์๋ฅผ ์ ํํ๊ฑฐ๋ ํน์ ํ ์๊ณ๊ฐ์ ์ง์ ํด ํ ๋๋ฒ ๋ฑ์ฅํ๋ ๋จ์ด๋ฅผ Vocabulary์ ๋ฑ๋กํ์ง ์๋ ๋ฑ์ ๋ฐฉ๋ฒ์ผ๋ก ๋จ์ด ๋
ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ๋ ์ญํ ๋ ์ํํฉ๋๋ค.
ย
Vectorizer ์์ค์ฝ๋
class SurnameVectorizer(object): """ ์ดํ ์ฌ์ ์ ์์ฑํ๊ณ ๊ด๋ฆฌํฉ๋๋ค """ def __init__(self, char_vocab, nationality_vocab): """ ๋งค๊ฐ๋ณ์: char_vocab (Vocabulary): ๋ฌธ์๋ฅผ ์ ์๋ก ๋งคํํฉ๋๋ค nationality_vocab (Vocabulary): ๊ตญ์ ์ ์ ์๋ก ๋งคํํฉ๋๋ค """ self.char_vocab = char_vocab self.nationality_vocab = nationality_vocab def vectorize(self, surname, vector_length=-1): """ ๋งค๊ฐ๋ณ์: title (str): ๋ฌธ์์ด vector_length (int): ์ธ๋ฑ์ค ๋ฒกํฐ์ ๊ธธ์ด๋ฅผ ๋ง์ถ๊ธฐ ์ํ ๋งค๊ฐ๋ณ์ """ indices = [self.char_vocab.begin_seq_index] indices.extend(self.char_vocab.lookup_token(token) for token in surname) indices.append(self.char_vocab.end_seq_index) if vector_length < 0: vector_length = len(indices) out_vector = np.zeros(vector_length, dtype=np.int64) out_vector[:len(indices)] = indices out_vector[len(indices):] = self.char_vocab.mask_index return out_vector, len(indices) @classmethod def from_dataframe(cls, surname_df): """๋ฐ์ดํฐ์ ๋ฐ์ดํฐํ๋ ์์ผ๋ก SurnameVectorizer ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ๋งค๊ฐ๋ณ์: surname_df (pandas.DataFrame): ์ฑ์จ ๋ฐ์ดํฐ์ ๋ฐํ๊ฐ: SurnameVectorizer ๊ฐ์ฒด """ char_vocab = SequenceVocabulary() nationality_vocab = Vocabulary() for index, row in surname_df.iterrows(): for char in row.surname: char_vocab.add_token(char) nationality_vocab.add_token(row.nationality) return cls(char_vocab, nationality_vocab) @classmethod def from_serializable(cls, contents): char_vocab = SequenceVocabulary.from_serializable(contents['char_vocab']) nat_vocab = Vocabulary.from_serializable(contents['nationality_vocab']) return cls(char_vocab=char_vocab, nationality_vocab=nat_vocab) def to_serializable(self): return {'char_vocab': self.char_vocab.to_serializable(), 'nationality_vocab': self.nationality_vocab.to_serializable()}
ย
4. DataLoader
DataLoader๋ Vectorizer์์ ๋ฒกํฐ๋ก ๋ณํํ ๋ฐ์ดํฐ ํฌ์ธํธ๋ค์ ๋ฏธ๋๋ฐฐ์น๋ก ๋ชจ์ ์์
์ ํธ๋ฆฌํ๊ฒ ํด์ค๋๋ค. DataLoader๊ฐ ์์ฑํ ๋ฏธ๋๋ฐฐ์น๋ฅผ ํตํด ๋ถ๋ฅ, ๋ถ์ ๋ชจ๋ธ๋ค์ด ํ์ต๊ณผ ํ
์คํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
ย
๋ฏธ๋๋ฐฐ์น๋ ํ์ต๊ณผ ํ
์คํธ์ ๋ฐ์ดํฐ ์ ์ฒด๋ฅผ ํ์ฉํ์ง ์๊ณ ์ผ๋ถ๋ง์ ํ์ฉํด ๋ ๋น ๋ฅด๊ฒ ๋ชจ๋ธ์ ๊ฐ์ค์น๋ฅผ ์ต์ ํ์ํค๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ ๋ ์์ ๋จ์๋ก ์ชผ๊ฐ ๊ฒ์ ๋งํฉ๋๋ค. ์๋ ๋งํฌ์์ ๋ฏธ๋๋ฐฐ์น์ ๋ํด ์ฝ์ด๋ณด์ธ์.
ย
DataLoader ์์ค์ฝ๋
def generate_batches(dataset, batch_size, shuffle=True, drop_last=True, device="cpu"): """ ํ์ดํ ์น DataLoader๋ฅผ ๊ฐ์ธ๊ณ ์๋ ์ ๋๋ ์ดํฐ ํจ์. ๊ฑฑ ํ ์๋ฅผ ์ง์ ๋ ์ฅ์น๋ก ์ด๋ํฉ๋๋ค. """ dataloader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last) for data_dict in dataloader: out_data_dict = {} for name, tensor in data_dict.items(): out_data_dict[name] = data_dict[name].to(device) yield out_data_dict
ย
์ด์ ๊ธ ์ฝ๊ธฐ
Dictionary ์๋ฃํ
key์ value๊ฐ 1๋1๋ก ์์ ์์ด ๋งคํ๋๋ ํํ์ ์๋ฃํ
โbananaโ๋ผ๋ ๋ฌธ์์ด์ value๋ก ํ๊ณ , ์ซ์ โ5โ๋ฅผ key๋ก ํ์ฌ ๋์
๋๋ฆฌ์ ์ ์ฅํ ๊ฒฝ์ฐ, key ๊ฐ์ธ 5๋ฅผ ํตํด โbananaโ value๋ฅผ ๋ฐ์์ฌ ์ ์๋ค.
[์์]
dict = {5 : โbananaโ}
dict[5]
>>> banana