Commit 1564d582 authored by Joseph Larralde's avatar Joseph Larralde
Browse files

name cosmetics

parent fefdb5c4
#include "rapidXMM.h"
#include "trainingData.h"
#include "machineLearning.h"
static bool trainingData2xmmTrainingSet(const rapidmix::trainingData& data, xmm::TrainingSet& set) {
if (data.trainingSet.size() <= 1) {
// no recorded phrase (only default one)
return false;
}
if (data.trainingSet.size() > 1 && data.trainingSet[1].elements.size() == 0) {
// empty recorded phrase
return false;
}
rapidmix::trainingData::element el = data.trainingSet[1].elements[0];
int dimIn = static_cast<int>(el.input.size());
int dimOut = static_cast<int>(el.output.size());
// translate and return true if data and set are compatible
// don't translate and return false otherwise
if (dimOut > 0 != set.bimodal()) {
return false;
}
xmm::Phrase xp;
if (set.bimodal()) {
set.dimension.set(dimIn + dimOut);
set.dimension_input.set(dimIn);
xp = xmm::Phrase(xmm::MemoryMode::OwnMemory, xmm::Multimodality::Bimodal);
xp.dimension.set(dimIn + dimOut);
xp.dimension_input.set(dimIn);
} else {
set.dimension.set(dimIn);
set.dimension_input.set(0);
xp = xmm::Phrase(xmm::MemoryMode::OwnMemory, xmm::Multimodality::Unimodal);
xp.dimension.set(dimIn);
xp.dimension_input.set(0);
}
set.clear();
//for (auto &phrase : data.trainingSet) {
// changed to look starting from index 1
// because phrase at index 0 is for unordered elements
for (int i = 1; i < data.trainingSet.size(); ++i) {
const rapidmix::trainingData::phrase &phrase = data.trainingSet[i];
xp.clear();
xp.label.set(phrase.label);
for (auto &element : phrase.elements) {
std::vector<float> obsIn(element.input.begin(), element.input.end());
std::vector<float> obsOut(element.output.begin(), element.output.end());
std::vector<float> obs;
obs.insert(obs.end(), obsIn.begin(), obsIn.end());
obs.insert(obs.end(), obsOut.begin(), obsOut.end());
xp.record(obs);
}
set.addPhrase(static_cast<int>(set.size()), xp);
}
return true;
}
//=============================== xmmTool ====================================//
template <class SingleClassModel, class Model>
bool xmmTool<SingleClassModel, Model>::train(const rapidmix::trainingData& newTrainingData) {
if (trainingData2xmmTrainingSet(newTrainingData, set)) {
model.train(&set);
model.reset();
return true;
}
return false;
}
////////// private JSON data manipulation methods :
//TODO: add a type field (gmm/gmr/hmm/hmr) in metadata when family is xmm
template <class SingleClassModel, class Model>
Json::Value xmmTool<SingleClassModel, Model>::toJSON(/*std::string modelType*/) {
Json::Value root;
Json::Value metadata;
Json::Value modelSet;
metadata["creator"] = "Rapid API C++";
metadata["version"] = "v0.1.1"; //TODO: This should be a macro someplace
metadata["family"] = "xmm";
root["metadata"] = metadata;
modelSet.append(model.toJson());
root["modelSet"] = modelSet;
return root;
}
template <class SingleClassModel, class Model>
bool xmmTool<SingleClassModel, Model>::fromJSON(Json::Value &jm) {
if (jm["metadata"]["family"].asString().compare("xmm") == 0 &&
jm["modelSet"].size() > 0) {
model.fromJson(jm["modelSet"][0]);
model.reset();
return true;
}
return false;
}
////////// public JSON file manipulation interface :
template <class SingleClassModel, class Model>
std::string xmmTool<SingleClassModel, Model>::getJSON() {
Json::Value result = toJSON();
return result.toStyledString();
}
template <class SingleClassModel, class Model>
void xmmTool<SingleClassModel, Model>::writeJSON(const std::string &filepath) {
Json::Value root = toJSON();
std::ofstream jsonOut;
jsonOut.open (filepath);
Json::StyledStreamWriter writer;
writer.write(jsonOut, root);
jsonOut.close();
}
template <class SingleClassModel, class Model>
bool xmmTool<SingleClassModel, Model>::putJSON(const std::string &jsonMessage) {
Json::Value parsedFromString;
Json::Reader reader;
bool parsingSuccessful = reader.parse(jsonMessage, parsedFromString);
return (parsingSuccessful && fromJSON(parsedFromString));
}
template <class SingleClassModel, class Model>
bool xmmTool<SingleClassModel, Model>::readJSON(const std::string &filepath) {
Json::Value root;
std::ifstream file(filepath);
file >> root;
return fromJSON(root);
}
//============================== xmmGmmTool ==================================//
std::vector<double> xmmGmmTool::run(const std::vector<double>& inputVector) {
xmmTool::preProcess(inputVector);
return model.results.smoothed_normalized_likelihoods;
}
//============================== xmmGmrTool ==================================//
std::vector<double> xmmGmrTool::run(const std::vector<double>& inputVector) {
xmmTool::preProcess(inputVector);
std::vector<float> *res = &model.results.output_values;
std::vector<double> dRes(res->begin(), res->end());
return dRes;
}
//============================== xmmHmmTool ==================================//
std::vector<double> xmmHmmTool::run(const std::vector<double>& inputVector) {
xmmTool::preProcess(inputVector);
std::vector<double> res;
int i(0);
for (auto &m : model.models) {
res.push_back(model.results.smoothed_normalized_likelihoods[i]);
res.push_back(m.second.results.progress);
i++;
}
return res;
}
//============================== xmmHmrTool ==================================//
std::vector<double> xmmHmrTool::run(const std::vector<double>& inputVector) {
xmmTool::preProcess(inputVector);
std::vector<float> *res = &model.results.output_values;
std::vector<double> dRes(res->begin(), res->end());
return dRes;
}
///////////////////////////////////////////////////////////////////////////
///// generic train method and forward declaration of specialized templates
///////////////////////////////////////////////////////////////////////////
template <class MachineLearningModule>
bool rapidmix::machineLearning<MachineLearningModule>::train(const trainingData &newTrainingData) {
return MachineLearningModule::train(newTrainingData);
}
template class rapidmix::machineLearning<xmmGmmTool>;
template class rapidmix::machineLearning<xmmGmrTool>;
template class rapidmix::machineLearning<xmmHmmTool>;
template class rapidmix::machineLearning<xmmHmrTool>;
/**
* @file rapidXmmTools.h
* @author joseph larralde
*
* @copyright
* Copyright (C) 2016 - 2017 by IRCAM - Centre Pompidou, Paris, France.
* All rights reserved.
*
* @ingroup machinelearning
*/
#ifndef _RAPID_XMM_TOOLS_H_
#define _RAPID_XMM_TOOLS_H_
// this works !
#ifndef EXTERNAL_JSONCPP_PATH
// #define EXTERNAL_JSONCPP_PATH "../../../../json/json.h" // relative to xmmJson.h
#define EXTERNAL_JSONCPP_PATH "json.h"
#endif /* EXTERNAL_JSONCPP_PATH */
#include "xmm.h"
// forward declaration
namespace rapidmix { class trainingData; }
// original defined in xmmModelConfiguration.hpp
enum xmmRegressionEstimator {
xmmLikeliestRegression,
xmmMixtureRegression
};
// original defined in xmmGaussianDistribution.hpp
enum xmmCovarianceMode {
xmmFullCovariance,
xmmDiagonalCovariance
};
// original defined in xmmHmmParameters.hpp
enum xmmHmmTransitionMode {
xmmHmmLeftRightTransition,
xmmHmmErgodicTransition
};
// original defined in xmmHmmParameters.hpp
enum xmmHmmRegressionEstimator {
xmmHmmFullRegression,
xmmHmmWindowedRegression,
xmmHmmLikeliestRegression
};
// this is the optional argument of machineLearning<xmmWhateverTool>'s constructors
struct xmmToolConfig {
xmmToolConfig() :
gaussians(1),
relativeRegularization(0.01),
absoluteRegularization(0.01),
regressionEstimator(xmmMixtureRegression),
covarianceMode(xmmFullCovariance),
states(5),
hierarchical(true),
hmmTransitionMode(xmmHmmErgodicTransition),
hmmRegressionEstimator(xmmHmmFullRegression),
likelihoodWindow(5) {}
// general parameters :
uint32_t gaussians;
float relativeRegularization;
float absoluteRegularization;
xmmRegressionEstimator regressionEstimator;
xmmCovarianceMode covarianceMode;
// hmm specific :
uint32_t states;
bool hierarchical;
xmmHmmTransitionMode hmmTransitionMode;
xmmHmmRegressionEstimator hmmRegressionEstimator;
// run-time parameter :
uint32_t likelihoodWindow;
};
//========================== template base class =============================//
template <class SingleClassModel, class Model>
class xmmTool {
protected:
xmmTool(bool bimodal) {
model = Model(bimodal);
model.configuration.multithreading = xmm::MultithreadingMode::Sequential;
model.configuration.changed = true;
set = xmm::TrainingSet(xmm::MemoryMode::OwnMemory,
bimodal
? xmm::Multimodality::Bimodal
: xmm::Multimodality::Unimodal
);
}
virtual void preProcess(const std::vector<double> &inputVector) {
std::vector<float> fv(inputVector.begin(), inputVector.end());
model.filter(fv);
}
public:
virtual ~xmmTool() {}
virtual bool train(const rapidmix::trainingData &newTrainingData);
virtual bool reset() {
model.reset();
return true;
}
/** Get a JSON representation of the model in the form of a styled string */
virtual std::string getJSON();
/** Write a JSON model description to specified file path */
virtual void writeJSON(const std::string &filepath);
/** configure empty model with string. See getJSON() */
virtual bool putJSON(const std::string &jsonMessage);
/** read a JSON file at file path and build a modelSet from it */
virtual bool readJSON(const std::string &filepath);
protected:
Model model;
xmm::TrainingSet set;
Json::Value toJSON();
bool fromJSON(Json::Value &jm);
};
//======================= base class for GMM models ==========================//
template <class SingleClassModel, class Model>
class xmmStaticTool : public xmmTool<SingleClassModel, Model> {
protected:
xmmStaticTool(xmmToolConfig cfg, bool bimodal) :
xmmTool<SingleClassModel, Model>(bimodal) {
xmm::Configuration<SingleClassModel>& mCfg = this->model.configuration;
mCfg.gaussians.set(cfg.gaussians);
mCfg.relative_regularization.set(cfg.relativeRegularization);
mCfg.absolute_regularization.set(cfg.absoluteRegularization);
xmm::MultiClassRegressionEstimator mcre;
switch (cfg.regressionEstimator) {
case xmmLikeliestRegression:
mcre = xmm::MultiClassRegressionEstimator::Likeliest;
case xmmMixtureRegression:
default:
mcre = xmm::MultiClassRegressionEstimator::Mixture;
break;
}
mCfg.multiClass_regression_estimator = mcre;
xmm::GaussianDistribution::CovarianceMode gdcm;
switch (cfg.covarianceMode) {
case xmmFullCovariance:
gdcm = xmm::GaussianDistribution::CovarianceMode::Full;
break;
case xmmDiagonalCovariance:
default:
gdcm = xmm::GaussianDistribution::CovarianceMode::Diagonal;
break;
}
mCfg.covariance_mode.set(gdcm);
mCfg.changed = true;
this->model.shared_parameters->likelihood_window.set(cfg.likelihoodWindow);
}
public:
virtual ~xmmStaticTool() {}
};
//======================= base class for HMM models ==========================//
template <class SingleClassModel, class Model>
class xmmTemporalTool : public xmmStaticTool<SingleClassModel, Model> {
protected:
xmmTemporalTool(xmmToolConfig cfg, bool bimodal) :
xmmStaticTool<SingleClassModel, Model>(cfg, bimodal) {
xmm::Configuration<SingleClassModel>& mCfg = this->model.configuration;
mCfg.states.set(cfg.states);
mCfg.hierarchical.set(cfg.hierarchical);
xmm::HMM::TransitionMode htm;
switch (cfg.hmmTransitionMode) {
case xmmHmmLeftRightTransition:
htm = xmm::HMM::TransitionMode::LeftRight;
break;
case xmmHmmErgodicTransition:
default:
htm = xmm::HMM::TransitionMode::Ergodic;
break;
}
mCfg.transition_mode.set(htm);
xmm::HMM::RegressionEstimator hre;
switch (cfg.hmmRegressionEstimator) {
case xmmHmmFullRegression:
hre = xmm::HMM::RegressionEstimator::Full;
break;
case xmmHmmWindowedRegression:
hre = xmm::HMM::RegressionEstimator::Windowed;
break;
case xmmHmmLikeliestRegression:
default:
hre = xmm::HMM::RegressionEstimator::Likeliest;
break;
}
mCfg.regression_estimator.set(hre);
mCfg.changed = true;
}
public:
virtual ~xmmTemporalTool() {}
};
//================== actual classes used in machineLearning.h ================//
/**
* @brief Static classification using Gaussian Mixture Models
*/
class xmmGmmTool : public xmmStaticTool<xmm::GMM, xmm::GMM> {
// class GMM : public xmmStaticTool<xmm::GMM, xmm::GMM> {
public:
xmmGmmTool(xmmToolConfig cfg = xmmToolConfig()) :
// GMM(xmmToolConfig cfg = xmmToolConfig()) :
xmmStaticTool<xmm::GMM, xmm::GMM>(cfg, false) {}
~xmmGmmTool() {}
// ~GMM() {}
std::vector<double> run(const std::vector<double>& inputVector);
};
/**
* @brief Static regression using Gaussian Mixture Models
*/
class xmmGmrTool : public xmmStaticTool<xmm::GMM, xmm::GMM> {
// class GMR : public xmmStaticTool<xmm::GMM, xmm::GMM> {
public:
xmmGmrTool(xmmToolConfig cfg = xmmToolConfig()) :
// GMR(xmmToolConfig cfg = xmmToolConfig()) :
xmmStaticTool<xmm::GMM, xmm::GMM>(cfg, true) {}
~xmmGmrTool() {}
// ~GMR() {}
std::vector<double> run(const std::vector<double>& inputVector);
};
/**
* @brief Temporal classification using Hierarchical Hidden Markov Models
*/
class xmmHmmTool : public xmmTemporalTool<xmm::HMM, xmm::HierarchicalHMM> {
// class HMM : public xmmTemporalTool<xmm::HMM, xmm::HierarchicalHMM> {
public:
xmmHmmTool(xmmToolConfig cfg = xmmToolConfig()) :
// HMM(xmmToolConfig cfg = xmmToolConfig()) :
xmmTemporalTool<xmm::HMM, xmm::HierarchicalHMM>(cfg, false) {}
~xmmHmmTool() {}
// ~HMM() {}
std::vector<double> run(const std::vector<double>& inputVector);
};
/**
* @brief Temporal regression using Hierarchical Hidden Markov Models
*/
class xmmHmrTool : public xmmTemporalTool<xmm::HMM, xmm::HierarchicalHMM> {
// class HMR : public xmmTemporalTool<xmm::HMM, xmm::HierarchicalHMM> {
public:
xmmHmrTool(xmmToolConfig cfg = xmmToolConfig()) :
// HMR(xmmToolConfig cfg = xmmToolConfig()) :
xmmTemporalTool<xmm::HMM, xmm::HierarchicalHMM>(cfg, true) {}
~xmmHmrTool() {}
// ~HMR() {}
std::vector<double> run(const std::vector<double>& inputVector);
};
#endif /* _RAPID_XMM_TOOLS_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment