关联权重
当自编码器整齐地对称时,就像我们刚刚构建的那样,一种常用技术是将解码器层的权重与编码器层的权重相关联。 这样减少了模型中的权重数量,加快了训练速度,并限制了过度拟合的风险。
具体来说,如果自编码器总共具有N个层(不计入输入层),并且
表示第L层的连接权重(例如,层 1 是第一隐藏层,则层N / 2是编码 层,而层N是输出层),则解码器层权重可以简单地定义为:
(其中L = 1, 2, ..., N2)。
不幸的是,使用fully_connected()函数在 TensorFlow 中实现相关权重有点麻烦;手动定义层实际上更容易。 代码结尾明显更加冗长:
activation = tf.nn.eluregularizer = tf.contrib.layers.l2_regularizer(l2_reg)initializer = tf.contrib.layers.variance_scaling_initializer()X = tf.placeholder(tf.float32, shape=[None, n_inputs])weights1_init = initializer([n_inputs, n_hidden1])weights2_init = initializer([n_hidden1, n_hidden2])weights1 = tf.Variable(weights1_init, dtype=tf.float32, name="weights1")weights2 = tf.Variable(weights2_init, dtype=tf.float32, name="weights2")weights3 = tf.transpose(weights2, name="weights3") # tied weightsweights4 = tf.transpose(weights1, name="weights4") # tied weightsbiases1 = tf.Variable(tf.zeros(n_hidden1), name="biases1")biases2 = tf.Variable(tf.zeros(n_hidden2), name="biases2")biases3 = tf.Variable(tf.zeros(n_hidden3), name="biases3")biases4 = tf.Variable(tf.zeros(n_outputs), name="biases4")hidden1 = activation(tf.matmul(X, weights1) + biases1)hidden2 = activation(tf.matmul(hidden1, weights2) + biases2)hidden3 = activation(tf.matmul(hidden2, weights3) + biases3)outputs = tf.matmul(hidden3, weights4) + biases4reconstruction_loss = tf.reduce_mean(tf.square(outputs - X))reg_loss = regularizer(weights1) + regularizer(weights2)loss = reconstruction_loss + reg_lossoptimizer = tf.train.AdamOptimizer(learning_rate)training_op = optimizer.minimize(loss)init = tf.global_variables_initializer()
这段代码非常简单,但有几件重要的事情需要注意:
- 首先,权重 3 和权重 4 不是变量,它们分别是权重 2 和权重 1 的转置(它们与它们“绑定”)。
- 其次,由于它们不是变量,所以规范它们是没有用的:我们只调整权重 1 和权重 2。
- 第三,偏置永远不会被束缚,并且永远不会正规化。
