DCGAN的基本实现示例-手写数字识别

DCGAN基本示例-手写数字识别

DCGAN原理分析

什么是DCGAN?
DCGAN就是将CNN和原始的GAN结合到了一起,生成模型和判别模型都运用了深度卷积神经网络的生成对抗网络。

模型结构图:
模型结构图

代码实现

import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tensorflow import keras
from sklearn.preprocessing import MinMaxScaler
import os

# 载入数据
(x_train_all, y_train_all), (_, _) = keras.datasets.mnist.load_data()

# 切分数据集
x_train, x_valid = x_train_all[5000:], x_train_all[:5000]
y_train, y_valid = y_train_all[5000:], y_train_all[:5000]

# 归一化处理
scaler = MinMaxScaler()
x_train_scaled = scaler.fit_transform(x_train.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)
# print(x_train_scaled.shape)

# 封装数据集
train_datasets = tf.data.Dataset.from_tensor_slices(x_train_scaled)
train_datasets = train_datasets.shuffle(x_train_scaled.shape[0]).batch(128)


# print(train_datasets)

# 建立模型
def generator_model():
    model = keras.Sequential()
    model.add(keras.layers.Dense(7 * 7 * 256, input_shape=(100,), use_bias=False))
    model.add(keras.layers.BatchNormalization())
    model.add(keras.layers.LeakyReLU())

    model.add(keras.layers.Reshape((7, 7, 256)))

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

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

    model.add(keras.layers.Conv2DTranspose(1, 5, strides=(2, 2), use_bias=False, padding='same'))

    return model


generator = generator_model()


# 定义判别器模型
def discrimintator_model():
    model = keras.Sequential()
    model.add(keras.layers.Conv2D(64, 5, strides=(2, 2), padding='same', input_shape=([28, 28, 1])))
    model.add(keras.layers.LeakyReLU())
    model.add(keras.layers.Dropout(0.3))

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

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

    return model


discrimintator = discrimintator_model()
# print(discrimintator.summary())

# 定义损失函数
cross_entropy = tf.losses.BinaryCrossentropy(from_logits=True)


# 定义判别器损失函数
def discriminator_loss(real_output, fake_output):
    return cross_entropy(tf.ones_like(real_output), real_output) + cross_entropy(tf.zeros_like(fake_output),
                                                                                 fake_output)


# 定义生成器损失
def generator_loss(fake_output):
    return cross_entropy(tf.ones_like(fake_output), fake_output)


# 定义优化器
generator_optimizer = tf.keras.optimizers.Adam(1e-5)
discrimintator_optimizer = tf.keras.optimizers.Adam(1e-5)

BATCHS = 128
EPOCHS = 50

num_example_to_generate = 16
noise_dim = 100

seed = tf.random.normal([num_example_to_generate, noise_dim])


# 迭代训练
@tf.function
def train_step(images):
    noise = tf.random.normal([num_example_to_generate, noise_dim])
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        gen_images = generator(noise, training=True)

        real_output = discrimintator(images, training=True)
        fake_output = discrimintator(gen_images, training=True)

        # 求损失
        gen_loss = generator_loss(fake_output)
        disc_loss = discriminator_loss(real_output, fake_output)

    # 根据损失求梯度
    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
    gradients_of_disciminator = disc_tape.gradient(disc_loss, discrimintator.trainable_variables)

    # 进行梯度优化
    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
    discrimintator_optimizer.apply_gradients(zip(gradients_of_disciminator, discrimintator.trainable_variables))


def showImg(generator_model, epoch, noise):
    pred = generator_model(noise)
    plt.figure(figsize=(4, 4))

    for i in range(pred.shape[0]):
        plt.subplot(4, 4, i + 1)
        plt.imshow(pred[i].numpy().reshape(28, 28), cmap='gray')
        plt.axis('off')

    plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
    plt.show()


