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

问题描述:

我正在研究一个项目,我需要降低观察的维度并仍然有一个有意义的表示。 Autoencoders的使用强烈建议有很多原因,但我不太确定这是最好的方法。用于高维数据的自动编码器

我有1400个样品的尺寸〜60,000太高,我试图将它们的维数降低到原来的10%。我使用theano autoencoders [Link],似乎成本保持在30,000左右(这是非常高的)。我尝试提高时代数量或降低学习速度,但没有成功。我不是autoencoders的大专家,所以我不知道如何从这里开始或什么时候停止尝试。

还有其他的测试我可以运行,但在继续之前,我想从你那里得到一个输入。

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

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

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

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

数据集: 1400 - 2000扫描书籍(包括封面)的图像约为60.000像素(这意味着一个特征向量为60.000元素)。每个特征向量已经在[0,1]中归一化,并且最初具有[0,255]中的值。

问题:减少其维度与自动编码(如果可能)

如果您需要任何额外的信息,或者如果我错过了一些东西,可能是有用的,以便更好地理解问题,请添加评论,我会幸福地帮助你帮助我=)。

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

+4

您是否打折了替代降维技术,如主成分分析? –

+0

我绝对考虑到这一点,但我仍然想知道为什么autoencoders不工作。 – G4bri3l

+1

所以我在这里说了一句“丹尼尔说的话”,因为你应该先尝试简单的事情,无论如何,PCA将为你做一样的单层自动编码器(并且你将无法训练更多那)。另一个建议是使用一个预先训练过的跳转点,例如你可以在sklearn-theano中找到的,选择最新的图层之一,并在空间上折叠出每个图书封面的大小为'(n_channels,)'的签名。这将捕获一些视觉信息。 – eickenberg

没有理由必须将30,000的成本视为“高”,除非更多地了解情况而不是问题中所述。例如,如果隐藏层的大小特别小并且数据中的冗余很少,那么全球最小的成本实际上可能大约为30,000。

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

您应该期望在第一次更新之后降低成本(如果您使用minibatch随机梯度下降,您将在每个时期有很多更新)。您还应该期望收敛成本随着隐藏层的大小增加而减少。

其他技术可能在一个情况下帮助像这样包括denoising autoencoder(这可以被认为是由随机噪声的重复涂敷时人为地增加你的训练数据集的大小)和论点集中在编码器的正规化功率contractive autoencoder ,你关心的部分。两者都可以在Theano中实现,第一个是subject of this tutorialwith code)。

自动编码器部分有用,因为它们可以学习非线性降维。还有其他的降维技术,它比自动编码器快得多。扩散图是一种流行的扩散图。局部线性嵌入是另一个。我已经在> 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

您能否进一步解释“n_samples”是什么?此外,代码在分配之前使用变量“walk”。你能澄清一下吗?谢谢。 – user823743

+0

你能解释一下“n_samples和walk”变量吗? – javac

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