用DCGAN生成卡通人脸

DCGAN的网络结构:

它的基本思想是训练两个网络,一个判别器一个生成器,可以把他们比喻成警和匪,警的职责就是判断出真是的伪造的,而匪的任务就是去造假,然后让警判别不出真假,他们互相对抗以提高各自的业务能力,他们对抗的过程可以用下面的式子来表示:

这个式子就是说我先固定生成器,然后使得判别器最大,也就是使得警的业务能力最强,也就是D(x)最大,要靠近1,D(G(z))最小,要靠近0,这样它辨别真假的能力就很强。然后固定判别器,使得G(z)最小,这样D(G(Z))就大了,就让判别器误以为是真的,最终达到真假难辨的目的。

先来看看训练效果吧:

数据集下载地址:

链接:https://pan.baidu.com/s/1kLnwLFzGUQIdFkhCum7B5Q 
提取码:6xim 

DCGAN与传统GAN的区别就在于

1、去掉了全连接,使用全卷积网络

2、最后一层使用sigmoid作为激活函数

3、在判别器的输入和生成器的输出不使用批量归一化,原因就是批量归一化会将数据的分布强制控制在一个范围内,这样在真实数据和生成数据输入进来的时候就会对判别不利。而生成器的输出是因为本来可能生成的是一个很接近真是的分布了,但是一做归一化后分布就变了。如果所有层都用BN的话会导致样本的震荡和不稳定。

4、判别器的中间层使用leakyrelu激活函数,生成器的使用relu。

训练的注意事项:

1、BN层的参数也要拿去训练,因为如果不训练的话那么就相当于人为的把数据的分布控制在一个范围内,与真实值就会有很大的偏差,一次BN层的参数也要拿去学习。

2、感受野的大小要稍微大一点,比如用5x5的卷积核,因为在做像生成和分割这样的问题是需要考虑像素之间的融合,如果太小,融合度就不够。

好了,说完了原理,我们来看看具体怎么做吧

首先搭建一个判别器,用一个类来定义:

class Dnet:
    def __init__(self):
        with tf.variable_scope('dnet'):
            self.w1 = tf.Variable(tf.random_normal(shape=[5, 5, 3, 64], dtype=tf.float32, stddev=0.02))
            self.b1 = tf.Variable(tf.zeros(shape=[64], dtype=tf.float32))
            self.w2 = tf.Variable(tf.random_normal(shape=[5, 5, 64, 128], dtype=tf.float32, stddev=0.02))
            self.b2 = tf.Variable(tf.zeros(shape=[128], dtype=tf.float32))
            self.w3 = tf.Variable(tf.random_normal(shape=[5, 5, 128, 256], dtype=tf.float32, stddev=0.02))
            self.b3 = tf.Variable(tf.zeros(shape=[256], dtype=tf.float32))
            self.w4 = tf.Variable(tf.random_normal(shape=[5, 5, 256, 512], dtype=tf.float32, stddev=0.02))
            self.b4 = tf.Variable(tf.zeros(shape=[512], dtype=tf.float32))
            self.w5 = tf.Variable(tf.random_normal(shape=[6*6*512,1], dtype=tf.float32, stddev=0.02))
            self.b5 = tf.Variable(tf.zeros(shape=[1], dtype=tf.float32))

    def forward(self, x,reuse=False):
        with tf.variable_scope('dnet',reuse=reuse):
            y1 = self.leaky_relu(tf.nn.conv2d(x, self.w1, strides=[1, 2, 2, 1], padding='SAME') + self.b1)#48
            y2 = self.leaky_relu(tf.layers.batch_normalization(tf.nn.conv2d(y1, self.w2, strides=[1, 2, 2, 1], padding='SAME') + self.b2,name='bn1'))#24
            y3 = self.leaky_relu(tf.layers.batch_normalization(tf.nn.conv2d(y2, self.w3, strides=[1, 2, 2, 1], padding='SAME') + self.b3,name='bn2'))#12
            y4 = self.leaky_relu(tf.layers.batch_normalization(tf.nn.conv2d(y3, self.w4, strides=[1, 2, 2, 1], padding='SAME') + self.b4,name='bn3'))#6
            y4 = tf.reshape(y4,[-1,6*6*512])
            y5 = tf.nn.sigmoid(tf.matmul(y4,self.w5)+self.b5)
            return y5

    def leaky_relu(self,x):
        return tf.maximum(0.2*x,x)

    def getParam(self):
        params = tf.trainable_variables()
        return [i for i in params if 'dnet' in i.name]

