2020机器学习GAN(1)

作者: zidea | 来源:发表于2020-02-20 21:51 被阅读0次

在 2018 年,深度学习掀起 GAN 的潮流,在许多领域都已经有了应用,而且基于 GAN 项目五花八门。早在** GAN** 出现时,就得 Yann LeCun 这样大牛的关注,并给予 GAN 很高评价。

yann_LeCun.jpg

准备推出系列 GAN 的分享,初步设计分享内容

目录

  • GAN 的 Hello World
  • GAN 背后的秘密
  • 闪亮登场
  • GAN 的演变
  • 突破
  • 实战

GAN 应用

图像生成、图像转换、图像生成文本、风格迁移、图像域的转换、图像超分辨率和图像修复等应用,有关 GAN 的应用我们随后的闪亮登场中详细介绍,并且还会相应给出实战案例。

现在问题是我们为什么不能判别器自己去生成图片,因为今天判别器已经知道什么是真实图片,什么样是伪造图片。问题在判别器手上是有真实图片,对于判别器来说生成图片是一件比较难的事。

我们来看一看是否让生成器自己来进行监督

GAN 家族

naruto_team.jpg

随后我们将逐一介绍如何用代码实现下面的 GAN,以及其特点和背后如何推导

  • GAN
  • DCGAN
  • CGAN
  • WGAN 和 EBGAN
  • SRGAN
  • InfoGAN BiGAN
  • cycleGAN
  • pix2pixGAN
hello_naruto.jpeg

hello GAN

有关 GAN 理论部分今天暂时就先不分享,先带大家一起写一个相对简单的 GAN 的 hello world。
今天我们用 keras 实现一个简单 CDGAN(用卷积神经网网络实现 GAN) 作为 HelloWorld。图片集是自己准备的火影忍者的人物头像,由于自己机器性能比较low 所以只能渲染小图而且只跑了 10000 次迭代。大家可以调整参数,训练 96 \times 96 的大图,这里我只渲染 28 \times 28 图。

0.jpg 1.jpg

我们在迭代 100 次,生成器在判别器的督促下就可以生成这样效果


naruto_100.png naruto_3000.png naruto_8000.png

在迭代到 8000 次,图片有点 blur 但是也能隐隐约约看到人脸效果,如果大家感兴趣可以迭代 40000 ~ 50000 就可以的得到不错效果。

生成器和判别器

naruto_vs_sasuke.png
GAN 结构中少不了生成器判别器生成器判别器组成 GAN。那么什么是判别器,什么又是生成器。在许多文章中,用到警察和小偷、或者是造假者和鉴别师来形象地说明生成器判别器,他们都是用一种对立关系来描述判别器生成器之间的关系。这里我更喜欢用鸣人(生成器)和佐助(判别器)来说明他们之间关系,关系是既是朋友又是对手的关系,在相互激励共同进步。鸣人少不了佐助,鸣人因为佐助进步而进步,说了这些可能大家对什么是判别器和生成器还是一头雾水,不急随后详细介绍。下面就是上面 helloGAN 的实现,大家可以先跑一跑。需要自己收集一些卡通人物图片放文件夹就可以训练。没跑起来也不急,随后我们通过 mnist 手写数字集作为数据集来一个一个 GAN 的模型。
imgs = self.load_batch_imgs(batch_size,'naruto_small_faces')

from keras.datasets import mnist
from keras.layers import Input,Dense,Reshape,Flatten,Dropout
from keras.layers import BatchNormalization,Activation,ZeroPadding2D
from keras.layers import LeakyReLU
from keras.layers import UpSampling2D,Conv2D
from keras.models import Sequential,Model
from keras.optimizers import Adam,RMSprop

from keras.models import load_model
from keras.preprocessing import image
import os
import matplotlib.pyplot as plt
import sys
import numpy as np

