Why do I get so different results for FastICA when I pre-whiten the signal myself compare the the whitening performed by scikitlearn?
Here is an example of me running the code using the whitening via scikitlearn.
%matplotlib inline
from matplotlib.pyplot import *
from numpy import *
from numpy.random import *
# Load three images
import imageio
i1 = imageio.imread('4.2.05.tiff')
i2 = imageio.imread('4.2.06.tiff')
i3 = imageio.imread('4.2.07.tiff')
# Make a mixing matrix
A = 5*random( (3,3)) + 1
# Make mixtures and rescale
M = stack( (i1,i2,i3), 3).reshape( -1, 3) @ A.T
M /= amax( M, 0)
# Apply FastICA on mixture
from sklearn.decomposition import FastICA
Z = FastICA(whiten=True).fit_transform( M)
# Shift and scale to image range
Z -= amin( Z, 0)
Z /= amax( Z, 0)
# Show me
subplot( 1, 3, 1)
imshow( concatenate( (i1,i2,i3), 0))
title( 'Originals'), xticks([]), yticks([])
subplot( 1, 3, 2)
imshow( concatenate( (M[:,0].reshape(i1.shape),M[:,1].reshape(i1.shape),M[:,2].reshape(i1.shape)), 0))
title( 'Mixtures'), xticks([]), yticks([])
subplot( 1, 3, 3)
imshow( concatenate( (Z[:,0].reshape(i1.shape),Z[:,1].reshape(i1.shape),Z[:,2].reshape(i1.shape)), 0))
title( 'Outputs'), xticks([]), yticks([])
tight_layout()
Here we pre-whiten the signals ourselves before placing it as an input to scikitlearn and set the whitening to False.
def svd_whiten(X):
X_mean = X.mean(axis=0)
X -= X_mean
U, s, Vt = np.linalg.svd(X, full_matrices=False)
# U and Vt are the singular matrices, and s contains the singular values.
# Since the rows of both U and Vt are orthonormal vectors, then U * Vt
# will be white
X_white = np.dot(U, Vt)
return X_white
M_whitened = svd_whiten(M)
Z_prewhitened = FastICA(whiten=False).fit_transform( M_whitened)
# Shift and scale to image range
Z_prewhitened -= amin( Z_prewhitened, 0)
Z_prewhitened /= amax( Z_prewhitened, 0)
# Show me
subplot( 1, 3, 1)
imshow( concatenate( (i1,i2,i3), 0))
title( 'Originals'), xticks([]), yticks([])
subplot( 1, 3, 2)
imshow( concatenate( (M[:,0].reshape(i1.shape),M[:,1].reshape(i1.shape),M[:,2].reshape(i1.shape)), 0))
title( 'Mixtures'), xticks([]), yticks([])
subplot( 1, 3, 3)
imshow( concatenate( (Z_prewhitened[:,0].reshape(i1.shape),Z_prewhitened[:,1].reshape(i1.shape),Z_prewhitened[:,2].reshape(i1.shape)), 0))
title( 'Outputs'), xticks([]), yticks([])
tight_layout()
If we set the whiten to True. We get the exact same results as without pre-whitening, but if we set the whiten to False, we get very different results. Why is this the case? Am I making a mistake somewhere?