然后构建生成器,也使用一个类:

class Gnet:
    def __init__(self):
        with tf.variable_scope("gnet"):
            self.w1 = tf.Variable(tf.random_normal(shape=[100, 64*8*6*6], dtype=tf.float32, stddev=0.02))
            self.b1 = tf.Variable(tf.zeros(shape=[64*8*6*6], dtype=tf.float32))
            self.w2 = tf.Variable(tf.random_normal(shape=[5, 5, 256, 512], dtype=tf.float32, stddev=0.02))
            self.b2 = tf.Variable(tf.zeros(shape=[256], dtype=tf.float32))
            self.w3 = tf.Variable(tf.random_normal(shape=[5, 5, 128,256], dtype=tf.float32, stddev=0.02))
            self.b3 = tf.Variable(tf.zeros(shape=[128], dtype=tf.float32))
            self.w4 = tf.Variable(tf.random_normal(shape=[5, 5, 64, 128], dtype=tf.float32, stddev=0.02))
            self.b4 = tf.Variable(tf.zeros(shape=[64], dtype=tf.float32))
            self.w5 = tf.Variable(tf.random_normal(shape=[5, 5, 3, 64], dtype=tf.float32, stddev=0.02))
            self.b5 = tf.Variable(tf.zeros(shape=[3], dtype=tf.float32))

    def forward(self, x):
        with tf.variable_scope("gnet"):
            y1 = tf.nn.relu(tf.layers.batch_normalization(tf.matmul(x, self.w1) + self.b1,name='bn1'))
            y1 = tf.reshape(y1, [-1, 6, 6, 512])
            y2 = tf.nn.relu(tf.layers.batch_normalization(
                tf.nn.conv2d_transpose(y1, self.w2, strides=[1, 2, 2, 1], padding='SAME',
                                       output_shape=[batch_size, 12, 12, 256]) + self.b2,name='bn2'))
            y3 = tf.nn.relu(tf.layers.batch_normalization(
                tf.nn.conv2d_transpose(y2, self.w3, output_shape=[batch_size, 24, 24, 128], strides=[1, 2, 2, 1],
                                                   padding='SAME') + self.b3,name='bn3'))
            y4 = tf.nn.relu(tf.layers.batch_normalization(
                tf.nn.conv2d_transpose(y3, self.w4, output_shape=[batch_size, 48, 48, 64], strides=[1, 2, 2, 1],
                                                   padding='SAME') + self.b4,name='bn4'))
            y5 = tf.nn.tanh(tf.nn.conv2d_transpose(y4, self.w5, output_shape=[batch_size, 96, 96, 3], strides=[1, 2, 2, 1],
                                                   padding='SAME') + self.b5)
            return y5

    def getParam(self):
        params = tf.trainable_variables()
        return [i for i in params if 'gnet' in i.name]

然后构建整个网络:

class Net:
    def __init__(self):
        self.real_x = tf.placeholder(shape=[None, 96,96,3], dtype=tf.float32)
        self.fack_x = tf.placeholder(shape=[None, 100], dtype=tf.float32)
        self.pos_y = tf.placeholder(shape=[None, 1], dtype=tf.float32)
        self.nega_y = tf.placeholder(shape=[None, 1], dtype=tf.float32)
        self.dnet = Dnet()
        self.gnet = Gnet()

    def forwrd(self):
        self.real_d_out = self.dnet.forward(self.real_x)
        self.g_out = self.gnet.forward(self.fack_x)
        self.g_d_out = self.dnet.forward(self.g_out,reuse=True)

    def backward(self):
        d_out_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.real_d_out, labels=self.pos_y))
        g_d_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.g_d_out, labels=self.nega_y))
        self.d_loss = d_out_loss + g_d_loss
        self.d_opt = tf.train.AdamOptimizer(learning_rate=0.0002, beta1=0.5).minimize(self.d_loss,var_list=self.dnet.getParam())
        self.g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.g_d_out, labels=self.pos_y))
        self.g_opt = tf.train.AdamOptimizer(learning_rate=0.0002, beta1=0.5).minimize(self.g_loss,var_list=self.gnet.getParam())
        self.d_para = self.dnet.getParam()
        self.g_para = self.gnet.getParam()

模型搭建好了,再对样本进行采样:

