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)

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