Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.

Устранение шума на изображениях с помощью ядерного PCA

В этом примере показано, как использовать KernelPCA для устранения шума на изображениях. Кратко говоря, мы используем аппроксимирующую функцию, полученную в процессе fit, чтобы восстановить исходное изображение.

Мы сравним результаты с точным восстановлением с помощью PCA.

Мы воспользуемся набором данных цифр USPS, чтобы воспроизвести результаты, представленные в разд. 4 работы [1].

Литература

[1]

Bakır, Gökhan H., Jason Weston и Bernhard Schölkopf. «Обучение поиску прообразов». Advances in Neural Information Processing Systems 16 (2004): 449–456.

# 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 (с ядром и без него) на зашумлённых изображениях, а затем используем эти модели для восстановления изображений и устранения шума.

Для этого мы разделим набор данных на обучающую и тестовую выборки: 1 000 образцов для обучения и 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, используя как линейный PCA, так и ядерный PCA с ядром радиальной базисной функции (RBF).

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 зависят от параметров n_components, gamma и alpha.

Общее время выполнения скрипта: (0 минут 6,176 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_digits_denoising.ipynb

Download Python source code: plot_digits_denoising.py

Download zipped: plot_digits_denoising.zip

Связанные примеры

Агломерация признаков

Ядерный PCA

Распознавание рукописных цифр

Онлайн-обучение словаря частей лиц

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/applications/plot_digits_denoising.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API