【发布时间】:2017-01-13 13:28:33
【问题描述】:
我正在尝试 zero-center 和 whiten CIFAR10 数据集,但我得到的结果看起来像随机噪声!Cifar10 数据集包含 60,000 大小为 32x32 的彩色图像。训练集包含50,000,测试集分别包含10,000图像。
以下 sn-ps 代码显示了我为使数据集变白所做的过程:
# zero-center
mean = np.mean(data_train, axis = (0,2,3))
for i in range(data_train.shape[0]):
for j in range(data_train.shape[1]):
data_train[i,j,:,:] -= mean[j]
first_dim = data_train.shape[0] #50,000
second_dim = data_train.shape[1] * data_train.shape[2] * data_train.shape[3] # 3*32*32
shape = (first_dim, second_dim) # (50000, 3072)
# compute the covariance matrix
cov = np.dot(data_train.reshape(shape).T, data_train.reshape(shape)) / data_train.shape[0]
# compute the SVD factorization of the data covariance matrix
U,S,V = np.linalg.svd(cov)
print 'cov.shape = ',cov.shape
print U.shape, S.shape, V.shape
Xrot = np.dot(data_train.reshape(shape), U) # decorrelate the data
Xwhite = Xrot / np.sqrt(S + 1e-5)
print Xwhite.shape
data_whitened = Xwhite.reshape(-1,32,32,3)
print data_whitened.shape
输出:
cov.shape = (3072L, 3072L)
(3072L, 3072L) (3072L,) (3072L, 3072L)
(50000L, 3072L)
(50000L, 32L, 32L, 3L)
(32L, 32L, 3L)
并尝试显示生成的图像:
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.misc import imshow
print data_whitened[0].shape
fig = plt.figure()
plt.subplot(221)
plt.imshow(data_whitened[0])
plt.subplot(222)
plt.imshow(data_whitened[100])
plt.show()
顺便说一下data_train[0].shape 是(3,32,32),
但如果我根据我得到的重塑白化图像
TypeError: Invalid dimensions for image data
这可能只是一个可视化问题吗?如果是这样,我怎样才能确保是这样?
更新:
感谢@AndrasDeak,我以这种方式修复了可视化代码,但输出看起来仍然是随机的:
data_whitened = Xwhite.reshape(-1,3,32,32).transpose(0,2,3,1)
print data_whitened.shape
fig = plt.figure()
plt.subplot(221)
plt.imshow(data_whitened[0])
更新 2:
这是我在运行下面给出的一些命令时得到的:
如下图所示,toimage 可以很好地显示图像,但试图重塑它,会弄乱图像。
# output is of shape (N, 3, 32, 32)
X = X.reshape((-1,3,32,32))
# output is of shape (N, 32, 32, 3)
X = X.transpose(0,2,3,1)
# put data back into a design matrix (N, 3072)
X = X.reshape(-1, 3072)
plt.imshow(X[6].reshape(32,32,3))
plt.show()
【问题讨论】:
-
我不熟悉美白,但是是的,您得到的错误是由于
plt.imshow期望(M,N,3)形状的数组作为 RGB 图像。但是这个问题更深层次:我也不希望你的data_train的形状是(N,3,32,32):它应该包含类似的行-列-RGB_通道尺寸模式。这表明您可能误解了输入的维度,这可以解释为什么您的输出不是您所期望的。 -
哦,除非我弄错了,否则您所做的零中心化等同于矢量化
data_train -= np.mean(data_train, axis = (0,2,3))[:,None,None],利用数组广播。 -
最后评论:我希望零居中可以逐个图像工作。您将每个图像的每个颜色通道居中。这意味着(如果
data_train的最后两个维度对应于像素)您需要np.mean(data_train,axis=(2,3)),并且相应地需要data_train -= np.mean(data_train, axis = (0,2,3))[...,None,None]。不对吗? -
这可能是个愚蠢的问题,但你不能使用 ctypes 访问内存中的字节,并简单地用 (255,255,255) (假设为 RGB)覆盖它们吗?
-
好的,我想我看到了(至少一个)问题。您只在代码中使用
reshapes,但您从(3,32,32)开始并以(32,32,3)结束。这是错误的。如果您重塑数据而不是排列索引(使用.transpose),您将把数组元素全部混淆。那肯定是错的。我不确定这是否正确,但您可能正在寻找data_whitened = Xwhite.reshape(-1,3,32,32).permute(0,2,3,1)。
标签: python image-preprocessing image-whitening