最原始的GAN-我开始慢慢的懂GAN了

参考一篇非常全面的博文(传送门),把最原始的GAN网络过了一遍,虽然还是心中有疑虑,还是有问题,但是好事多磨,总会想明白的。

自己想不懂的问题:

1.在训练网络(generator)中,它是怎么生成一个虚假图片的?

build_generator()这个函数就是一个全连接网络,都说generator就是来生成一个虚假图片的,但是最后build_generator返回不是一个造好的虚假图片啊!

在代码部分:

  noise= np.random.normal(0,1, (batch_size, 100))
  fake_images = generator.predict(noise)

由np.random.normal函数,生成正态分布的数据。将数据传入predict函数,为输入样本生成输出预测,预测的 Numpy 数组(或数组列表)。

这个地方的fake_images,我在程序中输出看了一下,图片信息看不懂。

所以很困惑,generator生成的虚假图片,是个什么样子的?我们给出的数据集是手写数据集,生成的虚假图片不应该是数字吗?

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

哈哈!我看懂啦!

1. fake_images的维度是(128,784)的,生成的图像是叠加在一起的,这就是我为什么看不懂生成的图片是个什么东西,因为我输出的维度不对,128是128张图片,784是28*28。(128,784)整体理解为,输出了128张28*28的图片。下面我就开始调整我输出的图像的维度了。

2.我把bach_size设置为1,这样输出的fake_images的维度就是(1,784),然后我再把生成的图片的维度转换一下,把一维的784,转换为二维的28*28

将图片转换维度后,就生成了上面的图片,这个图片就是生成器生成的图片。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.real_images = X_train[np.random.randint(0, X_train.shape[0], batch_size)]

这个是真实图像,X_train的维度是(60000,784)。np.random.randint(low,high,size,dtype)生成一个128维的行向量,行向量的数字范围是0-60000

输出的真实图像的维度是(128, 784);而且真实图像也是我所看不懂的。

为什么是这个样子的呢?

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

解答:

1.首先,生成的real_images图片的维度是错误的,一开始的batch_size的大小是128,所以生成的real_images的维度是(128,784)。

现在,我把batch_size的大小设置为了1,维度大小为(1.784),即生成了1张一维的图片,我把一维的784转换为二维的28*28

这样就能显示出来,从训练集中选出的真实图片里的数字是多少了

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3.GAN.train_on_batch(noise, label_real)

这个地方的代码是在生成训练网络,让鉴别网络停止训练

向网络中输入一堆噪声,期待的输出是将假图片预测为真。

我所理解:生成的假的图片,将假的图片预测为真了,说明生成假图片的能力提升了,下面该提升的就是鉴别能力了。

生成了虚假图片和真实图片之后,还生成了图片的标签,将图片和标签一起放进鉴别器里去鉴别,来提高鉴别器的鉴别能力。

再之后是鉴别器停止训练,训练生成器, 生成的假的图片,将假的图片预测为真了,说明生成假图片的能力提升了,下面该提升的就是鉴别能力了。

# -*- coding: utf-8 -*-
"""
Created on Sat May 22 15:40:12 2021

@author: LiMeng
"""

from keras.datasets import mnist
from keras.layers import Dense, Dropout, Input
from keras.models import Model,Sequential
from keras.layers.advanced_activations import LeakyReLU
from keras.optimizers import Adam
from tqdm import tqdm
import numpy as np
import matplotlib.pyplot as plt
#%matplotlib inline
#from google.colab import drive

# Load the dataset
def load_data():
  (x_train, y_train), (_, _) = mnist.load_data()
  x_train = (x_train.astype(np.float32) - 127.5)/127.5
  
  # Convert shape from (60000, 28, 28) to (60000, 784)
  x_train = x_train.reshape(60000, 784)
  return (x_train, y_train)

X_train, y_train = load_data()
print(X_train.shape, y_train.shape)

