InfoGAN

作者: zelda2333 | 来源:发表于2020-09-27 11:06 被阅读0次

    一、从GAN到InfoGAN

    1.GAN存在的问题

    GAN通过生成器与判别器的对抗学习,最终可以得到一个与real data分布一致的fake data,但是由于生成器的输入z是一个连续的噪声信号,并且没有任何约束,导致GAN无法利用这个z,并且无法将z的具体维度与数据的语义特征对应起来,并不是一个可解释的表示。

    GAN的结构.png

    2.InfoGAN:通过最大化生成对抗网络的信息进行可解释的表示学习

    InfoGAN是对GAN的一种改进,曾被OPENAI称为2016年的五大突破之一。

    InfoGAN以此为出发点,试图利用z寻找一个可解释的表达,于是将z进行拆解,可分为如下两部分:

    ①z:不可压缩的噪声

    ②c:可解释的隐变量(latent code)

    (其目的在于数据分布的显著结构化语义特征)

    作者希望通过约束隐变量c与生成数据之间的关系,可以使得c里面包括有对数据的可解释信息。如文中提到的MNIST数据集,c可以分为categorial latent code指向数字种类信息(0-9),continous latent code指向倾斜度、粗细。

    InfoGAN的结构.png

    网络结构图片来自:https://github.com/hwalsuklee/tensorflow-generative-model-collections

    二、InfoGAN理论分析

    1.无监督学习

    (1)无监督学习是指从无标签数据中学习出关键的语义特征。然后利用该特征用于分类、回归、策略学习等。

    (2)无监督学习的流行框架是表征学习,其目标是使用未标记的数据来学习将重要语义特征暴露为易于解码的要素表示。

    (3)无监督学习的很大部分是由生成模型驱动的。

    这是由于相信生成或创造观察到的数据需要某种形式理解的能力,希望一个良好的生成模型将自动学习一个特征分离的表示,即使很容易构建完美生成模型却具有随机不好的表示的。

    2.解耦表示

    (1)无监督学习是一个病态问题,因为相关下游任务通常是未知的。

    (2)数据的解耦表示对于相关的,但是未知的下游任务有比较好的效果。

    数据的解耦表示:是显示表示数据的显著特征。

    比如:对于人脸,一个有用的解耦表示就是将人脸表情、眼睛颜色、是否戴眼镜等一个个特征分别表示一个特征维度,每个维度的不同取值表示各个特征的取值。

    3.隐变量c

    ①对应于语义向量,隐变量编码代表数据分布的显著特征的语义特征。

    通过定义一系列的结构潜变量c1,c2,c3,……,相互独立,则:

    ②标准GAN中,直接为网络的输入进行训练,那么生成器将忽略隐变量c的作用,即P­­­G­(x|c)=P­G­(x)。

    或者可以看成隐变量c与x相互独立,不相关。

    ③InfoGAN提出一种无监督方式,让生成网络输入噪声变量z隐变量c。即生成网络表示为G(z,c)

    ④InfoGAN需要强化隐变量c的作用,使c能够直接代表生成的变量的某一方面的属性,所以需要让隐变量与生成的变量G(z,c)拥有尽可能多的共同信息。

    4.互信息I(X;Y)(最大化隐变量与生成结果的互信息)

    关于互信息的理解:熵、互信息、相对熵

    InfoGAN的目标:是加入一个新的隐变量c,使得c与生成的样本具有较高的互信息。这样c用于表示数据某个方面的语义信息,z用于表示样本x中与c无关的其它信息。

    ①定量互信息I(c;G(z.c))—>(InfoGAN提出信息正则化约束项)

    在信息论中,I(x;y)表示x里面关于y的信息有多少;

    ②在原始GAN损失函数V(D,G)基础上,提出加入信息正则化约束项I(c;G(z.c))

    image

    ③优化函数,采用近似方法

    求I需要涉及到P(c|x),但是分布很难求。使用下界代替I来进行简化。

    简化之后,函数I不在需要使用P(c|x)而是使用了一个下界函数Q(c|x) 作为因子高斯来进行替代,而Q(c|x)本质上是对P(c|x)的拟合;

    简化之后,虽然不需要使用P(c|x),但是需要从P(c|x)中采样以计算期望。当c包含连续变量时,较小的通常用于确保的微分熵与GAN目标规模相同。

    在具体实现中,Q和D共用了所有的卷积层,并只在最后增加了一个全连接层来输出Q(c|x),因此InfoGAN并没有在GAN上增加多少计算量。

    三、以故事的方式理解InfoGAN

    小D是一个很喜欢吃饺子的姑娘,喜欢吃不同的馅的饺子,而且对于饺子的要求十分高,尤其喜欢B城的一家饺子店的饺子,但是由于长期身在A城,没有办法吃到B城的饺子。
    而她的男朋友小G和她是异地,而且恰好是在B城,是一个非常宠她的小伙子,经常为了让她吃到满意的饺子,不断的尝试制作出和B城的饺子店一模一样的饺子。在每一次做完饺子之后,都会再去买一份小D爱吃的那家店的饺子,然后不辞千里给小D送去,让小D猜测哪个是他包的饺子,哪个是饺子店的饺子。终于,起初,小D总会一下子就能够分辨出来,终于,功夫不负有心人,有一天,小D已经分不出哪个是小G做的饺子哪个是饺子店的饺子了,因为它们都一样好吃了。
    故事讲到了这里,并没有结束,哈哈,毕竟好吃的除了男朋友,总少不了好闺蜜嘛,小D的好闺蜜叫小Q,不论是三观还是喜好都和小D保持高度一致,同样也喜欢吃B城的那家店的饺子,唯一不同的是,每次吃饺子的时候,都喜欢加点醋,但是,她拥有一个超能力,那就是,虽然不同馅的饺子的外形差异很细微,但是她是他们三个中唯一一个能够分辨出不同馅的饺子的样子的差异的人,而小D和小G并做不到这一点,经常吃一口才知道是什么馅的。

    • 1、判别器(Discriminator)
      小D:她的作用是判别饺子店的饺子和男朋友的饺子之间是否有差异的。
      而对于InfoGAN来说,就是判断real data (x)和生成器生成的fake data (G(z))之间的差异有多少。
    • 2、生成器(Generator)
      小G:他的作用是不断的提高自己的造假能力,知道他做出的不同馅的饺子小D分辨不出来是他做的还是饺子店做的为止。
      而对于InfoGAN来说,生成器就是利用噪声z和latent code c来进行生成仿真的数据,直到判别器无法分辨出数据到底是来自真实的数据x还是生成的数据G(z)为止。
    • 3、分类器
      小Q:她的作用是为了分辨出不同馅的饺子的差异,饺子上是没有标记的。
      而对于InfoGAN来说,Q网络是和D网络公用除了最后一层之外的其他所有的层的,它是为了分辨出数据之间的类别是什么,比如什么馅的饺子。
    • 4、GAN
      只有D网络和G网络的就是普通的GAN,这两个网络之间不断的进行博弈,直到G网络学会的fake data和real data是D网络分辨不出来的为止。

    四、代码

    # Build Generator
     def build_generator(self):
    
            model = Sequential()
    
            model.add(Dense(128 * 7 * 7, activation="relu", input_dim=self.latent_dim))
            model.add(Reshape((7, 7, 128)))
            model.add(BatchNormalization(momentum=0.8))
            model.add(UpSampling2D())
            model.add(Conv2D(128, kernel_size=3, padding="same"))
            model.add(Activation("relu"))
            model.add(BatchNormalization(momentum=0.8))
            model.add(UpSampling2D())
            model.add(Conv2D(64, kernel_size=3, padding="same"))
            model.add(Activation("relu"))
            model.add(BatchNormalization(momentum=0.8))
            model.add(Conv2D(self.channels, kernel_size=3, padding='same'))
            model.add(Activation("tanh"))
    
            gen_input = Input(shape=(self.latent_dim,))
            img = model(gen_input)
    
            model.summary()
    
            return Model(gen_input, img)
    
    # Build Discriminator and Q Net
        def build_disk_and_q_net(self):
    
            img = Input(shape=self.img_shape)
    
            # Shared layers between discriminator and recognition network
            model = Sequential()
            model.add(Conv2D(64, kernel_size=3, strides=2, input_shape=self.img_shape, padding="same"))
            model.add(LeakyReLU(alpha=0.2))
            model.add(Dropout(0.25))
            model.add(Conv2D(128, kernel_size=3, strides=2, padding="same"))
            model.add(ZeroPadding2D(padding=((0,1),(0,1))))
            model.add(LeakyReLU(alpha=0.2))
            model.add(Dropout(0.25))
            model.add(BatchNormalization(momentum=0.8))
            model.add(Conv2D(256, kernel_size=3, strides=2, padding="same"))
            model.add(LeakyReLU(alpha=0.2))
            model.add(Dropout(0.25))
            model.add(BatchNormalization(momentum=0.8))
            model.add(Conv2D(512, kernel_size=3, strides=2, padding="same"))
            model.add(LeakyReLU(alpha=0.2))
            model.add(Dropout(0.25))
            model.add(BatchNormalization(momentum=0.8))
            model.add(Flatten())
    
            img_embedding = model(img)
    
            # Discriminator
            validity = Dense(1, activation='sigmoid')(img_embedding)
    
            # Recognition
            q_net = Dense(128, activation='relu')(img_embedding)
            label = Dense(self.num_classes, activation='softmax')(q_net)
    
            # Return discriminator and recognition network
            return Model(img, validity), Model(img, label)
    

    参考链接:
    InfoGAN 网络训练过程介绍
    InfoGAN学习笔记
    InfoGAN 翻译
    InfoGAN:一种无监督生成方法 | 经典论文复现
    InfoGAN 代码

    相关文章

      网友评论

          本文标题:InfoGAN

          本文链接:https://www.haomeiwen.com/subject/zizzyktx.html