Merge pull request #1 from MachineEditor/JanFschr-bug-fixes

Added tensorboard support, hsv power, bug fixes - removed blur_out_mask
This commit is contained in:
Ognjen 2021-12-05 16:56:53 +01:00 committed by GitHub
commit 0613321ea3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 171 additions and 165 deletions

View file

@ -104,7 +104,7 @@ def gen_pts(W, H, rnd_state=None):
return pts1, pts2
def gen_warp_params (w, flip=False, rotation_range=[-2,2], scale_range=[-0.5, 0.5], tx_range=[-0.05, 0.05], ty_range=[-0.05, 0.05], rnd_state=None ):
def gen_warp_params (w, flip=False, rotation_range=[-2,2], scale_range=[-0.5, 0.5], tx_range=[-0.05, 0.05], ty_range=[-0.05, 0.05], rnd_state=None, warp_rnd_state=None):
if rnd_state is None:
rnd_state = np.random
if warp_rnd_state is None:

View file

@ -76,9 +76,11 @@ class PatchDiscriminator(nn.ModelBase):
nn.PatchDiscriminator = PatchDiscriminator
class UNetPatchDiscriminator(nn.ModelBase):
"""
Inspired by https://arxiv.org/abs/2002.12655 "A U-Net Based Discriminator for Generative Adversarial Networks"
Based on iperov commit 11add4cd4f5a61df26a8659f4cc5c8d9467bf5f8 from Jan 3, 2021 with added fp16 option
"""
def calc_receptive_field_size(self, layers):
"""
@ -133,6 +135,7 @@ class UNetPatchDiscriminator(nn.ModelBase):
def on_build(self, patch_size, in_ch, base_ch = 16, use_fp16 = False):
self.use_fp16 = use_fp16
conv_dtype = tf.float16 if use_fp16 else tf.float32
class ResidualBlock(nn.ModelBase):
def on_build(self, ch, kernel_size=3 ):
self.conv1 = nn.Conv2D( ch, ch, kernel_size=kernel_size, padding='SAME', dtype=conv_dtype)
@ -147,7 +150,11 @@ class UNetPatchDiscriminator(nn.ModelBase):
prev_ch = in_ch
self.convs = []
self.res1 = []
self.res2 = []
self.upconvs = []
self.upres1 = []
self.upres2 = []
layers = self.find_archi(patch_size)
level_chs = { i-1:v for i,v in enumerate([ min( base_ch * (2**i), 512 ) for i in range(len(layers)+1)]) }
@ -172,13 +179,10 @@ class UNetPatchDiscriminator(nn.ModelBase):
def forward(self, x):
if self.use_fp16:
x = tf.cast(x, tf.float16)
x = tf.nn.leaky_relu( self.in_conv(x), 0.2 )
encs = []
for conv in self.convs:
for conv, res1,res2 in zip(self.convs, self.res1, self.res2):
encs.insert(0, x)
x = tf.nn.leaky_relu( conv(x), 0.2 )
x = res1(x)
@ -186,23 +190,20 @@ class UNetPatchDiscriminator(nn.ModelBase):
center_out, x = self.center_out(x), tf.nn.leaky_relu( self.center_conv(x), 0.2 )
for i, (upconv, enc) in enumerate(zip(self.upconvs, encs)):
for i, (upconv, enc, upres1, upres2 ) in enumerate(zip(self.upconvs, encs, self.upres1, self.upres2)):
x = tf.nn.leaky_relu( upconv(x), 0.2 )
x = tf.concat( [enc, x], axis=nn.conv2d_ch_axis)
x = upres1(x)
x = upres2(x)
x = self.out_conv(x)
if self.use_fp16:
center_out = tf.cast(center_out, tf.float32)
x = tf.cast(x, tf.float32)
return center_out, x
return center_out, self.out_conv(x)
nn.UNetPatchDiscriminator = UNetPatchDiscriminator
class UNetPatchDiscriminatorV2(nn.ModelBase):
"""
Inspired by https://arxiv.org/abs/2002.12655 "A U-Net Based Discriminator for Generative Adversarial Networks"
Based on iperov commit 35877dbfd724c22040f421e93c1adbb7142e5b5d from Jul 14, 2021
"""
def calc_receptive_field_size(self, layers):
"""
@ -218,7 +219,7 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
ts *= s
return rf
def find_archi(self, target_patch_size, max_layers=6):
def find_archi(self, target_patch_size, max_layers=9):
"""
Find the best configuration of layers using only 3x3 convs for target patch size
"""
@ -230,12 +231,12 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
layers = []
sum_st = 0
layers.append ( [3, 2])
sum_st += 2
for i in range(layers_count-1):
st = 1 + (1 if val & (1 << i) !=0 else 0 )
layers.append ( [3, st ])
sum_st += st
layers.append ( [3, 2])
sum_st += 2
rf = self.calc_receptive_field_size(layers)
@ -244,7 +245,7 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
s[rf] = (layers_count, sum_st, layers)
else:
if layers_count < s_rf[0] or \
( layers_count == s_rf[0] and sum_st > s_rf[1] ):
( layers_count == s_rf[0] and sum_st > s_rf[1] ):
s[rf] = (layers_count, sum_st, layers)
if val == 0:
@ -254,7 +255,7 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
q=x[np.abs(np.array(x)-target_patch_size).argmin()]
return s[q][2]
def on_build(self, patch_size, in_ch, use_fp16 = False):
def on_build(self, patch_size, in_ch, base_ch = 16, use_fp16 = False):
self.use_fp16 = use_fp16
conv_dtype = tf.float16 if use_fp16 else tf.float32
@ -272,11 +273,8 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
prev_ch = in_ch
self.convs = []
self.res = []
self.upconvs = []
self.upres = []
layers = self.find_archi(patch_size)
base_ch = 16
level_chs = { i-1:v for i,v in enumerate([ min( base_ch * (2**i), 512 ) for i in range(len(layers)+1)]) }
@ -285,12 +283,8 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
for i, (kernel_size, strides) in enumerate(layers):
self.convs.append ( nn.Conv2D( level_chs[i-1], level_chs[i], kernel_size=kernel_size, strides=strides, padding='SAME', dtype=conv_dtype) )
self.res.append ( ResidualBlock(level_chs[i]) )
self.upconvs.insert (0, nn.Conv2DTranspose( level_chs[i]*(2 if i != len(layers)-1 else 1), level_chs[i-1], kernel_size=kernel_size, strides=strides, padding='SAME', dtype=conv_dtype) )
self.upres.insert (0, ResidualBlock(level_chs[i-1]*2) )
self.out_conv = nn.Conv2D( level_chs[-1]*2, 1, kernel_size=1, padding='VALID', dtype=conv_dtype)
self.center_out = nn.Conv2D( level_chs[len(layers)-1], 1, kernel_size=1, padding='VALID', dtype=conv_dtype)
@ -301,20 +295,18 @@ class UNetPatchDiscriminatorV2(nn.ModelBase):
if self.use_fp16:
x = tf.cast(x, tf.float16)
x = tf.nn.leaky_relu( self.in_conv(x), 0.1 )
x = tf.nn.leaky_relu( self.in_conv(x), 0.2 )
encs = []
for conv, res in zip(self.convs, self.res):
for conv in self.convs:
encs.insert(0, x)
x = tf.nn.leaky_relu( conv(x), 0.1 )
x = res(x)
x = tf.nn.leaky_relu( conv(x), 0.2 )
center_out, x = self.center_out(x), self.center_conv(x)
center_out, x = self.center_out(x), tf.nn.leaky_relu( self.center_conv(x), 0.2 )
for i, (upconv, enc, upres) in enumerate(zip(self.upconvs, encs, self.upres)):
x = tf.nn.leaky_relu( upconv(x), 0.1 )
for i, (upconv, enc) in enumerate(zip(self.upconvs, encs)):
x = tf.nn.leaky_relu( upconv(x), 0.2 )
x = tf.concat( [enc, x], axis=nn.conv2d_ch_axis)
x = upres(x)
x = self.out_conv(x)