def get_batch(path,batchsize):
    imgs = [os.path.join(path,img) for img in os.listdir(path)]
    batch_number = len(imgs)//batchsize
    imgs = imgs[:batch_number*batchsize]
    for i in range(batch_number):
        images = [cv2.imread(img) for img in imgs[i*batchsize:(i+1)*batchsize]]
        images = np.array(images)
        yield images

将生成的图片进行显示和保存:

def visit_img(batchsize,samples,i):
    fig,axes = plt.subplots(figsize=(12,12),nrows=8,ncols=8,sharex=True,sharey=True)
    for ax,img in zip(axes.flatten(),samples[-1]):
        ax.xaxis.set_visible(False)
        ax.yaxis.set_visible(False)
        im = ax.imshow(img.reshape((96, 96, 3)))
    plt.pause(0.5)
    plt.savefig(r'picture\{}.jpg'.format(i))

下面是整个代码:

import matplotlib.pyplot as plt
import tensorflow as tf
from scipy import misc
import os
import numpy as np
import os
from scipy import misc
import numpy as np

def vis_img(batch_size, samples,i):
    fig, axes = plt.subplots(figsize=(7, 7), nrows=8, ncols=8, sharey=True, sharex=True)
    for ax, img in zip(axes.flatten(), samples[batch_size]):
        # print(img.shape)
        ax.xaxis.set_visible(False)
        ax.yaxis.set_visible(False)
        im = ax.imshow(img.reshape((96, 96, 3)), cmap='Greys_r')
    # plt.show()
    plt.savefig(r'picture\{}.jpg'.format(i))


def read_img(path):
    img = misc.imresize(misc.imread(path), size=[96, 96])
    return img


def get_batch(path, batch_size):
    img_list = [os.path.join(path, i) for i in os.listdir(path)]

    n_batchs = len(img_list) // batch_size
    img_list = img_list[:n_batchs * batch_size]

    for ii in range(n_batchs):
        tmp_img_list = img_list[ii * batch_size:(ii + 1) * batch_size]
        img_batch = np.zeros(shape=[batch_size, 96, 96, 3])
        for jj, img in enumerate(tmp_img_list):
            img_batch[jj] = read_img(img)
        yield img_batch


def generator(inputs, stddev=0.02, alpha=0.2, name='generator', reuse=False):
    with tf.variable_scope(name, reuse=reuse) as scope:
        fc1 = tf.layers.dense(gen_input, 64 * 8 * 6 * 6, name='fc1')
        re1 = tf.reshape(fc1, (-1, 6, 6, 512), name='reshape')
        bn1 = tf.layers.batch_normalization(re1, name='bn1')
         # ac1 = tf.maximum(alpha * bn1, bn1,name='ac1')
        ac1 = tf.nn.relu(bn1, name='ac1')
        de_conv1 = tf.layers.conv2d_transpose(ac1, 256, kernel_size=[5, 5], padding='same', strides=2,
                                              kernel_initializer=tf.random_normal_initializer(stddev=stddev),
                                              name='decov1')
        bn2 = tf.layers.batch_normalization(de_conv1, name='bn2')
        # ac2 = tf.maximum(alpha * bn2, bn2,name='ac2')
        ac2 = tf.nn.relu(bn2, name='ac2')
        de_conv2 = tf.layers.conv2d_transpose(ac2, 128, kernel_size=[5, 5], padding='same',
                                              kernel_initializer=tf.random_normal_initializer(stddev=stddev), strides=2,
                                              name='decov2')
        bn3 = tf.layers.batch_normalization(de_conv2, name='bn3')
        # ac3 = tf.maximum(alpha * bn3, bn3,name='ac3')

        ac3 = tf.nn.relu(bn3, name='ac3')
        de_conv3 = tf.layers.conv2d_transpose(ac3, 64, kernel_size=[5, 5], padding='same',
                                              kernel_initializer=tf.random_normal_initializer(stddev=stddev), strides=2,
                                              name='decov3')
        bn4 = tf.layers.batch_normalization(de_conv3, name='bn4')
        # ac4 = tf.maximum(alpha * bn4, bn4,name='ac4')
        ac4 = tf.nn.relu(bn4, name='ac4')
        logits = tf.layers.conv2d_transpose(ac4, 3, kernel_size=[5, 5], padding='same',
                                            kernel_initializer=tf.random_normal_initializer(stddev=stddev), strides=2,
                                            name='logits')
        output = tf.tanh(logits)
        return output


