CGAN--条件生成对抗神经网络(文末留言免费赠书)

人工智能与算法学习

共 4325字,需浏览 9分钟

 ·

2021-06-26 14:37




CGAN概述

     原始的GAN在生成高维度数据时,只能随机生成,无法生成我们给定条件的数据。这极大的限制了GAN的应用范围,因为,对于我们来说,仅仅生成足够真实的数据(如图片)没有太大的意义,因为只要架起高清照相机,我们就能够得到足够多的、真实的图片,所以,只有能够生成我们指定条件的数据,才有意义。
      有条件约束的GAN,将数字类别作为约束条件与随机噪声一起输入到生成模型,使生成模型能够生成指定的手写数字。对应的,CGAN的辨别模型的输入也包含两个部分,图片和标签。





一、CGAN模型架构


        CGAN的模型架构,如图1所示

1     CGAN模型架构

   从图1中可以看出,样本数据中的图片(x)和类别标签(y)对,一起输入到辨别模型,除此之外,输入到辨别模型的还有生成模型生成的图片(Gz|y))与类别标签(y),辨别模型的目标是将他们区分开。生成模型的输入是类别标签(y)和随机噪声(z),输出的是生成的手写数字图片。需要注意的是,这里的类别标签(y)来源于样本数据,而不是随机生成的标签,只有这样生成模型才能学习到如何生成指定类别的手写数字。




二、 生成模型架构


       CGAN的生成模型,如图2所示。输入的类别标签(y)和随机噪声(z),分别与包含200个和1000个神经元的全连接层连接(类别标签先被转换成one-hot张量),该全连接层之后紧接着一个批量正则化层,激活函数采用的是ReLU

2    CGAN原始的生成模型架构

   然后,将上述两个全连接层串联起来,与一个包含512个神经元的全连接层连接起来,紧接着是带泄露的ReLU激活函数、批量正则化函数。需要说明的是,在原始的CGAN论文中,该层似乎是1200个神经元,但是,在实际模型训练过程中,笔者发现512个神经元模型更容易训练。

   最后,连接到包含784个神经元的全连接层,采用sigmoid激活函数,紧接着是批量正则化层。由于sigmoid输出的取值范围是[0, 1],所以,在模型训练阶段,我们读取样本数据时,需要将样本数据的取值范围从[0,255]映射到[0, 1],这样真实的样本数据和生成的数据取值范围才有可能一致。对应的,在展示生成的图片是,需要将生成的数据取值范围映射到[-1, 1],才能正确的显示图片,否则,生成的图片会变灰、变白,看起来很模糊。




三、辨别模型架构


       CGAN的辨别模型,见图3。样本数据的图片(x)首先与一个k=5、输出神经元个数为240Maxout网络层连接。Maxout网络层是全连接层的变种,原理和实现代码见“7.1.4 Maxout网络层”。类别标签分别(y)与一个k=5、输出神经元个数为50Maxout网络层连接。

   其次,将上述两个Maxout网络层的输出结果串联起来,再与一个k=4、输出神经元个数为240Maxout网络层连接。

   最后,将上述Maxout网络层的输出结果连接到一个只包含1个神经元的全连接层,该全连接层采用sigmoid作为激活函数。

3     CGAN原始的辨别模型架构




四、 Maxout网络层原理


       Maxout网络层是原始全连接层的变种。原始的全连接层的计算过程,见图4。此图展示了输入,输出的计算过程。其中,是激活函数,是权重,是偏置项。

4       原始全连接层示意图

   我们仍然以输入,输出为例,展示Maxout网络层的计算过程,参见图5。从图5中可以看出,与原始的全连接层神经网络相比,Maxout网络层中多了一个包含k个神经元的隐藏层,输入的分别与这k个神经元连接,对应的使用k组()权重参数,输出ky,然后,这ky输入给求最大值(max)函数,将求出的最大值作为Maxout的最终输出。

5    Maxout网络层的计算过程示意图





五、 Maxout网络层实现


      Maxout没有内置在TensorFlow 2.0的版本中,所以,我们来实现一个简单的、自定义Maxout网络层,命名为MaxoutDense

   实现自定义的Maxout网络层,需要实现一个继承tf.keras.layers.LayerMaxoutDense类,实现它的初始化函数、buid函数、以及call函数。其中,初始化函数,用于接收MaxoutDense的超参,比如koutput_dimsbuild函数用于对权重参数进行初始化,它是由父类在调用call函数之前自动调用。由于初始化参数时,需要根据输入张量的形状来计算参数的形状,因此,build的输入参数是input_shape,代表输入张量的形状。最后是call函数,输入参数是输入张量,call函数用于执行最终的计算。

      Maxout网络层的实现代码如下,我们将下面的代码保存到maxout.py文件中备用。

#!/usr/bin/env python3# -*- coding: UTF-8 -*-
from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_function
import tensorflow as tf # TensorFlow 2.0

class MaxoutDense(tf.keras.layers.Layer): def __init__(self, k, output_dims, kernel_initializer=None): """ 参数: k : k个神经元一组 output_dims: 输出的神经元个数 kernel_initializer: 参数初始化器,GAN模型训练困难,参数初始化必须小心。 在这里我们采用均值为0.0、方差为0.02的正态分布随机数来填充 """ super(MaxoutDense, self).__init__() self.k = k self.output_dims = output_dims if kernel_initializer is None: kernel_initializer = tf.random_normal_initializer( mean=0.0, stddev=0.02) self.kernel_initializer = kernel_initializer
def build(self, input_shape): """ 在调用call之前,根据输入张量的形状,初始化变量。 在调用call函数之前,由父类自动调用。 """ d = input_shape[-1]
self.W = tf.Variable(self.kernel_initializer( shape=[d, self.output_dims, self.k])) self.b = tf.Variable(self.kernel_initializer( shape=[self.output_dims, self.k]))
def call(self, input): """ 执行Maxout计算。 """ z = tf.tensordot(input, self.W, axes=1) + self.b # 对k组输出结果,求最大值 z = tf.reduce_max(z, axis=2)
        return z


     Maxout网络层的调用示例代码如下:

# 将图像连接到k=5、输出神经元个数为240的Maxout层image_h0 = MaxoutDense(k=5, output_dims=240)(image)
# 将k=5、输出神经元个数为240的Maxout层增加到模型中model = Sequential( )model.add(MaxoutDense(k=5, output_dims=50))
                     本文选自----《GAN生成对抗神经网络原理与实践》一书中,经授权此公号。



文末赠书




编辑推荐


  1. 全景:囊括GAN起源、发展和演变的全貌;

  2. 插图:100余幅插图,图说GAN的原理;

  3. 实战:10余种有代表性的GAN案例代码。

         

大家好!我们将这本《GAN生成对抗神经网络原理与实践》赠送给大家,你只需要留言评论即可,其中集赞最多的5位读者可以免费领取这本书。


活动截止时间:2021年6月26日  18:00整

想要的读者朋友请赶紧留言,邀请你的好友为你点赞吧!



点个在看你最好看

浏览 64
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报