67. 卷积自动编码器图像去噪#
67.1. 介绍#
通过前面的实验,你应该了解了一个基础自动编码器的结构及作用。本次挑战中,需要独立构建一个包含卷积结构的自动编码器,完成图片去噪任务。
67.2. 知识点#
卷积自动编码器
图像去噪
TensorFlow Keras
本次挑战仍然沿用大家熟悉的 MNIST 数据集。该数据集较为简单,其他大规模数据集会耗费相当长的训练时间。
和实验相似的是,这里将手写字符图像除以 255 完成归一化,并只选择 30000 个训练样本和 100 个测试样本。与此同时,我们需要对数据添加高斯噪声。区别于前面的实验,这里不再对图像进行展平,因为本次挑战需要构建卷积自动编码器。
import numpy as np
import tensorflow as tf
# 读取数据
(X_train, _), (X_test, _) = tf.keras.datasets.mnist.load_data()
# 选取数据并归一化
X_train = X_train[:30000] / 255
X_test = X_test[:100] / 255
# 添加随机高斯噪声
X_train_ = X_train + 0.4 * np.random.normal(size=X_train.shape)
X_test_ = X_test + 0.4 * np.random.normal(size=X_test.shape)
X_train_noisy = np.clip(X_train_, 0, 1)
X_test_noisy = np.clip(X_test_, 0, 1)
X_train.shape, X_train_noisy.shape, X_test.shape, X_test_noisy.shape
((30000, 28, 28), (30000, 28, 28), (100, 28, 28), (100, 28, 28))
接下来,我们开始构建一个已知结构的卷积自动编码器。其中,编码器部分肯定会用到熟悉的卷积层和池化层,但解码器部分需要与池化层相反的上采样层 tf.keras.layers.UpSampling2D
🔗。这一点很好理解,因为池化层本身对应的是下采样的过程。
挑战:按照下图所示的网络结构矢量图,使用 tf.keras
API 定义一个卷积自动编码器网络。
上图结构中 input_1
为输入,conv2d_1
代表输出。你也可以参考下方 Keras 模型期望输出定义网络,二者是一致的。
## 代码开始 ###
model = None
## 代码结束 ###
Solution to Exercise 67.1
input_ = tf.keras.layers.Input(shape=(28, 28, 1))
conv1 = tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same')(input_)
encoded = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(conv1)
up1 = tf.keras.layers.UpSampling2D((2, 2))(encoded)
decoded = tf.keras.layers.Conv2D(1, (3, 3), activation='sigmoid', padding='same')(up1)
model = tf.keras.models.Model(input_, decoded)
model.compile(optimizer='Adam', loss='binary_crossentropy')
运行测试
model.summary()
期望输出:
Layer (type) Output Shape Param #
=================================================================
input_7 (InputLayer) (None, 28, 28, 1) 0
_________________________________________________________________
conv2d_11 (Conv2D) (None, 28, 28, 32) 320
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 14, 14, 32) 0
_________________________________________________________________
up_sampling2d_5 (UpSampling2 (None, 28, 28, 32) 0
_________________________________________________________________
conv2d_12 (Conv2D) (None, 28, 28, 1) 289
=================================================================
Total params: 609
Trainable params: 609
Non-trainable params: 0
_________________________________________________________________
接下来,你可能需要将数据处理成网络能输入的形状,并自定义合适的参数完成网络训练。
挑战:完成自动编码器网络训练,并参考实验内容,使用前 5 个测试样本来对比去噪前后的效果。
## 补充代码 ###
Solution to Exercise 67.2
X_train_noisy = X_train_noisy.reshape(-1, 28, 28, 1)
X_train = X_train.reshape(-1, 28, 28, 1)
model.fit(X_train_noisy, X_train, batch_size=64, epochs=3)
from matplotlib import pyplot as plt
%matplotlib inline
n = 5
decoded_code = model.predict(
X_test_noisy[:n].reshape(-1, 28, 28, 1)) # 自动编码器推理
plt.figure(figsize=(10, 6))
for i in range(n):
# 输出原始测试样本图像
ax = plt.subplot(3, n, i+1)
plt.imshow(X_test_noisy[i].reshape(28, 28), cmap='gray')
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
# 输出自动编码器去噪后的图像
ax = plt.subplot(3, n, i+n+1)
plt.imshow(decoded_code[i].reshape(28, 28), cmap='gray')
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
期望输出:
如果你觉得这些内容对你有帮助,可以通过 微信赞赏码 或者 Buy Me a Coffee 请我喝杯咖啡。