From 1dd8426097c5213c32d9a40332651bf7ee75db8c Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 16 Sep 2019 13:23:52 -0400 Subject: [PATCH 1/3] added support for Boost serialization This will make to serialize libsvm model via Boost serialization. This functionality makes libsvm portable. Thus one can make the libsvm model part of their structure/class or send it over a network for example. --- svm-boost-serialization.hpp | 246 ++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 svm-boost-serialization.hpp diff --git a/svm-boost-serialization.hpp b/svm-boost-serialization.hpp new file mode 100644 index 00000000..c45042a2 --- /dev/null +++ b/svm-boost-serialization.hpp @@ -0,0 +1,246 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: serialization.hpp + * Author: arash + * + * Created on September 13, 2019, 6:34 p.m. + */ + +#ifndef LIBSVM_BOOST_SERIALIZATION_HPP +#define LIBSVM_BOOST_SERIALIZATION_HPP + +#include "svm.h" +#include +#include +#include + + +namespace boost { +namespace serialization { +namespace detail{ + template + T* Malloc(size_t n){ + return (T*)malloc((n)*sizeof(T)); + } + + template + std::vector save_1d_array(const T* array_1d, size_t n){ + std::vector vec_1d(n); + for(size_t i=0;i + void load_1d_array(const std::vector &vec_1d, T* &array_1d){ + array_1d = Malloc(vec_1d.size()); + for(size_t i=0;i + void load_2d_array(const std::vector > &vec_2d, T** &array_2d){ + array_2d = detail::Malloc(vec_2d.size()); + + for(size_t i=0;i +void serialize(Archive & ar, svm_node &n, const unsigned int version){ + ar & BOOST_SERIALIZATION_NVP(n.index); + ar & BOOST_SERIALIZATION_NVP(n.value); +} + +template +void serialize(Archive & ar, svm_parameter &p, const unsigned int version){ + ar & BOOST_SERIALIZATION_NVP(p.svm_type); + ar & BOOST_SERIALIZATION_NVP(p.kernel_type); + ar & BOOST_SERIALIZATION_NVP(p.degree); + ar & BOOST_SERIALIZATION_NVP(p.gamma); + ar & BOOST_SERIALIZATION_NVP(p.coef0); +} + +template +void save(Archive & ar, const svm_model &m, const unsigned int version){ + ar & BOOST_SERIALIZATION_NVP(m.param); + ar & BOOST_SERIALIZATION_NVP(m.nr_class); + ar & BOOST_SERIALIZATION_NVP(m.l); + + //SV + { + const svm_node * const *SV = m.SV; + std::vector > vec_SV(m.l); + + for(int i=0;iindex == -1) break; + p++; + } + } + } + + ar & BOOST_SERIALIZATION_NVP(vec_SV); + } + + //sv_coef + { + const double * const *sv_coef = m.sv_coef; + std::vector > vec_sv_coef(m.nr_class-1, std::vector(m.l)); + + for(int i=0;i vec_probA; + if(m.probA) // regression has probA only + { + vec_probA = detail::save_1d_array(m.probA, m.nr_class*(m.nr_class-1)/2); + } + ar & BOOST_SERIALIZATION_NVP(vec_probA); + } + + //probB + { + std::vector vec_probB; + if(m.probB) + { + vec_probB = detail::save_1d_array(m.probB, m.nr_class*(m.nr_class-1)/2); + } + ar & BOOST_SERIALIZATION_NVP(vec_probB); + } + + //label + { + std::vector vec_label; + if(m.label) + { + vec_label = detail::save_1d_array(m.label, m.nr_class); + } + ar & BOOST_SERIALIZATION_NVP(vec_label); + } + + //nSV + { + std::vector vec_nSV; + if(m.nSV) + { + vec_nSV = detail::save_1d_array(m.nSV, m.nr_class); + } + ar & BOOST_SERIALIZATION_NVP(vec_nSV); + } +} + +template +void load(Archive & ar, svm_model &m, const unsigned int version){ + m.rho = NULL; + m.probA = NULL; + m.probB = NULL; + m.sv_indices = NULL; + m.label = NULL; + m.nSV = NULL; + + ar & BOOST_SERIALIZATION_NVP(m.param); + ar & BOOST_SERIALIZATION_NVP(m.nr_class); + ar & BOOST_SERIALIZATION_NVP(m.l); + + //SV + { + std::vector > vec_SV; + ar & BOOST_SERIALIZATION_NVP(vec_SV); + detail::load_2d_array(vec_SV, m.SV); + } + + //sv_coef + { + std::vector > vec_sv_coef; + ar & BOOST_SERIALIZATION_NVP(vec_sv_coef); + detail::load_2d_array(vec_sv_coef, m.sv_coef); + } + + //rho + { + std::vector vec_rho; + ar & BOOST_SERIALIZATION_NVP(vec_rho); + detail::load_1d_array(vec_rho, m.rho); + } + + //probA + { + std::vector vec_probA; + ar & BOOST_SERIALIZATION_NVP(vec_probA); + if(!vec_probA.empty()){ + detail::load_1d_array(vec_probA, m.probA); + } + } + + //probB + { + std::vector vec_probB; + ar & BOOST_SERIALIZATION_NVP(vec_probB); + if(!vec_probB.empty()){ + detail::load_1d_array(vec_probB, m.probB); + } + } + + //label + { + std::vector vec_label; + ar & BOOST_SERIALIZATION_NVP(vec_label); + if(!vec_label.empty()){ + detail::load_1d_array(vec_label, m.label); + } + } + + //nSV + { + std::vector vec_nSV; + ar & BOOST_SERIALIZATION_NVP(vec_nSV); + if(!vec_nSV.empty()){ + detail::load_1d_array(vec_nSV, m.nSV); + } + } + + m.free_sv = 1; +} + +} // namespace serialization +} // namespace boost + +BOOST_SERIALIZATION_SPLIT_FREE(svm_model); + +#endif /* LIBSVM_BOOST_SERIALIZATION_HPP */ + From c4de3529dc6d369f17e3c7cdfcce76cb75614515 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Mon, 16 Sep 2019 13:27:02 -0400 Subject: [PATCH 2/3] removed the header --- svm-boost-serialization.hpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/svm-boost-serialization.hpp b/svm-boost-serialization.hpp index c45042a2..7374ecaa 100644 --- a/svm-boost-serialization.hpp +++ b/svm-boost-serialization.hpp @@ -1,16 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: serialization.hpp - * Author: arash - * - * Created on September 13, 2019, 6:34 p.m. - */ - #ifndef LIBSVM_BOOST_SERIALIZATION_HPP #define LIBSVM_BOOST_SERIALIZATION_HPP From 5934e91b7511901fa474d3b2f181eef777ff7308 Mon Sep 17 00:00:00 2001 From: aabghari <44274379+aabghari@users.noreply.github.com> Date: Wed, 18 Sep 2019 10:26:37 -0400 Subject: [PATCH 3/3] renamed some functions --- svm-boost-serialization.hpp | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/svm-boost-serialization.hpp b/svm-boost-serialization.hpp index 7374ecaa..5ef42236 100644 --- a/svm-boost-serialization.hpp +++ b/svm-boost-serialization.hpp @@ -11,12 +11,12 @@ namespace boost { namespace serialization { namespace detail{ template - T* Malloc(size_t n){ + T* SVMMalloc(size_t n){ return (T*)malloc((n)*sizeof(T)); } template - std::vector save_1d_array(const T* array_1d, size_t n){ + std::vector svm_save_1d_array(const T* array_1d, size_t n){ std::vector vec_1d(n); for(size_t i=0;i - void load_1d_array(const std::vector &vec_1d, T* &array_1d){ - array_1d = Malloc(vec_1d.size()); + void svm_load_1d_array(const std::vector &vec_1d, T* &array_1d){ + array_1d = SVMMalloc(vec_1d.size()); for(size_t i=0;i - void load_2d_array(const std::vector > &vec_2d, T** &array_2d){ - array_2d = detail::Malloc(vec_2d.size()); + void svm_load_2d_array(const std::vector > &vec_2d, T** &array_2d){ + array_2d = detail::SVMMalloc(vec_2d.size()); for(size_t i=0;i vec_probA; if(m.probA) // regression has probA only { - vec_probA = detail::save_1d_array(m.probA, m.nr_class*(m.nr_class-1)/2); + vec_probA = detail::svm_save_1d_array(m.probA, m.nr_class*(m.nr_class-1)/2); } ar & BOOST_SERIALIZATION_NVP(vec_probA); } @@ -125,7 +125,7 @@ void save(Archive & ar, const svm_model &m, const unsigned int version){ std::vector vec_probB; if(m.probB) { - vec_probB = detail::save_1d_array(m.probB, m.nr_class*(m.nr_class-1)/2); + vec_probB = detail::svm_save_1d_array(m.probB, m.nr_class*(m.nr_class-1)/2); } ar & BOOST_SERIALIZATION_NVP(vec_probB); } @@ -135,7 +135,7 @@ void save(Archive & ar, const svm_model &m, const unsigned int version){ std::vector vec_label; if(m.label) { - vec_label = detail::save_1d_array(m.label, m.nr_class); + vec_label = detail::svm_save_1d_array(m.label, m.nr_class); } ar & BOOST_SERIALIZATION_NVP(vec_label); } @@ -145,7 +145,7 @@ void save(Archive & ar, const svm_model &m, const unsigned int version){ std::vector vec_nSV; if(m.nSV) { - vec_nSV = detail::save_1d_array(m.nSV, m.nr_class); + vec_nSV = detail::svm_save_1d_array(m.nSV, m.nr_class); } ar & BOOST_SERIALIZATION_NVP(vec_nSV); } @@ -168,21 +168,21 @@ void load(Archive & ar, svm_model &m, const unsigned int version){ { std::vector > vec_SV; ar & BOOST_SERIALIZATION_NVP(vec_SV); - detail::load_2d_array(vec_SV, m.SV); + detail::svm_load_2d_array(vec_SV, m.SV); } //sv_coef { std::vector > vec_sv_coef; ar & BOOST_SERIALIZATION_NVP(vec_sv_coef); - detail::load_2d_array(vec_sv_coef, m.sv_coef); + detail::svm_load_2d_array(vec_sv_coef, m.sv_coef); } //rho { std::vector vec_rho; ar & BOOST_SERIALIZATION_NVP(vec_rho); - detail::load_1d_array(vec_rho, m.rho); + detail::svm_load_1d_array(vec_rho, m.rho); } //probA @@ -190,7 +190,7 @@ void load(Archive & ar, svm_model &m, const unsigned int version){ std::vector vec_probA; ar & BOOST_SERIALIZATION_NVP(vec_probA); if(!vec_probA.empty()){ - detail::load_1d_array(vec_probA, m.probA); + detail::svm_load_1d_array(vec_probA, m.probA); } } @@ -199,7 +199,7 @@ void load(Archive & ar, svm_model &m, const unsigned int version){ std::vector vec_probB; ar & BOOST_SERIALIZATION_NVP(vec_probB); if(!vec_probB.empty()){ - detail::load_1d_array(vec_probB, m.probB); + detail::svm_load_1d_array(vec_probB, m.probB); } } @@ -208,7 +208,7 @@ void load(Archive & ar, svm_model &m, const unsigned int version){ std::vector vec_label; ar & BOOST_SERIALIZATION_NVP(vec_label); if(!vec_label.empty()){ - detail::load_1d_array(vec_label, m.label); + detail::svm_load_1d_array(vec_label, m.label); } } @@ -217,7 +217,7 @@ void load(Archive & ar, svm_model &m, const unsigned int version){ std::vector vec_nSV; ar & BOOST_SERIALIZATION_NVP(vec_nSV); if(!vec_nSV.empty()){ - detail::load_1d_array(vec_nSV, m.nSV); + detail::svm_load_1d_array(vec_nSV, m.nSV); } }