我正在尝试在python中实现PCA。目前,我正在使用此代码将数据从低维数据和主组件表示回初始维度:
sameDimRepresentation = lowDimRepresentation[:, np.newaxis] * principalComponents.T
sameDimRepresentation = sameDimRepresentation.sum(axis=2)
代码的作用:
对于lowDimRepresentation
中的每一行,它计算行的每个元素(视为标量)和主成分的每个行向量(principalComponents.T
的列向量)之间的乘积,然后将所有这些乘向量相加(第 2 行)
lowDimRepresentation: an array of x by 100
principalComponents: an array of 100 by 784
resulting array: x by 784
使用x = 10000时,此方法工作正常,但之后出现内存错误。
我知道einsum
更节省内存,我试图用它重写相同的代码,但我没有管理。
有人可以帮我吗?
最坏的情况是,我只是将 60000 个案例分成 10000 个批次,然后运行这些位,但我希望实现更优雅的东西。
多谢!
所以有好消息也有坏消息。 好消息是einsum
版本非常简单:
np.einsum('ij,jl->il', lowDimRepresentation, principalComponents)
例如:
>>> import numpy as np
>>> x = 1000
>>> lowDimRepresentation = np.random.random((x, 100))
>>> principalComponents = np.random.random((100, 784))
>>> sameDimRepresentation = (lowDimRepresentation[:, np.newaxis] * principalComponents.T).sum(axis=2)
>>> esum_same = np.einsum('ij,jl->il', lowDimRepresentation, principalComponents)
>>> np.allclose(sameDimRepresentation, esum_same)
True
这也应该快一点:
>>> %timeit sameDimRepresentation = (lowDimRepresentation[:, np.newaxis] * principalComponents.T).sum(axis=2)
1 loops, best of 3: 1.12 s per loop
>>> %timeit esum_same = np.einsum('ij,jl->il', lowDimRepresentation, principalComponents)
10 loops, best of 3: 88.7 ms per loop
坏消息是,当我尝试将其应用于x=60000
情况时:
>>> esum_same = np.einsum('ij,jl->il', lowDimRepresentation, principalComponents)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: iterator is too large
所以我不确定它是否真的有助于解决你的真正问题。