未验证 提交 de021e4e 编写于 作者: L lvmengsi 提交者: GitHub

update reader and spade (#3400)

上级 554d8864
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
3. CGAN和DCGAN两个模型训练使用的数据集为MNIST数据集;StarGAN,AttGAN和STGAN的数据集为CelebA数据集。Pix2Pix和CycleGAN支持的数据集可以参考download.py中的cycle_pix_dataset。 3. CGAN和DCGAN两个模型训练使用的数据集为MNIST数据集;StarGAN,AttGAN和STGAN的数据集为CelebA数据集。Pix2Pix和CycleGAN支持的数据集可以参考download.py中的cycle_pix_dataset。
4. PaddlePaddle1.5.1及之前的版本不支持在AttGAN和STGAN模型里的判别器加上的instance norm。如果要在判别器中加上instance norm,请源码编译develop分支并安装。 4. PaddlePaddle1.5.1及之前的版本不支持在AttGAN和STGAN模型里的判别器加上的instance norm。如果要在判别器中加上instance norm,请源码编译develop分支并安装。
5. 中间效果图保存在${output_dir}/test文件夹中。对于Pix2Pix来说,inputA 和inputB 代表输入的两种风格的图片,fakeB表示生成图片;对于CycleGAN来说,inputA表示输入图片,fakeB表示inputA根据生成的图片,cycA表示fakeB经过生成器重构出来的对应于inputA的重构图片;对于StarGAN,AttGAN和STGAN来说,第一行表示原图,之后的每一行都代表一种属性变换。 5. 中间效果图保存在${output_dir}/test文件夹中。对于Pix2Pix来说,inputA 和inputB 代表输入的两种风格的图片,fakeB表示生成图片;对于CycleGAN来说,inputA表示输入图片,fakeB表示inputA根据生成的图片,cycA表示fakeB经过生成器重构出来的对应于inputA的重构图片;对于StarGAN,AttGAN和STGAN来说,第一行表示原图,之后的每一行都代表一种属性变换。
6. infer过程使用的test_list文件和训练过程中使用的train_list具有相同格式,第一行为样本数量,第二行为属性,之后的行中第一个表示图片名称,之后的-1和1表示该图片是否拥有该属性(1为有该属性,-1为没有该属性)。
图像生成模型库库的目录结构如下: 图像生成模型库库的目录结构如下:
``` ```
...@@ -139,6 +140,7 @@ StarGAN, AttGAN和STGAN所需要的[Celeba](http://mmlab.ie.cuhk.edu.hk/projects ...@@ -139,6 +140,7 @@ StarGAN, AttGAN和STGAN所需要的[Celeba](http://mmlab.ie.cuhk.edu.hk/projects
python infer.py \ python infer.py \
--model_net=$(StarGAN_or_AttGAN_or_STGAN) \ --model_net=$(StarGAN_or_AttGAN_or_STGAN) \
--init_model=$(path_to_init_model)\ --init_model=$(path_to_init_model)\
--test_list=$(path_to_test_list)\
--dataset_dir=$(path_to_data) --dataset_dir=$(path_to_data)
Pix2Pix和CycleGAN的效果如图所示: Pix2Pix和CycleGAN的效果如图所示:
......
...@@ -237,8 +237,8 @@ class triplex_reader_creator(reader_creator): ...@@ -237,8 +237,8 @@ class triplex_reader_creator(reader_creator):
batch_size=batch_size, batch_size=batch_size,
mode=mode) mode=mode)
self.name2id = {} self.name2id = {}
self.id2name = {} self.id2name = {}
def make_reader(self, args, return_name=False): def make_reader(self, args, return_name=False):
print(self.image_dir, self.list_filename) print(self.image_dir, self.list_filename)
...@@ -376,13 +376,18 @@ class celeba_reader_creator(reader_creator): ...@@ -376,13 +376,18 @@ class celeba_reader_creator(reader_creator):
self.batch_size = args.batch_size self.batch_size = args.batch_size
self.shuffle = args.shuffle self.shuffle = args.shuffle
lines = lines[2:train_end] lines = lines[2:train_end]
else: elif self.mode == 'TEST':
self.batch_size = args.n_samples self.batch_size = args.n_samples
self.shuffle = False self.shuffle = False
if self.mode == "TEST": lines = lines[train_end:test_end]
lines = lines[train_end:test_end] elif self.mode == 'VAL':
else: self.batch_size = args.n_samples
lines = lines[test_end:] self.shuffle = False
lines = lines[2:]
else:
raise NotImplementedError(
"Wrong Reader MODE: {}, mode must in [TRAIN|TEST|VAL]".format(
self.mode))
self.images = [] self.images = []
attr_names = args.selected_attrs.split(',') attr_names = args.selected_attrs.split(',')
......
...@@ -20,6 +20,7 @@ from .base_network import conv2d, deconv2d, norm_layer, conv2d_spectral_norm ...@@ -20,6 +20,7 @@ from .base_network import conv2d, deconv2d, norm_layer, conv2d_spectral_norm
import paddle.fluid as fluid import paddle.fluid as fluid
import numpy as np import numpy as np
class SPADE_model(object): class SPADE_model(object):
def __init__(self): def __init__(self):
pass pass
...@@ -30,80 +31,175 @@ class SPADE_model(object): ...@@ -30,80 +31,175 @@ class SPADE_model(object):
sw = cfg.crop_width // (2**num_up_layers) sw = cfg.crop_width // (2**num_up_layers)
sh = cfg.crop_height // (2**num_up_layers) sh = cfg.crop_height // (2**num_up_layers)
seg = input seg = input
x = fluid.layers.resize_nearest(seg, out_shape=(sh, sw), align_corners=False) x = fluid.layers.resize_nearest(
x = conv2d(x, 16*nf,3,padding=1,name=name + "_fc",use_bias=True, is_test=is_test) seg, out_shape=(sh, sw), align_corners=False)
x = self.SPADEResnetBlock(x, seg, 16 * nf, 16 * nf, cfg, name=name+"_head_0", is_test=is_test) x = conv2d(
x = fluid.layers.resize_nearest(x, scale=2, align_corners=False) x,
x = self.SPADEResnetBlock(x, seg, 16 * nf, 16 * nf, cfg, name=name+"_G_middle_0", is_test=is_test) 16 * nf,
x = self.SPADEResnetBlock(x, seg, 16 * nf, 16 * nf, cfg, name=name+"_G_middle_1", is_test=is_test) 3,
x = fluid.layers.resize_nearest(x, scale=2, align_corners=False) padding=1,
name=name + "_fc",
x = self.SPADEResnetBlock(x, seg, 16 * nf, 8 * nf, cfg, name=name+"_up_0", is_test=is_test) use_bias=True,
x = fluid.layers.resize_nearest(x, scale=2, align_corners=False) is_test=is_test)
x = self.SPADEResnetBlock(x, seg, 8 * nf, 4 * nf, cfg, name=name+"_up_1", is_test=is_test) x = self.SPADEResnetBlock(
x = fluid.layers.resize_nearest(x, scale=2, align_corners=False) x,
x = self.SPADEResnetBlock(x, seg, 4 * nf, 2 * nf, cfg, name=name+"_up_2", is_test=is_test) seg,
x = fluid.layers.resize_nearest(x, scale=2, align_corners=False) 16 * nf,
x = self.SPADEResnetBlock(x, seg, 2 * nf, 1 * nf, cfg, name=name+"_up_3", is_test=is_test) 16 * nf,
cfg,
name=name + "_head_0",
is_test=is_test)
x = fluid.layers.resize_nearest(x, scale=2.0, align_corners=False)
x = self.SPADEResnetBlock(
x,
seg,
16 * nf,
16 * nf,
cfg,
name=name + "_G_middle_0",
is_test=is_test)
x = self.SPADEResnetBlock(
x,
seg,
16 * nf,
16 * nf,
cfg,
name=name + "_G_middle_1",
is_test=is_test)
x = fluid.layers.resize_nearest(x, scale=2.0, align_corners=False)
x = self.SPADEResnetBlock(
x, seg, 16 * nf, 8 * nf, cfg, name=name + "_up_0", is_test=is_test)
x = fluid.layers.resize_nearest(x, scale=2.0, align_corners=False)
x = self.SPADEResnetBlock(
x, seg, 8 * nf, 4 * nf, cfg, name=name + "_up_1", is_test=is_test)
x = fluid.layers.resize_nearest(x, scale=2.0, align_corners=False)
x = self.SPADEResnetBlock(
x, seg, 4 * nf, 2 * nf, cfg, name=name + "_up_2", is_test=is_test)
x = fluid.layers.resize_nearest(x, scale=2.0, align_corners=False)
x = self.SPADEResnetBlock(
x, seg, 2 * nf, 1 * nf, cfg, name=name + "_up_3", is_test=is_test)
x = fluid.layers.leaky_relu( x = fluid.layers.leaky_relu(
x, alpha=0.2, name=name + '_conv_img_leaky_relu') x, alpha=0.2, name=name + '_conv_img_leaky_relu')
x = conv2d(x, 3,3,padding=1,name=name + "_conv_img",use_bias=True, is_test=is_test) x = conv2d(
x,
3,
3,
padding=1,
name=name + "_conv_img",
use_bias=True,
is_test=is_test)
x = fluid.layers.tanh(x) x = fluid.layers.tanh(x)
return x return x
def SPADEResnetBlock(self, x, seg, fin, fout, opt, name, is_test=False): def SPADEResnetBlock(self, x, seg, fin, fout, opt, name, is_test=False):
learn_shortcut = (fin != fout) learn_shortcut = (fin != fout)
fmiddle = min(fin, fout) fmiddle = min(fin, fout)
semantic_nc = opt.label_nc + (0 if opt.no_instance else 1) semantic_nc = opt.label_nc + (0 if opt.no_instance else 1)
if learn_shortcut: if learn_shortcut:
x_s = self.SPADE(x, seg, fin, name=name+".norm_s", is_test=is_test) x_s = self.SPADE(
x_s = conv2d_spectral_norm(x_s, fout,1,use_bias=False, name=name + ".conv_s", is_test=is_test) x, seg, fin, name=name + ".norm_s", is_test=is_test)
x_s = conv2d_spectral_norm(
x_s,
fout,
1,
use_bias=False,
name=name + ".conv_s",
is_test=is_test)
else: else:
x_s = x x_s = x
dx = self.SPADE(x, seg, fin, name=name+".norm_0", is_test=is_test) dx = self.SPADE(x, seg, fin, name=name + ".norm_0", is_test=is_test)
dx = fluid.layers.leaky_relu(dx, alpha=0.2, name=name+'_leaky_relu0') dx = fluid.layers.leaky_relu(dx, alpha=0.2, name=name + '_leaky_relu0')
dx = conv2d_spectral_norm(dx, fmiddle,3,padding=1,name=name + ".conv_0", use_bias=True, is_test=is_test) dx = conv2d_spectral_norm(
dx,
dx = self.SPADE(dx, seg, fmiddle, name=name+".norm_1", is_test=is_test) fmiddle,
dx = fluid.layers.leaky_relu(dx, alpha=0.2, name=name+'_leaky_relu1') 3,
dx = conv2d_spectral_norm(dx, fout,3,padding=1,name=name + ".conv_1", use_bias=True, is_test=is_test) padding=1,
name=name + ".conv_0",
use_bias=True,
is_test=is_test)
dx = self.SPADE(
dx, seg, fmiddle, name=name + ".norm_1", is_test=is_test)
dx = fluid.layers.leaky_relu(dx, alpha=0.2, name=name + '_leaky_relu1')
dx = conv2d_spectral_norm(
dx,
fout,
3,
padding=1,
name=name + ".conv_1",
use_bias=True,
is_test=is_test)
output = dx + x_s output = dx + x_s
return output return output
def SPADE(self, input, seg_map, norm_nc, name, is_test=False): def SPADE(self, input, seg_map, norm_nc, name, is_test=False):
nhidden = 128 nhidden = 128
ks = 3 ks = 3
pw = ks // 2 pw = ks // 2
seg_map = fluid.layers.resize_nearest(seg_map, out_shape=input.shape[2:], align_corners=False) seg_map = fluid.layers.resize_nearest(
actv = conv2d(seg_map, nhidden, ks, padding=pw, activation_fn='relu', name=name+".mlp_shared.0", use_bias=True) seg_map, out_shape=input.shape[2:], align_corners=False)
gamma = conv2d(actv, norm_nc, ks, padding=pw, name=name+".mlp_gamma", use_bias=True) actv = conv2d(
beta = conv2d(actv, norm_nc, ks, padding=pw, name=name+".mlp_beta", use_bias=True) seg_map,
nhidden,
ks,
padding=pw,
activation_fn='relu',
name=name + ".mlp_shared.0",
use_bias=True)
gamma = conv2d(
actv,
norm_nc,
ks,
padding=pw,
name=name + ".mlp_gamma",
use_bias=True)
beta = conv2d(
actv,
norm_nc,
ks,
padding=pw,
name=name + ".mlp_beta",
use_bias=True)
param_attr = fluid.ParamAttr( param_attr = fluid.ParamAttr(
name=name + ".param_free_norm.weight", name=name + ".param_free_norm.weight",
initializer=fluid.initializer.Constant(value=1.0), trainable=False) initializer=fluid.initializer.Constant(value=1.0),
trainable=False)
bias_attr = fluid.ParamAttr( bias_attr = fluid.ParamAttr(
name=name+".param_free_norm.bias", initializer=fluid.initializer.Constant(0.0), trainable=False) name=name + ".param_free_norm.bias",
initializer=fluid.initializer.Constant(0.0),
norm = fluid.layers.batch_norm(input=input, name=name, param_attr=param_attr, trainable=False)
bias_attr=bias_attr, moving_mean_name=name+".param_free_norm.running_mean", moving_variance_name=name+".param_free_norm.running_var", is_test=is_test)
norm = fluid.layers.batch_norm(
input=input,
name=name,
param_attr=param_attr,
bias_attr=bias_attr,
moving_mean_name=name + ".param_free_norm.running_mean",
moving_variance_name=name + ".param_free_norm.running_var",
is_test=is_test)
out = norm * (1 + gamma) + beta out = norm * (1 + gamma) + beta
return out return out
def network_D(self, input, name, cfg): def network_D(self, input, name, cfg):
num_D = 2 num_D = 2
result = [] result = []
for i in range(num_D): for i in range(num_D):
out = build_discriminator_Nlayers(input, name=name+"_%d"%i) out = build_discriminator_Nlayers(input, name=name + "_%d" % i)
result.append(out) result.append(out)
input = fluid.layers.pool2d(input, pool_size=3, pool_type="avg", pool_stride=2, pool_padding=1, name=name+"_pool%d"%i) input = fluid.layers.pool2d(
input,
pool_size=3,
pool_type="avg",
pool_stride=2,
pool_padding=1,
name=name + "_pool%d" % i)
return result return result
def build_discriminator_Nlayers(input, def build_discriminator_Nlayers(input,
name="discriminator", name="discriminator",
d_nlayers=4, d_nlayers=4,
...@@ -128,7 +224,7 @@ def build_discriminator_Nlayers(input, ...@@ -128,7 +224,7 @@ def build_discriminator_Nlayers(input,
res_list.append(res1) res_list.append(res1)
for i in range(1, d_nlayers): for i in range(1, d_nlayers):
conv_name = name + ".model{}.0.0".format(i) conv_name = name + ".model{}.0.0".format(i)
nf = min(nf*2, 512) nf = min(nf * 2, 512)
stride = 1 if i == d_nlayers - 1 else 2 stride = 1 if i == d_nlayers - 1 else 2
dis_output = conv2d_spectral_norm( dis_output = conv2d_spectral_norm(
res_list[-1], res_list[-1],
...@@ -141,7 +237,8 @@ def build_discriminator_Nlayers(input, ...@@ -141,7 +237,8 @@ def build_discriminator_Nlayers(input,
norm=norm_type, norm=norm_type,
activation_fn='leaky_relu', activation_fn='leaky_relu',
relufactor=0.2, relufactor=0.2,
use_bias=False, norm_affine=False) use_bias=False,
norm_affine=False)
res_list.append(dis_output) res_list.append(dis_output)
o_c4 = conv2d( o_c4 = conv2d(
res_list[-1], res_list[-1],
...@@ -154,4 +251,3 @@ def build_discriminator_Nlayers(input, ...@@ -154,4 +251,3 @@ def build_discriminator_Nlayers(input,
use_bias=True) use_bias=True)
res_list.append(o_c4) res_list.append(o_c4)
return res_list return res_list
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册