Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец для скачивания полного кода примера или для запуска этого примера в вашем браузере через JupyterLite или Binder

Деноизинг изображений с помощью ядрового PCA

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

Мы сравним результаты с точной реконструкцией, используя PCA.

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

Ссылки

[1]

Bakır, Gökhan H., Jason Weston, and Bernhard Schölkopf. “Learning to find pre-images.” 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 (с ядром и без него) на шумных изображениях, а затем использовании этих моделей для реконструкции и деноизинга этих изображений.

Таким образом, мы разделим наш набор данных на обучающий и тестовый, состоящие из 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, используя как линейный 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 имеет меньшую среднеквадратичную ошибку, чем ядровый PCA. Однако качественный анализ может не показать преимущество PCA над ядром PCA. Мы наблюдаем, что ядровый PCA способен удалить фоновый шум и получить более гладкое изображение.

Однако следует отметить, что результаты деноизинга с ядром PCA зависят от параметров n_components, gamma, и alpha.

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

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–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/applications/plot_digits_denoising.html

Spec-Zone.ru

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