DCGAN及其tensorflow版源码解读

上一节我们提到GD由多层感知机定义深度学习中对图像处理应用最好的模型是CNN,那么如何把CNNGAN结合?DCGAN是这方面最好的尝试之一。源码:https://github.com/Newmu/dcgan_code 。DCGAN论文作者用theano实现的,他还放上了其他人实现的版本,本文主要讨论tensorflow版本。

TensorFlow版本的源码:https://github.com/carpedm20/DCGAN-tensorflow


DCGAN把上述的G和D换成了两个卷积神经网络(CNN)。但不是直接换就可以了,DCGAN对卷积神经网络的结构做了一些改变,以提高样本的质量和收敛的速度,这些改变有:

  • 取消所有pooling层。G网络中使用转置卷积(transposed convolutional layer)进行上采样,D网络中用加入strided的卷积代替pooling。
  • 在D和G中均使用batch normalization
  • 去掉FC层,使网络变为全卷积网络
  • G网络中使用ReLU作为激活函数,最后一层使用tanh
  • D网络中使用LeakyReLU作为激活函数
这些改变在代码中都可以看到。DCGAN论文中提到对CNN结构有三点重要的改变:

(1) Allconvolutional net (Springenberg et al., 2014) 全卷积网络

Ÿ   判别模型D:使用带步长的卷积(strided convolutions)取代了的空间池化(spatial pooling),容许网络学习自己的空间下采样(spatial downsampling)。

Ÿ   生成模型G:使用微步幅卷积(fractional strided),容许它学习自己的空间上采样(spatial upsampling)

(2)在卷积特征之上消除全连接层。

Ÿ   (Mordvintsev et al.)提出的全局平均池化有助于模型的稳定性,但损害收敛速度。

GAN的第一层输入:服从均匀分布的噪声向量Z,因为只有矩阵乘法,因此可以被叫做全连接层,但结果会被reshape成4维张量,作为卷积栈的开始。

对于D,最后的卷积层被flatten(把矩阵变成向量),然后使用sigmoid函数处理输出。

生成模型:输出层用Tanh函数,其它层用ReLU激活函数。

判别模型:所有层使用LeakyReLU

(3)Batch Normalization 批标准化。

解决因糟糕的初始化引起的训练问题,使得梯度能传播更深层次。稳定学习,通过归一化输入的单元,使它们平均值为0,具有单位方差。

批标准化证明了生成模型初始化的重要性,避免生成模型崩溃:生成的所有样本都在一个点上(样本相同),这是训练GANs经常遇到的失败现象。

generator:100维的均匀分布Z投影到小的空间范围卷积表示,产生许多特征图。一系列四步卷积将这个表示转换为64x64像素的图像。不用到完全连接或者池化层。

配置

Python

TensorFlow

SciPy

pillow

