import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers import matplotlib.pyplot as plt %matplotlib inline import numpy as np import glob import os

查看tensorflow版本

1
tf.__version__

查看是否支持GPU

1
tf.test.is_gpu_available()

获取图片路径

1
image_path = glob.glob('E:anime-face/Anime Faces/*')

定义加载函数

1
2
3
4
5
6
7
def load_image(image_path):
img = tf.io.read_file(image_path)
img = tf.image.decode_jpeg(img,channels=3)
# img = tf.image.resize(img,[64,64])
img = tf.cast(img,tf.float32)
img = (img/127.5)-1
return img

创建输入管道

1
2
BATCH_SIZE = 128
BUFFER_SIZE = img_count
1
2
3
AUTOTUNE = tf.data.experimental.AUTOTUNE
image_ds = tf.data.Dataset.from_tensor_slices(image_path)
image_ds = image_ds.map(load_image,num_parallel_calls=AUTOTUNE)
1
2
image_ds = image_ds.shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
image_ds = image_ds.prefetch(AUTOTUNE)

生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def generator_model():#生成器
model = tf.keras.Sequential()
model.add(layers.Dense(8*8*256,input_shape=(100,),use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())

model.add(layers.Reshape((8,8,256)))#8*8*256

model.add(layers.Conv2DTranspose(128,5,strides=(1,1),padding='same',use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU()) #8*8*128

model.add(layers.Conv2DTranspose(64,5,strides=(2,2),padding='same',use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU()) #16*16*64

model.add(layers.Conv2DTranspose(32,5,strides=(2,2),padding='same',use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU()) #32*32*32

model.add(layers.Conv2DTranspose(3,5,strides=(2,2),padding='same',use_bias=False,activation='tanh'))#64,64,3


return model

辨别器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def discriminator_model():#辨别器
model = tf.keras.Sequential()
model.add(layers.Conv2D(32,(5,5),strides=(2,2),padding='same',input_shape=(64,64,3)))
model.add(layers.LeakyReLU())#32*32*32
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(64,(5,5),strides=(2,2),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())#16,16,64
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(128,(5,5),strides=(2,2),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())#8,8,128
model.add(layers.Dropout(0.3))

model.add(layers.Conv2D(256,(5,5),strides=(2,2),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())#4,4,256

model.add(layers.GlobalAveragePooling2D())

model.add(layers.Dense(1024))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Dense(1))
return model

定义loss计算指标

1
2
# 计算loss
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

辨别器loss

1
2
3
4
def discriminator_loss(real_out,fake_out):#辨别器loss    实际图片、生成图片
real_loss = cross_entropy(tf.ones_like(real_out),real_out)#我们希望真实的图片判定为1(ones)
fake_loss = cross_entropy(tf.zeros_like(fake_out),fake_out)#我们希望生成的图片判定为0(zeros)
return real_loss+fake_loss

生成器loss

1
2
def generator_loss(fake_out):#生成器loss    实际图片、生成图片
return cross_entropy(tf.ones_like(fake_out),fake_out)#对生成器我们希望生成的图片判定为0(zeros)

设置优化器

1
2
generator_opt = tf.keras.optimizers.Adam(1e-5)#10的负5次放
discriminator_opt = tf.keras.optimizers.Adam(1e-5)#10的负5次放

设置参数

1
2
3
4
5
6
7
8
9
EPOCHS = 1000
noise_dim = 100

num_exp_to_genertor = 4#每个rpoch生成样本数量

seed = tf.random.normal([num_exp_to_genertor,noise_dim])# 正态分布随机数

generator = generator_model()
discriminator = discriminator_model()

设置每步运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE,noise_dim])

with tf.GradientTape() as gen_type,tf.GradientTape() as disc_type:
real_out = discriminator(images,training=True)#真实输出 辨别器

gen_image = generator(noise,training=True)#生成图片输出
fake_out = discriminator(gen_image,training=True)

gen_loss = generator_loss(fake_out)
disc_loss = discriminator_loss(real_out,fake_out)
gradient_gen = gen_type.gradient(gen_loss,generator.trainable_variables)#计算生成器损失与生成器变量之间的梯度
gradient_disc = disc_type.gradient(disc_loss,discriminator.trainable_variables)#计算辨别器损失与辨别器变量之间的梯度

generator_opt.apply_gradients(zip(gradient_gen,generator.trainable_variables))
discriminator_opt.apply_gradients(zip(gradient_disc,discriminator.trainable_variables))

定义绘制函数

1
2
3
4
5
6
7
8
def genrate_plot_image(gen_model,test_noise):#将生成的图片打印出来
pre_images = gen_model(test_noise,training=False)#training=False 不需要训练
fig = plt.figure(figsize=(6,6))
for i in range(pre_images.shape[0]):
plt.subplot(2,2,i+1)
plt.imshow((pre_images[i,:,:,:]+1)/2)
plt.axis('off')
plt.show()

模型训练

1
2
3
4
5
6
def train(dataset,epochs):
for epoch in range(epochs):
for image_batch in dataset:
train_step(image_batch)
print("*",end='')
genrate_plot_image(generator,seed)