From 20efb25a90f0efeb869382ce961b38d4150f5754 Mon Sep 17 00:00:00 2001 From: Tiago Freitas Pereira <tiagofrepereira@gmail.com> Date: Tue, 27 Jan 2015 12:22:36 +0100 Subject: [PATCH] Implemented a different way to deal with two different MAP adaptations --- bob/learn/misc/MAP_gmm_trainer.cpp | 78 ++++++++++++--------------- bob/learn/misc/__MAP_gmm_trainer__.py | 18 ++++--- bob/learn/misc/__kmeans_trainer__.py | 4 +- bob/learn/misc/test_em.py | 6 +-- 4 files changed, 50 insertions(+), 56 deletions(-) diff --git a/bob/learn/misc/MAP_gmm_trainer.cpp b/bob/learn/misc/MAP_gmm_trainer.cpp index 66b3f04..48ce97c 100644 --- a/bob/learn/misc/MAP_gmm_trainer.cpp +++ b/bob/learn/misc/MAP_gmm_trainer.cpp @@ -13,7 +13,6 @@ /************ Constructor Section *********************************/ /******************************************************************/ -static inline bool f(PyObject* o){return o != 0 && PyObject_IsTrue(o) > 0;} /* converts PyObject to bool and returns false if object is NULL */ static auto MAP_GMMTrainer_doc = bob::extension::ClassDoc( BOB_EXT_MODULE_PREFIX ".MAP_GMMTrainer", @@ -27,8 +26,8 @@ static auto MAP_GMMTrainer_doc = bob::extension::ClassDoc( ) - //.add_prototype("gmm_base_trainer,prior_gmm,[reynolds_adaptation],[relevance_factor],[alpha]","") - .add_prototype("gmm_base_trainer, prior_gmm, reynolds_adaptation, [relevance_factor], [alpha]","") + .add_prototype("gmm_base_trainer,prior_gmm,relevance_factor","") + .add_prototype("gmm_base_trainer,prior_gmm,alpha","") .add_prototype("other","") .add_prototype("","") @@ -43,7 +42,7 @@ static auto MAP_GMMTrainer_doc = bob::extension::ClassDoc( static int PyBobLearnMiscMAPGMMTrainer_init_copy(PyBobLearnMiscMAPGMMTrainerObject* self, PyObject* args, PyObject* kwargs) { - char** kwlist = MAP_GMMTrainer_doc.kwlist(1); + char** kwlist = MAP_GMMTrainer_doc.kwlist(2); PyBobLearnMiscMAPGMMTrainerObject* o; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &PyBobLearnMiscMAPGMMTrainer_Type, &o)){ MAP_GMMTrainer_doc.print_usage(); @@ -57,25 +56,46 @@ static int PyBobLearnMiscMAPGMMTrainer_init_copy(PyBobLearnMiscMAPGMMTrainerObje static int PyBobLearnMiscMAPGMMTrainer_init_base_trainer(PyBobLearnMiscMAPGMMTrainerObject* self, PyObject* args, PyObject* kwargs) { - char** kwlist = MAP_GMMTrainer_doc.kwlist(0); + char** kwlist1 = MAP_GMMTrainer_doc.kwlist(0); + char** kwlist2 = MAP_GMMTrainer_doc.kwlist(1); PyBobLearnMiscGMMBaseTrainerObject* gmm_base_trainer; PyBobLearnMiscGMMMachineObject* gmm_machine; - PyObject* reynolds_adaptation = 0; + bool reynolds_adaptation = false; double alpha = 0.5; double relevance_factor = 4.0; + double aux = 0; + PyObject* keyword_relevance_factor = Py_BuildValue("s", kwlist1[2]); + PyObject* keyword_alpha = Py_BuildValue("s", kwlist2[2]); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!|O!dd", kwlist, &PyBobLearnMiscGMMBaseTrainer_Type, &gmm_base_trainer, + //Here we have to select which keyword argument to read + if (kwargs && PyDict_Contains(kwargs, keyword_relevance_factor) && (PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!|d", kwlist1, + &PyBobLearnMiscGMMBaseTrainer_Type, &gmm_base_trainer, &PyBobLearnMiscGMMMachine_Type, &gmm_machine, - &PyBool_Type, &reynolds_adaptation, - &relevance_factor, &alpha )){ - + &aux))) + reynolds_adaptation = true; + else if (kwargs && PyDict_Contains(kwargs, keyword_alpha) && (PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!|d", kwlist2, + &PyBobLearnMiscGMMBaseTrainer_Type, &gmm_base_trainer, + &PyBobLearnMiscGMMMachine_Type, &gmm_machine, + &aux))) + reynolds_adaptation = false; + else{ + std::cout << PyDict_Contains(kwargs, keyword_alpha) << std::endl; + PyErr_Format(PyExc_RuntimeError, "%s. The third argument must be a keyword argument.", Py_TYPE(self)->tp_name); MAP_GMMTrainer_doc.print_usage(); return -1; } + + + + if (reynolds_adaptation) + relevance_factor = aux; + else + alpha = aux; - self->cxx.reset(new bob::learn::misc::MAP_GMMTrainer(gmm_base_trainer->cxx, gmm_machine->cxx, f(reynolds_adaptation),relevance_factor, alpha)); + + self->cxx.reset(new bob::learn::misc::MAP_GMMTrainer(gmm_base_trainer->cxx, gmm_machine->cxx, reynolds_adaptation,relevance_factor, alpha)); return 0; } @@ -172,31 +192,6 @@ int PyBobLearnMiscMAPGMMTrainer_setGMMBaseTrainer(PyBobLearnMiscMAPGMMTrainerObj } -/***** reynolds_adaptation *****/ -static auto reynolds_adaptation = bob::extension::VariableDoc( - "reynolds_adaptation", - "bool", - "Will use the Reynolds adaptation factor? See Eq (14) from [Reynolds2000]_", - "" -); -PyObject* PyBobLearnMiscMAPGMMTrainer_getReynoldsAdaptation(PyBobLearnMiscMAPGMMTrainerObject* self, void*){ - BOB_TRY - return Py_BuildValue("O",self->cxx->getReynoldsAdaptation()?Py_True:Py_False); - BOB_CATCH_MEMBER("reynolds_adaptation could not be read", 0) -} -int PyBobLearnMiscMAPGMMTrainer_setReynoldsAdaptation(PyBobLearnMiscMAPGMMTrainerObject* self, PyObject* value, void*){ - BOB_TRY - - if(!PyBool_Check(value)){ - PyErr_Format(PyExc_RuntimeError, "%s %s expects a boolean", Py_TYPE(self)->tp_name, reynolds_adaptation.name()); - return -1; - } - - self->cxx->setReynoldsAdaptation(f(value)); - return 0; - BOB_CATCH_MEMBER("reynolds_adaptation could not be set", 0) -} - /***** relevance_factor *****/ static auto relevance_factor = bob::extension::VariableDoc( @@ -218,7 +213,7 @@ int PyBobLearnMiscMAPGMMTrainer_setRelevanceFactor(PyBobLearnMiscMAPGMMTrainerOb return -1; } - self->cxx->setRelevanceFactor(f(value)); + self->cxx->setRelevanceFactor(PyFloat_AS_DOUBLE(value)); return 0; BOB_CATCH_MEMBER("relevance_factor could not be set", 0) } @@ -244,7 +239,7 @@ int PyBobLearnMiscMAPGMMTrainer_setAlpha(PyBobLearnMiscMAPGMMTrainerObject* self return -1; } - self->cxx->setAlpha(f(value)); + self->cxx->setAlpha(PyFloat_AS_DOUBLE(value)); return 0; BOB_CATCH_MEMBER("alpha could not be set", 0) } @@ -259,13 +254,6 @@ static PyGetSetDef PyBobLearnMiscMAPGMMTrainer_getseters[] = { gmm_base_trainer.doc(), 0 }, - { - reynolds_adaptation.name(), - (getter)PyBobLearnMiscMAPGMMTrainer_getReynoldsAdaptation, - (setter)PyBobLearnMiscMAPGMMTrainer_setReynoldsAdaptation, - reynolds_adaptation.doc(), - 0 - }, { alpha.name(), (getter)PyBobLearnMiscMAPGMMTrainer_getAlpha, diff --git a/bob/learn/misc/__MAP_gmm_trainer__.py b/bob/learn/misc/__MAP_gmm_trainer__.py index a41855b..18f215d 100644 --- a/bob/learn/misc/__MAP_gmm_trainer__.py +++ b/bob/learn/misc/__MAP_gmm_trainer__.py @@ -11,7 +11,7 @@ import numpy # define the class class MAP_GMMTrainer(_MAP_GMMTrainer): - def __init__(self, gmm_base_trainer, prior_gmm, convergence_threshold=0.001, max_iterations=10, converge_by_likelihood=True, reynolds_adaptation=False, relevance_factor=4., alpha=0.5): + def __init__(self, gmm_base_trainer, prior_gmm, convergence_threshold=0.001, max_iterations=10, converge_by_likelihood=True, **kwargs): """ :py:class:`bob.learn.misc.MAP_GMMTrainer` constructor @@ -26,21 +26,27 @@ class MAP_GMMTrainer(_MAP_GMMTrainer): Number of maximum iterations converge_by_likelihood Tells whether we compute log_likelihood as a convergence criteria, or not - reynolds_adaptation - Will use the Reynolds adaptation procedure? See Eq (14) from [Reynolds2000]_ - relevance_factor - If set the :py:class:`bob.learn.misc.MAP_GMMTrainer.reynolds_adaptation` parameters, will apply the Reynolds Adaptation procedure. See Eq (14) from [Reynolds2000]_ alpha Set directly the alpha parameter (Eq (14) from [Reynolds2000]_), ignoring zeroth order statistics as a weighting factor. + relevance_factor + If set the :py:class:`bob.learn.misc.MAP_GMMTrainer.reynolds_adaptation` parameters, will apply the Reynolds Adaptation procedure. See Eq (14) from [Reynolds2000]_ """ - _MAP_GMMTrainer.__init__(self, gmm_base_trainer, prior_gmm, reynolds_adaptation=reynolds_adaptation, relevance_factor=relevance_factor, alpha=alpha) + if kwargs.get('alpha')!=None: + alpha = kwargs.get('alpha') + _MAP_GMMTrainer.__init__(self, gmm_base_trainer, prior_gmm, alpha=alpha) + else: + relevance_factor = kwargs.get('relevance_factor') + _MAP_GMMTrainer.__init__(self, gmm_base_trainer, prior_gmm, relevance_factor=relevance_factor) self.convergence_threshold = convergence_threshold self.max_iterations = max_iterations self.converge_by_likelihood = converge_by_likelihood + + + def train(self, gmm_machine, data): """ Train the :py:class:bob.learn.misc.GMMMachine using data diff --git a/bob/learn/misc/__kmeans_trainer__.py b/bob/learn/misc/__kmeans_trainer__.py index c4bab14..afe4949 100644 --- a/bob/learn/misc/__kmeans_trainer__.py +++ b/bob/learn/misc/__kmeans_trainer__.py @@ -13,7 +13,7 @@ class KMeansTrainer (_KMeansTrainer): def __init__(self, initialization_method="RANDOM", convergence_threshold=0.001, max_iterations=10, converge_by_average_min_distance=True): """ - :py:class:bob.learn.misc.KMeansTrainer constructor + :py:class:`bob.learn.misc.KMeansTrainer` constructor Keyword Parameters: initialization_method @@ -78,4 +78,4 @@ class KMeansTrainer (_KMeansTrainer): # copy the documentation from the base class -__doc__ = _KMeansTrainer.__doc__ \ No newline at end of file +__doc__ = _KMeansTrainer.__doc__ diff --git a/bob/learn/misc/test_em.py b/bob/learn/misc/test_em.py index 31e510e..dffb86a 100644 --- a/bob/learn/misc/test_em.py +++ b/bob/learn/misc/test_em.py @@ -115,7 +115,7 @@ def test_gmm_MAP_1(): gmm = GMMMachine(bob.io.base.HDF5File(datafile("gmm_ML.hdf5", __name__))) gmmprior = GMMMachine(bob.io.base.HDF5File(datafile("gmm_ML.hdf5", __name__))) - map_gmmtrainer = MAP_GMMTrainer(GMMBaseTrainer(True, False, False),gmmprior, reynolds_adaptation=False, relevance_factor=16) + map_gmmtrainer = MAP_GMMTrainer(GMMBaseTrainer(True, False, False),gmmprior, relevance_factor=4.) #map_gmmtrainer.set_prior_gmm(gmmprior) map_gmmtrainer.train(gmm, ar) @@ -142,7 +142,7 @@ def test_gmm_MAP_2(): gmm.variances = variances gmm.weights = weights - map_adapt = MAP_GMMTrainer(GMMBaseTrainer(True, False, False, mean_var_update_responsibilities_threshold=0.),gmm, alpha=4., relevance_factor=4., reynolds_adaptation=True) + map_adapt = MAP_GMMTrainer(GMMBaseTrainer(True, False, False, mean_var_update_responsibilities_threshold=0.),gmm, relevance_factor=4.) #map_adapt.set_prior_gmm(gmm) gmm_adapted = GMMMachine(2,50) @@ -186,7 +186,7 @@ def test_gmm_MAP_3(): max_iter_gmm = 1 accuracy = 0.00001 map_factor = 0.5 - map_gmmtrainer = MAP_GMMTrainer(GMMBaseTrainer(True, False, False, prior), prior_gmm, alpha=map_factor, reynolds_adaptation=False) + map_gmmtrainer = MAP_GMMTrainer(GMMBaseTrainer(True, False, False, prior), prior_gmm, alpha=map_factor) map_gmmtrainer.max_iterations = max_iter_gmm map_gmmtrainer.convergence_threshold = accuracy -- GitLab