GANs和Diffusion模型(2)

GANs和Diffusion模型(1)

使用CNN构建GAN

CNN是一种稀疏(sparse)神经网络,它可以捕捉一些位置不变的空间特征,因而非常广泛地应用于图像识别和处理中。

转置卷积层

有三种卷积层:

  • 标准卷积层(Standard Convolutional Layer)
  • 反卷积层(Deconvolutional Layer)
  • 转置卷积层(Transposed Convolutional Layer)

反卷积(Deconvolution):执行和标准卷积层相反的动作。使用一个feature map作为输入,产生原始输入。关于反卷积操作的详解可以参考这篇博文:卷积核二三事_跨步卷积和非跨步卷积-CSDN博客,不过里面的deconvolution并非博文所说的转置卷积,而是反卷积(或者叫逆卷积也可以),并且文中还有一个小问题:严格来说,并非“转置矩阵×输出图像=输入图像”,而是“逆矩阵×输出图像=输入图像”,除非卷积核展开后的矩阵的逆矩阵就是其转置矩阵。

转置卷积(Transposed Convolution):执行对输入数据进行上采样(upsampling)的层,即产生比输入的feature map具有更高的空间维度的feature map。

上图中,

  • 左侧绿色的部分代表输入的feature map;橙色部分代表卷积核。
  • 和普通的卷积操作相比,卷积核要做180度旋转(以中心为原点旋转),详见抽丝剥茧,带你理解转置卷积(反卷积)_抽丝剥茧带你理解转置卷积-CSDN博客
  • 参数s,p仍然被称为stride(卷积核的移动步长)和padding(零填充),但和标准卷积层中的s和p的含义并不相同。
  • "Calulcate"下面的参数含义为:
    • z:原始feature map的行、列之间添加的0,如第3张图中的紫色部分。图中行、列各添加了一排0,因此z = 1,从而反推出s = 2。
    • p':输入的feature map外围填充的0。这个和标准卷积层中的p含义相同。第4张图中在输入的feature map外围填充的一排0,因此p' = 1,可以反推出p  = 1,因为k = 3。
    • s':和标准卷积层中的s含义相同。这个参数的值永远为1。如第5张图所示
  • 第6张图给出了转置卷积运算之后产生的新的feature map

对于转置卷积层,输出feature map的尺寸的公式如下:o = (i - 1) * s + k - 2p

注意:关于转置卷积操作,还有另一种理解方式,详见What is Transposed Convolutional Layer? - GeeksforGeeks

深度卷积GANs

Deep Convolutional GANs (DCGANs),类似于普通GANs,但是其中每一个对抗都是一个具有一定结构限制的CNN。这些限制会帮助这组对抗网络学习到所需表达的结构,从而可以生成更好的图片。

DCGANs:

  • 和普通的GANs一样,也有生成器(generator)和鉴别器(discriminator)
  • 使用不同的神经网络——结构上受约束的(architecturally constrained)CNN
  • 第一次发表在2016年的文献上:https://arxiv.org/pdf/1511.06434.pdf(下面简称为DCGAN文献

DCGANs的结构(前面文献中的)

  • 跨步卷积(strided convolution)层替代汇聚层
  • 对生成器和鉴别器使用批规范化(batch normalization)
  • 删除了全连接隐藏层
  • 生成器激活函数使用ReLu+Tanh
  • 鉴别器激活函数使用LeakyReLU

跨步卷积(strided convolution)

文献作者发现汇聚层会有损模型的收敛,而当使用了跨步卷积后,该层使用转置卷积操作对输入进行上采样,可以提高性能。这里需要说明的是,实际上DCGAN文献中对生成器的跨步卷积称为fractionally-strided convolution(小跨步地卷积),这个在后来就被称为转置卷积。

批规范化(batch normalization)

批规范化层同样可以帮助模型收敛,该操作会对每一层的输出重新中心化,使得输出均值为0且具有单位方差。这会极大地减轻由于缺乏初始化而导致的问题。批规范化也有助于减轻梯度消失(vanishing gradient)问题,从而允许在更深的层中进行梯度传播。批规范化也有助于防止GANs模型坍塌,使得GANs可以产生更多样化的输出。除了生成器的输出层、和鉴别器的输入层之外,批规范化应用于深度卷积GAN模型的所有层。

关于批规范化的详解,可以参考这篇博文:BatchNormalization总结_batchnormalization参数-CSDN博客

DCGAN生成器结构

DCGAN生成器最终生成一个上采样。

