Berikut adalah tokoh kunci dari makalah Science 2006 oleh Hinton dan Salakhutdinov:
Ini menunjukkan pengurangan dimensi dataset MNIST ( gambar hitam dan putih dari satu digit) dari 784 dimensi asli menjadi dua.28 × 28
784 → 1000 → 500 → 250 → 2 → 250 → 500 → 1000 → 784
784 → 512 → 128 → 2 → 128 → 512 → 784
Kode ini disalin dari notebook Jupyter. Dalam Python 3.6 Anda perlu menginstal matplotlib (untuk pylab), NumPy, seaborn, TensorFlow dan Keras. Saat menjalankan shell Python, Anda mungkin perlu menambahkan plt.show()
untuk memperlihatkan plot.
Inisialisasi
%matplotlib notebook
import pylab as plt
import numpy as np
import seaborn as sns; sns.set()
import keras
from keras.datasets import mnist
from keras.models import Sequential, Model
from keras.layers import Dense
from keras.optimizers import Adam
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784) / 255
x_test = x_test.reshape(10000, 784) / 255
PCA
mu = x_train.mean(axis=0)
U,s,V = np.linalg.svd(x_train - mu, full_matrices=False)
Zpca = np.dot(x_train - mu, V.transpose())
Rpca = np.dot(Zpca[:,:2], V[:2,:]) + mu # reconstruction
err = np.sum((x_train-Rpca)**2)/Rpca.shape[0]/Rpca.shape[1]
print('PCA reconstruction error with 2 PCs: ' + str(round(err,3)));
Output ini:
PCA reconstruction error with 2 PCs: 0.056
Pelatihan autoencoder
m = Sequential()
m.add(Dense(512, activation='elu', input_shape=(784,)))
m.add(Dense(128, activation='elu'))
m.add(Dense(2, activation='linear', name="bottleneck"))
m.add(Dense(128, activation='elu'))
m.add(Dense(512, activation='elu'))
m.add(Dense(784, activation='sigmoid'))
m.compile(loss='mean_squared_error', optimizer = Adam())
history = m.fit(x_train, x_train, batch_size=128, epochs=5, verbose=1,
validation_data=(x_test, x_test))
encoder = Model(m.input, m.get_layer('bottleneck').output)
Zenc = encoder.predict(x_train) # bottleneck representation
Renc = m.predict(x_train) # reconstruction
Ini membutuhkan ~ 35 detik pada desktop pekerjaan saya dan menghasilkan:
Train on 60000 samples, validate on 10000 samples
Epoch 1/5
60000/60000 [==============================] - 7s - loss: 0.0577 - val_loss: 0.0482
Epoch 2/5
60000/60000 [==============================] - 7s - loss: 0.0464 - val_loss: 0.0448
Epoch 3/5
60000/60000 [==============================] - 7s - loss: 0.0438 - val_loss: 0.0430
Epoch 4/5
60000/60000 [==============================] - 7s - loss: 0.0423 - val_loss: 0.0416
Epoch 5/5
60000/60000 [==============================] - 7s - loss: 0.0412 - val_loss: 0.0407
jadi Anda sudah bisa melihat bahwa kami melampaui kehilangan PCA setelah hanya dua zaman pelatihan.
(Omong-omong, itu adalah instruktif untuk mengubah semua fungsi aktivasi ke activation='linear'
dan untuk mengamati bagaimana kerugian konvergen tepat ke hilangnya PCA. Itu karena autoencoder linier setara dengan PCA.)
Merencanakan proyeksi PCA berdampingan dengan representasi bottleneck
plt.figure(figsize=(8,4))
plt.subplot(121)
plt.title('PCA')
plt.scatter(Zpca[:5000,0], Zpca[:5000,1], c=y_train[:5000], s=8, cmap='tab10')
plt.gca().get_xaxis().set_ticklabels([])
plt.gca().get_yaxis().set_ticklabels([])
plt.subplot(122)
plt.title('Autoencoder')
plt.scatter(Zenc[:5000,0], Zenc[:5000,1], c=y_train[:5000], s=8, cmap='tab10')
plt.gca().get_xaxis().set_ticklabels([])
plt.gca().get_yaxis().set_ticklabels([])
plt.tight_layout()
Rekonstruksi
Dan sekarang mari kita lihat rekonstruksi (baris pertama - gambar asli, baris kedua - PCA, baris ketiga - autoencoder):
plt.figure(figsize=(9,3))
toPlot = (x_train, Rpca, Renc)
for i in range(10):
for j in range(3):
ax = plt.subplot(3, 10, 10*j+i+1)
plt.imshow(toPlot[j][i,:].reshape(28,28), interpolation="nearest",
vmin=0, vmax=1)
plt.gray()
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
plt.tight_layout()
Seseorang dapat memperoleh hasil yang lebih baik dengan jaringan yang lebih dalam, beberapa regularisasi, dan pelatihan yang lebih lama. Percobaan. Belajar mendalam itu mudah!