-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultiLabel_dataset.py
118 lines (88 loc) · 3.67 KB
/
multiLabel_dataset.py
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
# coding: utf-8
# In[5]:
import os
import random
import torch
from torch.utils.data import Dataset
from torchvision import transforms as T
from PIL import Image
# In[6]:
class multiLabel_dataset(Dataset):
"""Dataset class for the multiLabel dataset."""
def __init__(self, image_dir, attr_path, selected_attrs = None, crop_size = 128, mode = 'train'):
"""
Initialize and preprocess the dataset.
args
image_dir: (str) path for inputs
attr_path: (str) path of file containing attributes label
format of attr path :-
first line: number of images
ex. 202599
second line: names of all atrributes seperated by commas
ex. 5_o_Clock_Shadow Arched_Eyebrows Attractive Bags_Under_Eyes Bald Bangs
remaining lines: name of image and then int (1 : present, -1 : not present) seperated by commas
ex. 000001.jpg -1 1 1 -1 -1 -1
selected_attrs: (list, optional) list of atttributes for processing labels. Default, all attributes
in attributes file will be use to process labels.
crop_size: (int, optional)
mode: ({'train','test'}, optional)
returns:
one image and corresponding one hot vector
"""
self.image_dir = image_dir
self.attr_path = attr_path
self.selected_attrs = selected_attrs
transform = []
# to be extended for data augmentation
# if mode == 'train':
# transform.append(T.RandomHorizontalFlip())
transform.append(T.CenterCrop(crop_size))
transform.append(T.ToTensor())
transform.append(T.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5)))
transform = T.Compose(transform)
self.mode = mode
self.train_dataset = []
self.test_dataset = []
self.attr2idx = {}
self.idx2attr = {}
self.preprocess()
self.transform = transform
if mode == 'train':
self.num_images = len(self.train_dataset)
else:
self.num_images = len(self.test_dataset)
def preprocess(self):
"""Preprocess the attribute file."""
lines = [line.rstrip() for line in open(self.attr_path, 'r')]
all_attr_names = lines[1].split()
if self.selected_attrs == None:
self.selected_attrs = all_attr_names
for i, attr_name in enumerate(all_attr_names):
self.attr2idx[attr_name] = i
self.idx2attr[i] = attr_name
lines = lines[2:]
random.seed(1234)
random.shuffle(lines)
for i, line in enumerate(lines):
split = line.split()
filename = split[0]
values = split[1:]
label = []
for attr_name in self.selected_attrs:
idx = self.attr2idx[attr_name]
label.append(values[idx] == '1')
if (i+1) < 2000:
self.test_dataset.append([filename, label])
else:
self.train_dataset.append([filename, label])
print('Finished preprocessing the dataset...')
def __getitem__(self, index):
"""Return one image and its corresponding attribute label."""
dataset = self.train_dataset if self.mode == 'train' else self.test_dataset
filename, label = dataset[index]
image = Image.open(os.path.join(self.image_dir, filename))
return self.transform(image), torch.FloatTensor(label)
def __len__(self):
"""Return the number of images."""
return self.num_images