def discriminator(inputs, stddev=0.02, alpha=0.2, batch_size=64, name='discriminator', reuse=False):
    with tf.variable_scope(name, reuse=reuse) as scope:
        conv1 = tf.layers.conv2d(inputs, 64, (5, 5), (2, 2), padding='same',
                                 kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv1')
        ac1 = tf.maximum(alpha * conv1, conv1, name='ac1')

        conv2 = tf.layers.conv2d(ac1, 128, (5, 5), (2, 2), padding='same',
                                 kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv2')
        bn2 = tf.layers.batch_normalization(conv2, name='bn2')
        ac2 = tf.maximum(alpha * bn2, bn2, name='ac2')

        conv3 = tf.layers.conv2d(ac2, 256, (5, 5), (2, 2), padding='same',
                                 kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv3')
        bn3 = tf.layers.batch_normalization(conv3, name='bn3')
        ac3 = tf.maximum(alpha * bn3, bn3, name='ac3')

        conv4 = tf.layers.conv2d(ac3, 512, (5, 5), (2, 2), padding='same',
                                 kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='conv4')
        bn4 = tf.layers.batch_normalization(conv4, name='bn4')
        ac4 = tf.maximum(alpha * bn4, bn4, name='ac4')

        flat = tf.reshape(ac4, shape=[batch_size, 6 * 6 * 512], name='reshape')

        fc2 = tf.layers.dense(flat, 1, kernel_initializer=tf.random_normal_initializer(stddev=stddev), name='fc2')
        return fc2


lr = 0.0002
epochs = 100
batch_size = 64
alpha = 0.2#leakeyrelu的

#生成器的输入
with tf.name_scope('gen_input') as scope:
    gen_input = tf.placeholder(dtype=tf.float32, shape=[None, 100], name='gen_input')
#判别器的输入
with tf.name_scope('dis_input') as scope:
    real_input = tf.placeholder(dtype=tf.float32, shape=[None, 96, 96, 3], name='dis_input')

#生成图像
gen_out = generator(gen_input, stddev=0.02, alpha=alpha, name='generator', reuse=False)

real_logits = discriminator(real_input, alpha=alpha, batch_size=batch_size)
fake_logits = discriminator(gen_out, alpha=alpha, reuse=True)#重用已经创建的变量

# var_list_gen = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope='generator')
# var_list_dis = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,scope='discriminator')
train_var = tf.trainable_variables()#返回的是需要训练的变量列表
var_list_gen = [var for var in train_var if var.name.startswith('generator')]
var_list_dis = [var for var in train_var if var.name.startswith('discriminator')]
with tf.name_scope('metrics') as scope:
    loss_g = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(fake_logits) * 0.9, logits=fake_logits))
    loss_d_f = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.zeros_like(fake_logits), logits=fake_logits))
    loss_d_r = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(real_logits) * 0.9, logits=real_logits))
    loss_d = loss_d_f + loss_d_r
    gen_optimizer = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(loss_g, var_list=var_list_gen)
    dis_optimizer = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(loss_d, var_list=var_list_dis)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)#创建入队线程启动器用于多线程读取数据
    writer = tf.summary.FileWriter('./graph/DCGAN', sess.graph)
    saver = tf.train.Saver()

    for epoch in range(epochs):
        total_g_loss = 0
        total_d_loss = 0
        KK = 0
        for batch in get_batch('./faces/', batch_size):
            x_real = batch
            x_real = x_real / 127.5 - 1#归一化
            x_fake = np.random.uniform(-1, 1, size=[batch_size, 100])
            KK += 1
            _, tmp_loss_d = sess.run([dis_optimizer, loss_d], feed_dict={gen_input: x_fake, real_input: x_real})

            total_d_loss += tmp_loss_d

            _, tmp_loss_g = sess.run([gen_optimizer, loss_g], feed_dict={gen_input: x_fake})
            _, tmp_loss_g = sess.run([gen_optimizer, loss_g], feed_dict={gen_input: x_fake})
            total_g_loss += tmp_loss_g
            samples = sess.run(gen_out, feed_dict={gen_input: x_fake})
            samples = (((samples - samples.min()) * 255) / (samples.max() - samples.min())).astype(np.uint8)  # 归一化
        if (epoch+1) % 2 == 0:
            x_fake = np.random.uniform(-1, 1, [64, 100])

            samples = sess.run(gen_out, feed_dict={gen_input: x_fake})
            samples = (((samples - samples.min()) * 255) / (samples.max() - samples.min())).astype(np.uint8)#归一化

            vis_img(-1, [samples],epoch)

            print('epoch {},loss_g={}'.format(epoch, total_g_loss / 2 / KK))
            print('epoch {},loss_d={}'.format(epoch, total_d_loss / KK))
            saver.save(sess, "./checkpoints/DCGAN")

    writer.close()

