王牌娱乐_王牌娱乐详解如何使用Keras实现Wassertein GAN

中国围棋网2017年10月11日 04时10分42秒
62

原标题:教程 | 详解如何使用Keras实现Wassertein GAN

选自Deeply Random

机器之心编译

参与:晏奇、李泽南

在阅读论文 Wassertein GAN 时,作者发现理解它最好的办法就是用代码来实现其内容。于是在本文中,作者将用自己的在 Keras 上的代码来向大家简要介绍一下WGAN。

何为 GAN?

GAN,亦称为生成对抗网络(Generative Adversarial Network),它是生成模型中的一类——即一种能够通过观察来自特定分布的训练数据,进而尝试对这个分布进行预测的模型。这个模型新获取的样本「看起来」会和最初的训练样本类似。有些生成模型只会去学习训练数据分布的参数,有一些模型则只能从训练数据分布中提取样本,而有一些则可以二者兼顾。

目前,已经存在了很多种类的生成模型:全可见信念网络(Fully Visible Belief Network)、变分自编码器(Variational Autoencoder)、玻尔兹曼机(Boltzmann Machine),生成随机网络(Generative Stochastic Network),像素循环神经网络(PixelRNN)等等。以上的模型都因其所表征或接近的训练数据密度而有所区别。一些模型会去精细的表征训练数据,另一些则会以某种方式去和训练数据进行互动——比如说生成模型。GAN 就是这里所说的后者。大部分生成模型的学习原则都可被概括为「最大化相似度预测」——即让模型的参数能够尽可能地与训练数据相似。

GAN 的工作方式可以看成一个由两部分构成的游戏:生成器(Generator/G)和判别器(Discriminator/D)(一般而言,这两者都由神经网络构成)。生成器随机将一个噪声作为自己的输入,然后尝试去生成一个样本,目的是让判别器无法判断这个样本是来自训练数据还是来自生成器的。在判别器这里,我们让它以监督学习方式来工作,具体而言就是让它观察真实样本和生成器生成的样本,并且同时用标签告诉它这些样本分别来自哪里。在某种意义上,判别器可以代替固定的损失函数,并且尝试学习与训练数据分布相关的模式。

何为 Wasserstein GAN?

就其本质而言,任何生成模型的目标都是让模型(习得地)的分布与真实数据之间的差异达到最小。然而,传统 GAN 中的判别器 D 并不会当模型与真实的分布重叠度不够时去提供足够的信息来估计这个差异度——这导致生成器得不到一个强有力的反馈信息(特别是在训练之初),此外生成器的稳定性也普遍不足。

Wasserstein GAN 在原来的基础之上添加了一些新的方法,让判别器 D 去拟合模型与真实分布之间的 Wasserstein 距离。Wassersterin 距离会大致估计出「调整一个分布去匹配另一个分布还需要多少工作」。此外,其定义的方式十分值得注意,它甚至可以适用于非重叠的分布。

为了让判别器 D 可以有效地拟合 Wasserstein 距离:

K.mean(y_true * y_pred)


