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

GAN model library (#2101)

GAN model
上级 53ea0f31
......@@ -6,7 +6,7 @@ import paddle.fluid as fluid
import paddle
import numpy as np
from scipy.misc import imsave
from model import *
from model import build_generator_resnet_9blocks, build_gen_discriminator
import glob
from utility import add_arguments, print_arguments
......
from layers import *
from layers import conv2d, deconv2d
import paddle.fluid as fluid
......
......@@ -14,7 +14,7 @@ import paddle.fluid as fluid
import paddle.fluid.profiler as profiler
import data_reader
from utility import add_arguments, print_arguments, ImagePool
from trainer import *
from trainer import GATrainer, GBTrainer, DATrainer, DBTrainer
parser = argparse.ArgumentParser(description=__doc__)
add_arg = functools.partial(add_arguments, argparser=parser)
......
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from model import *
from model import build_generator_resnet_9blocks, build_gen_discriminator
import paddle.fluid as fluid
step_per_epoch = 1335
......
......@@ -21,7 +21,6 @@ import six
import random
import glob
import numpy as np
from paddle.fluid import core
def print_arguments(args):
......
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import print_function
from six.moves import range
from PIL import Image, ImageOps
import gzip
import numpy as np
import argparse
import struct
import os
import paddle
def RandomCrop(img, crop_w, crop_h):
w, h = img.shape[0], img.shape[1]
i = np.random.randint(0, w - crop_w)
j = np.random.randint(0, h - crop_h)
return img.crop((i, j, i + crop_w, j + crop_h))
def CentorCrop(img, crop_w, crop_h):
w, h = img.size[0], img.size[1]
i = int((w - crop_w) / 2.0)
j = int((h - crop_h) / 2.0)
return img.crop((i, j, i + crop_w, j + crop_h))
def RandomHorizonFlip(img):
i = np.random.rand()
if i > 0.5:
img = ImageOps.mirror(image)
return img
class reader_creator(object):
''' read and preprocess dataset'''
def __init__(self, image_dir, list_filename, batch_size=1, drop_last=False):
self.image_dir = image_dir
self.list_filename = list_filename
self.batch_size = batch_size
self.drop_last = drop_last
self.lines = open(self.list_filename).readlines()
def len(self):
if self.drop_last or len(self.lines) % self.batch_size == 0:
return len(self.lines) // self.batch_size
else:
return len(self.lines) // self.batch_size + 1
def get_train_reader(self, args, shuffle=False, return_name=False):
print(self.image_dir, self.list_filename)
def reader():
batch_out = []
while True:
if shuffle:
np.random.shuffle(self.lines)
for file in self.lines:
file = file.strip('\n\r\t ')
img = Image.open(os.path.join(self.image_dir,
file)).convert('RGB')
img = img.resize((args.load_size, args.load_size),
Image.BICUBIC)
if args.crop_type == 'Centor':
img = CentorCrop(img, args.crop_size, args.crop_size)
elif args.crop_type == 'Random':
img = RandomCrop(img, args.crop_size, args.crop_size)
img = (np.array(img).astype('float32') / 255.0 - 0.5) / 0.5
img = img.transpose([2, 0, 1])
if return_name:
batch_out.append([img, os.path.basename(file)])
else:
batch_out.append(img)
if len(batch_out) == self.batch_size:
yield batch_out
batch_out = []
if self.drop_last == False and len(batch_out) != 0:
yield batch_out
return reader
def get_test_reader(self, args, shuffle=False, return_name=False):
print(self.image_dir, self.list_filename)
def reader():
batch_out = []
for file in self.lines:
file = file.strip('\n\r\t ')
img = Image.open(os.path.join(self.image_dir, file)).convert(
'RGB')
img = img.resize((args.crop_size, args.crop_size),
Image.BICUBIC)
img = (np.array(img).astype('float32') / 255.0 - 0.5) / 0.5
img = img.transpose([2, 0, 1])
if return_name:
batch_out.append(
[img[np.newaxis, :], os.path.basename(file)])
else:
batch_out.append(img)
if len(batch_out) == self.batch_size:
yield batch_out
batch_out = []
if len(batch_out) != 0:
yield batch_out
return reader
def mnist_reader_creator(image_filename, label_filename, buffer_size):
def reader():
with gzip.GzipFile(image_filename, 'rb') as image_file:
img_buf = image_file.read()
with gzip.GzipFile(label_filename, 'rb') as label_file:
lab_buf = label_file.read()
step_label = 0
offset_img = 0
# read from Big-endian
# get file info from magic byte
# image file : 16B
magic_byte_img = '>IIII'
magic_img, image_num, rows, cols = struct.unpack_from(
magic_byte_img, img_buf, offset_img)
offset_img += struct.calcsize(magic_byte_img)
offset_lab = 0
# label file : 8B
magic_byte_lab = '>II'
magic_lab, label_num = struct.unpack_from(magic_byte_lab,
lab_buf, offset_lab)
offset_lab += struct.calcsize(magic_byte_lab)
while True:
if step_label >= label_num:
break
fmt_label = '>' + str(buffer_size) + 'B'
labels = struct.unpack_from(fmt_label, lab_buf, offset_lab)
offset_lab += struct.calcsize(fmt_label)
step_label += buffer_size
fmt_images = '>' + str(buffer_size * rows * cols) + 'B'
images_temp = struct.unpack_from(fmt_images, img_buf,
offset_img)
images = np.reshape(images_temp, (buffer_size, rows *
cols)).astype('float32')
offset_img += struct.calcsize(fmt_images)
images = images / 255.0 * 2.0 - 1.0
for i in range(buffer_size):
yield images[i, :], int(
labels[i]) # get image and label
return reader
class data_reader(object):
def __init__(self, cfg):
self.cfg = cfg
self.shuffle = self.cfg.shuffle
def make_data(self):
if self.cfg.dataset == 'mnist':
train_images = os.path.join(self.cfg.data_dir, self.cfg.dataset,
"train-images-idx3-ubyte.gz")
train_labels = os.path.join(self.cfg.data_dir, self.cfg.dataset,
"train-labels-idx1-ubyte.gz")
train_reader = paddle.batch(
paddle.reader.shuffle(
mnist_reader_creator(train_images, train_labels, 100),
buf_size=60000),
batch_size=self.cfg.batch_size)
return train_reader
else:
if self.cfg.model_net == 'CycleGAN':
dataset_dir = os.path.join(self.cfg.data_dir, self.cfg.dataset)
trainA_list = os.path.join(dataset_dir, "trainA.txt")
trainB_list = os.path.join(dataset_dir, "trainB.txt")
a_train_reader = reader_creator(
image_dir=dataset_dir,
list_filename=trainA_list,
batch_size=self.cfg.batch_size,
drop_last=self.cfg.drop_last)
b_train_reader = reader_creator(
image_dir=dataset_dir,
list_filename=trainB_list,
batch_size=self.cfg.batch_size,
drop_last=self.cfg.drop_last)
a_reader_test = None
b_reader_test = None
if self.cfg.run_test:
testA_list = os.path.join(dataset_dir, "testA.txt")
testB_list = os.path.join(dataset_dir, "testB.txt")
a_test_reader = reader_creator(
image_dir=dataset_dir,
list_filename=testA_list,
batch_size=1,
drop_last=self.cfg.drop_last)
b_test_reader = reader_creator(
image_dir=dataset_dir,
list_filename=testB_list,
batch_size=1,
drop_last=self.cfg.drop_last)
a_reader_test = a_test_reader.get_test_reader(
self.cfg, shuffle=False, return_name=True)
b_reader_test = b_test_reader.get_test_reader(
self.cfg, shuffle=False, return_name=True)
batch_num = max(a_train_reader.len(), b_train_reader.len())
a_reader = a_train_reader.get_train_reader(
self.cfg, shuffle=self.shuffle)
b_reader = b_train_reader.get_train_reader(
self.cfg, shuffle=self.shuffle)
return a_reader, b_reader, a_reader_test, b_reader_test, batch_num
else:
dataset_dir = os.path.join(self.cfg.data_dir, self.cfg.dataset)
train_list = os.path.join(dataset_dir, 'train.txt')
if self.cfg.data_list is not None:
train_list = self.cfg.data_list
train_reader = reader_creator(
image_dir=dataset_dir, list_filename=train_list)
reader_test = None
if self.cfg.run_test:
test_list = os.path.join(dataset_dir, "test.txt")
test_reader = reader_creator(
image_dir=dataset_dir,
list_filename=test_list,
batch_size=1,
drop_last=self.cfg.drop_last)
reader_test = test_reader.get_test_reader(
self.cfg, shuffle=False, return_name=True)
batch_num = train_reader.len()
return train_reader, reader_test, batch_num
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import print_function
from PIL import Image
import numpy as np
import os
import sys
import gzip
import argparse
import requests
import six
import hashlib
parser = argparse.ArgumentParser(description='Download dataset.')
#TODO add celeA dataset
parser.add_argument(
'--dataset',
type=str,
default='mnist',
help='name of dataset to download [mnist]')
def md5file(fname):
hash_md5 = hashlib.md5()
f = open(fname, "rb")
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
f.close()
return hash_md5.hexdigest()
def download_mnist(dir_path):
URL_DIC = {}
URL_PREFIX = 'http://yann.lecun.com/exdb/mnist/'
TEST_IMAGE_URL = URL_PREFIX + 't10k-images-idx3-ubyte.gz'
TEST_IMAGE_MD5 = '9fb629c4189551a2d022fa330f9573f3'
TEST_LABEL_URL = URL_PREFIX + 't10k-labels-idx1-ubyte.gz'
TEST_LABEL_MD5 = 'ec29112dd5afa0611ce80d1b7f02629c'
TRAIN_IMAGE_URL = URL_PREFIX + 'train-images-idx3-ubyte.gz'
TRAIN_IMAGE_MD5 = 'f68b3c2dcbeaaa9fbdd348bbdeb94873'
TRAIN_LABEL_URL = URL_PREFIX + 'train-labels-idx1-ubyte.gz'
TRAIN_LABEL_MD5 = 'd53e105ee54ea40749a09fcbcd1e9432'
URL_DIC[TRAIN_IMAGE_URL] = TRAIN_IMAGE_MD5
URL_DIC[TRAIN_LABEL_URL] = TRAIN_LABEL_MD5
URL_DIC[TEST_IMAGE_URL] = TEST_IMAGE_MD5
URL_DIC[TEST_LABEL_URL] = TEST_LABEL_MD5
### print(url)
for url in URL_DIC:
md5sum = URL_DIC[url]
data_dir = os.path.join(dir_path + 'mnist')
if not os.path.exists(data_dir):
os.makedirs(data_dir)
filename = os.path.join(data_dir, url.split('/')[-1])
retry = 0
retry_limit = 3
while not (os.path.exists(filename) and md5file(filename) == md5sum):
if os.path.exists(filename):
sys.stderr.write("file %s md5 %s" %
(md5file(filename), md5sum))
if retry < retry_limit:
retry += 1
else:
raise RuntimeError("Cannot download {0} within retry limit {1}".
format(url, retry_limit))
sys.stderr.write("Cache file %s not found, downloading %s" %
(filename, url))
r = requests.get(url, stream=True)
total_length = r.headers.get('content-length')
if total_length is None:
with open(filename, 'wb') as f:
shutil.copyfileobj(r.raw, f)
else:
with open(filename, 'wb') as f:
dl = 0
total_length = int(total_length)
for data in r.iter_content(chunk_size=4096):
if six.PY2:
data = six.b(data)
dl += len(data)
f.write(data)
done = int(50 * dl / total_length)
sys.stderr.write("\r[%s%s]" % ('=' * done,
' ' * (50 - done)))
sys.stdout.flush()
sys.stderr.write("\n")
sys.stdout.flush()
print(filename)
def download_cycle_pix(dir_path, dataname):
URL_PREFIX = 'https://people.eecs.berkeley.edu/~taesung_park/CycleGAN/datasets/'
IMAGE_URL = '{}.zip'.format(dataname)
url = URL_PREFIX + IMAGE_URL
if not os.path.exists(dir_path):
os.makedirs(dir_path)
r = requests.get(url, stream=True)
total_length = float(r.headers.get('content-length'))
filename = os.path.join(dir_path, IMAGE_URL)
print(filename)
if not os.path.exists(filename):
dl = 0
with open(filename, "wb") as f:
for data in r.iter_content(chunk_size=4096):
if six.PY2:
data = six.b(data)
dl += len(data)
f.write(data)
done = int(100 * dl / total_length)
sys.stderr.write("\r[{}{}] {}% ".format('=' * done, ' ' * (
100 - done), done))
sys.stdout.flush()
else:
sys.stderr.write('{}.zip is EXIST, DO NOT NEED to download it again.'.
format(dataname))
### unzip .zip file
if not os.path.exists(os.path.join(dir_path, '{}'.format(dataname))):
zip_f = zipfile.ZipFile(filename, 'r')
for zip_file in zip_f.namelist():
zip_f.extract(zip_file, dir_path)
### generator .txt file according to dirs
dirs = os.listdir(os.path.join(dir_path, '{}'.format(dataname)))
for d in dirs:
txt_file = d + '.txt'
txt_dir = os.path.join(dir_path, dataname)
f = open(os.path.join(txt_dir, txt_file), 'w')
for fil in os.listdir(os.path.join(txt_dir, d)):
wl = d + '/' + fil + '\n'
f.write(wl)
f.close()
sys.stderr.write("\n")
if __name__ == '__main__':
args = parser.parse_args()
cycle_pix_dataset = [
'apple2orange', 'summer2winter_yosemite', 'horse2zebra', 'monet2photo',
'cezanne2photo', 'ukiyoe2photo', 'vangogh2photo', 'maps', 'cityscapes',
'facades', 'iphone2dslr_flower', 'ae_photos', 'mini'
]
if args.dataset == 'mnist':
print('Download dataset: {}'.format(args.dataset))
download_mnist('./data/')
elif args.dataset in cycle_pix_dataset:
print('Download dataset: {}'.format(args.dataset))
download_cycle_pix('./data/', args.dataset)
else:
print('Please download by yourself, thanks')
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import functools
import os
from PIL import Image
import paddle.fluid as fluid
import paddle
import numpy as np
from scipy.misc import imsave
import glob
from util.config import add_arguments, print_arguments
parser = argparse.ArgumentParser(description=__doc__)
add_arg = functools.partial(add_arguments, argparser=parser)
# yapf: disable
add_arg('model_net', str, 'cgan', "The model used")
add_arg('net_G', str, "resnet_9block", "Choose the CycleGAN generator's network, choose in [resnet_9block|resnet_6block|unet_128|unet_256]")
add_arg('input', str, None, "The images to be infered.")
add_arg('init_model', str, None, "The init model file of directory.")
add_arg('output', str, "./infer_result", "The directory the infer result to be saved to.")
add_arg('input_style', str, "A", "The style of the input, A or B")
add_arg('norm_type', str, "batch_norm", "Which normalization to used")
add_arg('use_gpu', bool, True, "Whether to use GPU to train.")
add_arg('dropout', bool, False, "Whether to use dropout")
add_arg('data_shape', int, 256, "The shape of load image")
add_arg('g_base_dims', int, 64, "Base channels in CycleGAN generator")
# yapf: enable
def infer(args):
data_shape = [-1, 3, args.data_shape, args.data_shape]
input = fluid.layers.data(name='input', shape=data_shape, dtype='float32')
model_name = 'net_G'
if args.model_net == 'cyclegan':
from network.CycleGAN_network import network_G, network_D
if args.input_style == "A":
fake = network_G(input, name="GA", cfg=args)
elif args.input_style == "B":
fake = network_G(input, name="GB", cfg=args)
else:
raise "Input with style [%s] is not supported." % args.input_style
elif args.model_net == 'cgan':
pass
else:
pass
# prepare environment
place = fluid.CPUPlace()
if args.use_gpu:
place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
for var in fluid.default_main_program().global_block().all_parameters():
print(var.name)
print(args.init_model + '/' + model_name)
fluid.io.load_persistables(exe, args.init_model + "/" + model_name)
print('load params done')
if not os.path.exists(args.output):
os.makedirs(args.output)
for file in glob.glob(args.input):
print("read {}".format(file))
image_name = os.path.basename(file)
image = Image.open(file).convert('RGB')
image = image.resize((256, 256), Image.BICUBIC)
image = np.array(image).transpose([2, 0, 1]).astype('float32')
image = image / 255.0
image = (image - 0.5) / 0.5
data = image[np.newaxis, :]
tensor = fluid.LoDTensor()
tensor.set(data, place)
fake_temp = exe.run(fetch_list=[fake.name], feed={"input": tensor})
fake_temp = np.squeeze(fake_temp[0]).transpose([1, 2, 0])
input_temp = np.squeeze(data).transpose([1, 2, 0])
imsave(args.output + "/fake_" + image_name, (
(fake_temp + 1) * 127.5).astype(np.uint8))
if __name__ == "__main__":
args = parser.parse_args()
print_arguments(args)
infer(args)
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from .base_network import linear, conv2d, deconv2d, conv_cond_concat
import paddle.fluid as fluid
import numpy as np
import time
import os
import sys
class CGAN_model(object):
def __init__(self, batch_size=1):
self.batch_size = batch_size
self.img_w = 28
self.img_h = 28
self.y_dim = 1
self.gf_dim = 128
self.df_dim = 64
self.leaky_relu_factor = 0.2
def network_G(self, input, label, name="generator"):
# concat noise and label
y = fluid.layers.reshape(label, shape=[-1, self.y_dim, 1, 1])
xy = fluid.layers.concat([input, y], 1)
o_l1 = linear(
xy,
self.gf_dim * 8,
norm='batch_norm',
activation_fn='relu',
name=name + '_l1')
o_c1 = fluid.layers.concat([o_l1, y], 1)
o_l2 = linear(
o_c1,
self.gf_dim * (self.img_w // 4) * (self.img_h // 4),
norm='batch_norm',
activation_fn='relu',
name=name + '_l2')
o_r1 = fluid.layers.reshape(
o_l2,
shape=[-1, self.gf_dim, self.img_w // 4, self.img_h // 4],
name=name + '_reshape')
o_c2 = conv_cond_concat(o_r1, y)
o_dc1 = deconv2d(
o_c2,
self.gf_dim,
4,
2,
padding=[1, 1],
norm='batch_norm',
activation_fn='relu',
name=name + '_dc1',
output_size=[self.img_w // 2, self.img_h // 2])
o_c3 = conv_cond_concat(o_dc1, y)
o_dc2 = deconv2d(
o_dc1,
1,
4,
2,
padding=[1, 1],
activation_fn='tanh',
name=name + '_dc2',
output_size=[self.img_w, self.img_h])
out = fluid.layers.reshape(o_dc2, [-1, self.img_w * self.img_h])
return o_dc2
def network_D(self, input, label, name="discriminator"):
# concat image and label
x = fluid.layers.reshape(input, shape=[-1, 1, self.img_w, self.img_h])
y = fluid.layers.reshape(label, shape=[-1, self.y_dim, 1, 1])
xy = conv_cond_concat(x, y)
o_l1 = conv2d(
xy,
self.df_dim,
3,
2,
name=name + '_l1',
activation_fn='leaky_relu')
o_c1 = conv_cond_concat(o_l1, y)
o_l2 = conv2d(
o_c1,
self.df_dim,
3,
2,
name=name + '_l2',
norm='batch_norm',
activation_fn='leaky_relu')
o_f1 = fluid.layers.flatten(o_l2, axis=1)
o_c2 = fluid.layers.concat([o_f1, y], 1)
o_l3 = linear(
o_c2,
self.df_dim * 16,
norm='batch_norm',
activation_fn='leaky_relu',
name=name + '_l3')
o_c3 = fluid.layers.concat([o_l3, y], 1)
o_logit = linear(o_c3, 1, activation_fn='sigmoid', name=name + '_l4')
return o_logit
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from .base_network import conv2d, deconv2d, norm_layer
import paddle.fluid as fluid
class CycleGAN_model(object):
def __init__(self):
pass
def network_G(self, input, name, cfg):
if cfg.net_G == 'resnet_9block':
net = build_generator_resnet_blocks(
input,
name=name + "_resnet9block",
n_gen_res=9,
g_base_dims=cfg.g_base_dims,
use_dropout=cfg.dropout,
norm_type=cfg.norm_type)
elif cfg.net_G == 'resnet_6block':
net = build_generator_resnet_blocks(
input,
name=name + "_resnet6block",
n_gen_res=6,
g_base_dims=cfg.g_base_dims,
use_dropout=cfg.dropout,
norm_type=cfg.norm_type)
elif cfg.net_G == 'unet_128':
net = build_generator_Unet(
input,
name=name + "_unet128",
num_downsample=7,
g_base_dims=cfg.g_base_dims,
use_dropout=cfg.dropout,
norm_type=cfg.norm_type)
elif cfg.net_G == 'unet_256':
net = build_generator_Unet(
input,
name=name + "_unet256",
num_downsample=8,
g_base_dims=cfg.g_base_dims,
use_dropout=cfg.dropout,
norm_type=cfg.norm_type)
else:
raise NotImplementedError(
'network G: [%s] is wrong format, please check it' % cfg.net_G)
return net
def network_D(self, input, name, cfg):
if cfg.net_D == 'basic':
net = build_discriminator_Nlayers(
input,
name=name + '_basic',
d_nlayers=3,
d_base_dims=cfg.d_base_dims,
norm_type=cfg.norm_type)
elif cfg.net_D == 'nlayers':
net = build_discriminator_Nlayers(
input,
name=name + '_nlayers',
d_nlayers=cfg.d_nlayers,
d_base_dims=cfg.d_base_dims,
norm_type=cfg.norm_type)
elif cfg.net_D == 'pixel':
net = build_discriminator_Pixel(
input,
name=name + '_pixel',
d_base_dims=cfg.d_base_dims,
norm_type=cfg.norm_type)
else:
raise NotImplementedError(
'network D: [%s] is wrong format, please check it' % cfg.net_D)
return net
def build_resnet_block(inputres,
dim,
name="resnet",
use_bias=False,
use_dropout=False,
norm_type='batch_norm'):
out_res = fluid.layers.pad2d(inputres, [1, 1, 1, 1], mode="reflect")
out_res = conv2d(
out_res,
dim,
3,
1,
0.02,
name=name + "_c1",
norm=norm_type,
activation_fn='relu',
use_bias=use_bias)
if use_dropout:
out_res = fluid.layers.dropout(out_res, dropout_prob=0.5)
out_res = fluid.layers.pad2d(out_res, [1, 1, 1, 1], mode="reflect")
out_res = conv2d(
out_res,
dim,
3,
1,
0.02,
name=name + "_c2",
norm=norm_type,
use_bias=use_bias)
return out_res + inputres
def build_generator_resnet_blocks(inputgen,
name="generator",
n_gen_res=9,
g_base_dims=64,
use_dropout=False,
norm_type='batch_norm'):
''' generator use resnet block'''
'''The shape of input should be equal to the shape of output.'''
use_bias = norm_type == 'instance_norm'
pad_input = fluid.layers.pad2d(inputgen, [3, 3, 3, 3], mode="reflect")
o_c1 = conv2d(
pad_input,
g_base_dims,
7,
1,
0.02,
name=name + "_c1",
norm=norm_type,
activation_fn='relu')
o_c2 = conv2d(
o_c1,
g_base_dims * 2,
3,
2,
0.02,
1,
name=name + "_c2",
norm=norm_type,
activation_fn='relu')
res_input = conv2d(
o_c2,
g_base_dims * 4,
3,
2,
0.02,
1,
name=name + "_c3",
norm=norm_type,
activation_fn='relu')
for i in xrange(n_gen_res):
conv_name = name + "_r{}".format(i + 1)
res_output = build_resnet_block(
res_input,
g_base_dims * 4,
name=conv_name,
use_bias=use_bias,
use_dropout=use_dropout)
res_input = res_output
o_c4 = deconv2d(
res_output,
g_base_dims * 2,
3,
2,
0.02, [1, 1], [0, 1, 0, 1],
name=name + "_c4",
norm=norm_type,
activation_fn='relu')
o_c5 = deconv2d(
o_c4,
g_base_dims,
3,
2,
0.02, [1, 1], [0, 1, 0, 1],
name=name + "_c5",
norm=norm_type,
activation_fn='relu')
o_p2 = fluid.layers.pad2d(o_c5, [3, 3, 3, 3], mode="reflect")
o_c6 = conv2d(
o_p2,
3,
7,
1,
0.02,
name=name + "_c6",
activation_fn='tanh',
use_bias=True)
return o_c6
def Unet_block(inputunet,
i,
outer_dim,
inner_dim,
num_downsample,
innermost=False,
outermost=False,
norm_type='batch_norm',
use_bias=False,
use_dropout=False,
name=None):
if outermost == True:
downconv = conv2d(
inputunet,
inner_dim,
4,
2,
0.02,
1,
name=name + '_outermost_dc1',
use_bias=True)
i += 1
mid_block = Unet_block(
downconv,
i,
inner_dim,
inner_dim * 2,
num_downsample,
norm_type=norm_type,
use_bias=use_bias,
use_dropout=use_dropout,
name=name)
uprelu = fluid.layers.relu(mid_block, name=name + '_outermost_relu')
updeconv = deconv2d(
uprelu,
outer_dim,
4,
2,
0.02,
1,
name=name + '_outermost_uc1',
activation_fn='tanh',
use_bias=use_bias)
return updeconv
elif innermost == True:
downrelu = fluid.layers.leaky_relu(
inputunet, 0.2, name=name + '_innermost_leaky_relu')
upconv = conv2d(
downrelu,
inner_dim,
4,
2,
0.02,
1,
name=name + '_innermost_dc1',
activation_fn='relu',
use_bias=use_bias)
updeconv = deconv2d(
upconv,
outer_dim,
4,
2,
0.02,
1,
name=name + '_innermost_uc1',
norm=norm_type,
use_bias=use_bias)
return fluid.layers.concat([inputunet, updeconv], 1)
else:
downrelu = fluid.layers.leaky_relu(
inputunet, 0.2, name=name + '_leaky_relu')
downnorm = conv2d(
downrelu,
inner_dim,
4,
2,
0.02,
1,
name=name + 'dc1',
norm=norm_type,
use_bias=use_bias)
i += 1
if i < 4:
mid_block = Unet_block(
downnorm,
i,
inner_dim,
inner_dim * 2,
num_downsample,
norm_type=norm_type,
use_bias=use_bias,
name=name + '_mid{}'.format(i))
elif i < num_downsample - 1:
mid_block = Unet_block(
downnorm,
i,
inner_dim,
inner_dim,
num_downsample,
norm_type=norm_type,
use_bias=use_bias,
use_dropout=use_dropout,
name=name + '_mid{}'.format(i))
else:
mid_block = Unet_block(
downnorm,
i,
inner_dim,
inner_dim,
num_downsample,
innermost=True,
norm_type=norm_type,
use_bias=use_bias,
name=name + '_innermost')
uprelu = fluid.layers.relu(mid_block, name=name + '_relu')
updeconv = deconv2d(
uprelu,
outer_dim,
4,
2,
0.02,
1,
name=name + '_uc1',
norm=norm_type,
use_bias=use_bias)
if use_dropout:
upnorm = fluid.layers.dropout(upnorm, dropout_prob=0.5)
return fluid.layers.concat([inputunet, updeconv], 1)
def build_generator_Unet(inputgen,
name="generator",
num_downsample=7,
g_base_dims=64,
use_dropout=False,
norm_type='batch_norm'):
''' generator use Unet'''
use_bias = norm_type == 'instance_norm'
unet_block = Unet_block(
inputgen,
0,
3,
g_base_dims,
num_downsample,
outermost=True,
norm_type=norm_type,
use_bias=use_bias,
use_dropout=use_dropout,
name=name)
return unet_block
def build_discriminator_Nlayers(inputdisc,
name="discriminator",
d_nlayers=3,
d_base_dims=64,
norm_type='batch_norm'):
use_bias = norm_type != 'batch_norm'
dis_input = conv2d(
inputdisc,
d_base_dims,
4,
2,
0.02,
1,
name=name + "_c1",
activation_fn='leaky_relu',
relufactor=0.2,
use_bias=True)
d_dims = d_base_dims
for i in xrange(d_nlayers - 1):
conv_name = name + "_c{}".format(i + 2)
d_dims *= 2
dis_output = conv2d(
dis_input,
d_dims,
4,
2,
0.02,
1,
name=conv_name,
norm=norm_type,
activation_fn='leaky_relu',
relufactor=0.2,
use_bias=use_bias)
dis_input = dis_output
last_dims = min(2**d_nlayers, 8)
o_c4 = conv2d(
dis_output,
d_base_dims * last_dims,
4,
1,
0.02,
1,
name + "_c{}".format(d_nlayers + 1),
norm=norm_type,
activation_fn='leaky_relu',
relufactor=0.2,
use_bias=use_bias)
o_c5 = conv2d(
o_c4,
1,
4,
1,
0.02,
1,
name + "_c{}".format(d_nlayers + 2),
use_bias=True)
return o_c5
def build_discriminator_Pixel(inputdisc,
name="discriminator",
d_base_dims=64,
norm_type='batch_norm'):
use_bias = norm_type != 'instance_norm'
o_c1 = conv2d(
inputdisc,
d_base_dims,
1,
1,
0.02,
name=name + '_c1',
activation_fn='leaky_relu',
relufactor=0.2,
use_bias=True)
o_c2 = conv2d(
o_c1,
d_base_dims * 2,
1,
1,
0.02,
name=name + '_c2',
norm=norm_type,
activation_fn='leaky_relu',
relufactor=0.2,
use_bias=use_bias)
o_c3 = conv2d(o_c2, 1, 1, 1, 0.02, name=name + '_c3', use_bias=use_bias)
return o_c3
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from .base_network import conv2d, deconv2d, linear
import paddle.fluid as fluid
import numpy as np
import os
class DCGAN_model(object):
def __init__(self, batch_size=1):
self.batch_size = batch_size
self.img_dim = 28
self.gfc_dim = 2048
self.dfc_dim = 1024
self.gf_dim = 64
self.df_dim = 64
def network_G(self, input, name="generator"):
o_l1 = linear(input, self.gfc_dim, norm='batch_norm', name=name + '_l1')
o_l2 = linear(
o_l1,
self.gf_dim * 2 * self.img_dim // 4 * self.img_dim // 4,
norm='batch_norm',
name=name + '_l2')
o_r1 = fluid.layers.reshape(
o_l2, [-1, self.df_dim * 2, self.img_dim // 4, self.img_dim // 4])
o_dc1 = deconv2d(
o_r1,
self.gf_dim * 2,
4,
2,
padding=[1, 1],
activation_fn='relu',
output_size=[self.img_dim // 2, self.img_dim // 2],
name=name + '_dc1')
o_dc2 = deconv2d(
o_dc1,
1,
4,
2,
padding=[1, 1],
activation_fn='tanh',
output_size=[self.img_dim, self.img_dim],
name=name + '_dc2')
out = fluid.layers.reshape(o_dc2, shape=[-1, 28 * 28])
return out
def network_D(self, input, name="discriminator"):
o_r1 = fluid.layers.reshape(
input, shape=[-1, 1, self.img_dim, self.img_dim])
o_c1 = conv2d(
o_r1,
self.df_dim,
4,
2,
padding=[1, 1],
activation_fn='leaky_relu',
name=name + '_c1')
o_c2 = conv2d(
o_c1,
self.df_dim * 2,
4,
2,
padding=[1, 1],
norm='batch_norm',
activation_fn='leaky_relu',
name=name + '_c2')
o_l1 = linear(
o_c2,
self.dfc_dim,
norm='batch_norm',
activation_fn='leaky_relu',
name=name + '_l1')
out = linear(o_l1, 1, activation_fn='sigmoid', name=name + '_l2')
return out
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import division
import paddle.fluid as fluid
import numpy as np
import os
use_cudnn = True
if 'ce_mode' in os.environ:
use_cudnn = False
def norm_layer(input, norm_type='batch_norm', name=None):
if norm_type == 'batch_norm':
param_attr = fluid.ParamAttr(
name=name + '_w',
initializer=fluid.initializer.NormalInitializer(
loc=1.0, scale=0.02))
bias_attr = fluid.ParamAttr(
name=name + '_b', initializer=fluid.initializer.Constant(value=0.0))
return fluid.layers.batch_norm(
input,
param_attr=param_attr,
bias_attr=bias_attr,
moving_mean_name=name + '_mean',
moving_variance_name=name + '_var')
elif norm_type == 'instance_norm':
helper = fluid.layer_helper.LayerHelper("instance_norm", **locals())
dtype = helper.input_dtype()
epsilon = 1e-5
mean = fluid.layers.reduce_mean(input, dim=[2, 3], keep_dim=True)
var = fluid.layers.reduce_mean(
fluid.layers.square(input - mean), dim=[2, 3], keep_dim=True)
if name is not None:
scale_name = name + "_scale"
offset_name = name + "_offset"
scale_param = fluid.ParamAttr(
name=scale_name,
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=0.02),
trainable=True)
offset_param = fluid.ParamAttr(
name=offset_name,
initializer=fluid.initializer.Constant(0.0),
trainable=True)
scale = helper.create_parameter(
attr=scale_param, shape=input.shape[1:2], dtype=dtype)
offset = helper.create_parameter(
attr=offset_param, shape=input.shape[1:2], dtype=dtype)
tmp = fluid.layers.elementwise_mul(x=(input - mean), y=scale, axis=1)
tmp = tmp / fluid.layers.sqrt(var + epsilon)
tmp = fluid.layers.elementwise_add(tmp, offset, axis=1)
return tmp
else:
raise NotImplementedError("norm tyoe: [%s] is not support" % norm_type)
def conv2d(input,
num_filters=64,
filter_size=7,
stride=1,
stddev=0.02,
padding=0,
name="conv2d",
norm=None,
activation_fn=None,
relufactor=0.0,
use_bias=False):
param_attr = fluid.ParamAttr(
name=name + "_w",
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev))
if use_bias == True:
bias_attr = fluid.ParamAttr(
name=name + "_b", initializer=fluid.initializer.Constant(0.0))
else:
bias_attr = False
conv = fluid.layers.conv2d(
input,
num_filters,
filter_size,
name=name,
stride=stride,
padding=padding,
use_cudnn=use_cudnn,
param_attr=param_attr,
bias_attr=bias_attr)
if norm is not None:
conv = norm_layer(input=conv, norm_type=norm, name=name + "_norm")
if activation_fn == 'relu':
conv = fluid.layers.relu(conv, name=name + '_relu')
elif activation_fn == 'leaky_relu':
conv = fluid.layers.leaky_relu(
conv, alpha=relufactor, name=name + '_leaky_relu')
elif activation_fn == 'tanh':
conv = fluid.layers.tanh(conv, name=name + '_tanh')
elif activation_fn == None:
conv = conv
else:
raise NotImplementedError("activation: [%s] is not support" %
activation_fn)
return conv
def deconv2d(input,
num_filters=64,
filter_size=7,
stride=1,
stddev=0.02,
padding=[0, 0],
outpadding=[0, 0, 0, 0],
name="deconv2d",
norm=None,
activation_fn=None,
relufactor=0.0,
use_bias=False,
output_size=None):
param_attr = fluid.ParamAttr(
name=name + "_w",
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev))
if use_bias == True:
bias_attr = fluid.ParamAttr(
name=name + "_b", initializer=fluid.initializer.Constant(0.0))
else:
bias_attr = False
conv = fluid.layers.conv2d_transpose(
input,
num_filters,
output_size=output_size,
name=name,
filter_size=filter_size,
stride=stride,
padding=padding,
use_cudnn=use_cudnn,
param_attr=param_attr,
bias_attr=bias_attr)
conv = fluid.layers.pad2d(
conv, paddings=outpadding, mode='constant', pad_value=0.0)
if norm is not None:
conv = norm_layer(input=conv, norm_type=norm, name=name + "_norm")
if activation_fn == 'relu':
conv = fluid.layers.relu(conv, name=name + '_relu')
elif activation_fn == 'leaky_relu':
if relufactor == 0.0:
raise Warning(
"the activation is leaky_relu, but the relufactor is 0")
conv = fluid.layers.leaky_relu(
conv, alpha=relufactor, name=name + '_leaky_relu')
elif activation_fn == 'tanh':
conv = fluid.layers.tanh(conv, name=name + '_tanh')
elif activation_fn == 'sigmoid':
conv = fluid.layers.sigmoid(conv, name=name + '_sigmoid')
elif activation_fn == None:
conv = conv
else:
raise NotImplementedError("activation: [%s] is not support" %
activation_fn)
return conv
def linear(input,
output_size,
norm=None,
stddev=0.02,
activation_fn=None,
relufactor=0.2,
name='linear'):
param_attr = fluid.ParamAttr(
name=name + '_w',
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev))
bias_attr = fluid.ParamAttr(
name=name + "_b", initializer=fluid.initializer.Constant(0.0))
linear = fluid.layers.fc(input,
output_size,
param_attr=param_attr,
bias_attr=bias_attr,
name=name)
if norm is not None:
linear = norm_layer(input=linear, norm_type=norm, name=name + '_norm')
if activation_fn == 'relu':
linear = fluid.layers.relu(linear, name=name + '_relu')
elif activation_fn == 'leaky_relu':
if relufactor == 0.0:
raise Warning(
"the activation is leaky_relu, but the relufactor is 0")
linear = fluid.layers.leaky_relu(
linear, alpha=relufactor, name=name + '_leaky_relu')
elif activation_fn == 'tanh':
linear = fluid.layers.tanh(linear, name=name + '_tanh')
elif activation_fn == 'sigmoid':
linear = fluid.layers.sigmoid(linear, name=name + '_sigmoid')
elif activation_fn == None:
linear = linear
else:
raise NotImplementedError("activation: [%s] is not support" %
activation_fn)
return linear
def conv_cond_concat(x, y):
ones = fluid.layers.fill_constant_batch_size_like(
x, [-1, y.shape[1], x.shape[2], x.shape[3]], "float32", 1.0)
out = fluid.layers.concat([x, ones * y], 1)
return out
def conv_and_pool(x, num_filters, name, stddev=0.02, act=None):
param_attr = fluid.ParamAttr(
name=name + '_w',
initializer=fluid.initializer.NormalInitializer(
loc=0.0, scale=stddev))
bias_attr = fluid.ParamAttr(
name=name + "_b", initializer=fluid.initializer.Constant(0.0))
out = fluid.nets.simple_img_conv_pool(
input=x,
filter_size=5,
num_filters=num_filters,
pool_size=2,
pool_stride=2,
param_attr=param_attr,
bias_attr=bias_attr,
act=act)
return out
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import division
from __future__ import print_function
from util import config, utility
from data_reader import data_reader
import os
import sys
import six
import time
import numpy as np
import paddle
import paddle.fluid as fluid
def train(cfg):
reader = data_reader(cfg)
if cfg.model_net == 'CycleGAN':
a_reader, b_reader, a_reader_test, b_reader_test, batch_num = reader.make_data(
)
else:
if cfg.dataset == 'mnist':
train_reader = reader.make_data()
else:
train_reader, test_reader, batch_num = reader.make_data()
if cfg.model_net == 'CGAN':
from trainer.CGAN import CGAN
if cfg.dataset != 'mnist':
raise NotImplementedError('CGAN only support mnist now!')
model = CGAN(cfg, train_reader)
elif cfg.model_net == 'DCGAN':
from trainer.DCGAN import DCGAN
if cfg.dataset != 'mnist':
raise NotImplementedError('DCGAN only support mnist now!')
model = DCGAN(cfg, train_reader)
elif cfg.model_net == 'CycleGAN':
from trainer.CycleGAN import CycleGAN
model = CycleGAN(cfg, a_reader, b_reader, a_reader_test, b_reader_test,
batch_num)
else:
pass
model.build_model()
if __name__ == "__main__":
cfg = config.parse_args()
config.print_arguments(cfg)
assert cfg.load_size >= cfg.crop_size, "Load Size CANNOT less than Crop Size!"
if cfg.profile:
if cfg.use_gpu:
with profiler.profiler('All', 'total', '/tmp/profile') as prof:
train(cfg)
else:
with profiler.profiler("CPU", sorted_key='total') as cpuprof:
train(cfg)
else:
train(cfg)
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from network.CGAN_network import CGAN_model
from util import utility
import sys
import six
import os
import numpy as np
import time
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import paddle.fluid as fluid
class GTrainer():
def __init__(self, input, conditions, cfg):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = CGAN_model()
self.fake = model.network_G(input, conditions, name="G")
self.infer_program = self.program.clone()
d_fake = model.network_D(self.fake, conditions, name="D")
fake_labels = fluid.layers.fill_constant_batch_size_like(
input=input, dtype='float32', shape=[-1, 1], value=1.0)
self.g_loss = fluid.layers.reduce_mean(
fluid.layers.sigmoid_cross_entropy_with_logits(
x=d_fake, label=fake_labels))
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and (var.name.startswith("G")):
vars.append(var.name)
optimizer = fluid.optimizer.Adam(
learning_rate=cfg.learning_rate, beta1=0.5, name="net_G")
optimizer.minimize(self.g_loss, parameter_list=vars)
class DTrainer():
def __init__(self, input, conditions, labels, cfg):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = CGAN_model()
d_logit = model.network_D(input, conditions, name="D")
self.d_loss = fluid.layers.reduce_mean(
fluid.layers.sigmoid_cross_entropy_with_logits(
x=d_logit, label=labels))
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and (var.name.startswith("D")):
vars.append(var.name)
optimizer = fluid.optimizer.Adam(
learning_rate=cfg.learning_rate, beta1=0.5, name="net_D")
optimizer.minimize(self.d_loss, parameter_list=vars)
class CGAN(object):
def add_special_args(self, parser):
parser.add_argument(
'--noise_size', type=int, default=100, help="the noise dimension")
return parser
def __init__(self, cfg=None, train_reader=None):
self.cfg = cfg
self.train_reader = train_reader
def build_model(self):
img = fluid.layers.data(name='img', shape=[784], dtype='float32')
condition = fluid.layers.data(
name='condition', shape=[1], dtype='float32')
noise = fluid.layers.data(
name='noise', shape=[self.cfg.noise_size], dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='float32')
g_trainer = GTrainer(noise, condition, self.cfg)
d_trainer = DTrainer(img, condition, label, self.cfg)
# prepare environment
place = fluid.CUDAPlace(0) if self.cfg.use_gpu else fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
const_n = np.random.uniform(
low=-1.0, high=1.0,
size=[self.cfg.batch_size, self.cfg.noise_size]).astype('float32')
if self.cfg.init_model:
utility.init_checkpoints(self.cfg, exe, g_trainer, "net_G")
utility.init_checkpoints(self.cfg, exe, d_trainer, "net_D")
### memory optim
build_strategy = fluid.BuildStrategy()
build_strategy.enable_inplace = True
build_strategy.memory_optimize = False
g_trainer_program = fluid.CompiledProgram(
g_trainer.program).with_data_parallel(
loss_name=g_trainer.g_loss.name, build_strategy=build_strategy)
d_trainer_program = fluid.CompiledProgram(
d_trainer.program).with_data_parallel(
loss_name=d_trainer.d_loss.name, build_strategy=build_strategy)
t_time = 0
losses = [[], []]
for epoch_id in range(self.cfg.epoch):
for batch_id, data in enumerate(self.train_reader()):
if len(data) != self.cfg.batch_size:
continue
noise_data = np.random.uniform(
low=-1.0,
high=1.0,
size=[self.cfg.batch_size, self.cfg.noise_size]).astype(
'float32')
real_image = np.array(list(map(lambda x: x[0], data))).reshape(
[-1, 784]).astype('float32')
condition_data = np.array([x[1] for x in data]).reshape(
[-1, 1]).astype('float32')
real_label = np.ones(
shape=[real_image.shape[0], 1], dtype='float32')
fake_label = np.zeros(
shape=[real_image.shape[0], 1], dtype='float32')
s_time = time.time()
generate_image = exe.run(
g_trainer.infer_program,
feed={'noise': noise_data,
'condition': condition_data},
fetch_list=[g_trainer.fake])
d_real_loss = exe.run(d_trainer_program,
feed={
'img': real_image,
'condition': condition_data,
'label': real_label
},
fetch_list=[d_trainer.d_loss])[0]
d_fake_loss = exe.run(d_trainer_program,
feed={
'img': generate_image,
'condition': condition_data,
'label': fake_label
},
fetch_list=[d_trainer.d_loss])[0]
d_loss = d_real_loss + d_fake_loss
losses[1].append(d_loss)
for _ in six.moves.xrange(self.cfg.num_generator_time):
g_loss = exe.run(g_trainer_program,
feed={
'noise': noise_data,
'condition': condition_data
},
fetch_list=[g_trainer.g_loss])[0]
losses[0].append(g_loss)
batch_time = time.time() - s_time
t_time += batch_time
if batch_id % self.cfg.print_freq == 0:
image_path = self.cfg.output + '/images'
if not os.path.exists(image_path):
os.makedirs(image_path)
generate_const_image = exe.run(
g_trainer.infer_program,
feed={'noise': const_n,
'condition': condition_data},
fetch_list={g_trainer.fake})[0]
generate_image_reshape = np.reshape(generate_const_image, (
self.cfg.batch_size, -1))
total_images = np.concatenate(
[real_image, generate_image_reshape])
fig = utility.plot(total_images)
print(
'Epoch ID={} Batch ID={} D_loss={} G_loss={} Batch_time_cost={:.2f}'.
format(epoch_id, batch_id, d_loss[0], g_loss[0],
batch_time))
plt.title('Epoch ID={}, Batch ID={}'.format(epoch_id,
batch_id))
plt.savefig(
'{}/{:04d}_{:04d}.png'.format(image_path, epoch_id,
batch_id),
bbox_inches='tight')
plt.close(fig)
if self.cfg.save_checkpoints:
utility.checkpoints(epoch_id, self.cfg, exe, g_trainer, "net_G")
utility.checkpoints(epoch_id, self.cfg, exe, d_trainer, "net_D")
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from network.CycleGAN_network import CycleGAN_model
from util import utility
import paddle.fluid as fluid
import sys
import time
lambda_A = 10.0
lambda_B = 10.0
lambda_identity = 0.5
class GTrainer():
def __init__(self, input_A, input_B, cfg, step_per_epoch):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = CycleGAN_model()
self.fake_B = model.network_G(input_A, name="GA", cfg=cfg)
self.fake_B.persistable = True
self.fake_A = model.network_G(input_B, name="GB", cfg=cfg)
self.fake_A.persistable = True
self.cyc_A = model.network_G(self.fake_B, name="GB", cfg=cfg)
self.cyc_B = model.network_G(self.fake_A, name="GA", cfg=cfg)
self.infer_program = self.program.clone()
# Cycle Loss
diff_A = fluid.layers.abs(
fluid.layers.elementwise_sub(
x=input_A, y=self.cyc_A))
diff_B = fluid.layers.abs(
fluid.layers.elementwise_sub(
x=input_B, y=self.cyc_B))
self.cyc_A_loss = fluid.layers.reduce_mean(diff_A) * lambda_A
self.cyc_B_loss = fluid.layers.reduce_mean(diff_B) * lambda_B
self.cyc_loss = self.cyc_A_loss + self.cyc_B_loss
# GAN Loss D_A(G_A(A))
self.fake_rec_A = model.network_D(self.fake_B, name="DA", cfg=cfg)
self.G_A = fluid.layers.reduce_mean(
fluid.layers.square(self.fake_rec_A - 1))
# GAN Loss D_B(G_B(B))
self.fake_rec_B = model.network_D(self.fake_A, name="DB", cfg=cfg)
self.G_B = fluid.layers.reduce_mean(
fluid.layers.square(self.fake_rec_B - 1))
self.G = self.G_A + self.G_B
# Identity Loss G_A
self.idt_A = model.network_G(input_B, name="GA", cfg=cfg)
self.idt_loss_A = fluid.layers.reduce_mean(
fluid.layers.abs(
fluid.layers.elementwise_sub(
x=input_B, y=self.idt_A))) * lambda_B * lambda_identity
# Identity Loss G_B
self.idt_B = model.network_G(input_A, name="GB", cfg=cfg)
self.idt_loss_B = fluid.layers.reduce_mean(
fluid.layers.abs(
fluid.layers.elementwise_sub(
x=input_A, y=self.idt_B))) * lambda_A * lambda_identity
self.idt_loss = fluid.layers.elementwise_add(self.idt_loss_A,
self.idt_loss_B)
self.g_loss = self.cyc_loss + self.G + self.idt_loss
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and (var.name.startswith("GA") or
var.name.startswith("GB")):
vars.append(var.name)
self.param = vars
lr = cfg.learning_rate
optimizer = fluid.optimizer.Adam(
learning_rate=fluid.layers.piecewise_decay(
boundaries=[99 * step_per_epoch] +
[x * step_per_epoch for x in xrange(100, cfg.epoch - 1)],
values=[lr] + [
lr * (1.0 - (x - 99.0) / 101.0)
for x in xrange(100, cfg.epoch)
]),
beta1=0.5,
beta2=0.999,
name="net_G")
optimizer.minimize(self.g_loss, parameter_list=vars)
class DATrainer():
def __init__(self, input_B, fake_pool_B, cfg, step_per_epoch):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = CycleGAN_model()
self.rec_B = model.network_D(input_B, name="DA", cfg=cfg)
self.fake_pool_rec_B = model.network_D(
fake_pool_B, name="DA", cfg=cfg)
self.d_loss_A = (fluid.layers.square(self.fake_pool_rec_B) +
fluid.layers.square(self.rec_B - 1)) / 2.0
self.d_loss_A = fluid.layers.reduce_mean(self.d_loss_A)
optimizer = fluid.optimizer.Adam(learning_rate=0.0002, beta1=0.5)
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and var.name.startswith("DA"):
vars.append(var.name)
self.param = vars
lr = cfg.learning_rate
optimizer = fluid.optimizer.Adam(
learning_rate=fluid.layers.piecewise_decay(
boundaries=[99 * step_per_epoch] +
[x * step_per_epoch for x in xrange(100, cfg.epoch - 1)],
values=[lr] + [
lr * (1.0 - (x - 99.0) / 101.0)
for x in xrange(100, cfg.epoch)
]),
beta1=0.5,
beta2=0.999,
name="net_DA")
optimizer.minimize(self.d_loss_A, parameter_list=vars)
class DBTrainer():
def __init__(self, input_A, fake_pool_A, cfg, step_per_epoch):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = CycleGAN_model()
self.rec_A = model.network_D(input_A, name="DB", cfg=cfg)
self.fake_pool_rec_A = model.network_D(
fake_pool_A, name="DB", cfg=cfg)
self.d_loss_B = (fluid.layers.square(self.fake_pool_rec_A) +
fluid.layers.square(self.rec_A - 1)) / 2.0
self.d_loss_B = fluid.layers.reduce_mean(self.d_loss_B)
optimizer = fluid.optimizer.Adam(learning_rate=0.0002, beta1=0.5)
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and var.name.startswith("DB"):
vars.append(var.name)
self.param = vars
lr = 0.0002
optimizer = fluid.optimizer.Adam(
learning_rate=fluid.layers.piecewise_decay(
boundaries=[99 * step_per_epoch] +
[x * step_per_epoch for x in xrange(100, cfg.epoch - 1)],
values=[lr] + [
lr * (1.0 - (x - 99.0) / 101.0)
for x in xrange(100, cfg.epoch)
]),
beta1=0.5,
beta2=0.999,
name="net_DB")
optimizer.minimize(self.d_loss_B, parameter_list=vars)
class CycleGAN(object):
def add_special_args(self, parser):
parser.add_argument(
'--net_G',
type=str,
default="resnet_9block",
help="Choose the CycleGAN generator's network, choose in [resnet_9block|resnet_6block|unet_128|unet_256]"
)
parser.add_argument(
'--net_D',
type=str,
default="basic",
help="Choose the CycleGAN discriminator's network, choose in [basic|nlayers|pixel]"
)
parser.add_argument(
'--d_nlayers',
type=int,
default=3,
help="only used when CycleGAN discriminator is nlayers")
return parser
def __init__(self,
cfg=None,
A_reader=None,
B_reader=None,
A_test_reader=None,
B_test_reader=None,
batch_num=1):
self.cfg = cfg
self.A_reader = A_reader
self.B_reader = B_reader
self.A_test_reader = A_test_reader
self.B_test_reader = B_test_reader
self.batch_num = batch_num
def build_model(self):
data_shape = [-1, 3, self.cfg.crop_size, self.cfg.crop_size]
input_A = fluid.layers.data(
name='input_A', shape=data_shape, dtype='float32')
input_B = fluid.layers.data(
name='input_B', shape=data_shape, dtype='float32')
fake_pool_A = fluid.layers.data(
name='fake_pool_A', shape=data_shape, dtype='float32')
fake_pool_B = fluid.layers.data(
name='fake_pool_B', shape=data_shape, dtype='float32')
gen_trainer = GTrainer(input_A, input_B, self.cfg, self.batch_num)
d_A_trainer = DATrainer(input_B, fake_pool_B, self.cfg, self.batch_num)
d_B_trainer = DBTrainer(input_A, fake_pool_A, self.cfg, self.batch_num)
# prepare environment
place = fluid.CUDAPlace(0) if self.cfg.use_gpu else fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
A_pool = utility.ImagePool()
B_pool = utility.ImagePool()
if self.cfg.init_model:
utility.init_checkpoints(self.cfg, exe, gen_trainer, "net_G")
utility.init_checkpoints(self.cfg, exe, d_A_trainer, "net_DA")
utility.init_checkpoints(self.cfg, exe, d_B_trainer, "net_DB")
### memory optim
build_strategy = fluid.BuildStrategy()
build_strategy.enable_inplace = False
build_strategy.memory_optimize = False
gen_trainer_program = fluid.CompiledProgram(
gen_trainer.program).with_data_parallel(
loss_name=gen_trainer.g_loss.name,
build_strategy=build_strategy)
d_A_trainer_program = fluid.CompiledProgram(
d_A_trainer.program).with_data_parallel(
loss_name=d_A_trainer.d_loss_A.name,
build_strategy=build_strategy)
d_B_trainer_program = fluid.CompiledProgram(
d_B_trainer.program).with_data_parallel(
loss_name=d_B_trainer.d_loss_B.name,
build_strategy=build_strategy)
losses = [[], []]
t_time = 0
for epoch_id in range(self.cfg.epoch):
batch_id = 0
for i in range(self.batch_num):
data_A = next(self.A_reader())
data_B = next(self.B_reader())
tensor_A = fluid.LoDTensor()
tensor_B = fluid.LoDTensor()
tensor_A.set(data_A, place)
tensor_B.set(data_B, place)
s_time = time.time()
# optimize the g_A network
g_A_loss, g_A_cyc_loss, g_A_idt_loss, g_B_loss, g_B_cyc_loss,\
g_B_idt_loss, fake_A_tmp, fake_B_tmp = exe.run(
gen_trainer_program,
fetch_list=[
gen_trainer.G_A, gen_trainer.cyc_A_loss,
gen_trainer.idt_loss_A, gen_trainer.G_B,
gen_trainer.cyc_B_loss, gen_trainer.idt_loss_B,
gen_trainer.fake_A, gen_trainer.fake_B
],
feed={"input_A": tensor_A,
"input_B": tensor_B})
fake_pool_B = B_pool.pool_image(fake_B_tmp)
fake_pool_A = A_pool.pool_image(fake_A_tmp)
# optimize the d_A network
d_A_loss = exe.run(
d_A_trainer_program,
fetch_list=[d_A_trainer.d_loss_A],
feed={"input_B": tensor_B,
"fake_pool_B": fake_pool_B})[0]
# optimize the d_B network
d_B_loss = exe.run(
d_B_trainer_program,
fetch_list=[d_B_trainer.d_loss_B],
feed={"input_A": tensor_A,
"fake_pool_A": fake_pool_A})[0]
batch_time = time.time() - s_time
t_time += batch_time
if batch_id % self.cfg.print_freq == 0:
print("epoch{}: batch{}: \n\
d_A_loss: {}; g_A_loss: {}; g_A_cyc_loss: {}; g_A_idt_loss: {}; \n\
d_B_loss: {}; g_B_loss: {}; g_B_cyc_loss: {}; g_B_idt_loss: {}; \n\
Batch_time_cost: {:.2f}".format(
epoch_id, batch_id, d_A_loss[0], g_A_loss[0],
g_A_cyc_loss[0], g_A_idt_loss[0], d_B_loss[0], g_B_loss[
0], g_B_cyc_loss[0], g_B_idt_loss[0], batch_time))
losses[0].append(g_A_loss[0])
losses[1].append(d_A_loss[0])
sys.stdout.flush()
batch_id += 1
if self.cfg.run_test:
test_program = gen_trainer.infer_program
utility.save_test_image(epoch_id, self.cfg, exe, place,
test_program, gen_trainer,
self.A_test_reader, self.B_test_reader)
if self.cfg.save_checkpoints:
utility.checkpoints(epoch_id, self.cfg, exe, gen_trainer,
"net_G")
utility.checkpoints(epoch_id, self.cfg, exe, d_A_trainer,
"net_DA")
utility.checkpoints(epoch_id, self.cfg, exe, d_B_trainer,
"net_DB")
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from network.DCGAN_network import DCGAN_model
from util import utility
import sys
import six
import os
import numpy as np
import time
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import paddle.fluid as fluid
class GTrainer():
def __init__(self, input, label, cfg):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = DCGAN_model()
self.fake = model.network_G(input, name='G')
self.infer_program = self.program.clone()
d_fake = model.network_D(self.fake, name="D")
fake_labels = fluid.layers.fill_constant_batch_size_like(
input, dtype='float32', shape=[-1, 1], value=1.0)
self.g_loss = fluid.layers.reduce_mean(
fluid.layers.sigmoid_cross_entropy_with_logits(
x=d_fake, label=fake_labels))
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and (var.name.startswith("G")):
vars.append(var.name)
optimizer = fluid.optimizer.Adam(
learning_rate=cfg.learning_rate, beta1=0.5, name="net_G")
optimizer.minimize(self.g_loss, parameter_list=vars)
class DTrainer():
def __init__(self, input, labels, cfg):
self.program = fluid.default_main_program().clone()
with fluid.program_guard(self.program):
model = DCGAN_model()
d_logit = model.network_D(input, name="D")
self.d_loss = fluid.layers.reduce_mean(
fluid.layers.sigmoid_cross_entropy_with_logits(
x=d_logit, label=labels))
vars = []
for var in self.program.list_vars():
if fluid.io.is_parameter(var) and (var.name.startswith("D")):
vars.append(var.name)
optimizer = fluid.optimizer.Adam(
learning_rate=cfg.learning_rate, beta1=0.5, name="net_D")
optimizer.minimize(self.d_loss, parameter_list=vars)
class DCGAN(object):
def add_special_args(self, parser):
parser.add_argument(
'--noise_size', type=int, default=100, help="the noise dimension")
return parser
def __init__(self, cfg, train_reader):
self.cfg = cfg
self.train_reader = train_reader
def build_model(self):
img = fluid.layers.data(name='img', shape=[784], dtype='float32')
noise = fluid.layers.data(
name='noise', shape=[self.cfg.noise_size], dtype='float32')
label = fluid.layers.data(name='label', shape=[1], dtype='float32')
g_trainer = GTrainer(noise, label, self.cfg)
d_trainer = DTrainer(img, label, self.cfg)
# prepare enviorment
place = fluid.CUDAPlace(0)
exe = fluid.Executor(place)
exe.run(fluid.default_startup_program())
const_n = np.random.uniform(
low=-1.0, high=1.0,
size=[self.cfg.batch_size, self.cfg.noise_size]).astype('float32')
if self.cfg.init_model:
utility.init_checkpoints(self.cfg, exe, g_trainer, "net_G")
utility.init_checkpoints(self.cfg, exe, d_trainer, "net_D")
### memory optim
build_strategy = fluid.BuildStrategy()
build_strategy.enable_inplace = True
build_strategy.memory_optimize = False
g_trainer_program = fluid.CompiledProgram(
g_trainer.program).with_data_parallel(
loss_name=g_trainer.g_loss.name, build_strategy=build_strategy)
d_trainer_program = fluid.CompiledProgram(
d_trainer.program).with_data_parallel(
loss_name=d_trainer.d_loss.name, build_strategy=build_strategy)
t_time = 0
losses = [[], []]
for epoch_id in range(self.cfg.epoch):
for batch_id, data in enumerate(self.train_reader()):
if len(data) != self.cfg.batch_size:
continue
noise_data = np.random.uniform(
low=-1.0,
high=1.0,
size=[self.cfg.batch_size, self.cfg.noise_size]).astype(
'float32')
real_image = np.array(list(map(lambda x: x[0], data))).reshape(
[-1, 784]).astype('float32')
real_label = np.ones(
shape=[real_image.shape[0], 1], dtype='float32')
fake_label = np.zeros(
shape=[real_image.shape[0], 1], dtype='float32')
s_time = time.time()
generate_image = exe.run(g_trainer.infer_program,
feed={'noise': noise_data},
fetch_list=[g_trainer.fake])
d_real_loss = exe.run(
d_trainer_program,
feed={'img': real_image,
'label': real_label},
fetch_list=[d_trainer.d_loss])[0]
d_fake_loss = exe.run(
d_trainer_program,
feed={'img': generate_image,
'label': fake_label},
fetch_list=[d_trainer.d_loss])[0]
d_loss = d_real_loss + d_fake_loss
losses[1].append(d_loss)
for _ in six.moves.xrange(self.cfg.num_generator_time):
g_loss = exe.run(g_trainer_program,
feed={'noise': noise_data},
fetch_list=[g_trainer.g_loss])[0]
losses[0].append(g_loss)
batch_time = time.time() - s_time
t_time += batch_time
if batch_id % self.cfg.print_freq == 0:
image_path = self.cfg.output + '/images'
if not os.path.exists(image_path):
os.makedirs(image_path)
generate_const_image = exe.run(
g_trainer.infer_program,
feed={'noise': const_n},
fetch_list={g_trainer.fake})[0]
generate_image_reshape = np.reshape(generate_const_image, (
self.cfg.batch_size, -1))
total_images = np.concatenate(
[real_image, generate_image_reshape])
fig = utility.plot(total_images)
print(
'Epoch ID={} Batch ID={} D_loss={} G_loss={} Batch_time_cost={:.2f}'.
format(epoch_id, batch_id, d_loss[0], g_loss[0],
batch_time))
plt.title('Epoch ID={}, Batch ID={}'.format(epoch_id,
batch_id))
plt.savefig(
'{}/{:04d}_{:04d}.png'.format(image_path, epoch_id,
batch_id),
bbox_inches='tight')
plt.close(fig)
if self.cfg.save_checkpoints:
utility.checkpoints(epoch_id, self.cfg, exe, g_trainer, "net_G")
utility.checkpoints(epoch_id, self.cfg, exe, d_trainer, "net_D")
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
import importlib
def get_special_cfg(model_net):
model = "trainer." + model_net
modellib = importlib.import_module(model)
for name, cls in modellib.__dict__.items():
if name.lower() == model_net.lower():
model = cls()
return model.add_special_args
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
import six
import argparse
import functools
import distutils.util
import trainer
def print_arguments(args):
''' Print argparse's argument
Usage:
.. code-block:: python
parser = argparse.ArgumentParser()
parser.add_argument("name", default="Jonh", type=str, help="User name.")
args = parser.parse_args()
print_arguments(args)
:param args: Input argparse.Namespace for printing.
:type args: argparse.Namespace
'''
print("----------- Configuration Arguments -----------")
for arg, value in sorted(six.iteritems(vars(args))):
print("%s: %s" % (arg, value))
print("------------------------------------------------")
def add_arguments(argname, type, default, help, argparser, **kwargs):
"""Add argparse's argument.
Usage:
.. code-block:: python
parser = argparse.ArgumentParser()
add_argument("name", str, "Jonh", "User name.", parser)
args = parser.parse_args()
"""
type = distutils.util.strtobool if type == bool else type
argparser.add_argument(
"--" + argname,
default=default,
type=type,
help=help + ' Default: %(default)s.',
**kwargs)
def base_parse_args(parser):
add_arg = functools.partial(add_arguments, argparser=parser)
# yapf: disable
add_arg('model_net', str, "cgan", "The model used.")
add_arg('dataset', str, "mnist", "The dataset used.")
add_arg('data_dir', str, "./data", "The dataset root directory")
add_arg('data_list', str, None, "The dataset list file name")
add_arg('batch_size', int, 1, "Minibatch size.")
add_arg('epoch', int, 200, "The number of epoch to be trained.")
add_arg('g_base_dims', int, 64, "Base channels in CycleGAN generator")
add_arg('d_base_dims', int, 64, "Base channels in CycleGAN discriminator")
add_arg('load_size', int, 286, "the image size when load the image")
add_arg('crop_type', str, 'Centor',
"the crop type, choose = ['Centor', 'Random']")
add_arg('crop_size', int, 256, "crop size when preprocess image")
add_arg('save_checkpoints', bool, True, "Whether to save checkpoints.")
add_arg('run_test', bool, True, "Whether to run test.")
add_arg('use_gpu', bool, True, "Whether to use GPU to train.")
add_arg('profile', bool, False, "Whether to profile.")
add_arg('dropout', bool, False, "Whether to use drouput.")
add_arg('use_dropout', bool, False, "Whether to use dropout")
add_arg('drop_last', bool, False,
"Whether to drop the last images that cannot form a batch")
add_arg('shuffle', bool, True, "Whether to shuffle data")
add_arg('output', str, "./output",
"The directory the model and the test result to be saved to.")
add_arg('init_model', str, None, "The init model file of directory.")
add_arg('norm_type', str, "batch_norm", "Which normalization to used")
add_arg('learning_rate', int, 0.0002, "the initialize learning rate")
add_arg('num_generator_time', int, 1,
"the generator run times in training each epoch")
add_arg('print_freq', int, 10, "the frequency of print loss")
# yapf: enable
return parser
def parse_args():
parser = argparse.ArgumentParser(description=__doc__)
parser = base_parse_args(parser)
cfg, _ = parser.parse_known_args()
model_name = cfg.model_net
model_cfg = trainer.get_special_cfg(model_name)
parser = model_cfg(parser)
args = parser.parse_args()
return args
#copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import paddle.fluid as fluid
import os
import sys
import math
import distutils.util
import numpy as np
import inspect
import matplotlib
import six
matplotlib.use('agg')
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from scipy.misc import imsave
img_dim = 28
def plot(gen_data):
pad_dim = 1
paded = pad_dim + img_dim
gen_data = gen_data.reshape(gen_data.shape[0], img_dim, img_dim)
n = int(math.ceil(math.sqrt(gen_data.shape[0])))
gen_data = (np.pad(
gen_data, [[0, n * n - gen_data.shape[0]], [pad_dim, 0], [pad_dim, 0]],
'constant').reshape((n, n, paded, paded)).transpose((0, 2, 1, 3))
.reshape((n * paded, n * paded)))
fig = plt.figure(figsize=(8, 8))
plt.axis('off')
plt.imshow(gen_data, cmap='Greys_r', vmin=-1, vmax=1)
return fig
def checkpoints(epoch, cfg, exe, trainer, name):
output_path = cfg.output + '/chechpoints/' + str(epoch)
if not os.path.exists(output_path):
os.makedirs(output_path)
fluid.io.save_persistables(
exe, os.path.join(output_path, name), main_program=trainer.program)
print('save checkpoints {} to {}'.format(name, output_path))
sys.stdout.flush()
def init_checkpoints(cfg, exe, trainer, name):
assert os.path.exists(cfg.init_model), "{} cannot be found.".format(
cfg.init_model)
fluid.io.load_persistables(
exe, os.path.join(cfg.init_model, name), main_program=trainer.program)
print('load checkpoints {} {} DONE'.format(cfg.init_model, name))
sys.stdout.flush()
def save_test_image(epoch, cfg, exe, place, test_program, g_trainer,
A_test_reader, B_test_reader):
out_path = cfg.output + '/test'
if not os.path.exists(out_path):
os.makedirs(out_path)
for data_A, data_B in zip(A_test_reader(), B_test_reader()):
A_name = data_A[0][1]
B_name = data_B[0][1]
tensor_A = fluid.LoDTensor()
tensor_B = fluid.LoDTensor()
tensor_A.set(data_A[0][0], place)
tensor_B.set(data_B[0][0], place)
fake_A_temp, fake_B_temp, cyc_A_temp, cyc_B_temp = exe.run(
test_program,
fetch_list=[
g_trainer.fake_A, g_trainer.fake_B, g_trainer.cyc_A,
g_trainer.cyc_B
],
feed={"input_A": tensor_A,
"input_B": tensor_B})
fake_A_temp = np.squeeze(fake_A_temp[0]).transpose([1, 2, 0])
fake_B_temp = np.squeeze(fake_B_temp[0]).transpose([1, 2, 0])
cyc_A_temp = np.squeeze(cyc_A_temp[0]).transpose([1, 2, 0])
cyc_B_temp = np.squeeze(cyc_B_temp[0]).transpose([1, 2, 0])
input_A_temp = np.squeeze(data_A[0][0]).transpose([1, 2, 0])
input_B_temp = np.squeeze(data_B[0][0]).transpose([1, 2, 0])
imsave(out_path + "/fakeB_" + str(epoch) + "_" + A_name, (
(fake_B_temp + 1) * 127.5).astype(np.uint8))
imsave(out_path + "/fakeA_" + str(epoch) + "_" + B_name, (
(fake_A_temp + 1) * 127.5).astype(np.uint8))
imsave(out_path + "/cycA_" + str(epoch) + "_" + A_name, (
(cyc_A_temp + 1) * 127.5).astype(np.uint8))
imsave(out_path + "/cycB_" + str(epoch) + "_" + B_name, (
(cyc_B_temp + 1) * 127.5).astype(np.uint8))
imsave(out_path + "/inputA_" + str(epoch) + "_" + A_name, (
(input_A_temp + 1) * 127.5).astype(np.uint8))
imsave(out_path + "/inputB_" + str(epoch) + "_" + B_name, (
(input_B_temp + 1) * 127.5).astype(np.uint8))
class ImagePool(object):
def __init__(self, pool_size=50):
self.pool = []
self.count = 0
self.pool_size = pool_size
def pool_image(self, image):
if self.count < self.pool_size:
self.pool.append(image)
self.count += 1
return image
else:
p = np.random.rand()
if p > 0.5:
random_id = np.random.randint(0, self.pool_size - 1)
temp = self.pool[random_id]
self.pool[random_id] = image
return temp
else:
return image
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册