본문 바로가기
Deep Learning/Hands On Machine Learning

17.2 Undercomplete linear AutoEncoder로 PCA 수행하기

by 대소기 2021. 12. 23.

* AutoEncoder가 linear activation function만 활용하고, cost function이 MSE라면, 결국 PCA를 수행하는 것과 같다.

np.random.seed(4)

def generate_3d_data(m, w1=0.1, w2=0.3, noise=0.1):
    angles = np.random.rand(m) * 3 * np.pi / 2 - 0.5
    data = np.empty((m, 3))
    data[:, 0] = np.cos(angles) + np.sin(angles)/2 + noise * np.random.randn(m) / 2
    data[:, 1] = np.sin(angles) * 0.7 + noise * np.random.randn(m) / 2
    data[:, 2] = data[:, 0] * w1 + data[:, 1] * w2 + noise * np.random.randn(m)
    return data

X_train = generate_3d_data(60)
X_train = X_train - X_train.mean(axis=0, keepdims=0)

* linear autoencoder를 사용해 3차원 데이터를 2차원으로 축소하기 위해 3차원 데이터를 먼저 생성하였다.

 

np.random.seed(42)
tf.random.set_seed(42)

encoder = keras.models.Sequential([keras.layers.Dense(2, input_shape=[3])])
decoder = keras.models.Sequential([keras.layers.Dense(3, input_shape=[2])])
autoencoder = keras.models.Sequential([encoder, decoder])

autoencoder.compile(loss="mse", optimizer=keras.optimizers.SGD(learning_rate=1.5))

history = autoencoder.fit(X_train, X_train, epochs=20)

# Epoch 1/20
# 2/2 [==============================] - 2s 9ms/step - loss: 0.2547
# Epoch 2/20
# 2/2 [==============================] - 0s 8ms/step - loss: 0.1032
# Epoch 3/20
# 2/2 [==============================] - 0s 8ms/step - loss: 0.0551
# Epoch 4/20
# 2/2 [==============================] - 0s 8ms/step - loss: 0.0503
# 중략...
# Epoch 15/20
# 2/2 [==============================] - 0s 11ms/step - loss: 0.0057
# Epoch 16/20
# 2/2 [==============================] - 0s 8ms/step - loss: 0.0053
# Epoch 17/20
# 2/2 [==============================] - 0s 8ms/step - loss: 0.0050
# Epoch 18/20
# 2/2 [==============================] - 0s 12ms/step - loss: 0.0048
# Epoch 19/20
# 2/2 [==============================] - 0s 9ms/step - loss: 0.0049
# Epoch 20/20
# 2/2 [==============================] - 0s 8ms/step - loss: 0.0047

* 3차원 vector를 받아 2차원 vector로 축소하는 encoder, 2차원 vector인 latent presentation을 3차원 vector로 복원하는 decoder를 구성해 20 epoch 동안 훈련했다.

 

codings = encoder.predict(X_train)

fig = plt.figure(figsize=(4,3))
plt.plot(codings[:,0], codings[:, 1], "b.")
plt.xlabel("$z_1$", fontsize=18)
plt.ylabel("$z_2$", fontsize=18, rotation=0)
plt.grid(True)
save_fig("linear_autoencoder_pca_plot")
plt.show()

* predict 메소드를 사용해 encoder에 X_train을 집어넣어 2차원 vector들을 출력하였다.

* autoencoder를 통해 차원 축소를 했을 때 PCA와 동일하게 분산이 가능한 많이 보존되도록 데이터를 2차원 평면에 투영한다.