精彩å
容ä¸è¿·è·¯
åºå | AIç§æå¤§æ¬è¥ï¼ID:rgznai100ï¼
å¼è¨ï¼
è¿å å¹´æ¥ï¼GANçæå¯¹æå¼åºç¨ååç«çï¼ä¸è®ºæ¯æé³ä¸å¤§ç«çâèèçé»âè¿æ¯Bç«ä¸çâå¤åèæ§ç
§çâ以忢è¸çåè½ï¼é½æ¯åºäºGANçæå¯¹æå¼ç模åã使¯GANç®æ³å¯¹äºå¤§å¤æ°èè¨ä¸æè¾é¾ï¼æ
ä»å¤©æä»¬å°ä½¿ç¨æå°ç代ç ï¼ç®åå
¥é¨âçæå¯¹æå¼ç½ç»âï¼å®ç°ç¨GANçææ°åã
å
¶ä¸çæçå¾çææå¦ä¸å¯è§ï¼
æ¬æ¬¡ç¯å¢ä½¿ç¨çæ¯python3.6.5+windowså¹³å°
-
OS模åç¨æ¥å¯¹æ¬å°æä»¶è¯»åå é¤ãæ¥æ¾å°çæä»¶æä½
-
numpy模åç¨æ¥ç©éµåæ°æ®çè¿ç®å¤çï¼å
¶ä¸ä¹å
æ¬å深度å¦ä¹ æ¡æ¶ä¹é´ç交äºç
-
Kerasæ¨¡åæ¯ä¸ä¸ªç±Pythonç¼åç弿ºäººå·¥ç¥ç»ç½ç»åºï¼å¯ä»¥ä½ä¸ºTensorflowãMicrosoft-CNTKåTheanoçé«é¶åºç¨ç¨åºæ¥å£ï¼è¿è¡æ·±åº¦å¦ä¹ 模åç设计ãè°è¯ãè¯ä¼°ãåºç¨åå¯è§å ãå¨è¿éæä»¬ç¨æ¥æå»ºç½ç»å±åç´æ¥è¯»åæ°æ®éæä½ï¼ç®åæ¹ä¾¿
-
Matplotlib模åç¨æ¥å¯è§åè®ç»ææçæ°æ®å¾çå¶ä½
GAN ç±çæå¨ ï¼Generatorï¼åå¤å«å¨ (Discriminator) 两个ç½ç»æ¨¡åç»æï¼è¿ä¸¤ä¸ªæ¨¡åä½ç¨å¹¶ä¸ç¸åï¼èæ¯ç¸äºå¯¹æãæä»¬å¯ä»¥å¾ç®åççè§£æï¼Generatoræ¯é åçç人ï¼Discriminatoræ¯è´è´£é´å®çäººãæ£æ¯å ä¸ºçææ¨¡ååå¯¹ææ¨¡åçç¸äºå¯¹æå
³ç³»æç§°ä¹ä¸ºçæå¯¹æå¼ã
é£æä»¬ä¸ºä»ä¹ä¸éç¨VAEå»çææ¨¡åå¢ï¼åæä¹ç¥éGANçæçå¾ç伿¯VAEçæçæ´ä¼å¢ï¼é®é¢å°±å¨äºVAE模åä½ç¨æ¯ä½¿å¾çæææè¶ç¸ä¼¼è¶å¥½ï¼ä½äºå®ä¸ä»
ä»
æ¯ç¸ä¼¼å´åªæ¯ä¾è«è¦ç»ç¢ãè GAN æ¯éè¿ discriminator æ¥çæç®æ¨ï¼è䏿¯å VAE线æ§è¬çå¦ä¹ ã
è¿ä¸ªé¡¹ç®éæä»¬ç®æ æ¯è®ç»ç¥ç»ç½ç»çææ°çå¾åï¼è¿äºå¾å䏿°æ®éä¸å
å«çå¾åå°½å¯è½ç¸è¿ï¼è䏿¯ç®åçå¤å¶ç²è´´ãç¥ç»ç½ç»å¦ä¹ ä»ä¹æ¯å¾åçâæ¬è´¨âï¼ç¶åè½å¤ä»ä¸ä¸ªéæºçæ°åæ°ç»å¼å§å建å®ãå
¶ä¸»è¦ææ³æ¯è®©ä¸¤ä¸ªç¬ç«çç¥ç»ç½ç»ï¼ä¸ä¸ªäº§çå¨åä¸ä¸ªé´å«å¨ï¼ç¸äºç«äºãçæå¨ä¼åå»ºä¸æ°æ®éä¸çå¾çå°½å¯è½ç¸ä¼¼çæ°å¾åãå¤å«å¨è¯å¾äºè§£å®ä»¬æ¯åå§å¾çè¿æ¯åæå¾çã
å¨è¿éæä»¬åå§åéè¦ä½¿ç¨å°çåéï¼ä»¥åä¼åå¨ã对æå¼æ¨¡åçã
def __init__(self, width=28, height=28, channels=1):
    self.width = width
    self.height = height
    self.channels = channels
    self.shape = (self.width, self.height, self
.channels)
    self.optimizer = Adam(lr=0.0002, beta_1=0.5, decay=8e-8)
    self.G = self.__generator()
    self.G.compile(loss='binary_crossentropy', optimizer=self.optimizer)
    self.D = self.__discriminator()
    self.D.compile(loss='binary_crossentropy', optimizer=self.optimizer, metrics=['accuracy'])
    self.stacked_generator_discriminator = self.__stacked_generator_discriminator()
    self.stacked_generator_discriminator.compile(loss='binary_crossentropy', optimizer=self.optimizer)
