Примечание
Перейти в конец для скачивания полного кода примера или для запуска этого примера в вашем браузере через 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).
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}"
),
)
PCA имеет меньшую среднеквадратичную ошибку, чем ядровый PCA. Однако качественный анализ может не показать преимущество PCA над ядром PCA. Мы наблюдаем, что ядровый PCA способен удалить фоновый шум и получить более гладкое изображение.
Однако следует отметить, что результаты деноизинга с ядром PCA зависят от параметров n_components, gamma, и alpha.
Общее время выполнения скрипта: (0 минут 8.569 секунд)
Связанные примеры
© 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




