赞
踩
AE的思想是在1986年被提出来的,在接下来的几年,AE的思想席卷了个大研究论文。关于AE比较有代表性的模型有一下几种:
a r g m i n ( − log q ( x ∣ z ) ) = a r g m i n 1 2 ∥ x − μ ~ ( z ) σ ~ ( z ) ∥ 2 + c 2 log 2 π + 1 2 = a r g m i n 1 2 ∥ x − μ ~ ( z ) σ ~ ( z ) ∥ 2 argmin(−log q(x|z))=argmin12‖x−˜μ(z)˜σ(z)‖2+c2log 2π+12=argmin12‖x−˜μ(z)˜σ(z)‖2 argmin(−log q(x∣z))=argmin21∥∥∥∥σ~(z)x−μ~(z)∥∥∥∥2+2clog 2π+21=argmin21∥∥∥∥σ~(z)x−μ~(z)∥∥∥∥2
import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf import numpy as np from tensorflow import keras from tensorflow.keras import Sequential, layers from PIL import Image tf.random.set_seed(22) np.random.seed(22) assert tf.__version__.startswith('2.') # 合并多张图片 def save_images(imgs, name): new_im = Image.new('L', (280, 280)) index = 0 for i in range(0, 280, 28): for j in range(0, 280, 28): im = imgs[index] im = Image.fromarray(im, mode='L') new_im.paste(im, (i, j)) index += 1 new_im.save(name) h_dim = 10 batch_size = 10000 lr = 1e-3 # 一、获取数据集 (X_train, Y_train), (X_val, Y_val) = keras.datasets.fashion_mnist.load_data() # 二、数据处理:处理训练集为batch模型(不需要目标值) X_train = X_train.astype(np.float32) / 255. db_train = tf.data.Dataset.from_tensor_slices(X_train) db_train = db_train.shuffle(batch_size * 5).batch(batch_size) X_val = X_val.astype(np.float32) / 255. db_val = tf.data.Dataset.from_tensor_slices(X_val) db_val = db_val.batch(batch_size) print('X_train.shpae = {0},Y_train.shpae = {1},tf.reduce_max(Y_train) = {2},tf.reduce_min(Y_train) = {3}'.format(X_train.shape, Y_train.shape, tf.reduce_max(Y_train), tf.reduce_min(Y_train))) print('X_val.shpae = {0},Y_val.shpae = {1},tf.reduce_max(Y_val) = {2},tf.reduce_min(Y_val) = {3}'.format(X_val.shape, Y_val.shape, tf.reduce_max(Y_val), tf.reduce_min(Y_val))) # 三、创建AutoEncoder神经网络模型 class AutoEncoder(keras.Model): def __init__(self): super(AutoEncoder, self).__init__() # Encoders self.encoder = Sequential([ layers.Dense(256, activation=tf.nn.relu), # [b, 784] => [b, 256] layers.Dense(128, activation=tf.nn.relu), # [b, 256] => [b, 128] layers.Dense(h_dim) # [b, 128] => [b, 10] ]) # Decoders self.decoder = Sequential([ layers.Dense(128, activation=tf.nn.relu), # [b, 10] => [b, 128] layers.Dense(256, activation=tf.nn.relu), # [b, 128] => [b, 256] layers.Dense(784) # [b, 256] => [b, 784] ]) def call(self, inputs, training=None): # [b, 784] => [b, 10] h_out = self.encoder(inputs) # [b, 10] => [b, 784] x_hat = self.decoder(h_out) return x_hat # 四、实例化AutoEncoder神经网络模型 model = AutoEncoder() model.build(input_shape=(None, 784)) model.summary() optimizer = tf.optimizers.Adam(lr=lr) # 五、训练模型:整体数据集进行一次梯度下降来更新模型参数,整体数据集迭代一次,一般用epoch。每个epoch中含有batch_step_no个step,每个step中样本的数量就是设置的每个batch所含有的样本数量。 def train_epoch(epoch_no): for batch_step_no, X_batch in enumerate(db_train): # 每次计算一个batch的数据,循环结束则计算完毕整体数据的一次前向传播;每个batch的序号一般用step表示(batch_step_no) X_batch = tf.reshape(X_batch, [-1, 784]) # [b, 28, 28] => [b, 784] print('\tX_batch.shape = {0}'.format(X_batch.shape)) with tf.GradientTape() as tape: X_batch_hat_logits = model(X_batch) print('\tX_batch_hat_logits.shape = {0}'.format(X_batch_hat_logits.shape)) CrossEntropy_Loss = tf.losses.binary_crossentropy(X_batch, X_batch_hat_logits, from_logits=True) CrossEntropy_Loss = tf.reduce_mean(CrossEntropy_Loss) grads = tape.gradient(CrossEntropy_Loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) print('\t第{0}个epoch-->第{1}个batch step的初始时的:CrossEntropy_Loss = {2}'.format(epoch_no, batch_step_no + 1, CrossEntropy_Loss)) # 六、模型评估 test/evluation def evluation(epoch_no): X_batch = next(iter(db_val)) X_batch_784 = tf.reshape(X_batch, [-1, 784]) print('\tX_batch_784.shape = {0}'.format(X_batch_784.shape)) X_batch_logits_hat = model(X_batch_784) # model包含了encoder、decoder两大步骤 X_batch_prob_hat = tf.sigmoid(X_batch_logits_hat) X_batch_prob_hat = tf.reshape(X_batch_prob_hat, [-1, 28, 28]) # [b, 784] => [b, 28, 28] print('\tX_batch_prob_hat.shape = {0}'.format(X_batch_prob_hat.shape)) # X_batch_concat = tf.concat([X_batch, X_batch_prob_hat], axis=0) # [b, 28, 28] => [2b, 28, 28] # print('\tX_batch_concat.shape = {0}'.format(X_batch_concat.shape)) # X_batch_concat = X_batch_prob_hat X_batch_hat = X_batch_prob_hat.numpy() * 255. X_batch_hat = X_batch_hat.astype(np.uint8) save_images(X_batch_hat, 'AutoEncoder_images/rec_epoch_%d.png' % epoch_no) # 六、整体数据迭代多次梯度下降来更新模型参数 def train(): epoch_count = 3 # epoch_count为整体数据集迭代梯度下降次数 for epoch_no in range(1, epoch_count + 1): print('\n\n利用整体数据集进行模型的第{0}轮Epoch迭代开始:**********************************************************************************************************************************'.format(epoch_no)) train_epoch(epoch_no) evluation(epoch_no) print('利用整体数据集进行模型的第{0}轮Epoch迭代结束:**********************************************************************************************************************************'.format(epoch_no)) if __name__ == '__main__': train()
打印结果:
X_train.shpae = (60000, 28, 28),Y_train.shpae = (60000,),tf.reduce_max(Y_train) = 9,tf.reduce_min(Y_train) = 0 X_val.shpae = (10000, 28, 28),Y_val.shpae = (10000,),tf.reduce_max(Y_val) = 9,tf.reduce_min(Y_val) = 0 Model: "auto_encoder" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= sequential (Sequential) (None, 10) 235146 _________________________________________________________________ sequential_1 (Sequential) (None, 784) 235920 ================================================================= Total params: 471,066 Trainable params: 471,066 Non-trainable params: 0 _________________________________________________________________ 利用整体数据集进行模型的第1轮Epoch迭代开始:********************************************************************************************************************************** X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第1个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 0.6930073499679565 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第1个epoch-->第2个batch step的初始时的:CrossEntropy_Loss = 0.690101146697998 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第1个epoch-->第3个batch step的初始时的:CrossEntropy_Loss = 0.6838963627815247 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第1个epoch-->第4个batch step的初始时的:CrossEntropy_Loss = 0.6729660034179688 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第1个epoch-->第5个batch step的初始时的:CrossEntropy_Loss = 0.6565828323364258 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第1个epoch-->第6个batch step的初始时的:CrossEntropy_Loss = 0.6356714963912964 X_batch_784.shape = (10000, 784) X_batch_prob_hat.shape = (10000, 28, 28) 利用整体数据集进行模型的第1轮Epoch迭代结束:********************************************************************************************************************************** 利用整体数据集进行模型的第2轮Epoch迭代开始:********************************************************************************************************************************** X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第2个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 0.6140648722648621 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第2个epoch-->第2个batch step的初始时的:CrossEntropy_Loss = 0.595238447189331 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第2个epoch-->第3个batch step的初始时的:CrossEntropy_Loss = 0.5807722806930542 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第2个epoch-->第4个batch step的初始时的:CrossEntropy_Loss = 0.5614200234413147 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第2个epoch-->第5个batch step的初始时的:CrossEntropy_Loss = 0.5468764901161194 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第2个epoch-->第6个batch step的初始时的:CrossEntropy_Loss = 0.5310028195381165 X_batch_784.shape = (10000, 784) X_batch_prob_hat.shape = (10000, 28, 28) 利用整体数据集进行模型的第2轮Epoch迭代结束:********************************************************************************************************************************** 利用整体数据集进行模型的第3轮Epoch迭代开始:********************************************************************************************************************************** X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第3个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 0.5188546180725098 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第3个epoch-->第2个batch step的初始时的:CrossEntropy_Loss = 0.5084328055381775 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第3个epoch-->第3个batch step的初始时的:CrossEntropy_Loss = 0.49996528029441833 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第3个epoch-->第4个batch step的初始时的:CrossEntropy_Loss = 0.4927319288253784 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第3个epoch-->第5个batch step的初始时的:CrossEntropy_Loss = 0.4851318299770355 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第3个epoch-->第6个batch step的初始时的:CrossEntropy_Loss = 0.4777812361717224 X_batch_784.shape = (10000, 784) X_batch_prob_hat.shape = (10000, 28, 28) 利用整体数据集进行模型的第3轮Epoch迭代结束:********************************************************************************************************************************** 利用整体数据集进行模型的第4轮Epoch迭代开始:********************************************************************************************************************************** X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第4个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 0.4697949290275574 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第4个epoch-->第2个batch step的初始时的:CrossEntropy_Loss = 0.4621494710445404 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第4个epoch-->第3个batch step的初始时的:CrossEntropy_Loss = 0.45390141010284424 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第4个epoch-->第4个batch step的初始时的:CrossEntropy_Loss = 0.447597473859787 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第4个epoch-->第5个batch step的初始时的:CrossEntropy_Loss = 0.4424560070037842 X_batch.shape = (10000, 784) X_batch_hat_logits.shape = (10000, 784) 第4个epoch-->第6个batch step的初始时的:CrossEntropy_Loss = 0.4317522943019867 X_batch_784.shape = (10000, 784) X_batch_prob_hat.shape = (10000, 28, 28) 利用整体数据集进行模型的第4轮Epoch迭代结束:********************************************************************************************************************************** Process finished with exit code 0
import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf import numpy as np from tensorflow import keras from tensorflow.keras import Sequential, layers from PIL import Image tf.random.set_seed(22) np.random.seed(22) assert tf.__version__.startswith('2.') # 合并多张图片 def save_images(imgs, name): new_im = Image.new('L', (280, 280)) index = 0 for i in range(0, 280, 28): for j in range(0, 280, 28): im = imgs[index] im = Image.fromarray(im, mode='L') new_im.paste(im, (i, j)) index += 1 new_im.save(name) h_dim = 20 batch_size = 500 lr = 1e-3 # 一、获取数据集 (X_train, Y_train), (X_val, Y_val) = keras.datasets.fashion_mnist.load_data() # 二、数据处理:处理训练集为batch模型(不需要目标值) X_train = X_train.astype(np.float32) / 255. db_train = tf.data.Dataset.from_tensor_slices(X_train) db_train = db_train.shuffle(batch_size * 5).batch(batch_size) X_val = X_val.astype(np.float32) / 255. db_val = tf.data.Dataset.from_tensor_slices(X_val) db_val = db_val.batch(batch_size) print('X_train.shpae = {0},Y_train.shpae = {1},tf.reduce_max(Y_train) = {2},tf.reduce_min(Y_train) = {3}'.format(X_train.shape, Y_train.shape, tf.reduce_max(Y_train), tf.reduce_min(Y_train))) print('X_val.shpae = {0},Y_val.shpae = {1},tf.reduce_max(Y_val) = {2},tf.reduce_min(Y_val) = {3}'.format(X_val.shape, Y_val.shape, tf.reduce_max(Y_val), tf.reduce_min(Y_val))) z_dim = 10 class VAE(keras.Model): def __init__(self): super(VAE, self).__init__() # Encoder self.fc1 = layers.Dense(128) # 将图片降维得 latent vector:[b, 784] => [b, 128] self.fc2 = layers.Dense(z_dim) # fc1-->fc2--获得latent vector的均值预测值:[b, 128] => [b, 10] self.fc3 = layers.Dense(z_dim) # fc1-->fc3--获得latent vector的方差预测值:[b, 128] => [b, 10] # Decoder self.fc4 = layers.Dense(128) # [b, 20] => [b, 128] self.fc5 = layers.Dense(784) # [b, 128] => [b, 784] def encoder(self, x): h = tf.nn.relu(self.fc1(x)) # 将图片降维得 latent vector:[b, 784] => [b, 128] mu = self.fc2(h) # fc1-->fc2--获得latent vector的均值预测值:[b, 128] => [b, 10] log_var = self.fc3(h) # fc1-->fc3--获得latent vector的方差预测值:[b, 128] => [b, 10] return mu, log_var def decoder(self, z): out = tf.nn.relu(self.fc4(z)) # [b, 20] => [b, 128] out = self.fc5(out) # [b, 128] => [b, 784] return out def reparameterize(self, mu, log_var): eps = tf.random.normal(log_var.shape) std = tf.exp(log_var) ** 0.5 z = mu + std * eps return z def call(self, inputs, training=None): mu, log_var = self.encoder(inputs) # [b, 784] => [b, z_dim], [b, z_dim] z = self.reparameterize(mu, log_var) # reparameterization trick x_hat = self.decoder(z) return x_hat, mu, log_var # 四、实例化VAE神经网络模型 model = VAE() # model包含了encoder、reparameterize、decoder三大步骤 model.build(input_shape=(4, 784)) optimizer = tf.optimizers.Adam(lr) # 五、训练模型:整体数据集进行一次梯度下降来更新模型参数,整体数据集迭代一次,一般用epoch。每个epoch中含有batch_step_no个step,每个step中样本的数量就是设置的每个batch所含有的样本数量。 def train_epoch(epoch_no): for batch_step_no, X_batch in enumerate(db_train): # 每次计算一个batch的数据,循环结束则计算完毕整体数据的一次前向传播;每个batch的序号一般用step表示(batch_step_no) X_batch = tf.reshape(X_batch, [-1, 784]) # [b, 28, 28] => [b, 784] with tf.GradientTape() as tape: x_rec_logits, mu, log_var = model(X_batch) # 计算reconstruction损失 rec_loss = tf.nn.sigmoid_cross_entropy_with_logits(labels=X_batch, logits=x_rec_logits) rec_loss = tf.reduce_sum(rec_loss) / X_batch.shape[0] # 计算 kl-Divergence (mu, var) ~ N (0, 1);https://stats.stackexchange.com/questions/7440/kl-divergence-between-two-univariate-gaussians kl_div = -0.5 * (log_var + 1 - mu ** 2 - tf.exp(log_var)) kl_div = tf.reduce_sum(kl_div) / X_batch.shape[0] # 合并rec_loss与kl_div作为模型的整体损失 Loss = rec_loss + 1. * kl_div # 系数 1 表示 rec_loss 与 kl_div之间的权衡 grads = tape.gradient(Loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) if batch_step_no % 60 == 0: print('\t第{0}个epoch-->第{1}个batch step的初始时的:CrossEntropy_Loss = {2}'.format(epoch_no, batch_step_no + 1, Loss)) # 六、模型评估 test/evluation def evluation(epoch_no): # sampling:生成新图片 z = tf.random.normal((batch_size, z_dim)) logits = model.decoder(z) # 利用decoder作为generator将随机数据z生成原来数据集中没有的图片 x_hat = tf.sigmoid(logits) x_hat = tf.reshape(x_hat, [-1, 28, 28]).numpy() * 255. x_hat = x_hat.astype(np.uint8) save_images(x_hat, 'vae_images/sampled_epoch%d.png' % epoch_no) # reconstruction x = next(iter(db_val)) x = tf.reshape(x, [-1, 784]) x_hat_logits, _, _ = model(x) # model包含了encoder、reparameterize、decoder三大步骤 x_hat = tf.sigmoid(x_hat_logits) x_hat = tf.reshape(x_hat, [-1, 28, 28]).numpy() * 255. x_hat = x_hat.astype(np.uint8) save_images(x_hat, 'vae_images/rec_epoch%d.png' % epoch_no) # 六、整体数据迭代多次梯度下降来更新模型参数 def train(): epoch_count = 3 # epoch_count为整体数据集迭代梯度下降次数 for epoch_no in range(1, epoch_count + 1): print('\n\n利用整体数据集进行模型的第{0}轮Epoch迭代开始:**********************************************************************************************************************************'.format(epoch_no)) train_epoch(epoch_no) evluation(epoch_no) print('利用整体数据集进行模型的第{0}轮Epoch迭代结束:**********************************************************************************************************************************'.format(epoch_no)) if __name__ == '__main__': train()
打印结果:
X_train.shpae = (60000, 28, 28),Y_train.shpae = (60000,),tf.reduce_max(Y_train) = 9,tf.reduce_min(Y_train) = 0 X_val.shpae = (10000, 28, 28),Y_val.shpae = (10000,),tf.reduce_max(Y_val) = 9,tf.reduce_min(Y_val) = 0 利用整体数据集进行模型的第1轮Epoch迭代开始:********************************************************************************************************************************** 第1个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 548.28759765625 第1个epoch-->第61个batch step的初始时的:CrossEntropy_Loss = 332.11102294921875 利用整体数据集进行模型的第1轮Epoch迭代结束:********************************************************************************************************************************** 利用整体数据集进行模型的第2轮Epoch迭代开始:********************************************************************************************************************************** 第2个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 296.1214294433594 第2个epoch-->第61个batch step的初始时的:CrossEntropy_Loss = 281.6827697753906 利用整体数据集进行模型的第2轮Epoch迭代结束:********************************************************************************************************************************** 利用整体数据集进行模型的第3轮Epoch迭代开始:********************************************************************************************************************************** 第3个epoch-->第1个batch step的初始时的:CrossEntropy_Loss = 268.88427734375 第3个epoch-->第61个batch step的初始时的:CrossEntropy_Loss = 265.4090576171875 利用整体数据集进行模型的第3轮Epoch迭代结束:********************************************************************************************************************************** Process finished with exit code 0
参考资料:
A wizard’s guide to Adversarial Autoencoders: Part 1, Autoencoder?
Applied Deep Learning - Part 3: Autoencoders
Ref: Rifai, Salah, et al. "Contractive auto-encoders: Explicit invariance during feature extraction.“ Proceedings of the 28th International Conference on Machine Learning (ICML-11). 2011.
Vincent, Pascal, et al. “Extracting and composing robust features with denoising autoencoders.” ICML, 2008.
自动编码器与PCA的比较
深度学习笔记 | 第17讲:深度生成模型之自编码器(AutoEncoder)
autoencoder
Building Autoencoders in Keras
1. AutoEncoder介绍
几种AutoEncoder原理
Dropout in (Deep) Machine learning
A wizard’s guide to Adversarial Autoencoders: Part 2, Exploring latent space with Adversarial Autoencoders.
解析Variational AutoEncoder(VAE)
VAE(Variational Autoencoder)的原理
Variational AutoEncoder系列
Variational autoencoders.
Variational_Auto-Encoder
Variational Autoencoder in TensorFlow
Generate Anime Character with Variational Auto-encoder
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。