用不完整的线性自编码器执行 PCA

如果自编码器仅使用线性激活并且损失函数是均方误差(MSE),则可以显示它最终执行主成分分析(参见第 8 章)。

以下代码构建了一个简单的线性自编码器,以在 3D 数据集上执行 PCA,并将其投影到 2D:

  1. import tensorflow as tf
  2. from tensorflow.contrib.layers import fully_connected
  3. n_inputs = 3 # 3D inputs
  4. n_hidden = 2 # 2D codings
  5. n_outputs = n_inputs
  6. learning_rate = 0.01
  7. X = tf.placeholder(tf.float32, shape=[None, n_inputs])
  8. hidden = fully_connected(X, n_hidden, activation_fn=None)
  9. outputs = fully_connected(hidden, n_outputs, activation_fn=None)
  10. reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE
  11. optimizer = tf.train.AdamOptimizer(learning_rate)
  12. training_op = optimizer.minimize(reconstruction_loss)
  13. init = tf.global_variables_initializer()

这段代码与我们在过去章节中建立的所有 MLP 没有什么不同。 需要注意的两件事是:

  • 输出的数量等于输入的数量。
  • 为了执行简单的 PCA,我们设置activation_fn = None(即,所有神经元都是线性的)

而损失函数是 MSE。 我们很快会看到更复杂的自编码器。

现在让我们加载数据集,在训练集上训练模型,并使用它来对测试集进行编码(即将其投影到 2D):

  1. X_train, X_test = [...] # load the dataset
  2. n_iterations = 1000
  3. codings = hidden # the output of the hidden layer provides the codings
  4. with tf.Session() as sess:
  5. init.run()
  6. for iteration in range(n_iterations):
  7. training_op.run(feed_dict={X: X_train}) # no labels (unsupervised)
  8. codings_val = codings.eval(feed_dict={X: X_test})

图 15-2 显示了原始 3D 数据集(左侧)和自编码器隐藏层的输出(即编码层,右侧)。 正如您所看到的,自编码器找到了将数据投影到数据上的最佳二维平面,保留了数据的尽可能多的差异(就像 PCA 一样)。

用不完整的线性自编码器执行 PCA - 图1