代码示例 / 计算机视觉 / 卷积自编码器用于图像去噪

卷积自编码器用于图像去噪

作者: Santiago L. Valdarrama
创建日期: 2021/03/01
最后修改: 2021/03/01
描述: 如何训练一个深度卷积自编码器用于图像去噪。

在 Colab 中查看 GitHub 源代码


介绍

本示例演示如何实现一个深度卷积自编码器用于图像去噪,将来自 MNIST 数据集的噪声数字图像映射到干净数字图像。该实现基于 François Chollet 的一篇原始博客文章 在 Keras 中构建自编码器


环境设置

import numpy as np
import matplotlib.pyplot as plt

from keras import layers
from keras.datasets import mnist
from keras.models import Model


def preprocess(array):
    """规范化提供的数组并重塑它。"""
    array = array.astype("float32") / 255.0
    array = np.reshape(array, (len(array), 28, 28, 1))
    return array


def noise(array):
    """向提供的数组中的每个图像添加随机噪声。"""
    noise_factor = 0.4
    noisy_array = array + noise_factor * np.random.normal(
        loc=0.0, scale=1.0, size=array.shape
    )

    return np.clip(noisy_array, 0.0, 1.0)


def display(array1, array2):
    """显示每个数组中的十张随机图像。"""
    n = 10
    indices = np.random.randint(len(array1), size=n)
    images1 = array1[indices, :]
    images2 = array2[indices, :]

    plt.figure(figsize=(20, 4))
    for i, (image1, image2) in enumerate(zip(images1, images2)):
        ax = plt.subplot(2, n, i + 1)
        plt.imshow(image1.reshape(28, 28))
        plt.gray()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)

        ax = plt.subplot(2, n, i + 1 + n)
        plt.imshow(image2.reshape(28, 28))
        plt.gray()
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)

    plt.show()

准备数据

# 因为我们只需要数据集中的图像进行编码和解码,
# 所以我们不会使用标签。
(train_data, _), (test_data, _) = mnist.load_data()

# 规范化并重塑数据
train_data = preprocess(train_data)
test_data = preprocess(test_data)

# 创建一份添加噪声的数据副本
noisy_train_data = noise(train_data)
noisy_test_data = noise(test_data)

# 显示训练数据及其带噪声的版本
display(train_data, noisy_train_data)
正在从 https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz 下载数据
 11490434/11490434 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step

png


构建自编码器

我们将使用函数式 API 来构建我们的卷积自编码器。

input = layers.Input(shape=(28, 28, 1))

# 编码器
x = layers.Conv2D(32, (3, 3), activation="relu", padding="same")(input)
x = layers.MaxPooling2D((2, 2), padding="same")(x)
x = layers.Conv2D(32, (3, 3), activation="relu", padding="same")(x)
x = layers.MaxPooling2D((2, 2), padding="same")(x)

# 解码器
x = layers.Conv2DTranspose(32, (3, 3), strides=2, activation="relu", padding="same")(x)
x = layers.Conv2DTranspose(32, (3, 3), strides=2, activation="relu", padding="same")(x)
x = layers.Conv2D(1, (3, 3), activation="sigmoid", padding="same")(x)

# 自编码器
autoencoder = Model(input, x)
autoencoder.compile(optimizer="adam", loss="binary_crossentropy")
autoencoder.summary()
模型: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ 层 (类型)                      输出形状                参数数量 ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 输入层 (InputLayer)        │ (, 28, 28, 1)         │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 卷积层 (Conv2D)                 │ (, 28, 28, 32)        │        320 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 最大池化层 (MaxPooling2D)    │ (, 14, 14, 32)        │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 卷积层_1 (Conv2D)               │ (, 14, 14, 32)        │      9,248 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 最大池化层_1 (MaxPooling2D)  │ (, 7, 7, 32)          │          0 │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 转置卷积层                │ (, 14, 14, 32)        │      9,248 │
│ (Conv2DTranspose)               │                           │            │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 转置卷积层_1              │ (, 28, 28, 32)        │      9,248 │
│ (Conv2DTranspose)               │                           │            │
├─────────────────────────────────┼───────────────────────────┼────────────┤
│ 卷积层_2 (Conv2D)               │ (, 28, 28, 1)         │        289 │
└─────────────────────────────────┴───────────────────────────┴────────────┘
 总参数: 28,353 (110.75 KB)
 可训练参数: 28,353 (110.75 KB)
 非可训练参数: 0 (0.00 B)