下面这个更好:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from cartoon_face_dataset import MyDataset
import os


class D_Net:
    def __init__(self):
        with tf.variable_scope("d_net"):
            self.w1 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 3, 64], stddev=0.02))
            self.b1 = tf.Variable(tf.zeros([64]), dtype=tf.float32)
            self.w2 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 64, 128], stddev=0.02))
            self.b2 = tf.Variable(tf.zeros([128]), dtype=tf.float32)
            self.w3 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 128, 256], stddev=0.02))
            self.b3 = tf.Variable(tf.zeros([256]), dtype=tf.float32)
            self.w4 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 256, 512], stddev=0.02))
            self.b4 = tf.Variable(tf.zeros([512]), dtype=tf.float32)
            self.w5 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[6 * 6 * 512, 1], stddev=0.02))
            self.b5 = tf.Variable(tf.zeros([1]), dtype=tf.float32)

    def forward(self, x, reuse=False):
        with tf.variable_scope("d_net", reuse=reuse):
            net = tf.nn.leaky_relu(tf.nn.conv2d(x, self.w1, [1, 2, 2, 1], padding="SAME") + self.b1)
            net = tf.nn.leaky_relu(
                tf.layers.batch_normalization(tf.nn.conv2d(net, self.w2, [1, 2, 2, 1], padding="SAME") + self.b2,
                                              momentum=0.9, epsilon=1e-5))
            net = tf.nn.leaky_relu(
                tf.layers.batch_normalization(tf.nn.conv2d(net, self.w3, [1, 2, 2, 1], padding="SAME") + self.b3,
                                              momentum=0.9, epsilon=1e-5))
            net = tf.nn.leaky_relu(
                tf.layers.batch_normalization(tf.nn.conv2d(net, self.w4, [1, 2, 2, 1], padding="SAME") + self.b4,
                                              momentum=0.9, epsilon=1e-5))
            net = tf.matmul(tf.reshape(net, [128, 6 * 6 * 512]), self.w5) + self.b5
            params = tf.trainable_variables()
            self.params = [var for var in params if 'd_net' in var.name]
            # print(self.params)
            # exit()
            return net


class G_Net:
    def __init__(self):
        with tf.variable_scope("g_net"):
            self.w1 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[128, 6 * 6 * 512], stddev=0.02))
            self.b1 = tf.Variable(tf.zeros([6 * 6 * 512]), dtype=tf.float32)
            self.w2 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 256, 512], stddev=0.02))
            self.b2 = tf.Variable(tf.zeros([256]), dtype=tf.float32)
            self.w3 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 128, 256], stddev=0.02))
            self.b3 = tf.Variable(tf.zeros([128]), dtype=tf.float32)
            self.w4 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 64, 128], stddev=0.02))
            self.b4 = tf.Variable(tf.zeros([64]), dtype=tf.float32)
            self.w5 = tf.Variable(tf.truncated_normal(dtype=tf.float32, shape=[5, 5, 3, 64], stddev=0.02))
            self.b5 = tf.Variable(tf.zeros([3]), dtype=tf.float32)

    def forward(self, x, reuse=False):
        with tf.variable_scope("g_net", reuse=reuse):
            net = tf.matmul(x, self.w1) + self.b1
            net = tf.nn.relu(
                tf.layers.batch_normalization(tf.reshape(net, [-1, 6, 6, 512]), momentum=0.9, epsilon=1e-5))
            net = tf.nn.relu(
                tf.layers.batch_normalization(
                    tf.nn.conv2d_transpose(net, self.w2, [128, 12, 12, 256], [1, 2, 2, 1], padding="SAME") + self.b2,
                    momentum=0.9, epsilon=1e-5))
            net = tf.nn.relu(
                tf.layers.batch_normalization(
                    tf.nn.conv2d_transpose(net, self.w3, [128, 24, 24, 128], [1, 2, 2, 1], padding="SAME") + self.b3,
                    momentum=0.9, epsilon=1e-5))
            net = tf.nn.relu(
                tf.layers.batch_normalization(
                    tf.nn.conv2d_transpose(net, self.w4, [128, 48, 48, 64], [1, 2, 2, 1], padding="SAME") + self.b4,
                    momentum=0.9, epsilon=1e-5))
            net = tf.nn.tanh(
                tf.nn.conv2d_transpose(net, self.w5, [128, 96, 96, 3], [1, 2, 2, 1], padding="SAME") + self.b5)
            params = tf.trainable_variables()
            self.params = [var for var in params if 'g_net' in var.name]
            # print(self.params)
            return net


