GAN的目的
简而言之,在GAN中同时存在生成网络和判别网络两个神经网络,生成网络用于生成可以以假乱真新的数据,而判别网络用于判断所给的数据是否是真的数据。
而在GAN中,生成网络的目的是让判别网络认为其生成的数据是真实的,而判别网络则相当于警察,目的是尽最大可能鉴别出生成网络生成的数据来。
以此两个网络相互“打架”,最终两方的实力在斗争中都得到了显著的提升
斗争到最后,生成网络已经是一个老司机了,生成的数据足以骗过一下简单的判别网络,让人信以为真。
GAN的出世,可以说是给深度学习领域带来了新的生命力,赋予了创造数据的能力
预先的训练
在一开始如果采用随机的值作为判别网络D的参数,会使得生成网络G随意生成的一个数据(哪怕是很差的一个数据)逃过判别网络D的法眼
故为了使得条件更加苛刻,最终生成出来的效果好一点,则要把判别网络D做的更加强悍一些.
网络都有w b初始权重,因此为了实现该目的,我们可以对判别网络进行预先的训练
即让判别网络D先进行判断,让他知道哪些数据是0,哪些数据是1
定义一个model
1 2 3 4 5 6 7 |
model = GAN( DataDistribution(), #真实数据的分布 GeneratorDistribution(range=8), #随机初始化分布 args.num_steps, #迭代次数 args.batch_size, #迭代的batch args.log_every, #隔多少次打印信息 ) |
1 2 3 4 5 6 7 8 9 |
class DataDistribution(object): #真实数据分布(蓝色的线) def __init__(self): self.mu = 4 #均值 self.sigma = 0.5 #标准差 def sample(self, N): samples = np.random.normal(self.mu, self.sigma, N) samples.sort() return samples |
1 2 3 4 5 6 7 |
class GeneratorDistribution(object): #随机初始化分布 def __init__(self, range): self.range = range #随机初始化分布 def sample(self, N): return np.linspace(-self.range, self.range, N) + \ np.random.random(N) * 0.01 |
构造模型
1 2 3 4 5 6 7 8 9 10 11 12 |
class GAN(object): def __init__(self, data, gen, num_steps, batch_size, log_every): self.data = data self.gen = gen self.num_steps = num_steps self.batch_size = batch_size self.log_every = log_every self.mlp_hidden_size = 4 #神经网络隐层神经元数 self.learning_rate = 0.03 #神经网络学习率 self._create_model() |
构造预先判别网络模型
用placeholder
构造骨架,到用的时候再赋值进去即可
1 2 3 4 5 6 7 8 9 |
def _create_model(self): with tf.variable_scope('D_pre'): #tf的域 self.pre_input = tf.placeholder(tf.float32, shape=(self.batch_size, 1)) #12代表一个batch12个,一起训练,1表示一维的点 self.pre_labels = tf.placeholder(tf.float32, shape=(self.batch_size, 1)) #y值 <span style="color: #ff0000;">D_pre = discriminator(self.pre_input, self.mlp_hidden_size) #初始化网络D的构架</span> self.pre_loss = tf.reduce_mean(tf.square(D_pre - self.pre_labels)) #预测值和真实值差异 reduce_mean取平均值 self.pre_opt = optimizer(self.pre_loss, None, self.learning_rate) #定义优化器进行求解 |
网络初始化
1 2 3 4 5 6 7 |
def discriminator(input, h_dim): #h_dim输入网路的层数 input输入的数据 h0 = tf.tanh(linear(input, h_dim * 2, 'd0')) #输入要判别的,第一层输出 h1 = tf.tanh(linear(h0, h_dim * 2, 'd1')) #h0 12*8 第二层输出值 h2 = tf.tanh(linear(h1, h_dim * 2, scope='d2')) h3 = tf.sigmoid(linear(h2, 1, scope='d3')) #最终输出值 return h3 |
权值初始化
1 2 3 4 5 6 7 |
def linear(input, output_dim, scope=None, stddev=1.0): # 输入 输出 norm = tf.random_normal_initializer(stddev=stddev) #w随机高斯初始化 const = tf.constant_initializer(0.0) #b初始化 为0 with tf.variable_scope(scope or 'linear'): w = tf.get_variable('w', [input.get_shape()[1], output_dim], initializer=norm) #1*8 b = tf.get_variable('b', [output_dim], initializer=const) return tf.matmul(input, w) + b |
优化器求解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def optimizer(loss, var_list, initial_learning_rate): decay = 0.95 #学习率不断衰减的优化器 num_decay_steps = 150 #每迭代150次,衰减一次 batch = tf.Variable(0) learning_rate = tf.train.exponential_decay( #学习率衰减的方式 指数衰减法 initial_learning_rate, batch, num_decay_steps, decay, staircase=True ) optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize( #梯度下降求解器 loss, global_step=batch, var_list=var_list ) return optimizer |
用了梯度下降,去最小化loss。并返回最后的求解器
总结
整个步骤可以总结如下
- 完成预先判别网络D_pre的构架
- 判别网络预测值与真实值求差,求解loss
- 定义优化器进行求解
- 优化完成后得到wb,去初始化真正的判别网络D