From f763cf0edacc2156ee63e7be3de63689fb8add22 Mon Sep 17 00:00:00 2001 From: rschoene <rene.schoene@tu-dresden.de> Date: Fri, 28 Jun 2019 12:26:21 +0200 Subject: [PATCH] Fix Learner bugs. - Let ExternalMachineLearningModel.check() return true instead of throwing an exception - In Learner, use temporary files to store encog model - In MachineLearningImpl, do not use result for now (as newData won't work at the moment) - Minor fixes for base (add logger, add correct input to jastadd gradle task) --- eraser-base/build.gradle | 1 + eraser-base/src/main/jastadd/Logging.jadd | 17 +++++++--- .../src/main/jastadd/MachineLearning.jrag | 3 +- .../inf/st/eraser/starter/EraserStarter.java | 8 ++--- .../inf/st/eraser/starter/Setting.java | 2 +- eraser.starter/starter-setting.yaml | 4 ++- .../feedbackloop.learner_backup/Learner.java | 34 ++++++++++++++----- .../MachineLearningImpl.java | 6 ++-- 8 files changed, 51 insertions(+), 24 deletions(-) diff --git a/eraser-base/build.gradle b/eraser-base/build.gradle index 2d0b1f8e..fbe5f76e 100644 --- a/eraser-base/build.gradle +++ b/eraser-base/build.gradle @@ -118,6 +118,7 @@ task copyRagdoc(type: Copy, dependsOn: cleanRagdoc) { } generateAst.dependsOn preprocess +generateAst.inputs.files file("./src/main/jastadd/mainGen.ast"), file("./src/main/jastadd/mainGen.jadd") //compileJava.dependsOn jastadd // //// always run jastadd diff --git a/eraser-base/src/main/jastadd/Logging.jadd b/eraser-base/src/main/jastadd/Logging.jadd index dd41bc70..710bd79a 100644 --- a/eraser-base/src/main/jastadd/Logging.jadd +++ b/eraser-base/src/main/jastadd/Logging.jadd @@ -1,12 +1,21 @@ aspect Logging { + // Base protected org.apache.logging.log4j.Logger Item.logger = org.apache.logging.log4j.LogManager.getLogger(Item.class); protected org.apache.logging.log4j.Logger ItemPreference.logger = org.apache.logging.log4j.LogManager.getLogger(ItemPreference.class); - protected org.apache.logging.log4j.Logger Neuron.logger = org.apache.logging.log4j.LogManager.getLogger(Neuron.class); + // MachineLearning private org.apache.logging.log4j.Logger DummyMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(DummyMachineLearningModel.class); - private org.apache.logging.log4j.Logger Rule.logger = org.apache.logging.log4j.LogManager.getLogger(Rule.class); - private org.apache.logging.log4j.Logger MqttRoot.logger = org.apache.logging.log4j.LogManager.getLogger(MqttRoot.class); - private org.apache.logging.log4j.Logger InternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(MachineLearningModel.class); + private org.apache.logging.log4j.Logger InternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(InternalMachineLearningModel.class); + private org.apache.logging.log4j.Logger ExternalMachineLearningModel.logger = org.apache.logging.log4j.LogManager.getLogger(ExternalMachineLearningModel.class); + + // NeuralNetwork private org.apache.logging.log4j.Logger NeuralNetworkRoot.logger = org.apache.logging.log4j.LogManager.getLogger(NeuralNetworkRoot.class); private org.apache.logging.log4j.Logger OutputLayer.logger = org.apache.logging.log4j.LogManager.getLogger(OutputLayer.class); + protected org.apache.logging.log4j.Logger Neuron.logger = org.apache.logging.log4j.LogManager.getLogger(Neuron.class); + + // Rules + private org.apache.logging.log4j.Logger Rule.logger = org.apache.logging.log4j.LogManager.getLogger(Rule.class); + + // MQTT + private org.apache.logging.log4j.Logger MqttRoot.logger = org.apache.logging.log4j.LogManager.getLogger(MqttRoot.class); } diff --git a/eraser-base/src/main/jastadd/MachineLearning.jrag b/eraser-base/src/main/jastadd/MachineLearning.jrag index e5fc2f6f..98f5ba3b 100644 --- a/eraser-base/src/main/jastadd/MachineLearning.jrag +++ b/eraser-base/src/main/jastadd/MachineLearning.jrag @@ -112,7 +112,8 @@ aspect MachineLearning { @Override public boolean ExternalMachineLearningModel.check() { - throw new UnsupportedOperationException("check not available for external ML models (yet)!"); + logger.warn("check not available for external ML models (yet)!"); + return true; } //--- mlKind --- diff --git a/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/EraserStarter.java b/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/EraserStarter.java index 1715b337..2442c983 100644 --- a/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/EraserStarter.java +++ b/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/EraserStarter.java @@ -7,7 +7,6 @@ import de.tudresden.inf.st.eraser.feedbackloop.analyze.AnalyzeImpl; import de.tudresden.inf.st.eraser.feedbackloop.api.Analyze; import de.tudresden.inf.st.eraser.feedbackloop.api.Execute; import de.tudresden.inf.st.eraser.feedbackloop.api.Plan; -import de.tudresden.inf.st.eraser.feedbackloop.api.EncogModel; import de.tudresden.inf.st.eraser.feedbackloop.execute.ExecuteImpl; import de.tudresden.inf.st.eraser.feedbackloop.learner_backup.Learner; import de.tudresden.inf.st.eraser.feedbackloop.learner_backup.MachineLearningImpl; @@ -16,7 +15,6 @@ import de.tudresden.inf.st.eraser.jastadd.model.*; import de.tudresden.inf.st.eraser.openhab2.OpenHab2Importer; import de.tudresden.inf.st.eraser.openhab2.mqtt.MQTTUpdater; import de.tudresden.inf.st.eraser.spark.Application; -import de.tudresden.inf.st.eraser.util.JavaUtils; import de.tudresden.inf.st.eraser.util.ParserUtils; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.annotation.Arg; @@ -27,10 +25,8 @@ import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import java.util.Collections; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; @@ -124,7 +120,7 @@ public class EraserStarter { MachineLearningImpl handler = new MachineLearningImpl(learner, MachineLearningImpl.GOAL_ACTIVITY_PHONE_AND_WATCH); handler.setKnowledgeBaseRoot(root); logger.info("Reading activity recognition from csv file {}", settings.activity.file); - handler.initActivities(settings.activity.realURL().toString()); + handler.initActivities(settings.activity.realURL().getFile()); ExternalMachineLearningModel machineLearningModel = new ExternalMachineLearningModel(); machineLearningModel.setEncoder(handler); machineLearningModel.setDecoder(handler); @@ -139,7 +135,7 @@ public class EraserStarter { logger.info("Reading preference learning from csv file {}", settings.preference.file); MachineLearningImpl handler = new MachineLearningImpl(learner, MachineLearningImpl.GOAL_PREFERENCE_BRIGHTNESS_IRIS); handler.setKnowledgeBaseRoot(root); - handler.initPreferences(settings.preference.realURL().toString()); + handler.initPreferences(settings.preference.realURL().getFile()); ExternalMachineLearningModel machineLearningModel = new ExternalMachineLearningModel(); machineLearningModel.setEncoder(handler); machineLearningModel.setDecoder(handler); diff --git a/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/Setting.java b/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/Setting.java index dacbb428..09af126b 100644 --- a/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/Setting.java +++ b/eraser.starter/src/main/java/de/tudresden/inf/st/eraser/starter/Setting.java @@ -32,7 +32,7 @@ class Setting { URL realURL() { if (external) { try { - return Paths.get(file).toUri().toURL(); + return Paths.get(file).toUri().normalize().toURL(); } catch (MalformedURLException e) { logger.catching(e); return null; diff --git a/eraser.starter/starter-setting.yaml b/eraser.starter/starter-setting.yaml index df759704..ca4c6fab 100644 --- a/eraser.starter/starter-setting.yaml +++ b/eraser.starter/starter-setting.yaml @@ -26,6 +26,7 @@ load: activity: # File to read in. Expected format = csv file: datasets/backup/activity_data.csv + external: true # Use dummy model in which the current activity is directly editable. Default: false. dummy: true # Model id. Default: 1. @@ -34,7 +35,8 @@ activity: # Model for preference learning. If dummy is true, then the file parameter is ignored. preference: # File to read in. Expected format = csv - file: datasets/backup/preference_data.csv + file: ../datasets/backup/preference_data.csv + external: true # Use dummy model in which the current activity is directly editable. Default: false. dummy: false # Model id. Default: 1. diff --git a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/Learner.java b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/Learner.java index 52f357b1..e13e0fbe 100644 --- a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/Learner.java +++ b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/Learner.java @@ -1,6 +1,7 @@ package de.tudresden.inf.st.eraser.feedbackloop.learner_backup; import java.io.File; +import java.io.IOException; //import com.sun.javafx.tools.packager.Log; import org.encog.ConsoleStatusReportable; import org.encog.Encog; @@ -26,8 +27,8 @@ public class Learner { * */ private String csv_url_activity; private String csv_url_preference; - private String save_activity_model_file = "datasets/backup/activity_model.eg"; - private String save_preference_model_file = "datasets/backup/preference_model.eg"; + private File save_activity_model_file; + private File save_preference_model_file; private File csv_file; private VersatileDataSource a_souce; private VersatileMLDataSet a_data; @@ -43,6 +44,22 @@ public class Learner { private String[] preference_result; private String activity_result; + public Learner() { + try { + save_activity_model_file = File.createTempFile("activity_model", "eg"); + } catch (IOException e) { + // use local alternative + save_activity_model_file = new File("activity_model.eq"); + } + try { + save_preference_model_file = File.createTempFile("preference_model", "eg"); + } catch (IOException e) { + // use local alternative + save_preference_model_file = new File("preference_model.eg"); + } + save_activity_model_file.deleteOnExit(); + save_preference_model_file.deleteOnExit(); + } private void activityDataAnalyser(String activity_csv_url){ this.csv_url_activity = activity_csv_url; @@ -149,7 +166,7 @@ public class Learner { public String activity_predictor(String[] new_data){ activityDataAnalyser("datasets/backup/activity_data.csv"); - BasicNetwork activity_method = (BasicNetwork) loadObject(new File(save_activity_model_file)); + BasicNetwork activity_method = (BasicNetwork) loadObject(save_activity_model_file); MLData input = activity_helper.allocateInputVector(); System.out.println("input"+activity_helper); String[] activity_new_data = new String[12]; @@ -191,7 +208,7 @@ public class Learner { public String[] preference_predictor(String[] new_data){ preference_result = new String[2]; preferenceDataAnalyser("datasets/backup/preference_data.csv"); - BasicNetwork preference_method = (BasicNetwork)loadObject(new File(save_preference_model_file)); + BasicNetwork preference_method = (BasicNetwork)loadObject(save_preference_model_file); MLData input = preference_helper.allocateInputVector(); // // System.out.print("input: "+input); @@ -206,10 +223,11 @@ public class Learner { preference_result[1] = preference_helper.denormalizeOutputVectorToString(output)[1]; return preference_result; } - private void saveEncogModel(String model_file_url){ - if (model_file_url.equals(save_activity_model_file)){saveObject(new File(model_file_url), this.a_best_method);} - else { - saveObject(new File(model_file_url), this.p_best_method); + private void saveEncogModel(File modelFile){ + if (modelFile.equals(save_activity_model_file)) { + saveObject(modelFile, this.a_best_method); + } else { + saveObject(modelFile, this.p_best_method); } } diff --git a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java index f2f36db3..bebc211f 100644 --- a/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java +++ b/feedbackloop.learner_backup/src/main/java/de/tudresden/inf/st/eraser/feedbackloop.learner_backup/MachineLearningImpl.java @@ -135,14 +135,14 @@ public class MachineLearningImpl implements MachineLearningDecoder, MachineLearn public MachineLearningResult classify() { switch (this.goal) { case GOAL_ACTIVITY_PHONE_AND_WATCH: - String activityStringValue = result[0]; +// String activityStringValue = result[0]; Item activityItem = resolve(this.root.getOpenHAB2Model(), "activity"); // FIXME how to translate activityStringValue to a number? or should activity item state better be a String? - logger.debug("Classify would return activity: {}", activityStringValue); +// logger.debug("Classify would return activity: {}", activityStringValue); ItemPreference classifiedActivity = new ItemPreferenceDouble(activityItem, 0); return new MachineLearningResultImpl(classifiedActivity); case GOAL_PREFERENCE_BRIGHTNESS_IRIS: - String[] preference = {result[1], result[2]}; +// String[] preference = {result[1], result[2]}; // FIXME what is the meaning of result[1] and result[2] Item iris1 = resolve(this.root.getOpenHAB2Model(), "iris1_item"); ItemPreference classifiedPreference = new ItemPreferenceColor(iris1, TupleHSB.of(0, 0, 0)); -- GitLab