以 keras 这段损失函数为例:

  • 这里采用 mean 来适应不同的批大小以及乘积。

  • 预测的值通过乘上 element(可使用的真值)来最大化输出结果(优化器通常会将损失函数的值最小化)。

  • 论文作者表示,与 vanlillaGAN 相比,WGAN 有一下优点:

  • 有意义的损失指标。判别器 D 的损失可以与生成样本(这些样本使得可以更少地监控训练过程)的质量很好地关联起来。

  • 稳定性得到改进。当判别器 D 的训练达到了最佳,它便可以为生成器 G 的训练提供一个有用的损失。这意味着,对判别器 D 和生成器 G 的训练不必在样本数量上保持平衡(相反,在 Vanilla GAN 方法中而这是平衡的)。此外,作者也表示,在实验中,他们的 WGAN 模型没有发生过一次崩溃的情况。

  • 开始编程!

    我们会在 Keras 上实现 ACGAN 的 Wasserstein variety。在 ACGAN 这种生成对抗网络中,其判别器 D 不仅可以预测样本的真实与否,同时还可以将其进行归类。

    下方代码附有部分解释。

    [1] 导入库文件:


    import os

    import matplotlib.pyplot as plt
    %matplotlib inline
    %config InlineBackend.figure_format = 'retina' # enable hi-res output

    import numpy as np
    import tensorflow as tf

    import keras.backend as K
    from keras.datasets import mnist
    from keras.layers import *
    from keras.models import *
    from keras.optimizers import *
    from keras.initializers import *
    from keras.callbacks import *
    from keras.utils.generic_utils import Progbar


    [2].Runtime 配置


    # random seed
    RND = 777

    # output settings
    RUN = 'B'
    OUT_DIR = 'out/' + RUN
    TENSORBOARD_DIR = '/tensorboard/wgans/' + RUN
    SAVE_SAMPLE_IMAGES = False

    # GPU # to run on
    GPU = "0"

    BATCH_SIZE = 100
    ITERATIONS = 20000

    # size of the random vector used to initialize G
    Z_SIZE = 100


    [3]生成器 G 每进行一次迭代,判别器 D 都需要进行 D_ITERS 次迭代。

  • 由于在 WGAN 中让判别器质量能够优化这件事更加重要,所以判别器 D 与生成器 G 在训练次数上呈非对称比例。

  • 在论文的 v2 版本中,判别器 D 在生成器 G 每 1000 次迭代的前 25 次都会训练 100 次,此外,判别器也会当生成器每进行了 500 次迭代以后训练 100 次。

  • D_ITERS = 5


    [4]其它准备:


    # create output dirif not os.path.isdir(OUT_DIR): os.makedirs(OUT_DIR) # make only specific GPU to be utilized os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"os.environ["CUDA_VISIBLE_DEVICES"] = GPU # seed random generator for repeatability np.random.seed(RND) # force Keras to use last dimension for image channels K.set_image_dim_ordering('tf')


    [5]判别器的损失函数:

    def d_loss(y_true, y_pred): return K.mean(y_true * y_pred)


    [6].创建判别器 D

    判别器将图像作为输入,然后给出两个输出:

    def create_D():
    # weights are initlaized from normal distribution with below params weight_init = RandomNormal(mean=0., stddev=0.02) input_image = Input(shape=(28, 28, 1),) x = Conv2D( 32, (3, 3), padding='same',, kernel_initializer=weight_init)(input_image) x = LeakyReLU()(x) x = MaxPool2D(pool_size=2)(x) x = Dropout(0.3)(x) x = Conv2D( 64, (3, 3), padding='same',, kernel_initializer=weight_init)(x) x = MaxPool2D(pool_size=1)(x) x = LeakyReLU()(x) x = Dropout(0.3)(x) x = Conv2D( 128, (3, 3), padding='same',, kernel_initializer=weight_init)(x) x = MaxPool2D(pool_size=2)(x) x = LeakyReLU()(x) x = Dropout(0.3)(x) x = Conv2D( 256, (3, 3), padding='same',, kernel_initializer=weight_init)(x) x = MaxPool2D(pool_size=1)(x) x = LeakyReLU()(x) x = Dropout(0.3)(x) features = Flatten()(x) output_is_fake = Dense( 1, activation='linear',)(features) output_class = Dense( 10, activation='softmax',)(features) return Model( inputs=[input_image], outputs=[output_is_fake, output_class],)

    [7].创建生成器

    生成器有两个输入:

  • 一个尺寸为Z_SIZE的潜在随机变量。

  • 我们希望生成的数字类型(integer o 到 9)。

  • 标签:王牌娱乐,王牌娱乐官网,王牌娱乐娱乐

    本文链接:http://www.weiqi.cc/developer/116644.html 转载请注明出处