制作网站要求,网站大数据怎么做,佳能网站建设需求报告,怎样做引流推广上一篇文章–[GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(上#xff09;中#xff0c;我们先介绍了对于图像修复的背景#xff0c;需要利用什么信息来对缺失的区域进行修复#xff0c;以及将图像当做概率分布采样的样本来看待#xff0c;通过这个思路来开始进行…上一篇文章–[GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(上中我们先介绍了对于图像修复的背景需要利用什么信息来对缺失的区域进行修复以及将图像当做概率分布采样的样本来看待通过这个思路来开始进行图像的修复。
这篇文章将继续介绍原文的第二部分利用对抗生成网络来快速生成假图片。目录如下
第二步快速生成假的图片 从未知的概率分布中学习生成新的样本[ML-Heavy] 建立 GAN 模型采用 G(z) 生成假的图片[ML-Heavy] 训练 DCGAN目前的 GAN 和 DCGAN 实现[ML-Heavy] TensorFlow 实现 DCGAN在你的数据集上运行 DCGAN 模型
同样的标题带有 [ML-Heavy] 的会介绍比较多的细节可以选择跳过。 第二步快速生成假的图片
从未知的概率分布中学习生成新的样本
与其考虑如何计算概率密度函数现在在统计学中更好的方法是采用一个生成模型来学习如何生成新的、随机的样本。过去生成模型一直是很难训练或者非常难以实现但最近在这个领域已经有了一些让人惊讶的进展。Yann LeCun在这篇 Quora 上的问题“最近在深度学习有什么潜在的突破的领域”中给出了一种训练生成模型对抗训练方法的介绍并将其描述为过去十年内机器学习最有趣的想法 Yann LeCun 在回答中简单介绍了 GAN 的基本原理也就是两个网络相互博弈的过程。
实际上深度学习还有其他方法来训练生成模型比如 Variational Autoencoders(VAEs)。但在本文主要介绍对抗生成网络GANs
[ML-Heavy] 建立 GAN 模型
GANs 这个想法是 Ian Goodfellow 在其带有里程碑意义的论文“Generative Adversarial Nets” (GANs)发表在 2014 年的 Neural Information Processing Systems (NIPS) 会议上后开始火遍整个深度学习领域的。这个想法就是我们首先定义一个简单并众所周知的概率分布并表示为pzp_zpz在本文后面我们用 pzp_zpz 表示在[-1,1)包含-1但不包含1范围的均匀分布。用z∼pzz \thicksim p_zz∼pz表示从这个分布中采样如果pzp_zpz是一个五维的我们可以利用下面一行的 Python 代码来进行采样得到这里用到 numpy这个库
z np.random.uniform(-1, 1, 5)
array([ 0.77356483, 0.95258473, -0.18345086, 0.69224724, -0.34718733])现在我们有一个简单的分布来进行采样接下来可以定义一个函数G(z)来从原始的概率分布中生成样本代码例子如下所示
def G(z):...return imageSamplez np.random.uniform(-1, 1, 5)
imageSample G(z)那么问题来了怎么定义这个G(Z)函数让它实现输入一个向量然后返回一张图片呢答案就是采用一个深度神经网络。对于深度神经网络基础网络上有很多的介绍本文就不再重复介绍了。这里推荐的一些参考有斯坦福大学的 CS231n 课程、Ian Goodfellow 等人编著的《深度学习》书籍、形象解释图像的核心以及论文A guide to convolution arithmetic for deep learning。
通过深度学习可以有多种方法来实现G(z)函数。在原始的 GAN 论文中提出一种训练方法并给出初步的实验结果这个方法得到了极大的发展和改进。其中一种想法就是在论文“Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks”中提出的这篇论文的作者是 Alec Radford, Luke Metz, and Soumith Chintala发表在 2016 年的 International Conference on Learning Representations (ICLR)会议上这个方法因为提出采用深度卷积神经网络被称为 DCGANs它主要采用小步长卷积 fractionally-strided convolution方法来上采样图像。
那么什么是小步长卷积以及如何实现对图片的上采样呢 Vincent Dumoulin and Francesco Visin’s 在论文A guide to convolution arithmetic for deep learning以及 Github 项目都给出了这种卷积算术的详细介绍Github 地址如下
https://github.com/vdumoulin/conv_arithmetic
上述 Github 项目给出了非常直观的可视化如下图所示这让我们可以很直观了解小步长卷积是如何工作的。
首先你要知道一个正常的卷积操作是一个卷积核划过输入区域下图中蓝色区域后生成一个输出区域下图的绿色区域。这里输出区域的尺寸是小于输入区域的。当然如果你还不知道可以先看下斯坦福大学的CS231n 课程或者论文A guide to convolution arithmetic for deep learning。 接下来假设输入是 3x3。我们的目标是通过上采样让输出尺寸变大。你可以认为小步长卷积就是在像素之间填充 0 值来拓展输入区域的方法然后再对输入区域进行卷积操作正如下图所示得到一个 5x5 的输出。 注意对于作为上采样的卷积层有很多不同的名字比如全卷积(full convolution), 网络内上采样in-network upsampling, 小步长卷积fractionally-strided convolution, 反向卷积backwards convolution, 反卷积deconvolution, 上卷积upconvolution, 转置卷积transposed convolution。这里并不鼓励使用反卷积deconvolution这个词语因为在数学运算或者计算机视觉的其他应用中这个词语有着其他完全不同的意思这是一个非常频繁使用的词语。
现在利用小步长卷积作为基础我们可以实现G(z)函数让它接收一个z∼pzz \thicksim p_zz∼pz的向量输入然后输出一张尺寸是 64x64x3 的彩色图片其网络结构如下图所示 在 DCGAN 这篇论文中还提出了其他的一些技巧和改进来训练 DCGANs比如采用批归一化(batch normalization)或者是 leaky ReLUs 激活函数。
采用 G(z) 生成假的图片
现在先让我们暂停并欣赏下这种G(z)网络结构的强大在 DCGAN 论文中给出了如何采用一个卧室图片数据集训练 一个 DCGAN 模型然后采用G(z)生成如下的图片它们都是生成器网络 G 认为的卧室图片注意下面这些图片都是原始训练数据集没有的 此外你还可以对 z 输入实现一个向量算术操作下图就是一个例子 [ML-Heavy] 训练 DCGAN
现在我们定义好了G(z)也知道它的能力有多强大问题来了怎么训练呢我们需要确定很多隐变量或者说参数这也是采用对抗网络的原因了。
首先我们先定义几个符号。pdatap_datapdata表示训练数据但概率分布未知pzp_zpz表示从已知的概率分布采样的样本一般从高斯分布或者均匀分布采样z也被称为随机噪声最后一个pgp_gpg就是 G 网络生成的数据也可以说是生成概率分布。
接着介绍下判别器discriminatorD网络它是输入一批图片x然后返回该图片来自训练数据pdatap_{data}pdata的概率。如果来自训练数据D 应该返回一个接近 1 的数值否则应该是一个接近 0 的值来表示图片是假的来自 G 网络生成的。在 DCGANs 中D 网络是一个传统的卷积神经网络如下图所示一个包含4层卷积层和1层全连接层的卷积神经网络结构。 因此训练 D 网络的目标有以下两个
如果x来自训练数据集最大化D(x)如果x是来自 G 生成的数据最小化D(x)。
对应的 G 网络的目标就是要欺骗 D 网络生成以假乱真的图片。它生成的图片也是 D 的输入所以 G 的目标就是最大化D(G(z))也等价于最小化1-D(G(z))因为 D 其实是一个概率估计且输出范围是在 0 到 1 之间。
正如论文提到的训练对抗网络就如同在实现一个最小化最大化游戏(minimax game)。如下面的公式所示第一项是对真实数据分布的期望第二项是对生成数据的期望值。 训练的步骤如下图所示具体可以看下我之前写的文章[GAN学习系列2] GAN的起源有简单介绍了这个训练过程或者是看下 GAN 论文[5]的介绍 目前的 GAN 和 DCGAN 实现
目前在 Github 上有许多 GAN 和 DCGAN 的实现原文是写于2016年八月份现在的话代码就更多了
https://github.com/goodfeli/adversarialhttps://github.com/tqchen/mxnet-ganhttps://github.com/Newmu/dcgan_codehttps://github.com/soumith/dcgan.torchhttps://github.com/carpedm20/DCGAN-tensorflowhttps://github.com/openai/improved-ganhttps://github.com/mattya/chainer-DCGANhttps://github.com/jacobgil/keras-dcgan
本文实现的代码是基于 https://github.com/carpedm20/DCGAN-tensorflow
[ML-Heavy] TensorFlow 实现 DCGAN
这部分的实现的源代码可以在如下 Github 地址
https://github.com/bamos/dcgan-completion.tensorflow
当然主要实现部分代码是来自 https://github.com/carpedm20/DCGAN-tensorflow 。但采用这个项目主要是方便实现下一部分的图像修复工作。
主要实现代码是在model.py中的类DCGAN。采用类来实现模型是有助于训练后保存中间层的状态以及后续的加载使用。
首先我们需要定义生成器和判别器网络结构。在ops.py会定义网络结构用到的函数如linear,conv2d_transpose, conv2d以及 lrelu。代码如下所示
def generator(self, z):self.z_, self.h0_w, self.h0_b linear(z, self.gf_dim*8*4*4,g_h0_lin, with_wTrue)self.h0 tf.reshape(self.z_, [-1, 4, 4, self.gf_dim * 8])h0 tf.nn.relu(self.g_bn0(self.h0))self.h1, self.h1_w, self.h1_b conv2d_transpose(h0,[self.batch_size, 8, 8, self.gf_dim*4], nameg_h1, with_wTrue)h1 tf.nn.relu(self.g_bn1(self.h1))h2, self.h2_w, self.h2_b conv2d_transpose(h1,[self.batch_size, 16, 16, self.gf_dim*2], nameg_h2, with_wTrue)h2 tf.nn.relu(self.g_bn2(h2))h3, self.h3_w, self.h3_b conv2d_transpose(h2,[self.batch_size, 32, 32, self.gf_dim*1], nameg_h3, with_wTrue)h3 tf.nn.relu(self.g_bn3(h3))h4, self.h4_w, self.h4_b conv2d_transpose(h3,[self.batch_size, 64, 64, 3], nameg_h4, with_wTrue)return tf.nn.tanh(h4)def discriminator(self, image, reuseFalse):if reuse:tf.get_variable_scope().reuse_variables()h0 lrelu(conv2d(image, self.df_dim, named_h0_conv))h1 lrelu(self.d_bn1(conv2d(h0, self.df_dim*2, named_h1_conv)))h2 lrelu(self.d_bn2(conv2d(h1, self.df_dim*4, named_h2_conv)))h3 lrelu(self.d_bn3(conv2d(h2, self.df_dim*8, named_h3_conv)))h4 linear(tf.reshape(h3, [-1, 8192]), 1, d_h3_lin)return tf.nn.sigmoid(h4), h4当初始化这个类的时候就相当于用上述函数来构建了这个模型。我们需要创建两个 D 网络来共享参数一个的输入是真实数据另一个是来自 G 网络的生成数据。
self.G self.generator(self.z)
self.D, self.D_logits self.discriminator(self.images)
self.D_, self.D_logits_ self.discriminator(self.G, reuseTrue)接下来是定义损失函数。这里采用的是 D 的输出之间的交叉熵函数并且它的效果也不错。D 是期望对真实数据的预测都是 1对生成的假数据预测都是 0相反生成器 G 希望 D 的预测都是 1。代码的实现如下
self.d_loss_real tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits,tf.ones_like(self.D)))
self.d_loss_fake tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits_,tf.zeros_like(self.D_)))
self.d_loss self.d_loss_real self.d_loss_fakeself.g_loss tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits_,tf.ones_like(self.D_)))接着是分别对 G 和 D 的参数聚集到一起方便后续的梯度计算
t_vars tf.trainable_variables()self.d_vars [var for var in t_vars if d_ in var.name]
self.g_vars [var for var in t_vars if g_ in var.name]现在才有 ADAM 作为优化器来计算梯度ADAM 是一个深度学习中常用的自适应非凸优化方法它相比于随机梯度下降方法不需要手动调整学习率、动量momentum)以及其他的超参数。
d_optim tf.train.AdamOptimizer(config.learning_rate, beta1config.beta1) \.minimize(self.d_loss, var_listself.d_vars)
g_optim tf.train.AdamOptimizer(config.learning_rate, beta1config.beta1) \.minimize(self.g_loss, var_listself.g_vars)定义好模型和训练策略后接下来就是开始输入数据进行训练了。在每个 epoch 中先采样一个 mini-batch 的图片然后运行优化器来更新网络。有趣的是如果 G 只更新一次D 的 loss 是不会变为0的。此外在后面额外调用d_loss_fake和d_loss_real会增加不必要的计算量并且也是多余的因为它们的数值在d_optim和g_optim计算的时候已经计算到了。这里你可以尝试优化这部分代码然后发送一个 PR 到原始的 Github 项目中。
for epoch in xrange(config.epoch):...for idx in xrange(0, batch_idxs):batch_images ...batch_z np.random.uniform(-1, 1, [config.batch_size, self.z_dim]) \.astype(np.float32)# Update D network_, summary_str self.sess.run([d_optim, self.d_sum],feed_dict{ self.images: batch_images, self.z: batch_z })# Update G network_, summary_str self.sess.run([g_optim, self.g_sum],feed_dict{ self.z: batch_z })# Run g_optim twice to make sure that d_loss does not go to zero# (different from paper)_, summary_str self.sess.run([g_optim, self.g_sum],feed_dict{ self.z: batch_z })errD_fake self.d_loss_fake.eval({self.z: batch_z})errD_real self.d_loss_real.eval({self.images: batch_images})errG self.g_loss.eval({self.z: batch_z})完整的代码可以在 https://github.com/bamos/dcgan-completion.tensorflow/blob/master/model.py 中查看
在你的数据集上运行 DCGAN 模型
如果你跳过上一小节但希望运行一些代码这部分的实现的源代码可以在如下 Github 地址
https://github.com/bamos/dcgan-completion.tensorflow
当然主要实现部分代码是来自 https://github.com/carpedm20/DCGAN-tensorflow 。但采用这个项目主要是方便实现下一部分的图像修复工作。但必须注意的是如果你没有一个可以使用 CUDA 的 GPU 显卡那么训练网络将会非常慢。
首先需要克隆两份项目代码地址分别如下
https://github.com/bamos/dcgan-completion.tensorflow
http://cmusatyalab.github.io/openface
第一份就是作者的项目代码第二份是采用 OpenFace 的预处理图片的 Python 代码并不需要安装它的 Torch 依赖包。先创建一个新的工作文件夹然后开始克隆如下所示
git clone https://github.com/cmusatyalab/openface.git
git clone https://github.com/bamos/dcgan-completion.tensorflow.git接着是安装 Python2 版本的 OpenCV和 dlib采用 Python2 版本是因为 OpenFace 采用这个版本当然你也可以尝试修改为适应 Python3 版本。对于 OpenFace 的 Python 库安装可以查看其安装指导教程链接如下
http://cmusatyalab.github.io/openface/setup/
此外如果你没有采用一个虚拟环境那么需要加入sudo命令来运行setup.py实现全局的安装 OpenFace当然如果安装这部分有问题也可以采用 OpenFace 的 docker 镜像安装。安装的命令如下所示
cd openface
pip2 install -r requirements.txt
python2 setup.py install
models/get-models.sh
cd ..接着就是下载一些人脸图片数据集了这里并不要求它们是否带有标签因为不需要。目前开源可选的数据集包括
MS-Celeb-1M–https://www.microsoft.com/en-us/research/project/msr-image-recognition-challenge-irc/CelebA–http://mmlab.ie.cuhk.edu.hk/projects/CelebA.htmlCASIA-WebFace–http://www.cbsr.ia.ac.cn/english/CASIA-WebFace-Database.htmlFaceScrub–http://vintage.winklerbros.net/facescrub.htmlLFW–http://vis-www.cs.umass.edu/lfw/MegaFace–http://megaface.cs.washington.edu/
然后将数据集放到目录dcgan-completion.tensorflow/data/your-dataset/raw下表示其是原始的图片。
接着采用 OpenFace 的对齐工具来预处理图片并调整成64x64的尺寸
./openface/util/align-dlib.py data/dcgan-completion.tensorflow/data/your-dataset/raw align innerEyesAndBottomLip data/dcgan-completion.tensorflow/data/your-dataset/aligned --size 64最后是整理下保存对齐图片的目录保证只包含图片而没有其他的子文件夹
cd dcgan-completion.tensorflow/data/your-dataset/aligned
find . -name *.png -exec mv {} . \;
find . -type d -empty -delete
cd ../../..然后确保已经安装了 TensorFlow那么可以开始训练 DCGAN了
./train-dcgan.py --dataset ./data/your-dataset/aligned --epoch 20在samples文件夹中可以查看保存的由 G 生成的图片。这里作者是采用手上有的两个数据集 CASIA-WebFace 和 FaceScrub 进行训练并在训练 14 个 epochs 后生成的结果如下图所示 还可以通过 TensorBoard 来查看 loss 的变化
tensorboard --logdir ./logs小结
这就是本文的第二部分内容主要是介绍了 DCGAN 的基本原理以及代码实现还有就是训练前的准备和开始训练训练的实验结果。
在下一篇将介绍最后一步内容如何利用 DCGAN 来实现图像修复的工作
欢迎关注我的微信公众号–机器学习与计算机视觉或者扫描下方的二维码在后台留言和我分享你的建议和看法指正文章中可能存在的错误大家一起交流学习和进步 推荐阅读
1.机器学习入门系列(1)–机器学习概览(上)
2.机器学习入门系列(2)–机器学习概览(下)
3.[GAN学习系列] 初识GAN
4.[GAN学习系列2] GAN的起源
5.[GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(上