Commit 2d002e44 authored by Jussi Lindgren's avatar Jussi Lindgren
Browse files

Merge branch 'master' of...

Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/openvibe/openvibe into wip-jlindgre-motor-imagery-improvements
parents ddc5c64d e552372a
......@@ -1278,6 +1278,7 @@ boolean CInterfacedScenario::pickInterfacedObject(int x, int y, int iSizeX, int
return l_bRes;
}
//Fixme: this attribute is part of the saving process. That should not be the case.
#define OV_ClassId_Selected OpenViBE::CIdentifier(0xC67A01DC, 0x28CE06C1)
void CInterfacedScenario::undoCB(boolean bManageModifiedStatusFlag)
......
......@@ -176,14 +176,14 @@ This algorithm provides both hyperplane distance and probabilities.
\par Multilayer Perceptron (MLP)
A classifier algorithm which relies on an artificial neural network (<a href="https://hal.inria.fr/inria-00099922/en">Laurent Bougrain. Practical introduction to artificial neural networks. IFAC symposium on automation in Mining, Mineral and Metal Processing -
MMM'04, Sep 2004, Nancy, France, 6 p, 2004.<a>). In OpenViBE, the MLP is a 2-layers neural networks. The hyperbolic tangent is the activation function of the
neurons inside the hidden layer. The network is train using the backpropagation of the gradient. During the training, 80% of the training set is used to compute the gradient,
and 20% is used to validate the new model. The different weights and biases are updated only once per loop (just before validation). A coefficient alpha (learning coefficient) is used to moderate the importance of
the modification of weights and biases to avoid oscillations. The learning stop when the difference of the error per element (compute during validation) of two consecutive loops is under the value epsilon give in parameter.
MMM'04, Sep 2004, Nancy, France, 6 p, 2004.</a>). In OpenViBE, the MLP is a 2-layer neural network. The hyperbolic tangent is the activation function of the
neurons inside the hidden layer. The network is trained using the backpropagation of the gradient. During the training, 80% of the training set is used to compute the gradient,
and 20% is used to validate the new model. The different weights and biases are updated only once per iteration (just before the validation). A coefficient alpha (learning coefficient) is used to moderate the importance of
the modification of weights and biases to avoid oscillations. The learning stops when the difference of the error per element (computed during validation) of two consecutive iterations is under the value epsilon given as a parameter.
\par
\li Number of neurons in hidden layer: number of neurons that will be used in the hidden layer.
\li Learning stop condition : the epsilon value used to stop the learning
\li Learning coefficient: a coefficient which influence the speed of learning. The smaller the coefficient is, the longer the learning will take, the more chance you will have to have a good solution.
\li Learning coefficient: a coefficient which influence the speed of learning. The smaller the coefficient is, the longer the learning will take, the more chance you will have to get a good solution.
\par
Note that feature vectors are normalized between -1 and 1 (using the min/max of the training set) to avoid saturation of the hyperbolic tangent.
\par
......
......@@ -35,7 +35,7 @@ OpenViBE::int32 OpenViBEPlugins::Classification::LDAClassificationCompare(OpenVi
const OpenViBE::float64 l_f64MaxSecond = *(std::max_element(l_pClassificationValueBuffer, l_pClassificationValueBuffer+rSecondClassificationValue.getBufferElementCount()));
//Then we just compared them
if(!ov_float_equal(l_f64MaxFirst, l_f64MaxSecond))
if(ov_float_equal(l_f64MaxFirst, l_f64MaxSecond))
{
return 0;
}
......@@ -229,6 +229,9 @@ boolean CAlgorithmClassifierLDA::train(const IFeatureVectorSet& rFeatureVectorSe
// Compute cov
if(!m_pCovarianceAlgorithm->process()) {
this->getLogManager() << LogLevel_Error << "Global covariance computation failed\n";
//Free memory before leaving
delete[] l_oPerClassMeans;
return false;
}
......@@ -339,7 +342,7 @@ boolean CAlgorithmClassifierLDA::classify(const IFeatureVector& rFeatureVector,
}
else
{
if(m_vDiscriminantFunctions.size() == 0)
if(m_vDiscriminantFunctions.empty())
{
this->getLogManager() << LogLevel_Error << "LDA discriminant function list is empty\n";
return false;
......@@ -393,8 +396,8 @@ boolean CAlgorithmClassifierLDA::classify(const IFeatureVector& rFeatureVector,
}
rf64Class = m_vLabelList[l_ui32ClassIndex];
delete l_pValueArray;
delete l_pProbabilityValue;
delete[] l_pValueArray;
delete[] l_pProbabilityValue;
}
return true;
}
......
......@@ -43,7 +43,7 @@ OpenViBE::int32 OpenViBEPlugins::Classification::MLPClassificationCompare(OpenVi
OpenViBE::float64 l_f64MaxSecond = *(std::max_element(l_pClassificationValueBuffer, l_pClassificationValueBuffer+rSecondClassificationValue.getBufferElementCount()));
//Then we just compared them
if(!ov_float_equal(l_f64MaxFirst, l_f64MaxSecond))
if(ov_float_equal(l_f64MaxFirst, l_f64MaxSecond))
{
return 0;
}
......
......@@ -148,7 +148,7 @@ boolean CAlgorithmClassifierOneVsAll::classify(const IFeatureVector& rFeatureVec
{
l_oClassificationVector.push_back(CClassifierOutput(static_cast<float64>(op_f64ClassificationStateClass), static_cast<IMatrix*>(op_pClassificationValues)));
}
//this->getLogManager() << LogLevel_Info << l_iClassifierCounter << " " << (float64)op_f64ClassificationStateClass << " " << (*op_pClassificationValues)[0] << "\n";
this->getLogManager() << LogLevel_Debug << l_iClassifierCounter << " " << (float64)op_f64ClassificationStateClass << " " << (*op_pProbabilityValues)[0] << " " << (*op_pProbabilityValues)[1] << "\n";
}
//Now, we determine the best classification
......@@ -167,7 +167,7 @@ boolean CAlgorithmClassifierOneVsAll::classify(const IFeatureVector& rFeatureVec
}
else
{
if((*m_fAlgorithmComparison)((*l_oBest.second), *(l_pTemp.second)) < 0)
if((*m_fAlgorithmComparison)((*l_oBest.second), *(l_pTemp.second)) > 0)
{
l_oBest = l_pTemp;
rf64Class = l_iClassificationCount+1;
......@@ -179,6 +179,7 @@ boolean CAlgorithmClassifierOneVsAll::classify(const IFeatureVector& rFeatureVec
//If no one recognize the class, let's take the more relevant
if(rf64Class == -1)
{
this->getLogManager() << LogLevel_Debug << "Unable to find a class in first instance\n";
for(uint32 l_iClassificationCount = 0; l_iClassificationCount < l_oClassificationVector.size() ; ++l_iClassificationCount)
{
CClassifierOutput& l_pTemp = l_oClassificationVector[l_iClassificationCount];
......@@ -190,7 +191,7 @@ boolean CAlgorithmClassifierOneVsAll::classify(const IFeatureVector& rFeatureVec
else
{
//We take the one that is the least like the second class
if((*m_fAlgorithmComparison)((*l_oBest.second), *(l_pTemp.second)) > 0)
if((*m_fAlgorithmComparison)((*l_oBest.second), *(l_pTemp.second)) < 0)
{
l_oBest = l_pTemp;
rf64Class = l_iClassificationCount+1;
......
......@@ -36,7 +36,7 @@ extern const char* const c_sClassifierRoot;
OpenViBE::int32 OpenViBEPlugins::Classification::SVMClassificationCompare(OpenViBE::IMatrix& rFirstClassificationValue, OpenViBE::IMatrix& rSecondClassificationValue)
{
if(ov_float_equal(rFirstClassificationValue[0], ::fabs(rSecondClassificationValue[0])))
if(ov_float_equal(::fabs(rFirstClassificationValue[0]), ::fabs(rSecondClassificationValue[0])))
return 0;
else if(::fabs(rFirstClassificationValue[0]) > ::fabs(rSecondClassificationValue[0]))
return -1;
......@@ -264,14 +264,16 @@ boolean CAlgorithmClassifierSVM::train(const IFeatureVectorSet& rFeatureVectorSe
m_oProb.y[i] = rFeatureVectorSet[i].getLabel();
for(uint32 j=0;j<m_ui32NumberOfFeatures;j++)
{
m_oProb.x[i][j].index=j;
m_oProb.x[i][j].index=j+1;
m_oProb.x[i][j].value=rFeatureVectorSet[i].getBuffer()[j];
}
m_oProb.x[i][m_ui32NumberOfFeatures].index=-1;
}
if(m_oParam.gamma == 0 && m_ui32NumberOfFeatures > 0)
// Gamma of zero is interpreted as a request for automatic selection
if(m_oParam.gamma == 0)
{
m_oParam.gamma = 1.0/m_ui32NumberOfFeatures;
m_oParam.gamma = 1.0/(m_ui32NumberOfFeatures > 0 ? m_ui32NumberOfFeatures : 1.0);
}
if(m_oParam.kernel_type == PRECOMPUTED)
......@@ -336,13 +338,19 @@ boolean CAlgorithmClassifierSVM::classify(const IFeatureVector& rFeatureVector,
this->getLogManager() << LogLevel_Error << "Classifier expected " << m_ui32NumberOfFeatures << " features, got " << rFeatureVector.getSize() << "\n";
return false;
}
if(m_pModel->param.gamma == 0 &&
(m_pModel->param.kernel_type == POLY || m_pModel->param.kernel_type == RBF || m_pModel->param.kernel_type == SIGMOID))
{
m_pModel->param.gamma = 1.0/(m_ui32NumberOfFeatures > 0 ? m_ui32NumberOfFeatures : 1.0);
this->getLogManager() << LogLevel_Warning << "The SVM model had gamma=0. Setting it to [" << m_pModel->param.gamma << "].\n";
}
//std::cout<<"create l_pX"<<std::endl;
svm_node* l_pX=new svm_node[rFeatureVector.getSize()+1];
//std::cout<<"rFeatureVector.getSize():"<<rFeatureVector.getSize()<<"m_ui32NumberOfFeatures"<<m_ui32NumberOfFeatures<<std::endl;
for(unsigned int i=0;i<rFeatureVector.getSize();i++)
{
l_pX[i].index=i;
l_pX[i].index=i+1;
l_pX[i].value=rFeatureVector.getBuffer()[i];
//std::cout<< l_pX[i].index << ";"<<l_pX[i].value<<" ";
}
......@@ -360,20 +368,16 @@ boolean CAlgorithmClassifierSVM::classify(const IFeatureVector& rFeatureVector,
//std::cout<<rf64Class<<std::endl;
//std::cout<<"probability"<<std::endl;
//If we are not in these mode, label is NULL and there is no probability
//If we are not in these modes, label is NULL and there is no probability
if(m_pModel->param.svm_type == C_SVC || m_pModel->param.svm_type == NU_SVC)
{
rProbabilityValue.setSize(m_pModel->nr_class);
this->getLogManager() << LogLevel_Trace <<"Label predict: "<<rf64Class<<"\n";
for(int i=0;i<m_pModel->nr_class;i++)
{
this->getLogManager() << LogLevel_Trace << "index:"<<i<<" label:"<< m_pModel->label[i]<<" probability:"<<l_pProbEstimates[i]<<"\n";
if( m_pModel->label[i] == 1 )
{
rProbabilityValue.setSize(1);
rProbabilityValue[0]=l_pProbEstimates[i];
}
rProbabilityValue[i]=l_pProbEstimates[i];
}
}
else
......@@ -646,7 +650,7 @@ void CAlgorithmClassifierSVM::loadParamNodeConfiguration(XML::IXMLNode *pParamNo
}
//gamma
l_pTempNode = pParamNode->getChildByName(c_sDegreeNodeName);
l_pTempNode = pParamNode->getChildByName(c_sGammaNodeName);
if(l_pTempNode != NULL)
{
std::stringstream l_sData(l_pTempNode->getPCData());
......
#include "ovpCBoxAlgorithmClassifierProcessor.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <xml/IXMLHandler.h>
......@@ -128,9 +126,9 @@ boolean CBoxAlgorithmClassifierProcessor::loadClassifier(const char* sFilename)
// Connect the params to the new classifier
TParameterHandler < OpenViBE::IMatrix* > ip_oFeatureVector = m_pClassifier->getInputParameter(OVTK_Algorithm_Classifier_InputParameterId_FeatureVector);
ip_oFeatureVector.setReferenceTarget(m_oFeaturesDecoder.getOutputMatrix());
ip_oFeatureVector.setReferenceTarget(m_oFeatureVectorDecoder.getOutputMatrix());
m_oClassificationStateEncoder.getInputMatrix().setReferenceTarget(m_pClassifier->getOutputParameter(OVTK_Algorithm_Classifier_OutputParameterId_ClassificationValues));
m_oHyperplaneValuesEncoder.getInputMatrix().setReferenceTarget(m_pClassifier->getOutputParameter(OVTK_Algorithm_Classifier_OutputParameterId_ClassificationValues));
m_oProbabilityValuesEncoder.getInputMatrix().setReferenceTarget(m_pClassifier->getOutputParameter(OVTK_Algorithm_Classifier_OutputParameterId_ProbabilityValues));
// note: labelsencoder cannot be directly bound here as the classifier returns a float, but we need to output a stimulation
......@@ -163,11 +161,11 @@ boolean CBoxAlgorithmClassifierProcessor::initialize(void)
return false;
}
m_oFeaturesDecoder.initialize(*this,0);
m_oFeatureVectorDecoder.initialize(*this,0);
m_oStimulationDecoder.initialize(*this, 1);
m_oLabelsEncoder.initialize(*this, 0);
m_oClassificationStateEncoder.initialize(*this, 1);
m_oHyperplaneValuesEncoder.initialize(*this, 1);
m_oProbabilityValuesEncoder.initialize(*this, 2);
if(!loadClassifier(l_sConfigurationFilename.toASCIIString()))
......@@ -175,7 +173,6 @@ boolean CBoxAlgorithmClassifierProcessor::initialize(void)
return false;
}
m_bOutputHeaderSent=false;
return true;
}
......@@ -188,12 +185,12 @@ boolean CBoxAlgorithmClassifierProcessor::uninitialize(void)
m_pClassifier = NULL;
}
m_oClassificationStateEncoder.uninitialize();
m_oHyperplaneValuesEncoder.uninitialize();
m_oProbabilityValuesEncoder.uninitialize();
m_oLabelsEncoder.uninitialize();
m_oFeaturesDecoder.uninitialize();
m_oStimulationDecoder.uninitialize();
m_oFeatureVectorDecoder.uninitialize();
return true;
}
......@@ -214,29 +211,24 @@ boolean CBoxAlgorithmClassifierProcessor::process(void)
const uint64 l_ui64StartTime=l_rDynamicBoxContext.getInputChunkStartTime(0, i);
const uint64 l_ui64EndTime=l_rDynamicBoxContext.getInputChunkEndTime(0, i);
m_oFeaturesDecoder.decode(i);
if(m_oFeaturesDecoder.isHeaderReceived())
m_oFeatureVectorDecoder.decode(i);
if(m_oFeatureVectorDecoder.isHeaderReceived())
{
m_bOutputHeaderSent=false;
m_oLabelsEncoder.encodeHeader();
m_oHyperplaneValuesEncoder.encodeHeader();
m_oProbabilityValuesEncoder.encodeHeader();
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_ui64StartTime, l_ui64EndTime);
l_rDynamicBoxContext.markOutputAsReadyToSend(1, l_ui64StartTime, l_ui64EndTime);
l_rDynamicBoxContext.markOutputAsReadyToSend(2, l_ui64StartTime, l_ui64EndTime);
}
if(m_oFeaturesDecoder.isBufferReceived())
if(m_oFeatureVectorDecoder.isBufferReceived())
{
if(m_pClassifier->process(OVTK_Algorithm_Classifier_InputTriggerId_Classify))
{
if (m_pClassifier->isOutputTriggerActive(OVTK_Algorithm_Classifier_OutputTriggerId_Success))
{
//this->getLogManager() << LogLevel_Warning << "---Classification successful---\n";
if(!m_bOutputHeaderSent)
{
m_oLabelsEncoder.encodeHeader();
m_oClassificationStateEncoder.encodeHeader();
m_oProbabilityValuesEncoder.encodeHeader();
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_ui64StartTime, l_ui64StartTime);
l_rDynamicBoxContext.markOutputAsReadyToSend(1, l_ui64StartTime, l_ui64StartTime);
l_rDynamicBoxContext.markOutputAsReadyToSend(2, l_ui64StartTime, l_ui64StartTime);
m_bOutputHeaderSent=true;
}
TParameterHandler < float64 > op_f64ClassificationStateClass(m_pClassifier->getOutputParameter(OVTK_Algorithm_Classifier_OutputParameterId_Class));
......@@ -248,7 +240,7 @@ boolean CBoxAlgorithmClassifierProcessor::process(void)
l_pSet->setStimulationDuration(0, 0);
m_oLabelsEncoder.encodeBuffer();
m_oClassificationStateEncoder.encodeBuffer();
m_oHyperplaneValuesEncoder.encodeBuffer();
m_oProbabilityValuesEncoder.encodeBuffer();
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_ui64StartTime, l_ui64EndTime);
......@@ -257,8 +249,8 @@ boolean CBoxAlgorithmClassifierProcessor::process(void)
}
else
{
// this->getLogManager() << LogLevel_Error << "Classification failed (success trigger not active).\n";
// return false;
this->getLogManager() << LogLevel_Error << "Classification failed (success trigger not active).\n";
return false;
}
}
else
......@@ -267,10 +259,11 @@ boolean CBoxAlgorithmClassifierProcessor::process(void)
return false;
}
}
if(m_oFeaturesDecoder.isEndReceived())
if(m_oFeatureVectorDecoder.isEndReceived())
{
m_oLabelsEncoder.encodeEnd();
m_oClassificationStateEncoder.encodeEnd();
m_oHyperplaneValuesEncoder.encodeEnd();
m_oProbabilityValuesEncoder.encodeEnd();
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_ui64StartTime, l_ui64EndTime);
......
......@@ -32,17 +32,16 @@ namespace OpenViBEPlugins
private:
OpenViBEToolkit::TFeatureVectorDecoder< CBoxAlgorithmClassifierProcessor > m_oFeaturesDecoder;
OpenViBEToolkit::TStimulationDecoder< CBoxAlgorithmClassifierProcessor > m_oStimulationDecoder;
OpenViBEToolkit::TFeatureVectorDecoder < CBoxAlgorithmClassifierProcessor > m_oFeatureVectorDecoder;
OpenViBEToolkit::TStimulationDecoder < CBoxAlgorithmClassifierProcessor > m_oStimulationDecoder;
OpenViBEToolkit::TStimulationEncoder < CBoxAlgorithmClassifierProcessor > m_oLabelsEncoder;
OpenViBEToolkit::TStreamedMatrixEncoder < CBoxAlgorithmClassifierProcessor > m_oHyperplaneValuesEncoder;
OpenViBEToolkit::TStreamedMatrixEncoder < CBoxAlgorithmClassifierProcessor > m_oProbabilityValuesEncoder;
OpenViBEToolkit::TStimulationEncoder< CBoxAlgorithmClassifierProcessor > m_oLabelsEncoder;
OpenViBEToolkit::TStreamedMatrixEncoder< CBoxAlgorithmClassifierProcessor > m_oClassificationStateEncoder;
OpenViBEToolkit::TStreamedMatrixEncoder< CBoxAlgorithmClassifierProcessor > m_oProbabilityValuesEncoder;
OpenViBE::Kernel::IAlgorithmProxy* m_pClassifier;
std::map < OpenViBE::float64, OpenViBE::uint64 > m_vStimulation;
OpenViBE::boolean m_bOutputHeaderSent;
};
class CBoxAlgorithmClassifierProcessorDesc : virtual public OpenViBE::Plugins::IBoxAlgorithmDesc
......
......@@ -3,7 +3,6 @@
#include <system/ovCMemory.h>
#include <system/ovCMath.h>
#include <fstream>
#include <sstream>
#include <cmath>
#include <algorithm>
......@@ -40,8 +39,9 @@ using namespace std;
boolean CBoxAlgorithmClassifierTrainer::initialize(void)
{
m_pClassifier = NULL;
m_pStimulationsDecoder = NULL;
m_pStimulationsEncoder = NULL;
m_oLabelsDecoder.initialize(*this, 0);
m_oStimulationsEncoder.initialize(*this, 0);
IBox& l_rStaticBoxContext=this->getStaticBoxContext();
//As we add some parameter in the middle of "static" parameters, we cannot rely on settings index.
......@@ -104,20 +104,14 @@ boolean CBoxAlgorithmClassifierTrainer::initialize(void)
for(uint32 i=1; i<l_rStaticBoxContext.getInputCount(); i++)
{
m_vFeatureVectorsDecoder[i-1]=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_FeatureVectorStreamDecoder));
m_vFeatureVectorsDecoder[i-1]->initialize();
m_vFeatureVectorsDecoder.push_back(new OpenViBEToolkit::TFeatureVectorDecoder<CBoxAlgorithmClassifierTrainer>());
m_vFeatureVectorsDecoder[i-1]->initialize(*this, i);
}
m_pStimulationsDecoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamDecoder));
m_pStimulationsDecoder->initialize();
//We link the parameters to the extra parameters input parameter to transmit them
TParameterHandler < map<CString , CString> * > ip_pExtraParameter(m_pClassifier->getInputParameter(OVTK_Algorithm_Classifier_InputParameterId_ExtraParameter));
ip_pExtraParameter = m_pParameter;
m_pStimulationsEncoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamEncoder));
m_pStimulationsEncoder->initialize();
m_vFeatureCount.clear();
//If we have to deal with a pairing strategy we have to pass argument
......@@ -145,29 +139,19 @@ boolean CBoxAlgorithmClassifierTrainer::initialize(void)
boolean CBoxAlgorithmClassifierTrainer::uninitialize(void)
{
m_oLabelsDecoder.uninitialize();
m_oStimulationsEncoder.uninitialize();
// IBox& l_rStaticBoxContext=this->getStaticBoxContext();
// IBoxIO& l_rDynamicBoxContext=this->getDynamicBoxContext();
if(m_pClassifier)
{
m_pClassifier->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_pClassifier);
}
if(m_pStimulationsDecoder)
{
m_pStimulationsDecoder->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_pStimulationsDecoder);
}
if(m_pStimulationsEncoder)
{
m_pStimulationsEncoder->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_pStimulationsEncoder);
}
for(uint32 i=0; i<m_vFeatureVectorsDecoder.size(); i++)
{
m_vFeatureVectorsDecoder[i]->uninitialize();
this->getAlgorithmManager().releaseAlgorithm(*m_vFeatureVectorsDecoder[i]);
delete m_vFeatureVectorsDecoder[i];
}
m_vFeatureVectorsDecoder.clear();
......@@ -193,7 +177,6 @@ boolean CBoxAlgorithmClassifierTrainer::uninitialize(void)
boolean CBoxAlgorithmClassifierTrainer::processInput(uint32 ui32InputIndex)
{
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return true;
}
......@@ -208,33 +191,18 @@ boolean CBoxAlgorithmClassifierTrainer::process(void)
// Parses stimulations
for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(0); i++)
{
TParameterHandler < const IMemoryBuffer* > ip_pMemoryBuffer(m_pStimulationsDecoder->getInputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_InputParameterId_MemoryBufferToDecode));
TParameterHandler < const IStimulationSet* > op_pStimulationSet(m_pStimulationsDecoder->getOutputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_OutputParameterId_StimulationSet));
ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(0, i);
TParameterHandler < IStimulationSet* > ip_pStimulationSet(m_pStimulationsEncoder->getInputParameter(OVP_GD_Algorithm_StimulationStreamEncoder_InputParameterId_StimulationSet));
TParameterHandler < IMemoryBuffer* > op_pEncodedMemoryBuffer(m_pStimulationsEncoder->getOutputParameter(OVP_GD_Algorithm_StimulationStreamEncoder_OutputParameterId_EncodedMemoryBuffer));
TParameterHandler < IStimulationSet* > op_pStimulationSet = m_oLabelsDecoder.getOutputStimulationSet();
TParameterHandler < IStimulationSet* > ip_pStimulationSet = m_oStimulationsEncoder.getInputStimulationSet();
CStimulationSet l_oStimulationSet;
ip_pStimulationSet=&l_oStimulationSet;
m_oLabelsDecoder.decode(i);
if(l_rStaticBoxContext.getOutputCount()>=1)
{
op_pEncodedMemoryBuffer=l_rDynamicBoxContext.getOutputChunk(0);
}
else
if(m_oLabelsDecoder.isHeaderReceived())
{
op_pEncodedMemoryBuffer->setSize(0, true);
}
m_pStimulationsDecoder->process();
m_oStimulationsEncoder.encodeHeader();
if(m_pStimulationsDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedHeader))
{
m_pStimulationsEncoder->process(OVP_GD_Algorithm_StimulationStreamEncoder_InputTriggerId_EncodeHeader);
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_rDynamicBoxContext.getInputChunkStartTime(0, i), l_rDynamicBoxContext.getInputChunkEndTime(0, i));
}
if(m_pStimulationsDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedBuffer))
if(m_oLabelsDecoder.isBufferReceived())
{
for(uint64 j=0; j<op_pStimulationSet->getStimulationCount(); j++)
{
......@@ -244,22 +212,22 @@ boolean CBoxAlgorithmClassifierTrainer::process(void)
this->getLogManager() << LogLevel_Trace << "Raising train-completed Flag.\n";
uint64 l_ui32TrainCompletedStimulation = this->getTypeManager().getEnumerationEntryValueFromName(OV_TypeId_Stimulation,"OVTK_StimulationId_TrainCompleted");
l_oStimulationSet.appendStimulation(l_ui32TrainCompletedStimulation, op_pStimulationSet->getStimulationDate(j), 0);
ip_pStimulationSet->appendStimulation(l_ui32TrainCompletedStimulation, op_pStimulationSet->getStimulationDate(j), 0);
}
}
m_pStimulationsEncoder->process(OVP_GD_Algorithm_StimulationStreamEncoder_InputTriggerId_EncodeBuffer);
m_oStimulationsEncoder.encodeBuffer();
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_rDynamicBoxContext.getInputChunkStartTime(0, i), l_rDynamicBoxContext.getInputChunkEndTime(0, i));
}
if(m_pStimulationsDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedEnd))
if(m_oLabelsDecoder.isEndReceived())
{
m_pStimulationsEncoder->process(OVP_GD_Algorithm_StimulationStreamEncoder_InputTriggerId_EncodeEnd);
}
m_oStimulationsEncoder.encodeEnd();
if(l_rStaticBoxContext.getOutputCount()>=1)
{
l_rDynamicBoxContext.markOutputAsReadyToSend(0, l_rDynamicBoxContext.getInputChunkStartTime(0, i), l_rDynamicBoxContext.getInputChunkEndTime(0, i));
}
l_rDynamicBoxContext.markInputAsDeprecated(0, i);
//l_rDynamicBoxContext.markInputAsDeprecated(0, i);
}
// Parses feature vectors
......@@ -267,28 +235,25 @@ boolean CBoxAlgorithmClassifierTrainer::process(void)
{
for(j=0; j<l_rDynamicBoxContext.getInputChunkCount(i); j++)
{
TParameterHandler < const IMemoryBuffer* > ip_pFeatureVectorMemoryBuffer(m_vFeatureVectorsDecoder[i-1]->getInputParameter(OVP_GD_Algorithm_FeatureVectorStreamDecoder_InputParameterId_MemoryBufferToDecode));
TParameterHandler < const IMatrix* > op_pFeatureVectorMatrix(m_vFeatureVectorsDecoder[i-1]->getOutputParameter(OVP_GD_Algorithm_FeatureVectorStreamDecoder_OutputParameterId_Matrix));
ip_pFeatureVectorMemoryBuffer=l_rDynamicBoxContext.getInputChunk(i, j);
m_vFeatureVectorsDecoder[i-1]->process();
if(m_vFeatureVectorsDecoder[i-1]->isOutputTriggerActive(OVP_GD_Algorithm_FeatureVectorStreamDecoder_OutputTriggerId_ReceivedHeader))
TParameterHandler < IMatrix* > op_pFeatureVectorMatrix = m_vFeatureVectorsDecoder[i-1]->getOutputMatrix();
m_vFeatureVectorsDecoder[i-1]->decode(j);
if(m_vFeatureVectorsDecoder[i-1]->isHeaderReceived())
{
}
if(m_vFeatureVectorsDecoder[i-1]->isOutputTriggerActive(OVP_GD_Algorithm_FeatureVectorStreamDecoder_OutputTriggerId_ReceivedBuffer))
if(m_vFeatureVectorsDecoder[i-1]->isBufferReceived())
{
CBoxAlgorithmClassifierTrainer::SFeatureVector l_oFeatureVector;
l_oFeatureVector.m_pFeatureVectorMatrix=new CMatrix();
l_oFeatureVector.m_ui64StartTime=l_rDynamicBoxContext.getInputChunkStartTime(i, j);
l_oFeatureVector.m_ui64EndTime=l_rDynamicBoxContext.getInputChunkEndTime(i, j);
l_oFeatureVector.m_ui32InputIndex=i;
OpenViBEToolkit::Tools::Matrix::copy(*l_oFeatureVector.m_pFeatureVectorMatrix, *op_pFeatureVectorMatrix);
m_vFeatureVector.push_back(l_oFeatureVector);
m_vFeatureCount[i]++;
}
if(m_vFeatureVectorsDecoder[i-1]->isOutputTriggerActive(OVP_GD_Algorithm_FeatureVectorStreamDecoder_OutputTriggerId_ReceivedEnd))
if(m_vFeatureVectorsDecoder[i-1]->isEndReceived())
{
}
l_rDynamicBoxContext.markInputAsDeprecated(i, j);
//l_rDynamicBoxContext.markInputAsDeprecated(i, j);
}
}
......@@ -300,7 +265,7 @@ boolean CBoxAlgorithmClassifierTrainer::process(void)
this->getLogManager() << LogLevel_Error << "Fewer examples (" << (uint32)m_vFeatureVector.size() << ") than the specified partition count (" << m_ui64PartitionCount << ").\n";
return false;
}
if(m_vFeatureVector.size()==0)
if(m_vFeatureVector.empty())
{
this->getLogManager() << LogLevel_Warning << "Received train stimulation but no training examples received\n";
}
......@@ -313,8 +278,6 @@ boolean CBoxAlgorithmClassifierTrainer::process(void)
this->getLogManager() << LogLevel_Trace << "For information, we have " << m_vFeatureCount[i] << " feature vector(s) for input " << i << "\n";
}
float64 l_f64PartitionAccuracy=0;
float64 l_f64FinalAccuracy=0;
vector<float64> l_vPartitionAccuracies((unsigned int)m_ui64PartitionCount);
boolean l_bRandomizeVectorOrder = (&(this->getConfigurationManager()))->expandAsBoolean("${Plugin_Classification_RandomizeKFoldTestData}");
......@@ -340,6 +303,8 @@ boolean CBoxAlgorithmClassifierTrainer::process(void)
if(m_ui64PartitionCount>=2)
{
float64 l_f64PartitionAccuracy=0;
float64 l_f64FinalAccuracy=0;
OpenViBEToolkit::Tools::Matrix::clearContent(l_oConfusion);
......@@ -480,8 +445,11 @@ float64 CBoxAlgorithmClassifierTrainer::getAccuracy(const size_t uiStartIndex, c
{