CGAN生成MNIST数字

有关CGAN原理可以参考下面几篇博客

点击打开链接

点击打开链接

点击打开链接

CGAN代码

import matplotlib.pyplot as plt
import numpy as np
import os
from six.moves import xrange  
import pickle
import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

if not os.path.exists("logdir"):
    os.makedirs("logdir")
    
LOGDIR = "logdir" 
real_img_size = mnist.train.images[0].shape[0]
noise_size = 100
noise = 'normal0-1'
alpha = 0.1
learning_rate = 0.001
smooth = 0.05
# train
batch_size = 100
k = 10
epochs = 120

def leakyRelu(x, alpha=0.01):  
    return tf.maximum(x, alpha * x) 

def get_inputs(real_img_size, noise_size):
    real_img = tf.placeholder(tf.float32,
        shape = [None, real_img_size], name = "real_img")

    real_img_digit = tf.placeholder(tf.float32, shape = [None, k])

    noise_img = tf.placeholder(tf.float32,
        shape = [None, noise_size], name = "noise_img")

    return real_img, noise_img, real_img_digit

def fully_connected(name, value, output_shape):  
    with tf.variable_scope(name, reuse=None) as scope:  
        shape = value.get_shape().as_list()  
        w = tf.get_variable('w', [shape[1], output_shape], dtype=tf.float32,  
                                    initializer=tf.random_normal_initializer(stddev=0.01))  
        b = tf.get_variable('b', [output_shape], dtype=tf.float32, initializer=tf.constant_initializer(0.0))  
   
        return tf.matmul(value, w) + b 
    
def get_noise(noise,batch_size):
    if noise == 'uniform':
        batch_noise = np.random.uniform(-1, 1, size=(batch_size, noise_size))
    elif noise == 'normal':
        batch_noise = np.random.normal(-1, 1, size=(batch_size, noise_size))
    elif noise == 'normal0-1':
        batch_noise = np.random.normal(0, 1, size=(batch_size, noise_size))
    elif noise == 'uniform0-1':
        batch_noise = np.random.normal(0, 1, size=(batch_size, noise_size))
        
    return batch_noise

def get_generator(digit, noise_img,  reuse = False):
    with tf.variable_scope("generator", reuse = reuse):
        concatenated_img_digit = tf.concat([digit, noise_img], 1)
        
#         output = tf.layers.dense(concatenated_img_digit, 256)

        output = fully_connected('gf1',concatenated_img_digit,128)
        output = leakyRelu(output)
        output = tf.layers.dropout(output, rate = 0.5)
        
#         output = tf.layers.dense(output, 128)

        output = fully_connected('gf2',output, 128)
        output = leakyRelu(output)
        output = tf.layers.dropout(output, rate = 0.5)

#         logits = tf.layers.dense(output, 784)
        logits = fully_connected('gf3',output,784)
        outputs = tf.tanh(logits)
        
        return logits, outputs


def get_discriminator(digit, img,  reuse = False):
    with tf.variable_scope("discriminator", reuse=reuse):
        concatenated_img_digit = tf.concat([digit, img], 1)
        
#         output = tf.layers.dense(concatenated_img_digit, 256)
        output = fully_connected('df1',concatenated_img_digit,128)
        output = leakyRelu(output)
        output = tf.layers.dropout(output, rate = 0.5)
        
#         output = tf.layers.dense(concatenated_img_digit, 128)
        output = fully_connected('df2',output, 128)
        output = leakyRelu(output)
        output = tf.layers.dropout(output, rate = 0.5)

#         logits = tf.layers.dense(output, 1)
        logits = fully_connected('df3',output, 1)
        outputs = tf.sigmoid(logits)
        
        return logits, outputs

def save_genImages(gen, epoch):  
    r,c = 10,10  
    fig,axs = plt.subplots(r,c)  
    cnt = 0  
    print(gen.shape)
    for i in range(r):  
        for j in range(c):  
            axs[i,j].imshow(gen[cnt][:,:],cmap='Greys_r') 
            axs[i,j].axis('off')  
            cnt += 1
    if not os.path.exists('gen_mnist1'):  
        os.makedirs('gen_mnist1')  
    fig.savefig('gen_mnist1/%d.jpg' % epoch)  
    plt.close() 
    
def plot_loss(loss):  
    fig,ax = plt.subplots(figsize=(20,7))  
    losses = np.array(loss)  
    plt.plot(losses.T[0], label="Discriminator Loss")  
    plt.plot(losses.T[1],label="Discriminator_real_loss")
    plt.plot(losses.T[2],label="Discriminator_fake_loss")
    plt.plot(losses.T[3], label="Generator Loss")  
    plt.title("Training Losses")  
    plt.legend()  
    plt.savefig('loss1.jpg')  
    plt.show() 
    
