从 Numpy 的 SVD 分解中获得负 S 值?

Getting negative S value from SVD decomposition in Numpy?

我想使用 ZCA 对 CIFAR10 数据集进行白化处理。输入 X_train 的形状为 (40000, 32, 32, 3),其中 40000 是图像的数量,32x32x3 是每张图像的大小。为此,我正在使用 中的代码:

X_flat = np.reshape(X_train, (-1, 32*32*3))
# compute the covariance of the image data
cov = np.cov(X_flat, rowvar=True)   # cov is (N, N)
# singular value decomposition
U,S,V = np.linalg.svd(cov)     # U is (N, N), S is (N,)
# build the ZCA matrix
epsilon = 1e-5
zca_matrix = np.dot(U, np.dot(np.diag(1.0/np.sqrt(S + epsilon)), U.T))
# transform the image data       zca_matrix is (N,N)
zca = np.dot(zca_matrix, X_flat)    # zca is (N, 3072)

然而,在 运行 的时候我遇到了以下警告:

D:\toolkits.win\anaconda3-5.2.0\envs\dlwin36\lib\site- packages\ipykernel_launcher.py:8: RuntimeWarning: invalid value encountered in sqrt

所以在我得到 SVD 输出后,我尝试了:

print(np.min(S)) # prints -1.7798217

这是意外的,因为 S 只能有正值。此外,ZCA 美白结果不正确,它包含 nan 个值。

我尝试通过重新运行第二次使用相同的代码来重现此代码,这次我没有遇到任何警告或任何负 S 值,但我得到了:

print(np.min(S)) # prints nan

知道为什么会发生这种情况吗?


更新: 重新启动内核以释放 cpu 和 RAM 资源,并再次尝试 运行ning 这段代码。再次收到相同的警告,将负值输入 np.sqrt()。不确定它是否有帮助,但我还附上了 cpu 和 ram 利用率数据:

activity monitor figures

这里有一些想法。我没有你的数据集,所以我不能完全确定这些会解决你的问题,但我有足够的信心post将其作为答案而不是评论。

首先。您的 X_train 是 40'000 x 3072,其中每个 是一个数据向量,每个 是一个变量或特征。您想要 3072 x 3072 的协方差矩阵:将 rowvar=False 传递给 np.cov

我不太确定为什么 40'000 x 40'000 协方差矩阵的 SVD 会发散。假设您有足够的 RAM 来存储 12 GB 协方差矩阵,我能想到的一件事是数值溢出,因为您可能没有像 ZCA(和任何其他美白技术)所期望的那样删除数据的平均值?

第二个。去掉均值:X_zeromean = X_flat - np.mean(X_flat, 0).

如果你这样做,那么最后一步必须稍微修改一下(使尺寸对齐)。这是使用统一随机数据的快速检查:

import numpy as np
X_flat = np.random.rand(40000, 32*32*3)
X_zeromean = X_flat - np.mean(X_flat, 0)
cov = np.cov(X_zeromean, rowvar=False)
U,S,V = np.linalg.svd(cov)
epsilon = 1e-5
zca_matrix = np.dot(U, np.dot(np.diag(1.0/np.sqrt(S + epsilon)), U.T))
zca = np.dot(zca_matrix, X_zeromean.T) # <-- transpose needed here

作为完整性检查,np.cov(zca) 现在非常接近单位矩阵,如所期望的那样(zca 将翻转维度作为输入)。

(作为旁注,这是一种非常昂贵且数值不稳定的白化数据数组的方法:您不需要计算协方差然后采用 SVD——您做的工作是原来的两倍。您可以采用数据矩阵本身的瘦 SVD(np.linalg.svdfull_matrices=False 标志)并直接从那里计算白化矩阵,而无需评估协方差矩阵的昂贵外积。)