파이토치에서 dataset 만들기

참고 자료

KLUE benchmark ner file

Dataset 만들기

  1. Dataset을 Preprosessing 작업하기
  2. Dataloader에 넣고 배치(batch) 단위로 만들기
  3. 필요 시 collate_funtion으로 작업하기
    [미니 배치를 생성하기 위해 샘플 리스트를 병합하는 역할 등]

collate_fn을 Dataset class가 아닌 function을 사용하는 이유

  • Class에서 구현은 가능함.
  • 그러나 디버깅 단계에서 index값이 아닌 str으로 확인하는게 편하하기 때문입니다.
    [== token index나 label index를 str로 변환해서 확인하는게 불편합니다.]

KLUE-benchmark dataset-NER을 기준으로 예시입니다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#허깅페이스의 load_data 전처리
def load_data(file_path: str, tokenizer: PreTrainedTokenizer = None):
klue_data = Path(file_path)
klue_text = klue_data.read_text().strip()
documents = klue_text.split("\n\n")

data_list = []
for doc in documents:
char_labels = []
token_labels = []
chars = []
sentence = ""
for line in doc.split("\n"):
if line.startswith("##"):
continue
token, tag = line.split("\t")
sentence += token
char_labels.append(tag)
chars.append(token)

offset_mappings = tokenizer(sentence, return_offsets_mapping=True)["offset_mapping"]
for offset in offset_mappings:
start, end = offset
if start == end == 0:
continue
token_labels.append(char_labels[start])

instance = {
"sentence": sentence,
"token_label": token_labels,
"char_label": char_labels,
"offset_mapping": offset_mappings
}
data_list.append(instance)

return data_list

labels = [
"B-PS",
"I-PS",
"B-LC",
"I-LC",
"B-OG",
"I-OG",
"B-DT",
"I-DT",
"B-TI",
"I-TI",
"B-QT",
"I-QT",
"O",
]

label2id = {label: i for i, label in enumerate(labels)}
id2label = {i: label for label, i in label2id.items()}

# Dataset
class NerDataset(Dataset):
def __init__(
self,
tokenizer: PreTrainedTokenizer,
examples: List,
shuffle: bool = False,
**kwargs
):
self.dataset = examples
self.tokenizer = tokenizer
self.max_length = max_length

def __len__(self):
return len(self.dataset)

def __getitem__(self, index):
instance = self.dataset[index]

return instance

tokenizer = AutoTokenizer.from_pretrained("klue/bert-base")
examples = load_data(file_path, tokenizer)

print(examples[0])
#{'sentence': '경찰은 또 .....

# dataset
dataset = NerDataset(
tokenizer=tokenizer,
examples=examples,
max_length=max_length
)

# dataloader, collate_fn
data_loader = DataLoader(
dataset=dataset,
collate_fn=collate_fn
)

# 이렇게하면 data_loader가 완성되어 전처리가 다 끝납니다.
# 이 데이터를 확인하기 위해서는 아래 코드 실행(1배치만 확인)

for batch in data_loader:
print(batch)
break

Author

InhwanCho

Posted on

2023-08-18

Updated on

2023-08-18

Licensed under

Comments