100 lines
2.8 KiB
Python
100 lines
2.8 KiB
Python
from torchvision import datasets, transforms, models
|
|
import torch
|
|
import numpy as np
|
|
|
|
|
|
# train set transform
|
|
def train_transform(res):
|
|
return transforms.Compose([
|
|
# ResNet expects 224 x 224 res
|
|
# Inception expects 299 x 299
|
|
transforms.Resize((res, res)),
|
|
transforms.RandomHorizontalFlip(p=0.5),
|
|
transforms.ColorJitter(
|
|
brightness=0.2,
|
|
contrast=0.2,
|
|
saturation=0.1
|
|
),
|
|
transforms.ToTensor(),
|
|
# normalise to
|
|
transforms.Normalize(
|
|
mean=[0.485, 0.456, 0.406],
|
|
std=[0.229, 0.224, 0.225]
|
|
)
|
|
])
|
|
|
|
# test set transform
|
|
def test_transform(res):
|
|
return transforms.Compose([
|
|
transforms.Resize((res, res)),
|
|
transforms.ToTensor(),
|
|
transforms.Normalize(
|
|
mean=[0.485, 0.456, 0.406],
|
|
std=[0.229, 0.224, 0.225]
|
|
)
|
|
])
|
|
|
|
# Load data with 'identity' as target and transform it
|
|
def get_set():
|
|
return datasets.CelebA(
|
|
root='./data',
|
|
split='all',
|
|
target_type='identity',
|
|
download=True,
|
|
transform=None
|
|
)
|
|
|
|
|
|
def get_ids_and_counts(dataset):
|
|
return torch.unique(
|
|
dataset.identity,
|
|
return_counts=True
|
|
)
|
|
|
|
# filter selected identities from dataset
|
|
# How many classes, how many images per class
|
|
def select_ids( dataset, sample_size, class_size):
|
|
ids, counts = get_ids_and_counts(dataset=dataset)
|
|
eligible_mask = counts >= sample_size
|
|
eligible_ids = ids[eligible_mask].numpy()
|
|
|
|
if len(eligible_ids) < class_size:
|
|
raise ValueError(
|
|
f"Only found {len(eligible_ids)} identities with {sample_size}+ images."
|
|
)
|
|
|
|
# Randomly select 50 identities
|
|
return np.random.choice(eligible_ids, class_size, replace=False)
|
|
|
|
# optional function to get max amount of samples per class
|
|
def select_top_ids(dataset, class_size):
|
|
ids, counts = get_ids_and_counts(dataset=dataset)
|
|
|
|
# sort by number of images (descending)
|
|
sorted_indices = torch.argsort(counts, descending=True)
|
|
|
|
top_ids = ids[sorted_indices][:class_size].numpy()
|
|
|
|
return np.array(top_ids, dtype=int)
|
|
|
|
|
|
# split class images to train and test set.
|
|
def get_indices(dataset, identities, split_at, size = 30):
|
|
train_indices = []
|
|
test_indices = []
|
|
|
|
#training_sample = int(sample_size * training_ratio)
|
|
np.random.seed(42)
|
|
for person_id in identities:
|
|
# Get all indices for this specific person
|
|
indices = torch.where(dataset.identity == person_id)[0].numpy()
|
|
|
|
# Shuffle the indices for this person
|
|
np.random.shuffle(indices)
|
|
|
|
# split data to testing and training
|
|
train_indices.extend(indices[:split_at])
|
|
test_indices.extend(indices[split_at:size])
|
|
|
|
return train_indices, test_indices
|