From 47e48287057b49645c5bd880f80fa9a2f1a76c6d Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.anjos@idiap.ch> Date: Tue, 14 Jan 2014 08:59:24 +0100 Subject: [PATCH] Add linear activation --- setup.py | 7 +- .../{identity.cpp => identity_activation.cpp} | 25 ++-- xbob/machine/linear_activation.cpp | 134 ++++++++++++++++++ .../{logistic.cpp => logistic_activation.cpp} | 25 ++-- .../machine/{tanh.cpp => tanh_activation.cpp} | 26 ++-- 5 files changed, 181 insertions(+), 36 deletions(-) rename xbob/machine/{identity.cpp => identity_activation.cpp} (82%) create mode 100644 xbob/machine/linear_activation.cpp rename xbob/machine/{logistic.cpp => logistic_activation.cpp} (82%) rename xbob/machine/{tanh.cpp => tanh_activation.cpp} (80%) diff --git a/setup.py b/setup.py index 77a3d0e..5cbc90e 100644 --- a/setup.py +++ b/setup.py @@ -53,9 +53,10 @@ setup( Extension("xbob.machine._library", [ "xbob/machine/activation.cpp", - "xbob/machine/identity.cpp", - "xbob/machine/tanh.cpp", - "xbob/machine/logistic.cpp", + "xbob/machine/identity_activation.cpp", + "xbob/machine/tanh_activation.cpp", + "xbob/machine/logistic_activation.cpp", + "xbob/machine/linear_activation.cpp", "xbob/machine/main.cpp", ], packages = packages, diff --git a/xbob/machine/identity.cpp b/xbob/machine/identity_activation.cpp similarity index 82% rename from xbob/machine/identity.cpp rename to xbob/machine/identity_activation.cpp index 31ba779..56fa88e 100644 --- a/xbob/machine/identity.cpp +++ b/xbob/machine/identity_activation.cpp @@ -7,9 +7,10 @@ #include <xbob.machine/api.h> -PyDoc_STRVAR(s_activationsubtype_str, XBOB_EXT_MODULE_PREFIX ".IdentityActivation"); +PyDoc_STRVAR(s_identityactivation_str, + XBOB_EXT_MODULE_PREFIX ".IdentityActivation"); -PyDoc_STRVAR(s_activationsubtype_doc, +PyDoc_STRVAR(s_identityactivation_doc, "IdentityActivation() -> new IdentityActivation\n\ \n\ Computes :math:`f(z) = z` as activation function.\n\ @@ -22,9 +23,10 @@ typedef struct { /* Type-specific fields go here. */ bob::machine::IdentityActivation* base; -} PyBobMachineActivationSubtypeObject; +} PyBobMachineIdentityActivationObject; -static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObject* self, PyObject* args, PyObject* kwds) { +static int PyBobMachineIdentityActivation_init +(PyBobMachineIdentityActivationObject* self, PyObject* args, PyObject* kwds) { /* Parses input arguments in a single shot */ static const char* const_kwlist[] = {0}; @@ -39,7 +41,7 @@ static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObjec PyErr_SetString(PyExc_RuntimeError, ex.what()); } catch (...) { - PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_activationsubtype_str); + PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_identityactivation_str); } self->parent.base = self->base; @@ -50,7 +52,8 @@ static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObjec } -static void PyBobMachineActivationSubtype_delete (PyBobMachineActivationSubtypeObject* self) { +static void PyBobMachineIdentityActivation_delete +(PyBobMachineIdentityActivationObject* self) { delete self->base; self->parent.base = 0; @@ -59,13 +62,13 @@ static void PyBobMachineActivationSubtype_delete (PyBobMachineActivationSubtypeO } -PyTypeObject PyBobMachineActivationSubtype_Type = { +PyTypeObject PyBobMachineIdentityActivation_Type = { PyObject_HEAD_INIT(0) 0, /*ob_size*/ 0, /*tp_name*/ - sizeof(PyBobMachineActivationSubtypeObject), /*tp_basicsize*/ + sizeof(PyBobMachineIdentityActivationObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor)PyBobMachineActivationSubtype_delete, /*tp_dealloc*/ + (destructor)PyBobMachineIdentityActivation_delete, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -81,7 +84,7 @@ PyTypeObject PyBobMachineActivationSubtype_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - s_activationsubtype_doc, /* tp_doc */ + s_identityactivation_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -96,7 +99,7 @@ PyTypeObject PyBobMachineActivationSubtype_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)PyBobMachineActivationSubtype_init, /* tp_init */ + (initproc)PyBobMachineIdentityActivation_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; diff --git a/xbob/machine/linear_activation.cpp b/xbob/machine/linear_activation.cpp new file mode 100644 index 0000000..3c43316 --- /dev/null +++ b/xbob/machine/linear_activation.cpp @@ -0,0 +1,134 @@ +/** + * @author Andre Anjos <andre.anjos@idiap.ch> + * @date Mon 13 Jan 2014 17:25:32 CET + * + * @brief Implementation of the Linear Activation function + */ + +#include <xbob.machine/api.h> + +PyDoc_STRVAR(s_linearactivation_str, + XBOB_EXT_MODULE_PREFIX ".LinearActivation"); + +PyDoc_STRVAR(s_linearactivation_doc, +"LinearActivation([C=1.0]) -> new LinearActivation\n\ +\n\ +Computes :math:`f(z) = C \\cdot z` as activation function.\n\ +\n\ +The constructor builds a new linear activation function\n\ +with a given constant. Don't use this if you just want to\n\ +set constant to the default value (1.0). In such a case,\n\ +prefer to use the more efficient :py:class:`IdentityActivation`.\n\ +"); + +typedef struct { + PyBobMachineActivationObject parent; + + /* Type-specific fields go here. */ + bob::machine::LinearActivation* base; + +} PyBobMachineLinearActivationObject; + +static int PyBobMachineLinearActivation_init +(PyBobMachineLinearActivationObject* self, PyObject* args, PyObject* kwds) { + + /* Parses input arguments in a single shot */ + static const char* const_kwlist[] = {0}; + static char** kwlist = const_cast<char**>(const_kwlist); + + double C = 1.0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|d", kwlist, &C)) return -1; + + try { + self->base = new bob::machine::LinearActivation(C); + } + catch (std::exception& ex) { + PyErr_SetString(PyExc_RuntimeError, ex.what()); + } + catch (...) { + PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_linearactivation_str); + } + + self->parent.base = self->base; + + if (PyErr_Occurred()) return -1; + + return 0; + +} + +static void PyBobMachineLinearActivation_delete +(PyBobMachineLinearActivationObject* self) { + + delete self->base; + self->parent.base = 0; + self->base = 0; + self->parent.ob_type->tp_free((PyObject*)self); + +} + +PyDoc_STRVAR(s_C_str, "C"); +PyDoc_STRVAR(s_C_doc, +"The multiplication factor for the linear function (read-only)" +); + +static PyObject* PyBobMachineLinearActivation_C +(PyBobMachineLinearActivationObject* self) { + + return Py_BuildValue("d", self->base->C()); + +} + +static PyGetSetDef PyBobMachineLinearActivation_getseters[] = { + { + s_C_str, + (getter)PyBobMachineLinearActivation_C, + 0, + s_C_doc, + 0 + }, + {0} /* Sentinel */ +}; + +PyTypeObject PyBobMachineLinearActivation_Type = { + PyObject_HEAD_INIT(0) + 0, /*ob_size*/ + 0, /*tp_name*/ + sizeof(PyBobMachineLinearActivationObject), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)PyBobMachineLinearActivation_delete, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + s_linearactivation_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + PyBobMachineLinearActivation_getseters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)PyBobMachineLinearActivation_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; diff --git a/xbob/machine/logistic.cpp b/xbob/machine/logistic_activation.cpp similarity index 82% rename from xbob/machine/logistic.cpp rename to xbob/machine/logistic_activation.cpp index 2fe3279..8a5e669 100644 --- a/xbob/machine/logistic.cpp +++ b/xbob/machine/logistic_activation.cpp @@ -7,9 +7,10 @@ #include <xbob.machine/api.h> -PyDoc_STRVAR(s_activationsubtype_str, XBOB_EXT_MODULE_PREFIX ".LogisticActivation"); +PyDoc_STRVAR(s_logisticactivation_str, + XBOB_EXT_MODULE_PREFIX ".LogisticActivation"); -PyDoc_STRVAR(s_activationsubtype_doc, +PyDoc_STRVAR(s_logisticactivation_doc, "LogisticActivation() -> new LogisticActivation\n\ \n\ Computes :math:`f(z) = 1/(1+ e^{-z})` as activation function.\n\ @@ -22,9 +23,10 @@ typedef struct { /* Type-specific fields go here. */ bob::machine::LogisticActivation* base; -} PyBobMachineActivationSubtypeObject; +} PyBobMachineLogisticActivationObject; -static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObject* self, PyObject* args, PyObject* kwds) { +static int PyBobMachineLogisticActivation_init +(PyBobMachineLogisticActivationObject* self, PyObject* args, PyObject* kwds) { /* Parses input arguments in a single shot */ static const char* const_kwlist[] = {0}; @@ -39,7 +41,7 @@ static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObjec PyErr_SetString(PyExc_RuntimeError, ex.what()); } catch (...) { - PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_activationsubtype_str); + PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_logisticactivation_str); } self->parent.base = self->base; @@ -50,7 +52,8 @@ static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObjec } -static void PyBobMachineActivationSubtype_delete (PyBobMachineActivationSubtypeObject* self) { +static void PyBobMachineLogisticActivation_delete +(PyBobMachineLogisticActivationObject* self) { delete self->base; self->parent.base = 0; @@ -59,13 +62,13 @@ static void PyBobMachineActivationSubtype_delete (PyBobMachineActivationSubtypeO } -PyTypeObject PyBobMachineActivationSubtype_Type = { +PyTypeObject PyBobMachineLogisticActivation_Type = { PyObject_HEAD_INIT(0) 0, /*ob_size*/ 0, /*tp_name*/ - sizeof(PyBobMachineActivationSubtypeObject), /*tp_basicsize*/ + sizeof(PyBobMachineLogisticActivationObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor)PyBobMachineActivationSubtype_delete, /*tp_dealloc*/ + (destructor)PyBobMachineLogisticActivation_delete, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -81,7 +84,7 @@ PyTypeObject PyBobMachineActivationSubtype_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - s_activationsubtype_doc, /* tp_doc */ + s_logisticactivation_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -96,7 +99,7 @@ PyTypeObject PyBobMachineActivationSubtype_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)PyBobMachineActivationSubtype_init, /* tp_init */ + (initproc)PyBobMachineLogisticActivation_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; diff --git a/xbob/machine/tanh.cpp b/xbob/machine/tanh_activation.cpp similarity index 80% rename from xbob/machine/tanh.cpp rename to xbob/machine/tanh_activation.cpp index 39692a6..1a05363 100644 --- a/xbob/machine/tanh.cpp +++ b/xbob/machine/tanh_activation.cpp @@ -7,9 +7,10 @@ #include <xbob.machine/api.h> -PyDoc_STRVAR(s_activationsubtype_str, XBOB_EXT_MODULE_PREFIX ".HyperbolicTangentActivation"); +PyDoc_STRVAR(s_hyperbolictangentactivation_str, + XBOB_EXT_MODULE_PREFIX ".HyperbolicTangentActivation"); -PyDoc_STRVAR(s_activationsubtype_doc, +PyDoc_STRVAR(s_hyperbolictangentactivation_doc, "HyperbolicTangentActivation() -> new HyperbolicTangentActivation\n\ \n\ Computes :math:`f(z) = \\tanh(z)` as activation function.\n\ @@ -22,9 +23,11 @@ typedef struct { /* Type-specific fields go here. */ bob::machine::HyperbolicTangentActivation* base; -} PyBobMachineActivationSubtypeObject; +} PyBobMachineHyperbolicTangentActivationObject; -static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObject* self, PyObject* args, PyObject* kwds) { +static int PyBobMachineHyperbolicTangentActivation_init +(PyBobMachineHyperbolicTangentActivationObject* self, + PyObject* args, PyObject* kwds) { /* Parses input arguments in a single shot */ static const char* const_kwlist[] = {0}; @@ -39,7 +42,7 @@ static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObjec PyErr_SetString(PyExc_RuntimeError, ex.what()); } catch (...) { - PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_activationsubtype_str); + PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_hyperbolictangentactivation_str); } self->parent.base = self->base; @@ -50,7 +53,8 @@ static int PyBobMachineActivationSubtype_init(PyBobMachineActivationSubtypeObjec } -static void PyBobMachineActivationSubtype_delete (PyBobMachineActivationSubtypeObject* self) { +static void PyBobMachineHyperbolicTangentActivation_delete +(PyBobMachineHyperbolicTangentActivationObject* self) { delete self->base; self->parent.base = 0; @@ -59,13 +63,13 @@ static void PyBobMachineActivationSubtype_delete (PyBobMachineActivationSubtypeO } -PyTypeObject PyBobMachineActivationSubtype_Type = { +PyTypeObject PyBobMachineHyperbolicTangentActivation_Type = { PyObject_HEAD_INIT(0) 0, /*ob_size*/ 0, /*tp_name*/ - sizeof(PyBobMachineActivationSubtypeObject), /*tp_basicsize*/ + sizeof(PyBobMachineHyperbolicTangentActivationObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - (destructor)PyBobMachineActivationSubtype_delete, /*tp_dealloc*/ + (destructor)PyBobMachineHyperbolicTangentActivation_delete, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -81,7 +85,7 @@ PyTypeObject PyBobMachineActivationSubtype_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - s_activationsubtype_doc, /* tp_doc */ + s_hyperbolictangentactivation_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -96,7 +100,7 @@ PyTypeObject PyBobMachineActivationSubtype_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)PyBobMachineActivationSubtype_init, /* tp_init */ + (initproc)PyBobMachineHyperbolicTangentActivation_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ }; -- GitLab