Generative Adversarial Nets 笔记 (一)

栏目: 数据库 · 发布时间: 5年前

内容简介: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) $$ 我们希望最终生成器能生成更接近真实的样本,判别器也有很好的判别能力。文中定义了如下的判别器的优化函数 Generative Adversarial Nets 笔记 (一)

对于生成器最开始的时候的 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 的特性很有意思,比如可以生成各种图像,语音文本之类的数据。我还是有几个问题记录下:

  1. 如何控制生成的类容,比如手写数字生成,生成过程中输入的是随机噪音,生成的内容就无法控制,如何生成指定的数字。
  2. GAN 模型的评价方法和其他在弱监督学习场景下的应用效果如何。

以上所述就是小编给大家介绍的《Generative Adversarial Nets 笔记 (一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出MFC (第二版)

深入浅出MFC (第二版)

侯俊杰 / 华中科技大学出版社 / 2001-1 / 80.00元

《深入浅出MFC》分为四大篇。第一篇提出学习MFC程序设计之前的必要基础,包括Widnows程序的基本观念以及C++的高阶议题。“学前基础”是相当主观的认定,但作者是甚于自己的学习经验以及教学经验,其挑选应该颇具说服力。第二篇介绍Visual C++整合环境开发工具。此篇只是提纲挈领,并不企图取代Visual C++使用手册;然而对于软件使用的老手,此篇或已足以帮助掌握Visual C++整合环境......一起来看看 《深入浅出MFC (第二版)》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具