现在我们可以使用 train_data 作为输入数据和目标来训练我们的自编码器。注意我们使用相同格式设置验证数据。

autoencoder.fit(
    x=train_data,
    y=train_data,
    epochs=50,
    batch_size=128,
    shuffle=True,
    validation_data=(test_data, test_data),  # 验证数据
)
周期 1/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 8s 9ms/步 - 损失: 0.2537 - 验证损失: 0.0723
周期 2/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0718 - 验证损失: 0.0691
周期 3/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0695 - 验证损失: 0.0677
周期 4/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0682 - 验证损失: 0.0669
周期 5/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0673 - 验证损失: 0.0664
周期 6/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0668 - 验证损失: 0.0660
周期 7/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0664 - 验证损失: 0.0657
周期 8/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0661 - 验证损失: 0.0654
周期 9/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0657 - 验证损失: 0.0651
周期 10/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0655 - 验证损失: 0.0648
周期 11/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0653 - 验证损失: 0.0646
周期 12/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0651 - 验证损失: 0.0644
周期 13/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0649 - 验证损失: 0.0643
周期 14/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0647 - 验证损失: 0.0641
周期 15/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0646 - 验证损失: 0.0640
周期 16/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0645 - 验证损失: 0.0639
周期 17/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0642 - 验证损失: 0.0638
周期 18/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0641 - 验证损失: 0.0638
周期 19/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0640 - 验证损失: 0.0636
周期 20/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0639 - 验证损失: 0.0637
周期 21/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0639 - 验证损失: 0.0634
周期 22/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0637 - 验证损失: 0.0634
周期 23/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0636 - 验证损失: 0.0633
周期 24/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0637 - 验证损失: 0.0632
周期 25/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0635 - 验证损失: 0.0632
周期 26/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0635 - 验证损失: 0.0631
周期 27/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0635 - 验证损失: 0.0630
周期 28/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0635 - 验证损失: 0.0629
周期 29/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0634 - 验证损失: 0.0630
周期 30/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0633 - 验证损失: 0.0629
周期 31/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0633 - 验证损失: 0.0628
周期 32/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0632 - 验证损失: 0.0628
周期 33/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0631 - 验证损失: 0.0627
周期 34/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0631 - 验证损失: 0.0627
周期 35/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0630 - 验证损失: 0.0627
周期 36/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0631 - 验证损失: 0.0626
周期 37/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0629 - 验证损失: 0.0626
周期 38/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0630 - 验证损失: 0.0627
周期 39/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0630 - 验证损失: 0.0625
周期 40/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0629 - 验证损失: 0.0625
周期 41/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0628 - 验证损失: 0.0625
周期 42/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0629 - 验证损失: 0.0625
周期 43/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0629 - 验证损失: 0.0624
周期 44/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0628 - 验证损失: 0.0624
周期 45/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0628 - 验证损失: 0.0624
周期 46/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0627 - 验证损失: 0.0625
周期 47/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0628 - 验证损失: 0.0623
周期 48/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0627 - 验证损失: 0.0623
周期 49/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0626 - 验证损失: 0.0623
周期 50/50
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/步 - 损失: 0.0626 - 验证损失: 0.0622

<keras.src.callbacks.history.History 在 0x7ff5889d9930>

让我们在测试数据集上进行预测,并展示原始图像及其自动编码器的预测结果。

请注意,虽然预测结果与原始图像相差不多,但并不完全相同。

predictions = autoencoder.predict(test_data)
display(test_data, predictions)
 313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 1ms/step

png

现在我们知道我们的自动编码器有效,让我们使用噪声数据作为输入,干净数据作为目标重新训练它。我们希望我们的自动编码器学习如何去噪图像。