View file

@ -25,13 +25,17 @@ class TensorBoardTool:
def run(self):
from tensorboard import default
from tensorboard import program
from tensorboard import version as tb_version
# remove http messages
log = logging.getLogger('werkzeug').setLevel(logging.ERROR)
# Start tensorboard server
tb = program.TensorBoard(default.get_plugins())
tb.configure(argv=[None, '--logdir', self.dir_path, '--port', '6006', '--bind_all'])
tb_argv = [None, '--logdir', self.dir_path, '--port', '6006']
if int(tb_version.VERSION[0])>=2:
tb_argv.append("--bind_all")
tb.configure(argv=tb_argv)
url = tb.launch()
print('Launched TensorBoard at {}'.format(url))
io.log_info('Launched TensorBoard at {}\n'.format(url))
def process_img_for_tensorboard(input_img):
# convert format from bgr to rgb
@ -125,6 +129,25 @@ def trainerThread (s2c, c2s, e,
if not debug and not is_reached_goal:
model.create_backup()
def log_step(step, step_time, src_loss, dst_loss):
c2s.put({
'op': 'tb',
'action': 'step',
'step': step,
'step_time': step_time,
'src_loss': src_loss,
'dst_loss': dst_loss
})
def log_previews(step, previews, static_previews):
c2s.put({
'op': 'tb',
'action': 'preview',
'step': step,
'previews': previews,
'static_previews': static_previews
})
def send_preview():
if not debug:
previews = model.get_previews()
@ -322,7 +345,6 @@ def handle_tensorboard_op(input):
log_tensorboard_previews(step, previews, 'preview', train_summary_writer)
if static_previews is not None:
log_tensorboard_previews(step, static_previews, 'static_preview', train_summary_writer)
c2s.put({'op': 'close'})
class Zoom(Enum):
@ -584,7 +606,7 @@ def main(**kwargs):
selected_preview = selected_preview % len(previews)
update_preview = True
elif op == 'tb':
handle_tensorboard_op(input)
handle_tensorboard_op(item)
elif op == 'close':
break

View file

@ -394,6 +394,9 @@ class ModelBase(object):
def get_previews(self):
return self.onGetPreview ( self.last_sample )
def get_static_previews(self):
return self.onGetPreview (self.sample_for_preview)
def get_history_previews(self):
return self.onGetPreview (self.sample_for_preview, for_history=True)

View file

@ -51,6 +51,7 @@ class AMPModel(ModelBase):
default_ct_mode = self.options['ct_mode'] = self.load_or_def_option('ct_mode', 'none')
default_random_color = self.options['random_color'] = self.load_or_def_option('random_color', False)
default_clipgrad = self.options['clipgrad'] = self.load_or_def_option('clipgrad', False)
default_use_fp16 = self.options['use_fp16'] = self.load_or_def_option('use_fp16', False)
ask_override = self.ask_override()
if self.is_first_run() or ask_override:
@ -167,7 +168,7 @@ class AMPModel(ModelBase):
adabelief = self.options['adabelief']
# use_fp16 = self.options['use_fp16']
use_fp16 = self.options['use_fp16']
if self.is_exporting:
use_fp16 = io.input_bool ("Export quantized?", False, help_message='Makes the exported model faster. If you have problems, disable this option.')

View file

@ -68,6 +68,7 @@ class SAEHDModel(ModelBase):
default_random_color = self.options['random_color'] = self.load_or_def_option('random_color', False)
default_clipgrad = self.options['clipgrad'] = self.load_or_def_option('clipgrad', False)
default_pretrain = self.options['pretrain'] = self.load_or_def_option('pretrain', False)
default_use_fp16 = self.options['use_fp16'] = self.load_or_def_option('use_fp16', False)
ask_override = self.ask_override()
if self.is_first_run() or ask_override:
@ -151,6 +152,7 @@ Examples: df, liae, df-d, df-ud, liae-ud, ...
self.options['blur_out_mask'] = io.input_bool ("Blur out mask", default_blur_out_mask, help_message='Blurs nearby area outside of applied face mask of training samples. The result is the background near the face is smoothed and less noticeable on swapped face. The exact xseg mask in src and dst faceset is required.')
default_gan_power = self.options['gan_power'] = self.load_or_def_option('gan_power', 0.0)
default_gan_version = self.options['gan_version'] = self.load_or_def_option('gan_version', 2)
default_gan_patch_size = self.options['gan_patch_size'] = self.load_or_def_option('gan_patch_size', self.options['resolution'] // 8)
default_gan_dims = self.options['gan_dims'] = self.load_or_def_option('gan_dims', 16)
default_gan_smoothing = self.options['gan_smoothing'] = self.load_or_def_option('gan_smoothing', 0.1)
@ -178,6 +180,8 @@ Examples: df, liae, df-d, df-ud, liae-ud, ...
self.options['gan_power'] = np.clip ( io.input_number ("GAN power", default_gan_power, add_info="0.0 .. 10.0", help_message="Train the network in Generative Adversarial manner. Forces the neural network to learn small details of the face. Enable it only when the face is trained enough and don't disable. Typical value is 0.1"), 0.0, 10.0 )
if self.options['gan_power'] != 0.0:
self.options['gan_version'] = np.clip (io.input_int("GAN version", default_gan_version, add_info="2 or 3", help_message="Choose GAN version (v2: 7/16/2020, v3: 1/3/2021):"), 2, 3)
if self.options['gan_version'] == 3:
gan_patch_size = np.clip ( io.input_int("GAN patch size", default_gan_patch_size, add_info="3-640", help_message="The higher patch size, the higher the quality, the more VRAM is required. You can get sharper edges even at the lowest setting. Typical fine value is resolution / 8." ), 3, 640 )
self.options['gan_patch_size'] = gan_patch_size
@ -253,10 +257,6 @@ Examples: df, liae, df-d, df-ud, liae-ud, ...
if self.is_exporting:
use_fp16 = io.input_bool ("Export quantized?", False, help_message='Makes the exported model faster. If you have problems, disable this option.')
use_fp16 = False
if self.is_exporting:
use_fp16 = io.input_bool ("Export quantized?", False, help_message='Makes the exported model faster. If you have problems, disable this option.')
self.gan_power = gan_power = 0.0 if self.pretrain else self.options['gan_power']
random_warp = False if self.pretrain else self.options['random_warp']
random_src_flip = self.random_src_flip if not self.pretrain else True
@ -440,22 +440,6 @@ Examples: df, liae, df-d, df-ud, liae-ud, ...
y = tf.where(tf.equal(y, 0), tf.ones_like(y), y)
gpu_target_dst = gpu_target_dst*gpu_target_dstm_all + (x/y)*gpu_target_dstm_anti
gpu_target_srcm_anti = 1-gpu_target_srcm
gpu_target_dstm_anti = 1-gpu_target_dstm
if blur_out_mask:
sigma = resolution / 128
x = nn.gaussian_blur(gpu_target_src*gpu_target_srcm_anti, sigma)
y = 1-nn.gaussian_blur(gpu_target_srcm, sigma)
y = tf.where(tf.equal(y, 0), tf.ones_like(y), y)
gpu_target_src = gpu_target_src*gpu_target_srcm + (x/y)*gpu_target_srcm_anti
x = nn.gaussian_blur(gpu_target_dst*gpu_target_dstm_anti, sigma)
y = 1-nn.gaussian_blur(gpu_target_dstm, sigma)
y = tf.where(tf.equal(y, 0), tf.ones_like(y), y)
gpu_target_dst = gpu_target_dst*gpu_target_dstm + (x/y)*gpu_target_dstm_anti
# process model tensors
if 'df' in archi_type:
@ -822,7 +806,7 @@ Examples: df, liae, df-d, df-ud, liae-ud, ...
'random_noise': self.options['random_noise'],
'random_blur': self.options['random_blur'],
'random_jpeg': self.options['random_jpeg'],
'transform':True, 'channel_type' : channel_type, 'ct_mode': ct_mode,
'transform':True, 'channel_type' : channel_type, 'ct_mode': ct_mode, 'random_hsv_shift_amount' : random_hsv_power,
'face_type':self.face_type, 'data_format':nn.data_format, 'resolution': resolution},
{'sample_type': SampleProcessor.SampleType.FACE_IMAGE,'warp':False , 'transform':True, 'channel_type' : channel_type, 'ct_mode': ct_mode, 'face_type':self.face_type, 'data_format':nn.data_format, 'resolution': resolution},
{'sample_type': SampleProcessor.SampleType.FACE_MASK, 'warp':False , 'transform':True, 'channel_type' : SampleProcessor.ChannelType.G, 'face_mask_type' : SampleProcessor.FaceMaskType.FULL_FACE, 'face_type':self.face_type, 'data_format':nn.data_format, 'resolution': resolution},

View file

@ -9,3 +9,5 @@ scipy==1.4.1
colorama
tensorflow-gpu==2.4.0
tf2onnx==1.9.3
tensorboardX
crc32c

View file

@ -12,3 +12,5 @@ pyqt5
tf2onnx==1.9.3
Flask==1.1.1
flask-socketio==4.2.1
tensorboardX
crc32c