def Save_lossValue(e,epochs,train_loss_d,train_loss_d_real,train_loss_d_fake,train_loss_g):  
    with open('loss1.txt','a') as f:  
        f.write("Epoch {}/{}".format(e+1, epochs),
                "Discriminator loss: {:.4f}(Real: {:.4f} + Fake: {:.4f})".format(
                    train_loss_d, train_loss_d_real, train_loss_d_fake),
                "Generator loss: {:.4f}".format(train_loss_g))
    
tf.reset_default_graph()

real_img, noise_img, real_img_digit = get_inputs(real_img_size, noise_size)

# generator
g_logits, g_outputs = get_generator(real_img_digit, noise_img)

sample_images = tf.reshape(g_outputs, [-1, 28, 28, 1])
tf.summary.image("sample_images", sample_images, 10)

# discriminator
d_logits_real, d_outputs_real = get_discriminator(real_img_digit, real_img)
d_logits_fake, d_outputs_fake = get_discriminator(real_img_digit, g_outputs, reuse = True)


# discriminator loss
d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = d_logits_real, 
                                                                         labels = tf.ones_like(d_logits_real)) * (1 - smooth))
d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = d_logits_fake, 
                                                                         labels = tf.zeros_like(d_logits_fake)))
# loss
d_loss = tf.add(d_loss_real, d_loss_fake)
# generator loss
g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits = d_logits_fake,
                                                                    labels = tf.ones_like(d_logits_fake)) * (1 - smooth) )

tf.summary.scalar("d_loss_real", d_loss_real)
tf.summary.scalar("d_loss_fake", d_loss_fake)
tf.summary.scalar("d_loss", d_loss)
tf.summary.scalar("g_loss", g_loss)

# optimizer
train_vars = tf.trainable_variables()

# generator tensor
g_vars = [var for var in train_vars if var.name.startswith("generator")]
# discriminator tensor
d_vars = [var for var in train_vars if var.name.startswith("discriminator")]

# optimizer
d_train_opt = tf.train.AdamOptimizer(learning_rate).minimize(d_loss, var_list=d_vars)
g_train_opt = tf.train.AdamOptimizer(learning_rate).minimize(g_loss, var_list=g_vars)

summary = tf.summary.merge_all()