1.4 çæå¨æ¨¡åçæå»º
è¿éæä»¬å°½å¯è½ç®åçæå»ºä¸ä¸ªçæå¨æ¨¡åï¼3个å®å
¨è¿æ¥çå±ï¼ä½¿ç¨sequentialæ ååãç¥ç»å
æ°å嫿¯256,512,1024çï¼
 def __generator(self):
        """ Declare generator """
        model = Sequential()
        model.add(Dense(256, input_shape=(100,)))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(512))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(1024))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(self.width  * self.height * self.channels, activation='tanh'))
        model.add(Reshape((self.width, self.height, self.channels)))
        return model
1.5 å¤å«å¨æ¨¡åçæå»º
å¨è¿éåæ ·ç®åæå»ºå¤å«å¨ç½ç»å±ï¼åçæå¨æ¨¡å类似ï¼
def __discriminator(self):
    """ Declare discriminator """
    model = Sequential()
    model.add(Flatten(input_shape=self.shape))
    model.add(Dense((self.width * self.height * self.channels), input_shape=self.shape))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dense(np.int64((self.width * self.height * self.channels)/2)))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dense(1, activation='sigmoid'))
    model.summary()
    return model
1.6 对æå¼æ¨¡åçæå»º
è¿éæ¯è¾ä¸ºé¾çè§£çé¨åã让æä»¬å建ä¸ä¸ªå¯¹ææ§æ¨¡åï¼ç®åæ¥è¯´è¿åªæ¯ä¸ä¸ªåé¢è·çä¸ä¸ªé´å«å¨ççæå¨ã注æï¼å¨è¿éé´å«å¨çæé被å»ç»äºï¼æä»¥å½æä»¬è®ç»è¿ä¸ªæ¨¡åæ¶ï¼çæå¨å±å°ä¸åå½±åï¼åªæ¯åä¸ä¼ 鿢¯åº¦ã代ç å¾ç®åå¦ä¸ï¼
def __stacked_generator_discriminator(self):
    self.D.trainable = False
    model = Sequential()
    model.add(self.G)
    model.add(self.D)
    return model