class Net:
    def __init__(self):
        self.x = tf.placeholder(shape=[None, 96, 96, 3], dtype=tf.float32)
        self.init_data = tf.placeholder(shape=[None, 128], dtype=tf.float32)
        self.fake_label = tf.placeholder(shape=[None, 1], dtype=tf.float32)
        self.real_label = tf.placeholder(shape=[None, 1], dtype=tf.float32)

    def forward(self):
        self.d_net = D_Net()
        self.g_net = G_Net()
        self.g_out = self.g_net.forward(self.init_data)
        self.d_real_out = self.d_net.forward(self.x)
        self.d_fake_out = self.d_net.forward(self.g_out, reuse=True)

    def loss(self):
        d_real_loss = tf.reduce_mean(
            tf.nn.sigmoid_cross_entropy_with_logits(labels=self.real_label, logits=self.d_real_out))
        d_fake_loss = tf.reduce_mean(
            tf.nn.sigmoid_cross_entropy_with_logits(labels=self.fake_label, logits=self.d_fake_out))
        self.d_loss = d_fake_loss + d_real_loss
        self.g_loss = tf.reduce_mean(
            tf.nn.sigmoid_cross_entropy_with_logits(labels=self.fake_label, logits=self.d_fake_out))

    def backward(self):
        self.bp_g = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.g_loss, var_list=self.g_net.params)
        self.bp_d = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.d_loss, var_list=self.d_net.params)


def visit_image(batchsize, samples, i):
    fig, axes = plt.subplots(figsize=(48, 48), nrows=8, ncols=16, sharex=True, sharey=True)
    for ax, img in zip(axes.flatten(), samples[-1]):
        ax.xaxis.set_visible(False)
        ax.yaxis.set_visible(False)
        im = ax.imshow(img.reshape((96, 96, 3)))
    plt.savefig(r'C:\gan_faces\{0}.jpg'.format(i))


if __name__ == '__main__':
    net = Net()
    net.forward()
    net.loss()
    net.backward()
    init = tf.global_variables_initializer()
    mydataset = MyDataset(r"C:\faces", 128)

    with tf.Session() as sess:
        saver = tf.train.Saver()
        sess.run(init)
        # num = os.listdir("./gen_face/")[-1].split(".")[0]
        # if os.path.exists("./gen_face/{0}/checkpoint".format(num)):
        #     saver.restore(sess, "./gen_face/{0}/gen_face.ckpt".format(num))
        # else:
        #     sess.run(init)
        for i in range(100000):
            xs = mydataset.get_batch(sess)[0]
            # init_datas = np.random.normal(0, 0.02, (128, 128))
            init_datas = np.random.uniform(-1, 1, (128, 128))
            d_real_labels = np.ones(shape=[128, 1])
            d_fake_labels = np.zeros(shape=[128, 1])
            d_loss_, _ = sess.run([net.d_loss, net.bp_d],
                                  feed_dict={net.x: xs, net.init_data: init_datas, net.real_label: d_real_labels,
                                             net.fake_label: d_fake_labels})
            print("D_loss: ", d_loss_)
            # init_datas = np.random.normal(0, 0.02, (128, 128))
            g_fake_labels = np.ones(shape=[128, 1])
            for _ in range(2):
                g_loss_, _ = sess.run([net.g_loss, net.bp_g],
                                      feed_dict={net.init_data: init_datas, net.fake_label: g_fake_labels})
                print("G_loss: ", g_loss_)
            if i % 50 == 0:
                # init_datas = np.random.normal(0, 0.02, (128, 128))
                init_datas = np.random.uniform(-1, 1, (128, 128))
                g_out_ = sess.run(net.g_out, feed_dict={net.init_data: init_datas})
                img_array = np.array(g_out_) / 2 + 0.5
                # plt.imshow(img_array)
                # plt.pause(0.1)

                visit_image(-1, [img_array], i)

            if i % 50 == 0:
                saver.save(sess, "./gen_face/{0}/gen_face.ckpt".format(i))

猜你喜欢

转载自blog.csdn.net/weixin_38241876/article/details/90896565