【GAN】Tensorflow版基础GAN代码解析
【GAN】Tensorflow版基础GAN代码解析
2018年写的,原来只是想记录一下各函数用法,没想到阅读量3000多。之前大学时候用的都还是tensorflow,现在已经是pytorch的天下了。
各详细的介绍看:https://www.cnblogs.com/lwp-nicol/p/14656331.html
initializer总结
1. tf.constant_initializer(value)
将变量初始化为给定的常量,初始化一切所提供的值。
2. tf.random_normal_initializer(mean,stddev)
功能是将变量初始化为满足正态分布的随机值,主要参数(正态分布的均值和标准差),用所给的均值和标准差初始化均匀分布。
3. tf.truncated_normal_initializer(mean,stddev,seed,dtype)
- mean: 用于指定均值
- stddev: 用于指定标准差
- seed: 用于指定随机数种子
- dtype: 用于指定随机数的数据类型
功能:将变量初始化为满足正态分布的随机值,但如果随机出来的值偏离平均值超过2个标准差,那么这个数将会被重新随机,通常只需要设定一个标准差stddev这一个参数就可以。
4. tf.random_uniform_initializer(a,b,seed,dtype)
从a到b均匀初始化,将变量初始化为满足平均分布的随机值,主要参数(最大值,最小值)
优化器构造
1. compute_gradients(loss,var_list=None,gate_gradients=GATE_OP,aggregation_method=None,colocate_gradients_with_ops=False,grad_loss=None)
作用:对于在变量列表(var_list)中的变量计算对于损失函数的梯度,这个函数返回一个(梯度,变量)对的列表,其中梯度就是相对应变量的梯度了。这是minimize()函数的第一个部分。
参数:
- loss: 待减小的值
- var_list: 默认是在GraphKey.TRAINABLE_VARIABLES
2. apply_gradients(grads_and_vars,global_step=None,name=None)
作用:把梯度"应用"(Apply)到变量上面去。其实就是按照梯度下降的方式加到上面去。这是minimize()函数的第二个步骤。返回一个应用的操作。
参数:
- grads_and_vars: compute_gradients()函数返回的(gradient, variable)对的列表
- global_step: Optional Variable to increment by one after the variables have been updated.
3. minimize(loss,global_step=None,var_list=None,gate_gradients=GATE_OP,aggregation_method=None,colocate_gradients_with_ops=False,name=None,grad_loss=None)
变量初始化
sess.run(tf.global_variables_initializer())
函数中调用了 variable_initializer()
和 global_variables()
global_variables()
返回一个 Variable list ,里面保存的是 global variables。variable_initializer()
将 Variable list 中的所有 Variable 取出来,将其 variable.initializer
属性做成一个 op group。然后看 Variable 类的源码可以发现,variable.initializer
就是一个 assign op。
所以: sess.run(tf.global_variables_initializer())
就是 run了所有global Variable 的 assign op,这就是初始化参数的本来面目。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import os
from tensorflow.examples.tutorials.mnist import input_data
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
sess = tf.InteractiveSession()
mb_size = 128
Z_dim = 100
mnist = input_data.read_data_sets('MNIST_data', one_hot=True) # mnist数据集,one_hot是为了让标签二元,即只有0和1
def weight_var(shape, name): # 定义权重,传入权重shape和name
return tf.get_variable(name=name, shape=shape, initializer=tf.contrib.layers.xavier_initializer())
def bias_var(shape, name): # 定义偏置,传入偏置shape和name
return tf.get_variable(name=name, shape=shape, initializer=tf.constant_initializer(0))
# Discriminator Net
X = tf.placeholder(tf.float32, shape=[None, 784], name='X') # 样本x的shape是[batchsize][784]
D_W1 = weight_var([784, 128], 'D_W1') # D的中间层的w1
D_b1 = bias_var([128], 'D_b1')
D_W2 = weight_var([128, 1], 'D_W2') # D的输出层的w2
D_b2 = bias_var([1], 'D_b2')
theta_D = [D_W1, D_W2, D_b1, D_b2] # D的参数列表
# Generator Net
Z = tf.placeholder(tf.float32, shape=[None, 100], name='Z') # 随机噪声向量z的shape是[batchsize][100]
G_W1 = weight_var([100, 128], 'G_W1') # G的中间层的w1
G_b1 = bias_var([128], 'G_B1')
G_W2 = weight_var([128, 784], 'G_W2') # G的输出层的w2
G_b2 = bias_var([784], 'G_B2')
theta_G = [G_W1, G_W2, G_b1, G_b2] # G的参数列表
def generator(z): # 定义G,传入随机噪声z,返回G的输出
G_h1 = tf.nn.relu(tf.matmul(z, G_W1) + G_b1) # G_h1中间层经过激活函数后的输出
G_log_prob = tf.matmul(G_h1, G_W2) + G_b2 # G输出层没有经过激活函数的输出
G_prob = tf.nn.sigmoid(G_log_prob) # G输出层经过激活函数后的输出
return G_prob
def discriminator(x): # 定义D,传入样本x,返回D的输出和没有经过激活函数的输出
D_h1 = tf.nn.relu(tf.matmul(x, D_W1) + D_b1) # D_h1中间层经过激活函数后的输出
D_logit = tf.matmul(D_h1, D_W2) + D_b2 # D输出层没有经过激活函数的输出
D_prob = tf.nn.sigmoid(D_logit) # D输出层经过激活函数后的输出
return D_prob, D_logit
G_sample = generator(Z) # 调用generator(z)生成G样本
D_real, D_logit_real = discriminator(X) # discriminator(x)辨别样