å¨è¿éï¼æä»¬å¹¶æ²¡æç´æ¥å»è®ç»çæå¨ãèæ¯éè¿å¯¹ææ§æ¨¡åé´æ¥å°è®ç»å®ãæä»¬å°åªå£°ä¼ éç»äºå¯¹ææ¨¡åï¼å¹¶å°ææä»æ°æ®åºä¸è·åçå¾åæ è®°ä¸ºè´æ ç¾ï¼èå®ä»¬å°ç±çæå¨çæã
对çå®å¾åè¿è¡é¢å
è®ç»çé´å«å¨æä¸è½åæçå¾åæ 记为çå®å¾åï¼æç¯çé误å°å¯¼è´ç±æå¤±å½æ°è®¡ç®åºçæå¤±è¶æ¥è¶é«ãè¿å°±æ¯ååä¼ æåæ¥ä½ç¨çå°æ¹ãç±äºé´å«å¨çåæ°æ¯å»ç»çï¼å¨è¿ç§æ
åµä¸ï¼ååä¼ æä¸ä¼å½±åå®ä»¬ãç¸åï¼å®ä¼å½±åçæå¨çåæ°ãæä»¥ä¼åå¯¹ææ§æ¨¡åçæå¤±å½æ°æå³ç使çæçå¾åå°½å¯è½çç¸ä¼¼ï¼é´å«å¨å°è¯å«ä¸ºçå®çãè¿æ¢æ¯çæå¯¹æå¼çç¥å¥ä¹å¤!
æ
è®ç»é¶æ®µç»ææ¶ï¼æä»¬çç®æ æ¯å¯¹ææ§æ¨¡åçæå¤±å¼å¾å°ï¼èé´å«å¨ç误差尽å¯è½é«ï¼è¿æå³çå®ä¸åè½å¤å辨åºå·®å¼ã
æç»å¨æé¨çè®ç»ç»ææ¶ï¼é´å«å¨æå¤±çº¦ä¸º0.73ãèè尿们ç»å®è¾å
¥äº50%ççå®å¾åå50%çåæå¾åï¼è¿æå³çå®ææ¶æ æ³è¯å«åå¾åãè¿æ¯ä¸ä¸ªå¾å¥½çç»æï¼èèå°è¿ä¸ªä¾åç»å¯¹ä¸æ¯ä¼åçç»æãè¦ç¥éç¡®åçç¾åæ¯ï¼æå¯ä»¥å¨ç¼è¯æ¶æ·»å ä¸ä¸ªç²¾åº¦ææ ,è¿æ ·å®å¯è½å¾å°å¾å¤æ´å¥½çç»æå®ç°æ´å¤æçç»æççæå¨åå¤å«å¨ã
代ç å¦ä¸ï¼è¿élegit_imagesæ¯æåå§è®ç»çå¾åï¼èsyntetic_imagesæ¯çæçå¾åãï¼
def train(self, X_train, epochs=20000, batch = 32, save_interval = 100):
    for cnt in range(epochs):
        ## train discriminator
        random_index = np.random.randint(0, len(X_train) - np.int64(batch/2))
        legit_images = X_train[random_index : random_index + np.int64(batch/2)].reshape(np.int64(batch/2), self.width, self.height, self.channels)
        gen_noise = np.random.normal(0, 1, (np.int64(batch/2), 100))
        syntetic_images = self.G.predict(gen_noise)
        x_combined_batch = np.concatenate((legit_images, syntetic_images))
        y_combined_batch = np.concatenate((np.ones((np.int64(batch/2), 1)), np.zeros((np.int64(batch/2), 1))))
        d_loss = self.D.train_on_batch(x_combined_batch, y_combined_batch)
        # train generator
        noise = np.random.normal(0, 1, (batch, 100))
        y_mislabled = np.ones((batch, 1))
        g_loss = self.stacked_generator_discriminator.train_on_batch(noise, y_mislabled)
        print ('epoch: %d, [Discriminator :: d_loss: %f], [ Generator :: loss: %f]' % (cnt, d_loss[0], g_loss))
        if cnt % save_interval == 0:
            self
.plot_images(save2file=True, step=cnt)
使ç¨matplotlibæ¥å¯è§å模åè®ç»ææã
def plot_images(self, save2file=False, samples=16, step=0):
    ''' Plot and generated images '''
    if not os.path.exists("./images"):
        os.makedirs("./images")
    filename = "./images/mnist_%d.png" % step
    noise = np.random.normal(0, 1, (samples, 100))
    images = self.G.predict(noise)
    plt.figure(figsize=(10, 10))
    for i in range(images.shape[0]):
        plt.subplot(4, 4, i+1)
        image = images[i, :, :, :]
        image = np.reshape(image, [self.height, self.width])
        plt.imshow(image, cmap='gray')
        plt.axis('off')
    plt.tight_layout()
    if save2file:
        plt.savefig(filename)
        plt.close('all')
    else:
        plt.show()
