Примечание
Перейти в конец чтобы скачать полный пример кода или запустить этот пример в браузере через JupyterLite или Binder.
Удаление шума с изображения с использованием ядерного PCA#
Этот пример показывает, как использовать KernelPCA для
шумоподавления изображений. Короче говоря, мы используем преимущество аппроксимационной функции,
изученной во время fit для восстановления исходного изображения.
Мы сравним результаты с точной реконструкцией, используя
PCA.
Мы будем использовать набор данных цифр USPS для воспроизведения, представленного в разделе 4 [1].
Ссылки
# 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}"
)
Обучить PCA базис#
Теперь мы можем обучить наш базис PCA, используя как линейный PCA, так и ядерный PCA, который использует ядро радиальной базисной функции (RBF).
Восстановите и очистите тестовые изображения от шума#
Теперь мы можем преобразовать и восстановить зашумленный тестовый набор. Поскольку мы использовали меньше компонентов, чем количество исходных признаков, мы получим приближение исходного набора. Действительно, отбрасывая компоненты, объясняющие наименьшую дисперсию в 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}"
),
)
PCA имеет меньшую MSE, чем kernel PCA. Однако качественный анализ может не отдавать предпочтение PCA вместо kernel PCA. Мы наблюдаем, что kernel PCA способен удалять фоновый шум и обеспечивать более гладкое изображение.
Однако следует отметить, что результаты шумоподавления с помощью ядерного PCA
будут зависеть от параметров n_components, gamma, и alpha.
Общее время выполнения скрипта: (0 минут 7.614 секунд)
Связанные примеры




