TensorFlow实现去噪自编码器(Denoising Autoencoder)

去噪自编码器(Denoising Autoencoder, DAE)

在介绍去噪自编码器 (Denoising Autoencoder, DAE) 之前,首先介绍下DAE的一种使用场景示例,当我们在夜晚拍照时,或者其他黑暗环境时,我们的照片总是被大量的噪点所充斥,严重影响了图像质量,而 DAE 的目的就是用来去除这些图像中的噪声。为了更好的讲解 DAE,使用简单的 MNIST 数据集进行演示,以将我们的重心放在有关 DAE 的知识上。如下图所示,显示了三组 MNIST 数字。每组的顶行是原始图像 (Original Images);中间的行显示 DAE 的输入 (Noised Images),这些输入是被噪声破坏的原始图像,当噪声过多时,我们将很难读懂被破坏的数字;最后一行显示DAE的输出 (Denoised Images)。

DAE示例

Tips:如果对于自编码器还不是很了解的小伙伴,可以参考自编码器模型详解与实现(采用tensorflow2.x实现)

接下来就让我们实际构建一个 DAE,以消除图像中的噪声。

DAE模型架构

DAE模型架构根据 DAE 的介绍可以将输入定义为:
x = x o r i g + n o i s e x = x_{orig} + noise x=xorig+noise
其中 x o r i g x_{orig} xorig 表示被噪声 n o i s e noise noise 破坏的原始 MNIST 图像,编码器的目的是学习潜矢量 z z z。DAE的损失函数表示为:
L ( x o r i g , x ~ ) = M S E = 1 m ∑ i = 1 i = m ( x o r i g i − x ~ i ) 2 \mathcal L(x_{orig}, \tilde x)=MSE=\frac 1 m \sum_{i=1} ^{i=m}(x_{orig_i}-\tilde x_i)^2 L(xorig,x~)=MSE=m1i=1i=m(xorigix~i)2

其中, m m m 是输出的维度,例如在MNIST数据集中, m = w i d t h × h e i g h t × c h a n n e l s = 28 × 28 × 1 = 784 m=width × height×channels=28 × 28 × 1 = 784 m=width×height×channels=28×28×1=784 x o r i g i x_{orig_i} xorigi x i x_i xi 分别是 x o r i g x_{orig} xorig x ~ \tilde x x~ 中的元素。

DAE实现

数据预处理

为了实现DAE,首先需要构造训练数据集,输入数据是添加噪声的 MNIST 数字,训练输出数据是原始的干净 MNIST 数字。添加的噪声需要满足高斯分布,均值 μ = 0.5 μ = 0.5 μ=0.5,标准差 σ = 0.5 σ = 0.5 σ=0.5。由于添加随机噪声可能会产生小于0或大于1的无效像素值,因此需要将像素值裁剪为[0.0,1.0]范围内。

import numpy as np
import tensorflow as tf
from tensorflow import keras
from matplotlib import pyplot as plt
from PIL import Image

# 数据加载
(x_train,_),(x_test,_) = keras.datasets.mnist.load_data()

# 数据预处理
image_size = x_train.shape[1]
x_train = np.reshape(x_train,[-1,image_size,image_size,1])
x_test = np.reshape(x_test,[-1,image_size,image_size,1])
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.

# 产生高斯分布的噪声
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

# 将像素值裁剪为[0.0,1.0]范围内
x_train_noisy = np.clip(x_train_noisy,0.0,1.0)
x_test_noisy = np.clip(x_test_noisy,0.0,1.0)

模型构建与模型训练

# 超参数
input_shape = (image_size,image_size,1)
batch_size = 32
kernel_size = 3
latent_dim = 16
layer_filters = [32,64]

"""
模型
"""
#编码器
inputs = keras.layers.Input(shape=input_shape,name='encoder_input')
x = inputs
for filters in layer_filters:
    x = keras.layers.Conv2D(filters=filters,
            kernel_size=kernel_size,
            strides=2,
            activation='relu',
            padding='same')(x)
shape = keras.backend.int_shape(x)

x = keras.layers.Flatten()(x)
latent = keras.layers.Dense(latent_dim,name='latent_vector')(x)
encoder = keras.Model(inputs,latent,name='encoder')
encoder.summary()