class DCGAN():
    def __init__(self):
        # 输入图片维度
        self.img_rows = 28;#96
        self.img_cols = 28;
        self.channels = 3;
        
        # 这是一个彩色的图片的卷积
        self.img_shape=(self.img_rows,self.img_cols,self.channels)
        self.latent_dim =100

        optimizer = Adam(0.0002,0.5)
        # 分别为判别器和生成器的优化器
        optimizerD =RMSprop(lr=0.0008, clipvalue=1.0, decay=6e-8)
        optimizerG = RMSprop(lr=0.0004, clipvalue=1.0, decay=6e-8)
        print("-1")

        #对判别器进行构建和编译
        self.discriminator = self.build_discriminator()
        print("0")
        self.discriminator.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['accuracy'])
        print("1")
        #对生成器进行构造
        self.generator = self.build_generator()
        print("2")
        # 生成器介绍一个随机向量
        z = Input(shape=(self.latent_dim,))
        img = self.generator(z)

        # 总体模型只对生成器进行训练
        self.discriminator.trainable = False

        # 从生成器中生成的图 经过判别器获得一个valid
        valid = self.discriminator(img)
        self.combined = Model(z,valid)
        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)

    # 
    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(UpSampling2D())
        model.add(Conv2D(128, kernel_size=3, padding="same"))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Activation("relu"))
        model.add(UpSampling2D())
        model.add(Conv2D(64, kernel_size=3, padding="same"))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Activation("relu"))
        model.add(Conv2D(self.channels, kernel_size=3, padding="same"))
        model.add(Activation("tanh"))

        model.summary()  #打印网络参数

        noise = Input(shape=(self.latent_dim,))
        img = model(noise)
        return  Model(noise,img)  #定义一个 一个输入noise一个输出img的模型

    def build_discriminator(self):
        dropout = 0.25
        depth = 32
        model = Sequential()
        

        model.add(Conv2D(32, 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(64, kernel_size=3, strides=2, padding="same"))
        model.add(ZeroPadding2D(padding=((0,1),(0,1))))
        model.add(BatchNormalization(momentum=0.8))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(0.25))
        model.add(Conv2D(128, kernel_size=3, strides=2, padding="same"))
        model.add(BatchNormalization(momentum=0.8))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(0.25))
        model.add(Conv2D(256, kernel_size=3, strides=1, padding="same"))
        model.add(BatchNormalization(momentum=0.8))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(0.25))
        model.add(Flatten())
        model.add(Dense(1, activation='sigmoid'))

        model.summary()

        img = Input(shape=self.img_shape)
        validity = model(img)

        return Model(img,validity)

    def train(self,epochs,batch_size=128,save_interval = 50):

        # Adversarial ground truths
        valid = np.ones((batch_size, 1))
        fake = np.zeros((batch_size, 1))
        for epoch in range(epochs):

            # ---------------------
            #  Train Discriminator
            # ---------------------

            # Select a random half of images
            # idx = np.random.randint(0, X_train.shape[0], batch_size)
            # imgs = X_train[idx]
            imgs = self.load_batch_imgs(batch_size,'naruto_small_faces')

            # Sample noise and generate a batch of new images
            noise = np.random.normal(0, 1, (batch_size, self.latent_dim))
            gen_imgs = self.generator.predict(noise)

            # Train the discriminator (real classified as ones and generated as zeros)
            d_loss_real = self.discriminator.train_on_batch(imgs, valid)
            d_loss_fake = self.discriminator.train_on_batch(gen_imgs, fake)
            d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

            # ---------------------
            #  Train Generator
            # ---------------------

            # Train the generator (wants discriminator to mistake images as real)
            g_loss = self.combined.train_on_batch(noise, valid)

            # Plot the progress
            print ("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100*d_loss[1], g_loss))

            # If at save interval => save generated image samples
            if epoch % save_interval == 0:
                self.combined.save('./model/combined_model_%d.h5'%epoch)
                self.discriminator.save('./model/discriminator_model_%d.h5'%epoch )
                self.save_imgs(epoch)


    def load_batch_imgs(self,batch_size,dirName):
        img_names = os.listdir(os.path.join(dirName))
        img_names = np.array(img_names)
        idx = np.random.randint(0, img_names.shape[0], batch_size)
        img_names = img_names[idx]
        img = []
        # 把图片读取出来放到列表中
        for i in range(len(img_names)):
            images = image.load_img(os.path.join(dirName, img_names[i]), target_size=(28, 28))
            x = image.img_to_array(images)
            x = np.expand_dims(x, axis=0)
            img.append(x)
            # print('loading no.%s image' % i)

        # 把图片数组联合在一起

        x = np.concatenate([x for x in img])
        x = x / 127.5 - 1.
        return x


    def save_imgs(self, epoch):
        r, c = 5, 5
        noise = np.random.normal(0, 1, (r * c, self.latent_dim))  #高斯分布,均值0,标准差1,size= (5*5, 100)
        gen_imgs = self.generator.predict(noise)

        # Rescale images 0 - 1
        gen_imgs = 0.5 * gen_imgs + 0.5

        fig, axs = plt.subplots(r, c)
        cnt = 0   #生成的25张图 显示出来
        for i in range(r):
            for j in range(c):
                axs[i,j].imshow(gen_imgs[cnt, :,:,:])
                axs[i,j].axis('off')
                cnt += 1
        fig.savefig("images/naruto_%d.png" % epoch)
        plt.close()
    def loadModel(self):
        self.combined = load_model('./model/combined_model_last.h5')
        self.discriminator = load_model('./model/discriminator_model_last.h5')
if __name__ == '__main__':
    dcgan = DCGAN()
    dcgan.train(epochs=10000, batch_size=64, save_interval=100)

最后希望大家关注我们微信公众号


wechat.jpeg

相关文章

  • 2020机器学习GAN(1)

    在 2018 年,深度学习掀起 GAN 的潮流,在许多领域都已经有了应用,而且基于 GAN 项目五花八门。早在**...

  • 2020机器学习GAN(5)

    参考李宏毅老师分享 先解释一下根据样本进行生成图片,然后把图片每一个像素都看成其一个特征,那么图片就是存在一个高维...

  • 2020机器学习GAN(8)

    为什么不用 Discriminator 生成图片 其实 Discriminator 会从整体来考量图片好坏假设我们...

  • 2020机器学习GAN(F)

    训练 好现在定义好判别器模型和生成模型,而且定义好优化器这里梯度下降使用 Adam 给以较小学习率。在开始训练前我...

  • 2020机器学习GAN(3)

    代码讲解 今天 tensorflow2.0 实现一个简单全连接实现 GAN。我们先回忆在做机器学习一般流程,然后我...

  • 2020机器学习GAN(6)

    我们就是找到一个 G ,这个 G 可以让和之间的 JSDiv 距离尽量小。 回忆一下我们在 GAN 中任务,就是找...

  • 2020机器学习GAN(2)

    今天目标是介绍一下 GAN 是如何做到输出图片的这个样任务。在 GAN 中分别有两个阶段,在生成阶段就是固定生成器...

  • 机器学习-Gan算法

    2018/11/07 机器学习-Gan算法 Alpha go:运用蒙特卡洛搜索树,深度学习,机器学习三种方法 1...

  • 对抗生成网络

    1. 什么是 GAN? 好了,GAN 如此强大,那它到底是一个什么样的模型结构呢?我们之前学习过的机器学习或者神经...

  • 2020机器学习GAN(CGAN) (9)

    CGAN(Conditonal Generation GAN) 什么是 CGAN 呢?之前我们 GAN 生成图片是...

网友评论

    本文标题:2020机器学习GAN(1)

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