èèå°ä»£ç è¾å°ï¼ä¸è¿°ä»£ç å¤å¶ç²è´´å³å¯è¿è¡ã
#Â -*-Â coding:Â utf-8Â -*-
import os
import numpy as np
from IPython.core.debugger import Tracer
from keras.datasets import mnist
from keras.layers import Input, Dense, Reshape, Flatten, Dropout
from keras.layers import BatchNormalization
from keras.layers.advanced_activations import LeakyReLU
from keras.models import Sequential
from keras.optimizers import Adam
import matplotlib.pyplot as plt
plt.switch_backend('agg')   # allows code to run without a system DISPLAY
class GAN(object):
    """ Generative Adversarial Network class """
    def
 __init__(self, width=28, height=28, channels=1):
        self.width = width
        self.height = height
        self.channels = channels
        self.shape = (self.width, self.height, self.channels)
        self.optimizer = Adam(lr=0.0002, beta_1=0.5, decay=8e-8)
        self.G = self.__generator()
        self.G.compile(loss='binary_crossentropy', optimizer=self.optimizer)
        self.D = self.__discriminator()
        self.D.compile(loss='binary_crossentropy', optimizer=self.optimizer, metrics=['accuracy'])
        self.stacked_generator_discriminator = self.__stacked_generator_discriminator()
        self.stacked_generator_discriminator.compile(loss='binary_crossentropy', optimizer=self.optimizer)
    def __generator(self):
        """ Declare generator """
        model = Sequential()
        model.add(Dense(256, input_shape=(100,)))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(512))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(1024))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(self.width  * self.height * self.channels, activation='tanh'))
        model.add(Reshape((self.width, self.height, self.channels)))
        return model
    def __discriminator(self):
        """ Declare discriminator """
        model = Sequential()
        model.add(Flatten(input_shape=self.shape))
        model.add(Dense((self.width * self.height * self.channels), input_shape=self.shape))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dense(np.int64((self.width * self.height * self.channels)/2)))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dense(1, activation='sigmoid'))
        model.summary()
        return model
    def __stacked_generator_discriminator(self):
        self.D.trainable = False
        model = Sequential()
        model.add(self.G)
        model.add(self.D)
        return
 model
    def train(self, X_train, epochs=20000, batch = 32, save_interval = 100):
        for cnt in range(epochs):
            ## train discriminator
            random_index = np.random.randint(0, len(X_train) - np.int64(batch/2))
            legit_images = X_train[random_index : random_index + np.int64(batch/2)].reshape(np.int64(batch/2), self.width, self.height, self.channels)
            gen_noise = np.random.normal(0, 1, (np.int64(batch/
2), 100))
            syntetic_images = self.G.predict(gen_noise)
            x_combined_batch = np.concatenate((legit_images, syntetic_images))
            y_combined_batch = np.concatenate((np.ones((np.int64(batch/2), 1)), np.zeros((np.int64(batch/2), 1))))
            d_loss = self.D.train_on_batch(x_combined_batch, y_combined_batch)
            # train generator
            noise = np.random.normal(0, 1, (batch, 100))
            y_mislabled = np.ones((batch, 1))
            g_loss = self.stacked_generator_discriminator.train_on_batch(noise, y_mislabled)
            print ('epoch: %d, [Discriminator :: d_loss: %f], [ Generator :: loss: %f]' % (cnt, d_loss[0], g_loss))
            if cnt % save_interval == 0:
                self.plot_images(save2file=True, step=cnt)
    def plot_images(self, save2file=False, samples=16, step=0):
        ''' Plot and generated images '''
        if not os.path.exists("./images"):
            os.makedirs("./images")
        filename = "./images/mnist_%d.png" % step
        noise = np.random.normal(0, 1, (samples, 100))
        images = self.G.predict(noise)
        plt.figure(figsize=(10, 10))
        for i in range(images.shape[0]):
            plt.subplot(4, 4, i+1)
            image = images[i, :, :, :]
            image = np.reshape(image, [self.height, self.width])
            plt.imshow(image, cmap='gray')
            plt.axis('off')
        plt.tight_layout()
        if save2file:
            plt.savefig(filename)
            plt.close('all')
        else:
            plt.show()
if
 __name__ == '__main__':
    (X_train, _), (_, _) = mnist.load_data()
    # Rescale -1 to 1
    X_train = (X_train.astype(np.float32) - 127.5) / 127.5
    X_train = np.expand_dims(X_train, axis=3)
    gan = GAN()
    gan.train(X_train)