用各种GAN生成正态分布

用GAN生成正态分布

    毕设中有一部分与GAN(Generative Adversarial Networks)相关,但是一直不work,因此准备重新从最简单的GAN入手,实现一下试试看能不能发现什么问题。
    本文会用GAN从标准正态噪声生成均值为3.5,标准差为0.7的正态分布 N ( 3.5 , 0. 7 2 ) N(3.5, 0.7^2) N(3.5,0.72)


整体结构

    一个GAN由生成器Generator(G)和判别器Discriminator(D)构成,D希望能正确分辨真实样本和G生成的假样本,G希望能骗过D,让D认为G生成的样本是真的。根据GAN的不同,G和D的目标函数有所不同,结构和连接方式也各有不同,G与D内部的结构也比较自由(姑且这么认为,实际上还是需要小心设计的)。
    下图是一个原始GAN的结构。 z z z是一个 d d d维的噪声向量, x x x是从目标分布 N ( 3 , 0. 5 2 ) N(3, 0.5^2) N(3,0.52) 中采样得到的样本,即真实样本,也是一个 d d d维向量。


生成器与判别器

    由于任务比较简单,只是随机向量到随机向量,所以G和D的结构只使用MLP。方便起见,令随机向量维度 d = 10 d=10 d=10

# 生成器
class Generator_MLP(BasicBlock):
    def __init__(self, name=None):
        super(Generator_MLP, self).__init__(None, name or "Generator_MLP")
    def __call__(self, z, is_training=True, reuse=False):
        with tf.variable_scope(self.name, reuse=reuse):
            net = tf.nn.softplus(dense(z, 64, name='g_fc1'))
            out = dense(net, 10, name='g_fc2')
            return out
# 判别器
class Discriminator_MLP(BasicBlock):
    def __init__(self, name=None):
        super(Discriminator_MLP, self).__init__(None, name or "Discriminator_MLP")
    def __call__(self, x, is_training=True, reuse=False):
        with tf.variable_scope(self.name, reuse=reuse):
            net = tf.nn.tanh(dense(x, 64, name='d_fc1'))
            net = tf.nn.tanh(bn(dense(net, 64, name='d_fc2'), is_training, name='d_bn2'))
            yd = dense(net, 1, name="D_dense")
            return yd, net

目标函数

GAN

(1) L D = E [ l o g ( D ( x ) ) ] + E [ l o g ( 1 − D ( G ( z ) ) ] L G = E [ l o g ( D ( G ( z ) ) ) ] \begin{matrix} L_D=E[log(D(x))] + E[log(1-D(G(z))] \\ \\ L_G=E[log(D(G(z)))] \\ \end{matrix} \tag{1} LD=E[log(D(x))]+E[log(1D(G(z))]LG=E[log(D(G(z)))](1)

WGAN

(2) L D = E [ D ( x ) ] − E [ D ( G ( z ) ) ] L G = E [ D ( G ( z ) ) ] W D ← c l i p ( W D , − 0.1 , 0.1 ) \begin{matrix} L_D=E[D(x)]-E[D(G(z))] \\ \\ L_G=E[D(G(z))] \\ \\ W_D\leftarrow clip(W_D,-0.1,0.1) \end{matrix} \tag{2} LD=E[D(x)]E[D(G(z))]LG=E[D(G(z))]WDclip(WD,0.1,0.1)(2)

LSGAN

(1) L D = E [ ( D ( x ) − 1 ) 2 ] + E [ D ( G ( z ) 2 ] L G = E [ ( D ( G ( z ) ) − 1 ) 2 ] \begin{matrix} L_D=E[(D(x)-1)^2] + E[D(G(z)^2] \\ \\ L_G=E[(D(G(z))-1)^2] \\ \end{matrix} \tag{1} LD=E[(D(x)1)2]+E[D(G(z)2]LG=E[(D(G(z))1)2](1)

代码实现

def build_placeholder(self):
        self.noise = tf.placeholder(shape=(self.batch_size, self.noise_dim), dtype=tf.float32)
        self.source = tf.placeholder(shape=(self.batch_size, self.noise_dim), dtype=tf.float32)

def build_gan(self):
    self.G = self.generator(self.noise, is_training=True, reuse=False)
    self.G_test = self.generator(self.noise, is_training=False, reuse=True)
    self.logit_real, self.net_real = self.discriminator(self.source, is_training=True, reuse=False)
    self.logit_fake, self.net_fake = self.discriminator(self.G, is_training=True, reuse=True)

def build_optimizer(self):
    if self.gan_type == 'gan':
        self.D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.logit_real, labels=tf.ones_like(self.logit_real)))
        self.D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.logit_fake, labels=tf.zeros_like(self.logit_fake)))
        self.D_loss = self.D_loss_real + self.D_loss_fake
        self.G_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.logit_fake, labels=tf.ones_like(self.logit_fake)))
    elif self.gan_type == 'wgan':
        self.D_loss_real = - tf.reduce_mean(self.logit_real) 
        self.D_loss_fake = tf.reduce_mean(self.logit_fake)
        self.D_loss = self.D_loss_real + self.D_loss_fake
        self.G_loss = - self.D_loss_fake
        if self.clip_num:
            print "GC"
            self.D_clip = [v.assign(tf.clip_by_value(v, -self.clip_num, self.clip_num)) for v in self.discriminator.weights]
    elif self.gan_type == 'lsgan':
        def mse_loss(pred, data):
            return tf.sqrt(2 * tf.nn.l2_loss(pred - data)) / self.batch_size
        self.D_loss_real = tf.reduce_mean(mse_loss(self.logit_real, tf.ones_like(self.logit_real)))
        self.D_loss_fake = tf.reduce_mean(mse_loss(self.logit_fake, tf.zeros_like(self.logit_fake)))
        self.D_loss = 0.5 * (self.D_loss_real + self.D_loss_fake)
        self.G_loss = tf.reduce_mean(mse_loss(self.logit_fake, tf.ones_like(self.logit_fake)))
        if self.clip_num:
            print "GC"
            self.D_clip = [v.assign(tf.clip_by_value(v, -self.clip_num, self.clip_num)) for v in self.discriminator.weights]

结果

完整代码

https://github.com/SongDark/generate_normal

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于生成数据大的算法思想,通常可以采用生成模型或者GAN生成对抗网络)等方法。生成模型是一类统计模型,其目标是学习输入数据的概率分布,从而生成与输入数据相似的新数据。GAN是一种深度学习模型,它通过训练一个生成器和一个判别器来生成数据,其中生成器尝试生成与输入数据相似的新数据,而判别器则尝试区分生成的数据和真实数据。通过不断迭代训练生成器和判别器,GAN可以生成逼真的新数据。 对于生成数据小的算法思想,可以考虑使用插值、扩展或变换等方法。插值是一种基于已有数据的方法,通过对已有数据进行插值来生成新数据,常见的插值方法包括线性插值、三次样条插值等。扩展方法则是通过对已有数据进行扩展,例如复制、翻转、旋转等操作来生成新数据。变换方法则是通过对已有数据进行变换,例如平移、缩放、旋转等操作来生成新数据。 正态分布类型的随机数是指服从正态分布的随机数,正态分布是一种常见的连续型概率分布,其概率密度函数呈钟形曲线,均值和标准差是分布的两个参数。在生成正态分布类型的随机数时,可以使用均值为0、标准差为1的标准正态分布,也可以通过调整均值和标准差来得到不同的正态分布类型的随机数。常见的生成正态分布类型的随机数的方法包括逆变换采样法、Box-Muller转换法等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值