TensorFlow 实现

在 TensorFlow 中实现去噪自编码器并不难。 我们从高斯噪声开始。 这实际上就像训练一个常规的自编码器一样,除了给输入添加噪声外,重建损耗是根据原始输入计算的:

  1. X = tf.placeholder(tf.float32, shape=[None, n_inputs])
  2. X_noisy = X + tf.random_normal(tf.shape(X))
  3. [...]
  4. hidden1 = activation(tf.matmul(X_noisy, weights1) + biases1)
  5. [...]
  6. reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE
  7. [...]

由于X的形状只是在构造阶段部分定义的,我们不能预先知道我们必须添加到X中的噪声的形状。我们不能调用X.get_shape(),因为这只会返回部分定义的X的形状 ([None,n_inputs])和random_normal()需要一个完全定义的形状,因此会引发异常。 相反,我们调用tf.shape(X),它将创建一个操作,该操作将在运行时返回X的形状,该操作将在此时完全定义。

实施更普遍的 dropout 版本,而且这个版本并不困难:

  1. from tensorflow.contrib.layers import dropout
  2. keep_prob = 0.7
  3. is_training = tf.placeholder_with_default(False, shape=(), name='is_training')
  4. X = tf.placeholder(tf.float32, shape=[None, n_inputs])
  5. X_drop = dropout(X, keep_prob, is_training=is_training)
  6. [...]
  7. hidden1 = activation(tf.matmul(X_drop, weights1) + biases1)
  8. [...]
  9. reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE
  10. [...]

在训练期间,我们必须使用feed_dictis_training设置为True(如第 11 章所述):

  1. sess.run(training_op, feed_dict={X: X_batch, is_training: True})

但是,在测试期间,不需要将is_training设置为False,因为我们将其设置为对placeholder_with_default()函数调用的默认值。