Commit e552372a authored by Jussi Lindgren's avatar Jussi Lindgren
Browse files

Merge branch 'release-1.1.0-bugfixes' of git+ssh://scm.gforge.inria.fr//gitroot/openvibe/openvibe

parents ac340625 4324b77a
......@@ -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
......
......@@ -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());
......
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