sábado, 22 de mayo de 2021

GANs Convolucionales profundas DCGAN

Las características principales de las GANs convolucionales profundas son las siguientes:

Reemplazan cualquier capa de agrupación con convoluciones de paso (en el discriminador) y convoluciones traspuestas (en el generador)

Utilizan Normalización Batch en el generador y en el discriminador, excepto en la capa de salida del generador y en la capa de entrada del discriminador.

Elimina todas las capas ocultas completamente conectadas para arquitecturas más profundas.

Utiliza activación ReLU en el generador para todas las capas excepto la capa de salida la cual debe utilizar tanh.

Utiliza activación leaky ReLU en todas las capas del discriminador.

Estas características se utilizan en muchos casos, pero no siempre. Debemos poder experimentar con diferentes hiperparámetros, cambindo la semilla aleatoria y probando el modelo una y otra vez.

El siguiente ejemplo de DCGAN funciona razonablemente bien con eldataset de moda MNIST.

tf.random.set_seed(42)

np.random.seed(42)

codings_size = 100

generator = keras.models.Sequential([

    keras.layers.Dense(7 * 7 * 128, input_shape=[codings_size]),

    keras.layers.Reshape([7, 7, 128]),

    keras.layers.BatchNormalization(),

    keras.layers.Conv2DTranspose(64, kernel_size=5, strides=2, padding="SAME",

                                 activation="selu"),

    keras.layers.BatchNormalization(),

    keras.layers.Conv2DTranspose(1, kernel_size=5, strides=2, padding="SAME",

                                 activation="tanh"),

])

discriminator = keras.models.Sequential([

    keras.layers.Conv2D(64, kernel_size=5, strides=2, padding="SAME",

                        activation=keras.layers.LeakyReLU(0.2),

                        input_shape=[28, 28, 1]),

    keras.layers.Dropout(0.4),

    keras.layers.Conv2D(128, kernel_size=5, strides=2, padding="SAME",

                        activation=keras.layers.LeakyReLU(0.2)),

    keras.layers.Dropout(0.4),

    keras.layers.Flatten(),

    keras.layers.Dense(1, activation="sigmoid")

])

gan = keras.models.Sequential([generator, discriminator])

El generador toma codificaciones (codings) de tamaño 100 y las proyecta a 6272 dimensiones 7*7*28 y cambia la forma del resultado a un tensor de 7x7x128. Este tensor utiliza normalización por lotes y alimenta a una capa convolucional traspuesta con un paso de 2, la cual ensancha las muestras de 7x7  a 14x14 y reduce su profundidad de 128 a 64. El resultado se normaliza por lotes de nuevo y alimenta otr capa convolucional traspuesta con un paso de 2 la cual se ensancha de nuevo de 14x14 a 28x28 y reduce su profundidad de 64 a 1 esta capa utiliza la función de activación tanh con salidas en el rango -1 a 1 por esta razón antes de entrenar la GAN necesitamos reescalar el set de entrenamiento y ponerlo en el mismo rango. También necesitamos cambiarle la forma para añadirle un canal de dimensión.

discriminator.compile(loss="binary_crossentropy", optimizer="rmsprop")

discriminator.trainable = False

gan.compile(loss="binary_crossentropy", optimizer="rmsprop")

X_train_dcgan = X_train.reshape(-1, 28, 28, 1) * 2. - 1. # cambia la forma y la escala

El discriminador se parece mucho a una CNN regular para clasificación binaria pero en vez de utilizar capas de agrupación max para reducir la muestra de la imagen usa convoluciones de paso 2. Hay que notar también que utiliza la función de activación Leaky ReLU.

Respecto a las líneas marcadas al principio para las DCGAN hemos sustituido las capas de normalización por lotas por capas de Dropout en el discriminador y se ha reemplazado ReLU por SELU en el generador. Hay que sentirse libre para cambiar la arquitectura especialmente los relativos a las tasas de aprendizaje de ambas redes neuronales.

Finalmente construimos el dataset, entrenamos y compilamos el modelo.

batch_size = 32

dataset = tf.data.Dataset.from_tensor_slices(X_train_dcgan)

dataset = dataset.shuffle(1000)

dataset = dataset.batch(batch_size, drop_remainder=True).prefetch(1)

train_gan(gan, dataset, batch_size, codings_size)

tf.random.set_seed(42)

np.random.seed(42)

noise = tf.random.normal(shape=[batch_size, codings_size])

generated_images = generator(noise)

plot_multiple_images(generated_images, 8)

save_fig("dcgan_generated_images_plot", tight_layout=False)

Después de 50 épocas el modelo será capaz de genera imágenes como las de abajo.

GANs Convolucionales profundas DCGAN


 Traducido del capítulo 17 de “Hands-On Machine Learning with Scikit-Learn, Keras and Tensorflow, 2nd Edition by Aurelien Géron (O’Reilly). Copyright 2019 Kiwisoft S.A.S., 978-1-492-03264-9”


No hay comentarios:

Publicar un comentario