最近是一段特殊时期,因为发热,虽然未到过疫区或接触过疑似患者,但仍被要求在家隔离,本人非计算机专业,业余爱好编程,最感兴趣的是深度神经网络,天天看大佬们发各种博文或帖子,一直再学习,刚好利用在家隔离的时间,看了一些东西,也算略有所得,计算机专业飘过即可,和我一样的爱好者可以看看。
关于DCGAN的原理不再赘述,优快云里有太多博文,直接上自己的代码,当然参考了不少网友的博文,最初是学习应用GAN生成MNIST,后来继续学习DCGAN生成MNIST和cifar10,后来在网上找到别人发的man 和woman的图片集(cycleGAN的素材,暂时还没开始学,下一步就是它了),原图是256×256的,因为笔记本显卡的限制,跑不了这么大的图片,把它转为64×64的,batch size为8,设的很小,我的机器居然能跑起来,没有报显卡内存不足。训练了2个半小时,先看代码,里面有详细的注释,和我一样的新人可以参考一下,同时感谢优快云里的网友们发的文章。很多都是参考别人的,关于生成器和鉴别器的代码,我是参考别人的依葫芦画瓢弄得。
import tensorflow as tf
import numpy as np
import PIL.Image as Image
import os
import time
import matplotlib.pyplot as plt
LOG_PATH = 'dcgan_64'
SAMPLE_PATH = LOG_PATH + os.sep + 'sample'
# 噪声数据的大小,100
NOISE_SIZE = 100
# 每一个batch值
BATCH_SIZE = 8
# 真实图片尺寸
REAL_SHAPE = [-1, 64, 64, 3]
# ADAM参数
BETA1 = 0.5
BETA2 = 0.9
# 平滑参数
SMOOTH = 0.1
# 每次迭代判别器训练
CRITIC_NUM = 5
# 生成图片的维度
OUTPUT_DIM = 3
# 迭代的epoch值
EPOCHES = 30000
# 用于展示的图片,每行及每列个数,10*10=100
NUM_SHOW_SAMPLE = 10
# 学习率
LEARNING_RATE = 2e-4
# 构造输入样本的数据,real_size 和 noise_size, 生成初始化的real_image 和 noise_image
def get_inputs():
# 真实样本输入
inputs_real = tf.placeholder(tf.float32, [None, REAL_SHAPE[1], REAL_SHAPE[2], REAL_SHAPE[3]], name='inputs_real')
# 噪音数据的维度为[None , 100]
inputs_noise = tf.placeholder(tf.float32, [None, NOISE_SIZE], name='inouts_noise')
return inputs_real, inputs_noise
# 构造generator网络,将[None, 100]的噪音数据, 生成[None, 64, 64, 3]的图片数据
def get_generator(noise_img, output_dim, is_train=True):
"""
:param noise_img: 噪声信号,tensor类型
:param output_dim: 生成图片的通道数
:param is_train: 是否为训练状态,该参数主要用于作为batch_normalization方法中的参数使用(训练时候开启)
"""
# 训练时生成器不允许复用
with tf.variable_scope("generator", reuse=(not is_train)):
# 100 -> 8*8*128 - > [8, 8, 128]
# 进行全连接操作,将100的数据通过全连接,转换为[None ,8*8*128]
layer1 = tf.layers.dense(noise_img, 8 * 8 * 128, activation='relu')
# 进行维度变化,将其转换为[-1, 8, 8, 128]
layer1 = tf.reshape(layer1, [-1, 8, 8, 128])
# print('noise_img: ', np.shape(noise_img))
# print('layer1: ', np.shape(layer1))
# [8, 8, 128] -> [16, 16, 128] -> BN -> relu
# 进行反卷积操作, [8, 8, 128] -> [16, 16, 128]
layer2 = tf.layers.conv2d_transpose(layer1, 128, 3, 2, padding='same',
kernel_initializer=tf.random_normal_initializer(0, 0.02),
bias_initializer=tf.random_normal_initializer(0, 0.02))
# 进行归一化操作
layer2 = tf.layers.batch_normalization(layer2, momentum=0.8, training=is_train)
layer2 = tf.nn.relu(layer2)
# print('layer2: ', np.shape(layer2))
# [16, 16, 128] -> [32, 32, 64] -> BN -> relu
# 进行反卷积操作,stride=2,维度扩大为原来的2倍
layer3 = tf.layers.conv2d_transpose(layer2, 64, 3, 2, padding='same',
kernel_initializer=tf.random_normal_initializer(0, 0.02),
bias_initializer=tf.random_normal_initializer(0