UFLDL新版教程与编程练习(九):PCA Whitening(主成分分析与白化)

UFLDL是吴恩达团队编写的较早的一门深度学习入门,里面理论加上练习的节奏非常好,每次都想快点看完理论去动手编写练习,因为他帮你打好了整个代码框架,也有详细的注释,所以我们只要实现一点核心的代码编写工作就行了,上手快!

我这里找不到新版对应这块的中文翻译了,-_-,这是倒数第3个练习了,就快完了!
第九节是:PCA Whitening(主成分分析与白化)
PCA:Principal Components Analysis即主成分分析,是一种降维的常用方法,对于图像问题,要使PCA发挥得好,就希望图片经过预处理而能够有:

  1. 0均值
  2. 各特征之间有相同的方差

Whitening:就是使图片邻近像素值的相关性降低的算法
这一节直接放代码吧:

%%================================================================
clear;close all;clc;
%% Step 0a: Load data
%  Here we provide the code to load natural image data into x.
%  x will be a 784 * 600000 matrix, where the kth column x(:, k) corresponds to
%  the raw image data from the kth 12x12 image patch sampled.
%  You do not need to change the code below.

addpath(genpath('E:\SummerCourse\UFLDL\common'))
x = loadMNISTImages('E:\SummerCourse\UFLDL\common\train-images-idx3-ubyte'); % 784*60000
figure('name','Raw images');
randsel = randi(size(x,2),200,1); % A random selection of samples for visualization
display_network(x(:,randsel));

%%================================================================
%% Step 0b: Zero-mean the data (by row)
%  You can make use of the mean and repmat/bsxfun functions.

%%% YOUR CODE HERE %%%
avg = mean(x, 1);     % Compute the mean pixel intensity value separately for each patch. 
x = x - repmat(avg, size(x, 1), 1);
%%================================================================
%% Step 1a: Implement PCA to obtain xRot
%  Implement PCA to obtain xRot, the matrix in which the data is expressed
%  with respect to the eigenbasis of sigma, which is the matrix U.

%%% YOUR CODE HERE %%%
sigma = x * x' / size(x, 2); % covariance matrix
[U,S,V] = svd(sigma);
xRot = U' * x;          % rotated version of the data.

%%================================================================
%% Step 1b: Check your implementation of PCA
%  The covariance matrix for the data expressed with respect to the basis U
%  should be a diagonal matrix with non-zero entries only along the main
%  diagonal. We will verify this here.
%  Write code to compute the covariance matrix, covar. 
%  When visualised as an image, you should see a straight line across the
%  diagonal (non-zero entries) against a blue background (zero entries).

%%% YOUR CODE HERE %%%
covar = xRot * xRot' / size(xRot, 2); % xRot is same size with x
% Visualise the covariance matrix. You should see a line across the
% diagonal against a blue background.
figure('name','Visualisation of covariance matrix');
imagesc(covar);

%%================================================================
%% Step 2: Find k, the number of components to retain
%  Write code to determine k, the number of components to retain in order
%  to retain at least 99% of the variance.

%%% YOUR CODE HERE %%%
% I find k = 300 can retain at least 99% of the variance.
% I find k = 64 can retain at least 90% of the variance.
k = 300;
xTilde = U(:,1:k)' * x; % reduced dimension representation of the data, 
                         % where k is the number of eigenvectors to keep
%%================================================================
%% Step 3: Implement PCA with dimension reduction
%  Now that you have found k, you can reduce the dimension of the data by
%  discarding the remaining dimensions. In this way, you can represent the
%  data in k dimensions instead of the original 144, which will save you
%  computational time when running learning algorithms on the reduced
%  representation.
% 
%  Following the dimension reduction, invert the PCA transformation to produce 
%  the matrix xHat, the dimension-reduced data with respect to the original basis.
%  Visualise the data and compare it to the raw data. You will observe that
%  there is little loss due to throwing away the principal components that
%  correspond to dimensions with low variation.

%%% YOUR CODE HERE %%%
xHat = U * [xTilde;zeros((size(x,1)-k),size(xTilde,2))];
% Visualise the data, and compare it to the raw data
% You should observe that the raw and processed data are of comparable quality.
% For comparison, you may wish to generate a PCA reduced image which
% retains only 90% of the variance.

figure('name',['PCA processed images ',sprintf('(%d / %d dimensions)', k, size(x, 1)),'']);
display_network(xHat(:,randsel));
figure('name','Raw images');
display_network(x(:,randsel));

%%================================================================
%% Step 4a: Implement PCA with whitening and regularisation
%  Implement PCA with whitening and regularisation to produce the matrix
%  xPCAWhite. 

% epsilon = 0; 
epsilon = 0.01; 
%%% YOUR CODE HERE %%%
xPCAwhite = diag(1./sqrt(diag(S) + epsilon)) * U' * x;
%% Step 4b: Check your implementation of PCA whitening 
%  Check your implementation of PCA whitening with and without regularisation. 
%  PCA whitening without regularisation results a covariance matrix 
%  that is equal to the identity matrix. PCA whitening with regularisation
%  results in a covariance matrix with diagonal entries starting close to 
%  1 and gradually becoming smaller. We will verify these properties here.
%  Write code to compute the covariance matrix, covar1. 
%
%  Without regularisation (set epsilon to 0 or close to 0), 
%  when visualised as an image, you should see a red line across the
%  diagonal (one entries) against a blue background (zero entries).
%  With regularisation, you should see a red line that slowly turns
%  blue across the diagonal, corresponding to the one entries slowly
%  becoming smaller.

%%% YOUR CODE HERE %%%
covar1 = xPCAwhite * xPCAwhite' / size(x, 2); 
% Visualise the covariance matrix. You should see a red line across the
% diagonal against a blue background.
figure('name','Visualisation of covariance matrix');
imagesc(covar1);

%%================================================================
%% Step 5: Implement ZCA whitening
%  Now implement ZCA whitening to produce the matrix xZCAWhite. 
%  Visualise the data and compare it to the raw data. You should observe
%  that whitening results in, among other things, enhanced edges.

%%% YOUR CODE HERE %%%
xZCAWhite = U * diag(1./sqrt(diag(S) + epsilon)) * U' * x;
% Visualise the data, and compare it to the raw data.
% You should observe that the whitened images have enhanced edges.
figure('name','ZCA whitened images');
display_network(xZCAWhite(:,randsel));
figure('name','Raw images');
display_network(x(:,randsel));

运行结果:
正则化强度epsilon=0.1的协方差矩阵可视化图:


正则化强度epsilon=0.1的协方差矩阵可视化图

正则化强度epsilon=0的协方差矩阵可视化图:


正则化强度epsilon=0的协方差矩阵可视化图

正则化强度epsilon=0.01时ZCA Whitened图与原图对比
正则化强度epsilon=0.01时ZCA Whitened图与原图对比

正则化强度epsilon=0.1时ZCA Whitened图与原图对比:
正则化强度epsilon=0.1时ZCA Whitened图与原图对比

正则化强度epsilon=1时ZCA Whitened图与原图对比:

正则化强度epsilon=1时ZCA Whitened图与原图对比

保留99% variance(降维后,从原来的784降到现在的300)与原图对比:


保留99% variance

有理解不到位之处,还请指出,有更好的想法,可以在下方评论交流!

推荐阅读更多精彩内容