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.ml.linear.learner; 031 032import gov.sandia.cognition.math.matrix.mtj.SparseMatrix; 033 034import java.io.IOException; 035import java.io.PrintWriter; 036import java.io.StringWriter; 037import java.util.HashSet; 038import java.util.Random; 039import java.util.Set; 040 041import org.openimaj.io.WriteableASCII; 042import org.openimaj.ml.linear.learner.init.CurrentUMean; 043import org.openimaj.ml.linear.learner.init.CurrentWMean; 044import org.openimaj.ml.linear.learner.init.SparseRandomInitStrategy; 045import org.openimaj.ml.linear.learner.init.SparseZerosInitStrategy; 046import org.openimaj.ml.linear.learner.loss.SquareMissingLossFunction; 047import org.openimaj.ml.linear.learner.regul.L1L2Regulariser; 048 049/** 050 * Parameters used to control a {@link BilinearSparseOnlineLearner} 051 * 052 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 053 * 054 */ 055public class BilinearLearnerParameters extends LearningParameters implements WriteableASCII { 056 057 /** 058 * whether a bias component is added to w and u. Default is false. 059 */ 060 public static final String BIAS = "bias"; 061 /** 062 * The random seed of any randomised components of this learner (usually 063 * initialisation). Defaults to -1 (i.e. no seed) 064 */ 065 public static final String SEED = "seed"; 066 /** 067 * The initialisation strategy for W. Defaults to a 068 * {@link SparseRandomInitStrategy} with sparsity set to 0.5 069 */ 070 public static final String WINITSTRAT = "winitstrat"; 071 /** 072 * The initialisation strategy for U. Defaults to a 073 * {@link SparseRandomInitStrategy} with sparsity set to 0.5 074 */ 075 public static final String UINITSTRAT = "uinitstrat"; 076 /** 077 * The initialisation strategy for W when it is expanded. Defaults to the 078 * context aware {@link CurrentWMean} 079 */ 080 public static final String EXPANDEDWINITSTRAT = "expandedwinitstrat"; 081 /** 082 * The initialisation strategy for U when it is expanded. Defaults to the 083 * context aware {@link CurrentUMean} 084 */ 085 public static final String EXPANDEDUINITSTRAT = "expandeduinitstrat"; 086 /** 087 * The initialisation strategy for BIAS. Defaults to a 088 * {@link SparseZerosInitStrategy} 089 */ 090 public static final String BIASINITSTRAT = "biasinitstrat"; 091 /** 092 * The maximum number of iterations in the biconvex iterative stage. 093 * defaults to 3 094 */ 095 public static final String BICONVEX_MAXITER = "biconvex_maxiter"; 096 /** 097 * The threshold of the ratio between the (sum(new_w - old_w) + sum(new_u - 098 * old_u)) / (sum(old_u) + sum(old_w)) i.e. some notion of normalised 099 * changed of the paramters. Defaults to 0.01 100 */ 101 public static final String BICONVEX_TOL = "biconvex_tol"; 102 /** 103 * The parameter of the regulariser for W, defaults to LAMBDA 104 */ 105 public static final String LAMBDA_W = "lambda_w"; 106 /** 107 * The parameter of the regulariser for U, defaults to LAMBDA 108 */ 109 public static final String LAMBDA_U = "lambda_u"; 110 /** 111 * The parameter of the regulariser for both W and U 112 */ 113 public static final String LAMBDA = "lambda"; 114 /** 115 * The weighting of the subgradient of U, weighted down each ETASTEPS number 116 * of iterations of the biconvex scheme, defaults to 0.05 117 */ 118 public static final String ETA0_U = "eta0u"; 119 /** 120 * The weighting of the subgradient of W, weighted down each ETASTEPS number 121 * of iterations of the biconvex scheme, defaults to 0.05 122 */ 123 public static final String ETA0_W = "eta0w"; 124 /** 125 * The weighting of the subgradient of BIAS, weighted down each ETASTEPS 126 * number of iterations of the biconvex scheme, defaults to eta0 (0.05) 127 */ 128 public static final String ETA0_BIAS = "biaseta0"; 129 /** 130 * The loss function, defaults to {@link SquareMissingLossFunction} 131 */ 132 public static final String LOSS = "loss"; 133 /** 134 * The regularisation function, defaults to {@link L1L2Regulariser} 135 */ 136 public static final String REGUL = "regul"; 137 138 /** 139 * The steps at which point the eta parameter is reduced, defaults to 3 140 */ 141 public static final String ETASTEPS = "etasteps"; 142 /** 143 * Should all parameter matricies be held {@link SparseMatrix} instances and 144 * therefore remain sparse. Forces a copy but could save a lot. 145 */ 146 public static final String FORCE_SPARCITY = "forcesparcity"; 147 /** 148 * The value of w, u and beta are updated each time data is added s.t. w = w 149 * * (1.0 - DAM 150 * PENING). The default value is 0 151 */ 152 public static final String DAMPENING = "dampening"; 153 154 155 /** 156 * Whether the Vprime and Dprime matrices should be zscore standardised 157 */ 158 public static final String Z_STANDARDISE ="z_standardise"; 159 /** 160 * 161 */ 162 private static final long serialVersionUID = -2059819246888686435L; 163 164 165 /** 166 * The ammount by which ETA is made to increase each iteration 167 */ 168 public static final String ETA_GAMMA = "gamma"; 169 170 /** 171 * sets up the defaults 172 */ 173 public BilinearLearnerParameters() { 174 this.defaults.put(REGUL, new L1L2Regulariser()); 175 this.defaults.put(LOSS, new SquareMissingLossFunction()); 176 this.defaults.put(ETA0_U, 0.05); 177 this.defaults.put(ETA0_W, 0.05); 178 this.defaults.put(LAMBDA, 0.001); 179 this.defaults.put(LAMBDA_W, new Placeholder(LAMBDA)); 180 this.defaults.put(LAMBDA_U, new Placeholder(LAMBDA)); 181 this.defaults.put(BICONVEX_TOL, 0.01); 182 this.defaults.put(BICONVEX_MAXITER, 3); 183 this.defaults.put(SEED, -1); 184 this.defaults.put(WINITSTRAT, new SparseRandomInitStrategy(0, 1, 0.5, new Random())); 185 this.defaults.put(UINITSTRAT, new SparseRandomInitStrategy(0, 1, 0.5, new Random())); 186 this.defaults.put(EXPANDEDWINITSTRAT, new CurrentWMean()); 187 this.defaults.put(EXPANDEDUINITSTRAT, new CurrentUMean()); 188 this.defaults.put(BIAS, false); 189 this.defaults.put(BIASINITSTRAT, new SparseZerosInitStrategy()); 190 this.defaults.put(ETA0_BIAS, 0.05); 191 this.defaults.put(ETASTEPS, 3); 192 this.defaults.put(FORCE_SPARCITY, true); 193 this.defaults.put(DAMPENING, 0d); 194 this.defaults.put(Z_STANDARDISE, false); 195 this.defaults.put(ETA_GAMMA,1.5); 196 } 197 198 @Override 199 public void writeASCII(PrintWriter out) throws IOException { 200 final Set<String> a = new HashSet<String>(this.keySet()); 201 a.addAll(this.defaults.keySet()); 202 for (final String key : a) { 203 out.printf("%s: %s\n", key, this.getTyped(key)); 204 } 205 } 206 207 @Override 208 public String toString() { 209 StringWriter writer = new StringWriter(); 210 PrintWriter pw = new PrintWriter(writer, true); 211 try { 212 writeASCII(pw); 213 } catch (IOException e) { 214 } 215 pw.flush(); 216 return writer.toString(); 217 } 218 219 @Override 220 public String asciiHeader() { 221 return "Bilinear Learner Params"; 222 } 223 224 @Override 225 public BilinearLearnerParameters clone() { 226 BilinearLearnerParameters ret = new BilinearLearnerParameters(); 227 for (java.util.Map.Entry<String, Object> ent : this.entrySet()) { 228 ret.put(ent.getKey(), ent.getValue()); 229 } 230 return ret; 231 } 232 233}