我想使用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资源,并再次尝试运行此代码。同样,在向np.sqrt()
提供负值时也会收到同样的警告。不确定这是否有帮助,但我还附加了cpu和ram利用率数字:
发布于 2019-03-12 22:08:05
这里有几个想法。我没有你的数据集,所以我不能完全确定这些数据会解决你的问题,但我有足够的信心把它作为回答而不是评论。
第一。到3072年,您的X_train
是40'000,其中每一行都是数据向量,每一列都是变量或特性。您需要的协方差矩阵是3072乘3072:将rowvar=False
传递给np.cov
。
我不太清楚为什么40000×40000协方差矩阵的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.svd
标志的full_matrices=False
),并从那里直接计算白化矩阵,而无需为协方差矩阵评估昂贵的外部积。
https://stackoverflow.com/questions/55131665
复制相似问题