小白的GAN网络学习(二)- DCGAN

小白的GAN网络学习(二)- DCGAN

什么是DCGAN

DCGAN就是将CNN和原始的GAN结合到了一起,生成模型和判别模型都运用了深度卷积神经网络的生成对抗网络

DCGAN的设计技巧
  • 1.取消所有的Pooling层,G网络中使用转置卷积(Transposed convolutional layer)进行上采样,D网络中加入stride的卷积代替Pooling
  • 2.去掉FC层,使网络变为全卷积网络
  • 3.G网络中使用ReLU作为激活函数,最后一层使用tanh
  • 4.D网络中使用LeakyReLU作为激活函数
  • 5.在Generator和Discriminator上都使用BatchNormalization
    • 解决初始化差的问题
    • 帮助梯度传播到每一层
    • 防止Generator把所有的样本都收敛到同一个点
    • 直接将BN应用到所有层会导致样本震荡和模型不稳定,通过在Generator输出层和Discriminator输入层不采用BN层可以防止这种现象
  • 6.使用Adam优化器(beta1(一阶矩估计的指数衰减率)的值设置为0.5)
  • 7.论文参数:LeakyReLU斜率为0.2,lr=2e-4,batch_size=128
  • 8.小Tips:
    • 在Generator中,可以在第一层就添加BN层,同时第一层的strides=(1,1),最后一层不加BN层,同时使用tanh作为激活函数
    • 在Discriminator中,第一层不添加BN层,可以在每层添加Dropout层,这样做会降低Discriminator的学习速度,使结果更优
基于mnist数据集的DCGAN的TF代码
import tensorflow as tf
from tensorflow import keras 
from tensorflow.keras import layers
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

# 处理数据
(images,labels),(_,_)=keras.datasets.mnist.load_data()
images=np.expand_dims(images,-1)
images=images/127.5 -1
images=images.astype('float32')

BATCH_SIZE=128
BUFFER_SIZE=60000

dataset=tf.data.Dataset.from_tensor_slices(images)
dataset=dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

# 定义生成器
def generate_model():
    model=keras.Sequential()
    model.add(layers.Dense(7*7*256,input_shape=(100,),use_biase=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    model.add(layers.Reshape((7,7,256)))
    
    # 第一层转置卷积的strides=(1,1),也就是说没有改变图形大小,经过该层的图像大小为7*7*128
    model.add(layers.Conv2DTranspose(128,(3,3),strides=(1,1),padding='same',use_biase=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    # 经过该层后图像大小为14*14*64
    model.add(layers.Conv2DTranspose(64,(3,3),strides=(2,2),padding='same',use_bias=False))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())
    
    # 经过该层后图像大小为28*28*1
    model.add(layers.Conv2DTranspose(1,(3,3),strides=(2,2),padding='same',use_bias=False))
    return model
#----------------------------------------------------------------------
# 定义判别器
def discriminate_model():
    model=keras.Sequential()
    model.add(layers.Conv2D(64,(3,3),input_shape=(28,28,1),strides=(2,2),padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    
    model.add(layers.Conv2D(128,(3,3),strides=(2,2),padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))
    
    model.add(layers.Conv2D(256,(3,3),strides=(2,2),padding='same'))
    model.add(layers.LeakyReLU())
    
    model.add(layers.Flatten())
    return model
#--------------------------------------------------------------------
# 生成对象
generator=generate_model()
discriminator=discriminate_model()

# 定义损失函数
cross_entropy=keras.losses.BinaryCrossentropy(from_logits=True)

def gen_loss(fake_out):
    return cross_entropy(tf.ones_like(fake_out),fake_out)

def disc_loss(real_out,fake_out):
    real_loss=cross_entropy(tf.ones_like(real_out),real_out)
    fake_loss=cross_entropy(tf.zeros_like(fake_out),fake_out)
    total_loss=real_loss+fake_loss
    return total_loss
#---------------------------------------------------------------------
# 定义优化器
gen_optimizer=keras.optimizers.Adam(2e-4)
disc_optimizer=keras.optimizers.Adam(2e-4)
#---------------------------------------------------------------------
# 自定义训练函数
EPOCHS=100
noise_dim=100
num_exp_to_generate=16
seed=tf.random.normal([num_exp_to_generate,noise_dim])

def train_step(images):
    noise=tf.random.normal([BATCH_SIZE,noise_dim])
    with tf.GradientTape() as gen_tape,tf.GradientTape() as disc_tape:
        real_out=discriminator(images,training=True)
        gen_image=generator(noise,training=True)
        fake_out=discriminator(gen_image,training=True)
        
        generate_loss=gen_loss(fake_out)
        discriminate_loss=disc_loss(real_out,fake_out)
        
    gradient_gen=gen_tape.gradient(generate_loss,generator.trainable_variables)
    gradient_disc=disc_tape.gradient(discriminate_loss,discriminator.trainalbe_varialbes)
    gen_opt.apply_gradient(zip(gradient_gen,generator.trainable_varialbes))
    disc_opt.apple_gradient(zip(gradient_disc,discriminator.trainable_variables))
#-------------------------------------------------------------------
# 自定义绘图函数
def generate_plot_image(gen_model,test_noise):
    pre_image=gen_model(test_noise,training=False)
    fig=plt.figure(figsize=(4,4))
    for i in range(pre_image.shape[0]):
        plt.subplot(4,4,i+1)
        plt.imshow((pre_image[i,:,:]+1)/2,cmap='gray')
        plt.axis('off')
    plt.show()
#------------------------------------------------------------------
# 启动函数
def train(dataset,epochs):
    for epoch in range(epochs):
        for image_batch in dataset:
            train_step(image_batch)
        generate_plot_image(generator,seed)

train(dataset,EPOCHS)        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值