本文共 7219 字,大约阅读时间需要 24 分钟。
参考一篇(传送门),把最原始的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 mnistfrom keras.layers import Dense, Dropout, Inputfrom keras.models import Model,Sequentialfrom keras.layers.advanced_activations import LeakyReLUfrom keras.optimizers import Adamfrom tqdm import tqdmimport numpy as npimport matplotlib.pyplot as plt#%matplotlib inline#from google.colab import drive# Load the datasetdef 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 modelgenerator = 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 GANGAN = 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)
转载地址:http://uuoez.baihongyu.com/