内容简介:GAN 的为了从训练数据中学到生成数据的概率分布 $$ P_g $$ 。 GAN 定义了一个生成函数来拟合这个分布 $$ G(z; \theta_g)$$ 这就是 GAN 的 generator 这个可以是个全连接网络,或者 CNN 网络或者其他的。 其中 $$ z $$ 是一个固定的先验概率分布,比如从特定的正太分布中采样。 判别器的作用是输入一个 样本判断是生成器生成的还是来自训练数据的真实样本。把生成器定义为 $$ D(x) $$ 我们希望最终生成器能生成更接近真实的样本,判别器也有很好的判别能力。文
Generative Adversarial Nets 笔记 (一)
GAN 的 原始论文 给出了GAN 定义和一些简单的实现。
为了从训练数据中学到生成数据的概率分布 $$ P_g $$ 。 GAN 定义了一个生成函数来拟合这个分布 $$ G(z; \theta_g)$$ 这就是 GAN 的 generator 这个可以是个全连接网络,或者 CNN 网络或者其他的。 其中 $$ z $$ 是一个固定的先验概率分布,比如从特定的正太分布中采样。 判别器的作用是输入一个 样本判断是生成器生成的还是来自训练数据的真实样本。把生成器定义为 $$ D(x) $$ 我们希望最终生成器能生成更接近真实的样本,判别器也有很好的判别能力。文中定义了如下的判别器的优化函数
对于生成器最开始的时候的 loss 太小而导致梯度饱和作者的方式是最大化 $$ log(1-D(G(x))) $$
原文从理论的角度证明了这样得到的分布是全局最优的
一个手写数字生成的例子:
import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train),(x_test, y_test) = mnist.load_data() IMAGE_PIXELS = 28*28 NOISE_SIZE = 100 BATCH_SIZE = 100 def noise(n_rows, n_cols): return np.random.normal(size=(n_rows, n_cols)) def xavier_init(size): in_dim = size[0] if len(size) == 1 else size[1] stddev = 1. / np.sqrt(float(in_dim)) return tf.random_uniform(shape=size, minval=-stddev, maxval=stddev) def images_to_vectors(images): return images.reshape(images.shape[0], IMAGE_PIXELS) def vectors_to_images(vectors): return vectors.reshape(vectors.shape[0], 28, 28, 1) X = tf.placeholder(tf.float32, shape=(None, IMAGE_PIXELS)) # Layer 1 Variables D_W1 = tf.Variable(xavier_init([784, 1024])) D_B1 = tf.Variable(xavier_init([1024])) # Layer 2 Variables D_W2 = tf.Variable(xavier_init([1024, 512])) D_B2 = tf.Variable(xavier_init([512])) # Layer 3 Variables D_W3 = tf.Variable(xavier_init([512, 256])) D_B3 = tf.Variable(xavier_init([256])) # Out Layer Variables D_W4 = tf.Variable(xavier_init([256, 1])) D_B4 = tf.Variable(xavier_init([1])) # Store Variables in list D_var_list = [D_W1, D_B1, D_W2, D_B2, D_W3, D_B3, D_W4, D_B4] def discriminator(): l1 = tf.nn.dropout(tf.nn.leaky_relu(tf.matmul(x, D_W1) + D_B1, .2), .3) l2 = tf.nn.dropout(tf.nn.leaky_relu(tf.matmul(l1, D_W2) + D_B2, .2), .3) l3 = tf.nn.dropout(tf.nn.leaky_relu(tf.matmul(l2, D_W3) + D_B3, .2), .3) out = tf.matmul(l3, D_W4) + D_B4 return out Z = tf.placeholder(tf.float32, shape=(None, NOISE_SIZE)) # Layer 1 Variables G_W1 = tf.Variable(xavier_init([100, 256])) G_B1 = tf.Variable(xavier_init([256])) # Layer 2 Variables G_W2 = tf.Variable(xavier_init([256, 512])) G_B2 = tf.Variable(xavier_init([512])) # Layer 3 Variables G_W3 = tf.Variable(xavier_init([512, 1024])) G_B3 = tf.Variable(xavier_init([1024])) # Out Layer Variables G_W4 = tf.Variable(xavier_init([1024, 784])) G_B4 = tf.Variable(xavier_init([784])) G_var_list = [G_W1, G_B1, G_W2, G_B2, G_W3, G_B3, G_W4, G_B4] def generator(): l1 = tf.nn.leaky_relu(tf.matmul(z, G_W1) + G_B1, .2) l2 = tf.nn.leaky_relu(tf.matmul(l1, G_W2) + G_B2, .2) l3 = tf.nn.leaky_relu(tf.matmul(l2, G_W3) + G_B3, .2) out = tf.nn.tanh(tf.matmul(l3, G_W4) + G_B4) return out, var_list G_sample = generator(Z) D_real = discriminator(X) D_fake = discriminator(G_sample) # Losses D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_real, labels=tf.ones_like(D_real))) D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake, labels=tf.zeros_like(D_fake))) D_loss = D_loss_real + D_loss_fake G_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake, labels=tf.ones_like(D_fake))) # Optimizers D_opt = tf.train.AdamOptimizer(2e-4).minimize(D_loss, var_list=D_var_list) G_opt = tf.train.AdamOptimizer(2e-4).minimize(G_loss, var_list=G_var_list) num_test_samples = 16 test_noise = noise(num_test_samples, NOISE_SIZE) num_epochs = 200 # Start interactive session session = tf.InteractiveSession() # Init Variables tf.global_variables_initializer().run() for epoch in range(num_epochs): for n_batch, (batch,_) in enumerate(data_loader): # 1. Train Discriminator X_batch = images_to_vectors(batch.permute(0, 2, 3, 1).numpy()) feed_dict = {X: X_batch, Z: noise(BATCH_SIZE, NOISE_SIZE)} _, d_error, d_pred_real, d_pred_fake = session.run( [D_opt, D_loss, D_real, D_fake], feed_dict=feed_dict ) # 2. Train Generator feed_dict = {Z: noise(BATCH_SIZE, NOISE_SIZE)} _, g_error = session.run( [G_opt, G_loss], feed_dict=feed_dict ) if n_batch % 100 == 0: display.clear_output(True) # Generate images from test noise test_images = session.run( G_sample, feed_dict={Z: test_noise} ) test_images = vectors_to_images(test_images) # Log Images # Log Status
定义好模型和目标函数就可以用梯度更新的方式来训练模型。 看似还挺简单的和其他生成模型对比一下会发现我们不需要对数据的分布有任何的先验假设,比如 LDA 就是多项式分布的混合,而且对各个随机变量之间的关系也有很强的假设。
GAN 的特性很有意思,比如可以生成各种图像,语音文本之类的数据。我还是有几个问题记录下:
- 如何控制生成的类容,比如手写数字生成,生成过程中输入的是随机噪音,生成的内容就无法控制,如何生成指定的数字。
- GAN 模型的评价方法和其他在弱监督学习场景下的应用效果如何。
以上所述就是小编给大家介绍的《Generative Adversarial Nets 笔记 (一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 【每日笔记】【Go学习笔记】2019-01-04 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-02 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-07 Codis笔记
- vue笔记3,计算笔记
- Mysql Java 驱动代码阅读笔记及 JDBC 规范笔记
- 【每日笔记】【Go学习笔记】2019-01-16 go网络编程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深入浅出MFC (第二版)
侯俊杰 / 华中科技大学出版社 / 2001-1 / 80.00元
《深入浅出MFC》分为四大篇。第一篇提出学习MFC程序设计之前的必要基础,包括Widnows程序的基本观念以及C++的高阶议题。“学前基础”是相当主观的认定,但作者是甚于自己的学习经验以及教学经验,其挑选应该颇具说服力。第二篇介绍Visual C++整合环境开发工具。此篇只是提纲挈领,并不企图取代Visual C++使用手册;然而对于软件使用的老手,此篇或已足以帮助掌握Visual C++整合环境......一起来看看 《深入浅出MFC (第二版)》 这本书的介绍吧!