首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Numpy中的SVD分解得到负S值?

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

Stack Overflow用户
提问于 2019-03-12 22:37:22
回答 1查看 909关注 0票数 4

我想使用ZCA来白化CIFAR10数据集。输入的X_train是形状(40000、32、32、3),其中40000是图像的数量,32x32x3是每个图像的大小。为此,我使用了来自这个答案的代码:

代码语言:javascript
复制
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)

但是,在运行时,我遇到了以下警告:

代码语言:javascript
复制
D:\toolkits.win\anaconda3-5.2.0\envs\dlwin36\lib\site- packages\ipykernel_launcher.py:8: RuntimeWarning: invalid value encountered in sqrt

所以当我得到SVD输出后,我试着:

代码语言:javascript
复制
print(np.min(S)) # prints -1.7798217

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

我尝试通过第二次重复运行相同的代码来再现这个结果,这次我没有遇到任何警告或任何负面的S值,但是我得到了:

代码语言:javascript
复制
print(np.min(S)) # prints nan

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

更新:重新启动内核以释放cpu和RAM资源,并再次尝试运行此代码。同样,在向np.sqrt()提供负值时也会收到同样的警告。不确定这是否有帮助,但我还附加了cpu和ram利用率数字:

活动监测数字

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-13 06: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)

如果您这样做,那么最后一步必须修改一点(以使维度对齐)。下面是使用统一随机数据的快速检查:

代码语言:javascript
复制
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 ),并从那里直接计算白化矩阵,而无需为协方差矩阵评估昂贵的外部积。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55131665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档