title: Is this the correct way of whitening an image in python?
body: <p>I am trying to <code>zero-center</code> and <code>whiten</code> <code>CIFAR10</code> dataset, but the result I get looks like random noise!<br>
  <code>Cifar10</code> dataset contains <code>60,000</code> color images of size <code>32x32</code>. The training set contains <code>50,000</code> and test set contains <code>10,000</code> images respectively.<br>
  The following snippets of code show the process I did to get the dataset whitened :  </p>
  
  <pre><code># 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
  </code></pre>
  
  <p>outputs:</p>
  
  <pre><code>cov.shape =  (3072L, 3072L)
  (3072L, 3072L) (3072L,) (3072L, 3072L)
  (50000L, 3072L)
  (50000L, 32L, 32L, 3L)
  (32L, 32L, 3L)
  </code></pre>
  
  <p>and trying to show the resulting image : </p>
  
  <pre><code>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()
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/bvq3C.png" rel="noreferrer"><img src="https://i.stack.imgur.com/bvq3C.png" alt="enter image description here"></a></p>
  
  <p>By the way the <code>data_train[0].shape</code> is <code>(3,32,32)</code>, 
  but if I reshape the whittened image according to that I get </p>
  
  <pre><code>TypeError: Invalid dimensions for image data
  </code></pre>
  
  <p>Could this be a visualization issue only? if so how can I make sure thats the case? </p>
  
  <p><strong>Update :</strong><br>
  Thanks to @AndrasDeak, I fixed the visualization code this way, but still the output looks random : </p>
  
  <pre><code>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])
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/AOfr0.png" rel="noreferrer"><img src="https://i.stack.imgur.com/AOfr0.png" alt="enter image description here"></a></p>
  
  <p><strong>Update 2:</strong><br>
  This is what I get when I run some of the commands given below : 
  As it can be seen below, toimage can show the image just fine, but trying to reshape it, messes up the image. 
  <a href="https://i.stack.imgur.com/bIA7S.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/bIA7S.jpg" alt="enter image description here"></a></p>
  
  <pre><code># 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()
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/RLQl4.png" rel="noreferrer"><img src="https://i.stack.imgur.com/RLQl4.png" alt="enter image description here"></a></p>
  
  <p>for some wierd reason, this was what I got at first , but then after several tries, it changed to the previous image. 
  <a href="https://i.stack.imgur.com/U4IKq.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/U4IKq.jpg" alt="enter image description here"></a></p>