(可选)moviepy (https://github.com/Zulko/moviepy):用于可视化 

(可选)Align&Cropped Images.zip (http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html):人脸数据集


main.py

入口程序,事先定义所需参数的值。

执行程序:

训练一个模型:

    $ python main.py --dataset mnist --is_trainTrue

$ python main.py --dataset celebA --is_trainTrue --is_crop True

测试一个已存在模型:

    $ python main.py --dataset mnist

$ python main.py --dataset celebA --is_cropTrue

你也可以使用自己的dataset:

    $ mkdir data/DATASET_NAME

    添加图片到data/DATASET_NAME ...

    $ python main.py --dataset DATASET_NAME--is_train True

$ python main.py --dataset DATASET_NAME

训练出多张以假乱真的图片

源码分析

flags配置network的参数,在命令行中可以修改,比如

$pythonmain.py --image_size 96 --output_size 48 --dataset anime --is_crop True--is_train True --epoch 300

该套代码参数主要以mnist数据集为模板,如果要训练别的数据集,可以适当修改一些参数。mnist数据集可以通过download.py下载。

首先初始化model.py中的DCGAN,然后看是否需要训练(is_train)。

参数说明

c_dim:颜色通道,灰度图像设为1,彩色图像设为3

y_dim:只有训练mnist数据集时不为空

output_size:输出图像的边长,这里没有分长和宽,而是当做正方形,只设边长。

model.py

定义了DCGAN类,包括9个函数:

  •  __init__()

            gf_dim: (optional) G的第一个卷积层的过滤器个数 [64]

            df_dim: (optional) D的第一个卷积层的过滤器个数[64]

            gfc_dim: (optional) 全连接层G单元的个数 [1024]

            dfc_dim: (optional) 全连接层D单元的个数[1024]

其中self.d_bn2是batch标准化,见ops.py的batch_norm(object)。

然后建立模型(build_model)

  •  build_model()

histogram_summary:查看z的变化

self.G =self.generator(self.z):通过噪声z产生G

self.D,self.D_logits = self.discriminator(self.images):输入原始图像构建D

self.sampler = self.sampler(self.z):取样,代码和G很像,没有G训练的过程。

self.D_,self.D_logits_ = self.discriminator(self.G, reuse=True):输入G图像构建

summary这几步是关于可视化,就不管了

tf.ones_like:新建一个与给定tensor大小一致的tensor,其全部元素为1

d_loss_real:D识别出真的图片为真的

d_loss_fake:D识别出假的图片为假   G要降低这两个概率

g_loss:D识别假的图片为真的——D要降低这个概率

  • train()

  • generator()

反卷积的过程。s是输出图像的大小。linear()见ops.py

self.g_bn0(self.h0)调用ops.py里面的batch_norm中的__call__(self, x, train=True)

然后4次反卷积,激活函数为tanh

  • discriminator():

激活函数lrelu见ops.py。四次卷积和激活。然后线性化,返回sigmoid。

 load_mnist(), save(), load()

这三个加载保持等就不仔细讲了

download.py

下载数据

ops.py

  • batch_norm(object)

tf.contrib.layers.batch_norm的代码见https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/layers/python/layers/layers.py

batchnormalization来自于http://arxiv.org/abs/1502.03167

加快训练。

  • deconv2d()

引用tf的反卷积函数tf.nn.conv2d_transpose或tf.nn.deconv2d。以tf.nn.conv2d_transpose为例。

defconv2d_transpose(value, filter, output_shape, strides,padding="SAME", data_format="NHWC", name=None):

    value: 是一个4维的tensor,格式为[batch, height, width, in_channels] 或者 [batch, in_channels,height, width]。

    filter: 是一个4维的tensor,格式为[height, width, output_channels, in_channels],过滤器的in_ channels的维度要和这个匹配。

    output_shape: 一维tensor,表示反卷积操作的输出shapeA

    strides: 针对每个输入的tensor维度,滑动窗口的步长。

    padding: “VALID”或者”SAME”,padding算法

    data_format: “NHWC”或者”NCHW” ,对应value的数据格式。

    name: 可选,返回的tensor名。

deconv= tf.nn.conv2d_transpose(input_, w, output_shape=output_shape,strides=[1,d_h, d_w, 1])

第一个参数是输入,即上一层的结果,

第二个参数是输出输出的特征图维数,是个4维的参数,

第三个参数卷积核的移动步长,[1, d_h, d_w, 1],其中第一个对应一次跳过batch中的多少图片,第二个d_h对应一次跳过图片中多少行,第三个d_w对应一次跳过图片中多少列,第四个对应一次跳过图像的多少个通道。这里直接设置为[1,2,2,1]。即每次反卷积后,图像的滑动步长为2,特征图会扩大缩小为原来2*2=4倍。

utils.py

可视化等函数


总结:稀里糊涂的,就这样吧。有不足之处欢迎指正。


参考:

Springenberg, Jost Tobias, Dosovitskiy, Alexey, Brox, Thomas, and Riedmiller, Martin. Striving for simplicity: The all convolutional net. arXiv preprint arXiv:1412.6806, 2014.

Mordvintsev, Alexander, Olah, Christopher, and Tyka, Mike. Inceptionism : Going deeper into neural networks.http://googleresearch.blogspot.com/2015/06/inceptionism-going-deeper-into-neural.html. Accessed: 2015-06-17.

Radford A, Metz L, Chintala S. UnsupervisedRepresentation Learning with Deep Convolutional Generative AdversarialNetworks[J]. Computer Science, 2015.

http://blog.csdn.net/nongfu_spring/article/details/54342861

http://blog.csdn.net/solomon1558/article/details/52573596


原文地址:https://www.cnblogs.com/mandalalala/p/6798260.html