提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
@GAN入门实例【个人理解】
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包
tf.__version__
(train_images,train_labels), (_, _)=tf.keras.datasets.mnist.load_data()
等号左边第一括号是训练数据,第二个括号是测试数据,测试数据暂时不需要,就先用占位符占着,等号右边是加载mnist数据集
train_images.shape
train_images.dtype
train_images = train_images.reshape(train_images.shape[0],28,28,1).astype('float32')
reshape成一个四维张量
train_images = (train_images-127.5)/127.5
BATCH_SIZE = 256
BUFFER_SIZE = 6000
归一化有两种方式:
( img/127.5)-1:图像x取值范围[-1,1]
datasets = tf.data.Dataset.from_tensor_slices(train_images)
tf.data.Dataset.from_tensor_slices
-该函数是dataset核心函数之一,它的作用是把给定的元组、列表和张量等数据进行特征切片。切片的范围是从最外层维度开始的。如果有多个特征进行组合,那么一次切片是把每个组合的最外维度的数据切开,分成一组一组的
datasets = datasets.shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
shuffle:
datasets
def generator_model():
model = keras.Sequential()
model.add(layers.Dense(256,input_shape=(100,), use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Dense(512, use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Dense(28*28*1, use_bias=False,activation = 'tanh'))
model.add(layers.BatchNormalization())
model.add(layers.Reshape((28,28,1)))
return model
Sequential
参考 https://blog.csdn.net/mogoweb/article/details/82152174
Dense
卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。因为用到了所有的局部特征,所以叫全连接
BatchNormalization
def discriminator_model():
model = keras.Sequential()
model.add(layers.Flatten())
model.add(layers.Dense(512, use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Dense(256, use_bias=False))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Dense(1))
return model
Flatten
因为随着预测值越来越准确,交叉熵的值越来越小。
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
binaryCrossentropy()
tf.keras.losses.BinaryCrossentropy(yTrue,yPred)
from_logits
转载https://blog.csdn.net/muyuu/article/details/122762442
def discriminator_loss(real_out,fake_out):
read_loss = cross_entropy(tf.ones_like(real_out),real_out)
fake_loss = cross_entropy(tf.zeros_like(fake_out),fake_out)
return read_loss+fake_loss
我们希望real_out被判定为1;fake_out被判定为0.
def generator_loss(fake_out):
return cross_entropy(tf.ones_like(fake_out),fake_out)
我们希望生成的图片尽可能多的1;
generator_opt = tf.keras.optimizers.Adam(1e-4)
discriminator_opt = tf.keras.optimizers.Adam(1e-4)
几种常用优化器:
随机梯度下降法(SGD):
keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
lr:大或等于0的浮点数,学习率
momentum:大或等于0的浮点数,动量参数
decay:大或等于0的浮点数,每次更新后的学习率衰减值
nesterov:布尔值,确定是否使用Nesterov动量
Adagrad:
keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)
epsilon:大或等于0的小浮点数,防止除0错误
Adam
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
beta_1/beta_2:浮点数, 0
EPOCHS = 100
noise_dim = 100
num_exp_to_generate = 16
seed = tf.random.normal([num_exp_to_generate,noise_dim])
noise_dim = 100:
用长度为100的随机向量来生成手写数据集
num_exp_to_generate = 16
16个
tf.random_normal()
tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
服从指定正态分布的序列”中随机取出指定个数的值。
shape: 输出张量的形状,必选
转载:https://blog.csdn.net/dcrmg/article/details/79028043
generator = generator_model()
discriminator = discriminator_model()
def train_step(images):
noise = tf.random.normal([BATCH_SIZE,noise_dim])
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
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_tape.gradient(gen_loss,generator.trainable_variables)
gradient_disc = disc_tape.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))
with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:追踪两个model生成的梯度。
with enter() as variable:执行过程
关于梯度函数gradients,可参考
https://blog.csdn.net/QKK612501/article/details/115335437?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=2
apply_gradients(
grads_and_vars, name=None, experimental_aggregate_gradients=True
)
def generator_plot_image(gen_model,test_noise):
pre_images = gen_model(test_noise,training=False)
fig = plt.figure(figsize=(4,4))
for i in range(pre_images.shape[0]):
plt.subplot(4,4,i+1)
plt.imshow((pre_images[i, :, :, 0]+1)/2,cmap='gray')
plt.axis('off')
plt.show()
figure(figsize=(4,4)):初始4*4的画布,因为噪音有16个
subplot(4,4,i+1):四行四列第i+1个
imshow((pre_images[i, :, :, 0]+1)/2,cmap=‘gray’):显示第i张图片,取所有的长和宽,tanh的范围是[-1,1]将其转化为[0,1]上,画布是灰色的
plt.axis(‘off’):不显示坐标
def train(dataset,epochs):
for epoch in range(epochs):
for image_batch in dataset:
train_step(image_batch)
print('.',end='')
generator_plot_image(generator,seed)
train(datasets,EPOCHS)
懵懵懂懂的过了一遍,对全连接层还是很不理解,继续加油吧!争取早日毕业