用于高维数据的自动编码器

时间:2015-09-06 17:19:18

标签: python theano dimensionality-reduction autoencoder

我正在开展一个项目,在那里我需要减少观察的维度,并且仍然有一个有意义的表示。强烈建议使用自动编码器有很多原因,但我不太确定这是最好的方法。

我有1400个维度~60,000的样本太高了,我试图将它们的维数降低到原始维度的10%。我正在使用 theano autoencoders [Link],似乎费用一直在30,000左右(非常高)。我尝试提高时代数或降低学习率但没有成功。我不是自动编码器的大专家,所以我不知道如何从这里开始,或者什么时候停止尝试。

我可以运行其他测试,但在继续之前,我想收到你的意见。

  • 您认为数据集太小(我可以添加另外600个样本,总共~2000)?

  • 您认为使用堆叠自动编码器可以提供帮助吗?

  • 我应该不断调整参数(时期和学习率)吗?

由于数据集是图片的一部分,我试图从自动编码器中可视化重建,我得到的是每个样本的相同输出。这意味着在给定输入的情况下,自动编码器会尝试重建输入,但对于任何输入,我得到的是相同(几乎完全)的图像(哪种看起来像数据集中所有图像的平均值)。这意味着内部表示不够好,因为自动编码器无法从中重建图像。

数据集: 1400 - 2000个扫描书籍(包括封面)的图像,每个约60,000像素(转换为60.000个元素的特征向量)。每个特征向量已在[0,1]中标准化,最初的值为[0,255]。

问题:使用自动编码器降低维度(如果可能)

如果您需要任何额外信息,或者我错过了可能有助于更好地理解问题的内容,请添加评论,我很乐意帮助您帮助我=。

注意:我目前正在运行一个在整个数据集上有更多纪元的测试,我会根据结果更新我的帖子,但可能需要一段时间。

3 个答案:

答案 0 :(得分:3)

没有理由认为花费30,000作为"高"除非对问题的描述比对问题的描述有所了解。例如,如果隐藏层的大小特别小并且数据中的冗余很少,则全局最小成本实际上可能大约为30,000。

如果在训练之前成本是30,000(即使用随机编码器和解码器权重)并且即使在经过一些训练之后仍然保持在该水平附近,那么可能是错误的。

您应该预计在首次更新后成本会降低(如果您使用的是随机时间梯度下降,则每个时期会有很多更新)。随着隐藏层的大小增加,您还应该期望收敛成本降低。

在这种情况下可能有帮助的其他技术包括denoising autoencoder(可以认为是通过重复应用随机噪声人为地增加训练数据集的大小)和contractive autoencoder将其正规化功率集中在编码器上,这是您关心的部分。两者都可以在Theano中实现,第一个是subject of this tutorialwith code)。

答案 1 :(得分:2)

自动编码器之所以有用,部分原因在于它们可以学习非线性降维。然而,还有其他降维技术比自动编码器快得多。扩散图是一种流行的图;局部线性嵌入是另一种。我已经在> 2000 60k维数据(也是图像)上使用了扩散贴图,它可以在一分钟内完成。

这是使用numpy等人的直接Python实现:

def diffusion_maps(data, d, eps=-1, t=1):
    """
    data is organized such that columns are points. so it's 60k x 2k for you
    d is the target dimension
    eps is the kernel bandwidth, estimated automatically if == -1
    t is the diffusion time, 1 is usually fine
    """

    from scipy.spatial import pdist, squareform
    from scipy import linalg as la
    import numpy as np

    distances = squareform(pdist(data.T))

    if eps == -1:
        # if a kernel bandwidth was not supplied,
        # just use the distance to the tenth-nearest neighbor
        k = 10
        nn = np.sort(distances)
        eps = np.mean(nn[:, k + 1])

    kernel = np.exp(-distances ** 2 / eps ** 2)
    one = np.ones(n_samples)
    p_a = np.dot(kernel, one)
    kernel_p = walk / np.outer(p_a, p_a)
    dd = np.dot(kernel_p, one) ** 0.5
    walk = kernel_p / np.outer(dd, dd)

    vecs, eigs, _ = la.svd(walk, full_matrices=False)
    vecs = vecs / vecs[:, 0][:, None]
    diffusion_coordinates = vecs[:, 1:d + 1].T * (eigs[1:d + 1][:, None] ** t)

    return diffusion_coordinates

扩散地图的要点是,您可以对数据进行随机游走,这样您就可以更远地访问附近的点而不是遥远的点。然后,您可以定义点之间的距离(扩散距离),这实际上是在所有可能路径上在两点之间移动的平均概率。诀窍是这实际上非常容易计算;您需要做的就是对矩阵进行对角化,然后使用其特征向量将数据嵌入到低维空间中。在这种嵌入中,欧几里德距离是扩散距离,直到近似误差。

答案 2 :(得分:0)

首先是简单的事情...... 请注意,如果您在60,000维度空间中只有1400点,那么您可以不丢失,将维度降低到大小< = 1400 。这是一个简单的数学事实:您的数据矩阵是1400x60,000,因此其等级(维度)最多为1400.因此,主成分分析(PCA)将在1400维空间中生成1400个点而不会丢失。我强烈建议在考虑其他任何事情之前使用PCA来减少数据的维度。