autoencoder.fit(
    x=noisy_train_data,
    y=train_data,
    epochs=100,
    batch_size=128,
    shuffle=True,
    validation_data=(noisy_test_data, test_data),
)
Epoch 1/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.1110 - val_loss: 0.0922
Epoch 2/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0925 - val_loss: 0.0904
Epoch 3/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0910 - val_loss: 0.0895
Epoch 4/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0900 - val_loss: 0.0888
Epoch 5/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0892 - val_loss: 0.0882
Epoch 6/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0887 - val_loss: 0.0878
Epoch 7/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0884 - val_loss: 0.0874
Epoch 8/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0880 - val_loss: 0.0871
Epoch 9/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0876 - val_loss: 0.0869
Epoch 10/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0875 - val_loss: 0.0868
Epoch 11/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0872 - val_loss: 0.0864
Epoch 12/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0870 - val_loss: 0.0863
Epoch 13/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0869 - val_loss: 0.0860
Epoch 14/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0868 - val_loss: 0.0859
Epoch 15/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0865 - val_loss: 0.0857
Epoch 16/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0863 - val_loss: 0.0857
Epoch 17/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0863 - val_loss: 0.0858
Epoch 18/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0862 - val_loss: 0.0854
Epoch 19/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0859 - val_loss: 0.0856
Epoch 20/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0859 - val_loss: 0.0853
Epoch 21/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0858 - val_loss: 0.0851
Epoch 22/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0857 - val_loss: 0.0851
Epoch 23/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0856 - val_loss: 0.0850
Epoch 24/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0855 - val_loss: 0.0850
Epoch 25/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0853 - val_loss: 0.0849
Epoch 26/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0855 - val_loss: 0.0849
Epoch 27/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0853 - val_loss: 0.0849
Epoch 28/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0853 - val_loss: 0.0848
Epoch 29/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0853 - val_loss: 0.0850
Epoch 30/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0854 - val_loss: 0.0847
Epoch 31/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0851 - val_loss: 0.0846
Epoch 32/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0851 - val_loss: 0.0846
Epoch 33/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0846
Epoch 34/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0851 - val_loss: 0.0847
Epoch 35/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0846
Epoch 36/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0844
Epoch 37/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0845
Epoch 38/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0848 - val_loss: 0.0844
Epoch 39/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0843
Epoch 40/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0844
Epoch 41/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0848 - val_loss: 0.0844
Epoch 42/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0848 - val_loss: 0.0844
Epoch 43/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0849 - val_loss: 0.0846
Epoch 44/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0846 - val_loss: 0.0843
Epoch 45/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0847 - val_loss: 0.0845
Epoch 46/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0846 - val_loss: 0.0843
Epoch 47/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0845 - val_loss: 0.0842
Epoch 48/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0846 - val_loss: 0.0842
Epoch 49/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0847 - val_loss: 0.0846
Epoch 50/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0847 - val_loss: 0.0843
Epoch 51/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0846 - val_loss: 0.0842
Epoch 52/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0846 - val_loss: 0.0844
Epoch 53/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0844 - val_loss: 0.0842
Epoch 54/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0845 - val_loss: 0.0842
Epoch 55/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0845 - val_loss: 0.0841
Epoch 56/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0844
Epoch 57/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0845 - val_loss: 0.0841
Epoch 58/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0843
Epoch 59/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0842
Epoch 60/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0844 - val_loss: 0.0847
Epoch 61/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0846 - val_loss: 0.0840
Epoch 62/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0840
Epoch 63/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 64/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0844 - val_loss: 0.0841
Epoch 65/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 66/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 67/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0840
Epoch 68/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 69/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0840
Epoch 70/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 71/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0844 - val_loss: 0.0841
Epoch 72/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0840
Epoch 73/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 74/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0844 - val_loss: 0.0840
Epoch 75/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0840
Epoch 76/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0842
Epoch 77/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0841
Epoch 78/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0841
Epoch 79/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0840
Epoch 80/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0843 - val_loss: 0.0839
Epoch 81/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0842
Epoch 82/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0839
Epoch 83/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0840
Epoch 84/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0839
Epoch 85/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0839
Epoch 86/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0840 - val_loss: 0.0838
Epoch 87/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0839
Epoch 88/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0838
Epoch 89/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0838
Epoch 90/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0840
Epoch 91/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0839
Epoch 92/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0842 - val_loss: 0.0838
Epoch 93/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0838
Epoch 94/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0838
Epoch 95/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0840 - val_loss: 0.0837
Epoch 96/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0838
Epoch 97/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0838
Epoch 98/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0837
Epoch 99/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0841 - val_loss: 0.0838
Epoch 100/100
 469/469 ━━━━━━━━━━━━━━━━━━━━ 2s 3ms/step - loss: 0.0839 - val_loss: 0.0839

<keras.src.callbacks.history.History at 0x7ff5889da230>

现在让我们对噪声数据进行预测,并显示我们的自编码器的结果。

注意自编码器在去除输入图像的噪声方面表现得非常出色。

predictions = autoencoder.predict(noisy_test_data)
display(noisy_test_data, predictions)
 313/313 ━━━━━━━━━━━━━━━━━━━━ 0s 523us/step

png