使用预训练卷积网络作为GAN鉴别器

时间:2019-09-17 08:54:48

标签: python tensorflow keras gan

我已经从TF2.0文档中提取了一些代码来从自定义数据集中生成图像。代码是here

由于文档使用Keras,因此我认为我可能会将区分器网络更改为预训练的网络(例如InceptionV3),并且仅训练顶层。我找到了this代码(在一组新的类上微调了InceptionV3)。我似乎无法弄清楚如何用另一个替换一个。我了解我正在尝试用功能性API替换顺序模式。但是我想它们之间是相互联系的。但是,我并不是Keras的频繁用户。

我的问题是:如何将顺序模式下的自定义CNN替换为来自Functional API的经过预训练的CNN,以用作鉴别器?

编辑:如果有人有使用GANEstimator代替它做事的例子,我会很高兴,因为我更习惯于TF。

使用生成器生成随机图像

def make_generator_model():
    model = tf.keras.Sequential()
    model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Reshape((7, 7, 256)))
    assert model.output_shape == (None, 7, 7, 256) # Note: None is the batch size

    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
    assert model.output_shape == (None, 7, 7, 128)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
    assert model.output_shape == (None, 14, 14, 64)
    model.add(layers.BatchNormalization())
    model.add(layers.LeakyReLU())

    model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
    assert model.output_shape == (None, 28, 28, 3)

    return model

generator = make_generator_model()
noise = tf.random.normal([1, 100])
generated_image = generator(noise, training=False)

当前的鉴别器和辅助器(输出tf.Tensor([[-0.0003378]],shape =(1,1),dtype = float32))

def make_discriminator_model():
    model = tf.keras.Sequential()
    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
                                     input_shape=[28, 28, 1]))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))

    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
    model.add(layers.LeakyReLU())
    model.add(layers.Dropout(0.3))

    model.add(layers.Flatten())
    model.add(layers.Dense(1))

    return model

cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

def discriminator_loss(real_output, fake_output):
    real_loss = cross_entropy(tf.ones_like(real_output), real_output)
    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
    total_loss = real_loss + fake_loss
    return total_loss

discriminator = make_discriminator_model()
decision = discriminator(generated_image)
print (decision)

所需的区分符

def make_discriminator_model():
    # create the base pre-trained model
    model = InceptionV3(weights='imagenet', include_top=False)

    # ADD TOP LAYERS

    # FREEZE ALL LAYERS EXCEPT TOP LAYERS

    return model

# COMPILE

def discriminator_loss(real_output, fake_output):
    real_loss = ??? # Real Loss
    fake_loss = ??? # Fake loss
    total_loss = real_loss + fake_loss
    return total_loss

noise = tf.random.normal([1, 100])
generated_image = generator(noise, training=False)

discriminator = make_discriminator_model()
decision = discriminator(generated_image)
print (decision)

所有进口

  from __future__ import absolute_import, division, print_function, unicode_literals

try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass
import tensorflow as tf
print('TF version: {}'.format(tf.__version__))

import glob
import imageio
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
from PIL import Image
from tensorflow.keras import layers
import time

from IPython import display
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications import vgg16
import os.path
from tensorflow.keras.applications.inception_v3 import InceptionV3
from tensorflow.keras.preprocessing import image
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras import backend as K

编辑: 这就是我最终的鉴别力!感谢@pandrey

def make_discriminator_model():
    pre_trained = tf.keras.applications.InceptionV3(
        weights='imagenet', include_top=False, input_shape=IMG_SHAPE
    )
    pre_trained.trainable = False  # mark all weights as non-trainable
    model = tf.keras.Sequential([pre_trained])
    model.add(layers.GlobalAveragePooling2D())
    model.add(layers.Dense(1))   
    return model

1 个答案:

答案 0 :(得分:0)

这是实现部分预训练并冻结的模型的一种方法:

# Load the pre-trained model and freeze it.
pre_trained = tf.keras.applications.InceptionV3(
    weights='imagenet', include_top=False
)
pre_trained.trainable = False  # mark all weights as non-trainable
# Define a Sequential model, adding trainable layers on top of the previous.
model = tf.keras.Sequential([pre_trained])
# ADD TOP LAYERS HERE, just as you would in your example code
# You can check that the proper parameters are frozen or learnable with:
model.summary()

与您作为示例给出的函数相比,我认为您不需要更改损失函数。