用不完整的线性自编码器执行 PCA
如果自编码器仅使用线性激活并且损失函数是均方误差(MSE),则可以显示它最终执行主成分分析(参见第 8 章)。
以下代码构建了一个简单的线性自编码器,以在 3D 数据集上执行 PCA,并将其投影到 2D:
import tensorflow as tf
from tensorflow.contrib.layers import fully_connected
n_inputs = 3 # 3D inputs
n_hidden = 2 # 2D codings
n_outputs = n_inputs
learning_rate = 0.01
X = tf.placeholder(tf.float32, shape=[None, n_inputs])
hidden = fully_connected(X, n_hidden, activation_fn=None)
outputs = fully_connected(hidden, n_outputs, activation_fn=None)
reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE
optimizer = tf.train.AdamOptimizer(learning_rate)
training_op = optimizer.minimize(reconstruction_loss)
init = tf.global_variables_initializer()
这段代码与我们在过去章节中建立的所有 MLP 没有什么不同。 需要注意的两件事是:
- 输出的数量等于输入的数量。
- 为了执行简单的 PCA,我们设置
activation_fn = None
(即,所有神经元都是线性的)
而损失函数是 MSE。 我们很快会看到更复杂的自编码器。
现在让我们加载数据集,在训练集上训练模型,并使用它来对测试集进行编码(即将其投影到 2D):
X_train, X_test = [...] # load the dataset
n_iterations = 1000
codings = hidden # the output of the hidden layer provides the codings
with tf.Session() as sess:
init.run()
for iteration in range(n_iterations):
training_op.run(feed_dict={X: X_train}) # no labels (unsupervised)
codings_val = codings.eval(feed_dict={X: X_test})
图 15-2 显示了原始 3D 数据集(左侧)和自编码器隐藏层的输出(即编码层,右侧)。 正如您所看到的,自编码器找到了将数据投影到数据上的最佳二维平面,保留了数据的尽可能多的差异(就像 PCA 一样)。