2020-11-13 18:03:54 +00:00
|
|
|
import os
|
|
|
|
|
|
|
|
import torch
|
|
|
|
import os.path as osp
|
|
|
|
import torchvision
|
2020-12-18 16:18:34 +00:00
|
|
|
import trainer.eval.evaluator as evaluator
|
2020-11-13 18:03:54 +00:00
|
|
|
from pytorch_fid import fid_score
|
2021-02-08 15:09:21 +00:00
|
|
|
from utils.util import opt_get
|
|
|
|
|
2021-03-03 03:51:48 +00:00
|
|
|
# Evaluator that generates uniform noise to feed into a generator, then calculates a FID score on the results.
|
2020-11-13 18:03:54 +00:00
|
|
|
class StyleTransferEvaluator(evaluator.Evaluator):
|
|
|
|
def __init__(self, model, opt_eval, env):
|
2021-06-14 15:51:44 +00:00
|
|
|
super().__init__(model, opt_eval, env, uses_all_ddp=False)
|
2020-11-13 18:03:54 +00:00
|
|
|
self.batches_per_eval = opt_eval['batches_per_eval']
|
|
|
|
self.batch_sz = opt_eval['batch_size']
|
|
|
|
self.im_sz = opt_eval['image_size']
|
|
|
|
self.fid_real_samples = opt_eval['real_fid_path']
|
|
|
|
self.gen_output_index = opt_eval['gen_index'] if 'gen_index' in opt_eval.keys() else 0
|
2021-02-08 15:09:21 +00:00
|
|
|
self.noise_type = opt_get(opt_eval, ['noise_type'], 'imgnoise')
|
|
|
|
self.latent_dim = opt_get(opt_eval, ['latent_dim'], 512) # Not needed if using 'imgnoise' input.
|
2021-04-22 00:14:17 +00:00
|
|
|
self.image_norm_range = tuple(opt_get(env['opt'], ['image_normalization_range'], [0,1]))
|
2020-11-13 18:03:54 +00:00
|
|
|
|
|
|
|
def perform_eval(self):
|
2021-03-03 03:51:48 +00:00
|
|
|
fid_fake_path = osp.join(self.env['base_path'], "../", "fid", str(self.env["step"]))
|
2020-11-13 18:03:54 +00:00
|
|
|
os.makedirs(fid_fake_path, exist_ok=True)
|
|
|
|
counter = 0
|
2021-04-22 00:14:17 +00:00
|
|
|
self.model.eval()
|
2020-11-13 18:03:54 +00:00
|
|
|
for i in range(self.batches_per_eval):
|
2021-02-08 15:09:21 +00:00
|
|
|
if self.noise_type == 'imgnoise':
|
|
|
|
batch = torch.FloatTensor(self.batch_sz, 3, self.im_sz, self.im_sz).uniform_(0., 1.).to(self.env['device'])
|
|
|
|
elif self.noise_type == 'stylenoise':
|
2021-03-03 03:51:48 +00:00
|
|
|
batch = torch.randn(self.batch_sz, self.latent_dim).to(self.env['device'])
|
2020-11-13 18:03:54 +00:00
|
|
|
gen = self.model(batch)
|
|
|
|
if not isinstance(gen, list) and not isinstance(gen, tuple):
|
|
|
|
gen = [gen]
|
|
|
|
gen = gen[self.gen_output_index]
|
2021-04-22 00:14:17 +00:00
|
|
|
gen = (gen - self.image_norm_range[0]) / (self.image_norm_range[1]-self.image_norm_range[0])
|
2020-11-13 18:03:54 +00:00
|
|
|
for b in range(self.batch_sz):
|
|
|
|
torchvision.utils.save_image(gen[b], osp.join(fid_fake_path, "%i_.png" % (counter)))
|
|
|
|
counter += 1
|
2021-04-22 00:14:17 +00:00
|
|
|
self.model.train()
|
2020-11-13 18:03:54 +00:00
|
|
|
|
2021-03-03 03:51:48 +00:00
|
|
|
print("Got all images, computing fid")
|
2020-11-13 18:03:54 +00:00
|
|
|
return {"fid": fid_score.calculate_fid_given_paths([self.fid_real_samples, fid_fake_path], self.batch_sz, True,
|
|
|
|
2048)}
|