GAN 网络在MINIST数据集上的简单运用

这篇博客介绍了如何使用TensorFlow构建生成对抗网络(GAN)。首先,导入了必要的库,如TensorFlow、Keras和NumPy。接着,加载MNIST数据集并进行预处理。然后,定义了生成器和判别器模型,以及相应的损失函数和优化器。训练过程中,通过训练步骤更新模型参数。虽然最终结果并不理想,但整个流程展示了GAN的基本构建和训练过程。
摘要由CSDN通过智能技术生成

温习了一下lab的内容

用的包

用的tensorflow

import tensorflow as tf
keras = tf.keras
layers = tf.keras.layers
# Include numpy for basic stuff
import numpy as np
# matplotlib allows us to visualise our data.
import matplotlib.pyplot as plt
# Import a library for displaying models
from IPython.display import Image

导入数据

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Print the shapes of the array and the unique label 
print(x_train.shape, y_train.shape, np.unique(y_test))
# Pick an example index
example_idx = 0
plt.imshow(x_train[example_idx,...],cmap='gray')
# Print the label
plt.show()

预处理数据

# Divide the image data to put it in the right range and convert to floating point numbers
x_train = x_train.astype("float32") / 255
# Preprocess the test data the same way
x_test = x_test.astype("float32") / 255

# Stick the data together
x_data = np.concatenate([x_train, x_test], axis=0)

# Reshape to (-1, im_height, im_width, 1)
x_data = np.reshape(x_data, (-1, 28, 28,1))

# We're not interested in the labels, but if we were...
# Convert the labels to floating point
y_train = y_train.astype("float32")
y_test = y_test.astype("float32")
y_data = np.concatenate([y_train, y_test], axis=0)

# Define the BATCH_SIZE as a variable as we need it later
BATCH_SIZE = 256
# Prepare the training dataset into batches and shuffle the examples
train_dataset = tf.data.Dataset.from_tensor_slices(x_data)
train_dataset = train_dataset.shuffle(buffer_size=10000).batch(BATCH_SIZE)

构建生成器

最初的图片大小为 [28 * 28] ,28+28=49,所以映射成 [7 * 7]

def make_generator(z_size=32, layer_sizes=[256, 128, 64]):
  """
  z_size specifies the latent variable dimension
  layer_sizes: is a list containing the number of channels at each stage in the generator
  """
  # Note that the Input size relates to the size of each instance
  inputs = keras.Input(shape=(z_size,), name="z")
  net = inputs

  # We first need to increase the size of our Tensor to reshape it into an image and
  # apply some convolutions. Let's map our z into a 7x7xlayers[0].  
  net = layers.Dense(7*7*layer_sizes[0],use_bias=False)(net)

  # The Dense lay produces a new vector, which we can reshape to look like an image.
  # Reshape to the right image size
  net = layers.Reshape((7,7,layer_sizes[0]))(net)

  # Apply batch normalisation followed by leaky relu (a slight variation on the relu activation function)
  net = layers.BatchNormalization(scale=False, center=False)(net)
  net = layers.LeakyReLU()(net)
  # Let's do our first convolution
  net = layers.Conv2D(layer_sizes[1], 5, padding='same', use_bias=False)(net)
  net = layers.BatchNormalization(scale=False, center=False)(net)
  net = layers.LeakyReLU()(net)

  # We want to grow the size of the image, let's do this by applying bilinear upsampling
  net = layers.UpSampling2D(size=(2,2))(net)

  # Followed by convolution, batch norm and relu again
  net = layers.Conv2D(layer_sizes[2], 5, padding='same', use_bias=False)(net)
  net = layers.BatchNormalization(scale=False, center=False)(net)
  net = layers.LeakyReLU()(net)

    # We want to grow the size of the image, let's do this by applying bilinear upsampling
  net = layers.UpSampling2D(size=(2,2))(net)

  # We do one final convolution to produce the final image (use a sigmoid to put the values in the correct range)
  net = layers.Conv2D(1, 5, padding='same', activation='sigmoid')(net)
  

  return keras.Model(inputs=inputs, outputs=net)

