-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathQuickDrawDataset.py
More file actions
90 lines (68 loc) · 3.02 KB
/
Copy pathQuickDrawDataset.py
File metadata and controls
90 lines (68 loc) · 3.02 KB
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
from typing import List, Optional
import urllib.request
from pathlib import Path
import requests
import torch
import math
import numpy as np
def get_quickdraw_class_names():
"""
TODO - Check performance w/ gsutil in colab. The following command downloads all files to ./data
`gsutil cp gs://quickdraw_dataset/full/numpy_bitmap/* ./data`
"""
url = "https://raw.githubusercontent.com/googlecreativelab/quickdraw-dataset/master/categories.txt"
r = requests.get(url)
classes = [x.replace(' ', '_') for x in r.text.splitlines()]
return classes
def download_quickdraw_dataset(root="./data", limit: Optional[int] = None, class_names: List[str]=None):
if class_names is None:
class_names = get_quickdraw_class_names()
root = Path(root)
root.mkdir(exist_ok=True, parents=True)
url = 'https://storage.googleapis.com/quickdraw_dataset/full/numpy_bitmap/'
print("Downloading Quickdraw Dataset...")
for class_name in (class_names[:limit]):
fpath = root / f"{class_name}.npy"
if not fpath.exists():
urllib.request.urlretrieve(f"{url}{class_name.replace('_', '%20')}.npy", fpath)
def load_quickdraw_data(root="./data", max_items_per_class=5000):
all_files = Path(root).glob('*.npy')
x = np.empty([0, 784], dtype=np.uint8)
y = np.empty([0], dtype=np.uint8)
class_names = []
print(f"Loading {max_items_per_class} examples for each class from the Quickdraw Dataset...")
for idx, file in enumerate((sorted(all_files))):
data = np.load(file)
data = data[0: max_items_per_class, :]
labels = np.full(data.shape[0], idx)
x = np.concatenate((x, data), axis=0)
y = np.append(y, labels)
class_names.append(file.stem)
return x, y, class_names
class QuickDrawDataset(torch.utils.data.Dataset):
def __init__(self, root, max_items_per_class=5000, class_limit=None, transforms=None):
super().__init__()
self.root = root
self.max_items_per_class = max_items_per_class
self.class_limit = class_limit
self.transforms = transforms
# download_quickdraw_dataset(root, class_names=get_quickdraw_class_names())
self.X, self.Y, self.classes = load_quickdraw_data(self.root, self.max_items_per_class)
def __getitem__(self, idx):
y = self.Y[idx]
x = (self.X[idx] / 255.).astype(np.float32).reshape(28, 28)
x = self.transforms(x)
return x, y.item()
def __len__(self):
return len(self.X)
def collate_fn(self, batch):
x = torch.stack([item[0] for item in batch])
y = torch.LongTensor([item[1] for item in batch])
return {'pixel_values': x, 'labels': y}
def split(self, pct=0.1):
num_classes = len(self.classes)
indices = torch.randperm(len(self)).tolist()
n_val = math.floor(len(indices) * pct)
train_ds = torch.utils.data.Subset(self, indices[:-n_val])
val_ds = torch.utils.data.Subset(self, indices[-n_val:])
return train_ds, val_ds