# 解码器
latent_inputs = keras.layers.Input(shape=(latent_dim,),name='decoder_input')
x = keras.layers.Dense(shape[1]*shape[2]*shape[3])(latent_inputs)
x = keras.layers.Reshape((shape[1],shape[2],shape[3]))(x)
for filters in layer_filters[::-1]:
    x = keras.layers.Conv2DTranspose(filters=filters,
            kernel_size=kernel_size,
            strides=2,
            padding='same',
            activation='relu')(x)
outputs = keras.layers.Conv2DTranspose(filters=1,
        kernel_size=kernel_size,
        padding='same',
        activation='sigmoid',
        name='decoder_output')(x)
decoder = keras.Model(latent_inputs,outputs,name='decoder')
decoder.summary

autoencoder = keras.Model(inputs,decoder(encoder(inputs)),name='autoencoder')
autoencoder.summary()

# 模型编译与训练
autoencoder.compile(loss='mse',optimizer='adam')
autoencoder.fit(x_train_noisy,
        x_train,validation_data=(x_test_noisy,x_test),
        epochs=10,
        batch_size=batch_size)

# 模型测试
x_decoded = autoencoder.predict(x_test_noisy)

rows,cols = 3,9
num = rows * cols
imgs = np.concatenate([x_test[:num],x_test_noisy[:num],x_decoded[:num]])
imgs = imgs.reshape((rows * 3, cols, image_size, image_size))
imgs = np.vstack(np.split(imgs,rows,axis=1))
imgs = imgs.reshape((rows * 3,-1,image_size,image_size))
imgs = np.vstack([np.hstack(i) for i in imgs])
imgs = (imgs * 255).astype(np.uint8)
plt.figure()
plt.axis('off')
plt.imshow(imgs,interpolation='none',cmap='gray')
plt.show()

效果展示

模型效果
如上图所示,当噪声水平从 σ = 0.5 σ=0.5 σ=0.5 增加到 σ = 0.75 σ=0.75 σ=0.75 σ = 1.0 σ=1.0 σ=1.0 时,DAE 具有一定的鲁棒性,可以较好的恢复出原始图像。但是,在 σ = 1.0 σ=1.0 σ=1.0 时,某些数字,没有被正确地恢复。

  • 25
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 40
    评论
Autoencoder和K-means是两种常用的无监督学习方法,可以用于数据降维和聚类。下面是一个关于如何使用Autoencoder和K-means进行数据降维和聚类的示例: 1. Autoencoder是一种神经网络模型,它可以将输入数据压缩成低维编码,然后再将编码解压缩为与原始数据尽可能接近的形式。这种压缩和解压缩的过程可以用于数据降维,即将高维数据转换为低维表示。在这个示例中,我们使用Autoencoder对图像数据进行降维。 ```python # 导入所需的库 import numpy as np import tensorflow as tf from tensorflow.keras.layers import Input, Dense from tensorflow.keras.models import Model # 加载数据 data = np.load('data.npy') # 构建Autoencoder模型 input_dim = data.shape[1] encoding_dim = 98 input_layer = Input(shape=(input_dim,)) encoder_layer = Dense(encoding_dim, activation='relu')(input_layer) decoder_layer = Dense(input_dim, activation='sigmoid')(encoder_layer) autoencoder = Model(input_layer, decoder_layer) # 编译和训练模型 autoencoder.compile(optimizer='adam', loss='binary_crossentropy') autoencoder.fit(data, data, epochs=10, batch_size=32) # 获取编码器模型 encoder = Model(input_layer, encoder_layer) # 使用编码器对数据进行降维 encoded_data = encoder.predict(data) ``` 2. K-means是一种聚类算法,它将数据分成K个不同的簇,使得每个数据点都属于与其最近的簇。在这个示例中,我们使用K-means对降维后的数据进行聚类。 ```python from sklearn.cluster import KMeans # 构建K-means模型 kmeans = KMeans(n_clusters=10) # 对降维后的数据进行聚类 kmeans.fit(encoded_data) # 获取聚类结果 labels = kmeans.labels_ ``` 通过结合Autoencoder和K-means,我们可以将高维数据降低到较低的维度,并使用K-means对降维后的数据进行聚类。这样可以加快对未标记数据的标记过程。
评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盼小辉丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值