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版本
查看是否支持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)