saver = tf.train.Saver()
def train():
    #保存loss值
    losses = []
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())

        summary_writer = tf.summary.FileWriter(LOGDIR, sess.graph)
    
        # Run the Op to initialize the variables.
        for e in xrange(epochs):
            for i in xrange(mnist.train.num_examples//(batch_size * k)):
                for j in xrange(k):
                    batch = mnist.train.next_batch(batch_size)
      
                    digits = batch[1]
      
                    # scale the input images
                    images = batch[0].reshape((batch_size, 784))
                    images = 2 * images - 1 #生成器激活函数tanh,(-1~1),把原始图像(0~1)也变为(-1~1)
      
                    # generator input noises
                    noises = get_noise(noise, batch_size)
      
                    # Run optimizer
                    sess.run([d_train_opt, g_train_opt],
                        feed_dict = {real_img: images, noise_img: noises, real_img_digit: digits})
              
            # train loss
    #         images = 2 * mnist.train.images - 1.0
    #         noises = get_sample([mnist.train.num_examples, noise_size])
    #         digits = mnist.train.labels
      
            summary_str, train_loss_d_real, train_loss_d_fake, train_loss_g = \
                sess.run([summary, d_loss_real, d_loss_fake, g_loss],
                feed_dict = {real_img: images, noise_img: noises, real_img_digit: digits})
                
            train_loss_d = train_loss_d_real + train_loss_d_fake
            losses.append((train_loss_d,train_loss_d_real,train_loss_d_fake,train_loss_g))
            
            summary_writer.add_summary(summary_str, e)
            summary_writer.flush()
           
            print("Epoch {}/{}".format(e+1, epochs),
                "Discriminator loss: {:.4f}(Real: {:.4f} + Fake: {:.4f})".format(
                    train_loss_d, train_loss_d_real, train_loss_d_fake),
                "Generator loss: {:.4f}".format(train_loss_g))
            
            #保存模型
            saver.save(sess, 'checkpoints/cgan.ckpt')
            
            #查看每轮结果
            gen_sample = get_noise(noise, batch_size)
            label = [0,0,0,0,0,0,0,0,1,0] * 100 #给定标签条件生成制定的数字
            labels = np.array(label)
            labels = labels.reshape(-1,10)
            _,gen = sess.run(get_generator(real_img_digit, noise_img, reuse=True),
                             feed_dict = {noise_img:gen_sample,real_img_digit:labels})
            if e % 1== 0:
                gen = gen.reshape(-1,28,28)
                gen = (gen + 1)/2
                save_genImages(gen, e)
        plot_loss(losses)
        
#加载保存的模型
def test():
    saver = tf.train.Saver(var_list=g_vars)
    with tf.Session() as sess:
#         saver.restore(sess,tf.train.latest_checkpoint("checkpoints"))
        saver.restore(sess,'checkpoints/cgan.ckpt')
        sample_noise = get_noise(noise, batch_size)
        label = [0,0,0,0,0,0,0,0,0,1] * 100
        labels = np.array(label)
        labels = labels.reshape(-1,10)
        _,gen_samples = sess.run(get_generator(real_img_digit, noise_img, reuse=True),feed_dict={noise_img:sample_noise,real_img_digit:labels})
        for i in range(len(gen_samples)):
            plt.imshow(gen_samples[i].reshape(28,28),cmap='Greys_r')
            plt.show()

if __name__ == '__main__':
#     train()
    test()

tensorboard可视化,将log文件拷贝到D盘

cmd 

D:

tensorboard --logdir=D:\logdir

 http://G9BM865Z33FR0W7:6006粘贴到谷歌浏览器

可视化图


loss曲线


  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用Jittor训练CGAN模型生成手写数字的代码示例: ```python import jittor as jt from jittor import nn from jittor import Dataset from jittor import transform import jittor.random as random import numpy as np class MNIST(Dataset): def __init__(self, train=True, transform=None): self.train = train self.transform = transform if self.train: self.images = np.load("train_images.npy") self.labels = np.load("train_labels.npy") else: self.images = np.load("test_images.npy") self.labels = np.load("test_labels.npy") def __getitem__(self, index): img = self.images[index].astype('float32') / 255.0 label = self.labels[index] if self.transform is not None: img = self.transform(img) return img, label def __len__(self): return len(self.images) class Generator(nn.Module): def __init__(self, latent_dim=100, img_shape=(1, 28, 28)): super(Generator, self).__init__() self.img_shape = img_shape self.model = nn.Sequential( nn.Linear(latent_dim, 128), nn.ReLU(), nn.Linear(128, 256), nn.BatchNorm1d(256, 0.8), nn.ReLU(), nn.Linear(256, 512), nn.BatchNorm1d(512, 0.8), nn.ReLU(), nn.Linear(512, 1024), nn.BatchNorm1d(1024, 0.8), nn.ReLU(), nn.Linear(1024, int(np.prod(img_shape))), nn.Tanh() ) def execute(self, z): img = self.model(z) img = img.reshape((img.shape[0],) + self.img_shape) return img class Discriminator(nn.Module): def __init__(self, img_shape=(1, 28, 28)): super(Discriminator, self).__init__() self.img_shape = img_shape self.model = nn.Sequential( nn.Linear(int(np.prod(img_shape)), 512), nn.LeakyReLU(0.2), nn.Linear(512, 256), nn.LeakyReLU(0.2), nn.Linear(256, 1), nn.Sigmoid(), ) def execute(self, img): img_flat = img.flatten(1) validity = self.model(img_flat) return validity # 定义超参数 latent_dim = 100 img_shape = (1, 28, 28) lr = 0.0002 b1 = 0.5 b2 = 0.999 batch_size = 64 n_epochs = 200 # 定义数据集和数据转换 transform = transform.Compose([ transform.Resize(28), transform.ImageNormalize(mean=0.5, std=0.5), ]) train_dataset = MNIST(train=True, transform=transform) train_loader = jt.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True) # 定义生成器和判别器 generator = Generator(latent_dim=latent_dim, img_shape=img_shape) discriminator = Discriminator(img_shape=img_shape) # 定义损失函数和优化器 adversarial_loss = nn.BCELoss() optimizer_G = nn.Adam(generator.parameters(), lr=lr, betas=(b1, b2)) optimizer_D = nn.Adam(discriminator.parameters(), lr=lr, betas=(b1, b2)) # 训练CGAN模型 for epoch in range(n_epochs): for i, (imgs, _) in enumerate(train_loader): # 训练判别器 optimizer_D.zero_grad() real_imgs = jt.array(imgs) z = jt.array(random.normal((imgs.shape[0], latent_dim))) fake_imgs = generator(z) real_labels = jt.ones((batch_size, 1)) fake_labels = jt.zeros((batch_size, 1)) d_loss_real = adversarial_loss(discriminator(real_imgs), real_labels) d_loss_fake = adversarial_loss(discriminator(fake_imgs), fake_labels) d_loss = (d_loss_real + d_loss_fake) / 2.0 d_loss.backward() optimizer_D.step() # 训练生成器 optimizer_G.zero_grad() z = jt.array(random.normal((imgs.shape[0], latent_dim))) fake_imgs = generator(z) g_loss = adversarial_loss(discriminator(fake_imgs), real_labels) g_loss.backward() optimizer_G.step() # 输出训练信息 batches_done = epoch * len(train_loader) + i if batches_done % 400 == 0: print( f"[Epoch {epoch}/{n_epochs}] [Batch {i}/{len(train_loader)}] [D loss: {d_loss.item()}] [G loss: {g_loss.item()}]" ) ``` 在上述代码中,我们定义了MNIST数据集类和它的数据转换,生成器和判别器模型,以及损失函数和优化器。在训练循环中,我们依次训练判别器和生成器,并输出训练信息。运行以上代码,训练200个epoch后,我们可以得到生成生成的手写数字图片。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值