diff --git a/CHANGELIST.md b/CHANGELIST.md index 0940d3a75..47ff0df0c 100644 --- a/CHANGELIST.md +++ b/CHANGELIST.md @@ -19,6 +19,8 @@ v0.4.0 ### Unstable changes +- Added `matrix.op.repmat` function. +- Added `matrix.ext.iterate` iterator. - Added statistical distributions in `stats.dist`. - Added `matrix.ext.convolution` and `matrix.ext.real_fftwh`. - Added `Matrix::convolution` method. It is in experimental stage, please, @@ -28,6 +30,9 @@ v0.4.0 ### API Changes +- Removed major order differentiation in `matrix`. +- `tokens.matrix` **automatically** wraps `matrix` instances, from Lua to C++. +- `matrix` **automatically** unwraps `tokens.matrix` instances, from C++ to Lua. - Added new methods to `AprilMath::Limits` class. - Added `metrics.roc` for ROC computation. - Added new `class` behavior taken from @@ -62,6 +67,7 @@ v0.4.0 ### C/C++ +- Added `LuaTable` class to allow access of Lua tables from C++ code. - Added TAR support in C/C++, allowing to use streams as the standard I/O objects in APRIL-ANN. - Added `basics` namespace which stores almost all C/C++ code in `basics` diff --git a/EXAMPLES/xor.lua b/EXAMPLES/xor.lua index 57788280d..3cefe8dd1 100644 --- a/EXAMPLES/xor.lua +++ b/EXAMPLES/xor.lua @@ -11,9 +11,7 @@ trainer:randomize_weights{ sup = 0.1 } trainer:set_option("learning_rate", 8.0) -trainer:set_option("momentum", 0.5) -trainer:set_option("weight_decay", 1e-05) -trainer:set_layerwise_option("b.*", "weight_decay", 0.0) +trainer:set_option("momentum", 0.8) local m_xor = matrix.fromString[[ 4 3 diff --git a/packages/ann/ann/binding/bind_ann_base.lua.cc b/packages/ann/ann/binding/bind_ann_base.lua.cc index 660b0437a..8236e999b 100644 --- a/packages/ann/ann/binding/bind_ann_base.lua.cc +++ b/packages/ann/ann/binding/bind_ann_base.lua.cc @@ -20,54 +20,80 @@ * */ //BIND_HEADER_C +#include + #include "bind_function_interface.h" #include "bind_matrix.h" #include "bind_sparse_matrix.h" #include "bind_mtrand.h" #include "bind_tokens.h" +#include "bind_util.h" #include "table_of_token_codes.h" using namespace AprilUtils; using namespace Basics; namespace ANN { - static bool rewrapToAtLeastDim2(Token *&tk) { + static bool rewrapToAtLeastDim2(AprilUtils::SharedPtr &tk) { if (tk->getTokenCode() == table_of_token_codes::token_matrix) { Basics::TokenMatrixFloat *tk_mat = tk->convertTo(); Basics::MatrixFloat *m = tk_mat->getMatrix(); if (m->getNumDim() == 1) { int dims[2] = { 1, m->getDimSize(0) }; - Basics::Token *new_tk = new Basics::TokenMatrixFloat(m->rewrap(dims, 2)); - IncRef(new_tk); - DecRef(tk); - tk = new_tk; + tk.reset( new Basics::TokenMatrixFloat(m->rewrap(dims, 2)) ); return true; } } return false; } - static void unwrapToDim1(Token *&tk) { + static void unwrapToDim1(AprilUtils::SharedPtr &tk) { if (tk->getTokenCode() == table_of_token_codes::token_matrix) { Basics::TokenMatrixFloat *tk_mat = tk->convertTo(); Basics::MatrixFloat *m = tk_mat->getMatrix(); int dim = m->getDimSize(1); Basics::MatrixFloat *new_m = m->rewrap(&dim, 1); - Basics::Token *tk = new Basics::TokenMatrixFloat(new_m); + tk.reset( new Basics::TokenMatrixFloat(new_m) ); } } - template - void pushHashTableInLuaStack(lua_State *L, - AprilUtils::hash &hashobject, - PushFunction push_function) { - lua_createtable(L, 0, hashobject.size()); - for (typename AprilUtils::hash::iterator it = hashobject.begin(); - it != hashobject.end(); ++it) { - push_function(L, it->second); - lua_setfield(L, -2, it->first.c_str()); - } +} + +void lua_pushAuxANNComponent(lua_State *L, ANNComponent *value) { + if (typeid(*value) == typeid(StackANNComponent)) { + lua_pushStackANNComponent(L, (StackANNComponent*)value); + } + else if (typeid(*value) == typeid(JoinANNComponent)) { + lua_pushJoinANNComponent(L, (JoinANNComponent*)value); + } + else if (dynamic_cast(value)) { + lua_pushActivationFunctionANNComponent(L, (ActivationFunctionANNComponent*)value); + } + else if (dynamic_cast(value)) { + lua_pushStochasticANNComponent(L, (StochasticANNComponent*)value); + } + else { + lua_pushANNComponent(L, value); + } +} + +namespace AprilUtils { + + template<> ANN::ANNComponent *LuaTable:: + convertTo(lua_State *L, int idx) { + return lua_toANNComponent(L, idx); + } + + template<> void LuaTable:: + pushInto(lua_State *L, ANN::ANNComponent *value) { + lua_pushAuxANNComponent(L, value); } + + template<> bool LuaTable:: + checkType(lua_State *L, int idx) { + return lua_isANNComponent(L, idx); + } + } //BIND_END @@ -101,6 +127,7 @@ namespace ANN { #include "relu_actf_component.h" #include "hardtanh_actf_component.h" #include "sin_actf_component.h" +#include "log_actf_component.h" #include "linear_actf_component.h" #include "gaussian_noise_component.h" #include "salt_and_pepper_component.h" @@ -113,6 +140,8 @@ namespace ANN { using namespace Functions; using namespace ANN; +void lua_pushAuxANNComponent(lua_State *L, ANNComponent *value); + //BIND_END ///////////////////////////////////////////////////// @@ -138,10 +167,11 @@ using namespace ANN; input_size); // Basics::MatrixFloat *obj; - if (w && w->getMajorOrder() == CblasColMajor) obj = w->clone(); + if (w) { + obj = w->clone(); + } else { obj = Connections::build(input_size, output_size); - if (w) Connections::loadWeights(obj, w, first_pos, column_size); } LUABIND_RETURN(MatrixFloat, obj); } @@ -351,48 +381,48 @@ using namespace ANN; //BIND_METHOD ANNComponent get_input { - Basics::Token *aux = obj->getInput(); - if (aux == 0) { + AprilUtils::SharedPtr aux( obj->getInput() ); + if (aux.empty()) { LUABIND_RETURN(Token, new TokenNull()); } else { - LUABIND_RETURN(Token, aux); + LUABIND_RETURN(AuxToken, aux); } } //BIND_END //BIND_METHOD ANNComponent get_output { - Basics::Token *aux = obj->getOutput(); - if (aux == 0) { + AprilUtils::SharedPtr aux( obj->getOutput() ); + if (aux.empty()) { LUABIND_RETURN(Token, new TokenNull()); } else { - LUABIND_RETURN(Token, aux); + LUABIND_RETURN(AuxToken, aux); } } //BIND_END //BIND_METHOD ANNComponent get_error_input { - Basics::Token *aux = obj->getErrorInput(); + AprilUtils::SharedPtr aux( obj->getErrorInput() ); if (aux == 0) { LUABIND_RETURN(Token, new TokenNull()); } else { - LUABIND_RETURN(Token, aux); + LUABIND_RETURN(AuxToken, aux); } } //BIND_END //BIND_METHOD ANNComponent get_error_output { - Basics::Token *aux = obj->getErrorOutput(); + AprilUtils::SharedPtr aux( obj->getErrorOutput() ); if (aux == 0) { LUABIND_RETURN(Token, new TokenNull()); } else { - LUABIND_RETURN(Token, aux); + LUABIND_RETURN(AuxToken, aux); } } //BIND_END @@ -418,35 +448,32 @@ using namespace ANN; //BIND_METHOD ANNComponent forward { - Basics::Token *input; + AprilUtils::SharedPtr input; bool during_training; LUABIND_CHECK_ARGN(>=, 1); LUABIND_CHECK_ARGN(<=, 2); LUABIND_GET_PARAMETER(1, AuxToken, input); LUABIND_GET_OPTIONAL_PARAMETER(2, bool, during_training, false); - IncRef(input); bool rewrapped = rewrapToAtLeastDim2(input); - Basics::Token *output = obj->doForward(input, during_training); + AprilUtils::SharedPtr output( obj->doForward(input.get(), + during_training) ); if (rewrapped) unwrapToDim1(output); - LUABIND_RETURN(Token, output); - DecRef(input); + LUABIND_RETURN(AuxToken, output); } //BIND_END //BIND_METHOD ANNComponent backprop { - Basics::Token *input; + AprilUtils::SharedPtr input; LUABIND_CHECK_ARGN(==, 1); LUABIND_GET_PARAMETER(1, AuxToken, input); - IncRef(input); bool rewrapped = rewrapToAtLeastDim2(input); - Basics::Token *gradient = obj->doBackprop(input); - if (gradient != 0) { + AprilUtils::SharedPtr gradient( obj->doBackprop(input.get()) ); + if (!gradient.empty()) { if (rewrapped) unwrapToDim1(gradient); - LUABIND_RETURN(Token, gradient); + LUABIND_RETURN(AuxToken, gradient); } else LUABIND_RETURN_NIL(); - DecRef(input); } //BIND_END @@ -462,14 +489,13 @@ using namespace ANN; { LUABIND_CHECK_ARGN(<=, 1); int argn = lua_gettop(L); - Basics::MatrixFloatSet *weight_grads_dict; - if (argn == 1) - LUABIND_GET_PARAMETER(1, MatrixFloatSet, weight_grads_dict); - else - weight_grads_dict = new Basics::MatrixFloatSet(); + AprilUtils::LuaTable weight_grads_dict; + if (argn == 1) { + weight_grads_dict = AprilUtils::LuaTable(L,1); + } // obj->computeAllGradients(weight_grads_dict); - LUABIND_RETURN(MatrixFloatSet, weight_grads_dict); + LUABIND_RETURN(LuaTable, weight_grads_dict); } //BIND_END @@ -500,41 +526,38 @@ using namespace ANN; LUABIND_CHECK_ARGN(<=, 1); int argn = lua_gettop(L); unsigned int input_size=0, output_size=0; - Basics::MatrixFloatSet *weights_dict = 0; - AprilUtils::hash components_dict; + AprilUtils::LuaTable weights_dict(L), components_dict(L); if (argn == 1) { LUABIND_CHECK_PARAMETER(1, table); check_table_fields(L, 1, "input", "output", "weights", (const char *)0); LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, input, uint, input_size, 0); LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, output, uint, output_size, 0); - LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, weights, - MatrixFloatSet, weights_dict, 0); + lua_getfield(L, 1, "weights"); + if (!lua_isnil(L, -1)) weights_dict = lua_toLuaTable(L,-1); + lua_pop(L, 1); } - if (weights_dict == 0) weights_dict = new Basics::MatrixFloatSet(); // obj->build(input_size, output_size, weights_dict, components_dict); // - LUABIND_RETURN(ANNComponent, obj); - LUABIND_RETURN(MatrixFloatSet, weights_dict); - pushHashTableInLuaStack(L, components_dict, lua_pushANNComponent); - LUABIND_INCREASE_NUM_RETURNS(1); + LUABIND_RETURN(AuxANNComponent, obj); + LUABIND_RETURN(LuaTable, weights_dict); + LUABIND_RETURN(LuaTable, components_dict); } //BIND_END //BIND_METHOD ANNComponent copy_weights { - Basics::MatrixFloatSet *weights_dict = new Basics::MatrixFloatSet(); + AprilUtils::LuaTable weights_dict(L); obj->copyWeights(weights_dict); - LUABIND_RETURN(MatrixFloatSet, weights_dict); + LUABIND_RETURN(LuaTable, weights_dict); } //BIND_END //BIND_METHOD ANNComponent copy_components { - AprilUtils::hash components_dict; + AprilUtils::LuaTable components_dict(L); obj->copyComponents(components_dict); - pushHashTableInLuaStack(L, components_dict, lua_pushANNComponent); - LUABIND_RETURN_FROM_STACK(-1); + LUABIND_RETURN(LuaTable, components_dict); } //BIND_END @@ -546,7 +569,7 @@ using namespace ANN; LUABIND_GET_PARAMETER(1, string, name); string name_string(name); ANNComponent *component = obj->getComponent(name_string); - LUABIND_RETURN(ANNComponent, component); + LUABIND_RETURN(AuxANNComponent, component); } //BIND_END @@ -717,8 +740,9 @@ using namespace ANN; //BIND_METHOD StackANNComponent unroll { lua_checkstack(L, obj->size()); - for (unsigned int i=0; isize(); ++i) - LUABIND_RETURN(ANNComponent, obj->getComponentAt(i)); + for (unsigned int i=0; isize(); ++i) { + LUABIND_RETURN(AuxANNComponent, obj->getComponentAt(i)); + } } //BIND_END @@ -728,26 +752,24 @@ using namespace ANN; int argn = lua_gettop(L); lua_checkstack(L, argn); for (int i=1; i<=argn; ++i) { - unsigned int idx; - LUABIND_GET_PARAMETER(i, uint, idx); - --idx; - if (idx >= obj->size()) + unsigned int idx = lua_tointeger(L, i); + if (idx > obj->size()) LUABIND_FERROR2("Incorrect index, expected <= %d, found %d\n", - obj->size(), idx+1); - LUABIND_RETURN(ANNComponent, obj->getComponentAt(idx)); + obj->size(), idx); + LUABIND_RETURN(AuxANNComponent, obj->getComponentAt(idx - 1)); } } //BIND_END //BIND_METHOD StackANNComponent top { - LUABIND_RETURN(ANNComponent, obj->topComponent()); + if (obj->size() > 0) LUABIND_RETURN(AuxANNComponent, obj->topComponent()); } //BIND_END //BIND_METHOD StackANNComponent pop { - obj->popComponent(); + if (obj->size() > 0) obj->popComponent(); LUABIND_RETURN(StackANNComponent, obj); } //BIND_END @@ -1011,10 +1033,16 @@ using namespace ANN; int *kernel, *step, n, input_planes_dim; check_table_fields(L, 1, "name", "weights", "kernel", "input_planes_dim", "step", "n", (const char *)0); + LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, input_planes_dim, int, + input_planes_dim, -1); + if (input_planes_dim > 1) { + LUABIND_ERROR("Deprecated property, new version only allowed for input_planes_dim==1\n"); + } + else if (input_planes_dim == 1) { + ERROR_PRINT("Deprecated property, not needed in the new version"); + } LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, name, string, name, 0); LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, weights, string, weights, 0); - LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, input_planes_dim, int, - input_planes_dim, 1); LUABIND_GET_TABLE_PARAMETER(1, n, int, n); // lua_getfield(L, 1, "kernel"); @@ -1041,8 +1069,7 @@ using namespace ANN; LUABIND_TABLE_TO_VECTOR(-1, int, step, size); } lua_pop(L, 1); - obj = new ConvolutionANNComponent(size, kernel, step, - input_planes_dim, n, + obj = new ConvolutionANNComponent(size, kernel, step, n, name, weights); LUABIND_RETURN(ConvolutionANNComponent, obj); delete[] kernel; @@ -1548,6 +1575,29 @@ using namespace ANN; } //BIND_END +///////////////////////////////////////////////////// +// LogActfANNComponent // +///////////////////////////////////////////////////// + +//BIND_LUACLASSNAME LogActfANNComponent ann.components.actf.log +//BIND_CPP_CLASS LogActfANNComponent +//BIND_SUBCLASS_OF LogActfANNComponent ActivationFunctionANNComponent + +//BIND_CONSTRUCTOR LogActfANNComponent +{ + LUABIND_CHECK_ARGN(<=, 1); + int argn = lua_gettop(L); + const char *name=0; + if (argn == 1) { + LUABIND_CHECK_PARAMETER(1, table); + check_table_fields(L, 1, "name", (const char *)0); + LUABIND_GET_TABLE_OPTIONAL_PARAMETER(1, name, string, name, 0); + } + obj = new LogActfANNComponent(name); + LUABIND_RETURN(LogActfANNComponent, obj); +} +//BIND_END + ///////////////////////////////////////////////////// // LinearActfANNComponent // ///////////////////////////////////////////////////// diff --git a/packages/ann/ann/c_src/activation_function_component.cc b/packages/ann/ann/c_src/activation_function_component.cc index 5355ccbad..051ce462a 100644 --- a/packages/ann/ann/c_src/activation_function_component.cc +++ b/packages/ann/ann/c_src/activation_function_component.cc @@ -56,7 +56,6 @@ namespace ANN { // change current input by new input AssignRef(input,_input->convertTo()); MatrixFloat *input_mat = input->getMatrix(); - april_assert(input_mat->getMajorOrder() == CblasColMajor); april_assert(input_mat->getNumDim() >= 2); if (!input_mat->getIsContiguous()) { input_mat = input_mat->clone(); @@ -91,7 +90,6 @@ namespace ANN { // change current input by new input AssignRef(error_input,_error_input->convertTo()); MatrixFloat *error_input_mat = error_input->getMatrix(); - april_assert(error_input_mat->getMajorOrder() == CblasColMajor); april_assert(error_input_mat->getNumDim() >= 2); if (!error_input_mat->getIsContiguous()) { error_input_mat = error_input_mat->clone(); @@ -139,8 +137,8 @@ namespace ANN { void ActivationFunctionANNComponent::build(unsigned int _input_size, unsigned int _output_size, - MatrixFloatSet *weights_dict, - hash &components_dict) { + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict) { ANNComponent::build(_input_size, _output_size, weights_dict, components_dict); if (input_size == 0) input_size = output_size; if (output_size == 0) output_size = input_size; diff --git a/packages/ann/ann/c_src/activation_function_component.h b/packages/ann/ann/c_src/activation_function_component.h index 9f7697978..336445073 100644 --- a/packages/ann/ann/c_src/activation_function_component.h +++ b/packages/ann/ann/c_src/activation_function_component.h @@ -63,8 +63,8 @@ namespace ANN { virtual void build(unsigned int _input_size, unsigned int _output_size, - Basics::MatrixFloatSet *weights_dict, - AprilUtils::hash &components_dict); + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict); }; } diff --git a/packages/ann/ann/c_src/activation_function_kernels.cu b/packages/ann/ann/c_src/activation_function_kernels.cu index 89e0d3c1e..7e984234c 100644 --- a/packages/ann/ann/c_src/activation_function_kernels.cu +++ b/packages/ann/ann/c_src/activation_function_kernels.cu @@ -144,22 +144,16 @@ namespace ANN { } else { #endif - AprilMath::FloatGPUMirroredMemoryBlock *input_units = - input->getRawDataAccess(); - AprilMath::FloatGPUMirroredMemoryBlock *output_units = - output->getRawDataAccess(); - const float *input_units_ptr = input_units->getPPALForRead(); - float *output_units_ptr = output_units->getPPALForWrite(); - for (unsigned int b = 0; b < bunch_size; ++b) { - float minimum = input_units_ptr[0]; - float maximum = input_units_ptr[0]; - unsigned int cur_pos = bunch_size; + Basics::MatrixFloat::const_iterator input_it(input->iteratorAt(b,0)); + float minimum = *input_it; + float maximum = *input_it; + ++input_it; for (unsigned int i = 2; i < size; i += 2) { - float prev_unit = input_units_ptr[cur_pos]; - cur_pos += bunch_size; - float cur_unit = input_units_ptr[cur_pos]; - cur_pos += bunch_size; + float prev_unit = *input_it; + ++input_it; + float cur_unit = *input_it; + ++input_it; if (prev_unit < cur_unit) { if (prev_unit < minimum) minimum = prev_unit; if (cur_unit > maximum) maximum = cur_unit; @@ -169,25 +163,26 @@ namespace ANN { } } if ((size & 1) == 0) { // si es impar - unsigned int last_pos = (size - 1) * bunch_size; - if (input_units_ptr[last_pos] < minimum) - minimum = input_units_ptr[last_pos]; - if (input_units_ptr[last_pos] > maximum) - maximum = input_units_ptr[last_pos]; + if (*input_it < minimum) minimum = *input_it; + if (*input_it > maximum) maximum = *input_it; } if ((maximum - minimum) > 30.0f) minimum = maximum - 30.0f; double addition = 0; - cur_pos = 0; + input_it = input->iteratorAt(b,0); + Basics::MatrixFloat::iterator output_it(output->iteratorAt(b,0)); for (unsigned int i = 0; i < size; i++) { - double e = exp(input_units_ptr[cur_pos] - minimum); - output_units_ptr[cur_pos] = e; + double e = exp(*input_it - minimum); + *output_it = e; addition += e; - cur_pos += bunch_size; + ++input_it; + ++output_it; } float ratio = 1.0f/addition; - cblas_sscal(size, ratio, output_units_ptr, bunch_size); - output_units_ptr++; - input_units_ptr++; + output_it = output->iteratorAt(b,0); + for (unsigned int i = 0; i < size; i++) { + *output_it *= ratio; + ++output_it; + } } #ifdef USE_CUDA } @@ -229,50 +224,42 @@ namespace ANN { } else { #endif - AprilMath::FloatGPUMirroredMemoryBlock *input_units = - input->getRawDataAccess(); - AprilMath::FloatGPUMirroredMemoryBlock *output_units = - output->getRawDataAccess(); - const float *input_units_ptr = input_units->getPPALForRead(); - float *output_units_ptr = output_units->getPPALForWrite(); - for (unsigned int b = 0; b < bunch_size; ++b) { - float maximum = input_units_ptr[0]; - unsigned int cur_pos = bunch_size; + Basics::MatrixFloat::const_iterator input_it(input->iteratorAt(b,0)); + float maximum = *input_it; + ++input_it; for (unsigned int i = 2; i < size; i += 2) { - float prev_unit = input_units_ptr[cur_pos]; - cur_pos += bunch_size; - float cur_unit = input_units_ptr[cur_pos]; + float prev_unit = *input_it; + ++input_it; + float cur_unit = *input_it; + ++input_it; if (prev_unit < cur_unit) { if (cur_unit > maximum) maximum = cur_unit; } else { if (prev_unit > maximum) maximum = prev_unit; } - cur_pos += bunch_size; } if ((size & 1) == 0) { // si es par - unsigned int last_pos = (size - 1) * bunch_size; - if (input_units_ptr[last_pos] > maximum) - maximum = input_units_ptr[last_pos]; + if (*input_it > maximum) maximum = *input_it; } + input_it = input->iteratorAt(b,0); + Basics::MatrixFloat::iterator output_it(output->iteratorAt(b,0)); double addition = 0.0f; - cur_pos = 0; for (unsigned int i = 0; i < size; i++) { - output_units_ptr[cur_pos] = input_units_ptr[cur_pos] - maximum; - double exp_output = AprilMath::m_exp(static_cast(output_units_ptr[cur_pos])); + *output_it = *input_it - maximum; + double exp_output = AprilMath::m_exp(static_cast(*output_it)); addition += exp_output; - cur_pos += bunch_size; + ++input_it; + ++output_it; } + output_it = output->iteratorAt(b,0); float ratio = static_cast(log(addition)); - cur_pos = 0; for (unsigned int i = 0; i < size; i++) { - output_units_ptr[cur_pos] -= ratio; - april_assert(!(output_units_ptr[cur_pos] > 0.0f) && + *output_it -= ratio; + april_assert(!(*output_it > 0.0f) && "Numerical inestability at log-softmax activation function"); - cur_pos += bunch_size; + ++output_it; } - output_units_ptr++; - input_units_ptr++; } #ifdef USE_CUDA } diff --git a/packages/ann/ann/c_src/ann_component.h b/packages/ann/ann/c_src/ann_component.h index 4201e9d09..80d8a816f 100644 --- a/packages/ann/ann/c_src/ann_component.h +++ b/packages/ann/ann/c_src/ann_component.h @@ -22,31 +22,18 @@ #define ANNCOMPONENT_H #include -#include "aux_hash_table.h" // required for build #include "connection.h" #include "disallow_class_methods.h" #include "error_print.h" #include "function_interface.h" -#include "hash_table.h" // required for build #include "mystring.h" +#include "lua_table.h" #include "token_base.h" #include "matrixFloat.h" -#include "matrixFloatSet.h" #include "unused_variable.h" #include "vector.h" -using AprilUtils::hash; // required for build -using AprilUtils::string; -using AprilUtils::vector; - -#ifndef NDEBUG -#define ASSERT_MATRIX(m) do { \ - april_assert( (m)->getMajorOrder() == CblasColMajor ); \ - } while(0) -// april_assert( (m)->getNumDim() == 2 ); -#else #define ASSERT_MATRIX(m) -#endif /** * @brief Maximum size of automatically generated names. @@ -56,10 +43,30 @@ using AprilUtils::vector; */ #define MAX_NAME_STR 256 +namespace ANN { + // forward declaration + class ANNComponent; +} + +namespace AprilUtils { + + template<> ANN::ANNComponent *LuaTable:: + convertTo(lua_State *L, int idx); + + template<> void LuaTable:: + pushInto(lua_State *L, ANN::ANNComponent *value); + + template<> bool LuaTable:: + checkType(lua_State *L, int idx); +} + + /** * @brief All ANN components and other stuff is implemented here. */ namespace ANN { + + unsigned int mult(const int *v, int n); @@ -284,22 +291,20 @@ namespace ANN { /** * @brief Computation of gradient of all ANNComponent's is done here. * - * @param[in,out] weight_grads_dict - A Basics::MatrixFloatSet reference where + * @param[in,out] weight_grads_dict - A AprilUtils::LuaTable reference where * gradient matrices will be stored. * * This method traverses all the ANNComponent's using the given - * Basics::MatrixFloatSet. If hasWeightsName() is true, the method - * computeGradients() will be executed with the shared Basics::MatrixFloat - * reference (i.e. AprilUtils::SharedPtr) related to the @c weights_name - * property. + * AprilUtils::LuaTable. If hasWeightsName() is true, the method + * computeGradients() will be executed. * * @note The @c weight_grads_dict[weights_name] can be an empty reference, * in this case, the called method has the responsability of its proper * initialization. */ - virtual void computeAllGradients(Basics::MatrixFloatSet *weight_grads_dict){ - if (!weights_name.empty()) { - computeGradients( (*weight_grads_dict)[weights_name].getDense() ); + virtual void computeAllGradients(AprilUtils::LuaTable &weight_grads_dict){ + if (hasWeightsName()) { + computeGradients( weights_name.c_str(), weight_grads_dict ); } } @@ -354,35 +359,37 @@ namespace ANN { * @param _output_size - The output size given to the method. It can be @c * _input_size=0 to indicate that it is unknown or don't care. * - * @param[in,out] weights_dict - A pointer to Basics::MatrixFloatSet where + * @param[in,out] weights_dict - A reference to AprilUtils::LuaTable where * weight matrices are stored. * - * @param[out] components_dict - A dictionary of ANNComponent's which are - * part of the ANN. + * @param[out] components_dict - A AprilUtils::LuaTable of ANNComponent's which + * are part of the ANN. * * @note Derived classes must re-implement this method throwing errors if * necessary when input/output sizes have unexpected values, and calling to * the parent method before doing anything. * - * @note The @c weights_dict param contains weight Basics::MatrixFloat - * references (i.e. AprilUtils::SharedPtr) indexed by @c weights_name - * property. The reference can be empty and the derived class is responsible - * to initialize it properly. If it is not empty, the derived class is - * responsible to check its size correctness. + * @note The @c weights_dict param can contain any Lua or APRIL-ANN type + * indexed by @c weights_name property. It can be empty and the derived + * class is responsible to initialize it properly. If it is not empty, the + * derived class is responsible to check its size and type correctness. */ virtual void build(unsigned int _input_size, unsigned int _output_size, - Basics::MatrixFloatSet *weights_dict, - AprilUtils::hash &components_dict) { + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict) { UNUSED_VARIABLE(weights_dict); // if (is_built) ERROR_EXIT(128, "Rebuild is forbidden!!!!\n"); is_built = true; //////////////////////////////////////////////////////////////////// - ANNComponent *&component = components_dict[name]; - if (component != 0 && - component != this) ERROR_EXIT1(102, "Non unique component name found: %s\n", - name.c_str()); - else component = this; + ANNComponent *component = components_dict.opt(name.c_str(), 0); + if (component != 0 && component != this) { + ERROR_EXIT1(102, "Non unique component name found: %s\n", name.c_str()); + } + else { + component = this; + components_dict.put(name.c_str(), component); + } //////////////////////////////////////////////////////////////////// if (input_size == 0) input_size = _input_size; if (output_size == 0) output_size = _output_size; @@ -399,7 +406,7 @@ namespace ANN { } /// Retrieve matrix weights from ANNComponent's. - virtual void copyWeights(Basics::MatrixFloatSet *weights_dict) { + virtual void copyWeights(AprilUtils::LuaTable &weights_dict) { UNUSED_VARIABLE(weights_dict); } @@ -409,8 +416,8 @@ namespace ANN { * @note All derived classes which rewrite this method must call parent * method before doing anything. */ - virtual void copyComponents(AprilUtils::hash &components_dict) { - components_dict[name] = this; + virtual void copyComponents(AprilUtils::LuaTable &components_dict) { + components_dict.put(name.c_str(), this); } /// For debug purposes. @@ -502,8 +509,9 @@ namespace ANN { * This method is rewritten only by ANNComponent's which contain trainable * weight matrices, and therefore it is needed to compute its gradients. * - * @param weight_grads - A shared reference (i.e. AprilUtils::SharedPtr) to - * a Basics::MatrixFloat pointer. + * @param weights_name - A string with the corresponding weights name. + * + * @param weight_grads - A dictionary where to store the gradients. * * @note The default implementation in ANNComponent does nothing. * @@ -511,7 +519,9 @@ namespace ANN { * class is responsible to initialize it properly, or to check the * correctness of sizes and dimensions. */ - virtual void computeGradients(AprilUtils::SharedPtr &weight_grads) { + virtual void computeGradients(const char *weights_name, + AprilUtils::LuaTable &weight_grads) { + UNUSED_VARIABLE(weights_name); UNUSED_VARIABLE(weight_grads); } diff --git a/packages/ann/ann/c_src/bias_component.cc b/packages/ann/ann/c_src/bias_component.cc index cb33d996e..167e40c32 100644 --- a/packages/ann/ann/c_src/bias_component.cc +++ b/packages/ann/ann/c_src/bias_component.cc @@ -83,15 +83,19 @@ namespace ANN { bias_vector->resetSharedCount(); } - void BiasANNComponent::computeGradients(AprilUtils::SharedPtr & grads_mat) { + void BiasANNComponent::computeGradients(const char *name, + AprilUtils::LuaTable &weight_grads_dict) { // count one use of the vector bias_vector->addToSharedCount(); - if (grads_mat.empty()) { + MatrixFloat *grads_mat = weight_grads_dict.opt(name, 0); + if (grads_mat == 0) { grads_mat = bias_vector->cloneOnlyDims(); - matZeros(grads_mat.get()); + matZeros(grads_mat); + weight_grads_dict.put(name, grads_mat); } - else if (!grads_mat->sameDim(bias_vector)) + else if (!grads_mat->sameDim(bias_vector)) { ERROR_EXIT(128, "Incorrect weights matrix dimensions\n"); + } #ifdef USE_CUDA grads_mat->setUseCuda(use_cuda); #endif @@ -99,7 +103,7 @@ namespace ANN { unsigned int bunch_size = error_input_mat->getDimSize(0); // bias update: prev_bias[j] = prev_bias[j] + \sum_b norm_learn_rate * ERROR_INPUT[b,j] if (bunch_size == 1) { - matAxpy(grads_mat.get(), 1.0f, error_input_mat); + matAxpy(grads_mat, 1.0f, error_input_mat); } else { doAxpyLoop(output_size, @@ -125,8 +129,8 @@ namespace ANN { void BiasANNComponent::build(unsigned int _input_size, unsigned int _output_size, - MatrixFloatSet *weights_dict, - hash &components_dict) { + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict) { ANNComponent::build(_input_size, _output_size, weights_dict, components_dict); // @@ -140,10 +144,10 @@ namespace ANN { unsigned int weights_input_size = 1; unsigned int weights_output_size = output_size; //////////////////////////////////////////////////////////////////// - AprilUtils::SharedPtr &w = (*weights_dict)[weights_name].getDense(); + MatrixFloat *w = weights_dict.opt(weights_name, 0); // printf("%s :: %p %p\n", weights_name.c_str(), w, bias_vector); - if (!w.empty()) { - AssignRef(bias_vector, w.get()); + if (w != 0) { + AssignRef(bias_vector, w); // printf("COPY OF BIAS FROM HASH %s\n", weights_name.c_str()); if (!Connections::checkInputOutputSizes(bias_vector, weights_input_size, @@ -161,22 +165,22 @@ namespace ANN { IncRef(bias_vector); } // else printf("USING PREVIOUS BIAS %s\n", weights_name.c_str()); - w = bias_vector; + weights_dict.put(weights_name, bias_vector); } } - void BiasANNComponent::copyWeights(MatrixFloatSet *weights_dict) { + void BiasANNComponent::copyWeights(AprilUtils::LuaTable &weights_dict) { if (bias_vector == 0) ERROR_EXIT1(100, "Component not built, impossible execute copyWeights [%s]\n", name.c_str()); - AprilUtils::SharedPtr &w = (*weights_dict)[weights_name].getDense(); - if (!w.empty() && w.get() != bias_vector) + MatrixFloat *w = weights_dict.opt(weights_name, 0); + if (w != 0 && w != bias_vector) ERROR_EXIT2(101, "Weights dictionary contains %s weights name which is " "not shared with bias_vector attribute [%s]\n", weights_name.c_str(), name.c_str()); - else if (w.empty()) { - w = bias_vector; + else if (w == 0) { + weights_dict.put(weights_name, bias_vector); } } diff --git a/packages/ann/ann/c_src/bias_component.h b/packages/ann/ann/c_src/bias_component.h index 9b7f1695c..10e8b7f5a 100644 --- a/packages/ann/ann/c_src/bias_component.h +++ b/packages/ann/ann/c_src/bias_component.h @@ -40,7 +40,7 @@ namespace ANN { bool during_training); virtual Basics::MatrixFloat *privateDoBackprop(Basics::MatrixFloat *input_error); virtual void privateReset(unsigned int it=0); - virtual void computeGradients(AprilUtils::SharedPtr & grad_mat); + virtual void computeGradients(const char *name, AprilUtils::LuaTable &weight_grads_dict); public: BiasANNComponent(unsigned int size=0, @@ -49,9 +49,9 @@ namespace ANN { virtual ANNComponent *clone(); virtual void build(unsigned int input_size, unsigned int output_size, - Basics::MatrixFloatSet *weights_dict, - AprilUtils::hash &components_dict); - virtual void copyWeights(Basics::MatrixFloatSet *weights_dict); + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict); + virtual void copyWeights(AprilUtils::LuaTable &weights_dict); virtual char *toLuaString(); }; diff --git a/packages/ann/ann/c_src/connection.cc b/packages/ann/ann/c_src/connection.cc index b5b7bfe37..0a3945477 100644 --- a/packages/ann/ann/c_src/connection.cc +++ b/packages/ann/ann/c_src/connection.cc @@ -52,7 +52,7 @@ namespace ANN { unsigned int num_outputs) { int dims[2] = { static_cast(num_outputs), static_cast(num_inputs) }; - MatrixFloat *weights = new MatrixFloat(2, dims, CblasColMajor); + MatrixFloat *weights = new MatrixFloat(2, dims); if (weights == 0) ERROR_EXIT(130, "Impossible to allocate memory\n"); return weights; @@ -123,9 +123,9 @@ namespace ANN { if (min_size > static_cast(data->size())) ERROR_EXIT2(24, "Incorrect matrix size, was %d, expected >= %d\n", data->size(), min_size); - if (!data->isSimple()) - ERROR_EXIT(128, "Matrices need to be simple (contiguous " - "and in row-major)\n"); + if (!data->getIsContiguous()) { + ERROR_EXIT(128, "Matrices need to be contiguous\n"); + } unsigned int current_w_pos = first_weight_pos; MatrixFloat::iterator w_it(weights->begin()); for (unsigned int j=0; j static_cast(data->size())) ERROR_EXIT2(24, "Incorrect matrix size, was %d, expected >= %d\n", data->size(), min_size); - if (!data->isSimple()) - ERROR_EXIT(128, "Matrices need to be simple (contiguous " - "and in row-major)\n"); + if (!data->getIsContiguous()) + ERROR_EXIT(128, "Matrices need to contiguous\n"); unsigned int current_w_pos = first_weight_pos; MatrixFloat::const_iterator w_it(weights->begin()); for (unsigned int j=0; j stream(new CStringStream()); stream->put("matrix.fromString[["); - AprilUtils::HashTableOptions options; - weights->write( stream.get(), options.putBoolean("ascii", false) ); + AprilUtils::LuaTable options; + weights->write( stream.get(), options.put("ascii", false) ); stream->put("]]\0", 3); // forces a \0 at the end of the buffer return stream->releaseString(); } diff --git a/packages/ann/ann/c_src/const_component.cc b/packages/ann/ann/c_src/const_component.cc index cd851f53b..4e330b932 100644 --- a/packages/ann/ann/c_src/const_component.cc +++ b/packages/ann/ann/c_src/const_component.cc @@ -29,12 +29,11 @@ namespace ANN { ANNComponent(name, 0, component->getInputSize(), component->getOutputSize()), - component(component), - component_weights(new Basics::MatrixFloatSet()) { + component(component) { if (!component->getIsBuilt()) { ERROR_EXIT(128, "Needs a built component!\n"); } - component->copyWeights(component_weights.get()); + component->copyWeights(component_weights); } ConstANNComponent::~ConstANNComponent() { } @@ -57,8 +56,8 @@ namespace ANN { void ConstANNComponent::build(unsigned int _input_size, unsigned int _output_size, - Basics::MatrixFloatSet *weights_dict, - AprilUtils::hash &components_dict) { + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict) { ANNComponent::build(_input_size, _output_size, weights_dict, components_dict); } @@ -66,11 +65,11 @@ namespace ANN { AprilUtils::SharedPtr stream(new AprilIO::CStringStream()); char *component_str = component->toLuaString(); - char *component_weights_str = component_weights->toLuaString(); + AprilUtils::string component_weights_str( component_weights.toLuaString() ); stream->printf("ann.components.const{ name='%s', component=%s:build{ weights=%s } }", name.c_str(), component_str, - component_weights_str); + component_weights_str.c_str()); stream->put("\0",1); // forces a \0 at the end of the buffer delete[] component_str; delete[] component_weights_str; diff --git a/packages/ann/ann/c_src/const_component.h b/packages/ann/ann/c_src/const_component.h index d3f73933f..05be3961c 100644 --- a/packages/ann/ann/c_src/const_component.h +++ b/packages/ann/ann/c_src/const_component.h @@ -32,7 +32,7 @@ namespace ANN { protected: AprilUtils::SharedPtr component; - AprilUtils::SharedPtr component_weights; + AprilUtils::LuaTable component_weights; public: ConstANNComponent(ANNComponent *component, const char *name); @@ -53,8 +53,8 @@ namespace ANN { virtual void build(unsigned int _input_size, unsigned int _output_size, - Basics::MatrixFloatSet *weights_dict, - AprilUtils::hash &components_dict); + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict); virtual char *toLuaString(); }; diff --git a/packages/ann/ann/c_src/convolution_bias_component.cc b/packages/ann/ann/c_src/convolution_bias_component.cc index 2d4f07aaf..8add1a708 100644 --- a/packages/ann/ann/c_src/convolution_bias_component.cc +++ b/packages/ann/ann/c_src/convolution_bias_component.cc @@ -54,8 +54,7 @@ namespace ANN { MatrixFloat *bias_vec = bias_vector->select(1,0); IncRef(bias_vec); // the output bias as a 2d matrix of BUNCHxN - MatrixFloat *bias_matrix_2d = new MatrixFloat(2, window_size, - CblasColMajor); + MatrixFloat *bias_matrix_2d = new MatrixFloat(2, window_size); IncRef(bias_matrix_2d); // first pattern is done out of the loop MatrixFloat *dest = bias_matrix_2d->select(0, 0); @@ -176,12 +175,15 @@ namespace ANN { return error_mat; } - void ConvolutionBiasANNComponent::computeGradients(AprilUtils::SharedPtr &grads_mat) { + void ConvolutionBiasANNComponent::computeGradients(const char *name, + AprilUtils::LuaTable &grads_mat_dict) { // reset shared counter bias_vector->addToSharedCount(number_input_windows); - if (grads_mat.empty()) { + MatrixFloat *grads_mat = grads_mat_dict.opt(name, 0); + if (grads_mat == 0) { grads_mat = bias_vector->cloneOnlyDims(); - matZeros(grads_mat.get()); + matZeros(grads_mat); + grads_mat_dict.put(name, grads_mat); } #ifdef USE_CUDA grads_mat->setUseCuda(use_cuda); @@ -234,14 +236,14 @@ namespace ANN { void ConvolutionBiasANNComponent::build(unsigned int _input_size, unsigned int _output_size, - MatrixFloatSet *weights_dict, - hash &components_dict) { + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict) { ANNComponent::build(_input_size, _output_size, weights_dict, components_dict); //////////////////////////////////////////////////////////////////// - AprilUtils::SharedPtr &b = (*weights_dict)[weights_name].getDense(); - if (!b.empty()) { - AssignRef(bias_vector, b.get()); + MatrixFloat *b = weights_dict.opt(weights_name, 0); + if (b != 0) { + AssignRef(bias_vector, b); if (!Connections::checkInputOutputSizes(bias_vector,1,hidden_size)) ERROR_EXIT2(256,"The bias vector input/output sizes are not correct, " "expected 1x%d [%s]\n", hidden_size, name.c_str()); @@ -251,22 +253,22 @@ namespace ANN { bias_vector = Connections::build(1, hidden_size); IncRef(bias_vector); } - b = bias_vector; + weights_dict.put(weights_name, bias_vector); } } - void ConvolutionBiasANNComponent::copyWeights(MatrixFloatSet *weights_dict) { + void ConvolutionBiasANNComponent::copyWeights(AprilUtils::LuaTable &weights_dict) { if (bias_vector == 0) ERROR_EXIT1(100, "Component not built, impossible execute copyWeights [%s]\n", name.c_str()); - AprilUtils::SharedPtr &b = (*weights_dict)[weights_name].getDense(); - if (!b.empty() && b.get() != bias_vector) + MatrixFloat *b = weights_dict.opt(weights_name, 0); + if (b != 0 && b != bias_vector) ERROR_EXIT2(101, "Weights dictionary contains %s bias name which is " "not shared with bias_vector attribute [%s]\n", weights_name.c_str(), name.c_str()); - else if (b.empty()) { - b = bias_vector; + else if (b == 0) { + weights_dict.put(weights_name, bias_vector); } } diff --git a/packages/ann/ann/c_src/convolution_bias_component.h b/packages/ann/ann/c_src/convolution_bias_component.h index 93d8ca520..2a94a5342 100644 --- a/packages/ann/ann/c_src/convolution_bias_component.h +++ b/packages/ann/ann/c_src/convolution_bias_component.h @@ -52,7 +52,7 @@ namespace ANN { protected: - virtual void computeGradients(AprilUtils::SharedPtr & grad_mat); + virtual void computeGradients(const char *name, AprilUtils::LuaTable &weight_grads_dict); virtual Basics::MatrixFloat *privateDoForward(Basics::MatrixFloat *input, bool during_training); virtual Basics::MatrixFloat *privateDoBackprop(Basics::MatrixFloat *input_error); @@ -71,9 +71,9 @@ namespace ANN { virtual ANNComponent *clone(); virtual void build(unsigned int input_size, unsigned int output_size, - Basics::MatrixFloatSet *weights_dict, - AprilUtils::hash &components_dict); - virtual void copyWeights(Basics::MatrixFloatSet *weights_dict); + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict); + virtual void copyWeights(AprilUtils::LuaTable &weights_dict); virtual char *toLuaString(); }; diff --git a/packages/ann/ann/c_src/convolution_component.cc b/packages/ann/ann/c_src/convolution_component.cc index 20b6b5f49..bf97d0895 100644 --- a/packages/ann/ann/c_src/convolution_component.cc +++ b/packages/ann/ann/c_src/convolution_component.cc @@ -30,17 +30,12 @@ using namespace Basics; namespace ANN { - /////////////////////////////////////////// + //////////////////////////////////////////// // ConvolutionANNComponent implementation // - /////////////////////////////////////////// + //////////////////////////////////////////// void ConvolutionANNComponent::initializeArrays(const int *input_dims) { - for (int i=1; i(hidden_size); kernel_step[0] = 1; - input_window_order_step[0] = 0; output_window_size[0] = 0; output_window_size[1] = static_cast(hidden_size); - output_window_order_step[0] = 0; output_window_step[0] = 1; output_window_step[1] = 1; for(int i=0; igetDimPtr(); initializeArrays(input_dims); MatrixFloat *output_mat; - output_mat = new MatrixFloat(input_num_dims+1, output_dims, CblasColMajor); + output_mat = new MatrixFloat(input_num_dims+1, output_dims); IncRef(output_mat); #ifdef USE_CUDA output_mat->setUseCuda(use_cuda); @@ -173,14 +155,12 @@ namespace ANN { new MatrixFloat::sliding_window(input_mat, input_window_size, 0, // OFFSET kernel_step, - input_window_num_steps, - input_window_order_step); + input_window_num_steps); MatrixFloat::sliding_window *output_sw = new MatrixFloat::sliding_window(output_mat, output_window_size, 0, // OFFSET output_window_step, - output_window_num_steps, - output_window_order_step); + output_window_num_steps); number_input_windows = input_sw->numWindows(); // CONVOLUTION OVER number_input_windows MatrixFloat *input_w = input_sw->getMatrix(); @@ -253,14 +233,12 @@ namespace ANN { new MatrixFloat::sliding_window(error_output_mat, input_window_size, 0, // OFFSET kernel_step, - input_window_num_steps, - input_window_order_step); + input_window_num_steps); MatrixFloat::sliding_window *error_input_sw = new MatrixFloat::sliding_window(error_input_mat, output_window_size, 0, // OFFSET output_window_step, - output_window_num_steps, - output_window_order_step); + output_window_num_steps); april_assert(error_input_sw->numWindows() == number_input_windows); // CONVOLUTION GRADIENT MatrixFloat *error_input_w = error_input_sw->getMatrix(); @@ -316,11 +294,14 @@ namespace ANN { return error_output_mat; } - void ConvolutionANNComponent::computeGradients(AprilUtils::SharedPtr &grads_mat) { + void ConvolutionANNComponent::computeGradients(const char *name, + AprilUtils::LuaTable &grads_mat_dict) { weights_matrix->addToSharedCount(number_input_windows); - if (grads_mat.empty()) { + MatrixFloat *grads_mat = grads_mat_dict.opt(name, 0); + if (grads_mat == 0) { grads_mat = weights_matrix->cloneOnlyDims(); - matZeros(grads_mat.get()); + matZeros(grads_mat); + grads_mat_dict.put(name, grads_mat); } #ifdef USE_CUDA grads_mat->setUseCuda(use_cuda); @@ -331,13 +312,11 @@ namespace ANN { MatrixFloat::sliding_window input_sw(input_mat, input_window_size, 0, // OFFSET kernel_step, - input_window_num_steps, - input_window_order_step); + input_window_num_steps); MatrixFloat::sliding_window error_input_sw(error_input_mat, output_window_size, 0, // OFFSET output_window_step, - output_window_num_steps, - output_window_order_step); + output_window_num_steps); MatrixFloat *input_w = input_sw.getMatrix(); MatrixFloat *error_input_w = error_input_sw.getMatrix(); IncRef(input_w); @@ -355,7 +334,7 @@ namespace ANN { IncRef(error_input_flattened); // WEIGHTS UPDATE - matGemm(grads_mat.get(), + matGemm(grads_mat, CblasTrans, CblasNoTrans, 1.0f, error_input_flattened, // A @@ -382,8 +361,7 @@ namespace ANN { ANNComponent *ConvolutionANNComponent::clone() { ConvolutionANNComponent *component = new ConvolutionANNComponent(input_num_dims, kernel_dims+1, kernel_step+1, - input_planes_dim, hidden_size, - name.c_str(), weights_name.c_str()); + hidden_size, name.c_str(), weights_name.c_str()); component->input_size = input_size; component->output_size = output_size; return component; @@ -391,19 +369,19 @@ namespace ANN { void ConvolutionANNComponent::build(unsigned int _input_size, unsigned int _output_size, - MatrixFloatSet *weights_dict, - hash &components_dict) { + AprilUtils::LuaTable &weights_dict, + AprilUtils::LuaTable &components_dict) { ANNComponent::build(_input_size, _output_size, weights_dict, components_dict); // unsigned int weights_input_size = kernel_size; unsigned int weights_output_size = hidden_size; //////////////////////////////////////////////////////////////////// - AprilUtils::SharedPtr &w = (*weights_dict)[weights_name].getDense(); + MatrixFloat *w = weights_dict.opt(weights_name.c_str(), 0); // printf("%s :: %p %p\n", weights_name.c_str(), w, weights_matrix); - if (!w.empty()) { + if (w != 0) { // printf("COPY OF WEIGHTS FROM HASH %s\n", weights_name.c_str()); - AssignRef(weights_matrix, w.get()); + AssignRef(weights_matrix, w); if (!Connections::checkInputOutputSizes(weights_matrix, weights_input_size, weights_output_size)) @@ -420,30 +398,30 @@ namespace ANN { IncRef(weights_matrix); } // else printf("USING PREVIOUS WEIGHTS %s\n", weights_name.c_str()); - w = weights_matrix; + weights_dict.put(weights_name.c_str(), weights_matrix); } } - void ConvolutionANNComponent::copyWeights(MatrixFloatSet *weights_dict) { + void ConvolutionANNComponent::copyWeights(AprilUtils::LuaTable &weights_dict) { if (weights_matrix == 0) ERROR_EXIT1(100, "Component not built, impossible execute copyWeights [%s]\n", name.c_str()); - AprilUtils::SharedPtr &w = (*weights_dict)[weights_name].getDense(); - if (!w.empty() && w.get() != weights_matrix) + MatrixFloat *w = weights_dict.opt(weights_name.c_str(), 0); + if (w != 0 && w != weights_matrix) ERROR_EXIT2(101, "Weights dictionary contains %s weights name which is " "not shared with weights_matrix attribute [%s]\n", weights_name.c_str(), name.c_str()); - else if (w.empty()) { - w = weights_matrix; + else if (w == 0) { + weights_dict.put(weights_name.c_str(), weights_matrix); } } char *ConvolutionANNComponent::toLuaString() { buffer_list buffer; buffer.printf("ann.components.convolution{ name='%s',weights='%s'," - "n=%d, input_planes_dim=%d, kernel={", name.c_str(), weights_name.c_str(), - hidden_size, input_planes_dim); + "n=%d, kernel={", name.c_str(), weights_name.c_str(), + hidden_size); for (int i=0; i