2019-08-23 13:42:47 +00:00
|
|
|
import torch
|
2020-08-26 00:14:45 +00:00
|
|
|
import logging
|
2020-09-07 23:01:48 +00:00
|
|
|
from munch import munchify
|
2019-08-23 13:42:47 +00:00
|
|
|
import models.archs.SRResNet_arch as SRResNet_arch
|
|
|
|
import models.archs.discriminator_vgg_arch as SRGAN_arch
|
2020-04-29 05:00:29 +00:00
|
|
|
import models.archs.DiscriminatorResnet_arch as DiscriminatorResnet_arch
|
2020-05-04 20:01:43 +00:00
|
|
|
import models.archs.DiscriminatorResnet_arch_passthrough as DiscriminatorResnet_arch_passthrough
|
2019-08-23 13:42:47 +00:00
|
|
|
import models.archs.RRDBNet_arch as RRDBNet_arch
|
2020-05-29 02:26:30 +00:00
|
|
|
import models.archs.feature_arch as feature_arch
|
2020-06-16 17:23:50 +00:00
|
|
|
import models.archs.SwitchedResidualGenerator_arch as SwitchedGen_arch
|
2020-08-02 18:55:08 +00:00
|
|
|
import models.archs.SPSR_arch as spsr
|
2020-07-31 20:59:54 +00:00
|
|
|
from collections import OrderedDict
|
2019-08-23 13:42:47 +00:00
|
|
|
|
2020-08-26 00:14:45 +00:00
|
|
|
logger = logging.getLogger('base')
|
|
|
|
|
2019-08-23 13:42:47 +00:00
|
|
|
# Generator
|
2020-08-22 14:24:34 +00:00
|
|
|
def define_G(opt, net_key='network_G', scale=None):
|
|
|
|
if net_key is not None:
|
|
|
|
opt_net = opt[net_key]
|
|
|
|
else:
|
|
|
|
opt_net = opt
|
|
|
|
if scale is None:
|
|
|
|
scale = opt['scale']
|
2019-08-23 13:42:47 +00:00
|
|
|
which_model = opt_net['which_model_G']
|
|
|
|
|
|
|
|
# image restoration
|
|
|
|
if which_model == 'MSRResNet':
|
|
|
|
netG = SRResNet_arch.MSRResNet(in_nc=opt_net['in_nc'], out_nc=opt_net['out_nc'],
|
|
|
|
nf=opt_net['nf'], nb=opt_net['nb'], upscale=opt_net['scale'])
|
|
|
|
elif which_model == 'RRDBNet':
|
2020-04-22 06:37:41 +00:00
|
|
|
# RRDB does scaling in two steps, so take the sqrt of the scale we actually want to achieve and feed it to RRDB.
|
2020-06-02 16:47:15 +00:00
|
|
|
initial_stride = 1 if 'initial_stride' not in opt_net else opt_net['initial_stride']
|
|
|
|
assert initial_stride == 1 or initial_stride == 2
|
|
|
|
# Need to adjust the scale the generator sees by the stride since the stride causes a down-sample.
|
|
|
|
gen_scale = scale * initial_stride
|
2019-08-23 13:42:47 +00:00
|
|
|
netG = RRDBNet_arch.RRDBNet(in_nc=opt_net['in_nc'], out_nc=opt_net['out_nc'],
|
2020-06-02 17:15:55 +00:00
|
|
|
nf=opt_net['nf'], nb=opt_net['nb'], scale=gen_scale, initial_stride=initial_stride)
|
2020-06-25 01:49:37 +00:00
|
|
|
elif which_model == "ConfigurableSwitchedResidualGenerator2":
|
2020-07-09 23:34:51 +00:00
|
|
|
netG = SwitchedGen_arch.ConfigurableSwitchedResidualGenerator2(switch_depth=opt_net['switch_depth'], switch_filters=opt_net['switch_filters'],
|
2020-06-25 01:49:37 +00:00
|
|
|
switch_reductions=opt_net['switch_reductions'],
|
|
|
|
switch_processing_layers=opt_net['switch_processing_layers'], trans_counts=opt_net['trans_counts'],
|
|
|
|
trans_kernel_sizes=opt_net['trans_kernel_sizes'], trans_layers=opt_net['trans_layers'],
|
2020-07-18 13:24:02 +00:00
|
|
|
transformation_filters=opt_net['transformation_filters'], attention_norm=opt_net['attention_norm'],
|
2020-06-25 01:49:37 +00:00
|
|
|
initial_temp=opt_net['temperature'], final_temperature_step=opt_net['temperature_final_step'],
|
2020-06-29 03:21:57 +00:00
|
|
|
heightened_temp_min=opt_net['heightened_temp_min'], heightened_final_step=opt_net['heightened_final_step'],
|
2020-07-03 18:07:31 +00:00
|
|
|
upsample_factor=scale, add_scalable_noise_to_transforms=opt_net['add_noise'])
|
2020-08-03 16:25:37 +00:00
|
|
|
elif which_model == 'spsr_net_improved':
|
|
|
|
netG = spsr.SPSRNetSimplified(in_nc=opt_net['in_nc'], out_nc=opt_net['out_nc'], nf=opt_net['nf'],
|
|
|
|
nb=opt_net['nb'], upscale=opt_net['scale'])
|
2020-09-11 22:09:28 +00:00
|
|
|
elif which_model == "spsr_switched_with_ref2" or which_model == "spsr3":
|
2020-08-29 15:27:18 +00:00
|
|
|
xforms = opt_net['num_transforms'] if 'num_transforms' in opt_net.keys() else 8
|
2020-09-07 23:01:48 +00:00
|
|
|
netG = spsr.SwitchedSpsrWithRef2(in_nc=3, out_nc=3, nf=opt_net['nf'], xforms=xforms, upscale=opt_net['scale'],
|
2020-08-29 15:27:18 +00:00
|
|
|
init_temperature=opt_net['temperature'] if 'temperature' in opt_net.keys() else 10)
|
2020-09-12 04:55:37 +00:00
|
|
|
elif which_model == "spsr4":
|
|
|
|
xforms = opt_net['num_transforms'] if 'num_transforms' in opt_net.keys() else 8
|
|
|
|
netG = spsr.Spsr4(in_nc=3, out_nc=3, nf=opt_net['nf'], xforms=xforms, upscale=opt_net['scale'],
|
|
|
|
init_temperature=opt_net['temperature'] if 'temperature' in opt_net.keys() else 10)
|
2020-09-14 02:10:24 +00:00
|
|
|
elif which_model == "spsr5":
|
|
|
|
xforms = opt_net['num_transforms'] if 'num_transforms' in opt_net.keys() else 8
|
|
|
|
netG = spsr.Spsr5(in_nc=3, out_nc=3, nf=opt_net['nf'], xforms=xforms, upscale=opt_net['scale'],
|
|
|
|
init_temperature=opt_net['temperature'] if 'temperature' in opt_net.keys() else 10)
|
2020-09-12 04:55:37 +00:00
|
|
|
elif which_model == "backbone_encoder":
|
|
|
|
netG = SwitchedGen_arch.BackboneEncoder(pretrained_backbone=opt_net['pretrained_spinenet'])
|
2019-08-23 13:42:47 +00:00
|
|
|
else:
|
|
|
|
raise NotImplementedError('Generator model [{:s}] not recognized'.format(which_model))
|
|
|
|
|
|
|
|
return netG
|
|
|
|
|
|
|
|
|
2020-08-25 23:58:20 +00:00
|
|
|
class GradDiscWrapper(torch.nn.Module):
|
|
|
|
def __init__(self, m):
|
|
|
|
super(GradDiscWrapper, self).__init__()
|
2020-08-26 00:14:45 +00:00
|
|
|
logger.info("Wrapping a discriminator..")
|
2020-08-25 23:58:20 +00:00
|
|
|
self.m = m
|
|
|
|
|
2020-08-26 00:14:45 +00:00
|
|
|
def forward(self, x):
|
|
|
|
return self.m(x)
|
2020-08-25 23:58:20 +00:00
|
|
|
|
|
|
|
def define_D_net(opt_net, img_sz=None, wrap=False):
|
2019-08-23 13:42:47 +00:00
|
|
|
which_model = opt_net['which_model_D']
|
|
|
|
|
|
|
|
if which_model == 'discriminator_vgg_128':
|
2020-08-31 15:50:30 +00:00
|
|
|
netD = SRGAN_arch.Discriminator_VGG_128(in_nc=opt_net['in_nc'], nf=opt_net['nf'], input_img_factor=img_sz / 128, extra_conv=opt_net['extra_conv'])
|
2020-08-02 18:55:08 +00:00
|
|
|
elif which_model == 'discriminator_vgg_128_gn':
|
2020-08-31 15:50:30 +00:00
|
|
|
netD = SRGAN_arch.Discriminator_VGG_128_GN(in_nc=opt_net['in_nc'], nf=opt_net['nf'], input_img_factor=img_sz / 128)
|
2020-08-26 00:14:45 +00:00
|
|
|
if wrap:
|
|
|
|
netD = GradDiscWrapper(netD)
|
2020-04-29 05:00:29 +00:00
|
|
|
elif which_model == 'discriminator_resnet':
|
2020-05-02 01:56:14 +00:00
|
|
|
netD = DiscriminatorResnet_arch.fixup_resnet34(num_filters=opt_net['nf'], num_classes=1, input_img_size=img_sz)
|
2020-05-04 20:01:43 +00:00
|
|
|
elif which_model == 'discriminator_resnet_passthrough':
|
2020-05-15 19:50:49 +00:00
|
|
|
netD = DiscriminatorResnet_arch_passthrough.fixup_resnet34(num_filters=opt_net['nf'], num_classes=1, input_img_size=img_sz,
|
2020-05-19 15:41:16 +00:00
|
|
|
number_skips=opt_net['number_skips'], use_bn=True,
|
|
|
|
disable_passthrough=opt_net['disable_passthrough'])
|
2020-07-06 03:49:09 +00:00
|
|
|
elif which_model == 'discriminator_pix':
|
|
|
|
netD = SRGAN_arch.Discriminator_VGG_PixLoss(in_nc=opt_net['in_nc'], nf=opt_net['nf'])
|
2020-07-10 22:16:03 +00:00
|
|
|
elif which_model == "discriminator_unet":
|
|
|
|
netD = SRGAN_arch.Discriminator_UNet(in_nc=opt_net['in_nc'], nf=opt_net['nf'])
|
2020-07-16 16:10:09 +00:00
|
|
|
elif which_model == "discriminator_unet_fea":
|
2020-07-20 01:05:08 +00:00
|
|
|
netD = SRGAN_arch.Discriminator_UNet_FeaOut(in_nc=opt_net['in_nc'], nf=opt_net['nf'], feature_mode=opt_net['feature_mode'])
|
2020-07-23 02:52:59 +00:00
|
|
|
elif which_model == "discriminator_switched":
|
|
|
|
netD = SRGAN_arch.Discriminator_switched(in_nc=opt_net['in_nc'], nf=opt_net['nf'], initial_temp=opt_net['initial_temp'],
|
|
|
|
final_temperature_step=opt_net['final_temperature_step'])
|
2020-08-06 14:56:21 +00:00
|
|
|
elif which_model == "cross_compare_vgg128":
|
2020-08-31 15:41:48 +00:00
|
|
|
netD = SRGAN_arch.CrossCompareDiscriminator(in_nc=opt_net['in_nc'], ref_channels=opt_net['ref_channels'] if 'ref_channels' in opt_net.keys() else 3, nf=opt_net['nf'], scale=opt_net['scale'])
|
2020-09-11 03:35:29 +00:00
|
|
|
elif which_model == "discriminator_refvgg":
|
|
|
|
netD = SRGAN_arch.RefDiscriminatorVgg128(in_nc=opt_net['in_nc'], nf=opt_net['nf'], input_img_factor=img_sz / 128)
|
2019-08-23 13:42:47 +00:00
|
|
|
else:
|
|
|
|
raise NotImplementedError('Discriminator model [{:s}] not recognized'.format(which_model))
|
|
|
|
return netD
|
|
|
|
|
2020-07-31 20:59:54 +00:00
|
|
|
# Discriminator
|
2020-08-25 23:58:20 +00:00
|
|
|
def define_D(opt, wrap=False):
|
2020-07-31 20:59:54 +00:00
|
|
|
img_sz = opt['datasets']['train']['target_size']
|
|
|
|
opt_net = opt['network_D']
|
2020-08-25 23:58:20 +00:00
|
|
|
return define_D_net(opt_net, img_sz, wrap=wrap)
|
2020-07-31 20:59:54 +00:00
|
|
|
|
|
|
|
def define_fixed_D(opt):
|
|
|
|
# Note that this will not work with "old" VGG-style discriminators with dense blocks until the img_size parameter is added.
|
|
|
|
net = define_D_net(opt)
|
|
|
|
|
|
|
|
# Load the model parameters:
|
|
|
|
load_net = torch.load(opt['pretrained_path'])
|
|
|
|
load_net_clean = OrderedDict() # remove unnecessary 'module.'
|
|
|
|
for k, v in load_net.items():
|
|
|
|
if k.startswith('module.'):
|
|
|
|
load_net_clean[k[7:]] = v
|
|
|
|
else:
|
|
|
|
load_net_clean[k] = v
|
|
|
|
net.load_state_dict(load_net_clean)
|
|
|
|
|
|
|
|
# Put into eval mode, freeze the parameters and set the 'weight' field.
|
|
|
|
net.eval()
|
|
|
|
for k, v in net.named_parameters():
|
|
|
|
v.requires_grad = False
|
|
|
|
net.fdisc_weight = opt['weight']
|
|
|
|
|
2020-07-31 21:07:10 +00:00
|
|
|
return net
|
|
|
|
|
2019-08-23 13:42:47 +00:00
|
|
|
|
|
|
|
# Define network used for perceptual loss
|
2020-08-22 19:08:33 +00:00
|
|
|
def define_F(which_model='vgg', use_bn=False, for_training=False, load_path=None):
|
|
|
|
if which_model == 'vgg':
|
2020-05-29 02:26:30 +00:00
|
|
|
# PyTorch pretrained VGG19-54, before ReLU.
|
|
|
|
if use_bn:
|
|
|
|
feature_layer = 49
|
|
|
|
else:
|
|
|
|
feature_layer = 34
|
2020-07-31 17:20:39 +00:00
|
|
|
if for_training:
|
|
|
|
netF = feature_arch.TrainableVGGFeatureExtractor(feature_layer=feature_layer, use_bn=use_bn,
|
2020-08-22 19:08:33 +00:00
|
|
|
use_input_norm=True)
|
2020-07-31 17:20:39 +00:00
|
|
|
else:
|
|
|
|
netF = feature_arch.VGGFeatureExtractor(feature_layer=feature_layer, use_bn=use_bn,
|
2020-08-22 19:08:33 +00:00
|
|
|
use_input_norm=True)
|
|
|
|
elif which_model == 'wide_resnet':
|
|
|
|
netF = feature_arch.WideResnetFeatureExtractor(use_input_norm=True)
|
|
|
|
else:
|
|
|
|
raise NotImplementedError
|
2020-05-29 02:26:30 +00:00
|
|
|
|
2020-07-31 22:29:47 +00:00
|
|
|
if load_path:
|
|
|
|
# Load the model parameters:
|
|
|
|
load_net = torch.load(load_path)
|
|
|
|
load_net_clean = OrderedDict() # remove unnecessary 'module.'
|
|
|
|
for k, v in load_net.items():
|
|
|
|
if k.startswith('module.'):
|
|
|
|
load_net_clean[k[7:]] = v
|
|
|
|
else:
|
|
|
|
load_net_clean[k] = v
|
|
|
|
netF.load_state_dict(load_net_clean)
|
|
|
|
|
2020-08-23 23:22:34 +00:00
|
|
|
if not for_training:
|
2020-07-31 22:29:47 +00:00
|
|
|
# Put into eval mode, freeze the parameters and set the 'weight' field.
|
|
|
|
netF.eval()
|
|
|
|
for k, v in netF.named_parameters():
|
|
|
|
v.requires_grad = False
|
|
|
|
|
2019-08-23 13:42:47 +00:00
|
|
|
return netF
|