husky1r 2023-02-27 11:48 采纳率: 66.7%
浏览 32

GAN为什么生成图片没有效果?

为什么我是用GAN进行图片生成,完全没有生成效果?

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.gen_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)

这是部分训练图片

img


这是数据集链接:
链接:https://pan.baidu.com/s/1qDXTSarO_Y7BGgHnWBP34w?pwd=1234
提取码:1234
这是训练过程:(其中gen_loss是生成器损失,disc_loss是判别器损失,fake_out是噪声通过判别器的输出,real_out是真实训练样本通过判别器的输出)

img


这是生成的图片(完全是噪声,感觉一点都没有学习到东西):

img

求帮忙看一下..

  • 写回答

2条回答 默认 最新

  • MarkHan_ 2023-02-27 13:00
    关注

    该回答引用GPTᴼᴾᴱᴺᴬᴵ
    根据你说的判断不出来什么问题啊,以下是一些可能导致GAN无法生成有效图像的常见原因:

    1. 训练不足或过度拟合:GAN模型需要进行足够的训练才能够产生有效的生成图像。如果训练不足,生成器可能无法学习到有效的图像生成方式。另外,如果模型过度拟合了训练数据,可能会导致生成的图像过于接近训练数据,缺乏多样性。

    2. 网络结构不合理:GAN模型需要合理的网络结构才能够产生有效的生成图像。如果生成器或判别器的网络结构设计不合理,可能会导致生成器无法有效地生成图像,或者判别器无法准确地识别真实图像和生成图像之间的差异。

    3. 学习率过高或过低:GAN模型的学习率需要适当地设置,如果学习率设置过高,可能会导致模型不稳定,而如果学习率设置过低,可能会导致模型收敛缓慢。

    4. 数据集质量不佳:GAN模型需要足够多且质量高的训练数据才能够产生有效的生成图像。如果训练数据质量不佳,可能会导致模型无法学习到有效的图像生成方式。

    5. 损失函数设计不合理:GAN模型需要合理的损失函数才能够产生有效的生成图像。如果损失函数设计不合理,可能会导致生成器无法有效地生成图像,或者判别器无法准确地识别真实图像和生成图像之间的差异。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月27日

悬赏问题

  • ¥60 远程协助启动mysql服务
  • ¥15 想问一下STM32创建工程模板时遇到得问题
  • ¥15 Fiddler抓包443
  • ¥20 Qt Quick Android 项目报错及显示问题
  • ¥15 而且都没有 OpenCVConfig.cmake文件我是不是需要安装opencv,如何解决?
  • ¥15 oracleBIEE analytics
  • ¥15 H.264选择性加密例程
  • ¥50 windows的SFTP服务器如何能批量同步用户信息?
  • ¥15 centos7.9升级python3.0的问题
  • ¥15 安装CentOS6时卡住