Python 如何创建编码器/解码器权重镜像(转置)的自动编码器

Python 如何创建编码器/解码器权重镜像(转置)的自动编码器,python,tensorflow,machine-learning,deep-learning,autoencoder,Python,Tensorflow,Machine Learning,Deep Learning,Autoencoder,我正在尝试使用TensorFlow构建我的第一个自动编码器神经网络。编码器和解码器中各层的尺寸相同,只是相反。autoencoder学习将图像数据压缩和重建到合理的标准,但我想尝试通过使用解码器作为编码器的精确转置来提高其性能 我不知道如何在TensorFlow中实现这一点 以下是我的网络建设的一个片段: imgW, imgH = 28, 28 encoderDims = [ imgW * imgH, (imgW // 2) * (imgH // 2), (imgW //

我正在尝试使用TensorFlow构建我的第一个自动编码器神经网络。编码器和解码器中各层的尺寸相同,只是相反。autoencoder学习将图像数据压缩和重建到合理的标准,但我想尝试通过使用解码器作为编码器的精确转置来提高其性能

我不知道如何在TensorFlow中实现这一点

以下是我的网络建设的一个片段:

imgW, imgH = 28, 28
encoderDims = [
    imgW * imgH,
    (imgW // 2) * (imgH // 2),
    (imgW // 3) * (imgH // 3),
    (imgW // 4) * (imgH // 4)
]
decoderDims = list(reversed(encoderDims))

encoderWeights, encoderBiases = [], []
decoderWeights, decoderBiases = [], []
for layer in range(len(encoderDims) - 1):
    encoderWeights.append(
        tf.Variable(tf.random_normal([encoderDims[layer], encoderDims[layer + 1]]))
    )
    encoderBiases.append(
        tf.Variable(tf.random_normal([encoderDims[layer + 1]]))
    )
    decoderWeights.append(
        tf.Variable(tf.random_normal([decoderDims[layer], decoderDims[layer + 1]]))
    )
    decoderBiases.append(
        tf.Variable(tf.random_normal([decoderDims[layer + 1]]))
    )

input = tf.placeholder(tf.float32, [None, imgW * imgH])
encoded = input
for layer in range(len(encoderDims) - 1):
    encoded = tf.add(tf.matmul(encoded, encoderWeights[layer]), encoderBiases[layer])
    encoded = tf.nn.sigmoid(encoded)

decoded = encoded
for layer in range(len(decoderDims) - 1):
    decoded = tf.add(tf.matmul(decoded, decoderWeights[layer]), decoderBiases[layer])
    if layer != len(decoderDims) - 2:
        decoded = tf.nn.sigmoid(decoded)

loss = tf.losses.mean_squared_error(labels=input, predictions=decoded)
train = tf.train.AdamOptimizer(learningRate).minimize(loss)
我不知道如何克服的两个问题是:

  • 在训练期间,我如何调整仅编码器参数
  • 我如何创建解码器权重和偏差,以便在编码器参数的每次迭代训练后,将其设置为新调整编码器参数的转置

  • 我怀疑这将优于常规自动编码器。但是如果你应该得到令人惊讶的好结果,让社区知道。关于你的问题:

    1.)由于必须在输入和输出之间使用一些重建误差,唯一的选择是使用整个网络进行训练(例如,编码器和解码器作为一个整体)。但是,您可以为解码器变量设置一个标志,以防止它们在初始化后被算法更改。将它们设置为
    trainable=False
    。训练一个历元后,可以手动将其设置为转置编码器权重

    2.)在这里,我不知道你如何解释“转置”。如果您的意思是编码器第1层的权重应该与解码器最后一层的权重匹配,您可以尝试以下方法:

    for layer in range(len(encoderWeights)):
        decoderWeights[-layer-1] = tf.transpose(encoderWeights[layer])
    

    如果要单独转置图层矩阵,可以使用said
    tf.tranpose()
    。从数学角度来看,矩阵乘法的正确逆运算应该是逆矩阵(如果定义了逆矩阵)。TensorFlow确实为此提供了
    tf.matrix\u inverse()
    。但是,在使用时要非常小心,因为不能保证合理的结果。

    “我怀疑这会优于常规自动编码器。”本文()概述了在推荐系统中使用深度自动编码器模型的成功结果(这也是我正在尝试的)说这是他们在第一页最后一段所做的。Geoffrey Hinton提出的autoencoders()的原始论文也使用了这种权值矩阵从编码器到解码器的转换,然后,对编码器和解码器的权重进行独立的进一步微调。关于第二点:是的,这只是需要对矩阵进行简单的数学转置,因为编码器的第一个权重矩阵的大小,例如728x400,因此解码器的最后一个权重矩阵现在需要是400x728的转置。在第一点上,我认为可以使用类似的方法。在阅读了你的观点之后,我想我可以在每次迭代中使用编码器,通过对每个编码权重矩阵进行转置来计算损耗,然后模拟解码过程,从中可以计算损耗。接下来,从这个损失中,我可以按照您概述的那样训练编码器权重。这将重复,直到损失足够低,然后我可以通过转置经过训练的编码器权重来构建永久解码器,并保存整个模型。关于第一个语句,这完全是基于我的直觉。我还没看过报纸,但我一定会看的。谢谢你让我意识到这一点。关于你对第1点的回答。):这是一个很好的详细描述,我将如何处理这一问题。我只是不知道你说的迭代是什么意思。您打算在每批训练后或完成一个历元后复制编码器重量吗?关于第2点::我更新了我的答案,因为你指定了你想要的操作。是的,对不起,迭代我只是指一批的每一次向前传递。当前输入将通过编码器输入,然后我将通过编码器权重矩阵的转置(模拟解码器)乘以编码层,以便能够计算损失,然后在处理下一批之前相应地调整编码器权重。我已经让它工作了,但是如果没有偏差,它似乎不能很好地工作,现在我认为在涉及偏差时,根本不可能实现编码器到解码器的这种“镜像”。