DCGAN鉴别器结构

DCGAN鉴别器结构最终输出一个鉴别结果:图片为真的概率

程序示例

下面针对GANs和Diffusion模型(1)中的fashion MNIST图片集的问题,我们改为使用DCGAN模型。大部分代码是差不多了,我们这里只展示不同的部分。

读取数据

增加了BatchNormalization, Conv2DTranspose, Conv2D这3个层

import os
import time
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

from tqdm import tqdm
from keras import layers, Sequential
from keras.layers import Dense, BatchNormalization, ReLU, Reshape, Conv2DTranspose, Conv2D, Input, Flatten, LeakyReLU, Dropout
from keras.datasets import fashion_mnist

batch size选择了32

buffer_size = 600000
batch_size = 32

定义生成器

可以看出,生成器的神经网络中,我们使用了转置卷积和批规范化。

def generator_model():
  model = Sequential()
  model.add(Dense(7 * 7 * 256, input_shape = (100, )))
  model.add(BatchNormalization())
  model.add(ReLU())
  #Reshape to 4 dimensions: batches first, then followed by (7, 7, 256)
  model.add(Reshape((7, 7, 256)))

  #Transposed convolutional layer which performs upsampling
  model.add(Conv2DTranspose(128, (5,5), strides=(1,1), padding='same'))
  model.add(BatchNormalization())
  model.add(ReLU())

  model.add(Conv2DTranspose(64, (5,5), strides=(2,2), padding='same'))
  model.add(BatchNormalization())
  model.add(ReLU())

  #Output layer
  #As each centered & scaled value is from -1 to 1, we choose 'tanh'
  model.add(Conv2DTranspose(1, (5,5), strides=(2,2), padding='same', activation='tanh'))

  return model

generator = generator_model()
generator.summary()

模型summary如下,

模型参数是这样计算的:

  • 第一个全连接层Dense:输入100x1向量,输出7*7*256=12544个结点,因此有参数:100*12544+12544 = 1266944个
  • 接下来的BatchNormalization:对于当前层的每一个结点,batch normalization有4个参数,因此有:12544 * 4 = 50176。具体细节可以查看前面在批规范化(batch normalization)中给出的参考博文
  • 单纯的激活函数和调整数据形状(reshape)当然不需要任何参数,所以是0
  • 转置卷积层Conv2DTranspose:由于在输入该层之前,数据被reshape为256个7x7矩阵,因此可以看成256个结点,每个结点有一个7x7矩阵,用于接下来的转置卷积操作;而卷积核是5x5的(共25个参数),当前层定义了128个结点,因此参数个数为:256*128*25 + 128(偏好) = 819328
  • 接下来的接下来的BatchNormalization,按照前面的规则:结点数x4,得出参数个数为:128*4 = 512

后面几层的参数个数计算方式和上面一样,读者可以自行验算。

定义鉴别器

def descriminator_model():
  model = Sequential()

  model.add(Conv2D(64, (5,5), strides=(2,2), padding='same',
                   input_shape=[28, 28, 1]))
  model.add(BatchNormalization())
  model.add(LeakyReLU(0.2))
  model.add(Dropout(0.3))

  model.add(Conv2D(128, (5,5), strides=(2,2), padding='same'))
  model.add(BatchNormalization())
  model.add(LeakyReLU(0.2))
  model.add(Dropout(0.3))

  model.add(Flatten())
  #Output layer, output is a signal score
  model.add(Dense(1, activation='sigmoid'))
  return model

discriminator = descriminator_model()
discriminator.summary()

模型summary如下:

同样,有兴趣的读者可以按照前面介绍的方法,自行验算参数个数。普通卷积和转置卷积的参数个数是一样的。通过计算参数个数,可以更好地理解模型的结构。

模型验证

定义损失函数,训练的过程都和(1)中的普通GAN模型一样。通过训练我们发现DCGAN模型的性能明显要好一些。

例如,第1期和第50期的训练结果如下。可以看到,第1期的训练结果就已经不是纯噪声了,第50期中fake score已经达到了50%的理想情况(鉴别器对生成器产生的图片的鉴别结果已经相当于抛硬币的50%概率了)。

再看曲线图。可以看到,随着训练的进行,生成器的loss明显下降,鉴别器loss明显上升,并且生成器的loss已经小于鉴别器loss了。从得分来看,real score和fake score都在向0.5靠拢,这个结果也可以认为是收敛的,不像(1)中的普通GAN模型,这两个曲线之间始终有一块空白,无法收敛。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值