Skip to content
Snippets Groups Projects
Commit 86393d58 authored by Tiago de Freitas Pereira's avatar Tiago de Freitas Pereira
Browse files

In this issue I'm:

1. Removed the loading and saving functions via HDF5 in the C++ and in the python API

2. Implemented the methods `to_dict` and `from_dict` for the Machine

3. Test cases

4. [black]

BIC and GFK machines are still missing
parent 0e7c2005
Branches
No related tags found
1 merge request!11WIP: First attempt to approach the issue bob.bio.base#106
Pipeline #32525 failed
......@@ -5,9 +5,11 @@ import bob.learn.activation
# import our own Library
import bob.extension
bob.extension.load_bob_library('bob.learn.linear', __file__)
bob.extension.load_bob_library("bob.learn.linear", __file__)
from ._library import *
from .machine import Machine
from . import version
from .version import module as __version__
from .version import api as __api_version__
......@@ -15,10 +17,13 @@ from .version import api as __api_version__
from .auxiliary import *
from .GFK import GFKMachine, GFKTrainer
def get_config():
"""Returns a string containing the configuration information.
"""
return bob.extension.get_config(__name__, version.externals, version.api)
"""
Returns a string containing the configuration information.
"""
return bob.extension.get_config(__name__, version.externals, version.api)
# gets sphinx autodoc done right - don't remove it
__all__ = [_ for _ in dir() if not _.startswith('_')]
__all__ = [_ for _ in dir() if not _.startswith("_")]
......@@ -65,10 +65,6 @@ namespace bob { namespace learn { namespace linear {
{
}
Machine::Machine (bob::io::base::HDF5File& config) {
load(config);
}
Machine::~Machine() {}
Machine& Machine::operator=
......@@ -106,28 +102,6 @@ namespace bob { namespace learn { namespace linear {
m_activation->str() == b.m_activation->str());
}
void Machine::load (bob::io::base::HDF5File& config) {
//reads all data directly into the member variables
m_input_sub.reference(config.readArray<double,1>("input_sub"));
m_input_div.reference(config.readArray<double,1>("input_div"));
m_weight.reference(config.readArray<double,2>("weights"));
m_bias.reference(config.readArray<double,1>("biases"));
m_buffer.resize(m_input_sub.extent(0));
//switch between different versions - support for version 1
if (config.hasAttribute(".", "version")) { //new version
config.cd("activation");
m_activation = bob::learn::activation::load_activation(config);
config.cd("..");
}
else { //old version
uint32_t act = config.read<uint32_t>("activation");
m_activation = bob::learn::activation::make_deprecated_activation(act);
}
}
void Machine::resize (size_t input, size_t output) {
m_input_sub.resizeAndPreserve(input);
......@@ -138,19 +112,6 @@ namespace bob { namespace learn { namespace linear {
}
void Machine::save (bob::io::base::HDF5File& config) const {
config.setAttribute(".", "version", 1);
config.setArray("input_sub", m_input_sub);
config.setArray("input_div", m_input_div);
config.setArray("weights", m_weight);
config.setArray("biases", m_bias);
config.createGroup("activation");
config.cd("activation");
m_activation->save(config);
config.cd("..");
}
void Machine::forward_ (const blitz::Array<double,1>& input, blitz::Array<double,1>& output) const {
......
File deleted
File added
......@@ -59,10 +59,6 @@ namespace bob { namespace learn { namespace linear {
*/
Machine (const Machine& other);
/**
* Starts a new Machine from an existing Configuration object.
*/
Machine (bob::io::base::HDF5File& config);
/**
* Just to virtualise the destructor
......@@ -88,16 +84,6 @@ namespace bob { namespace learn { namespace linear {
bool is_similar_to(const Machine& b, const double r_epsilon=1e-5,
const double a_epsilon=1e-8) const;
/**
* Loads data from an existing configuration object. Resets the current
* state.
*/
void load (bob::io::base::HDF5File& config);
/**
* Saves an existing machine to a Configuration object.
*/
void save (bob::io::base::HDF5File& config) const;
/**
* Forwards data through the network, outputs the values of each linear
......
......@@ -47,7 +47,6 @@ static auto Machine_doc = bob::extension::ClassDoc(
.add_parameter("input_size", "int", "[Default: 0] The dimensionality of the input data that should be projected")
.add_parameter("output_size", "int", "[Default: 0] The dimensionality of the output data")
.add_parameter("weights", "array_like(2D, float)", "A weight matrix to initialize the :py:attr:`weights`")
.add_parameter("config", ":py:class:`bob.io.base.HDF5File`", "The HDF5 file open for reading")
.add_parameter("other", ":py:class:`bob.learn.linear.Machine`", "The machine to copy construct")
);
......@@ -90,22 +89,6 @@ BOB_TRY
BOB_CATCH_MEMBER("constructor", -1)
}
static int PyBobLearnLinearMachine_init_hdf5(PyBobLearnLinearMachineObject* self,
PyObject* args, PyObject* kwds) {
BOB_TRY
/* Parses input arguments in a single shot */
char** kwlist = Machine_doc.kwlist(2);
PyObject* config = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist,
&PyBobIoHDF5File_Type, &config)) return -1;
auto h5f = reinterpret_cast<PyBobIoHDF5FileObject*>(config);
self->cxx = new bob::learn::linear::Machine(*(h5f->f));
return 0;
BOB_CATCH_MEMBER("constructor", -1)
}
static int PyBobLearnLinearMachine_init_copy
(PyBobLearnLinearMachineObject* self, PyObject* args, PyObject* kwds) {
......@@ -145,10 +128,6 @@ static int PyBobLearnLinearMachine_init(PyBobLearnLinearMachineObject* self,
arg = PyList_GET_ITEM(tmp, 0);
}
if (PyBobIoHDF5File_Check(arg)) {
return PyBobLearnLinearMachine_init_hdf5(self, args, kwds);
}
if (PyBlitzArray_Check(arg) || PyArray_Check(arg)) {
return PyBobLearnLinearMachine_init_weights(self, args, kwds);
}
......@@ -679,48 +658,6 @@ BOB_TRY
BOB_CATCH_MEMBER("forward", 0)
}
static auto load = bob::extension::FunctionDoc(
"load",
"Loads the machine from the given HDF5 file",
0,
true
)
.add_prototype("hdf5")
.add_parameter("hdf5", ":py:class:`bob.io.base.HDF5File`", "An HDF5 file opened for reading")
;
static PyObject* PyBobLearnLinearMachine_Load(PyBobLearnLinearMachineObject* self, PyObject* args, PyObject* kwargs) {
BOB_TRY
char** kwlist = load.kwlist();
PyBobIoHDF5FileObject* file;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&", kwlist, PyBobIoHDF5File_Converter, &file)) return 0;
auto file_ = make_safe(file);
self->cxx->load(*file->f);
Py_RETURN_NONE;
BOB_CATCH_MEMBER("load", 0)
}
static auto save = bob::extension::FunctionDoc(
"save",
"Saves the machine to the given HDF5 file",
0,
true
)
.add_prototype("hdf5")
.add_parameter("hdf5", ":py:class:`bob.io.base.HDF5File`", "An HDF5 file open for writing")
;
static PyObject* PyBobLearnLinearMachine_Save(PyBobLearnLinearMachineObject* self, PyObject* args, PyObject* kwargs) {
BOB_TRY
char** kwlist = save.kwlist();
PyBobIoHDF5FileObject* file;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,"O&", kwlist, PyBobIoHDF5File_Converter, &file)) return 0;
auto file_ = make_safe(file);
self->cxx->save(*file->f);
Py_RETURN_NONE;
BOB_CATCH_MEMBER("save", 0)
}
static auto is_similar_to = bob::extension::FunctionDoc(
......@@ -795,18 +732,6 @@ static PyMethodDef PyBobLearnLinearMachine_methods[] = {
METH_VARARGS|METH_KEYWORDS,
forward.doc()
},
{
load.name(),
(PyCFunction)PyBobLearnLinearMachine_Load,
METH_VARARGS|METH_KEYWORDS,
load.doc()
},
{
save.name(),
(PyCFunction)PyBobLearnLinearMachine_Save,
METH_VARARGS|METH_KEYWORDS,
save.doc()
},
{
is_similar_to.name(),
(PyCFunction)PyBobLearnLinearMachine_IsSimilarTo,
......@@ -857,7 +782,7 @@ bool init_BobLearnLinearMachine(PyObject* module)
// Linear Machine
PyBobLearnLinearMachine_Type.tp_name = Machine_doc.name();
PyBobLearnLinearMachine_Type.tp_basicsize = sizeof(PyBobLearnLinearMachineObject);
PyBobLearnLinearMachine_Type.tp_flags = Py_TPFLAGS_DEFAULT;
PyBobLearnLinearMachine_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
PyBobLearnLinearMachine_Type.tp_doc = Machine_doc.doc();
// set the functions
......
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
from ._library import Machine as _Machine_C
import bob.learn.activation
class Machine(_Machine_C):
__doc__ = _Machine_C.__doc__
def to_dict(self):
"""
Dumps its content to a :py:class:`dict`
**Returns**
A :py:class:`dict` with :py:class:`bob.learn.linear.Machine` variables
"""
output_dict = dict()
output_dict["input_sub"] = self.input_subtract
output_dict["input_div"] = self.input_divide
output_dict["weights"] = self.weights
output_dict["activation"] = self.activation_py.to_dict()["id"]
output_dict["biases"] = self.biases
return output_dict
@classmethod
def from_dict(cls, input_dict):
"""
Loads itself from a python dict :py:class:`dict`
"""
machine = cls(input_dict["weights"])
machine.biases = input_dict["biases"]
machine.input_subtract = input_dict["input_sub"]
machine.input_divide = input_dict["input_div"]
activation = bob.learn.activation.Activation.from_dict(
{"id": input_dict["activation"]}
)
machine.activation = activation
# TODO: Temporarily solution to load activation
machine.activation_py = activation
return machine
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment