我正在尝试对包含 100.000 个图像(每个图像大小为 224x224x3)的图像数据集执行 PCA。
我希望将图像投影到 1000 维空间(或附近的某个位置)。
我在笔记本电脑(16GB 内存、i7、无 GPU)上执行此操作,并且已设置svd_solver='randomized'。
然而,适配需要永远。数据集和图像尺寸是否太大或者我可以使用一些技巧?
谢谢!
编辑:
这是代码:
pca = PCA(n_components=1000, svd_solver='randomized')
pca.fit(X)
Z = pca.transform(X)
X 是一个 100000 x 150528 矩阵,其行代表展平的图像。
最佳答案
如果您认为需要 1000 个主成分,您确实应该重新考虑降维的选择。如果你有那么多,那么你就不再具有可解释性,所以你不妨使用其他更灵活的降维算法(例如变分自动编码器、t-sne、kernel-PCA)。 PCA 的一个主要优点是主成分的可解释性。
如果您有同一位置的视频流,那么您应该可以使用 <10 个分量(尽管主分量追求可能更好)。此外,如果您的图像数据集不由相似的图像组成,那么 PCA 可能不是正确的选择。
此外,对于图像,非负矩阵分解 (NMF) 可能更适合。对于 NMF,您可以执行随机梯度优化,对每个梯度步骤的像素和图像进行二次采样。
但是,如果您仍然坚持执行 PCA,那么我认为 Facebook 提供的随机求解器是您最好的选择。运行 pip install fbpca
并运行以下代码
from fbpca import pca
# load data into X
U, s, Vh = pca(X, 1000)
如果不利用某些矩阵结构,例如,不可能比这更快。稀疏性或 block 组成(您的数据集不太可能具有)。
此外,如果您需要帮助来选择正确数量的主成分,我建议使用此代码
import fbpca
from bisect import bisect_left
def compute_explained_variance(singular_values):
return np.cumsum(singular_values**2)/np.sum(singular_values**2)
def ideal_number_components(X, wanted_explained_variance):
singular_values = fbpca.svd(X, compute_uv=False) # This line is a bottleneck.
explained_variance = compute_explained_variance(singular_values)
return bisect_left(explained_variance, wanted_explained_variance)
def auto_pca(X, wanted_explained_variance):
num_components = ideal_number_components(X, explained_variance)
return fbpca.pca(X, num_components) # This line is a bottleneck if the number of components is high
当然,上面的代码不支持交叉验证,您确实应该使用交叉验证来选择正确的组件数量。
关于python - 用于图像数据集的 scikit-learn PCA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56187198/