はじめに
この実験では、Kernel PCA を使って画像のノイズ除去を行う方法を示します。その考え方は、ノイズのない画像に基づいて PCA の基底を学習し、それを使ってノイズのある画像を再構成してノイズ除去することです。この目的のために、USPS の数字データセットを使用します。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。
時々、Jupyter Notebook が読み込み終了するまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証は自動化できません。
学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
OpenML を使ってデータセットを読み込む
scikit-learn のfetch_openml()関数を使って、USPS の数字データセットを読み込みます。その後、MinMaxScaler()を使ってデータを正規化します。
import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
X, y = fetch_openml(data_id=41082, as_frame=False, return_X_y=True, parser="pandas")
X = MinMaxScaler().fit_transform(X)
学習用とテスト用のセットを作成する
データセットを、サンプル数 1000 の学習用セットと、サンプル数 100 のテスト用セットに分割します。テスト用セットにガウスノイズを加え、元のデータのコピーを 2 つ作成します。1 つはノイズがあるものと、もう 1 つはノイズのないものです。
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):
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)
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 と Kernel PCA の両方を使って PCA の基底を学習します。Kernel 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 と Kernel 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}"
),
)
まとめ
この実験では、Kernel PCA を使って画像のノイズを除去する方法を学びました。USPS の数字データセットを使ってそのプロセスを示しました。ノイズのない画像に基づいて PCA の基底を学び、それを使ってノイズのある画像を再構成してノイズを除去しました。線形 PCA と Kernel PCA の両方の結果を比較し、Kernel PCA は背景ノイズを除去し、画像を滑らかにするのにより効率的であることがわかりました。ただし、n_components、gamma、およびalphaに適切な値を選択する際には注意が必要です。