Skip to content
Snippets Groups Projects
Commit e47b38c1 authored by FRohde's avatar FRohde
Browse files

- added function to read metadata from file (item-id -> input-/output-vector position)

- added documentation to selected classes/methods
- included Kays code changes in June
parent 872a8543
No related branches found
No related tags found
No related merge requests found
Pipeline #4614 failed
......@@ -9,7 +9,7 @@ dependencies {
compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
compile group: 'org.fusesource.mqtt-client', name: 'mqtt-client', version: '1.15'
compile group: 'org.influxdb', name: 'influxdb-java', version: '2.15'
compile project(':feedbackloop.learner')
// compile project(':feedbackloop.learner')
testCompile group: 'org.testcontainers', name: 'testcontainers', version: '1.11.2'
testCompile group: 'org.testcontainers', name: 'influxdb', version: '1.11.2'
testCompile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.11.2'
......
......@@ -18,7 +18,7 @@ dependencies {
compile project(':feedbackloop.analyze')
compile project(':feedbackloop.plan')
compile project(':feedbackloop.execute')
// compile project(':feedbackloop.learner')
compile project(':feedbackloop.learner')
compile project(':feedbackloop.learner_backup')
compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.9.8'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
......
package de.tudresden.inf.st.eraser.feedbackloop.learner;
import de.tudresden.inf.st.eraser.feedbackloop.learner.LearnerHelper;
import de.tudresden.inf.st.eraser.jastadd.model.*;
import java.time.Instant;
......@@ -6,22 +7,21 @@ import java.util.ArrayList;
import java.util.List;
/**
* Adapter for internally held machine learning models.
* Adapter for accessing machine learning models that are used for activity recognition.
* @author MoralDav
* @author Bierzynski
*
* @author rschoene - Initial contribution
*/
public class ActivityLearningHandler extends LearningHandler{
public ActivityLearningHandler setLearner(LearnerImpl learner) {
return (ActivityLearningHandler)super.setLearner(learner);
public ActivityLearningHandler(LearnerImpl learner, OpenHAB2Model openHAB2model){
super(learner,openHAB2model);
}
public ActivityLearningHandler setModel(InternalMachineLearningModel model) {
return (ActivityLearningHandler)super.setModel(model);
}
public void InitActivityLearning(){}
//get items that this model is supposed to change
@Override
public List<Item> getTargets() {
List<Item> targets = new ArrayList<Item>();
......@@ -32,6 +32,14 @@ public class ActivityLearningHandler extends LearningHandler{
return targets ;
}
/**
* Function accesses the meta-information (text file: at which position within the input vector
* are the values for a specific item id expected to be delivered?) of the activity recognition
* Network-object (managed by the Learner-object) to determine those Items whose current values
* are required by the activity recognition machine-learning model for its decision making.
*
* @return
*/
@Override
public List<Item> getRelevantItems() {
List<Item> relevantItems = new ArrayList<Item>();
......@@ -47,17 +55,25 @@ public class ActivityLearningHandler extends LearningHandler{
this.getLogger().debug("Ignored training trigger.");
}
//classify using the input vector given by newData
@Override
/**
* Function triggers the Learner-object to estimate the current activity using the sensor data
* that are found in the activity learning input vector (which is kept up-to-date by the function
* LearningHandler.newData). The obtained result is wrapped in a PreferenceItem and ExternalMachineLearningResult.
*
* @return
*/
@Override
public MachineLearningResult classify() {
List<Item> targets = getTargets();//get items that this model is supposed to change
//Using activity recognition to get current activity
ActivityItem activity_item = (ActivityItem) targets.get(0);
ActivityItem activity_item = (ActivityItem) targets.get(LearnerHelper.IDX_ACTIVITY_ITEM_TARGET);
//prepare output
List<ItemPreference> preferences = new ArrayList<ItemPreference>();
ItemPreference preference = getPreferenceItem(activity_item, new double[] {this.getLearner().getActivity()});
double [] activity = new double[] {this.getLearner().getActivity()};
ItemPreference preference = wrapIntoPreferenceItem(activity_item, activity, LearnerHelper.ID_ACTIVITY_MODEL);
preferences.add(preference);//add preference to the preferences array
......
......@@ -29,7 +29,9 @@ public class LearnerHelper {
private static DoubleArrayDoubleFunction sigmoid = inputs -> Math.signum(Arrays.stream(inputs).sum());
private static DoubleArrayDoubleFunction tanh = inputs -> Math.tanh(Arrays.stream(inputs).sum());
private static DoubleArrayDoubleFunction function_one = inputs -> 1.0;
public static int ID_ACTIVITY_MODEL = 0;
public static int ID_PREFERENCE_MODEL = 1;
public static int IDX_ACTIVITY_ITEM_TARGET=0;
public static NeuralNetworkRoot transform(EncogModel encogModel) {
NeuralNetworkRoot result = NeuralNetworkRoot.createEmpty();
List<Double> weights = encogModel.getWeights();
......
......@@ -16,17 +16,18 @@ import org.encog.util.arrayutil.NormalizedField;
import org.encog.util.csv.CSVFormat;
import org.encog.util.csv.ReadCSV;
import java.io.File;
import java.io.InputStream;
import java.io.*;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.logging.Level;
/**
* Implementation of the Learner.
*
* @author Bierzyns - Initial contribution
* @author MoralDav
*/
public class LearnerImpl implements Learner {
......@@ -38,8 +39,44 @@ public class LearnerImpl implements Learner {
private CSVFormat format = new CSVFormat('.', ',');
private Map<Integer, Dataset> datasets = new HashMap<>();
private Map<Integer, Network> models = new HashMap<>();
// maps a model-id to an input vector, i.e., to a vector that contains those
// sensor-values/activities that this model will be applied to when LearnerImpl.computeResult
// is called.
private Map<Integer, List<Double>> inputVectors = new HashMap<>();
public Map<String, Integer> readMapFromFile(String string_relative_path){
// create and load properties from file
Properties properties = new Properties();
try{
Path relative_path = Paths.get(string_relative_path);
Path absolute_path = relative_path.toAbsolutePath();
FileInputStream inputStream = new FileInputStream(String.valueOf(absolute_path));
if (inputStream != null) {
properties.load(inputStream);
} else {
throw new FileNotFoundException("property file '" + absolute_path.toString() + "' not found ");
}
inputStream.close();
}catch (IOException e){
System.out.println("error");
}
Map<String, Integer> map = new HashMap<>();
for (final String itemId: properties.stringPropertyNames())
map.put(itemId, Integer.parseInt(properties.getProperty(itemId)));
return map;
}
public void InitModelsVectors(String fileInputVector, String fileOutputVector, int modelId){
Network network = models.get(modelId);
Map<String, Integer> mapInput = readMapFromFile(fileInputVector);
network.setIndexInputvector(mapInput);
Map<String, Integer> mapOutput = readMapFromFile(fileOutputVector);
network.setIndexOutputvector(mapOutput);
}
@Override
public void setKnowledgeBase(Root knowledgeBase) {
this.knowledgeBase = knowledgeBase;
......@@ -67,46 +104,64 @@ public class LearnerImpl implements Learner {
return true;
}
public boolean loadModelFromFile(String path, int modelID, List<Integer> inputMaxes,
List<Integer> inputMins, List<Integer> targetMaxes, List<Integer> targetMins) {
logger.debug("Load model from file {}", path);
models.put(modelID, new Network(path, modelID, inputMaxes, inputMins, targetMaxes, targetMins));
return true;
}
@Override
public boolean loadModelFromFile(File file, int modelID, List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins,List<String> listInputIndex, List<String> listOutputIndex) {
List<Integer> targetMins) {
logger.debug("Load model from file {}", file);
models.put(modelID, new Network(file.getAbsolutePath(), modelID, inputMaxes, inputMins, targetMaxes, targetMins, listInputIndex, listOutputIndex));
models.put(modelID, new Network(file.getAbsolutePath(), modelID, inputMaxes, inputMins, targetMaxes, targetMins));
inputVectors.put(modelID,new ArrayList<>());
return true;
}
@Override
public boolean loadModelFromFile(InputStream input, int modelID, List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins,List<String> listInputIndex, List<String> listOutputIndex) {
List<Integer> targetMins) {
logger.debug("Load model from input stream");
models.put(modelID, new Network(input, modelID, inputMaxes, inputMins, targetMaxes, targetMins, listInputIndex, listOutputIndex));
models.put(modelID, new Network(input, modelID, inputMaxes, inputMins, targetMaxes, targetMins));
inputVectors.put(modelID,new ArrayList<>());
return true;
}
@Override
public boolean train(int inputCount, int outputCount, int hiddenCount, int hiddenNeuronCount, int modelID,
List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins,List<String> listInputIndex, List<String> listOutputIndex) {
public boolean train(int inputCount, int outputCount, int hiddenCount, int hiddenNeuronCount,
int modelID, List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins) {
// Method for the initial training of algorithms and models. That uses external data set for training.
double learningrate = 0.07;
double momentum = 0.02;
if (datasets.get(modelID) != null) {
Dataset set = datasets.get(modelID);
ReadCSV csv = set.getCsv();
Network model = new Network(inputCount, outputCount, hiddenCount, hiddenNeuronCount, modelID, inputMaxes,
inputMins, targetMaxes, targetMins, listInputIndex, listOutputIndex);
inputMins, targetMaxes, targetMins);
model.setLearningrate(learningrate);
model.setMomentum(momentum);
ArrayList<Double> input = new ArrayList<>();
ArrayList<Double> target = new ArrayList<>();
// double[][] input = new double[rowCount][inputMins.size()];
// double[][] target = new double[rowCount][targetMins.size()];
List<Double> input = new ArrayList<>();
List<Double> target = new ArrayList<>();
int countRows = 0;
logger.debug("read csv");
// LOGGER.log(Level.WARNING, "tcol size: " + set.getTargetColumns().size() + "tcol0: " + set.getTargetColumns().get(0) + "tcol1: " + set.getTargetColumns().get(1) + "tcol2: " + set.getTargetColumns().get(2));
while (csv.next()) {
logger.debug("Train next csv row");
// train one row after another
for (int i = 0; i < csv.getColumnCount(); i++) {
int col_nr = i + 1;
if (set.getTargetColumns().contains(col_nr)) {
if (set.getTargetColumns().contains(i)) {
target.add(csv.getDouble(i));
} else {
input.add(csv.getDouble(i));
......@@ -116,11 +171,29 @@ public class LearnerImpl implements Learner {
model.train(input, target);
input.clear();
target.clear();
// train with all rows at same time
/* int tar_nr = 0;
int in_nr = 0;
for (int i = 0; i < csv.getColumnCount(); i++) {
if (set.getTargetColumns().contains(i)) {
target[countRows][tar_nr]= csv.getDouble(i);
tar_nr++;
} else {
input[countRows][in_nr]= csv.getDouble(i);
in_nr++;
}
}
countRows++; */
}
// model.train(input, target);
models.put(modelID, model);
inputVectors.put(modelID,new ArrayList<>());
model.saveModel(modelFolderPath);
model.saveModel(this.modelFolderPath);
return true;
}
......@@ -130,10 +203,10 @@ public class LearnerImpl implements Learner {
@Override
public boolean train(double[][] data, int inputCount, int outputCount, int hiddenCount, int hiddenNeuronCount, int modelID,
List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins, List<Integer> targetColumns, List<String> listInputIndex, List<String> listOutputIndex) {
List<Integer> targetMins, List<Integer> targetColumns) {
Network model = new Network(inputCount, outputCount, hiddenCount, hiddenNeuronCount, modelID, inputMaxes,
inputMins, targetMaxes, targetMins, listInputIndex, listOutputIndex);
inputMins, targetMaxes, targetMins);
return reTrainModel(model, data, targetColumns, modelID);
}
......@@ -163,7 +236,7 @@ public class LearnerImpl implements Learner {
model.train(input, target);
input.clear();
target.clear();
target.clear();
}
}
......@@ -237,7 +310,7 @@ public class LearnerImpl implements Learner {
private void setValueInputVectorByModelId(int modelId, int index, Double value){
this.inputVectors.get(modelId).set(index,value);
this.inputVectors.get(modelId).set(index,value);
}
private int getInputIndex( String itemId, int modelID){
......@@ -249,35 +322,35 @@ public class LearnerImpl implements Learner {
}
public double getActivity(){
double[] output_activity_recognition = this.models.get(0).computeResult(this.inputVectors.get(0));
double[] output_activity_recognition = this.models.get(LearnerHelper.ID_ACTIVITY_MODEL).computeResult(this.inputVectors.get(LearnerHelper.ID_ACTIVITY_MODEL));
return output_activity_recognition[0];
}
public double[] getPreferencesForCurrentActivity(){
return this.models.get(1).computeResult(this.inputVectors.get(1));
return this.models.get(LearnerHelper.ID_PREFERENCE_MODEL).computeResult(this.inputVectors.get(LearnerHelper.ID_PREFERENCE_MODEL));
}
//prepare input vector for classify
private void updateInputVector(Item item, int modelId){
int index = getInputIndex(item.getID(),modelId);//get position in the input vector
//update item in position "index" in input vector
if(item instanceof ColorItem){//color items have three values (HSB)
ColorItem coloritem = (ColorItem) item;
TupleHSB state = coloritem.get_state();
setValueInputVectorByModelId(modelId,index, Double.valueOf(state.getHue()) );
setValueInputVectorByModelId(modelId,index+1, Double.valueOf(state.getSaturation()));
setValueInputVectorByModelId(modelId,index+2, Double.valueOf(state.getBrightness()));
}else{
double value = item.getStateAsDouble();
setValueInputVectorByModelId(modelId,index, value );
}
int index = getInputIndex(item.getID(),modelId);//get position in the input vector
//update item in position "index" in input vector
if(item instanceof ColorItem){//color items have three values (HSB)
ColorItem coloritem = (ColorItem) item;
TupleHSB state = coloritem.get_state();
setValueInputVectorByModelId(modelId,index, Double.valueOf(state.getHue()) );
setValueInputVectorByModelId(modelId,index+1, Double.valueOf(state.getSaturation()));
setValueInputVectorByModelId(modelId,index+2, Double.valueOf(state.getBrightness()));
}else{
double value = item.getStateAsDouble();
setValueInputVectorByModelId(modelId,index, value );
}
}
public void updateLearner(List<Item> changedItems){
int n_models = this.models.size();
for(Item item:changedItems){
for(int i = 0; i< n_models ;i++){
if(this.models.get(i).itemRelevant(item.getID())) {
if(this.models.get(i).isRelevantItem(item.getID())) {
updateInputVector(item, i);
}
}
......@@ -285,21 +358,28 @@ public class LearnerImpl implements Learner {
}
public List<String> getTargetItemsIdsPreferenceLearning() {
return this.models.get(1).getTargetItemsIds();
return this.models.get(LearnerHelper.ID_PREFERENCE_MODEL).getTargetItemsIds();
}
public List<String> getRelevantItemsIdsPrefenceLearning() {
return this.models.get(1).getRelevantItemsIds();
return this.models.get(LearnerHelper.ID_PREFERENCE_MODEL).getRelevantItemsIds();
}
public List<String> getTargetItemsIdsActivityLearning() {
return this.models.get(0).getTargetItemsIds();
return this.models.get(LearnerHelper.ID_ACTIVITY_MODEL).getTargetItemsIds();
}
public List<String> getRelevantItemsIdsActivityLearning() {
return this.models.get(0).getRelevantItemsIds();
return this.models.get(LearnerHelper.ID_ACTIVITY_MODEL).getRelevantItemsIds();
}
public double[] computeResult(int modelID, List<Double> inputVector) {
Network model = this.models.get(modelID);
return model.computeResult(inputVector);
}
}
......@@ -7,36 +7,44 @@ import java.time.Instant;
import java.util.List;
/**
* Adapter for internally held machine learning models.
* Adapter for accessing machine learning models that are held outside of the knowledge base.
* Class contains functions that are commonly used by ActivityLearningHandler and
* PreferenceLearningHandler. It accesses a Learner-object to update all input vectors of the
* associated machine-learning models (function: newData) and the openHAB2model-object to
* obtain references to the Item-objects * of the individual sensors/actuators (function: resolve)
*
* @author rschoene - Initial contribution
* @author MoralDav
* @author Bierzynski
*/
public abstract class LearningHandler implements MachineLearningEncoder, MachineLearningDecoder {
private static final Logger logger = LogManager.getLogger(LearningHandler.class);
private LearnerImpl Learner;
private InternalMachineLearningModel model;
//private InternalMachineLearningModel model;
private OpenHAB2Model openHAB2model;
public LearningHandler(LearnerImpl learner, OpenHAB2Model openHAB2model){
this.Learner = learner;
this.openHAB2model = openHAB2model;
}
public LearnerImpl getLearner() {
return this.Learner;
}
public LearningHandler setLearner(LearnerImpl learner) {
this.Learner=learner;
return this;
}
public OpenHAB2Model getOpenHAB2model(){return this.openHAB2model;}
/**
* Function triggers the Learner to update the input vectors of all Networks (i.e.,
* machine-learning models) that it manages with the item values that have changed
*
* @param changedItems A list of items whose state has changed
*/
@Override
public void newData(List<Item> changedItems) {
//prepare input vector for each model and each item
this.getLearner().updateLearner(changedItems);
}
public LearningHandler setModel(InternalMachineLearningModel model) {
this.model = model;
return this;
}
public static Logger getLogger() {
return logger;
......@@ -47,6 +55,13 @@ public abstract class LearningHandler implements MachineLearningEncoder, Machin
// ignored
}
/**
* Function allows for accessing the Item-object that is associated in the knowledge base
* to the given itemId.
*
* @param itemId
* @return
*/
public Item resolve(String itemId) {
java.util.Optional<Item> maybeItem = this.openHAB2model.resolveItem(itemId);
......@@ -74,9 +89,9 @@ public abstract class LearningHandler implements MachineLearningEncoder, Machin
@Override
public abstract MachineLearningResult classify();
public ItemPreference getPreferenceItem(Item item, double[] output_preferenceLearning){
public ItemPreference wrapIntoPreferenceItem(Item item, double[] output_preferenceLearning, int modelId){
ItemPreference preference;
int index = this.Learner.getOutputIndex(item.getID(),1);
int index = this.Learner.getOutputIndex(item.getID(),modelId);
if(item.getClass().getName()=="ColorItem"){
preference = new ItemPreferenceColor(item, TupleHSB.of( (int)Math.round(output_preferenceLearning[index]), (int)Math.round(output_preferenceLearning[index+1]), (int)Math.round(output_preferenceLearning[index+2])));
}else{
......
......@@ -2,9 +2,9 @@ package de.tudresden.inf.st.eraser.feedbackloop.learner;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -18,14 +18,13 @@ import org.encog.neural.networks.training.propagation.back.Backpropagation;
import org.encog.persist.EncogDirectoryPersistence;
import org.encog.util.arrayutil.NormalizationAction;
import org.encog.util.arrayutil.NormalizedField;
import java.util.HashMap;
import java.util.Map;
import org.encog.util.simple.EncogUtility;
/**
* Network class serves as interface to encog BasicNetwork and holdsfunctions for handling the BasicNetwork (training, input, output and inference)
*
* @author Bierzynski - initial contribution
* @author MoralDav
*/
public class Network {
private static final Logger logger = LogManager.getLogger(Network.class);
......@@ -33,8 +32,17 @@ public class Network {
private int modelID;
private ArrayList<NormalizedField> normalizersIn;
private ArrayList<NormalizedField> normalizersTar;
// maps item-ids to the index positions at which the values of those items
// are expected to be placed in the input-vector of this model (see LearnerImpl.InputVectors)
// TODO: use LearnerImpl.InitModelsVectors to update indexInputvector/indexOutputvector
private Map<String, Integer> indexInputvector = new HashMap<>();
// maps item-ids to the index positions at which the values of those items will be placed within
// the output of this model (see e.g.: PreferenceLearningHandler.classify, Network.computeResult)
private Map<String, Integer> indexOutputvector = new HashMap<>();
private Double learningrate=3.5;
private Double momentum=0.3;
/**
* Constructor for when the neural network is created from data.
......@@ -48,12 +56,14 @@ public class Network {
* @param inputMins list that contains min values of all input columns (sensors) e.g. light intensity 0
* @param targetMaxes list that contains max values of all output columns (results) e.g. brightness 100 for preference learning
* @param targetMins list that contains min values of all output columns (results) e.g. brightness 0 for preference learning
* @param listInputIndex list that containg the item's Ids to initialize the map indexInputvector
* @param listOutputIndex list that containg the item's Ids to initialize the map indexOutpurvector
*/
public Network(int inputCount, int outputCount, int hiddenCount, int hiddenNeuronCount, int modelID,
List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins,List<String> listInputIndex,List<String> listOutputIndex) {
List<Integer> targetMins) {
learningrate = 3.5;
momentum = 0.3;
normalizersIn = new ArrayList<>();
normalizersTar = new ArrayList<>();
......@@ -73,17 +83,15 @@ public class Network {
addNormalizer(inputMaxes, inputMins, normalizersIn);
addNormalizer(targetMaxes, targetMins, normalizersTar);
initializeMaps(listInputIndex,listOutputIndex);
}
private void initializeMaps(List<String> listInputIndex, List<String> listOutputIndex){
for(int i = 0; i < listInputIndex.size();i++){
this.indexInputvector.put(listInputIndex.get(i),i);
}
for(int i = 0; i < listOutputIndex.size();i++){
this.indexOutputvector.put(listOutputIndex.get(i),i);
}
public void setIndexInputvector(Map<String, Integer> indexInputvector) {
this.indexInputvector = indexInputvector;
}
public void setIndexOutputvector(Map<String, Integer> indexOutputvector) {
this.indexOutputvector = indexOutputvector;
}
public List<String> getTargetItemsIds(){
......@@ -121,12 +129,22 @@ public class Network {
* @param inputMins list that contains min values of all input columns (sensors) e.g. light intensity 0
* @param targetMaxes list that contains max values of all output columns (results) e.g. brightness 100 for preference learning
* @param targetMins list that contains min values of all output columns (results) e.g. brightness 0 for preference learning
* @param listInputIndex list that containg the item's Ids to initialize the map indexInputvector
* @param listOutputIndex list that containg the item's Ids to initialize the map indexOutpurvector
*/
public Network(String path, int modelID, List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins, List<String> listInputIndex,List<String> listOutputIndex) {
this(() -> (BasicNetwork) EncogDirectoryPersistence.loadObject(new File(path, "NN_" + modelID)), modelID, inputMaxes, inputMins, targetMaxes, targetMins,listInputIndex,listOutputIndex);
List<Integer> targetMins) {
learningrate = 3.5;
momentum = 0.3;
this.modelID = modelID;
normalizersIn = new ArrayList<>();
normalizersTar = new ArrayList<>();
network = (BasicNetwork) EncogDirectoryPersistence.loadObject(new File(path + "NN_" + modelID));
addNormalizer(inputMaxes, inputMins, normalizersIn);
addNormalizer(targetMaxes, targetMins, normalizersTar);
}
/**
......@@ -139,16 +157,16 @@ public class Network {
* @param inputMins list that contains min values of all input columns (sensors) e.g. light intensity 0
* @param targetMaxes list that contains max values of all output columns (results) e.g. brightness 100 for preference learning
* @param targetMins list that contains min values of all output columns (results) e.g. brightness 0 for preference learning
* @param listInputIndex list that containg the item's Ids to initialize the map indexInputvector
* @param listOutputIndex list that containg the item's Ids to initialize the map indexOutpurvector
*/
public Network(InputStream input, int modelID, List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins, List<String> listInputIndex,List<String> listOutputIndex) {
this(() -> (BasicNetwork) EncogDirectoryPersistence.loadObject(input), modelID, inputMaxes, inputMins, targetMaxes, targetMins, listInputIndex,listOutputIndex);
List<Integer> targetMins) {
this(() -> (BasicNetwork) EncogDirectoryPersistence.loadObject(input), modelID, inputMaxes, inputMins, targetMaxes, targetMins);
}
private Network(LoadEncogModel loader, int modelID, List<Integer> inputMaxes, List<Integer> inputMins, List<Integer> targetMaxes,
List<Integer> targetMins, List<String> listInputIndex,List<String> listOutputIndex) {
List<Integer> targetMins) {
learningrate = 3.5;
momentum = 0.3;
this.modelID = modelID;
normalizersIn = new ArrayList<>();
......@@ -158,7 +176,7 @@ public class Network {
addNormalizer(inputMaxes, inputMins, normalizersIn);
addNormalizer(targetMaxes, targetMins, normalizersTar);
initializeMaps(listInputIndex,listOutputIndex);
}
@FunctionalInterface
......@@ -204,7 +222,36 @@ public class Network {
train.finishTraining();
}
// method to train with all rows
public void train(double[][] input, double[][] target) {
double[][] INPUT_ = new double[input.length][input[0].length];
double[][] IDEAL = new double[target.length][target[0].length];
for(int i = 0; i<input.length; i++) {
for (int j = 0; j < input[0].length; j++) {
INPUT_[i][j] = normalizersIn.get(j).normalize(input[i][j]);
}
}
for(int a = 0; a<target.length; a++) {
for (int b = 0; b < target[0].length; b++) {
IDEAL[a][b] = normalizersTar.get(b).normalize(target[a][b]);
}
}
MLDataSet trainingSet = new BasicMLDataSet(INPUT_, IDEAL);
MLTrain train = new Backpropagation(network, trainingSet, learningrate, momentum);
//int epoch = 1;
do {
train.iteration();
// LOGGER.log(Level.WARNING, "Epoch #" + epoch + " Error:" + train.getError());
// epoch++;
} while (train.getError() > 0.005);
train.finishTraining();
}
/**
* Method that uses the {@link BasicNetwork} to predict/classify/.. something based on an input.
*
......@@ -239,7 +286,15 @@ public class Network {
return normalizersTar;
}
public boolean itemRelevant(String itemId){
public boolean isRelevantItem(String itemId){
return this.indexInputvector.containsKey(itemId);
}
public void setMomentum(Double momentum) {
this.momentum = momentum;
}
public void setLearningrate(Double learningrate) {
this.learningrate = learningrate;
}
}
......@@ -7,18 +7,18 @@ import java.util.List;
/**
* Adapter for internally held machine learning models.
*
* @author rschoene - Initial contribution
* @author MoralDav
* @author Bierzynski
* @
*/
public class PreferenceLearningHandler extends ActivityLearningHandler implements MachineLearningEncoder, MachineLearningDecoder {
public PreferenceLearningHandler setLearner(LearnerImpl learner) {
return (PreferenceLearningHandler) super.setLearner(learner);
}
public PreferenceLearningHandler setModel(InternalMachineLearningModel model) {
return (PreferenceLearningHandler) super.setModel(model);
public PreferenceLearningHandler(LearnerImpl learner, OpenHAB2Model openHAB2model){
super(learner,openHAB2model);
}
@Override
public List<Item> getTargets() {
List<Item> targets = new ArrayList<Item>();
......@@ -29,6 +29,15 @@ public class PreferenceLearningHandler extends ActivityLearningHandler implement
return targets ;
}
/**
* Function accesses the meta-information (text file: at which position within the input vector
* are the values for a specific item id expected to be delivered?) of the preference learning
* Network-object (managed by the Learner-object) to determine those Items whose current values
* are required by the preference learning machine-learning model for its decision making.
*
* @return
*/
@Override
public List<Item> getRelevantItems() {
List<Item> relevantItems = new ArrayList<Item>();
......@@ -44,12 +53,22 @@ public class PreferenceLearningHandler extends ActivityLearningHandler implement
getLogger().debug("Ignored training trigger.");
}
//classify using the input vector given by newData
/**
* Function triggers the Learner-object to estimate the currently preferred lighting configuration
* using the sensor data that are found in the preference learning input vector (which is kept
* up-to-date by the function LearningHandler.newData). To further update this input vector the
* currently performed activity is estimated first and written into the preference learning input
* vector (this.getLearner().updateLearner(changedItems)).
*
* @return
*/
@Override
public MachineLearningResult classify() {
//Using activity recognition to get current activity
MachineLearningResult resultActivityRecognition = super.classify();
ActivityItem current_activity = (ActivityItem) resultActivityRecognition.getPreferences();
List<ItemPreference> preferencesList = resultActivityRecognition.getPreferences();
Item item = preferencesList.get(LearnerHelper.IDX_ACTIVITY_ITEM_TARGET).getItem();
ActivityItem current_activity = (ActivityItem) item ;
//update Learner's state
List<Item> changedItems = new ArrayList<>();
......@@ -64,7 +83,7 @@ public class PreferenceLearningHandler extends ActivityLearningHandler implement
List<ItemPreference> preferences = new ArrayList<ItemPreference>();
List<Item> targets = getTargets();//get items that this model is supposed to change
for (Item i:targets){
ItemPreference preference = getPreferenceItem(i,output_preferenceLearning);
ItemPreference preference = wrapIntoPreferenceItem(i,output_preferenceLearning, LearnerHelper.ID_PREFERENCE_MODEL);
preferences.add(preference);//add preference to the preferences array
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment