论文标题:Unsupervised Representation Learning with Deep Convolutional Generative
Adversarial Networks
论文链接:https://arxiv.org/abs/1511.06434 <https://arxiv.org/abs/1511.06434>
参考资料:http://blog.csdn.net/liuxiao214/article/details/73500737
<http://blog.csdn.net/liuxiao214/article/details/73500737>
     http://blog.csdn.net/solomon1558/article/details/52573596
<http://blog.csdn.net/solomon1558/article/details/52573596>
     https://buptldy.github.io/2016/10/29/2016-10-29-deconv/
<https://buptldy.github.io/2016/10/29/2016-10-29-deconv/>

DCGAN的框架

在以往的尝试中,将CNN应用于GAN,都没有获得成功。但是经过一系列探索,我们找到一类结构,可以在分辨率更高、更深的生成模型上稳定地训练。

Historical attempts to scale up GANs using CNNs to model images have been
unsuccessful. However, after extensive model exploration we identified a family
of architectures that resulted in stable training across a range of datasets
and allowed for training higher resolution and deeper generative models.

我们的方法基于对CNN的以下改进:

*
全卷积网络(all convolutional net):用步幅卷积(strided
convolutions)替代确定性空间池化函数(deterministic spatial pooling
functions)(比如最大池化)。允许网络学习自身upsampling/downsampling方式(生成器G/判别器D)。在网络中,所有的pooling层使用
步幅卷积(strided convolutions)(判别网络)和微步幅度卷积(fractional-strided
convolutions)(生成网络)进行替换。

*
在卷积特征之上消除全连接层:例如:全局平均池化(global average pooling),曾被应用于图像分类任务(Mordvintsev et al.
<http://googleresearch.blogspot.com/2015/06/inceptionism-going-deeper-into-neural.html>
)中。global average pooling虽然可以提高模型的稳定性,但是降低了收敛速度。图1所示为模型的框架。

*
批量归一化(Batch Normalization):将每个单元的输入都标准化为0均值与单位方差。这样有助于解决poor
initialization问题并帮助梯度流向更深的网络。防止G把所有rand input都折叠到一个点。但是,将所有层都进行Batch
Normalization,会导致样本震荡和模型不稳定,因此,生成器(G)的输出层和辨别器(D)的输入层不采用Batch Normalization。

*
激活函数:在生成器(G)中,输出层使用Tanh函数,其余层采用 ReLu 函数 ; 判别器(D)中都采用leaky rectified activation(
Maas et al., 2013
<http://googleresearch.blogspot.com/2015/06/inceptionism-going-deeper-into-neural.html>
) (Xu et al., 2015 <https://arxiv.org/abs/1502.00641>) 。

Architecture guidelines for stable Deep Convolutional GANs

* Replace any pooling layers with strided convolutions (discriminator) and
fractional-strided convolutions (generator).
* Use batchnorm in both the generator and the discriminator.
* Remove fully connected hidden layers for deeper architectures.
* Use ReLU activation in generator for all layers except for the output,
which uses Tanh.
* Use LeakyReLU activation in the discriminator for all layers.
Fractionally Strided Convolution )

