2022-02-16
在/home///DCGAN/下新建一个文件utils.py,输入如下代码:
import scipy.misc import numpy as np # 保存图片函数 def save_images(images, size, path): """ Save the samples images The best size number is int(max(sqrt(image.shape[0]),sqrt(image.shape[1]))) + 1 example: The batch_size is 64, then the size is recommended [8, 8] The batch_size is 32, then the size is recommended [6, 6] """ # 图片归一化,主要用于生成器输出是 tanh 形式的归一化 img = (images + 1.0) / 2.0 h, w = img.shape[1], img.shape[2] # 产生一个大画布,用来保存生成的 batch_size 个图像 merge_img = np.zeros((h * size[0], w * size[1], 3)) # 循环使得画布特定地方值为某一幅图像的值 for idx, image in enumerate(images): i = idx % size[1] j = idx // size[1] merge_img[j*h:j*h+h, i*w:i*w+w, :] = image # 保存画布 return scipy.misc.imsave(path, merge_img)
该函数的作用是保存训练过程中采样产生的图像。
在/home///DCGAN/下新建文件model.py,定义训练时的生成器、判别器和采样网络,在model.py中输入如下代码:
import tensorflow as tf from ops import * BATCH_SIZE = 64 # 定义生成器 def generator(z, y, train = True): # y 是一个 [BATCH_SIZE, 10] 维的向量,把 y 转成四维张量 yb = tf.reshape(y, [BATCH_SIZE, 1, 1, 10], name = 'yb') # 把 y 作为约束条件和 z 拼接起来 z = tf.concat(1, [z, y], name = 'z_concat_y') # 经过一个全连接,BN 和激活层 ReLu h1 = tf.nn.relu(batch_norm_layer(fully_connected(z, 1024, 'g_fully_connected1'), is_train = train, name = 'g_bn1')) # 把约束条件和上一层拼接起来 h1 = tf.concat(1, [h1, y], name = 'active1_concat_y') h2 = tf.nn.relu(batch_norm_layer(fully_connected(h1, 128 * 49, 'g_fully_connected2'), is_train = train, name = 'g_bn2')) h2 = tf.reshape(h2, [64, 7, 7, 128], name = 'h2_reshape') # 把约束条件和上一层拼接起来 h2 = conv_cond_concat(h2, yb, name = 'active2_concat_y') h3 = tf.nn.relu(batch_norm_layer(deconv2d(h2, [64,14,14,128], name = 'g_deconv2d3'), is_train = train, name = 'g_bn3')) h3 = conv_cond_concat(h3, yb, name = 'active3_concat_y') # 经过一个 sigmoid 函数把值归一化为 0~1 之间, h4 = tf.nn.sigmoid(deconv2d(h3, [64, 28, 28, 1], name = 'g_deconv2d4'), name = 'generate_image') return h4 # 定义判别器 def discriminator(image, y, reuse = False): # 因为真实数据和生成数据都要经过判别器,所以需要指定 reuse 是否可用 if reuse: tf.get_variable_scope().reuse_variables() # 同生成器一样,判别器也需要把约束条件串联进来 yb = tf.reshape(y, [BATCH_SIZE, 1, 1, 10], name = 'yb') x = conv_cond_concat(image, yb, name = 'image_concat_y') # 卷积,激活,串联条件。 h1 = lrelu(conv2d(x, 11, name = 'd_conv2d1'), name = 'lrelu1') h1 = conv_cond_concat(h1, yb, name = 'h1_concat_yb') h2 = lrelu(batch_norm_layer(conv2d(h1, 74, name = 'd_conv2d2'), name = 'd_bn2'), name = 'lrelu2') h2 = tf.reshape(h2, [BATCH_SIZE, -1], name = 'reshape_lrelu2_to_2d') h2 = tf.concat(1, [h2, y], name = 'lrelu2_concat_y') h3 = lrelu(batch_norm_layer(fully_connected(h2, 1024, name = 'd_fully_connected3'), name = 'd_bn3'), name = 'lrelu3') h3 = tf.concat(1,[h3, y], name = 'lrelu3_concat_y') # 全连接层,输出以为 loss 值 h4 = fully_connected(h3, 1, name = 'd_result_withouts_sigmoid') return tf.nn.sigmoid(h4, name = 'discriminator_result_with_sigmoid'), h4 # 定义训练过程中的采样函数 def sampler(z, y, train = True): tf.get_variable_scope().reuse_variables() return generator(z, y, train = train)
可以看到,生成器的大小从 7×7 变为 14×14 再变为 28×28。每一层都添加了约束 y,完美诠释了论文中给出的网络。之所以加参数,是因为层中训练和测试的过程不同。该参数用于区分训练和测试。生成器的最后一层使用函数将值归一化在0和1之间。如果不加约束网络使用tanh函数,所以函数中使用语句:img = ( + 1.< @0) / 2.0。
该函数的作用是在训练过程中对生成器生成的图像进行采样,因此该函数必须指定可复用。重用说明见: 。
参考:
1.
分类:
技术要点:
相关文章:
© 版权声明
本站下载的源码均来自公开网络收集转发二次开发而来,
若侵犯了您的合法权益,请来信通知我们1413333033@qq.com,
我们会及时删除,给您带来的不便,我们深表歉意。
下载用户仅供学习交流,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担,访问及下载者下载默认同意本站声明的免责申明,请合理使用切勿商用。
THE END
暂无评论内容