【问题标题】:one hidden layer sufficient for auto-encoder to have output same as input一个隐藏层足以让自动编码器具有与输入相同的输出
【发布时间】:2016-11-22 10:35:51
【问题描述】:

我正在使用基于 Theano 的自动编码器做一些工作,将输入作为来自高斯混合的样本,一个隐藏层。我希望输出与输入相同,但我没有实现。我受到this 实施教程的启发。只有一个隐藏层的自动编码器是否也足以恢复输出的精确副本?

我的代码如下所示:

` def train(self, n_epochs=100, mini_batch_size=1, learning_rate=0.01):
    index = T.lscalar()
    x=T.matrix('x')
    params = [self.W, self.b1, self.b2]
    hidden = self.activation_function(T.dot(x, self.W)+self.b1)
    output = T.dot(hidden,T.transpose(self.W))+self.b2
    output = self.output_function(output)


    # Use mean square error
    L = T.sum((x - output) ** 2)
    cost = L.mean()

    updates=[]

    #Return gradient with respect to W, b1, b2.
    gparams = T.grad(cost,params)

    #Create a list of 2 tuples for updates.
    for param, gparam in zip(params, gparams):
        updates.append((param, param-learning_rate*gparam))

    #Train given a mini-batch of the data.
    train = th.function(inputs=[index], outputs=cost, updates=updates,
                        givens={x:self.X[index:index+mini_batch_size,:]})
    import time
    start_time = time.clock()
    acc_cost = []
    for epoch in xrange(n_epochs):

        #print "Epoch:", epoch
        for row in xrange(0,self.m, mini_batch_size):
            cost = train(row)
        acc_cost.append(cost)

    plt.plot(range(n_epochs), acc_cost)
    plt.ylabel("cost")
    plt.xlabel("epochs")
    plt.show()

    # Format input data for plotable format
    norm_data = self.X.get_value()
    plot_var1 = []
    plot_var1.append(norm_data[:,0])
    plot_var2 = []
    plot_var2.append(norm_data[:,1])
    plt.plot(plot_var1, plot_var2, 'ro')

    # Hidden output
    x=T.dmatrix('x')
    hidden = self.activation_function(T.dot(x,self.W)+self.b1)
    transformed_data = th.function(inputs=[x], outputs=[hidden])
    hidden_data = transformed_data(self.X.get_value())
    #print "hidden_output ", hidden_data[0]

    # final output
    y=T.dmatrix('y')
    W = T.transpose(self.W)
    output = self.activation_function(T.dot(y,W) + self.b2)
    transformed_data = th.function(inputs=[y], outputs=[output])
    output_data = transformed_data(hidden_data[0])[0]
    print "decoded_output ", output_data

    # Format output data for plotable format
    plot_var1 = []
    plot_var1.append(output_data[:,0])
    plot_var2 = []
    plot_var2.append(output_data[:,1])
    plt.plot(plot_var1, plot_var2, 'bo')
    plt.show()



' 

【问题讨论】:

  • 理论上 1 个隐藏层 MLP 是一种通用函数逼近器,使用更深的层可能会提高最终模型的损失和泛化能力。但是,您的实施可能存在一些问题。你能提供你使用的代码吗?
  • 我不能在这里粘贴我的代码,因为它只允许评论中的几个字符
  • 训练损失曲线是什么样子的?
  • 抱歉,由于网络问题,您之前的回答好像被删除了?但我的问题是使用两种不同的权重有什么意义,为什么我们需要转置 self.w2 ?因为,我认为我们只需要一个权重并将其转置到另一层。学习曲线似乎很好,成本值逐渐下降,大约 2000 个 epoch 后,它变得饱和,成本值在 0 左右。谢谢。

标签: python theano autoencoder


【解决方案1】:

在您的代码中:

    params = [self.W, self.b1, self.b2]
    hidden = self.activation_function(T.dot(x, self.W)+self.b1)
    output = T.dot(hidden,T.transpose(self.W))+self.b2

您对输入和输出使用相同的权重。怎么样:

    params = [self.W1, self.W2, self.b1, self.b2]
    hidden = self.activation_function(T.dot(x, self.W1)+self.b1)
    output = T.dot(hidden,self.W2)+self.b2

自动编码器不是 PCA。如果您想使用相同的权重,最好将权重约束为正交。

否则,制作更深的 AE 可能会有所帮助。由于只有一个独立的权重矩阵,所提出的模型很难像 3 层 MLP 那样作为通用函数逼近器。

【讨论】:

  • 好吧,我想我们只需要一个 weight 。因为在其他层(输出层),我只是简单地转置了权重。就像[这里](deeplearning.net/tutorial/dA.html#autoencoders)所说的那样。因为 w 和 w' 是捆绑的权重并且是相互转置的。那么在你的回答中,使用 self.w2 的转置有什么意义?
  • @Shyamkkhadka 我的错,只要形状匹配就不需要转置(复制太快)。制作两个独立权重的目的是使其成为 3 层 MLP,这是一个通用函数逼近器。如果您的 AE 中有 4 个权重,则可以让其中两个相互转置。
  • 所以在你看来,如果我想近似一个简单的 3 层自动编码器,我应该使用两个不同的权重(w1,w2)。对我来说,它看起来像 3 层 MLP。是不是符合autoencoder的原理?我们应该将权重(权重的转置)绑定在一起。
  • @Shyamkkhadka 谁说自动编码器必须使用捆绑重量?只有线性 PCA 需要 正交 权重相互转置,同时使用线性激活函数。 AE 可以被视为 PCA 的扩展。在实践中,我们可以在 AE 中插入卷积、循环、对抗、噪声......基本上任何东西。
  • 好吧,可能是我的自动编码器错了。然后我会尝试两种不同的重量。
猜你喜欢
  • 1970-01-01
  • 2020-01-29
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2018-04-28
  • 2019-01-02
相关资源
最近更新 更多