in downstream/semseg/lib/test.py [0:0]
def test(model, data_loader, config, transform_data_fn=None, has_gt=True):
device = get_torch_device(config.misc.is_cuda)
dataset = data_loader.dataset
num_labels = dataset.NUM_LABELS
global_timer, data_timer, iter_timer = Timer(), Timer(), Timer()
criterion = nn.CrossEntropyLoss(ignore_index=config.data.ignore_label)
losses, scores, ious = AverageMeter(), AverageMeter(), 0
aps = np.zeros((0, num_labels))
hist = np.zeros((num_labels, num_labels))
logging.info('===> Start testing')
global_timer.tic()
data_iter = data_loader.__iter__()
max_iter = len(data_loader)
max_iter_unique = max_iter
# Fix batch normalization running mean and std
model.eval()
# Clear cache (when run in val mode, cleanup training cache)
torch.cuda.empty_cache()
if config.test.save_prediction or config.test.test_original_pointcloud:
if config.test.save_prediction:
save_pred_dir = config.test.save_pred_dir
os.makedirs(save_pred_dir, exist_ok=True)
else:
save_pred_dir = tempfile.mkdtemp()
if os.listdir(save_pred_dir):
raise ValueError(f'Directory {save_pred_dir} not empty. '
'Please remove the existing prediction.')
with torch.no_grad():
for iteration in range(max_iter):
data_timer.tic()
if config.data.return_transformation:
coords, input, target, transformation = data_iter.next()
else:
coords, input, target = data_iter.next()
transformation = None
data_time = data_timer.toc(False)
# Preprocess input
iter_timer.tic()
if config.net.wrapper_type != None:
color = input[:, :3].int()
if config.augmentation.normalize_color:
input[:, :3] = input[:, :3] / 255. - 0.5
sinput = SparseTensor(input, coords).to(device)
# Feed forward
inputs = (sinput,) if config.net.wrapper_type == None else (sinput, coords, color)
soutput = model(*inputs)
output = soutput.F
pred = get_prediction(dataset, output, target).int()
iter_time = iter_timer.toc(False)
if config.test.save_prediction or config.test.test_original_pointcloud:
save_predictions(coords, pred, transformation, dataset, config, iteration, save_pred_dir)
if has_gt:
if config.test.evaluate_original_pointcloud:
raise NotImplementedError('pointcloud')
output, pred, target = permute_pointcloud(coords, pointcloud, transformation,
dataset.label_map, output, pred)
target_np = target.numpy()
num_sample = target_np.shape[0]
target = target.to(device)
cross_ent = criterion(output, target.long())
losses.update(float(cross_ent), num_sample)
scores.update(precision_at_one(pred, target), num_sample)
hist += fast_hist(pred.cpu().numpy().flatten(), target_np.flatten(), num_labels)
ious = per_class_iu(hist) * 100
prob = torch.nn.functional.softmax(output, dim=1)
ap = average_precision(prob.cpu().detach().numpy(), target_np)
aps = np.vstack((aps, ap))
# Due to heavy bias in class, there exists class with no test label at all
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=RuntimeWarning)
ap_class = np.nanmean(aps, 0) * 100.
if iteration % config.test.test_stat_freq == 0 and iteration > 0:
reordered_ious = dataset.reorder_result(ious)
reordered_ap_class = dataset.reorder_result(ap_class)
class_names = dataset.get_classnames()
print_info(
iteration,
max_iter_unique,
data_time,
iter_time,
has_gt,
losses,
scores,
reordered_ious,
hist,
reordered_ap_class,
class_names=class_names)
if iteration % config.train.empty_cache_freq == 0:
# Clear cache
torch.cuda.empty_cache()
global_time = global_timer.toc(False)
reordered_ious = dataset.reorder_result(ious)
reordered_ap_class = dataset.reorder_result(ap_class)
class_names = dataset.get_classnames()
print_info(
iteration,
max_iter_unique,
data_time,
iter_time,
has_gt,
losses,
scores,
reordered_ious,
hist,
reordered_ap_class,
class_names=class_names)
if config.test.test_original_pointcloud:
logging.info('===> Start testing on original pointcloud space.')
dataset.test_pointcloud(save_pred_dir)
logging.info("Finished test. Elapsed time: {:.4f}".format(global_time))
return losses.avg, scores.avg, np.nanmean(ap_class), np.nanmean(per_class_iu(hist)) * 100