DCGAN - 理解代码的问题

问题描述 投票:0回答:1

这是Deconvolutional-Convoltional Generative Adversarial Network(DC-GAN)代码的一部分

discriminator.trainable = False
ganInput = Input(shape=(100,))
# getting the output of the generator
# and then feeding it to the discriminator
# new model = D(G(input))
x = generator(ganInput)
ganOutput = discriminator(x)
gan = Model(input=ganInput, output=ganOutput)
gan.compile(loss='binary_crossentropy', optimizer=Adam())

问题1 - 我不明白ganInput = Input(shape =(100,))行的作用。显然ganInput是一个变量,但什么是输入?这是一个功能吗?如果Input是一个函数,那么ganInput包含什么?

问题2 - Model API的作用是什么?我在keras文档中读到了但未能理解它在这里做了什么。

请询问您需要的任何进一步说明/细节。

带有TensorFlow后端的Keras完整的源代码:https://github.com/yashk2810/DCGAN-Keras/blob/master/DCGAN.ipynb

python-3.x tensorflow keras conv-neural-network
1个回答
2
投票

线ganInput = Input(shape=(100,))只是定义输入的形状,这是一个形状的张量(100,)

该模型将包括计算输出给定输入所需的所有层。对于多输入或多输出模型,您也可以使用列表:

model = Model(inputs=[ganInput1, ganInput2], outputs=[ganOutput1, ganOutput2, ganOutput3])

这意味着计算ganOutput1,ganOutput2,ganOutput3模型api需要输入层ganInput1,ganInput2

这对于回溯是必要的,因此Model api具有计算输出所需的内容

这一行加载mnist数据:(X_train, Y_train), (X_test, Y_test) = mnist.load_data() .... X_trainY_train有训练数据及其相应的目标值.... X_testY_test有训练数据及其相应的目标值

# ======================================================
# Here the data is being loaded 
# X_train = training data, Y_train = training targets 
# X_test = testing data , Y_test = testing targets 
# ======================================================
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()

# ================================================
# Reshaping the training and testing data
# He has added one extra dimension which is always one
# ================================================
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)


X_train = X_train.astype('float32')

# ================================================
# Initially pixel values are in range of 0-255
# he makes the pixel values to be between -1 to 1
#==================================================
X_train = (X_train - 127.5) / 127.5

X_train.shape

# ======================================================================
# He builds the generator model over here 
# 1] Dense layer with no of neurons = 128*7*7 & takes 100 numbers as input
# 2] Applying Batch Normalization
# 3] Upsampling layer
# 4] Convolution layer with activation LeakyRELU
# 5] Applying BatchNormalization
# 6] UpSampling2D layer
# 7] Convolution layer with activation LeakyRELU
# ======================================================================
generator = Sequential([
        Dense(128*7*7, input_dim=100, activation=LeakyReLU(0.2)),
        BatchNormalization(),
        Reshape((7,7,128)),
        UpSampling2D(),
        Convolution2D(64, 5, 5, border_mode='same', activation=LeakyReLU(0.2)),
        BatchNormalization(),
        UpSampling2D(),
        Convolution2D(1, 5, 5, border_mode='same', activation='tanh')
    ])

generator.summary()

# ======================================================================
# He builds the discriminator model over here 
# 1] Convolution layer which takes as input an image of shape (28, 28, 1)
# 2] Dropout layer
# 3] Convolution layer for down-sampling with LeakyReLU as activation
# 4] Dropout layer
# 5] Flatten layer to flatten the output
# 6] 1 output node with sigmoid activation
# ======================================================================
discriminator = Sequential([
        Convolution2D(64, 5, 5, subsample=(2,2), input_shape=(28,28,1), border_mode='same', activation=LeakyReLU(0.2)),
        Dropout(0.3),
        Convolution2D(128, 5, 5, subsample=(2,2), border_mode='same', activation=LeakyReLU(0.2)),
        Dropout(0.3),
        Flatten(),
        Dense(1, activation='sigmoid')
    ])

discriminator.summary()

generator.compile(loss='binary_crossentropy', optimizer=Adam())
discriminator.compile(loss='binary_crossentropy', optimizer=Adam())

discriminator.trainable = False

# =====================================================================
# Remember above generator takes 100 numbers as input in the first layer
# Dense(128*7*7, input_dim=100, activation=LeakyReLU(0.2))
# Input(shape=(100,)) returns a tensor of this shape (100,)
# ====================================================================
ganInput = Input(shape=(100,))
# getting the output of the generator
# and then feeding it to the discriminator
# new model = D(G(input))

# ===========================================================
# giving the input tensor of shape (100,) to generator model 
# ===========================================================
x = generator(ganInput)

# ===========================================================
# the output of generator will be of shape (batch_size, 28, 28, 1)  
# this output of generator will go to discriminator as input 
# Remember we have defined discriminator input as shape (28, 28, 1)
# ===========================================================
ganOutput = discriminator(x)

# =========================================================================
# Now it is clear that generators output is needed as input to discriminator
# You have to tell this to Model api for backpropogation
# Your Model api is the whole model you have built
# it tells you that your model is a combination of generator and discriminator model where that data flow is from generator to discriminator
# YOUR_Model = generator -> discriminator
# This is something like you want to train generator and discriminator as one single model and not as two different models
# but at the same time they are actually being trained individually (Hope this makes sense)
# =========================================================================
gan = Model(input=ganInput, output=ganOutput)
gan.compile(loss='binary_crossentropy', optimizer=Adam())
gan.summary()

def train(epoch=10, batch_size=128):
    batch_count = X_train.shape[0] // batch_size

    for i in range(epoch):
        for j in tqdm(range(batch_count)):
            # Input for the generator
            noise_input = np.random.rand(batch_size, 100)

            # getting random images from X_train of size=batch_size 
            # these are the real images that will be fed to the discriminator
            image_batch = X_train[np.random.randint(0, X_train.shape[0], size=batch_size)]

            # these are the predicted images from the generator
            predictions = generator.predict(noise_input, batch_size=batch_size)

            # the discriminator takes in the real images and the generated images
            X = np.concatenate([predictions, image_batch])

            # labels for the discriminator
            y_discriminator = [0]*batch_size + [1]*batch_size

            # Let's train the discriminator
            discriminator.trainable = True
            discriminator.train_on_batch(X, y_discriminator)

            # Let's train the generator
            noise_input = np.random.rand(batch_size, 100)
            y_generator = [1]*batch_size
            discriminator.trainable = False
            gan.train_on_batch(noise_input, y_generator)
© www.soinside.com 2019 - 2024. All rights reserved.