3

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

我有 1400 个尺寸约为 60,000 的样本,这太高了,我正试图将它们的维度降低到原始维度的 10%。我正在使用theano 自动编码器[ Link ],似乎成本一直在 30,000 左右(非常高)。我尝试增加 epoch 数或降低学习率,但均未成功。我不是自动编码器方面的专家,所以我不确定如何从这里开始,或者何时停止尝试。

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

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

  • 你认为使用堆叠的自动编码器会有所帮助吗?

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

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

数据集: 1400 - 2000 张扫描书籍(包括封面)的图像,每张约 60.000 像素(转换为 60.000 个元素的特征向量)。每个特征向量都在 [0,1] 中进行了归一化,最初的值在 [0,255] 中。

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

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

注意:我目前正在对整个数据集进行更多时期的测试,我将根据结果更新我的帖子,但这可能需要一段时间。

4

3 回答 3

3

没有理由将 30,000 的成本视为“高”,除非对情况的了解比问题中描述的更多。例如,如果隐藏层的大小特别小并且数据中几乎没有冗余,那么全局最小成本实际上可能在 30,000 左右。

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

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

在这种情况下可能有帮助的其他技术包括去噪自动编码器(可以被认为是通过重复应用随机噪声人为地增加训练数据集的大小)和收缩自动编码器,它将其正则化能力集中在编码器上,你关心的部分。两者都可以在 Theano 中实现,第一个是本教程的主题带有代码)。

于 2015-09-07T16:42:12.120 回答
3

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

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

于 2016-02-01T18:39:08.010 回答
1

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

于 2018-01-06T13:15:27.930 回答