参考一篇非常全面的博文(传送门),把最原始的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)
转载:https://blog.csdn.net/LMengi000/article/details/117168791