in experiments/overlap/extract_features.py [0:0]
def extract_features(feature_extractor, dataset, batch_size, loader_params, average=True, num_gpus=1, average_num=None, preemption_protection=False, is_leader=True):
sampler = torch.utils.data.distributed.DistributedSampler(dataset, shuffle=False)\
if num_gpus > 1 else None
loader = torch.utils.data.DataLoader(
dataset,
batch_size=batch_size,
shuffle=False,
sampler=sampler,
num_workers=loader_params.num_workers,
pin_memory=loader_params.pin_memory,
drop_last=False
)
features = None
count = 0
starting_iter = -1
if preemption_protection and os.path.exists('feature_extraction.tmp.npz'):
data = np.loadz('feature_extraction.tmp.npz')
features = torch.Tensor(data['features']).cuda()
count = data['count']
starting_iter = data['curr_iter']
for curr_iter, (inputs, labels) in enumerate(loader):
if preemption_protection and curr_iter <= starting_iter:
continue
inputs, labels = inputs.cuda(), labels.cuda(non_blocking=True)
curr_features = feature_extractor.extract(inputs)
if average and average_num is None:
curr_features = torch.sum(curr_features, dim=0)
if num_gpus > 1:
torch.distributed.all_reduce(curr_features)
features = (features + curr_features.detach().cpu()) if features is not None else curr_features.detach().cpu()
elif average:
num_features = len(dataset) // average_num
if num_gpus > 1:
curr_features = distributed_gather_features(curr_features, batch_size, num_gpus)
if features is None:
features = torch.zeros(num_features, curr_features.size(-1))
if count + curr_features.size(0) > num_features:
remainder = count + curr_features.size(0) - num_features
features[count:, :] += curr_features[:num_features-count,:].detach().cpu()
offset = 0
while remainder > num_features:
features += curr_features[offset+num_features-count:2*num_features-count+offset].detach().cpu()
offset += num_features
remainder -= num_features
features[:remainder,:] += curr_features[offset+num_features-count:,:].detach().cpu()
count = remainder
else:
features[count:count+curr_features.size(0),:] += curr_features.detach().cpu()
count += curr_features.size(0)
count = count % num_features
else:
if num_gpus > 1:
curr_features = distributed_gather_features(curr_features, batch_size, num_gpus)
if features is None:
features = torch.zeros(len(dataset), curr_features.size(-1))
features[count:count+curr_features.size(0),:] = curr_features.detach().cpu()
count += curr_features.size(0)
if preemption_protection and curr_iter % 5000 == 0 and is_leader:
np.savez('feature_extraction.tmp.npz', features=features.detach().cpu().numpy(), count=count, curr_iter=curr_iter)
if average and average_num is None:
features /= len(dataset)
elif average:
features /= average_num
return features.detach().cpu().numpy()