001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.math.matrix.algorithm.whitening; 031 032import org.openimaj.citation.annotation.Reference; 033import org.openimaj.citation.annotation.ReferenceType; 034import org.openimaj.math.matrix.algorithm.pca.SvdPrincipalComponentAnalysis; 035import org.openimaj.math.statistics.normalisation.Normaliser; 036 037import Jama.Matrix; 038 039/** 040 * The ZCA Whitening transform. Works like PCA whitening, but after variance 041 * normalisation, rotates the data back to the original orientation. The benefit 042 * is that the data will still "look-like" the original input to some extent. 043 * 044 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 045 */ 046@Reference( 047 type = ReferenceType.Article, 048 author = { "Anthony J. Bell", "Terrence J. Sejnowski" }, 049 title = "The `Independent Components' of Natural Scenes are Edge Filters.", 050 year = "1997", 051 journal = "VISION RESEARCH", 052 pages = { "3327", "", "3338" }, 053 volume = "37") 054public class ZCAWhitening extends PCAWhitening { 055 /** 056 * Construct with the given variance regularization parameter and data 057 * normalisation strategy. 058 * 059 * @param eps 060 * the variance normalisation regularizer (each principle 061 * dimension is divided by sqrt(lamba + eps), where lamba is the 062 * corresponding eigenvalue). 063 * @param ns 064 * the normalisation to apply to each input data vector prior to 065 * training the transform or applying the actual whitening. 066 */ 067 public ZCAWhitening(double eps, Normaliser ns) { 068 super(eps, ns); 069 } 070 071 @Override 072 public void train(double[][] data) { 073 ns.normalise(data); 074 final double[][] normData = ns.normalise(data); 075 076 final SvdPrincipalComponentAnalysis pca = new SvdPrincipalComponentAnalysis(); 077 pca.learnBasisNorm(new Matrix(normData)); 078 transform = pca.getBasis().copy(); 079 final double[] weight = pca.getEigenValues(); 080 final double[][] td = transform.getArray(); 081 082 for (int c = 0; c < weight.length; c++) 083 weight[c] = 1 / Math.sqrt(weight[c] + eps); 084 085 for (int r = 0; r < td.length; r++) 086 for (int c = 0; c < td[0].length; c++) 087 td[r][c] = td[r][c] * weight[c]; 088 089 transform = transform.times(pca.getBasis().transpose()); 090 } 091}