From 81741fb5b3fe86bf29a130f367ea102e3aa99b0b Mon Sep 17 00:00:00 2001 From: Peng Li Date: Mon, 23 Jul 2018 19:37:19 +0800 Subject: [PATCH] separate pytwrpper from predictorWrappery --- include/PredictorWrapper.h | 10 +- include/PyWrapper.cpp | 2 + include/PyWrapper.h | 29 +++ include/SharedPtr.h | 2 +- python/model.pkl | 453 --------------------------------------------- src/Engine.cpp | 3 +- src/MultiTracker.cpp | 3 +- src/PredictorWrapper.cpp | 134 ++++---------- src/PyWrapper.cpp | 113 +++++++++++ test/TestPredictor.cpp | 3 +- 10 files changed, 186 insertions(+), 566 deletions(-) create mode 100644 include/PyWrapper.cpp create mode 100644 include/PyWrapper.h delete mode 100644 python/model.pkl create mode 100644 src/PyWrapper.cpp diff --git a/include/PredictorWrapper.h b/include/PredictorWrapper.h index c41a8bc..18ea862 100644 --- a/include/PredictorWrapper.h +++ b/include/PredictorWrapper.h @@ -14,18 +14,14 @@ namespace suanzi { class PredictorWrapper { public: - static PredictorWrapperPtr create(const std::string& python_dir, const std::string& model_dir); // model.pkl file + PredictorWrapper(const std::string& module="predictor", const std::string& pydir = "./python"); ~PredictorWrapper(){} void dump(); double predict(int index, const std::vector& f); + bool load(const std::string& fname); // load pkl file private: - PredictorWrapper(const std::string& py_dir, const std::string& fname); - static PredictorWrapperWPtr instance; - - PY_FUN dump_func; - PY_FUN predict_func; - + boost::python::object m_module; }; } diff --git a/include/PyWrapper.cpp b/include/PyWrapper.cpp new file mode 100644 index 0000000..6319940 --- /dev/null +++ b/include/PyWrapper.cpp @@ -0,0 +1,2 @@ +#include + diff --git a/include/PyWrapper.h b/include/PyWrapper.h new file mode 100644 index 0000000..24323cc --- /dev/null +++ b/include/PyWrapper.h @@ -0,0 +1,29 @@ +#ifndef _PY_WRAPPER_H_ +#define _PY_WRAPPER_H_ + +#include +#include "SharedPtr.h" +#include + +namespace suanzi { + +TK_DECLARE_PTR(PyWrapper); +class PyWrapper +{ +public: + static PyWrapperPtr getInstance(const std::string& pydir); // get Python Interprete + virtual ~PyWrapper(); + boost::python::object import(const std::string& module); + void exec(const std::string& cmd); + static std::string parse_python_exception(); + +private: + PyWrapper(const std::string& python_dir); + boost::python::object main_namespace; + boost::python::object main_module; +}; + +} + + +#endif // _PY_WRAPPER_H_ diff --git a/include/SharedPtr.h b/include/SharedPtr.h index 9b13584..8c2c303 100644 --- a/include/SharedPtr.h +++ b/include/SharedPtr.h @@ -6,7 +6,7 @@ #define TK_DECLARE_PTR(className) \ class className; \ typedef std::shared_ptr className##Ptr; \ - typedef std::weak_ptr className##WPtr; + typedef std::weak_ptr className##WPtr #endif #endif /* _SHARED_PTR_H_ */ diff --git a/python/model.pkl b/python/model.pkl deleted file mode 100644 index e26d88b..0000000 --- a/python/model.pkl +++ /dev/null @@ -1,453 +0,0 @@ -(lp1 -ccopy_reg -_reconstructor -p2 -(csklearn.linear_model.logistic -LogisticRegression -p3 -c__builtin__ -object -p4 -NtRp5 -(dp6 -S'warm_start' -p7 -I00 -sS'C' -F1 -sS'n_jobs' -p8 -I1 -sS'verbose' -p9 -I0 -sS'fit_intercept' -p10 -I01 -sS'solver' -p11 -S'liblinear' -p12 -sS'classes_' -p13 -cnumpy.core.multiarray -_reconstruct -p14 -(cnumpy -ndarray -p15 -(I0 -tS'b' -tRp16 -(I1 -(L2L -tcnumpy -dtype -p17 -(S'i4' -I0 -I1 -tRp18 -(I3 -S'<' -NNNI-1 -I-1 -I0 -tbI00 -S'\x00\x00\x00\x00\x01\x00\x00\x00' -tbsS'n_iter_' -p19 -g14 -(g15 -(I0 -tS'b' -tRp20 -(I1 -(L1L -tg17 -(S'i4' -I0 -I1 -tRp21 -(I3 -S'<' -NNNI-1 -I-1 -I0 -tbI00 -S'\x0b\x00\x00\x00' -tbsS'intercept_scaling' -p22 -I1 -sS'penalty' -p23 -S'l2' -p24 -sS'multi_class' -p25 -S'ovr' -p26 -sS'random_state' -p27 -NsS'_sklearn_version' -p28 -S'0.19.0' -p29 -sS'dual' -p30 -I00 -sS'tol' -p31 -F0.0001 -sS'coef_' -p32 -g14 -(g15 -(I0 -tS'b' -tRp33 -(I1 -(L1L -L8L -tg17 -(S'f8' -I0 -I1 -tRp34 -(I3 -S'<' -NNNI-1 -I-1 -I0 -tbI00 -S'\xe2\x06dQ\xb5\xd1\x11@\xb4\x06\x1c.{`\xfb?\xea}\x1c\xea \xb7\xbb?TQz6\x17\r\xdc\xbfc}J\xd5\xfb\x81\x0c@\x92\xe9\xf7\r/\xa3\xf4\xbf\xf5\xc9mcQ\xfe\x01\xc0:\xa9`\xd4\xd3\xfb\xf7\xbf' -tbsS'intercept_' -p35 -g14 -(g15 -(I0 -tS'b' -tRp36 -(I1 -(L1L -tg34 -I00 -S'\xee\xa1\x95\x9f\xd3\xeb}?' -tbsS'max_iter' -p37 -I100 -sS'class_weight' -p38 -Nsbag2 -(g3 -g4 -NtRp39 -(dp40 -g7 -I00 -sS'C' -F1 -sg8 -I1 -sg9 -I0 -sg10 -I01 -sg11 -g12 -sg13 -g14 -(g15 -(I0 -tS'b' -tRp41 -(I1 -(L2L -tg18 -I00 -S'\x00\x00\x00\x00\x01\x00\x00\x00' -tbsg19 -g14 -(g15 -(I0 -tS'b' -tRp42 -(I1 -(L1L -tg21 -I00 -S'\x0c\x00\x00\x00' -tbsg22 -I1 -sg23 -g24 -sg25 -g26 -sg27 -Nsg28 -g29 -sg30 -I00 -sg31 -F0.0001 -sg32 -g14 -(g15 -(I0 -tS'b' -tRp43 -(I1 -(L1L -L16L -tg34 -I00 -S'4\xf7\\\xbf\xe6$\x0c@biKO\x01\x00\xf6?\xff\x82\x07*\xe9\xf7\xd2?\xb8\xe3\xd7|\x14O\xdf\xbfKS\xd5?\x10\x00\xaf\xd6!\xa7\x81?\xb7\xbe\xa9,\xb0k\xec?\xf7\x18\x82?\xf8\xa6\xc2\xbfU\xe8Ni\xf2\xa2\xfa?\xff\x84E\xf7!\x98\xdf\xbf\xbb\x91N=\x86\xfd\xf1?\xd7/\xef\xb4\xb3\xc2\xe0?\x0c\x96\x13\x04Al\xd4?\xa4\xd3a\x12\x1d\xce\xc1\xbf\xd2(9\xcd\x9dh\xef?H /\xedC\xcf\xda?J\n\xa1\x1fD\x98\xc1?m%\xc3&\xaa;\xdb?' -tbsg35 -g14 -(g15 -(I0 -tS'b' -tRp50 -(I1 -(L1L -tg34 -I00 -S'\x80\x1d\xf1\xf3(\x89\xe3\xbf' -tbsg37 -I100 -sg38 -Nsbag2 -(g3 -g4 -NtRp51 -(dp52 -g7 -I00 -sS'C' -F1 -sg8 -I1 -sg9 -I0 -sg10 -I01 -sg11 -g12 -sg13 -g14 -(g15 -(I0 -tS'b' -tRp53 -(I1 -(L2L -tg18 -I00 -S'\x00\x00\x00\x00\x01\x00\x00\x00' -tbsg19 -g14 -(g15 -(I0 -tS'b' -tRp54 -(I1 -(L1L -tg21 -I00 -S'\r\x00\x00\x00' -tbsg22 -I1 -sg23 -g24 -sg25 -g26 -sg27 -Nsg28 -g29 -sg30 -I00 -sg31 -F0.0001 -sg32 -g14 -(g15 -(I0 -tS'b' -tRp55 -(I1 -(L1L -L32L -tg34 -I00 -S'N+\xd0R\xed\x8f\x06@\xe0\x9f\xab\xc1\x16\x8f\xf4?\xbe+\xed&\xea\r\xd0?\xb6\xfc,\x074\x8b\xe2\xbf\x8f>f\x8e\xa3\x07\x01@\xe7lu\xbbn\x9b\xf1\xbf>[@s\xc7:\x0e\xc0\x86"\xb8\xaa,\xdb\x85?\xec\xddMJ)\x1a\xea?\xec*\xe1\xfc.\xc5\xd4?\t\xef,\xd8\xf41\xd4?J[\'\x8fP\x14\xab\xbf\x8fA\xea\xd8\xf0b\xe6?3\x8a|\t1\x1c\xc1\xbfn6\xdf\x96\xc6\xe2\xfa?&\x04\x82\x14\x1f5\xdb\xbf\xcc+\x18\xfa\x9f\x0b\xea?\xc6\x1c\xcf\xec\xcf\xa0\xd8?\n\xa5\xbe\xb2\xd7\x1c\xd4?\x82c M\x85\xf6\xbb\xbf\x1b\xb6\x17\x972"\xe1?U\x90/\x04\x8f\xdb\xd2?\x93\xceVv\xe2\x9f\x9c?$p\x16#o\x93\xd7?\x0e\x1a\xfe=\xe7\xc3\xea?h\xfa\xee\xd04y\xdf?\xf8\xad\xff\x86\xf0\xc4\xd1?\xa4N\xb3<87\xb4?\xb8\xc9\xce@\xdc(\xc4?HSA\x9b\xd1I\xcb?g\n\xd9tn\x10\xd0?t\x9db\x95u\xd0\xdc?' -tbsg35 -g14 -(g15 -(I0 -tS'b' -tRp56 -(I1 -(L1L -tg34 -I00 -S'\xbc;\xceA\xf6\xc7\xe2\xbf' -tbsg37 -I100 -sg38 -Nsbag2 -(g3 -g4 -NtRp57 -(dp58 -g7 -I00 -sS'C' -F1 -sg8 -I1 -sg9 -I0 -sg10 -I01 -sg11 -g12 -sg13 -g14 -(g15 -(I0 -tS'b' -tRp59 -(I1 -(L2L -tg18 -I00 -S'\x00\x00\x00\x00\x01\x00\x00\x00' -tbsg19 -g14 -(g15 -(I0 -tS'b' -tRp60 -(I1 -(L1L -tg21 -I00 -S'\x0e\x00\x00\x00' -tbsg22 -I1 -sg23 -g24 -sg25 -g26 -sg27 -Nsg28 -g29 -sg30 -I00 -sg31 -F0.0001 -sg32 -g14 -(g15 -(I0 -tS'b' -tRp61 -(I1 -(L1L -L40L -tg34 -I00 -S'\xd9\xfe\'\xeeW\xc4\x05@\x9f:b\xf1F\xa4\xf4?\xf28\xaf\xdc`\xd4\xc8?\xf5\xcb.\x85#\xa9\xe7\xbf6"e&G\xbb\x00@1\x833\xe4O\xa9\xf1\xbfEm\x1d\x8b\xb9\xdb\x0c\xc0\x83\xd6J\xe3Q|\xcd?\xa5\xd5?\x034"\xe5?\xd7d\x92\xaf\x8ev\xdc?\xe2U:|\xe0\xf9\xd1?\xcf>~0\xadm\xcb\xbf\x92D.n\xf6\'\xde?\x83\x90\x81\x07\xab\xa2\xd2\xbfn\x96L\x15W*\xfa?\xecC\xfaMtr\xdd\xbf4\r\xcew\x90\xad\xe7?\x10Wu\x18\x84"\xe2?\xe7m\xba\xb1pk\xd2?T\x84V\xe1V\x86\xbd\xbf\x82\x1b-\x0c\xb6H\xcf?\xe9F\x06{\x8dW\xc8?\xa5\xb5d\x0e\x1b\x11\xbe\xbf\x9f\xe4y4\xe5n\xd3?\xe0\xf8M\xb1\xff\xb5\xd9?)\xb1e\xc4\xb4\x02\xe0?\x04\xdb\x94\xe2\xfd\xa6\xd1?9\xa7\x04\x89\xff\x90\xbf?\xee\x8f\xab\x1d1\x1c\xc8\xbf&w\xf6X\xd0\x8f\xc1?\xf3\xdeI\xaa\xfc\x02\xb2?\xae\xbf\xa3Sj\xa0\xc1?\x83\xdb\xcf\rr\x0e\xec?\r\xe8\xb1k\xc9\x14\xe0?\x1b"j?o\xc8\xd2?\xdf9_W\xa7{\xcd?.\xbf&\xea\xa2\x1f\xda?\xbeno\xb3\xe8\xda\xb5?\x85&\xcbt\xd3r\xd0?\x04\xbb\xffur\xc1\xde?' -tbsg35 -g14 -(g15 -(I0 -tS'b' -tRp62 -(I1 -(L1L -tg34 -I00 -S'\x90\xe2;h\x9e\xbf\xe2\xbf' -tbsg37 -I100 -sg38 -Nsba. \ No newline at end of file diff --git a/src/Engine.cpp b/src/Engine.cpp index 1b7cca2..fbdf337 100644 --- a/src/Engine.cpp +++ b/src/Engine.cpp @@ -29,7 +29,8 @@ EnginePtr Engine::create() Engine::Engine() { - detector = std::make_shared(); + //detector = std::make_shared(); + detector = DetectorPtr(new Detector()); } Engine::~Engine() diff --git a/src/MultiTracker.cpp b/src/MultiTracker.cpp index 138657e..bbfc6f3 100644 --- a/src/MultiTracker.cpp +++ b/src/MultiTracker.cpp @@ -18,7 +18,8 @@ MultiTracker::MultiTracker(EngineWPtr e) : engine(e) { LOG_DEBUG(TAG, "init - loading model.pkl"); - predictor = PredictorWrapper::create("./python", "./python/model.pkl"); + predictor = PredictorWrapperPtr(new PredictorWrapper()); + predictor->load("./resources/model.pkl"); predictor->dump(); this->descriptor = {Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9}; } diff --git a/src/PredictorWrapper.cpp b/src/PredictorWrapper.cpp index ebe7579..5559ddc 100644 --- a/src/PredictorWrapper.cpp +++ b/src/PredictorWrapper.cpp @@ -3,6 +3,7 @@ #include "Logger.h" #include #include +#include "PyWrapper.h" namespace py = boost::python; @@ -10,12 +11,8 @@ using namespace std; using namespace suanzi; -PredictorWrapperWPtr PredictorWrapper::instance; - const static std::string TAG = "PredictorWrapper"; -static std::string parse_python_exception(); - template boost::python::list toPythonList(const std::vector& v) { typename std::vector::iterator iter; @@ -26,114 +23,47 @@ boost::python::list toPythonList(const std::vector& v) { return list; } -PredictorWrapperPtr PredictorWrapper::create(const std::string& python_dir, const std::string& model_path) -{ - if (instance.lock()){ - return PredictorWrapperPtr(); - } - PredictorWrapperPtr ins (new PredictorWrapper(python_dir, model_path)); - instance = ins; - return ins; -} +#define CALL_WITH_EXCEPTION(expr, ret_val) \ + try{ \ + py::object py_ret = expr; \ + ret_val = py::extract(py_ret); \ + }catch(boost::python::error_already_set const &){ \ + LOG_ERROR(TAG, PyWrapper::parse_python_exception()); \ + } \ -void PredictorWrapper::dump() + +PredictorWrapper::PredictorWrapper(const string& module, const string& pydir) { - LOG_DEBUG(TAG, "dump"); - std::string ss = ""; + PyWrapperPtr interpreter = PyWrapper::getInstance(pydir); try{ - py::object ret = this->dump_func(); - ss = py::extract(ret); + m_module = interpreter->import(module); } catch (boost::python::error_already_set const &){ - std::string perror_str = parse_python_exception(); - LOG_ERROR(TAG, "Error in Python: " + perror_str) + LOG_ERROR(TAG, PyWrapper::parse_python_exception()); } - LOG_DEBUG(TAG, ss); } -double PredictorWrapper::predict(int index, const std::vector& ff) +bool PredictorWrapper::load(const string& fname) { - LOG_DEBUG(TAG, "predict"); - py::object ret; - try{ - ret = this->predict_func(index, toPythonList(ff)); - } catch (boost::python::error_already_set const &){ - std::string perror_str = parse_python_exception(); - LOG_ERROR(TAG, "Error in Python: " + perror_str) - } - double rr = py::extract(ret); - LOG_DEBUG(TAG, "return: " + std::to_string(rr)); - return rr; + LOG_DEBUG(TAG, "load " + fname); + py::object func = m_module.attr("init"); + string ret; + CALL_WITH_EXCEPTION(func(fname.c_str()), ret); + return true; } -PredictorWrapper::PredictorWrapper(const std::string& py_dir, const std::string& model_path) +void PredictorWrapper::dump() { - Py_Initialize(); - try{ - py::object main_module = py::import("__main__"); - py::object main_namespace = main_module.attr("__dict__"); - py::exec("import sys", main_namespace); - std::string cmd = "sys.path.insert(0, '" + py_dir + "')"; - py::exec(cmd.c_str(), main_namespace); - py::exec("import signal", main_namespace); - py::exec("signal.signal(signal.SIGINT, signal.SIG_DFL)", main_namespace); - py::object predictor_mod = py::import("predictor"); - py::object predictor_init = predictor_mod.attr("init"); - dump_func = predictor_mod.attr("dump"); - predict_func = predictor_mod.attr("predict"); - predictor_init(model_path.c_str()); - } catch (boost::python::error_already_set const &){ - std::string perror_str = parse_python_exception(); - LOG_ERROR(TAG, "Error in Python: " + perror_str) - } + LOG_DEBUG(TAG, "dump"); + py::object func = m_module.attr("dump"); + string ret = ""; + CALL_WITH_EXCEPTION(func(), ret); + LOG_DEBUG(TAG, ret); } -static std::string parse_python_exception(){ - PyObject *type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL; - // Fetch the exception info from the Python C API - PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr); - - // Fallback error - std::string ret("Unfetchable Python error"); - // If the fetch got a type pointer, parse the type into the exception string - if(type_ptr != NULL){ - py::handle<> h_type(type_ptr); - py::str type_pstr(h_type); - // Extract the string from the boost::python object - py::extract e_type_pstr(type_pstr); - // If a valid string extraction is available, use it - // otherwise use fallback - if(e_type_pstr.check()) - ret = e_type_pstr(); - else - ret = "Unknown exception type"; - } - // Do the same for the exception value (the stringification of the exception) - if(value_ptr != NULL){ - py::handle<> h_val(value_ptr); - py::str a(h_val); - py::extract returned(a); - if(returned.check()) - ret += ": " + returned(); - else - ret += std::string(": Unparseable Python error: "); - } - // Parse lines from the traceback using the Python traceback module - if(traceback_ptr != NULL){ - py::handle<> h_tb(traceback_ptr); - // Load the traceback module and the format_tb function - py::object tb(py::import("traceback")); - py::object fmt_tb(tb.attr("format_tb")); - // Call format_tb to get a list of traceback strings - py::object tb_list(fmt_tb(h_tb)); - // Join the traceback strings into a single string - py::object tb_str(py::str("\n").join(tb_list)); - // Extract the string, check the extraction, and fallback in necessary - py::extract returned(tb_str); - if(returned.check()) - ret += ": " + returned(); - else - ret += std::string(": Unparseable Python traceback"); - } - return ret; -} - +double PredictorWrapper::predict(int index, const vector& features) +{ + py::object func = m_module.attr("predict"); + double rr = 0; + CALL_WITH_EXCEPTION(func(index, toPythonList(features)), rr); + return rr; +} diff --git a/src/PyWrapper.cpp b/src/PyWrapper.cpp new file mode 100644 index 0000000..e19fe3d --- /dev/null +++ b/src/PyWrapper.cpp @@ -0,0 +1,113 @@ +#include "PyWrapper.h" +#include +#include +#include "Logger.h" + +namespace py = boost::python; +using namespace std; +using namespace suanzi; + +static const std::string TAG = "PyWrapper"; + +PyWrapperPtr PyWrapper::getInstance(const string& pydir) +{ + LOG_DEBUG(TAG, "getInstance"); + static PyWrapperPtr instance (new PyWrapper(pydir)); + return instance; +} + +PyWrapper::PyWrapper(const std::string& python_dir) +{ + LOG_DEBUG(TAG, "Init Python interpreter"); + Py_Initialize(); + try{ + main_module = py::import("__main__"); + main_namespace = main_module.attr("__dict__"); + py::exec("import sys", main_namespace); + std::string cmd = "sys.path.insert(0, '" + python_dir + "')"; + py::exec(cmd.c_str(), main_namespace); + py::exec("import signal", main_namespace); + py::exec("signal.signal(signal.SIGINT, signal.SIG_DFL)", main_namespace); + } catch (boost::python::error_already_set const &){ + LOG_ERROR(TAG, "Error in Python: " + parse_python_exception()) + } +} + +PyWrapper::~PyWrapper() +{ + Py_Finalize(); + LOG_DEBUG(TAG, "DeInit Python interpreter"); +} + +py::object PyWrapper::import(const std::string& module) +{ + LOG_DEBUG(TAG, "import " + module); + py::object o; + try{ + o = py::import(module.c_str()); + } catch (boost::python::error_already_set const &){ + LOG_ERROR(TAG, parse_python_exception()); + } + return o; +} + +void PyWrapper::exec(const std::string& cmd) +{ + try{ + py::exec(cmd.c_str()); + } catch(boost::python::error_already_set const &){ + LOG_ERROR(TAG, parse_python_exception()); + } +} + + +// refer to http://www.sigverse.org/wiki/en/index.php?Import%20and%20use%20of%20user%20defined%20python%20modules +std::string PyWrapper::parse_python_exception(){ + PyObject *type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL; + // Fetch the exception info from the Python C API + PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr); + + // Fallback error + std::string ret("Unfetchable Python error"); + // If the fetch got a type pointer, parse the type into the exception string + if(type_ptr != NULL){ + py::handle<> h_type(type_ptr); + py::str type_pstr(h_type); + // Extract the string from the boost::python object + py::extract e_type_pstr(type_pstr); + // If a valid string extraction is available, use it + // otherwise use fallback + if(e_type_pstr.check()) + ret = e_type_pstr(); + else + ret = "Unknown exception type"; + } + // Do the same for the exception value (the stringification of the exception) + if(value_ptr != NULL){ + py::handle<> h_val(value_ptr); + py::str a(h_val); + py::extract returned(a); + if(returned.check()) + ret += ": " + returned(); + else + ret += std::string(": Unparseable Python error: "); + } + // Parse lines from the traceback using the Python traceback module + if(traceback_ptr != NULL){ + py::handle<> h_tb(traceback_ptr); + // Load the traceback module and the format_tb function + py::object tb(py::import("traceback")); + py::object fmt_tb(tb.attr("format_tb")); + // Call format_tb to get a list of traceback strings + py::object tb_list(fmt_tb(h_tb)); + // Join the traceback strings into a single string + py::object tb_str(py::str("\n").join(tb_list)); + // Extract the string, check the extraction, and fallback in necessary + py::extract returned(tb_str); + if(returned.check()) + ret += ": " + returned(); + else + ret += std::string(": Unparseable Python traceback"); + } + return ret; +} diff --git a/test/TestPredictor.cpp b/test/TestPredictor.cpp index c6087f0..e3add17 100644 --- a/test/TestPredictor.cpp +++ b/test/TestPredictor.cpp @@ -5,7 +5,8 @@ using namespace suanzi; TEST(Predictor, load) { - PredictorWrapperPtr predictor = PredictorWrapper::create("../python", "../python/model.pkl"); + PredictorWrapperPtr predictor (new PredictorWrapper("predictor", "../python")); + predictor->load("../resources/model.pkl"); predictor->dump(); std::vector ff (40, 1); double prob = predictor->predict(4, ff); -- 2.11.0