反卷积(Fractionally Strided Convolution )也被称为:Transposed Convolution or
Deconvolution。
【此处参考 Transposed Convolution, Fractionally Strided Convolution or
Deconvolution <https://buptldy.github.io/2016/10/29/2016-10-29-deconv/>】
先申明几个概念:(详见卷积神经网络 <http://blog.csdn.net/stalbo/article/details/79397492>)

* 二维离散卷积(N=2N=2)
* 方形的特征输入(i1=i2=ii1=i2=i)
* 方形的卷积核尺寸(k1=k2=kk1=k2=k)
* 每个维度相同的步长(s1=s2=ss1=s2=s)
* 每个维度相同的padding(p1=p2=pp1=p2=p)
在介绍反卷积之前,我们先来看看卷积运算和矩阵运算之间的关系。

卷积和矩阵相乘
考虑如下一个简单的卷积层运算,其参数为 i=1,k=3,s=1,p=0i=1,k=3,s=1,p=0,输出 o=2o=2。

对于上述卷积运算,我们把上图所示的3×3卷积核展成一个如下所示的[4,16]的稀疏矩阵 CC,其中,非0元素 wi,jwi,j 表示卷积核的第 ii 行,第
jj 列。

我们再把4×4的输入特征展成[16,1]的矩阵 XX,那么 Y=CXY=CX
则是一个[4,1]的输出特征矩阵,把它重新排列2×2的输出特征就得到最终的结果,从上述分析可以看出卷积层的计算其实是可以转化成矩阵相乘的。值得注意的是,在一些深度学习网络的开源框架中并不是通过这种这个转换方法来计算卷积的,因为这个转换会存在很多无用的0乘操作,Caffe中具体实现卷积计算的方法可参考
Implementing convolution as a matrix multiplication
<https://buptldy.github.io/2016/10/01/2016-10-01-im2col/>。

通过上述的分析,我们已经知道卷积层的前向操作可以表示为和矩阵C相乘,那么 我们很容易得到卷积层的反向传播就是和C的转置相乘。

反卷积和卷积的关系
全面我们已经说过反卷积又被称为Transposed(转置)
Convolution,我们可以看出其实卷积层的前向传播过程就是反卷积层的反向传播过程,卷积层的反向传播过程就是反卷积层的前向传播过程。因为卷积层的前向反向计算分别为乘
CC 和 CTCT,而反卷积层的前向反向计算分别为乘 CTCT 和 (CT)T(CT)T 。所以它们的前向传播和反向传播刚好交换过来。


下图表示一个和上图卷积计算对应的反卷积操作,其中他们的输入输出关系正好相反。如果不考虑通道以卷积运算的反向运算来计算反卷积运算的话,我们还可以通过离散卷积的方法来求反卷积(这里只是为了说明,实际工作中不会这么做)。

同样为了说明,定义反卷积操作参数如下:

* 二维的离散卷积(N=2N=2)
* 方形的特征输入(i′1=i′2=i′i1′=i2′=i′)
* 方形的卷积核尺寸(k′1=k′2=k′k1′=k2′=k′)
* 每个维度相同的步长(s′1=s′2=s′s1′=s2′=s′)
* 每个维度相同的padding (p′1=p′2=p′p1′=p2′=p′)
下图表示的是参数为(i′=2,k′=3,s′=1,p′=2i′=2,k′=3,s′=1,p′=2)的反卷积操作,其对应的卷积操作参数为 (i=4,k=3,s=
1,p=0i=4,k=3,s=1,p=0)。我们可以发现对应的卷积和非卷积操作其 (k=k′,s=s′k=k′,s=s′),但是反卷积却多了p′=2p′=2
。通过对比我们可以发现卷积层中左上角的输入只对左上角的输出有贡献,所以反卷积层会出现p′=k−p−1=2p′=k−p−1=2
。通过示意图,我们可以发现,反卷积层的输入输出在s=s′=1s=s′=1的情况下关系为:
o′=i′−k′+2p′+1=i′+(k−1)−2po′=i′−k′+2p′+1=i′+(k−1)−2p
Fractionally Strided Convolution
上面也提到过反卷积有时候也被叫做Fractionally Strided Convolution,翻译过来大概意思就是小数步长的卷积。对于步长 s>1s>1
的卷积,我们可能会想到其对应的反卷积步长s′<1s′<1。 如下图所示为一个参数为 i=5,k=3,s=2,p=1i=5,k=3,s=2,p=1
的卷积操作(就是第一张图所演示的)所对应的反卷积操作。对于反卷积操作的小数步长我们可以理解为:在其输入特征单元之间插入s−1s−1
个0,插入0后把其看出是新的特征输入,然后此时步长s′s′ 不再是小数而是为1。因此,结合上面所得到的结论,我们可以得出Fractionally
Strided Convolution的输入输出关系为:
o′=s(i′−1)+k−2po′=s(i′−1)+k−2p
更多关于卷积和反卷积的可视化理解:https://github.com/vdumoulin/conv_arithmetic
<https://github.com/vdumoulin/conv_arithmetic>

训练细节及实验

详见论文