精彩å
容ä¸è¿·è·¯
åºå | 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)