Why am I using GAN for image generation, no generation effect at all?
import cv2
import numpy as np
import os
import tensorflow.keras as keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, Dense, MaxPooling2D, Conv2DTranspose, BatchNormalization, LeakyReLU, Reshape, Flatten
from tensorflow.keras.losses import BinaryCrossentropy, MeanSquaredError
import tensorflow as tf
import tqdm
class GAN:
def __init__(self, lr, noiseDim, batchSize, epoch, mean=0, var=1):
# 初始化参数
self.lr = lr
self.noiseDim = noiseDim
self.epoch = epoch
self.mean = mean
self.var = var
self.batchSize = batchSize
# 损失函数
self.lossFunc = BinaryCrossentropy(from_logits=False)
# 优化器
self.generator_opt = keras.optimizers.Adam(self.lr)
self.discriminator_opt = keras.optimizers.Adam(self.lr)
# 初始化网络
self.model_d = self.discriminator_model()
self.model_g = self.generator_model()
def generator_model(self):
"""生成器"""
model1 = Sequential()
# 全连接层
model1.add(Dense(256, use_bias=True, activation="selu"))
model1.add(Dense(64, use_bias=True, activation="selu"))
model1.add(Dense(256, use_bias=True, activation="selu"))
model1.add(Dense(12 * 12 * 64, use_bias=True, activation="selu"))
# 变换数据形状
model1.add(Reshape((12, 12, 64)))
# 卷积层
model1.add(Conv2DTranspose(32, kernel_size=1, strides=(1, 1), use_bias=True, padding="same", activation="selu", data_format="channels_last"))
model1.add(Conv2DTranspose(16, kernel_size=3, strides=(2, 2), use_bias=True, padding="same", activation="selu", data_format="channels_last"))
model1.add(Conv2DTranspose(8, kernel_size=3, strides=(2, 2), use_bias=True, padding="same", activation="selu", data_format="channels_last"))
model1.add(Conv2DTranspose(3, kernel_size=3, strides=(2, 2), use_bias=True, padding="same", activation="selu", data_format="channels_last"))
return model1
def discriminator_model(self):
"""判别器"""
model2 = Sequential()
# 卷积层
model2.add(Conv2D(8, kernel_size=1, strides=(1, 1), use_bias=True, padding="same", activation="selu", data_format="channels_last"))
# 池化层
model2.add(MaxPooling2D(pool_size=(2, 2), strides=2, padding="same", data_format="channels_last")) # 48*48*8
# 卷积层
model2.add(Conv2D(16, kernel_size=3, strides=(2, 2), use_bias=True, padding="same", activation="selu", data_format="channels_last"))
# 池化层
model2.add(MaxPooling2D(pool_size=(2, 2), strides=2, padding="same", data_format="channels_last")) # 12*12*16
# 改变形状
model2.add(Flatten())
# 全连接层
model2.add(Dense(128, activation="selu"))
model2.add(Dense(64, activation="selu"))
model2.add(Dense(1, activation="sigmoid"))
return model2
def generator_loss(self, fake_out):
loss = self.lossFunc(tf.ones_like(fake_out), fake_out)
return loss
def discriminator_loss(self, fake_out, real_out):
loss = self.lossFunc(tf.ones_like(real_out), real_out) + self.lossFunc(tf.zeros_like(fake_out), fake_out)
return loss
def train_step(self, X):
# 生成噪声
noise = tf.random.normal([self.batchSize, self.noiseDim], self.mean, self.var)
# 训练
with tf.GradientTape() as gen_tape:
self.data = self.model_g(noise, training=True)
self.fake_out = self.model_d(self.gen_data, training=True)
self.gen_loss = self.generator_loss(self.fake_out)
self.gradient_gen = gen_tape.gradient(self.gen_loss, self.model_g.trainable_variables)
self.generator_opt.apply_gradients(zip(self.gradient_gen, self.model_g.trainable_variables))
with tf.GradientTape() as disc_tape:
self.real_out = self.model_d(X, training=True)
self.disc_loss = self.discriminator_loss(self.fake_out, self.real_out)
self.gradient_disc = disc_tape.gradient(self.disc_loss, self.model_d.trainable_variables)
self.discriminator_opt.apply_gradients(zip(self.gradient_disc, self.model_d.trainable_variables))
def fit(self, X):
for loop in range(self.epoch):
for batch in range(len(X)//self.batchSize):
subData = X[batch*self.batchSize:(batch+1)*self.batchSize]
self.train_step(subData)
print(f"epoch={loop+1}/{self.epoch}, gen_loss={self.gen_loss.numpy()}, disc_loss={self.disc_loss.numpy()}, "
f"fake_out={np.mean(self.fake_out)}, real_out={np.mean(self.real_out)}")
keras.Model.save(self.model_g, "./GAN_TF2_CNN/generator/")
keras.Model.save(self.model_d, "./GAN_TF2_CNN/discriminator/")
def predict(self, length):
model_g = keras.models.load_model("./GAN_TF2_CNN/generator/")
# 生成噪声
noise = tf.random.normal([length, self.noiseDim], self.mean, self.var)
# 生成数据
gen_data = model_g(noise, training=False)
return gen_data.numpy()
def loadData():
dir = "D:\\BaiduNetdiskDownload\\faces\\faces\\"
fileName = os.listdir(dir)
data = []
for name in tqdm.tqdm(fileName, desc="load images", unit="img", ncols=100, colour="green"):
img = cv2.imread(dir + name)
img = (img / 255) * 2 - 1
data.append(img)
cv2.destroyAllWindows()
return np.array(data)
def convertImages(data):
data = ((data + 1)/2)*255
for i in range(data.shape[0]):
cv2.imwrite(f"./GeneatorImages/{i}.jpg", data[i])
cv2.destroyAllWindows()
if __name__ == "__main__":
data = loadData()
gan = GAN(lr=0.001, noiseDim=100, batchSize=200, epoch=10, mean=0, var=1)
gan.fit(data)
result = gan.predict(10)
convertImages(result)
this is part of the training images < br / >
< div class = "aw - list - img >
Please have a look...
0 Answer
No answer yet
这家伙很懒,什么都没留下...