初探DCGAN,TensorFlow2.0实现动漫头像生成

今天第一次用tensorflow2.0做demo,参考原文链接

 

from __future__ import print_function, division

from tensorflow.keras.layers import Input, Dense, Reshape, Dropout
from tensorflow.keras.layers import BatchNormalization, Activation, GlobalAveragePooling2D, Flatten
from tensorflow.keras.layers import LeakyReLU
from tensorflow.keras.layers import UpSampling2D, Conv2D
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.optimizers import Adam, SGD, RMSprop
from PIL import Image
import matplotlib.pyplot as plt

import os

import numpy as np

class DCGAN():
    def __init__(self):
        # 输入shape
        self.img_rows = 64
        self.img_cols = 64
        self.channels = 3
        self.img_shape = (self.img_rows, self.img_cols, self.channels)
        self.latent_dim = 100
        # adam优化器
        # optimizer = Adam(0.00015, 0.5)
        optimizer = SGD(0.0002, 0.5)
        # 判别模型
        self.discriminator = self.build_discriminator()
        self.discriminator.compile(loss=['binary_crossentropy'],
            optimizer=optimizer,
            metrics=['accuracy'])
        # 生成模型
        self.generator = self.build_generator()

        # conbine是生成模型和判别模型的结合
        # 判别模型的trainable为False
        # 用于训练生成模型
        z = Input(shape=(self.latent_dim,))
        img = self.generator(z)

        self.discriminator.trainable = False

        valid = self.discriminator(img)

        self.combined = Model(z, valid)
        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)

    def build_generator(self):
        model = Sequential()
        model.add(Dense(512 * 4 * 4, activation='relu', input_dim=self.latent_dim))  # 输入维度为100
        model.add(Reshape((4, 4, 512)))
        model.add(UpSampling2D())
        model.add(Conv2D(256, kernel_size=5, padding='same', kernel_initializer = 'glorot_uniform'))
        model.add(BatchNormalization(momentum=0.5))
        model.add(Activation("relu"))
        model.add(UpSampling2D())
        model.add(Conv2D(128, kernel_size=5, padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(BatchNormalization(momentum=0.5))
        model.add(Activation("relu"))
        model.add(UpSampling2D())
        model.add(Conv2D(64, kernel_size=5, padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(BatchNormalization(momentum=0.5))
        model.add(Activation("relu"))
        model.add(UpSampling2D())
        model.add(Conv2D(3, kernel_size=5, padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(Activation("tanh"))
        model.summary()  # 打印网络参数
        noise = Input(shape=(self.latent_dim,))
        img = model(noise)

        return Model(noise, img)

    def build_discriminator(self):
        model = Sequential()
        dropout = 0.5
        model.add(Conv2D(64, kernel_size=5, strides=(2,2), input_shape=self.img_shape, padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(dropout))
        model.add(Conv2D(128, kernel_size=5, strides=(2,2), padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(BatchNormalization(momentum=0.5))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(dropout))
        model.add(Conv2D(256, kernel_size=5, strides=(2,2), padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(BatchNormalization(momentum=0.5))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(dropout))
        model.add(Conv2D(512, kernel_size=5, strides=(2,2), padding="same", kernel_initializer = 'glorot_uniform'))
        model.add(BatchNormalization(momentum=0.5))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dropout(dropout))
        model.add(Flatten())
        model.add(Dense(1, activation='sigmoid'))
        model.summary()
        img = Input(shape=self.img_shape)
        validity = model(img)

        return Model(img, validity)

    def train(self, epochs, batch_size=128, save_interval=50):
        # 载入数据
        filename = "E:/数据集/faces/"
        X_train = load_image(filename)

        # Adversarial ground truths
        valid = np.ones((batch_size, 1))-np.random.random_sample((batch_size,1))*0.1
        fake = np.random.random_sample((batch_size,1))*0.1

        for epoch in range(epochs):

            # --------------------- #
            #  训练判别模型
            # --------------------- #
            idx = np.random.randint(0, X_train.shape[0], batch_size)
            imgs = X_train[idx]

            noise = np.random.normal(0, 1, (batch_size, self.latent_dim))
            gen_imgs = self.generator.predict(noise)

            # 训练并计算loss
            d_loss_real = self.discriminator.train_on_batch(imgs, valid)
            d_loss_fake = self.discriminator.train_on_batch(gen_imgs, fake)
            d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

            # ---------------------
            #  训练生成模型
            # ---------------------
            g_loss = self.combined.train_on_batch(noise, valid)

            print("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100 * d_loss[1], g_loss))

            if epoch % save_interval == 0:
                self.save_imgs(epoch)

    def save_imgs(self, epoch):
        r, c = 5, 5
        noise = np.random.normal(0, 1, (r * c, self.latent_dim))
        gen_imgs = self.generator.predict(noise)
        gen_imgs = 0.5 * gen_imgs + 0.5

        fig, axs = plt.subplots(r, c)
        cnt = 0
        for i in range(r):
            for j in range(c):
                axs[i, j].imshow(gen_imgs[cnt, :, :, :])
                axs[i, j].axis('off')
                cnt += 1
        fig.savefig("dc_images/MeganFaces_%d.png" % epoch)
        plt.close()


def load_image(filename):
    imgs = os.listdir(filename)
    x_train = np.empty((imgs.__len__(), 64, 64, 3), dtype='float32')

    for i in range(len(imgs)):
        img = Image.open(filename + imgs[i])
        img = img.resize((64,64))
        img_arr = np.asarray(img, dtype='float32')
        x_train[i, :, :, :] = img_arr/127.5 - 1.

    return x_train


if __name__ == '__main__':
    if not os.path.exists("./dc_images"):
        os.makedirs("./dc_images")
    dcgan = DCGAN()
    dcgan.train(epochs=20000, batch_size=256, save_interval=50)

发现一些问题,7800多次epoch后图片还是灰色的 应该是我现在水平有限,不知道哪里出了问题。。。有知道的小伙伴们能告诉一下嘛。。。。

初探DCGAN,TensorFlow2.0实现动漫头像生成_第1张图片

 

你可能感兴趣的:(初学系列,tensorflow,神经网络,深度学习,数据挖掘,机器学习)