简介

在人脸数据上训练DCGAN,并生成一些人脸图片

数据

使用两个数据集

  • LFW:http://vis-www.cs.umass.edu/lfw/,Labeled Faces in the Wild,超过1.3W张图片,其中1680人拥有超过两张或以上图片
  • CelebA:http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html,CelebFaces Attributes Dataset,包括10177人共计超过20W张图片,并且每张图片还包括人脸的5个关键点位置和40个属性的01标注,例如是否有眼镜、帽子、胡子等

实现

和上节课的代码差不多,根据彩色图片进行适当调整即可

加载库

# -*- 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

下载LFW数据并解压处理,CelebA数据已经准备好

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 = 0for 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

设定用于生成人脸的数据集

# dataset = 'lfw_new_imgs' # LFW
dataset = 'celeba' # CelebA
images = glob.glob(os.path.join(dataset, '*.*'))
print(len(images))

定义一些常量、网络输入、辅助函数

batch_size = 100
z_dim = 100
WIDTH = 64
HEIGHT = 64OUTPUT_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)

判别器部分

def discriminator(image, reuse=None, is_training=is_training):momentum = 0.9with 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

生成器部分

def generator(z, is_training=is_training):momentum = 0.9with tf.variable_scope('generator', reuse=None):d = 4h0 = 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

损失函数

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

优化函数

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)

读取图片的函数

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.

合成图片的函数

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])))if len(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.5elif len(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.5elif len(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 + jif 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_imgreturn m

模型的训练

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 in range(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 in images[offset: offset + batch_size]])batch = (batch - 0.5) * 2d_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) / 2imgs = [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)

LFW人脸生成结果如下

CelebA人脸生成结果如下

保存模型,便于后续使用

saver = tf.train.Saver()
saver.save(sess, os.path.join(OUTPUT_DIR, 'dcgan_' + dataset), global_step=60000)

在单机上使用模型生成人脸图片

# -*- coding: utf-8 -*-import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import osbatch_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])))if len(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.5elif len(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.5elif len(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 + jif 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_imgreturn msess = 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()

参考

  • DCGAN-tensorflow:https://github.com/carpedm20/DCGAN-tensorflow
  • LFW:http://vis-www.cs.umass.edu/lfw/
  • CelebA:http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html

视频讲解课程

深度有趣(一)

深度有趣 | 08 DCGAN人脸图片生成相关推荐

  1. 使用PyTorch构建卷积GAN源码(详细步骤讲解+注释版) 02人脸图片生成 上

    阅读提示:本篇文章的代码为在普通GAN代码上实现人脸图片生成的修改,文章内容仅包含修改内容,全部代码讲解需结合下面的文章阅读. 相关资料链接为:使用PyTorch构建GAN生成对抗 本次训练代码使用了 ...

  2. 深度有趣 | 23 歌词古诗自动生成

    简介 使用RNN实现歌词和古诗的自动生成 RNN多用于处理序列数据,通过学习数据上下文之间的关系,可以在给定若干个连续数据点的基础上,预测下一个可能的数据点 以下是最基础的RNN公式,当然也可以使用L ...

  3. 好像还挺好玩的GAN2——Keras搭建DCGAN利用深度卷积神经网络实现图片生成

    好像还挺好玩的GAN2--Keras搭建DCGAN利用深度卷积神经网络实现图片生成 注意事项 学习前言 什么是DCGAN 神经网络构建 1.Generator 2.Discriminator 训练思路 ...

  4. 【项目实战课】基于Pytorch的DCGAN人脸嘴部表情图像生成实战

    欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的DCGAN人脸嘴部表情图像生成实战>. 所谓项目实战课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行 ...

  5. 有趣的图像生成——使用DCGAN与pytorch生成动漫头像

    有趣的图像生成--使用DCGAN与pytorch生成动漫头像 文章目录 有趣的图像生成--使用DCGAN与pytorch生成动漫头像 一.源码下载 二.什么是DCGAN 三.DCGAN的实现 1.** ...

  6. 深度学习之自编码器(5)VAE图片生成实战

    深度学习之自编码器(5)VAE图片生成实战 1. VAE模型 2. Reparameterization技巧 3. 网络训练 4. 图片生成 VAE图片生成实战完整代码  本节我们基于VAE模型实战F ...

  7. 深度有趣 | 09 Inception-v3图片分类

    简介 Inception-v3是由Google提出,用于实现ImageNet大规模视觉识别任务(ImageNet Large Visual Recognition Challenge)的一种神经网络 ...

  8. [GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(下)

    这是本文的最后一部分内容了,前两部分内容的文章: [GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(上) [GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复( ...

  9. [GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(中)

    上一篇文章–[GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(上)中,我们先介绍了对于图像修复的背景,需要利用什么信息来对缺失的区域进行修复,以及将图像当做概率分布采样的样本来看 ...

最新文章

  1. pandas使用replace函数将所有的无穷大值np.inf替换为缺失值np.nan、使用pandas的fillna函数用经验固定值填充缺失值np.nan
  2. 漫话:如何给女朋友解释为什么不能在 MySQL 中使用 UTF-8 编码
  3. Spring Boot 入门
  4. Android 各种工
  5. 大数据和人工智能的关系是什么?
  6. OpenCV vs Dlib 人脸检测比较分析
  7. ubuntu中实践操作系统第二章系统调用与课件不同之处
  8. java笔试题算法题,吐血整理
  9. BigGAN论文解读
  10. 关于CC2541蓝牙开发板的学习笔记
  11. 学习Hibernate框架笔记-第1天
  12. A*寻路算法之解决目标点不可达问题
  13. Hazelcast IMDG参考中文版手册-第二章-入门
  14. 业余草告诉你甲骨文正式宣布将 Java EE 移交给 Eclipse 基金会
  15. 攻防红队日记:利用路由器创建PPTP搭建隧道进内网
  16. mu修改连接服务器名,自己设置mu服务器自己玩
  17. proteus仿真4路AD转换——pcf8591芯片
  18. 985程序员吐槽:互联网行业疲于奔命,公务员才是我想要的生活
  19. Web前端UI框架 JQuery WeUI
  20. 数字多波束相控阵基础知识

热门文章

  1. 【php基础入门】PHP中常用的数组操作使用方法笔记整理(推荐)
  2. 更改python保存路径_更的解释|更的意思|汉典“更”字的基本解释
  3. 玩游戏也能借钱?这家公司推出游戏贷,催用户还钱被要求“叫爸爸”
  4. 为什么房产等实体资产不适合做同质化所有权拆分
  5. 联想笔记本怎么进入pe系统_联想笔记本电脑无法进入PE
  6. 计算机主板 安装系统,电脑更换主板不用重装系统的方法有哪些
  7. 思维的力量——六顶思考帽
  8. 关于中华人民共和国网络安全法及本人免责声明
  9. powerdesigner画鲁棒图
  10. RabbitMq分布式事务解决方案第一篇