📜  ML |具有TensorFlow 2.0的自动编码器

📅  最后修改于: 2021-04-17 03:57:33             🧑  作者: Mango

本教程演示了如何通过训练Autoencoder在TensorFlow 2.0中使用图模式执行来生成手写数字图像。

自动编码器是使用神经网络和/或卷积神经网络实现的数据压缩和解压缩算法。数据被压缩为瓶颈,该瓶颈的维数小于初始输入的维数。解压缩使用中间表示来再次生成相同的输入图像。让我们使用TensorFlow 2.0编写一个好的AutoEncoder,默认情况下它急切地希望了解该算法的机制。自动编码器被认为是GAN和CVAE等更高级的生成模型的良好先决条件。
首先,根据可用的硬件下载TensorFlow 2.0。如果您使用的是Google Colab,请遵循此IPython Notebook或此colab演示。确保可以安装GPU的适当版本的CUDA和CUDNN。在此处访问TensorFlow页面上的官方下载说明。

代码:导入库

# Install TensorFlow 2.0 by using the following command
# For CPU installation
# pip install -q tensorflow == 2.0
# For GPU installation (CUDA and CuDNN must be available)
# pip install -q tensorflow-gpu == 2.0
  
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
  
  
import tensorflow as tf
print(tf.__version__)

确认适当的TF下载后,添加其他依赖项以进行数据扩充并定义自定义函数,如下所示。标准缩放器通过对列进行排列来对数据进行分类。使用tf.GradientTape来执行AutoDiff(自动微分)以获取渐变时,get_random_block_from_data函数非常有用。

import numpy as np
import sklearn.preprocessing as prep
import tensorflow.keras.layers as layers
  
def standard_scale(X_train, X_test):
    preprocessor = prep.StandardScaler().fit(X_train)
    X_train = preprocessor.transform(X_train)
    X_test = preprocessor.transform(X_test)
    return X_train, X_test
  
def get_random_block_from_data(data, batch_size):
    start_index = np.random.randint(0, len(data) - batch_size)
    return data[start_index:(start_index + batch_size)]

自动编码器可能具有有损的中间表示形式,也称为压缩表示形式。这种降维在存在无损图像数据压缩的众多用例中很有用。因此,可以说AutoEncoder的编码器部分对数据的密集表示进行编码。在这里,我们将使用TensorFlow子类化API定义编码器和解码器的自定义层。

class Encoder(tf.keras.layers.Layer):
    '''Encodes a digit from the MNIST dataset'''
      
    def __init__(self,
                n_dims,
                name ='encoder',
                **kwargs):
        super(Encoder, self).__init__(name = name, **kwargs)
        self.n_dims = n_dims
        self.n_layers = 1
        self.encode_layer = layers.Dense(n_dims, activation ='relu')
          
    @tf.function        
    def call(self, inputs):
        return self.encode_layer(inputs)
  
class Decoder(tf.keras.layers.Layer):
    '''Decodes a digit from the MNIST dataset'''
  
    def __init__(self,
                n_dims,
                name ='decoder',
                **kwargs):
        super(Decoder, self).__init__(name = name, **kwargs)
        self.n_dims = n_dims
        self.n_layers = len(n_dims)
        self.decode_middle = layers.Dense(n_dims[0], activation ='relu')
        self.recon_layer = layers.Dense(n_dims[1], activation ='sigmoid')
          
    @tf.function        
    def call(self, inputs):
        x = self.decode_middle(inputs)
        return self.recon_layer(x)

然后,我们扩展tf.keras.Model来定义一个自定义模型,该模型利用我们先前定义的自定义层来形成AutoEncoder模型。当数据可用于模型对象时,调用函数将被覆盖,这是前向传递。注意@tf。函数函数装饰器。它确保函数执行在图形中进行,从而加快了我们的执行速度。

class Autoencoder(tf.keras.Model):
    '''Vanilla Autoencoder for MNIST digits'''
      
    def __init__(self,
                 n_dims =[200, 392, 784],
                 name ='autoencoder',
                 **kwargs):
        super(Autoencoder, self).__init__(name = name, **kwargs)
        self.n_dims = n_dims
        self.encoder = Encoder(n_dims[0])
        self.decoder = Decoder([n_dims[1], n_dims[2]])
          
    @tf.function        
    def call(self, inputs):
        x = self.encoder(inputs)
        return self.decoder(x)

下面的代码块准备数据集,并准备好数据,以便在训练AutoEncoder之前将其馈送到函数的预处理管道中。

mnist = tf.keras.datasets.mnist
  
(X_train, _), (X_test, _) = mnist.load_data()
X_train = tf.cast(np.reshape(
        X_train, (X_train.shape[0], 
                  X_train.shape[1] * X_train.shape[2])), tf.float64)
X_test = tf.cast(
        np.reshape(X_test, 
                   (X_test.shape[0], 
                    X_test.shape[1] * X_test.shape[2])), tf.float64)
  
X_train, X_test = standard_scale(X_train, X_test)

TensorFlow最佳实践是使用tf.data.Dataset快速从数据集中获取带有混洗批次的张量切片以进行训练。以下代码块演示了tf.data的用法,还定义了用于训练AutoEncoder模型的超参数。

train_data = tf.data.Dataset.from_tensor_slices(
        X_train).batch(128).shuffle(buffer_size = 1024)
test_data = tf.data.Dataset.from_tensor_slices(
        X_test).batch(128).shuffle(buffer_size = 512)
  
n_samples = int(len(X_train) + len(X_test))
training_epochs = 20
batch_size = 128
display_step = 1
  
optimizer = tf.optimizers.Adam(learning_rate = 0.01)
mse_loss = tf.keras.losses.MeanSquaredError()
loss_metric = tf.keras.metrics.Mean()

我们已经完成了训练AutoEncoder模型的所有前提条件!我们剩下要做的就是定义一个AutoEncoder对象,并在调用model.train上面的超参数之前,使用优化器和损失编译模型。瞧!您会看到损耗减少,自动编码器提高了性能!

ae = Autoencoder([200, 392, 784])
ae.compile(optimizer = tf.optimizers.Adam(0.01), 
           loss ='categorical_crossentropy')
ae.fit(X_train, X_train, batch_size = 64, epochs = 5)

您可以在此处检出IPython Notebook,并在此处检出我提交给TensorFlow的colab演示。在GitHub上关注我。