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.experiments.sinabill; 031 032import gov.sandia.cognition.math.matrix.Matrix; 033 034import java.io.File; 035import java.io.IOException; 036import java.util.ArrayList; 037import java.util.HashMap; 038import java.util.List; 039import java.util.Map; 040 041import org.openimaj.io.FileUtils; 042import org.openimaj.io.IOUtils; 043import org.openimaj.ml.linear.data.BillMatlabFileDataGenerator; 044import org.openimaj.ml.linear.data.BillMatlabFileDataGenerator.Mode; 045import org.openimaj.ml.linear.evaluation.BilinearEvaluator; 046import org.openimaj.ml.linear.evaluation.RootMeanSumLossEvaluator; 047import org.openimaj.ml.linear.learner.BilinearLearnerParameters; 048import org.openimaj.ml.linear.learner.BilinearSparseOnlineLearner; 049import org.openimaj.ml.linear.learner.init.SingleValueInitStrat; 050import org.openimaj.ml.linear.learner.init.SparseZerosInitStrategy; 051import org.openimaj.util.pair.Pair; 052 053public class RegretExperiment extends BilinearExperiment{ 054 055 private static final String BATCH_EXPERIMENT = "batchStreamLossExperiments/batch_1366231606223/experiment.log"; 056 057 @Override 058 public void performExperiment() throws Exception { 059 060 Map<Integer,Double> batchLosses = loadBatchLoss(); 061 BilinearLearnerParameters params = new BilinearLearnerParameters(); 062 params.put(BilinearLearnerParameters.ETA0_U, 0.02); 063 params.put(BilinearLearnerParameters.ETA0_W, 0.02); 064 params.put(BilinearLearnerParameters.LAMBDA, 0.001); 065 params.put(BilinearLearnerParameters.BICONVEX_TOL, 0.01); 066 params.put(BilinearLearnerParameters.BICONVEX_MAXITER, 10); 067 params.put(BilinearLearnerParameters.BIAS, true); 068 params.put(BilinearLearnerParameters.ETA0_BIAS, 0.5); 069 params.put(BilinearLearnerParameters.WINITSTRAT, new SingleValueInitStrat(0.1)); 070 params.put(BilinearLearnerParameters.UINITSTRAT, new SparseZerosInitStrategy()); 071 BillMatlabFileDataGenerator bmfdg = new BillMatlabFileDataGenerator( 072 new File(MATLAB_DATA()), 073 98, 074 true 075 ); 076 prepareExperimentLog(params); 077 BilinearSparseOnlineLearner learner = new BilinearSparseOnlineLearner(params); 078 bmfdg.setFold(-1, Mode.ALL); // go through all items in day order 079 int j = 0; 080 BilinearEvaluator eval = new RootMeanSumLossEvaluator(); 081 eval.setLearner(learner); 082 while(true){ 083 Pair<Matrix> next = bmfdg.generate(); 084 if(next == null) break; 085 List<Pair<Matrix>> asList = new ArrayList<Pair<Matrix>>(); 086 asList.add(next); 087 if(learner.getW() != null){ 088 if(!batchLosses.containsKey(j)){ 089 logger.debug(String.format("...No batch result found for: %d, done",j)); 090 break; 091 } 092 logger.debug("...Calculating regret for item"+j); 093 double loss = eval.evaluate(asList); 094 logger.debug(String.format("... loss: %f",loss)); 095 double batchloss = batchLosses.get(j); 096 logger.debug(String.format("... batch loss: %f",batchloss)); 097 logger.debug(String.format("... regret: %f",(loss-batchloss))); 098 } 099 learner.process(next.firstObject(), next.secondObject()); 100 logger.debug(String.format("... loss (post addition): %f",eval.evaluate(asList))); 101 logger.debug(String.format("Saving learner, Fold %d, Item %d",-1, j)); 102 File learnerOut = new File(FOLD_ROOT(-1),String.format("learner_%d",j)); 103 IOUtils.writeBinary(learnerOut, learner); 104 105 j++; 106 } 107 } 108 109 private Map<Integer, Double> loadBatchLoss() throws IOException { 110 String[] batchExperimentLines = FileUtils.readlines(new File( 111 DATA_ROOT(), 112 BATCH_EXPERIMENT 113 )); 114 int seenItems = 0; 115 Map<Integer, Double> ret = new HashMap<Integer, Double>(); 116 for (String line : batchExperimentLines) { 117 118 if(line.contains("New Item Seen: ")){ 119 seenItems = Integer.parseInt(line.split(":")[1].trim()); 120 } 121 122 if(line.contains("Loss:")){ 123 ret.put(seenItems, Double.parseDouble(line.split(":")[1].trim())); 124 } 125 } 126 return ret; 127 } 128 129 public static void main(String[] args) throws Exception { 130 BilinearExperiment exp = new RegretExperiment(); 131 exp.performExperiment(); 132 } 133 134}