Bawię się zabawkowym przykładem, aby zrozumieć autoencoder PCA kontra keras
Mam następujący kod do zrozumienia PCA:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import decomposition
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
pca = decomposition.PCA(n_components=3)
pca.fit(X)
pca.explained_variance_ratio_
array([ 0.92461621, 0.05301557, 0.01718514])
pca.components_
array([[ 0.36158968, -0.08226889, 0.85657211, 0.35884393],
[ 0.65653988, 0.72971237, -0.1757674 , -0.07470647],
[-0.58099728, 0.59641809, 0.07252408, 0.54906091]])
Zrobiłem kilka odczytów i odtwarzam kody za pomocą kamer, w tym ten.
Jednak kod referencyjny wydaje się zbyt dużym skokiem dla mojego poziomu zrozumienia.
Czy ktoś ma krótki kod automatycznego kodera, który może mi pokazać
(1) jak wyciągnąć pierwsze 3 elementy z automatycznego kodera
(2) w jaki sposób zrozumieć, jaką różnicę rejestruje auto-enkoder
(3) jak komponenty autokodera porównują się z komponentami PCA
Odpowiedzi:
3 dla odpowiedzi № 1Po pierwsze, celem autokodera jestnauczyć się reprezentacji (kodowania) dla zestawu danych, zwykle w celu zmniejszenia wymiarów. Tak więc docelowym wyjściem autoencodera jest samo wejście autoencodera.
W [1] pokazano, że jeśli istnieje jedna liniowa ukryta warstwa, a do wyszkolenia sieci zastosowano kryterium błędu średniego kwadratu, wówczas k
ukryte jednostki uczą się rzutować dane wejściowe w zakresie first k principal components
danych. A w [2] widać, że jeśli ukryta warstwa jest nieliniowa, autoencoder zachowuje się inaczej niż PCA, z możliwością uchwycenia multimodalnych aspektów rozkładu wejściowego.
Autoencodery są specyficzne dla danych, co oznacza, żebędą tylko w stanie kompresować dane podobne do tego, na czym zostali przeszkoleni. Tak więc przydatność funkcji poznanych przez ukryte warstwy może być wykorzystana do oceny skuteczności metody.
Z tego powodu jednym ze sposobów ocenySkuteczność autoencodera w redukcji wymiarów polega na zmniejszeniu wydajności środkowej ukrytej warstwy i porównaniu dokładności / wydajności pożądanego algorytmu na podstawie tych zredukowanych danych, a nie przy użyciu oryginalnych danych. Zasadniczo PCA jest metodą liniową, podczas gdy autokodery są zwykle nieliniowe. Matematycznie trudno jest je ze sobą porównać, ale intuicyjnie podam przykład zmniejszenia wymiarów w zestawie danych MNIST przy użyciu Autoencodera dla lepszego zrozumienia. Kod jest tutaj:
from keras.datasets import mnist
from keras.models import Model
from keras.layers import Input, Dense
from keras.utils import np_utils
import numpy as np
num_train = 60000
num_test = 10000
height, width, depth = 28, 28, 1 # MNIST images are 28x28
num_classes = 10 # there are 10 classes (1 per digit)
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(num_train, height * width)
X_test = X_test.reshape(num_test, height * width)
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
X_train /= 255 # Normalise data to [0, 1] range
X_test /= 255 # Normalise data to [0, 1] range
Y_train = np_utils.to_categorical(y_train, num_classes) # One-hot encode the labels
Y_test = np_utils.to_categorical(y_test, num_classes) # One-hot encode the labels
input_img = Input(shape=(height * width,))
x = Dense(height * width, activation="relu")(input_img)
encoded = Dense(height * width//2, activation="relu")(x)
encoded = Dense(height * width//8, activation="relu")(encoded)
y = Dense(height * width//256, activation="relu")(x)
decoded = Dense(height * width//8, activation="relu")(y)
decoded = Dense(height * width//2, activation="relu")(decoded)
z = Dense(height * width, activation="sigmoid")(decoded)
model = Model(input_img, z)
model.compile(optimizer="adadelta", loss="mse") # reporting the accuracy
model.fit(X_train, X_train,
epochs=10,
batch_size=128,
shuffle=True,
validation_data=(X_test, X_test))
mid = Model(input_img, y)
reduced_representation =mid.predict(X_test)
out = Dense(num_classes, activation="softmax")(y)
reduced = Model(input_img, out)
reduced.compile(loss="categorical_crossentropy",
optimizer="adam",
metrics=["accuracy"])
reduced.fit(X_train, Y_train,
epochs=10,
batch_size=128,
shuffle=True,
validation_data=(X_test, Y_test))
scores = reduced.evaluate(X_test, Y_test, verbose=1)
print("Accuracy: ", scores[1])
Wytwarza $ yin mathbb {R} ^ {3} $ (prawie jak to, co dostajesz decomposition.PCA(n_components=3)
). Na przykład tutaj widać wyniki warstwy y
dla cyfry 5
instancja w zbiorze danych:
class y_1 y_2 y_3
5 87.38 0.00 20.79
Jak widać w powyższym kodzie, kiedy łączymy warstwę y
do a softmax
gęsta warstwa:
mid = Model(input_img, y)
reduced_representation =mid.predict(X_test)
nowy model mid
daj nam dobrą dokładność klasyfikacji 95%
. Rozsądnie byłoby to powiedzieć y
, jest wydajnie wyodrębnionym wektorem funkcji dla zestawu danych.
Referencje:
[1]: Bourlard, Hervé i Yves Kamp. „Auto-asocjacja przez wielowarstwowe perceptrony i rozkład wartości osobliwych”. Cybernetyka biologiczna 59.4 (1988): 291–294.
[2]: Japkowicz, Nathalie, Stephen Jose Hanson i Mark A. Gluck. „Nieliniowe automatyczne powiązanie nie jest równoważne z PCA”. Obliczenia neuronowe 12.3 (2000): 531-545.