def train(traindatasets, epochs):
    for epoch in range(epochs):
        for image_batch in traindatasets:
            train_step(image_batch)
            print('.', end='')
        print()

        showImg(generator, epoch + 1, seed)

    showImg(generator, epochs, seed)


train(train_datasets, EPOCHS)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用Tensorflow实现DCGAN生成手写数字的详细代码: 首先,我们需要导入必要的库和数据集。这里我们使用Tensorflow自带的MNIST数据集。 ```python import tensorflow as tf import numpy as np import matplotlib.pyplot as plt from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("MNIST_data/") ``` 接下来,我们定义生成器和判别器的网络结构。生成器的输入是一个随机噪声,输出是一张28x28的手写数字图片。判别器的输入是一张28x28的手写数字图片,输出是一个判别得分,表示这张图片是真实图片的概率。 ```python def generator(z, reuse=None): with tf.variable_scope('gen', reuse=reuse): hidden1 = tf.layers.dense(inputs=z, units=128, activation=tf.nn.leaky_relu) hidden2 = tf.layers.dense(inputs=hidden1, units=256, activation=tf.nn.leaky_relu) output = tf.layers.dense(inputs=hidden2, units=784, activation=tf.nn.tanh) return output def discriminator(X, reuse=None): with tf.variable_scope('dis', reuse=reuse): hidden1 = tf.layers.dense(inputs=X, units=128, activation=tf.nn.leaky_relu) hidden2 = tf.layers.dense(inputs=hidden1, units=256, activation=tf.nn.leaky_relu) logits = tf.layers.dense(inputs=hidden2, units=1) output = tf.sigmoid(logits) return output, logits ``` 然后,我们定义生成器和判别器的输入和损失函数。其中,生成器的损失函数是生成的假图片与真实图片的差异,判别器的损失函数是真实图片和假图片的区分度。 ```python real_images = tf.placeholder(tf.float32, shape=[None, 784]) z = tf.placeholder(tf.float32, shape=[None, 100]) G = generator(z) D_output_real, D_logits_real = discriminator(real_images) D_output_fake, D_logits_fake = discriminator(G, reuse=True) def loss_func(logits_in, labels_in): return tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits_in, labels=labels_in)) D_real_loss = loss_func(D_logits_real, tf.ones_like(D_logits_real) * 0.9) D_fake_loss = loss_func(D_logits_fake, tf.zeros_like(D_logits_fake)) D_loss = D_real_loss + D_fake_loss G_loss = loss_func(D_logits_fake, tf.ones_like(D_logits_fake)) ``` 接下来,我们定义生成器和判别器的优化器,并且训练模型。 ```python lr = 0.001 tvars = tf.trainable_variables() d_vars = [var for var in tvars if 'dis' in var.name] g_vars = [var for var in tvars if 'gen' in var.name] D_trainer = tf.train.AdamOptimizer(lr).minimize(D_loss, var_list=d_vars) G_trainer = tf.train.AdamOptimizer(lr).minimize(G_loss, var_list=g_vars) batch_size = 100 epochs = 100 init = tf.global_variables_initializer() samples = [] with tf.Session() as sess: sess.run(init) for epoch in range(epochs): num_batches = mnist.train.num_examples // batch_size for i in range(num_batches): batch = mnist.train.next_batch(batch_size) batch_images = batch[0].reshape((batch_size, 784)) batch_images = batch_images * 2 - 1 batch_z = np.random.uniform(-1, 1, size=(batch_size, 100)) _ = sess.run(D_trainer, feed_dict={real_images: batch_images, z: batch_z}) _ = sess.run(G_trainer, feed_dict={z: batch_z}) print("Epoch:", epoch) sample_z = np.random.uniform(-1, 1, size=(1, 100)) gen_sample = sess.run(generator(z, reuse=True),feed_dict={z: sample_z}) samples.append(gen_sample) plt.imshow(samples[0].reshape(28,28)) plt.show() ``` 最后,我们可以看到生成的手写数字图片。随着训练的迭代次数增加,生成的图片会越来越真实。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值