使用核PCA进行图像去噪#

此示例演示如何使用 KernelPCA 对图像进行去噪。简而言之,我们利用在 fit 期间学习到的近似函数来重建原始图像。

我们将使用 PCA 进行精确重建,并将结果与之进行比较。

我们将使用USPS数字数据集来重现 [1] 第4节中介绍的内容。

参考文献

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

通过OpenML加载数据集#

USPS数字数据集可在OpenML中获得。我们使用 fetch_openml 获取此数据集。此外,我们对数据集进行归一化处理,使所有像素值都在(0, 1)范围内。

import numpy as np

from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler

X, y = fetch_openml(data_id=41082, as_frame=False, return_X_y=True)
X = MinMaxScaler().fit_transform(X)

我们的想法是在噪声图像上学习PCA基(使用和不使用核),然后使用这些模型来重建和去噪这些图像。

因此,我们将数据集分为训练集和测试集,训练集包含1000个样本,测试集包含100个样本。这些图像是无噪声的,我们将用它们来评估去噪方法的效率。此外,我们创建原始数据集的副本并添加高斯噪声。

此应用程序的目的是展示我们可以通过在一些未损坏的图像上学习PCA基来对损坏的图像进行去噪。我们将使用PCA和基于核的PCA来解决这个问题。

X_train, X_test, y_train, y_test = train_test_split(
    X, y, stratify=y, random_state=0, train_size=1_000, test_size=100
)

rng = np.random.RandomState(0)
noise = rng.normal(scale=0.25, size=X_test.shape)
X_test_noisy = X_test + noise

noise = rng.normal(scale=0.25, size=X_train.shape)
X_train_noisy = X_train + noise

此外,我们将创建一个辅助函数来通过绘制测试图像来定性地评估图像重建。

import matplotlib.pyplot as plt


def plot_digits(X, title):
    """Small helper function to plot 100 digits."""
    fig, axs = plt.subplots(nrows=10, ncols=10, figsize=(8, 8))
    for img, ax in zip(X, axs.ravel()):
        ax.imshow(img.reshape((16, 16)), cmap="Greys")
        ax.axis("off")
    fig.suptitle(title, fontsize=24)

此外,我们将使用均方误差(MSE)来定量地评估图像重建。

让我们首先看看无噪声图像和噪声图像之间的区别。我们将检查这方面的测试集。

plot_digits(X_test, "Uncorrupted test images")
plot_digits(
    X_test_noisy, f"Noisy test images\nMSE: {np.mean((X_test - X_test_noisy) ** 2):.2f}"
)
  • Uncorrupted test images
  • Noisy test images MSE: 0.06

学习PCA#

我们现在可以使用线性PCA和使用径向基函数(RBF)核的核PCA来学习我们的PCA基。

from sklearn.decomposition import PCA, KernelPCA

pca = PCA(n_components=32, random_state=42)
kernel_pca = KernelPCA(
    n_components=400,
    kernel="rbf",
    gamma=1e-3,
    fit_inverse_transform=True,
    alpha=5e-3,
    random_state=42,
)

pca.fit(X_train_noisy)
_ = kernel_pca.fit(X_train_noisy)

重建和去噪测试图像#

现在,我们可以转换和重建噪声测试集。由于我们使用的组件少于原始特征的数量,我们将得到原始集的近似值。实际上,通过丢弃在PCA中最少解释方差的组件,我们希望去除噪声。核PCA也有类似的想法;但是,我们期望得到更好的重建,因为我们使用非线性核来学习PCA基,并使用核岭来学习映射函数。

X_reconstructed_kernel_pca = kernel_pca.inverse_transform(
    kernel_pca.transform(X_test_noisy)
)
X_reconstructed_pca = pca.inverse_transform(pca.transform(X_test_noisy))
plot_digits(X_test, "Uncorrupted test images")
plot_digits(
    X_reconstructed_pca,
    f"PCA reconstruction\nMSE: {np.mean((X_test - X_reconstructed_pca) ** 2):.2f}",
)
plot_digits(
    X_reconstructed_kernel_pca,
    (
        "Kernel PCA reconstruction\n"
        f"MSE: {np.mean((X_test - X_reconstructed_kernel_pca) ** 2):.2f}"
    ),
)
  • Uncorrupted test images
  • PCA reconstruction MSE: 0.01
  • Kernel PCA reconstruction MSE: 0.03

PCA的MSE低于核PCA。但是,定性分析可能并不支持PCA而不是核PCA。我们观察到,核PCA能够去除背景噪声并提供更平滑的图像。

但是,应该注意的是,使用核PCA进行去噪的结果将取决于参数n_componentsgammaalpha

**脚本的总运行时间:**(0分钟8.871秒)

相关示例

特征聚集

特征聚集

核 PCA

核 PCA

识别手写数字

识别手写数字

人脸部件字典的在线学习

人脸部件字典的在线学习

由Sphinx-Gallery生成的图库