def build_generator():
    model = Sequential()
    
    model.add(Dense(units=256, input_dim=100))
    model.add(LeakyReLU(alpha=0.2))
    
    model.add(Dense(units=512))
    model.add(LeakyReLU(alpha=0.2))
    
    model.add(Dense(units=1024))
    model.add(LeakyReLU(alpha=0.2))
    
    model.add(Dense(units=784, activation='tanh'))
    
    model.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5))
    return model

generator = build_generator()
generator.summary()
"""
dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是暂时,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。
dropout是CNN中防止过拟合提高效果的一个大杀器
"""
def build_discriminator():
    model = Sequential()
    
    model.add(Dense(units=1024 ,input_dim=784))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dropout(0.3))
       
    model.add(Dense(units=512))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dropout(0.3))
       
    model.add(Dense(units=256))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dropout(0.3))
      
    model.add(Dense(units=1, activation='sigmoid'))
    
    model.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5))
    return model
  
discriminator = build_discriminator()
discriminator.summary()

def build_GAN(discriminator, generator):
    discriminator.trainable=False
    GAN_input = Input(shape=(100,))
    x = generator(GAN_input)
    GAN_output= discriminator(x)
    GAN = Model(inputs=GAN_input, outputs=GAN_output)
    GAN.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5))
    return GAN

GAN = build_GAN(discriminator, generator)
GAN.summary()

def draw_images(generator, epoch, examples=25, dim=(5,5), figsize=(10,10)):
    noise= np.random.normal(loc=0, scale=1, size=[examples, 100])
    generated_images = generator.predict(noise)
    generated_images = generated_images.reshape(25,28,28)
    plt.figure(figsize=figsize)
    for i in range(generated_images.shape[0]):
        plt.subplot(dim[0], dim[1], i+1)
        plt.imshow(generated_images[i], interpolation='nearest', cmap='Greys')
        plt.axis('off')
    plt.tight_layout()
    plt.savefig('Generated_images %d.png' %epoch)
    
    
def train_GAN(epochs=1, batch_size=128):    
  #Loading the data
  X_train, y_train = load_data()

  # Creating GAN
  generator= build_generator()
  discriminator= build_discriminator()
  GAN = build_GAN(discriminator, generator)
#  print("\nepochs %d\n" %epochs)
  for i in range(1, epochs+1):
    print("\nEpoch %d\n" %i)
    
    for _ in tqdm(range(batch_size)):
      # Generate fake images from random noiset
      """
      np.random.normal生成正态分布:均值为0,方差为1,维度为(batch_size,100)--->(128,100)
      generator生成器的输入是128张100维的数据 fake_images即为generator生成的虚假图像
      np.random.randint(low,high,size,dtype) array = np.random.randint(0, X_train.shape[0], batch_size)
           生成128维(行向量) 0-60000的数字,X_train.shape[0]为 60000,
      
      """
      noise= np.random.normal(0,1, (batch_size, 100))
      fake_images = generator.predict(noise)
      #画出虚假图像
      #plt.imshow(fake_images)
      #plt.title("fake_images")
      # Select a random batch of real images from MNIST
      
      real_images = X_train[np.random.randint(0, X_train.shape[0], batch_size)]
      #画出真实图像
      #plt.imshow(real_images)
      #plt.title("real_images")
      # Labels for fake and real images           
      label_fake = np.zeros(batch_size)
      label_real = np.ones(batch_size) 

      # Concatenate fake and real images 
      X = np.concatenate([fake_images, real_images])
      y = np.concatenate([label_fake, label_real])

      # Train the discriminator
      discriminator.trainable=True
      discriminator.train_on_batch(X, y)

      # Train the generator/chained GAN model (with frozen weights in discriminator) 
      discriminator.trainable=False
      GAN.train_on_batch(noise, label_real)

      #Draw generated images every 15 epoches     
    if i == 1 or i % 10 == 0:
        draw_images(generator, i)
train_GAN(epochs=400, batch_size=128)

 

  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值