# Test the function works - but don't save the result yet
make_generator()

构建判别器

def make_discriminator(layer_sizes=[64, 128]):
  """
  layer_sizes: list containing the number of channels at each stage of the discriminator
  """
  # Note that the Input size relates to the size of each instance
  inputs = keras.Input(shape=(28,28,1), name="image")
  net = inputs

  # We can also define the layer object, and store it in a Python variable and call it later
  # We're more likely to want to do this for layers that contain model weights
  conv1 = layers.Conv2D(filters=layer_sizes[0], kernel_size=5, padding='same', strides=(2,2))
  net = conv1(net)
  # Dropout might help a bit
  #net = layers.Dropout(0.1)(net)
  net = layers.LeakyReLU()(net)

  conv2 = layers.Conv2D(filters=layer_sizes[1], kernel_size=5, padding='same', strides=(2,2))
  net = conv2(net)
  # Dropout might help a bit
  #net = layers.Dropout(0.1)(net)
  net = layers.LeakyReLU()(net)


  # We need to flatten the spatial dimensions before putting it through the dense layers
  net = layers.Flatten()(net)
  dense1 = layers.Dense(units=1)
  # Apply the dense layer
  net = dense1(net)

  return keras.Model(inputs=inputs, outputs=net)

make_discriminator()

构建模型

noise_dim = 64

generator = make_generator(z_size=noise_dim, layer_sizes=[256, 128, 64])

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

#plt.imshow(generated_image, cmap='gray')

# Print the output of the discriminator
discriminator = make_discriminator(layer_sizes=[64, 128])
print(discriminator(generated_image))
plt.imshow(generated_image[0, :, :, 0], cmap='gray')

定义模型损失

# This method returns a helper function to compute cross entropy loss
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True, label_smoothing=0.1)

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

def generator_loss(fake_output):
    return cross_entropy(tf.ones_like(fake_output), fake_output)

# Define the optimizers
generator_optimizer = tf.keras.optimizers.Adam(1e-4, beta_1=0.5)
discriminator_optimizer = tf.keras.optimizers.Adam(2e-4, beta_1=0.5)

定义训练step

# Notice the use of `tf.function`
# This annotation causes the function to be "compiled". Making it faster to call thereafter
@tf.function
def train_step(images):
    noise = tf.random.normal([BATCH_SIZE, noise_dim])
    # Create a pair of gradient tapes
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
      # Generate some fake data from the noise input
      generated_images = generator(noise, training=True)
      # Call the discriminator on the real images
      real_output = discriminator(images, training=True)
      # Call the discriminator on the generated images
      fake_output = discriminator(generated_images, training=True)
      # Calculate the losses
      gen_loss = generator_loss(fake_output)
      disc_loss = discriminator_loss(real_output, fake_output)
    # Calculate the gradient of the losses for the right variables
    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
    gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
    # Update the model variables
    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
    discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))
    # Return the losses
    return gen_loss, disc_loss

开始训练

def train(dataset, epochs):
  for epoch in range(epochs):

    for idx, image_batch in enumerate(dataset):
      losses = train_step(image_batch)
      # Every N btaches, print the losses of that batch and draw some example images
      if idx % 10 == 0:
        print(losses)
        noise = tf.random.normal([3, noise_dim])
        generated_image = generator(noise, training=False)
        plt.subplot(131)
        plt.imshow(generated_image[0, :, :, 0], cmap='gray')
        plt.subplot(132)
        plt.imshow(generated_image[1, :, :, 0], cmap='gray')
        plt.subplot(133)
        plt.imshow(generated_image[2, :, :, 0], cmap='gray')
        plt.show()

# 
train(train_dataset, 30)

运行结果

并不是很理想
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值