TensorFlow深度学习实战——去噪自编码器详解与实现

发布于:2025-07-08 ⋅ 阅读:(15) ⋅ 点赞:(0)

0. 前言

去噪自编码器 (Denoising Autoencoder, DAE) 是一种自编码器 (Autoencoder) 的变体,其主要目的是通过学习从噪声数据中恢复无噪数据来提高特征学习的能力。与传统自编码器不同,去噪自编码器在训练过程中故意对输入数据添加噪声,然后要求模型从这些“损坏”的输入中恢复出原始的、无噪声的输入数据。通过这种方式,去噪自编码器能够学习到更加鲁棒和具有判别力的特征。

1. 去噪自编码器架构

瓶颈层维度低于输入(输出)层的自编码器属于欠完备自编码器 (undercomplete autoencoders),而去噪自编码器属于过完备自编码器 (overcomplete autoencoders),因为当瓶颈层的维度大于输入层时,重建表现更好。
去噪自编码器从有噪声的输入中学习,将带有噪声的输入到编码器网络,然后将解码器重建的图像与原始图像进行比较。核心思想在于,使网络学习如何去噪,自编码器不再仅仅进行逐像素比较,而是通过去噪,同时学习邻近像素的信息。
去噪自编码器与其他自编码器有两个主要区别:首先,瓶颈层中的隐藏单元数量 n_hidden 大于输入层的单元数 m,即 n_hidden > m。其次,编码器的输入是带有噪声的输入。
因此,需要在测试和训练图像中都添加噪声:

noise = np.random.normal(loc=0.5, scale=0.5, size=x_train.shape)
x_train_noisy = x_train + noise
noise = np.random.normal(loc=0.5, scale=0.5, size=x_test.shape)
x_test_noisy = x_test + noise
x_train_noisy = np.clip(x_train_noisy, 0., 1.)
x_test_noisy = np.clip(x_test_noisy, 0., 1.)

接下来,实现去噪自编码器,观察去噪自编码器的去噪效果。

2. 使用去噪自编码器去除图像中的噪声

在本节中,使用去噪自编码器去除 MNIST 手写数字图像中的噪声。

(1) 首先,导入所需的模块:

import numpy as np
import tensorflow as tf
import tensorflow.keras as K
import matplotlib.pyplot as plt

(2) 定义模型的超参数:

batch_size = 256
max_epochs = 50
learning_rate = 1e-3
momentum = 8e-1
hidden_dim = 128
original_dim = 784

(3) 加载 MNIST 数据集,对其进行标准化,并向其中添加噪声:

(x_train, _), (x_test, _) = K.datasets.mnist.load_data()

x_train = x_train / 255.
x_test = x_test / 255.

x_train = x_train.astype(np.float32)
x_test = x_test.astype(np.float32)

x_train = np.reshape(x_train, (x_train.shape[0], 784))
x_test = np.reshape(x_test, (x_test.shape[0], 784))

noise = np.random.normal(loc=0.5, scale=0.5, size=x_train.shape)
x_train_noisy = x_train + noise
noise = np.random.normal(loc=0.5, scale=0.5, size=x_test.shape)
x_test_noisy = x_test + noise

(4) 定义编码器、解码器和自编码器类:

class Encoder(K.layers.Layer):
    def __init__(self, hidden_dim):
        super(Encoder, self).__init__()
        self.hidden_layer = K.layers.Dense(units=hidden_dim, activation=tf.nn.relu)
        
    def call(self, input_features):
        activation = self.hidden_layer(input_features)
        return activation

class Decoder(K.layers.Layer):
    def __init__(self, hidden_dim, original_dim):
        super(Decoder, self).__init__()
        self.output_layer = K.layers.Dense(units=original_dim, activation=tf.nn.relu)
  
    def call(self, encoded):
        activation = self.output_layer(encoded)
        return activation

class Autoencoder(K.Model):
    def __init__(self, hidden_dim, original_dim):
        super(Autoencoder, self).__init__()
        self.loss = []
        self.encoder = Encoder(hidden_dim=hidden_dim)
        self.decoder = Decoder(hidden_dim=hidden_dim, original_dim=original_dim)

    def call(self, input_features):
        encoded = self.encoder(input_features)
        reconstructed = self.decoder(encoded)
        return reconstructed

(5) 创建模型,并定义损失函数和优化器。使用 TensorFlow 内置 compile()fit() 方法,而未编写自定义训练循环:

model = Autoencoder(hidden_dim=hidden_dim, original_dim=original_dim)

model.compile(loss='mse', optimizer='adam')

loss = model.fit(x_train_noisy,
                x_train,
                validation_data=(x_test_noisy, x_test),
                epochs=max_epochs,
                verbose=2,
                batch_size=batch_size)

(6) 绘制训练过程中损失的变化:

plt.plot(range(max_epochs), loss.history['loss'])
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.show()

下图显示了每个 epoch 的损失:

去噪自编码器

3. 图像去噪效果

观察模型的实际去噪效果:

number = 10  # how many digits we will display
plt.figure(figsize=(20, 4))
for index in range(number):
    # display original
    ax = plt.subplot(2, number, index + 1)
    plt.imshow(x_test_noisy[index].reshape(28, 28), cmap='gray')
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # display reconstruction
    ax = plt.subplot(2, number, index + 1 + number)
    plt.imshow(model(x_test_noisy)[index].numpy().reshape(28, 28), cmap='gray')
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

下图中,第一行是带噪声的输入图像,第二行是由训练后的去噪自编码器生成的清晰图像:

去噪结果

相关链接

TensorFlow深度学习实战(1)——神经网络与模型训练过程详解
TensorFlow深度学习实战(2)——使用TensorFlow构建神经网络
TensorFlow深度学习实战(3)——深度学习中常用激活函数详解
TensorFlow深度学习实战(4)——正则化技术详解
TensorFlow深度学习实战(5)——神经网络性能优化技术详解
TensorFlow深度学习实战(6)——回归分析详解
TensorFlow深度学习实战(7)——分类任务详解
TensorFlow深度学习实战(8)——卷积神经网络
TensorFlow深度学习实战(9)——构建VGG模型实现图像分类
TensorFlow深度学习实战(10)——迁移学习详解
TensorFlow深度学习实战(11)——风格迁移详解
TensorFlow深度学习实战(15)——编码器-解码器架构
TensorFlow深度学习实战(16)——注意力机制详解
TensorFlow深度学习实战(17)——主成分分析详解
TensorFlow深度学习实战(18)——K-means 聚类详解
TensorFlow深度学习实战(19)——受限玻尔兹曼机
TensorFlow深度学习实战(20)——自组织映射详解
TensorFlow深度学习实战(23)——自编码器详解与实现
TensorFlow深度学习实战(24)——卷积自编码器详解与实现
TensorFlow深度学习实战——稀疏自编码器详解与实现