TensorFlow 实现
在 TensorFlow 中实现去噪自编码器并不难。 我们从高斯噪声开始。 这实际上就像训练一个常规的自编码器一样,除了给输入添加噪声外,重建损耗是根据原始输入计算的:
X = tf.placeholder(tf.float32, shape=[None, n_inputs])
X_noisy = X + tf.random_normal(tf.shape(X))
[...]
hidden1 = activation(tf.matmul(X_noisy, weights1) + biases1)
[...]
reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE
[...]
由于X
的形状只是在构造阶段部分定义的,我们不能预先知道我们必须添加到X
中的噪声的形状。我们不能调用X.get_shape()
,因为这只会返回部分定义的X
的形状 ([None,n_inputs]
)和random_normal()
需要一个完全定义的形状,因此会引发异常。 相反,我们调用tf.shape(X)
,它将创建一个操作,该操作将在运行时返回X
的形状,该操作将在此时完全定义。
实施更普遍的 dropout 版本,而且这个版本并不困难:
from tensorflow.contrib.layers import dropout
keep_prob = 0.7
is_training = tf.placeholder_with_default(False, shape=(), name='is_training')
X = tf.placeholder(tf.float32, shape=[None, n_inputs])
X_drop = dropout(X, keep_prob, is_training=is_training)
[...]
hidden1 = activation(tf.matmul(X_drop, weights1) + biases1)
[...]
reconstruction_loss = tf.reduce_mean(tf.square(outputs - X)) # MSE
[...]
在训练期间,我们必须使用feed_dict
将is_training
设置为True
(如第 11 章所述):
sess.run(training_op, feed_dict={X: X_batch, is_training: True})
但是,在测试期间,不需要将is_training
设置为False
,因为我们将其设置为对placeholder_with_default()
函数调用的默认值。