Introduction to the
We train DCGAN on face data and generate some face pictures
data
Use two data sets
- LFW: Vis-www.cs.umass.edu/lfw/, Labeled Faces in the Wild, over 1.3W images, 1680 of whom had more than two or more images
- CelebA:mmlab.ie.cuhk.edu.hk/projects/Ce… , CelebFaces Attributes Dataset, which includes more than 20W images of 10177 people, and each image also includes 5 key positions of face and 01 annotation of 40 Attributes, such as glasses, hat, beard, etc
implementation
Same code as last lesson, according to the color picture can be adjusted appropriately
Load the library
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
import urllib
import tarfile
import os
import matplotlib.pyplot as plt
%matplotlib inline
from imageio import imread, imsave, mimsave
from scipy.misc import imresize
import glob
Copy the code
Download LFW data and decompress it. CelebA data is ready
url = 'http://vis-www.cs.umass.edu/lfw/lfw.tgz'
filename = 'lfw.tgz'
directory = 'lfw_imgs'
new_dir = 'lfw_new_imgs'
if not os.path.isdir(new_dir):
os.mkdir(new_dir)
if not os.path.isdir(directory):
if not os.path.isfile(filename):
urllib.request.urlretrieve(url, filename)
tar = tarfile.open(filename, 'r:gz')
tar.extractall(path=directory)
tar.close()
count = 0
for dir_, _, files in os.walk(directory):
for file_ in files:
img = imread(os.path.join(dir_, file_))
imsave(os.path.join(new_dir, '%d.png' % count), img)
count += 1
Copy the code
Sets the data set used to generate the face
# dataset = 'lfw_new_imgs' # LFW
dataset = 'celeba' # CelebA
images = glob.glob(os.path.join(dataset, '*. *'))
print(len(images))
Copy the code
Define constants, network inputs, and helper functions
batch_size = 100
z_dim = 100
WIDTH = 64
HEIGHT = 64
OUTPUT_DIR = 'samples_' + dataset
if not os.path.exists(OUTPUT_DIR):
os.mkdir(OUTPUT_DIR)
X = tf.placeholder(dtype=tf.float32, shape=[None, HEIGHT, WIDTH, 3], name='X')
noise = tf.placeholder(dtype=tf.float32, shape=[None, z_dim], name='noise')
is_training = tf.placeholder(dtype=tf.bool, name='is_training') def lrelu (x, leak = 0.2) :return tf.maximum(x, leak * x)
def sigmoid_cross_entropy_with_logits(x, y):
return tf.nn.sigmoid_cross_entropy_with_logits(logits=x, labels=y)
Copy the code
Discriminator part
Def discriminator(image, reuse=None, is_training=is_training): momentum = 0.9 with tf.variable_scope()'discriminator', reuse=reuse):
h0 = lrelu(tf.layers.conv2d(image, kernel_size=5, filters=64, strides=2, padding='same'))
h1 = tf.layers.conv2d(h0, kernel_size=5, filters=128, strides=2, padding='same')
h1 = lrelu(tf.contrib.layers.batch_norm(h1, is_training=is_training, decay=momentum))
h2 = tf.layers.conv2d(h1, kernel_size=5, filters=256, strides=2, padding='same')
h2 = lrelu(tf.contrib.layers.batch_norm(h2, is_training=is_training, decay=momentum))
h3 = tf.layers.conv2d(h2, kernel_size=5, filters=512, strides=2, padding='same')
h3 = lrelu(tf.contrib.layers.batch_norm(h3, is_training=is_training, decay=momentum))
h4 = tf.contrib.layers.flatten(h3)
h4 = tf.layers.dense(h4, units=1)
return tf.nn.sigmoid(h4), h4
Copy the code
Generator section
Def generator(z, is_training=is_training): momentum = 0.9 with tf.variable_scope('generator', reuse=None):
d = 4
h0 = tf.layers.dense(z, units=d * d * 512)
h0 = tf.reshape(h0, shape=[-1, d, d, 512])
h0 = tf.nn.relu(tf.contrib.layers.batch_norm(h0, is_training=is_training, decay=momentum))
h1 = tf.layers.conv2d_transpose(h0, kernel_size=5, filters=256, strides=2, padding='same')
h1 = tf.nn.relu(tf.contrib.layers.batch_norm(h1, is_training=is_training, decay=momentum))
h2 = tf.layers.conv2d_transpose(h1, kernel_size=5, filters=128, strides=2, padding='same')
h2 = tf.nn.relu(tf.contrib.layers.batch_norm(h2, is_training=is_training, decay=momentum))
h3 = tf.layers.conv2d_transpose(h2, kernel_size=5, filters=64, strides=2, padding='same')
h3 = tf.nn.relu(tf.contrib.layers.batch_norm(h3, is_training=is_training, decay=momentum))
h4 = tf.layers.conv2d_transpose(h3, kernel_size=5, filters=3, strides=2, padding='same', activation=tf.nn.tanh, name='g')
return h4
Copy the code
Loss function
g = generator(noise)
d_real, d_real_logits = discriminator(X)
d_fake, d_fake_logits = discriminator(g, reuse=True)
vars_g = [var for var in tf.trainable_variables() if var.name.startswith('generator')]
vars_d = [var for var in tf.trainable_variables() if var.name.startswith('discriminator')]
loss_d_real = tf.reduce_mean(sigmoid_cross_entropy_with_logits(d_real_logits, tf.ones_like(d_real)))
loss_d_fake = tf.reduce_mean(sigmoid_cross_entropy_with_logits(d_fake_logits, tf.zeros_like(d_fake)))
loss_g = tf.reduce_mean(sigmoid_cross_entropy_with_logits(d_fake_logits, tf.ones_like(d_fake)))
loss_d = loss_d_real + loss_d_fake
Copy the code
Optimization function
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) with tf.control_dependencies(update_ops): Optimizer_d = tf. Train. AdamOptimizer (learning_rate = 0.0002, beta1 = 0.5). Minimize (loss_d, Var_list =vars_d) optimizer_g = tf.train.adamoptimizer (learning_rate=0.0002, beta1=0.5). Minimize (loss_g, var_list=vars_g)Copy the code
The function that reads the picture
def read_image(path, height, width):
image = imread(path)
h = image.shape[0]
w = image.shape[1]
if h > w:
image = image[h // 2 - w // 2: h // 2 + w // 2, :, :]
else:
image = image[:, w // 2 - h // 2: w // 2 + h // 2, :]
image = imresize(image, (height, width))
return image / 255.
Copy the code
The function that synthesizes the picture
def montage(images):
if isinstance(images, list):
images = np.array(images)
img_h = images.shape[1]
img_w = images.shape[2]
n_plots = int(np.ceil(np.sqrt(images.shape[0])))
iflen(images.shape) == 4 and images.shape[3] == 3: M = np.ones((images.shape[1] * n_plots + n_plots + 1, images.shape[2] * n_plots + n_plots + 1, 3)) * 0.5eliflen(images.shape) == 4 and images.shape[3] == 1: M = np.ones((images.shape[1] * n_plots + n_plots + 1, images.shape[2] * n_plots + n_plots + 1, 1)) * 0.5eliflen(images.shape) == 3: M = np.ones((images.shape[1] * n_plots + n_plots + 1, images.shape[2] * n_plots + n_plots + 1)) * 0.5else:
raise ValueError('Could not parse image shape of {}'.format(images.shape))
for i in range(n_plots):
for j in range(n_plots):
this_filter = i * n_plots + j
if this_filter < images.shape[0]:
this_img = images[this_filter]
m[1 + i + i * img_h:1 + i + (i + 1) * img_h,
1 + j + j * img_w:1 + j + (j + 1) * img_w] = this_img
return m
Copy the code
Model training
Sess = tf.session () sess.run(tf.global_variables_initializer()) z_samples = Np.random. Uniform (-1.0, 1.0, [batch_size, z_dim]).astype(np.float32) samples = [] loss = {'d': [].'g': []}
offset = 0
for i inrange(60000): N = np.random. Uniform (-1.0, 1.0, [batch_size, z_dim]).astype(np.float32) offset = (offset + batch_size) % len(images) batch = np.array([read_image(img, HEIGHT, WIDTH)for img inImages [offset: offset + batch_size]]) Batch = (batch-0.5) * 2 d_ls, g_ls = sess.run([loss_d, loss_g], feed_dict={X: batch, noise: n, is_training: True}) loss['d'].append(d_ls)
loss['g'].append(g_ls)
sess.run(optimizer_d, feed_dict={X: batch, noise: n, is_training: True})
sess.run(optimizer_g, feed_dict={X: batch, noise: n, is_training: True})
sess.run(optimizer_g, feed_dict={X: batch, noise: n, is_training: True})
if i % 500 == 0:
print(i, d_ls, g_ls)
gen_imgs = sess.run(g, feed_dict={noise: z_samples, is_training: False})
gen_imgs = (gen_imgs + 1) / 2
imgs = [img[:, :, :] for img in gen_imgs]
gen_imgs = montage(imgs)
plt.axis('off')
plt.imshow(gen_imgs)
imsave(os.path.join(OUTPUT_DIR, 'sample_%d.jpg' % i), gen_imgs)
plt.show()
samples.append(gen_imgs)
plt.plot(loss['d'], label='Discriminator')
plt.plot(loss['g'], label='Generator')
plt.legend(loc='upper right')
plt.savefig(os.path.join(OUTPUT_DIR, 'Loss.png'))
plt.show()
mimsave(os.path.join(OUTPUT_DIR, 'samples.gif'), samples, fps=10)
Copy the code
The LFW results are as follows
CelebA face generation results are as follows
Save the model for later use
saver = tf.train.Saver()
saver.save(sess, os.path.join(OUTPUT_DIR, 'dcgan_' + dataset), global_step=60000)
Copy the code
Use the model to generate face images on a single machine
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
batch_size = 100
z_dim = 100
dataset = 'lfw_new_imgs'
# dataset = 'celeba'
def montage(images):
if isinstance(images, list):
images = np.array(images)
img_h = images.shape[1]
img_w = images.shape[2]
n_plots = int(np.ceil(np.sqrt(images.shape[0])))
iflen(images.shape) == 4 and images.shape[3] == 3: M = np.ones((images.shape[1] * n_plots + n_plots + 1, images.shape[2] * n_plots + n_plots + 1, 3)) * 0.5eliflen(images.shape) == 4 and images.shape[3] == 1: M = np.ones((images.shape[1] * n_plots + n_plots + 1, images.shape[2] * n_plots + n_plots + 1, 1)) * 0.5eliflen(images.shape) == 3: M = np.ones((images.shape[1] * n_plots + n_plots + 1, images.shape[2] * n_plots + n_plots + 1)) * 0.5else:
raise ValueError('Could not parse image shape of {}'.format(images.shape))
for i in range(n_plots):
for j in range(n_plots):
this_filter = i * n_plots + j
if this_filter < images.shape[0]:
this_img = images[this_filter]
m[1 + i + i * img_h:1 + i + (i + 1) * img_h,
1 + j + j * img_w:1 + j + (j + 1) * img_w] = this_img
return m
sess = tf.Session()
sess.run(tf.global_variables_initializer())
saver = tf.train.import_meta_graph(os.path.join('samples_' + dataset, 'dcgan_' + dataset + '-60000.meta'))
saver.restore(sess, tf.train.latest_checkpoint('samples_' + dataset))
graph = tf.get_default_graph()
g = graph.get_tensor_by_name('generator/g/Tanh:0')
noise = graph.get_tensor_by_name('noise:0')
is_training = graph.get_tensor_by_name('is_training:0') n = Np.random. Uniform (-1.0, 1.0, [batch_size, z_DIM]).astype(nP.float32) gen_imgs = sess.run(g, feed_dict={noise: n, is_training: False}) gen_imgs = (gen_imgs + 1) / 2 imgs = [img[:, :, :]for img in gen_imgs]
gen_imgs = montage(imgs)
gen_imgs = np.clip(gen_imgs, 0, 1)
plt.figure(figsize=(8, 8))
plt.axis('off')
plt.imshow(gen_imgs)
plt.show()
Copy the code
reference
- DCGAN-tensorflow:github.com/carpedm20/D…
- LFW:vis-www.cs.umass.edu/lfw/
- CelebA:mmlab.ie.cuhk.edu.hk/projects/Ce…
Video lecture course
Deep and interesting (1)