【问题标题】:Is there a way to prevent numpy.linalg.svd running out of memory?有没有办法防止 numpy.linalg.svd 内存不足?
【发布时间】:2013-11-02 15:32:07
【问题描述】:

我有 100 万个 3d 点要传递给 numpy.linalg.svd,但它很快就会耗尽内存。有没有办法把这个操作分解成更小的块?

我不知道它在做什么,但我是否应该只传递代表 3x3、4x4 矩阵的数组?因为我在网上看到了它的用法,他们传递具有任意数量元素的数组。

【问题讨论】:

  • 来自文档svd 需要2-D arrays 作为输入。如果您通过full_matrices=False...,您似乎需要更少的内存...
  • 这有帮助,但它会给出完全相同的结果吗?我得到了相同的结果,但参数的描述对我来说没有意义。

标签: python numpy matrix linear-algebra svd


【解决方案1】:

如果您的情况有 MxN,则 1000000x3 矩阵numpy.linalg.svd 不需要 M==N。事实上,这正是 SVD 可以用来计算秩和伪逆等事物的地方。诸如 linalg.inv 之类的方法需要一个方阵(和满秩)矩阵来获得定义的结果。

@Saullo Castro 是正确的。 full_matrices=False 可以变得难以处理,因为 U 矩阵不是 1Mx1M 元素,而是 1Mx3,节省了大量资金。我不确定 numpy 使用哪种简化的 SVD 算法(我认为它可能是紧凑型 SVD 或瘦):维基百科上对 3 个广泛使用的算法的简要描述:http://en.wikipedia.org/wiki/Singular_value_decomposition 在简化的 SVD 部分。它们都围绕将整个 U 矩阵的计算简化为简化形式,这对于某些甚至许多问题来说已经足够了。节省最多的是 numberObservations>>numberFeatures

关于你是否得到相同的结果。简短的回答可能是肯定的,具体取决于您将使用 SVD 结果做什么。例如,您将获得与原始形式相同的矩阵(到浮点容差水平),其简化形式与原始形式相同,如下面的代码所示。注意在上例中 U 的大小是 numberObservations x numberObservations,而在 full_matrices=False 中,U 的大小是 numberObservations x numberFeatures

此代码改编自 numpy.linalg.svd 文档,允许人们尝试任意行/列,选择奇异值。

总是可以将 U 矩阵的大小减小到 M x min(M,N)。根据您的数据结构和存在多少噪音,可能会进一步减少。仅仅因为 numpy.isclose 为假并不意味着计算出的 SV 对所有上下文都不利。您可以使用 mostSignificantSingularValues 变量进行试验,该变量从完整的 SVD 中获取顶部的 SV。

numberObservations = 900
numberFeatures = 600
mostSignificantSingularValues = 600

a = np.random.randn( numberObservations, numberFeatures) + 1j*np.random.randn(numberObservations, numberFeatures)

#Reconstruction based on full SVD:

U, s, V = np.linalg.svd(a, full_matrices=True)
print(U.shape, V.shape, s.shape)
S = np.zeros((numberObservations, numberFeatures), dtype=complex)
S[:mostSignificantSingularValues, :mostSignificantSingularValues] = np.diag(s[:mostSignificantSingularValues])
print(np.allclose(a, np.dot(U, np.dot(S, V))))
d1 = a - np.dot(U, np.dot(S, V))#
#True

#Reconstruction based on reduced SVD:

U, s, V = np.linalg.svd(a, full_matrices=False)
print(U.shape, V.shape, s.shape)
S = np.diag(s)
print(np.allclose(a, np.dot(U, np.dot(S, V))))

d2 = a - np.dot(U, np.dot(S, V))#

【讨论】:

    【解决方案2】:

    尝试使用scipy.linalg.svd代替numpy的func。

    【讨论】:

      猜你喜欢
      • 2019-02-15
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 2017-01-17
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多